3.3. サービス提供証明書のシークレットによるサービストラフィックのセキュリティー保護
3.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
3.3.2. サービス証明書の追加
サービスとの通信のセキュリティーを保護するには、サービスと同じ namespace のシークレットに署名済みの提供証明書とキーのペアを生成します。
生成される証明書は、内部サービス DNS 名 <service.name>.<service.namespace>.svc
にのみ有効であり、内部通信用にのみ有効です。サービスがヘッドレスサービス (clusterIP
値が設定されていない) である場合、生成された証明書には *.<service.name>.<service.namespace>.svc
形式のワイルドカードのサブジェクトも含まれます。
生成された証明書にはヘッドレスサービスのワイルドカードサブジェクトが含まれるため、クライアントが個別の Pod を区別する必要がある場合はサービス CA を使用しないでください。この場合は、以下のようになります。
- 別の CA を使用して個別の TLS 証明書を生成します。
- サービス CA は、個々の Pod に送信される接続に関する信頼される CA として許可することはできず、他の Pod がこの権限を借用することはできません。これらの接続は、個別の TLS 証明書の生成に使用されている CA を信頼するように設定される必要があります。
前提条件
- サービスが定義されていること。
手順
サービスに
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
たとえば、以下のコマンドを使用してサービス
test1
にアノテーションを付けます。$ oc annotate service test1 service.beta.openshift.io/serving-cert-secret-name=test1
アノテーションが存在することを確認するためにサービスを検査します。
$ 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 ...
-
クラスターがサービスのシークレットを生成した後に、
Pod
仕様がこれをマウントでき、Pod はシークレットが利用可能になった後にこれを実行できます。
関連情報
- サービス証明書を使用して、reencrypt TLS 終端を使用してセキュアなルートを設定できます。詳細は、カスタム証明書を使用した re-encrypt ルートの作成 を参照してください。
3.3.3. サービス CA バンドルの設定マップへの追加
Pod は、service.beta.openshift.io/inject-cabundle=true
のアノテーションの付いた ConfigMap
オブジェクトをマウントしてサービス CA 証明書にアクセスできます。アノテーションが付けられると、クラスターはサービス CA 証明書を設定マップの service-ca.crt
キーに自動的に挿入します。この CA 証明書にアクセスできると、TLS クライアントはサービス提供証明書を使用してサービスへの接続を検証できます。
このアノテーションが設定マップに追加されると、その中に含まれるすべての既存データが削除されます。service-ca.crt
を組み込む設定マップとしては、Pod の設定の保存先と同じ設定マップではなく、別の設定マップを使用することが推奨されます。
手順
設定マップに
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
設定マップを表示して、サービス 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. サービス CA バンドルの API サービスへの追加
APIService
オブジェクトに service.beta.openshift.io/inject-cabundle=true
のアノテーションを付け、その spec.caBundle
フィールドにサービス CA バンドルを設定できます。これにより、Kubernetes API サーバーはターゲットに設定されたエンドポイントのセキュリティーを保護するために使用されるサービス CA 証明書を検証することができます。
手順
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
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 バンドルのカスタムリソース定義への追加
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 バンドルを挿入することは役に立ちます。
手順
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
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 バンドルの変更用 Webhook 設定への追加
MutatingWebhookConfiguration
オブジェクトに service.beta.openshift.io/inject-cabundle=true
のアノテーションを付け、各 Webhook の clientConfig.caBundle
フィールドにサービス CA バンドルを設定できます。これにより、Kubernetes API サーバーはターゲットに設定されたエンドポイントのセキュリティーを保護するために使用されるサービス CA 証明書を検証することができます。
異なる Webhook に異なる CA バンドルを指定する必要がある受付 Webhook 設定にはこのアノテーションを設定しないでください。これを実行する場合、サービス CA バンドルはすべての Webhook に挿入されます。
手順
変更用 Webhook 設定に
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>
を、アノテーションを付ける変更用 Webhook 設定の名前に置き換えます。
たとえば、以下のコマンドを使用して変更用 webhook 設定
test1
にアノテーションを付けます。$ oc annotate mutatingwebhookconfigurations test1 service.beta.openshift.io/inject-cabundle=true
変更用 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> ...
3.3.7. サービス CA バンドルの変更用 webhook 設定への追加
ValidatingWebhookConfiguration
オブジェクトに service.beta.openshift.io/inject-cabundle=true
のアノテーションを付け、各 Webhook の clientConfig.caBundle
フィールドにサービス CA バンドルを設定できます。これにより、Kubernetes API サーバーはターゲットに設定されたエンドポイントのセキュリティーを保護するために使用されるサービス CA 証明書を検証することができます。
異なる Webhook に異なる CA バンドルを指定する必要がある受付 Webhook 設定にはこのアノテーションを設定しないでください。これを実行する場合、サービス CA バンドルはすべての Webhook に挿入されます。
手順
検証用 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
検証用 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> ...
3.3.8. 生成されたサービス証明書の手動によるローテーション
関連付けられたシークレットを削除することにより、サービス証明書をローテーションできます。シークレットを削除すると、新規のシークレットが自動的に作成され、新規証明書が作成されます。
前提条件
- 証明書とキーのペアを含むシークレットがサービス用に生成されていること。
手順
証明書を含むシークレットを確認するためにサービスを検査します。これは、以下に示すように
serving-cert-secret-name
アノテーションにあります。$ oc describe service <service_name>
出力例
... service.beta.openshift.io/serving-cert-secret-name: <secret> ...
サービスの生成されたシークレットを削除します。このプロセスで、シークレットが自動的に再作成されます。
$ oc delete secret <secret> 1
- 1
<secret>
を、直前の手順のシークレットの名前に置き換えます。
新規シークレットを取得し、
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 で発行されるサービス提供証明書を使用できるようになります。
前提条件
- クラスター管理者としてログインしている必要があります。
手順
以下のコマンドを使用して、現在のサービス CA 証明書の有効期限を表示します。
$ oc get secrets/signing-key -n openshift-service-ca \ -o template='{{index .data "tls.crt"}}' \ | base64 --decode \ | openssl x509 -noout -enddate
サービス CA を手動でローテーションします。このプロセスは、新規サービス証明書に署名するために使用される新規サービス CA を生成します。
$ oc delete secret/signing-key -n openshift-service-ca
新規証明書をすべてのサービスに適用するには、クラスター内のすべての 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 は削除後に自動的に再起動します。