8.3. サービス提供証明書のシークレットによるサービストラフィックのセキュリティー保護
8.3.1. サービス提供証明書について
サービス提供証明書は、暗号化を必要とする複雑なミドルウェアアプリケーションをサポートすることが意図されています。これらの証明書は、TLS Web サーバー証明書として発行されます。
service-ca
コントローラーは、サービス証明書を生成するために x509.SHA256WithRSA
署名アルゴリズムを使用します。
生成される証明書およびキーは PEM 形式のもので、作成されたシークレット内の tls.crt
および tls.key
にそれぞれ保存されます。証明書およびキーは、有効期間に近づくと自動的に置き換えられます。
サービス証明書を発行するサービス CA 証明書は 26 ヵ月間有効であり、有効期間が 6 ヵ月未満になると自動的にローテーションされます。ローテーション後も、直前のサービス 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
8.3.2. サービス証明書の追加
サービスとの通信のセキュリティーを保護するには、サービスと同じ namespace のシークレットに署名済みの提供証明書とキーのペアを生成します。
生成される証明書は、内部サービス DNS 名 <service.name>.<service.namespace>.svc
にのみ有効であり、内部通信用にのみ有効です。
前提条件
- サービスが定義されていること。
手順
サービスに
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
たとえば、以下のコマンドを使用してサービス
foo
にアノテーションを付けます。$ oc annotate service foo service.beta.openshift.io/serving-cert-secret-name=foo
アノテーションが存在することを確認するためにサービスを検査します。
$ 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 ...
- クラスターがサービスのシークレットを生成した後に、 PodSpec がこれをマウントでき、Pod はシークレットが利用可能になった後にこれを実行できます。
8.3.3. サービス証明書の ConfigMap への追加
Pod は、service.beta.openshift.io/inject-cabundle=true
のアノテーションの付いた ConfigMap をマウントしてサービス CA 証明書にアクセスできます。アノテーションが付けられると、クラスターはサービス CA 証明書を ConfigMap のservice-ca.crt
キーに自動的に挿入します。この CA 証明書にアクセスできると、TLS クライアントはサービス提供証明書を使用してサービスへの接続を検証できます。
このアノテーションが ConfigMap に追加されると、その中に含まれるすべての既存データが削除されます。service-ca.crt
を組み込む ConfigMap としては、Pod の設定の保存先と同じ ConfigMap ではなく、別の ConfigMap を使用することが推奨されます。
手順
ConfigMap に
service.beta.openshift.io/inject-cabundle=true
のアノテーションを付けます。$ oc annotate configmap <configmap-name> \1 service.beta.openshift.io/inject-cabundle=true
- 1
<configmap-name>
を、アノテーションを付ける ConfigMap の名前に置き換えます。
注記volumeMount の
service-ca.crt
キーを明示的に参照することにより、ConfigMap が CA バンドルと共に挿入されるまで、Pod を起動できなくなります。たとえば、ConfigMap
foo
にアノテーションを付けるには、以下のコマンドを使用します。$ oc annotate configmap foo service.beta.openshift.io/inject-cabundle=true
証明書が生成されていることを確認するために ConfigMap を表示します。これは、YAML 出力の
service-ca.crt
として表示されます。$ oc get configmap <configmap-name> -o yaml apiVersion: v1 data: service-ca.crt: | -----BEGIN CERTIFICATE----- ...
8.3.4. 生成されたサービス証明書の手動によるローテーション
関連付けられたシークレットを削除することにより、サービス証明書をローテーションできます。シークレットを削除すると、新規のシークレットが自動的に作成され、新規証明書が作成されます。
前提条件
- 証明書とキーのペアを含むシークレットがサービス用に生成されていること。
手順
証明書を含むシークレットを確認するためにサービスを検査します。これは、以下に示すように
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
8.3.5. サービス CA 証明書の手動によるローテーション
サービス CA は 26 ヵ月間有効で、有効期間が 6 ヵ月未満になると自動的に更新されます。
必要に応じて、以下の手順でサービス CA を手動で更新することができます。
手動でローテーションされるサービス CA は、直前のサービス CA で信頼を維持しません。クラスターの Pod が再起動するまでサービスが一時的に中断する可能性があります。これにより、Pod が新規サービス CA で発行されるサービス提供証明書を使用できるようになります。
前提条件
- クラスター管理者としてログインしている必要があります。
手順
以下のコマンドを使用して、現在のサービス CA 証明書の有効期限を表示します。
$ oc get secrets/signing-key -n openshift-service-ca \ -o template='{{index .data "tls.crt"}}' \ | base64 -d \ | 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 は削除後に自動的に再起動します。