3.3. 서비스 제공 인증서 보안을 사용하여 서비스 트래픽 보안

3.3.1. 서비스 제공 인증서 이해

서비스 제공 인증서는 암호화가 필요한 복잡한 미들웨어 애플리케이션을 지원하기 위한 것입니다. 이러한 인증서는 TLS 웹 서버 인증서로 발급됩니다.

service-ca 컨트롤러에서는 x509.SHA256WithRSA 서명 알고리즘을 사용하여 서비스 인증서를 생성합니다.

생성된 인증서 및 키는 PEM 형식이며, 생성된 보안의 tls.crttls.key에 각각 저장됩니다. 인증서와 키는 만료 시기가 다가오면 자동으로 교체됩니다.

서비스 인증서를 발급하는 서비스 CA 인증서는 26개월 동안 유효하며 유효 기간이 13개월 미만으로 남아 있으면 자동으로 순환됩니다. 교체 후에도 이전 서비스 CA 구성은 만료될 때까지 계속 신뢰 상태가 유지됩니다. 그러면 만료되기 전에 유예 기간 동안 영향을 받는 모든 서비스의 주요 자료를 새로 고칠 수 있습니다. 서비스를 다시 시작하고 키 자료를 새로 고치는 이 유예 기간 동안 클러스터를 업그레이드하지 않으면 이전 서비스 CA가 만료된 후 실패하지 않도록 서비스를 직접 다시 시작해야 할 수도 있습니다.

참고

다음 명령을 사용하여 클러스터의 모든 Pod를 직접 다시 시작할 수 있습니다. 이 명령을 실행하면 모든 네임스페이스에서 실행 중인 모든 Pod가 삭제되므로 서비스가 중단됩니다. 이 Pod는 삭제 후 자동으로 다시 시작됩니다.

$ for I in $(oc get ns -o jsonpath='{range .items[*]} {.metadata.name}{"\n"} {end}'); \
      do oc delete pods --all -n $I; \
      sleep 1; \
      done

3.3.2. 서비스 인증서 추가

서비스와의 통신을 보호하려면 서명된 제공 인증서와 키 쌍을 서비스와 동일한 네임스페이스의 보안에 생성합니다.

생성된 인증서는 내부 서비스 DNS 이름 <service.name>.<service.namespace>.svc에만 유효하고 내부 통신에만 유효합니다. 서비스가 헤드리스 서비스(clusterIP 값이 설정되지 않음)인 경우 생성된 인증서에는 *.<service.name>.<service.namespace>.svc 형식의 와일드카드 제목도 포함됩니다.

중요

생성된 인증서에는 헤드리스 서비스에 대한 와일드카드 제목이 포함되어 있으므로 클라이언트가 개별 Pod를 구분해야 하는 경우 서비스 CA를 사용하지 않아야 합니다. 이 경우 다음을 수행합니다.

  • 다른 CA를 사용하여 개별 TLS 인증서를 생성합니다.
  • 개별 Pod로 전달되며 다른 Pod로 가장해서는 안 되는 연결에 대해 서비스 CA를 신뢰할 수 있는 CA로 수락하지 마십시오. 이러한 연결은 개별 TLS 인증서를 생성하는 데 사용된 CA를 신뢰하도록 구성해야 합니다.

사전 요구 사항:

  • 서비스가 정의되어 있어야 합니다.

프로세스

  1. service.beta.openshift.io/serving-cert-secret-name으로 서비스에 주석을 답니다.

    $ oc annotate service <service_name> \1
         service.beta.openshift.io/serving-cert-secret-name=<secret_name> 2
    1
    <service_name>을 보호할 서비스 이름으로 교체합니다.
    2
    <secret_name>은 인증서와 키 쌍이 포함되어 생성된 보안의 이름입니다. <service_name>과 동일하게 설정하면 편리합니다.

    예를 들어 서비스 test1에 주석을 달려면 다음 명령을 사용합니다.

    $ oc annotate service test1 service.beta.openshift.io/serving-cert-secret-name=test1
  2. 서비스를 검사하여 주석이 있는지 확인합니다.

    $ oc describe service <service_name>

    출력 예

    ...
    Annotations:              service.beta.openshift.io/serving-cert-secret-name: <service_name>
                              service.beta.openshift.io/serving-cert-signed-by: openshift-service-serving-signer@1556850837
    ...

  3. 클러스터에서 서비스 보안을 생성하면 Pod 사양에서 보안을 마운트하고, 사용 가능 상태가 되면 Pod에서 실행합니다.

