인그레스 트래픽 처리
인그레스 트래픽 처리 (Handling ingress traffic)
Linkerd를 각종 Kubernetes 인그레스 컨트롤러와 함께 구성하고, 인그레스 모드와 TLS 처리, 여러 인그레스 옵션별 설정 방법을 다루는 문서예요.
본문
인그레스 트래픽(ingress traffic)은 클러스터 외부에서 클러스터 안으로 들어오는 트래픽을 말해요. 단순성과 조합성(composability)을 위해 Linkerd 자체는 클러스터로 들어오는 트래픽을 처리하는 내장 인그레스 솔루션을 제공하지 않습니다. 대신 Linkerd는 기존의 다양한 Kubernetes 인그레스 옵션과 함께 동작하도록 설계되었어요.
Linkerd와 선택한 인그레스 솔루션을 결합하려면 두 가지가 필요합니다:
- (필요하면) 인그레스가 Linkerd를 지원하도록 구성하기
- 인그레스 파드를 메시에 포함시키기(meshing)
엄밀히 말하면 클러스터로 트래픽을 허용하기 위해 인그레스 파드를 메시에 포함시킬 필요는 없어요. 하지만 권장됩니다. 트래픽이 클러스터에 들어오는 순간부터 Linkerd가 L7 메트릭과 상호 TLS 같은 기능을 제공할 수 있게 되기 때문이에요.
외부 TLS 처리 (Handling external TLS)
인그레스 컨트롤러의 흔한 역할 중 하나는 외부 세계(예: HTTPS 호출)의 TLS를 종료하는 것입니다.
다른 모든 파드와 마찬가지로, 메시에 포함된 인그레스로의 트래픽에는 인바운드와 아웃바운드 두 구성 요소가 있어요. 인그레스가 TLS를 종료한다면, Linkerd는 이 인바운드 TLS 트래픽을 불투명한 TCP 스트림으로 취급하고, 이 연결 측면에 대해서는 바이트 수준 메트릭만 제공할 수 있습니다.
인그레스 컨트롤러가 TLS 연결을 종료하고 내부 서비스로 해당 HTTP 또는 gRPC 트래픽을 발행하면, 이 아웃바운드 호출은 완전한 메트릭 세트와 mTLS 지원을 받게 됩니다.
인그레스 모드 (Ingress mode)
대부분의 인그레스 컨트롤러는 다른 서비스처럼 메시에 포함될 수 있어요. 즉 적절한 수준에 linkerd.io/inject: enabled annotation을 적용하면 됩니다. (자세한 내용은 서비스를 Linkerd에 추가하기 문서 참고)
하지만 일부 인그레스 옵션은 linkerd.io/inject: ingress annotation을 사용하는 특별한 "인그레스" 모드로 메시에 포함되어야 합니다.
아래 지침에서 각 인그레스가 이 모드를 필요로 하는지 설명할게요.
"인그레스" 모드를 사용한다면, 인그레스 네임스페이스의 다른 리소스는 정상적으로 메시에 포함되도록, namespace 수준이 아니라 워크로드 수준에서 이 인그레스 annotation을 설정할 것을 권장합니다.
Warning
인그레스를 인그레스 모드로 메시에 포함시킬 때, 클러스터 내부와 외부 엔드포인트로 가는 오픈 릴레이(open relay)가 생기지 않도록, 클라이언트 트래픽에서 들어오는 l5d-dst-override 헤더를 제거하도록 반드시 구성해야 해요. 인그레스 컨트롤러는 내부 서비스로 가는 요청에 자체 l5d-dst-override 헤더를 여전히 추가할 수 있습니다.
Note
Linkerd 2.13.0부터 2.13.4에는 인그레스 모드에서 l5d-dst-override 헤더가 필수가 되어, 없으면 요청이 실패하는 버그가 있었어요. 이 버그는 2.13.5에서 수정되었고, 2.13.0 이전에는 존재하지 않았습니다.
Note
인그레스 컨트롤러를 kube-system 또는 cert-manager 네임스페이스에 배포하지 마세요. Linkerd는 기본적으로 주입 시 이런 네임스페이스를 무시합니다.
인그레스 모드와 그 필요성에 대한 자세한 내용은 아래의 Ingress details를 참고하세요.
Linkerd에서 흔히 쓰는 인그레스 옵션 (Common ingress options for Linkerd)
Linkerd와 함께 사용되어 온 일반적인 인그레스 옵션은 다음과 같습니다:
- Ambassador (일명 Emissary)
- Nginx (커뮤니티 버전)
- Nginx (F5 NGINX 버전)
- Traefik, Traefik 1.x
- Traefik 2.x
- GCE
- Gloo
- Contour
- Kong
- Haproxy
- EnRoute
- ngrok
특정 인그레스 사용에 대한 빠른 시작 가이드는 아래 해당 인그레스 섹션을 참고하세요. 목록에 없는 인그레스를 쓴다 해도 걱정하지 마세요. 아마 동작할 가능성이 높습니다. 아래 Ingress details를 참고하세요.
Emissary-Ingress (일명 Ambassador)
Emissary-Ingress는 일반적으로 메시에 포함될 수 있어요. 인그레스 모드 annotation이 필요하지 않습니다. Ambassador / Emissary를 구성하는 예시 매니페스트는 다음과 같습니다:
`apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: web-ambassador-mapping
namespace: emojivoto
spec:
hostname: '*'
prefix: /
service: http://web-svc.emojivoto.svc.cluster.local:80
`
더 자세한 가이드는 Linkerd 서비스 메시와 함께 Emissary 인그레스를 설치하는 문서를 읽는 것을 권장합니다.
Nginx (커뮤니티 버전)
이 섹션은 Kubernetes 커뮤니티 버전의 Nginx 인그레스 컨트롤러 kubernetes/ingress-nginx를 말합니다.
Nginx는 일반적으로 메시에 포함될 수 있어요. 인그레스 모드 annotation이 필요하지 않습니다.
nginx.ingress.kubernetes.io/service-upstream annotation을 "true"로 설정해야 합니다. 예를 들어:
`# apiVersion: networking.k8s.io/v1beta1 # for k8s
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: emojivoto-web-ingress
namespace: emojivoto
annotations:
nginx.ingress.kubernetes.io/service-upstream: 'true'
spec:
ingressClassName: nginx
defaultBackend:
service:
name: web-svc
port:
number: 80
`
ingress-nginx Helm 차트를 사용한다면, 인그레스 컨트롤러를 담은 네임스페이스에는 linkerd.io/inject: enabled를 annotation해서는 안 된다는 점에 주의하세요. 대신 kind: Deployment(.spec.template.metadata.annotations)에 annotation을 해야 합니다. 예를 들어:
`controller:
podAnnotations:
linkerd.io/inject: enabled
`
이유는 이 Helm 차트가 (다른 것들과 함께) 두 개의 Kubernetes 리소스를 정의하기 때문입니다:
- kind: ValidatingWebhookConfiguration. 이는 ingress-nginx-admission-create-XXXXX 같은 이름의 수명이 짧은 파드를 만들어 곧바로 종료시킵니다.
- kind: Deployment. 이는 ingress-nginx-controller-XXXX 같은 이름의 장기 실행 파드를 만들고, 여기에 Nginx docker 컨테이너가 들어 있습니다.
namespace 수준에서 주입 annotation을 설정하면 수명이 짧은 파드까지 메시에 포함되어, 설계대로 종료되지 못하게 됩니다.
Nginx (F5 NGINX 버전)
이 섹션은 F5 NGINX가 개발·유지보수하는 Nginx 인그레스 컨트롤러 nginxinc/kubernetes-ingress를 말합니다.
이 버전의 Nginx도 일반적으로 메시에 포함될 수 있으며, 인그레스 모드 annotation이 필요하지 않습니다.
ingress 리소스 대신 VirtualServer/VirtualServerRoute CRD 리소스를 사용해야 합니다 (자세한 내용은 이 Github 이슈 참고).
use-cluster-ip 필드를 true로 설정해야 합니다. 예를 들어:
`apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: emojivoto-web-ingress
namespace: emojivoto
spec:
ingressClassName: nginx
upstreams:
- name: web
service: web-svc
port: 80
use-cluster-ip: true
routes:
- path: /
action:
pass: web
`
Traefik
Traefik은 인그레스 모드를 활성화한 상태로, 즉 기본 enabled가 아니라 linkerd.io/inject: ingress annotation과 함께 메시에 포함되어야 합니다.
지침은 Traefik의 1.x와 2.x 버전이 다릅니다.
Traefik 1.x
Traefik 1.x를 Linkerd의 인그레스로 사용하는 가장 간단한 방법은 ingress.kubernetes.io/custom-request-headers를 가진 Kubernetes Ingress 리소스를 구성하는 것입니다:
`# apiVersion: networking.k8s.io/v1beta1 # for k8s
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
namespace: emojivoto
annotations:
ingress.kubernetes.io/custom-request-headers: l5d-dst-override:web-svc.emojivoto.svc.cluster.local:80
spec:
ingressClassName: traefik
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
`
여기서 중요한 annotation은:
`ingress.kubernetes.io/custom-request-headers: l5d-dst-override:web-svc.emojivoto.svc.cluster.local:80
`
Traefik은 요청이 향하는 서비스를 Linkerd에 알려주는 l5d-dst-override 헤더를 추가합니다. Kubernetes 서비스 FQDN(web-svc.emojivoto.svc.cluster.local)과 목적지 servicePort를 모두 포함해야 해요.
테스트하려면 컨트롤러의 외부 IP 주소를 얻어야 합니다. Helm으로 Traefik을 설치했다면 다음 명령으로 IP 주소를 얻을 수 있습니다:
`kubectl get svc --all-namespaces \
-l app=traefik \
-o='custom-columns=EXTERNAL-IP:.status.loadBalancer.ingress[0].ip'
`
그 다음 이 IP를 curl과 함께 사용할 수 있어요:
`curl -H "Host: example.com" http://external-ip
`
Note
Traefik의 서비스 가중치(service weights)를 사용한다면 이 솔루션은 동작하지 않아요. Linkerd는 항상 l5d-dst-override의 서비스 이름으로 요청을 보내기 때문입니다. 대신 traefik.frontend.passHostHeader: "false"를 사용하는 것이 해결책입니다.
Traefik 2.x
Traefik 2.x는 IngressRoute라는 Custom Resource Definition(CRD)으로 경로 기반 요청 라우팅을 지원합니다.
기본 Kubernetes Ingress 리소스 대신 IngressRoute를 사용하기로 했다면, l5d-dst-override 헤더를 추가하기 위해 Traefik의 Middleware Custom Resource Definition도 사용해야 합니다.
아래 YAML은 위에서 설명한 것과 같은 결과를 emojivoto 애플리케이션에 대해 Traefik CRD로 만들어 냅니다.
`apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: l5d-header-middleware
namespace: traefik
spec:
headers:
customRequestHeaders:
l5d-dst-override: 'web-svc.emojivoto.svc.cluster.local:80'
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
annotations:
kubernetes.io/ingress.class: traefik
creationTimestamp: null
name: emojivoto-web-ingress-route
namespace: emojivoto
spec:
entryPoints: []
routes:
- kind: Rule
match: PathPrefix(`/`)
priority: 0
middlewares:
- name: l5d-header-middleware
services:
- kind: Service
name: web-svc
port: 80
nativeLB: true
`
GCE
GCE 인그레스는 인그레스 모드를 활성화한 상태로, 즉 기본 enabled가 아니라 linkerd.io/inject: ingress annotation과 함께 메시에 포함되어야 합니다.
이 예제는 Google Cloud Static External IP Address와 Google-managed 인증서를 이용한 TLS를 사용하는 방법을 보여줍니다.
`# apiVersion: networking.k8s.io/v1beta1 # for k8s
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
namespace: emojivoto
annotations:
ingress.kubernetes.io/custom-request-headers:
'l5d-dst-override: web-svc.emojivoto.svc.cluster.local:80'
ingress.gcp.kubernetes.io/pre-shared-cert: 'managed-cert-name'
kubernetes.io/ingress.global-static-ip-name: 'static-ip-name'
spec:
ingressClassName: gce
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
`
이 예제 정의를 사용하려면 managed-cert-name과 static-ip-name을 프로젝트에 정의된 짧은 이름으로 바꾸세요 (IP 주소 자체가 아니라 IP 주소의 이름을 사용합니다).
관리형 인증서는 프로비저닝에 약 30-60분이 걸리지만, 인그레스 상태는 몇 분 안에 정상이 되어야 해요. 관리형 인증서가 프로비저닝되면 인그레스는 인터넷에 보이게 됩니다.
Gloo
Gloo는 인그레스 모드를 활성화한 상태로, 즉 기본 enabled가 아니라 linkerd.io/inject: ingress annotation과 함께 메시에 포함되어야 합니다.
Gloo v0.13.20부터 Gloo는 Linkerd와의 네이티브 통합을 지원해서, 필요한 Linkerd 헤더를 자동으로 추가합니다. Gloo를 기본 위치에 설치했다고 가정하면, 다음 명령으로 네이티브 통합을 활성화할 수 있어요:
`kubectl patch settings -n gloo-system default \
-p '{"spec":{"linkerd":true}}' --type=merge
`
이제 Gloo는 모든 Kubernetes 업스트림에 l5d-dst-override 헤더를 자동으로 추가합니다.
이제 업스트림에 라우트를 추가하기만 하면 됩니다. 예:
`glooctl add route --path-prefix=/ --dest-name booksapp-webapp-7000
`
Contour
Contour는 인그레스 모드를 활성화한 상태로, 즉 기본 enabled가 아니라 linkerd.io/inject: ingress annotation과 함께 메시에 포함되어야 합니다.
다음 예제는 Contour getting started 문서를 사용해 필요한 헤더를 수동으로 설정하는 방법을 보여줍니다.
Contour의 Envoy DaemonSet은 서비스 어카운트 토큰을 자동 마운트하지 않아요. 이 토큰은 Linkerd 프록시가 파드 간 mTLS를 수행하는 데 필요합니다. 그래서 먼저 Contour를 주입하지 않고 설치한 다음, DaemonSet에 automountServiceAccountToken: true를 패치하고, 그 후에 주입해야 합니다. 선택적으로 default 어카운트를 피하기 위해 전용 서비스 어카운트를 만들 수도 있어요.
`# install Contour
kubectl apply -f https://projectcontour.io/quickstart/contour.yaml
# create a service account (optional)
kubectl apply -f - apiVersion: v1
kind: ServiceAccount
metadata:
name: envoy
namespace: projectcontour
EOF
# add service account to envoy (optional)
kubectl patch daemonset envoy -n projectcontour --type json -p='[{"op": "add", "path": "/spec/template/spec/serviceAccount", "value": "envoy"}]'
# auto mount the service account token (required)
kubectl patch daemonset envoy -n projectcontour --type json -p='[{"op": "replace", "path": "/spec/template/spec/automountServiceAccountToken", "value": true}]'
# inject linkerd first into the DaemonSet
kubectl -n projectcontour get daemonset -oyaml | linkerd inject - | kubectl apply -f -
# inject linkerd into the Deployment
kubectl -n projectcontour get deployment -oyaml | linkerd inject - | kubectl apply -f -
`
Contour와 Envoy 설치에 Linkerd sidecar가 실행 중인지 확인하세요.
다음으로 데모 서비스를 배포합니다:
`linkerd inject https://projectcontour.io/examples/kuard.yaml | kubectl apply -f -
`
외부 트래픽을 서비스로 라우팅하려면 HTTPProxy를 제공해야 합니다:
`apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: kuard
namespace: default
spec:
routes:
- requestHeadersPolicy:
set:
- name: l5d-dst-override
value: kuard.default.svc.cluster.local:80
services:
- name: kuard
port: 80
virtualhost:
fqdn: 127.0.0.1.nip.io
`
l5d-dst-override 헤더가 대상 service로 명시적으로 설정된 것을 확인하세요.
마지막으로 동작하는 서비스 메시를 테스트할 수 있습니다:
`kubectl port-forward svc/envoy -n projectcontour 3200:80
http://127.0.0.1.nip.io:3200
`
Note
파드 스펙에 config.linkerd.io/skip-outbound-ports: 8001을 annotation해야 합니다. Envoy 파드는 8001 포트의 Contour 파드에 TLS를 통해 연결하려고 하는데, 이는 이 인그레스 모드에서 지원되지 않기 때문에 프록시가 그 아웃바운드 포트를 건너뛰도록 해야 합니다.
Note
Contour를 flagger와 함께 사용한다면 l5d-dst-override 헤더가 자동으로 설정됩니다.
Kong
Kong은 인그레스 모드를 활성화한 상태로, 즉 기본 enabled가 아니라 linkerd.io/inject: ingress annotation과 함께 메시에 포함되어야 합니다.
이 예제는 다음 요소를 사용합니다:
- Kong 차트
- emojivoto 예제 애플리케이션
emojivoto를 설치하기 전에 클러스터에 Linkerd와 Kong을 설치하세요. Kong 배포를 주입할 때 --ingress 플래그(또는 annotation)를 사용하세요.
KongPlugin(Kong CRD)과 Ingress 리소스도 선언해야 합니다.
`apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: set-l5d-header
namespace: emojivoto
plugin: request-transformer
config:
remove:
headers:
- l5d-dst-override # Prevents open relay
add:
headers:
- l5d-dst-override:$(headers.host).svc.cluster.local
---
# apiVersion: networking.k8s.io/v1beta1 # for k8s
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
namespace: emojivoto
annotations:
konghq.com/plugins: set-l5d-header
spec:
ingressClassName: kong
rules:
- http:
paths:
- path: /api/vote
pathType: Prefix
backend:
service:
name: web-svc
port:
name: http
- path: /api/list
pathType: Prefix
backend:
service:
name: web-svc
port:
name: http
`
여기서 우리는 KongPlugin에 l5d-dst-override를 명시적으로 설정합니다. 템플릿을 값으로 사용해, 요청의 host 헤더를 사용하고 그로부터 l5d-dst-override 값을 설정할 수 있어요.
마지막으로 emojivoto를 설치해서 emojivoto의 deploy/vote-bot이 인그레스를 대상으로 하고 web-svc.emojivoto 서비스에 대한 host 헤더 값을 포함하도록 합니다.
주입된 emojivoto 애플리케이션을 적용하기 전에 vote-bot Deployment를 다음과 같이 변경하세요:
`env:
# Target the Kong ingress instead of the Emojivoto web service
- name: WEB_HOST
value: kong-proxy.kong:80
# Override the host header on requests so that it can be used to set the l5d-dst-override header
- name: HOST_OVERRIDE
value: web-svc.emojivoto
`
Haproxy
Note
haproxy 기반 인그레스 컨트롤러는 두 종류가 있습니다. 이 예제는 haproxytech의 kubernetes-ingress 컨트롤러를 위한 것이며, haproxy-ingress 컨트롤러가 아닙니다.
Haproxy는 인그레스 모드를 활성화한 상태로, 즉 기본 enabled가 아니라 linkerd.io/inject: ingress annotation과 함께 메시에 포함되어야 합니다.
Haproxy를 Linkerd의 인그레스로 사용하는 가장 간단한 방법은 haproxy.org/request-set-header annotation으로 Kubernetes Ingress 리소스를 구성하는 것입니다:
`apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
namespace: emojivoto
annotations:
kubernetes.io/ingress.class: haproxy
haproxy.org/request-set-header: |
l5d-dst-override web-svc.emojivoto.svc.cluster.local:80
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
`
안타깝게도 현재는 전역 config map에서 서비스 이름·네임스페이스·포트를 변수로 사용해 동적으로 이 작업을 수행하는 것을 지원하지 않습니다. 그래서 각 인그레스 규칙이 하드코딩된 값과 함께 자체 haproxy.org/request-set-header annotation이 필요하기 때문에, 하나의 인그레스 매니페스트에 여러 서비스 인그레스 규칙을 결합할 수 없습니다.
EnRoute OneStep
EnRoute를 Linkerd와 메시로 연결하는 것은 전역으로 플래그 하나만 설정하면 됩니다:
`apiVersion: enroute.saaras.io/v1
kind: GlobalConfig
metadata:
labels:
app: web
name: enable-linkerd
namespace: default
spec:
name: linkerd-global-config
type: globalconfig_globals
config: |
{
"linkerd_enabled": true
}
`
이제 EnRoute 파드에 Linkerd 프록시를 주입해 EnRoute를 메시에 포함시킬 수 있습니다. linkerd 유틸리티로 EnRoute 배포를 업데이트해 Linkerd 프록시를 주입할 수 있어요.
`kubectl get -n enroute-demo deploy -o yaml | linkerd inject - | kubectl apply -f -
`
linkerd_enabled 플래그는 l5d-dst-override 헤더를 자동으로 설정합니다. 이 플래그는 라우팅을 위한 엔드포인트 선택도 linkerd에 위임합니다.
더 자세한 내용과 커스터마이징은 EnRoute와 Linkerd를 이용한 종단 간 암호화 문서에서 확인할 수 있습니다.
ngrok
ngrok은 일반적으로 메시에 포함될 수 있어요. 인그레스 모드 annotation이 필요하지 않습니다.
무료 ngrok 계정에 가입하고 ngrok Ingress 컨트롤러 설치 단계를 진행한 후, 서비스에 인그레스 객체를 구성하고 kubectl apply -f ingress.yaml로 적용하면 인그레스를 추가할 수 있습니다.
이것은 Linkerd getting started 가이드에 사용된 emojivoto 앱의 예입니다. host 값을 ngrok 계정의 무료 정적 도메인으로 바꿔야 해요. 유료 ngrok 계정이라면 ngrok 에이전트의 --domain 플래그를 사용하는 것과 같은 방식으로 구성할 수 있습니다.
`apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: emojivoto-ingress
namespace: emojivoto
spec:
ingressClassName: ngrok
rules:
- host: [YOUR STATIC DOMAIN.ngrok-free.app]
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
`
이제 emojivoto 앱은 여러분의 정적 도메인에서 전 세계 누구에게나 제공되어야 합니다.
Ingress 상세 (Ingress details)
이 섹션에서는 Linkerd가 일반적으로 인그레스 컨트롤러와 어떻게 상호작용하는지 다룹니다.
Linkerd가 라우트 기반 메트릭, 동적 트래픽 라우팅 같은 L7 기능을 제대로 적용하려면, 인그레스 컨트롤러가 목적지 Kubernetes Service의 IP/포트에 연결해야 합니다. 하지만 기본적으로 많은 인그레스가 자체 엔드포인트 선택을 해서, Service가 아닌 목적지 Pod의 IP/포트에 직접 연결합니다.
따라서 인그레스와 Linkerd를 결합하는 방법은 두 가지 중 하나예요:
- 목적지로서 Service의 IP와 포트에 연결하도록, 즉 자체 엔드포인트 선택을 건너뛰도록 인그레스를 구성합니다. (예: 위의 Nginx 참고)
- 대안으로, l5d-dst-override, Host, :authority 같은 헤더에 Service IP/포트를 전달하도록 인그레스를 구성하고, Linkerd를 인그레스 모드로 구성합니다. 이 모드에서는 해당 헤더 중 하나에서 값을 읽습니다.
형식 #2의 가장 일반적인 접근법은 명시적인 l5d-dst-override 헤더를 사용하는 것입니다.
Note
일부 인그레스 컨트롤러는 고정 세션(sticky sessions)을 지원합니다. 세션 고정을 위해 인그레스 컨트롤러는 자체 엔드포인트 선택을 해야 합니다. 즉 Linkerd는 Kubernetes Service의 IP/포트에 연결하지 못하고, 대신 파드에 직접 연결하게 됩니다. 따라서 고정 세션과 ServiceProfiles는 상호 배타적입니다.
Note
인그레스 컨트롤러를 주입한 후 요청에 2-3초 지연이 발생한다면, 아마 type: LoadBalancer의 서비스가 클라이언트 소스 IP를 가리고 있기 때문일 가능성이 높아요. 인그레스의 서비스 정의에 externalTrafficPolicy: Local을 설정하면 해결할 수 있습니다.
Note
Kubernetes Ingress API 정의는 backend의 servicePort가 문자열 값이어도 허용하지만, Linkerd에서는 숫자 servicePort 값만 사용할 수 있어요. 문자열 값을 만나면 Linkerd는 기본적으로 포트 80을 사용합니다.
더 알아보기 (Learn more)
- Linkerd에 서비스 추가하기 (Adding your services to Linkerd)
- Linkerd 인그레스 기능 개요