Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

第11章 証明書の再デプロイ

11.1. 概要

OpenShift Container Platform は、以下のコンポーネントで証明書を使用してセキュアな接続を提供します。

  • マスター (API サーバーとコントローラー)
  • etcd
  • ノード
  • レジストリー
  • ルーター

インストーラーによって提供される Ansible Playbook を使用すると、クラスター証明書の有効期限を自動的にチェックできます。これらの証明書を自動的にバックアップしたり、再デプロイしたりするための Playbook も提供されます。これらの Playbook を使用すると、一般的な証明書エラーを修正できます。

証明書の再デプロイのユースケースとして以下が考えられます。

  • インストーラーによって誤ったホスト名が検出され、そのことがすぐに判明しなかった。
  • 証明書の有効期限が切れており、証明書を更新する必要がある。
  • 新しい CA があり、その CA を代わりに使用する証明書を作成する。

11.2. 証明書の有効期限のチェック

インストーラーを使用して、設定可能な日数内に有効期限が切れる証明書に関する警告やすでに有効期限が切れた証明書に関する通知を受け取ることができます。証明書の有効期限 Playbook では、Ansible の openshift_certificate_expiry ロールが使用されます。

ロールによって検査される証明書には、以下が含まれます。

  • マスターおよびノードサービス証明書
  • etcd シークレットのルーターおよびレジストリーサービス証明書
  • マスター、ノード、ルーター、レジストリー、および cluster-admin ユーザーの kubeconfig ファイル
  • etcd 証明書 (組み込み証明書を含む)

11.2.1. ロールの変数

openshift_certificate_expiry ロールは、以下の変数を使用します。

表11.1 コア変数

変数名デフォルト値説明

openshift_certificate_expiry_config_base

/etc/origin

OpenShift Container Platform 基本設定ディレクトリーです。

openshift_certificate_expiry_warning_days

30

現在を起点として指定された日数内に有効期限が切れる証明書にフラグを付けます。

openshift_certificate_expiry_show_all

no

正常な (期限切れや警告のない) 証明書を結果に組み込みます。

表11.2 オプションの変数

変数名デフォルト値説明

openshift_certificate_expiry_generate_html_report

no

有効期限切れのチェック結果に関する HTML レポートを生成します。

openshift_certificate_expiry_html_report_path

/tmp/cert-expiry-report.html

HTML レポートを保存するための完全パスです。

openshift_certificate_expiry_save_json_results

no

有効期限のチェック結果を JSON ファイルとして保存します。

openshift_certificate_expiry_json_results_path

/tmp/cert-expiry-report.json

JSON レポートを保存するための完全パスです。

11.2.2. 証明書の有効期限 Playbook の実行

OpenShift Container Platform インストーラーは、openshift_certificate_expiry ロールのさまざまな設定セットを使用して証明書の有効期限 Playbook のサンプル一式を提供します。

これらの Playbook は、クラスターを表す インベントリーファイルと一緒に使用する必要があります。最適な結果を得るには、ansible-playbook-v オプションを指定して実行します。

easy-mode.yaml のサンプル Playbook を使用すると、ロールアウトを仕様に合わせて調整する前に試すことができます。この Playbook は以下を実行します。

  • JSON レポートと定型化された HTML レポートを /tmp/ に生成します。
  • ほぼ常に結果が得られるように警告期間を長い期間に設定します。
  • すべての証明書 (正常であるかどうかを問わず) を結果に組み込みます。

easy-mode.yaml Playbook

- name: Check cert expirys
  hosts: nodes:masters:etcd
  become: yes
  gather_facts: no
  vars:
    openshift_certificate_expiry_warning_days: 1500
    openshift_certificate_expiry_save_json_results: yes
    openshift_certificate_expiry_generate_html_report: yes
    openshift_certificate_expiry_show_all: yes
  roles:
    - role: openshift_certificate_expiry

easy-mode.yaml Playbook を実行するには、以下を実行します。