추가 리소스

3.3.3. 구성 맵에 서비스 CA 번들 추가

Pod는 service.beta.openshift.io/inject-cabundle=true 로 주석이 달린 ConfigMap 오브젝트를 마운트하여 서비스 CA 인증서에 액세스할 수 있습니다. 주석이 달리면 클러스터에서 서비스 CA 인증서를 구성 맵의 service-ca.crt 키에 자동으로 삽입합니다. 이 CA 인증서에 액세스하면 TLS 클라이언트가 서비스 제공 인증서를 사용하여 서비스에 대한 연결을 확인할 수 있습니다.

중요

구성 맵에 이 주석을 달면 기존 데이터가 모두 삭제됩니다. Pod 구성을 저장하는 것과 동일한 구성 맵을 사용하는 대신 별도의 구성 맵을 사용하여 service-ca.crt를 포함하는 것이 좋습니다.

프로세스

  1. service.beta.openshift.io/inject-cabundle=true로 구성 맵에 주석을 답니다.

    $ oc annotate configmap <config_map_name> \1
         service.beta.openshift.io/inject-cabundle=true
    1
    <config_map_name>을 주석을 달 구성 맵 이름으로 교체합니다.
    참고

    볼륨 마운트 시 service-ca.crt 키를 명시적으로 참조하면 CA 번들로 구성 맵을 삽입할 때까지 Pod가 시작되지 않습니다. 이 동작은 볼륨 제공 인증서 구성에서 optional 필드를 true로 설정하여 덮어쓸 수 있습니다.

    예를 들어 구성 맵 test1에 주석을 달려면 다음 명령을 사용합니다.

    $ oc annotate configmap test1 service.beta.openshift.io/inject-cabundle=true
  2. 구성 맵을 보고 서비스 CA 번들이 삽입되었는지 확인합니다.

    $ oc get configmap <config_map_name> -o yaml

    CA 번들은 YAML 출력에서 service-ca.crt 키 값으로 표시됩니다.

    apiVersion: v1
    data:
      service-ca.crt: |
        -----BEGIN CERTIFICATE-----
    ...

3.3.4. API 서비스에 서비스 CA 번들 추가

spec.caBundle 필드에 서비스 CA 번들이 입력되도록 service.beta.openshift.io/inject-cabundle=trueAPIService 오브젝트에 주석을 답니다. 그러면 쿠버네티스 API 서버가 대상 끝점을 보호하는 데 사용되는 서비스 CA 인증서의 유효성을 확인할 수 있습니다.

프로세스

  1. service.beta.openshift.io/inject-cabundle=true로 API 서비스에 주석을 답니다.

    $ oc annotate apiservice <api_service_name> \1
         service.beta.openshift.io/inject-cabundle=true
    1
    <api_service_name>을 주석을 달 API 서비스 이름으로 교체합니다.

    예를 들어 API 서비스 test1에 주석을 달려면 다음 명령을 사용합니다.

    $ oc annotate apiservice test1 service.beta.openshift.io/inject-cabundle=true
  2. API 서비스를 보고 서비스 CA 번들이 삽입되었는지 확인합니다.

    $ oc get apiservice <api_service_name> -o yaml

    CA 번들은 YAML 출력의 spec.caBundle 필드에 표시됩니다.

    apiVersion: apiregistration.k8s.io/v1
    kind: APIService
    metadata:
      annotations:
        service.beta.openshift.io/inject-cabundle: "true"
    ...
    spec:
      caBundle: <CA_BUNDLE>
    ...

3.3.5. 사용자 정의 리소스 정의에 서비스 CA 번들 추가

spec.conversion.webhook.clientConfig.caBundle 필드에 서비스 CA 번들이 입력되도록 CustomResourceDefinition(CRD) 오브젝트에 service.beta.openshift.io/inject-cabundle=true로 주석을 답니다. 그러면 쿠버네티스 API 서버가 대상 끝점을 보호하는 데 사용되는 서비스 CA 인증서의 유효성을 확인할 수 있습니다.

