BackendTLSPolicy 예제

BackendTLSPolicy 예제 (BackendTLSPolicy Example)

이 예제는 echo-server 샘플 애플리케이션을 사용해서 BackendTLSPolicy를 활용하는 방법을 보여드려요. 인증서를 생성하려면 mkcert 도구가 필요하며, 자세한 내용은 해당 도구의 공식 사이트를 참고해주세요.

출처: BackendTLSPolicy Example

본문

이 예제는 echo-server 샘플 애플리케이션을 사용해서 BackendTLSPolicy를 어떻게 사용하는지 보여드릴게요.

인증서를 생성하려면 mkcert 도구가 필요해요. 자세한 내용은 해당 도구의 공식 사이트를 참고해주세요.

이 작업은 self-signed CA를 사용하며, 오직 데모 목적만을 위한 거예요.

echo-server 배포하기 (Deploy echo-server)

다음을 적용해서 echo-server를 배포해볼게요.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: backend
---
apiVersion: v1
kind: Service
metadata:
  name: backend
  labels:
    app: backend
    service: backend
spec:
  ports:
    - name: http
      port: 3000
      targetPort: 3000
  selector:
    app: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend
      version: v1
  template:
    metadata:
      labels:
        app: backend
        version: v1
    spec:
      serviceAccountName: backend
      containers:
        - image: gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e
          imagePullPolicy: IfNotPresent
          name: backend
          ports:
            - containerPort: 3000
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace

echo-server용 Gateway와 HTTPRoute를 만들려면 다음을 적용해주세요:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: cilium
  listeners:
    - name: http
      protocol: HTTP
      port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: backend
spec:
  parentRefs:
    - name: my-gateway
  hostnames:
    - "www.example.com"
  rules:
    - backendRefs:
        - group: ""
          kind: Service
          name: backend
          port: 3000
          weight: 1
      matches:
        - path:
            type: PathPrefix
            value: /

샘플 애플리케이션을 테스트해볼게요:

$ curl -v --resolve www.example.com:80:<GATEWAY_IP_ADDRESS> http://www.example.com/get

curl 명령은 요청에 대한 정보를 반환해요. 대략 다음과 같이 보일 거예요:

{
 "path": "/get",
 "host": "www.example.com",
 "method": "GET",
 "proto": "HTTP/1.1",
 "headers": {
  "Accept": [
   "*/*"
  ],
  "User-Agent": [
   "curl/8.20.0"
  ],
  "X-Envoy-Internal": [
   "true"
  ],
  "X-Forwarded-For": [
   "172.19.0.1"
  ],
  "X-Forwarded-Proto": [
   "http"
  ],
  "X-Request-Id": [
   "bb913f3e-7538-4873-88e4-25499fe5b3ff"
  ]
 },
 "namespace": "default",
 "ingress": "",
 "service": "",
 "pod": "backend-86c6c76f-ptczl"
}

데모 TLS 인증서 생성하기 (Generate demo TLS Certificates)

example.com에 대한 인증서와 키를 생성해볼게요.

먼저 루트 인증서를 만듭니다.

mkcert www.example.com

그러면 현재 디렉터리에 인증서와 키가 출력돼요.

클러스터에 시크릿과 configmap 만들기 (Create the secret and configmap in your cluster)

인증서와 키를 Kubernetes Secret에 저장해볼게요.

kubectl create secret tls example-cert --key=www.example.com-key.pem --cert=www.example.com.pem

클러스터에 configmap을 만들어볼게요.

kubectl create configmap example-ca --from-file=ca.crt=www.example.com.pem

게이트웨이와 백엔드 사이에 TLS 설정하기 (Setup TLS between gateway and backend)

TLS를 활성화하도록 백엔드 디플로이먼트를 패치해볼게요. 다음 명령은 TLS 인증서 시크릿을 볼륨으로 백엔드 컨테이너에 마운트해요.

 kubectl patch deployment backend --type=json --patch '
- op: add
  path: /spec/template/spec/containers/0/volumeMounts
  value:
  - name: secret-volume
    mountPath: /etc/secret-volume
- op: add
  path: /spec/template/spec/volumes
  value:
  - name: secret-volume
    secret:
      secretName: example-cert
      items:
      - key: tls.crt
        path: crt
      - key: tls.key
        path: key
- op: add
  path: /spec/template/spec/containers/0/env/-
  value:
    name: TLS_SERVER_CERT
    value: /etc/secret-volume/crt
- op: add
  path: /spec/template/spec/containers/0/env/-
  value:
    name: TLS_SERVER_PRIVKEY
    value: /etc/secret-volume/key
'

백엔드 서비스가 포트 443을 노출하도록 구성해볼게요. 다음을 적용해서 backend 서비스의 포트가 443에서 수신하도록 업데이트해주세요:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: backend
    service: backend
  name: backend
spec:
  selector:
    app: backend
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: 8443

Cilium Gateway가 백엔드와 TLS 연결을 사용하도록 BackendTLSPolicy를 만들어볼게요.

apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
  name: enable-backend-tls
  namespace: default
spec:
  targetRefs:
  - group: ''
    kind: Service
    name: backend
    sectionName: https
  validation:
    caCertificateRefs:
    - name: example-ca
      group: ''
      kind: ConfigMap
    hostname: www.example.com

백엔드 서비스에서 편집한 올바른 포트를 사용하도록 HTTPRoute 백엔드 참조를 패치해볼게요.

kubectl patch HTTPRoute backend --type=json --patch '
 - op: replace
   path: /spec/rules/0/backendRefs/0/port
   value: 443
'

백엔드 TLS 연결 테스트하기 (Testing the backend TLS connection)

Gateway를 통해 서비스에 curl을 보내볼게요.

$ curl -vI --resolve "www.example.com:80:<YOUR_GATEWAY_EXTERNAL_IP>" http://www.example.com:80/get

200 OK 응답을 받아야 해요. curl 응답은 앞선 curl 응답과 비슷하지만, 응답에 TLS 암호화 세부 정보가 함께 표시된다는 점을 주목해주세요:

{
  "tls": {
   "version": "TLSv1.3",
   "serverName": "www.example.com",
   "negotiatedProtocol": "http/1.1",
   "cipherSuite": "TLS_AES_128_GCM_SHA256"
  }
 }

더 알아보기 (Learn more)