$ ansible-playbook -v -i <inventory_file> \
    /usr/share/ansible/openshift-ansible/playbooks/openshift-checks/certificate_expiry/easy-mode.yaml
他のサンプル Playbook

その他のサンプル Playbook も /usr/share/ansible/openshift-ansible/playbooks/certificate_expiry/ ディレクトリーから直接実行できます。

表11.3 他のサンプル Playbook

ファイル名使用法

default.yaml

openshift_certificate_expiry ロールのデフォルトの動作を生成します。

html_and_json_default_paths.yaml

HTML および JSON アーティファクトをデフォルトのパスに生成します。

longer_warning_period.yaml

有効期限切れの警告期間を 1500 日に変更します。

longer-warning-period-json-results.yaml

有効期限切れの警告期間を 1500 日に変更し、結果を JSON ファイルとして保存します。

これらのサンプル Playbook を実行するには、以下を実行します。

$ ansible-playbook -v -i <inventory_file> \
    /usr/share/ansible/openshift-ansible/playbooks/openshift-checks/certificate_expiry/<playbook>

11.2.3. 出力形式

上述のように、チェックレポートは 2 つの形式で出力できます。機械の解析に適した JSON 形式と簡単にスキミングできる定型化された HTML ページを使用できます。

HTML レポート

インストーラーには、HTML レポートのサンプルが付属しています。以下のファイルをブラウザーで開いて表示できます。

/usr/share/ansible/openshift-ansible/roles/openshift_certificate_expiry/examples/cert-expiry-report.html

JSON レポート

保存された JSON の結果には、datasummary の 2 つの最上位レベルのキーがあります。

data キーは、検証された各ホストの名前がキーとして、該当するホストごとに特定された証明書の確認結果が値として含まれるハッシュです。

summary キーは、以下の条件に当てはまる証明書の合計数をまとめたハッシュです。

  • クラスター全体で検査済み
  • 問題なし
  • 設定された警告期間内に有効期限が切れる
  • すでに有効期限が切れている

完全な JSON レポートのサンプルについては、/usr/share/ansible/openshift-ansible/roles/openshift_certificate_expiry/examples/cert-expiry-report.json を参照してください。

JSON データのサマリーでは、さまざまなコマンドラインツールを使用して警告や有効期限を簡単にチェックできます。たとえば、grep を使用して summary という語を検索し、一致した箇所の後ろの 2 行を出力できます (-A2)。