참고

CRD가 변환에 웹 후크를 사용하도록 구성된 경우 서비스 CA 번들은 CRD에만 삽입됩니다. CRD의 웹 후크가 서비스 CA 인증서로 보안된 경우에만 서비스 CA 번들을 삽입하는 것이 유용합니다.

프로세스

  1. service.beta.openshift.io/inject-cabundle=true로 CRD에 주석을 답니다.

    $ oc annotate crd <crd_name> \1
         service.beta.openshift.io/inject-cabundle=true
    1
    <crd_name>을 주석을 달 CRD 이름으로 교체합니다.

    예를 들어 CRD test1에 주석을 달려면 다음 명령을 사용합니다.

    $ oc annotate crd test1 service.beta.openshift.io/inject-cabundle=true
  2. CRD를 보고 서비스 CA 번들이 삽입되었는지 확인합니다.

    $ oc get crd <crd_name> -o yaml

    CA 번들은 YAML 출력의 spec.conversion.webhook.clientConfig.caBundle 필드에 표시됩니다.

    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      annotations:
        service.beta.openshift.io/inject-cabundle: "true"
    ...
    spec:
      conversion:
        strategy: Webhook
        webhook:
          clientConfig:
            caBundle: <CA_BUNDLE>
    ...

3.3.6. 변경 웹 후크 구성에 서비스 CA 번들 추가

각 웹 후크의 clientConfig.caBundle 필드에 서비스 CA 번들이 입력되도록 service.beta.openshift.io/inject-cabundle=trueMutatingWebhookConfiguration 오브젝트에 주석을 달 수 있습니다. 그러면 쿠버네티스 API 서버가 대상 끝점을 보호하는 데 사용되는 서비스 CA 인증서의 유효성을 확인할 수 있습니다.

참고

웹 후크마다 다른 CA 번들을 지정해야 하는 승인 웹 후크 구성에는 이 주석을 설정하지 마십시오. 그러면 모든 웹 후크에 서비스 CA 번들이 삽입됩니다.

프로세스

  1. service.beta.openshift.io/inject-cabundle=true로 변경 웹 후크 구성에 주석을 답니다.

    $ oc annotate mutatingwebhookconfigurations <mutating_webhook_name> \1
         service.beta.openshift.io/inject-cabundle=true
    1
    <mutating_webhook_name>을 주석을 달 변경 웹 후크 구성 이름으로 교체합니다.

    예를 들어 변경 웹 후크 구성 test1에 주석을 달려면 다음 명령을 사용합니다.

    $ oc annotate mutatingwebhookconfigurations test1 service.beta.openshift.io/inject-cabundle=true
  2. 변경 웹 후크 구성을 보고 서비스 CA 번들이 삽입되었는지 확인합니다.

    $ oc get mutatingwebhookconfigurations <mutating_webhook_name> -o yaml

    CA 번들은 YAML 출력에 있는 모든 웹 후크의 clientConfig.caBundle 필드에 표시됩니다.

    apiVersion: admissionregistration.k8s.io/v1
    kind: MutatingWebhookConfiguration
    metadata:
      annotations:
        service.beta.openshift.io/inject-cabundle: "true"
    ...
    webhooks:
    - myWebhook:
      - v1beta1
      clientConfig:
        caBundle: <CA_BUNDLE>
    ...

3.3.7. 검증 웹 후크 구성에 서비스 CA 번들 추가

각 웹 후크의 clientConfig.caBundle 필드에 서비스 CA 번들이 입력되도록 service.beta.openshift.io/inject-cabundle=trueValidatingWebhookConfiguration 오브젝트에 주석을 달 수 있습니다. 그러면 쿠버네티스 API 서버가 대상 끝점을 보호하는 데 사용되는 서비스 CA 인증서의 유효성을 확인할 수 있습니다.

참고

웹 후크마다 다른 CA 번들을 지정해야 하는 승인 웹 후크 구성에는 이 주석을 설정하지 마십시오. 그러면 모든 웹 후크에 서비스 CA 번들이 삽입됩니다.

