Kubernetes 리소스는 간단하게 다뤘습니다.
모든 예제 YAML은 AI에 의해 생성되었으며 특정 환경과 관련이 없습니다.
CustomResourceDefinitionapiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: virtualservices.networking.istio.io
spec:
group: networking.istio.io
names:
kind: VirtualService
plural: virtualservices
singular: virtualservice
shortNames:
- vs
scope: Namespaced
versions:
- name: v1beta1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
hosts:
type: array
items:
type: string
http:
type: array
items:
type: objectMutatingWebhookConfigurationapi-server가 요청을 받을 때 조건에 맞으면 외부 webhook을 호출해서 객체를 수정(mutate)하도록 연결하는 리소스
mutatingAdmissionWebhook은 api-server로 들어오는 객체를 수정해 기본값을 주거나 sidecar를 주입하는데 사용
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: istio-sidecar-injector
webhooks:
- name: sidecar-injector.istio.io # DNS 형식, unique
admissionReviewVersions:
- v1
sideEffects: None
failurePolicy: Fail
reinvocationPolicy: IfNeeded
timeoutSeconds: 10
clientConfig:
service:
name: istiod # 실제 webhook 요청을 처리하는 서비스
namespace: istio-system
path: /inject
port: 443
caBundle: <BASE64>
namespaceSelector:
matchExpressions:
- key: istio-injection # namespace 라벨이 있는 경우에만 주입을 수행하는 대표적인 opt-in 방식
operator: In
values:
- enabled
rules: # mutate 대상 (ex. Pod)
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
scope: NamespacedValidatingWebhookConfigurationKubernetes 리소스가 생성/수정되기 전에 “유효한지 검사”하고, 잘못되면 요청을 거부하는 설정
- clusterScoped: true
- builtin: true
- specless: true
```yaml
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: istio-validator-istio-system
labels:
app: istiod
istio: istiod
istio.io/rev: default
release: istio
app.kubernetes.io/name: istiod
webhooks:
- name: rev.validation.istio.io
admissionReviewVersions:
- v1
sideEffects: None
matchPolicy: Equivalent
timeoutSeconds: 10
failurePolicy: Ignore # webhook 준비 전까지 fail-open -> 준비 후 Fail로 패치
clientConfig:
service:
name: istiod
namespace: istio-system
path: /validate
port: 443
caBundle: <BASE64_CA_BUNDLE>
objectSelector: # validate 대상
matchExpressions:
- key: istio.io/rev
operator: In
values:
- default
rules: # validate 규칙
- operations:
- CREATE
- UPDATE
apiGroups:
- security.istio.io
- networking.istio.io
- telemetry.istio.io
- extensions.istio.io
apiVersions:
- "*"
resources:
- "*"
scope: "*"
```
DeploymentEndpointEndpointSliceNamespaceNodePodDaemonSetStatefulSetSecretServiceConfigMapServiceAccountCertificateSigningRequestClusterTrustBundleIngressIngressClassLeaseHorizontalPodAutoscalerPodDisruptionBudgetGatewayClassistio: ingressgateway)GatewayClass
↓
Istio gateway controller가 감지
↓
Gateway 리소스 생성 처리
↓
실제 ingressgateway(Envoy) 구성
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio
spec:
controllerName: istio.io/gateway-controller
GatewayapiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: default
spec:
gatewayClassName: istio
listeners:
- name: http
protocol: HTTP
port: 80
hostname: "*.example.com"
- name: https
protocol: HTTPS
port: 443
hostname: "example.com"
tls:
mode: Terminate
certificateRefs:
- name: tls-secretHTTPRouteapiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-route
namespace: default
spec:
parentRefs: # Gateway 정의
- name: my-gateway
hostnames:
- example.com
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: my-service # Service
port: 80GRPCRouteapiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpc-route
namespace: default
spec:
parentRefs:
- name: my-gateway
hostnames:
- api.example.com
rules:
- matches:
- method:
service: helloworld.Greeter
method: SayHello
backendRefs:
- name: grpc-service # Service
port: 50051TCPRouteapiVersion: gateway.networking.k8s.io/v1
kind: TCPRoute
metadata:
name: tcp-route
namespace: default
spec:
parentRefs:
- name: my-gateway
rules:
- backendRefs:
- name: my-tcp-service
port: 3306
# HTTP Host Header 기반 매칭 없음
---
# Gateway 설정
listeners:
- name: mysql
port: 3306
protocol: TCPUDPRouteapiVersion: gateway.networking.k8s.io/v1
kind: UDPRoute
metadata:
name: udp-route
namespace: default
spec:
parentRefs:
- name: my-gateway
rules:
- backendRefs:
- name: dns-service
port: 53
---
# Gateway 설정
listeners:
- name: udp
port: 53
protocol: UDPTLSRouteapiVersion: gateway.networking.k8s.io/v1
kind: TLSRoute
metadata:
name: tls-route
namespace: default
spec:
parentRefs:
- name: my-gateway
hostnames:
- example.com
- api.example.com
rules:
- backendRefs:
- name: my-service
port: 443InferencePoolapiVersion: inference.networking.x-k8s.io/v1alpha1
kind: InferencePool
metadata:
name: my-model
namespace: default
spec:
targetRef:
group: ""
kind: Service
name: model-service
replicas:
min: 1
max: 10
loadBalancing:
policy: LeastRequest
model:
name: gpt-modelReferenceGrantvs Istio Sidecar
- ReferenceGrant = “누가 누구를 참조할 수 있는지 허용(보안)” - 리소스 참조
- Istio Sidecar = “어떤 트래픽을 볼지/허용할지 제한(트래픽 범위)” - 서비스 통신 (트래픽)
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
name: allow-http-route
namespace: other-ns # 보호 대상 리소스가 있는 ns
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute # 접근 가능 주체
namespace: default
to:
- group: ""
kind: Service # 허용 리소스
```
XBackendTrafficPolicyapiVersion: gateway.networking.x-k8s.io/v1alpha1
kind: XBackendTrafficPolicy
metadata:
name: my-policy
namespace: default
spec:
targetRefs:
- group: ""
kind: Service
name: my-service
loadBalancing:
policy: LeastRequest
retry:
attempts: 3
perTryTimeout: 2s
timeout: 5sBackendTLSPolicyapiVersion: gateway.networking.k8s.io/v1alpha2
kind: BackendTLSPolicy
metadata:
name: backend-tls
namespace: default
spec:
targetRefs:
- group: ""
kind: Service
name: my-service
tls:
mode: Simple
caCertRefs:
- name: ca-cert
sni: my-service.default.svc.cluster.localListenerSetapiVersion: gateway.networking.x-k8s.io/v1alpha1
kind: ListenerSet
metadata:
name: extra-listeners
namespace: default
spec:
parentRefs:
- name: my-gateway
listeners: # Gateway Listeners와 동일한 구조
- name: http-alt
port: 8080
protocol: HTTP
- name: https-alt
port: 8443
protocol: HTTPSVirtualServiceapiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: my-service
spec:
hosts:
- my-service # 요청 받을 주소 (ex. 도메인)
http:
- route:
- destination:
host: my-service # 트래픽 보낼 대상 주소
port:
number: 80DestinationRuleapiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: my-service
spec:
host: my-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 10
http:
http1MaxPendingRequests: 100
tls:
mode: ISTIO_MUTUAL
outlierDetection:
consecutive5xxErrors: 5
interval: 10s
baseEjectionTime: 30sGatewayapiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: istio-system
spec:
selector: # label을 가진
istio: ingressgateway # 어떤 Pod(Envoy)가 Gateway 처리할지 지정
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "myapp.example.com"ServiceEntry➕ 외부 서비스 라우팅 제어를 위해서 VirtualService를 붙이는 경우도 있다.
```yaml
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-google
spec:
hosts:
- www.google.com
location: MESH_EXTERNAL
ports:
- number: 443
name: https
protocol: HTTPS
resolution: DNS
# DNS: DNS lookup
# STATIC: IP 직접 지정
# NONE: DNS 없이 passthrough
```
WorkloadEntryapiVersion: networking.istio.io/v1
kind: WorkloadEntry
metadata:
name: vm-1
namespace: default
spec:
address: 10.0.0.10 # VM or 외부 서버 IP
labels: # Service selector와 매칭 -
app: my-service
version: v1
ports:
http: 8080
serviceAccount: default # mTLS, 인증에 사용
# Service
# ↓ selector
# Pod (K8s)
# WorkloadEntry (VM)
# ↓
# 같은 서비스로 묶임WorkloadGroup# VM 내부에서 명령 실행 시 본인 정보 등 합쳐서 WorkloadEntry 생성
istioctl x workload entry configure \
--workloadGroup my-service \
--namespace default
```yaml
apiVersion: networking.istio.io/v1
kind: WorkloadGroup
metadata:
name: my-service
namespace: default
spec:
metadata:
labels:
app: my-service
version: v1
template:
serviceAccount: default
ports:
http: 8080
probe:
httpGet:
path: /health
port: 8080
```
EnvoyFilterapiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: add-header
spec:
workloadSelector:
labels:
app: my-app
configPatches:
- applyTo: HTTP_FILTER # NETWORK_FILTER, CLUSTER, LISTENER
match:
context: SIDECAR_OUTBOUND # SIDECAR_OUTBOUND, GATEWAY
patch:
operation: INSERT_BEFORE # ADD, MERGE, REPLACE, REMOVE
value:
name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inlineCode: |
function envoy_on_request(request_handle)
request_handle:headers():add("x-custom-header", "test")
endSidecarapiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
name: default
namespace: my-namespace
spec:
egress:
- hosts:
- "./*"
- "istio-system/*"ProxyConfigapiVersion: networking.istio.io/v1beta1
kind: ProxyConfig
metadata:
name: default
namespace: istio-system
spec:
concurrency: 2
environmentVariables:
ISTIO_META_DNS_CAPTURE: "true"
tracing:
sampling: 100
image:
imageType: distroless
vs EnvoyFilter
- proxyConfig: Envoy의 기본 동작(bootstrap/런타임 옵션)을 설정 - 스레드 수, 로그 레벨 등
- envoyFilter: Envoy의 구성(xDS: listener/route/filter 등)을 직접 수정(patch)
MeshConfigIstio 전체 서비스 메시에 대한 전역(global) 동작을 설정하는 구성
- Kubernetes 리소스 아님, Istio 설치 시 설정값 (istioctl / Helm)
- IstioOperator를 안 쓰면 MeshConfig는 Helm values 또는 istiod 설정(ConfigMap/args)에서 관리
MeshNetworksmeshNetworks:
network1:
endpoints:
- fromRegistry: cluster1
gateways:
- address: 1.2.3.4
port: 15443
network2:
endpoints:
- fromRegistry: cluster2
gateways:
- address: 5.6.7.8
port: 15443AuthorizationPolicyALLOW + rules 없음 = 아무 것도 허용 안함
DENY + rules {} = 모든 요청 차단
# backend에서 frontdend가 특정 엔드포인트로 GET 요청 보내는 걸 허용
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: allow-frontend
namespace: default
spec:
action: ALLOW # DENY, CUSTOM, AUDIT
selector:
matchLabels:
app: backend
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/frontend"]
to: # backend 대상
- operation:
methods: ["GET"]
paths: ["/api/v1/*"]
ports: ["8080"]
RequestAuthenticationapiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata:
name: jwt-auth
namespace: default
spec:
selector:
matchLabels:
app: backend
fromHeaders: # 기본 Authorization
- name: x-jwt-token
fromParams:
- access_token
jwtRules:
- issuer: "https://accounts.google.com"
jwksUri: "https://www.googleapis.com/oauth2/v3/certs"PeerAuthenticationw/ DestinationRule
- PeerAuthentication: 서버가 mTLS 받을 준비됨
- DestinationRule: 클라이언트가 mTLS로 보낼지 결정
- 없어도 mesh 내부 통신은 istiod가 TLS 설정 자동 생성 - (
meshConfig.enableAutoMtls에서도 설정 가능)- 사이드카 없는 워크로드에서 호출하거나 mesh 밖 트래픽에서 호출하는 경우 통신 문제 발생 가능
- mesh 밖이어도 gateway→server 통신에 auto mTLS 적용 가능
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: default
spec:
mtls:
mode: STRICT # PERMISSIVE, DISABLE
TelemetryapiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
name: metrics-config
spec:
metrics:
- providers:
- name: prometheus
overrides:
- match:
metric: REQUEST_COUNT
disabled: false
---
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
name: access-logs
spec:
accessLogging:
- providers:
- name: envoy
---
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
name: tracing-config
spec:
tracing:
- providers:
- name: zipkin
randomSamplingPercentage: 100WasmPluginapiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: my-wasm-plugin
namespace: default
spec:
selector:
matchLabels:
app: my-app
url: oci://ghcr.io/istio-ecosystem/wasm-plugins/my-plugin:latest # Wasm 모듈 위치
phase: AUTHN # AUTHZ, STATS
pluginConfig:
key: valueistiod
├─ HTTPRoute → Gateway RDS
└─ VirtualService → Sidecar RDS
Listener → Route → Cluster → Endpoint
= 받고 → 어디로 보낼지 결정하고 → 서비스 선택하고 → 실제 Pod로 보냄
istioctl proxy-configistioctl proxy-config all <pod> -n <ns> -o <format>