$ grep -A2 summary /tmp/cert-expiry-report.json
    "summary": {
        "warning": 16,
        "expired": 0

また、jq ツールが使用可能な場合は、このツールを使用して特定の値を選択できます。以下の最初の 2 つの例は、warning または expired のいずれかの値を選択する方法を示しています。3 つ目の例は、両方の値を一度に選択する方法を示しています。

$ jq '.summary.warning' /tmp/cert-expiry-report.json
16

$ jq '.summary.expired' /tmp/cert-expiry-report.json
0

$ jq '.summary.warning,.summary.expired' /tmp/cert-expiry-report.json
16
0

11.3. 証明書の再デプロイ

該当するすべてのホストにマスター、etcd、ノード、レジストリーまたはルーター証明書を再デプロイするには、以下の Playbook を使用します。現在の CA を使用してこれらすべての証明書を一度に再デプロイすることも、特定のコンポーネント用の証明書のみを再デプロイすることも、新しく生成された CA またはカスタム CA 自体を再デプロイすることもできます。

証明書の有効期限 Playbook と同様に、これらの Playbook はクラスターを表すインベントリーファイルを使用して実行する必要があります。

とくにインベントリーでは、すべてのホスト名と IP アドレスが現在のクラスター設定に一致するように、以下の変数でそれらを指定するか、または上書きする必要があります。

  • openshift_hostname
  • openshift_public_hostname
  • openshift_ip
  • openshift_public_ip
  • openshift_master_cluster_hostname
  • openshift_master_cluster_public_hostname

以下のコマンドを実行すると、必要な Playbook が利用できるようになります。

# yum install atomic-openshift-utils
注記

再デプロイ中に自動生成された証明書の有効性 (有効期限が切れるまでの日数) も Ansible で設定できます。「証明書の有効性の設定」を参照してください。

注記

OpenShift Container Platform CA および etcd 証明書の有効期限は 5 年です。署名付きの OpenShift Container Platform 証明書の有効期限は 2 年です。

11.3.1. 現行の OpenShift Container Platform および etcd CA を使用したすべての証明書の再デプロイ

redeploy-certificates.yml Playbook は、OpenShift Container Platform CA 証明書を再生成しません。新しいマスター 、etcd、ノード、レジストリー、およびルーター証明書は、新規の証明書に署名するために現在の CA 証明書を使用して作成されます。

これには、以下の順次の再起動も伴います。

  • etcd
  • マスターサービス
  • ノードサービス

現行の OpenShift Container Platform CA を使用してマスター、etcd、およびノード証明書を再デプロイするには、この Playbook を実行し、インベントリーファイルを指定します。

$ ansible-playbook -i <inventory_file> \
    /usr/share/ansible/openshift-ansible/playbooks/redeploy-certificates.yml

11.3.2. 新規またはカスタムの OpenShift Container Platform CA の再デプロイ

openshift-master/redeploy-openshift-ca.yml Playbook は、新規の CA 証明書を生成し、クライアントの kubeconfig ファイルとノードの信頼できる CA のデータベース (CA-trust) を含むすべてのコンポーネントに更新されたバンドルを配布することによって OpenShift Container Platform CA 証明書を再デプロイします。

これには、以下の順次の再起動も伴います。

  • マスターサービス
  • ノードサービス
  • Docker

さらに、証明書を再デプロイする際には、OpenShift Container Platform によって生成される CA を使用する代わりに、カスタム CA 証明書を指定することもできます。

マスターサービスが再起動すると、レジストリーとルーターは、再デプロイされなくてもマスターと引き続き通信できます。これは、マスターの提供証明書が同一であり、レジストリーとルーターの CA が依然として有効であるためです。

新たに生成される CA またはカスタム CA を再デプロイするには、以下を実行します。

  1. オプションで、カスタム CA を指定します。カスタム CA パラメーター openshift_master_ca_certificate の一部として指定する certfile には、OpenShift Container Platform 証明書に署名する単一証明書のみが含まれる必要があります。チェーンに中間証明書が含まれる場合、それらを別のファイルにバンドルする必要があります。

    1. 中間証明書なしで CA を指定するには、インベントリーファイルに以下の変数を指定します。

      # Configure custom ca certificate
      # NOTE: CA certificate will not be replaced with existing clusters.
      # This option may only be specified when creating a new cluster or
      # when redeploying cluster certificates with the redeploy-certificates
      # playbook.
      openshift_master_ca_certificate={'certfile': '</path/to/ca.crt>', 'keyfile': '</path/to/ca.key>'}
    2. 中間 CA によって発行された CA 証明書を指定するには、以下を実行します。

      1. CA の中間およびルート証明書の詳細チェーンが含まれるバンドルされた証明書を作成します。

        # cat intermediate/certs/<intermediate.cert.pem> \
              certs/ca.cert.pem >> intermediate/certs/ca-chain.cert.pem
      2. 以下の変数をインベントリーファイルに設定します。

        # Configure custom ca certificate
        # NOTE: CA certificate will not be replaced with existing clusters.
        # This option may only be specified when creating a new cluster or
        # when redeploying cluster certificates with the redeploy-certificates
        # playbook.
        openshift_master_ca_certificate={'certfile': '</path/to/ca.crt>', 'keyfile': '</path/to/ca.key>'}
        openshift_additional_ca=intermediate/certs/ca-chain.cert.pem
  2. openshift-master/redeploy-openshift-ca.yml Playbook を実行し、インベントリーファイルを指定します。

    $ ansible-playbook -i <inventory_file> \
        /usr/share/ansible/openshift-ansible/playbooks/openshift-master/redeploy-openshift-ca.yml

新規の OpenShift Container Platform CA が導入されている場合、新規の CA によって署名された証明書をすべてのコンポーネントに再デプロイする必要がある場合にはいつでも openshift-master/redeploy-certificates.yml Playbook を使用できます。

11.3.3. 新規 etcd CA の再デプロイ

openshift-etcd/redeploy-ca.yml Playbook は、新規 CA 証明書を生成し、すべての etcd ピアとマスタークライアントに更新したバンドルを配布することによって etcd CA 証明書を再デプロイします。

これには、以下の順次の再起動も伴います。

  • etcd
  • マスターサービス

新たに生成された etcd CA を再デプロイするには、以下を実行します。

  1. openshift-etcd/redeploy-ca.yml Playbook を実行し、インベントリーファイルを指定します。

    $ ansible-playbook -i <inventory_file> \
        /usr/share/ansible/openshift-ansible/playbooks/openshift-etcd/redeploy-ca.yml

新規 etcd CA が導入されている場合、新規 CA によって署名された証明書を etcd ピアとマスタークライアントに再デプロイする必要がある場合にはいつでも openshift-etcd/redeploy-certificates.yml Playbook を使用できます。または、redeploy-certificates.yml Playbook を使用して、etcd ピアとマスタークライアントに加えて、OpenShift Container Platform コンポーネントの証明書も再デプロイできます。

11.3.4. マスター証明書のみの再デプロイ

openshift-master/redeploy-certificates.yml Playbook は、マスター証明書のみを再デプロイします。これには、マスターサービスの順次の再起動も伴います。

マスター証明書を再デプロイするには、この Playbook を実行し、インベントリーファイルを指定します。

$ ansible-playbook -i <inventory_file> \
    /usr/share/ansible/openshift-ansible/playbooks/openshift-master/redeploy-certificates.yml
重要

この Playbook を実行した後に、サービス提供証明書を含む既存のシークレットを削除するか、またはアノテーションを削除し、適切なサービスに再度追加して、サービス提供証明書またはキーペアを再生成する必要があります。

11.3.5. etcd 証明書のみの再デプロイ

openshift-etcd/redeploy-certificates.yml Playbook は、マスタークライアント証明書を含む etcd 証明書のみを再デプロイします。

これには、以下の順次の再起動も伴います。

  • etcd
  • マスターサービス

etcd 証明書を再デプロイするには、この Playbook を実行し、インベントリーファイルを指定します。

$ ansible-playbook -i <inventory_file> \
    /usr/share/ansible/openshift-ansible/playbooks/openshift-etcd/redeploy-certificates.yml

11.3.6. ノード証明書のみの再デプロイ

openshift-node/redeploy-certificates.yml Playbook は、ノード証明書のみを再デプロイします。これには、ノードサービスの順次の再起動も伴います。

ノード証明書を再デプロイするには、この Playbook を実行し、インベントリーファイルを指定します

$ ansible-playbook -i <inventory_file> \
    /usr/share/ansible/openshift-ansible/playbooks/openshift-node/redeploy-certificates.yml

11.3.7. レジストリー証明書またはルーター証明書のみの再デプロイ

openshift-hosted/redeploy-registry-certificates.yml Playbook と openshift-hosted/redeploy-router-certificates.yml Playbook は、インストーラーによって作成されたレジストリー証明書とルーター証明書を置き換えます。レジストリーとルーターでカスタム証明書が使用されている場合にそれらを手動で置き換えるには、「 カスタムのレジストリー証明書またはルーター証明書の再デプロイ」を参照してください。

11.3.7.1. レジストリー証明書のみの再デプロイ

レジストリー証明書を再デプロイするには、以下の Playbook を実行し、インベントリーファイルを指定します。

$ ansible-playbook -i <inventory_file> \
    /usr/share/ansible/openshift-ansible/playbooks/openshift-hosted/redeploy-registry-certificates.yml

11.3.7.2. ルーター証明書のみの再デプロイ

ルーター証明書を再デプロイするには、以下の Playbook を実行し、インベントリーファイルを指定します。

$ ansible-playbook -i <inventory_file> \
    /usr/share/ansible/openshift-ansible/playbooks/openshift-hosted/redeploy-router-certificates.yml

11.3.8. カスタムのレジストリー証明書またはルーター証明書の再デプロイ

再デプロイされた CA が原因でノードが退避させられると、レジストリー Pod とルーター Pod が再起動されます。レジストリー証明書とルーター証明書を新規 CA と共に再デプロイしなかった場合は、それらが古い証明書を使用してマスターにアクセスできなくなるため、停止状態が生じることがあります。

証明書を再デプロイする Playbook は、カスタムのレジストリー証明書またはルーター証明書を再デプロイできません。この問題を解決するため、レジストリー証明書とルーター証明書を手動で再デプロイする必要があります。

11.3.8.1. 手動によるレジストリー証明書の再デプロイ

レジストリー証明書を手動で再デプロイするには、新規レジストリー証明書を registry-certificates という名前のシークレットに追加してから、レジストリーを再デプロイする必要があります。

  1. これ以降の手順では default プロジェクトに切り替えます。

    $ oc project default
  2. 最初にレジストリーを OpenShift Container Platform 3.1 以前で作成した場合は、環境変数が証明書を保存するために使用されている場合があります (この方法は現在は推奨されていません。代わりにシークレットをご使用ください)。

    1. 以下のコマンドを実行し、OPENSHIFT_CA_DATAOPENSHIFT_CERT_DATA、および OPENSHIFT_KEY_DATA 環境変数を探します。

      $ oc env dc/docker-registry --list
    2. これらの環境変数が存在しない場合は、この手順を省略します。存在する場合は、以下の ClusterRoleBinding を作成します。

      $ cat <<EOF |
      apiVersion: v1
      groupNames: null
      kind: ClusterRoleBinding
      metadata:
        creationTimestamp: null
        name: registry-registry-role
      roleRef:
        kind: ClusterRole
        name: system:registry
      subjects:
      - kind: ServiceAccount
        name: registry
        namespace: default
      userNames:
      - system:serviceaccount:default:registry
      EOF
      oc create -f -

      次に、以下のコマンドを実行して環境変数を削除します。

      $ oc env dc/docker-registry OPENSHIFT_CA_DATA- OPENSHIFT_CERT_DATA- OPENSHIFT_KEY_DATA- OPENSHIFT_MASTER-
  3. 以下の環境変数をローカルに設定し、後で使用するコマンドを単純化します。

    $ REGISTRY_IP=`oc get service docker-registry -o jsonpath='{.spec.clusterIP}'`
    $ REGISTRY_HOSTNAME=`oc get route/docker-registry -o jsonpath='{.spec.host}'`
  4. 新規レジストリー証明書を作成します。

    $ oc adm ca create-server-cert \
        --signer-cert=/etc/origin/master/ca.crt \
        --signer-key=/etc/origin/master/ca.key \
        --hostnames=$REGISTRY_IP,docker-registry.default.svc,docker-registry.default.svc.cluster.local,$REGISTRY_HOSTNAME \
        --cert=/etc/origin/master/registry.crt \
        --key=/etc/origin/master/registry.key \
        --signer-serial=/etc/origin/master/ca.serial.txt

    Ansible ホストインベントリーファイル (デフォルトで /etc/ansible/hosts) に最初に一覧表示されているマスターから oc adm コマンドを実行します。

  5. registry-certificates シークレットを新規レジストリー証明書で更新します。

    $ oc create secret generic registry-certificates \
        --from-file=/etc/origin/master/registry.crt,/etc/origin/master/registry.key \
        -o json --dry-run | oc replace -f -
  6. レジストリーを再デプロイします。

    $ oc rollout latest dc/docker-registry

11.3.8.2. 手動によるルーター証明書の再デプロイ

ルーターの初回デプロイ時に、アノテーションがサービス提供証明書シークレットを自動的に作成するルーターのサービスに追加されます。

ルーター証明書を手動で再デプロイするため、そのサービス提供証明書の再作成をトリガーできます。これは、シークレットを削除し、アノテーションを削除してから router サービスに再度追加し、ルーターを再デプロイして実行できます。

  1. これ以降の手順では default プロジェクトに切り替えます。

    $ oc project default
  2. 最初にレジストリーを OpenShift Container Platform 3.1 以前で作成した場合は、環境変数が証明書を保存するために使用されている場合があります (この方法は現在は推奨されていません。代わりにサービス提供証明書シークレットをご使用ください)。

    1. 以下のコマンドを実行し、OPENSHIFT_CA_DATAOPENSHIFT_CERT_DATA、および OPENSHIFT_KEY_DATA 環境変数を探します。

      $ oc env dc/router --list
    2. それらの変数が存在する場合は、以下の ClusterRoleBinding を作成します。

      $ cat <<EOF |
      apiVersion: v1
      groupNames: null
      kind: ClusterRoleBinding
      metadata:
        creationTimestamp: null
        name: router-router-role
      roleRef:
        kind: ClusterRole
        name: system:router
      subjects:
      - kind: ServiceAccount
        name: router
        namespace: default
      userNames:
      - system:serviceaccount:default:router
      EOF
      oc create -f -
    3. それらの変数が存在する場合は、以下のコマンドを実行してそれらを削除します。

      $ oc env dc/router OPENSHIFT_CA_DATA- OPENSHIFT_CERT_DATA- OPENSHIFT_KEY_DATA- OPENSHIFT_MASTER-
  3. 証明書を取得します。

    • 外部の認証局 (CA) を使用して証明書に署名する場合、以下の内部プロセスに従って、新規の証明書を作成し、これを OpenShift Container Platform に指定します。
    • 内部 OpenShift Container Platform CA を使用して証明書に署名する場合は、以下のコマンドを実行します。

      重要

      以下のコマンドは、内部で署名される証明書を生成します。これは、OpenShift Container Platform CA を信頼するクライアントによってのみ信頼されます。

      $ cd /root
      $ mkdir cert ; cd cert
      $ oc adm ca create-server-cert \
          --signer-cert=/etc/origin/master/ca.crt \
          --signer-key=/etc/origin/master/ca.key \
          --signer-serial=/etc/origin/master/ca.serial.txt \
          --hostnames='*.hostnames.for.the.certificate' \
          --cert=router.crt \
          --key=router.key \

      これらのコマンドは以下のファイルを生成します。

      • router.crt という名前の新規の証明書
      • 署名する CA 証明書チェーン /etc/origin/master/ca.crt のコピーです。このチェーンには中間の CA を使用する場合に複数の証明書が含まれる場合があります。
      • router.key という名前の対応するプライベートキー。
  4. 生成された証明書を連結する新規ファイルを作成します。

    $ cat router.crt /etc/origin/master/ca.crt router.key > router.pem
  5. 新規シークレットを生成する前に、現在のシークレットをバックアップします。

    $ oc export secret router-certs > ~/old-router-certs-secret.yaml
  6. 新規の証明書およびキーを保持する新規シークレットを作成し、既存のシークレットの内容を置き換えます。

    $ oc create secret tls router-certs --cert=router.pem \ 1
        --key=router.key -o json --dry-run | \
        oc replace -f -
    1
    router.pem は、生成した証明書の連結を含むファイルです。
  7. 以下のアノテーションを router サービスから削除します。

    $ oc annotate service router \
        service.alpha.openshift.io/serving-cert-secret-name- \
        service.alpha.openshift.io/serving-cert-signed-by-
  8. アノテーションを再度追加します。

    $ oc annotate service router \
        service.alpha.openshift.io/serving-cert-secret-name=router-certs
  9. ルーターを再デプロイします。

    $ oc rollout latest dc/router