프로세스

  1. service.beta.openshift.io/inject-cabundle=true로 검증 웹 후크 구성에 주석을 답니다.

    $ oc annotate validatingwebhookconfigurations <validating_webhook_name> \1
         service.beta.openshift.io/inject-cabundle=true
    1
    <validating_webhook_name>을 주석을 달 검증 웹 후크 구성 이름으로 교체합니다.

    예를 들어 검증 웹 후크 구성 test1에 주석을 달려면 다음 명령을 사용합니다.

    $ oc annotate validatingwebhookconfigurations test1 service.beta.openshift.io/inject-cabundle=true
  2. 검증 웹 후크 구성을 보고 서비스 CA 번들이 삽입되었는지 확인합니다.

    $ oc get validatingwebhookconfigurations <validating_webhook_name> -o yaml

    CA 번들은 YAML 출력에 있는 모든 웹 후크의 clientConfig.caBundle 필드에 표시됩니다.

    apiVersion: admissionregistration.k8s.io/v1
    kind: ValidatingWebhookConfiguration
    metadata:
      annotations:
        service.beta.openshift.io/inject-cabundle: "true"
    ...
    webhooks:
    - myWebhook:
      - v1beta1
      clientConfig:
        caBundle: <CA_BUNDLE>
    ...

3.3.8. 생성된 서비스 인증서를 직접 순환

관련 보안을 삭제하여 서비스 인증서를 순환할 수 있습니다. 보안을 삭제하면 새로운 보안이 자동으로 생성되어 새 인증서가 생성됩니다.

사전 요구 사항

  • 인증서 및 키 쌍을 포함하는 보안이 서비스용으로 생성되어야 합니다.

프로세스

  1. 서비스를 검사하여 인증서가 포함된 보안을 판별합니다. 아래 표시된 대로 serving-cert-secret-name 주석에 있습니다.

    $ oc describe service <service_name>

    출력 예

    ...
    service.beta.openshift.io/serving-cert-secret-name: <secret>
    ...

  2. 서비스용으로 생성된 보안을 삭제합니다. 이 프로세스는 자동으로 보안을 재생성합니다.

    $ oc delete secret <secret> 1
    1
    <secret>을 이전 단계의 보안 이름으로 교체합니다.
  3. 새 보안을 확보하고 AGE를 검사하여 인증서가 다시 생성되었는지 확인합니다.

    $ oc get secret <service_name>

    출력 예

    NAME              TYPE                DATA   AGE
    <service.name>    kubernetes.io/tls   2      1s

3.3.9. 서비스 CA 인증서를 직접 순환

서비스 CA는 26개월 동안 유효하며 유효 기간이 13개월 미만으로 남아 있으면 자동으로 새로 고쳐집니다.

필요하면 다음 절차에 따라 서비스 CA를 직접 새로 고칠 수 있습니다.

주의

수동으로 순환된 서비스 CA는 이전 서비스 CA와의 신뢰를 유지 관리하지 않습니다. 클러스터의 Pod가 다시 시작되어 Pod가 새 서비스 CA에서 발급한 서비스 제공 인증서를 사용하고 있는지 확인할 때까지 일시적으로 서비스 중단이 발생할 수 있습니다.

사전 요구 사항

  • 클러스터 관리자로 로그인해야 합니다.

프로세스

  1. 다음 명령을 사용하여 현재 서비스 CA 인증서의 만료 날짜를 봅니다.

    $ oc get secrets/signing-key -n openshift-service-ca \
         -o template='{{index .data "tls.crt"}}' \
         | base64 --decode \
         | openssl x509 -noout -enddate
  2. 서비스 CA를 직접 순환합니다. 이 프로세스는 새로운 서비스 인증서에 서명하는 데 사용될 새로운 서비스 CA를 생성합니다.

    $ oc delete secret/signing-key -n openshift-service-ca
  3. 새 인증서를 모든 서비스에 적용하도록 클러스터의 모든 Pod를 다시 시작합니다. 이 명령을 실행하면 모든 서비스가 업데이트된 인증서를 사용합니다.

    $ for I in $(oc get ns -o jsonpath='{range .items[*]} {.metadata.name}{"\n"} {end}'); \
          do oc delete pods --all -n $I; \
          sleep 1; \
          done
    주의

    이 명령은 모든 네임스페이스에서 실행 중인 모든 Pod를 대상으로 진행하고 삭제하므로 서비스가 중단됩니다. 이 Pod는 삭제 후 자동으로 다시 시작됩니다.