2.3. サービス提供証明書のシークレットによるサービストラフィックのセキュリティー保護

2.3.1. サービス提供証明書について

サービス提供証明書は、暗号化を必要とする複雑なミドルウェアアプリケーションをサポートすることが意図されています。これらの証明書は、TLS Web サーバー証明書として発行されます。

service-ca コントローラーは、サービス証明書を生成するために x509.SHA256WithRSA 署名アルゴリズムを使用します。

生成される証明書およびキーは PEM 形式のもので、作成されたシークレット内の tls.crt および tls.key にそれぞれ保存されます。証明書およびキーは、有効期間に近づくと自動的に置き換えられます。

サービス証明書を発行するサービス CA 証明書は 26 ヵ月間有効であり、有効期間が 13 ヵ月未満になると自動的にローテーションされます。ローテーション後も、直前のサービス CA 設定は有効期限が切れるまで信頼されます。これにより、影響を受けるすべてのサービスについて、期限が切れる前にそれらのキーの情報を更新できるように猶予期間が許可されます。この猶予期間中にクラスターをアップグレード(サービスを再起動してそれらのキー情報を更新する)を実行しない場合、直前のサービス CA の期限が切れた後の失敗を防ぐためにサービスを手動で再起動する必要がある場合があります。

注記

以下のコマンドを使用して、クラスター内のすべての Pod を手動で再起動できます。このコマンドは、すべての namespace で実行されているすべての 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

2.3.2. サービス証明書の追加

サービスとの通信のセキュリティーを保護するには、サービスと同じ namespace のシークレットに署名済みの提供証明書とキーのペアを生成します。

重要

生成される証明書は、内部サービス DNS 名 <service.name>.<service.namespace>.svc にのみ有効であり、内部通信用にのみ有効です。

前提条件

  • サービスが定義されていること。

手順

  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 はシークレットが利用可能になった後にこれを実行できます。

2.3.3. サービス CA バンドルの設定マップへの追加

Pod は、service.beta.openshift.io/inject-cabundle=true のアノテーションの付いた ConfigMap オブジェクトをマウントしてサービス CA 証明書にアクセスできます。アノテーションが付けられると、クラスターはサービス CA 証明書を設定マップの service-ca.crt キーに自動的に挿入します。この CA 証明書にアクセスできると、TLS クライアントはサービス提供証明書を使用してサービスへの接続を検証できます。

重要

このアノテーションが設定マップに追加されると、その中に含まれるすべての既存データが削除されます。service-ca.crt を組み込む設定マップとしては、Pod の設定の保存先と同じ設定マップではなく、別の設定マップを使用することが推奨されます。

手順

  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-----
    ...

2.3.4. サービス CA バンドルの API サービスへの追加

APIService オブジェクトに service.beta.openshift.io/inject-cabundle=true のアノテーションを付け、その spec.caBundle フィールドにサービス CA バンドルを設定できます。これにより、Kubernetes API サーバーはターゲットに設定されたエンドポイントのセキュリティーを保護するために使用されるサービス CA 証明書を検証することができます。

手順

  1. API サービスに service.beta.openshift.io/inject-cabundle=true のアノテーションを付けます。

    $ 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>
    ...

2.3.5. サービス CA バンドルのカスタムリソース定義への追加

CustomResourceDefinition (CRD) オブジェクトに service.beta.openshift.io/inject-cabundle=true のアノテーションを付け、その spec.conversion.webhook.clientConfig.caBundle フィールドにサービス CA バンドルを設定できます。これにより、Kubernetes API サーバーはターゲットに設定されたエンドポイントのセキュリティーを保護するために使用されるサービス CA 証明書を検証することができます。

注記

サービス CA バンドルは、CRD が変換に Webhook を使用するように設定されている場合にのみ CRD にインジェクトされます。CRD の Webhook がサービス CA 証明書でセキュリティー保護されている場合にのみ、サービス CA バンドルを挿入することは役に立ちます。

手順

  1. CRD に service.beta.openshift.io/inject-cabundle=true のアノテーションを付けます。

    $ 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>
    ...

2.3.6. サービス CA バンドルの変更用 Webhook 設定への追加

MutatingWebhookConfiguration オブジェクトに service.beta.openshift.io/inject-cabundle=true のアノテーションを付け、各 Webhook の clientConfig.caBundle フィールドにサービス CA バンドルを設定できます。これにより、Kubernetes API サーバーはターゲットに設定されたエンドポイントのセキュリティーを保護するために使用されるサービス CA 証明書を検証することができます。

注記

異なる Webhook に異なる CA バンドルを指定する必要がある受付 Webhook 設定にはこのアノテーションを設定しないでください。これを実行する場合、サービス CA バンドルはすべての Webhook について挿入されます。

手順

  1. 変更用 webhook 設定に service.beta.openshift.io/inject-cabundle=trueのアノテーションを付けます。

    $ oc annotate mutatingwebhookconfigurations <mutating_webhook_name> \1
         service.beta.openshift.io/inject-cabundle=true
    1
    <mutatingwebhook-name> を、アノテーションを付ける変更用 webhook 設定の名前に置き換えます。

    たとえば、以下のコマンドを使用して変更用 webhook 設定 test1 にアノテーションを付けます。

    $ oc annotate mutatingwebhookconfigurations test1 service.beta.openshift.io/inject-cabundle=true
  2. 変更用 webhook 設定を表示して、サービス CA バンドルが挿入されていることを確認します。

    $ oc get mutatingwebhookconfigurations <mutating_webhook_name> -o yaml

    CA バンドルは、YAML 出力のすべての Webhook の 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>
    ...

2.3.7. サービス CA バンドルの変更用 webhook 設定への追加

ValidatingWebhookConfiguration オブジェクトに service.beta.openshift.io/inject-cabundle=true のアノテーションを付け、各 Webhook の clientConfig.caBundle フィールドにサービス CA バンドルを設定できます。これにより、Kubernetes API サーバーはターゲットに設定されたエンドポイントのセキュリティーを保護するために使用されるサービス CA 証明書を検証することができます。

注記

異なる Webhook に異なる CA バンドルを指定する必要がある受付 Webhook 設定にはこのアノテーションを設定しないでください。これを実行する場合、サービス CA バンドルはすべての Webhook について挿入されます。

手順

  1. 変更用 webhook 設定に 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> をアノテーションを付ける検証用 webhook 設定の名前に置き換えます。

    たとえば、以下のコマンドを使用して検証用 webhook 設定 test1 にアノテーションを付けます。

    $ oc annotate validatingwebhookconfigurations test1 service.beta.openshift.io/inject-cabundle=true
  2. 検証用 webhook 設定を表示して、サービス CA バンドルが挿入されていることを確認します。

    $ oc get validatingwebhookconfigurations <validating_webhook_name> -o yaml

    CA バンドルは、YAML 出力のすべての Webhook の 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>
    ...

2.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

2.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
    警告

    このコマンドは、すべての namespace で実行されているすべての Pod を調べ、これらを削除するため、サービスを中断させます。これらの Pod は削除後に自動的に再起動します。