trust-manager による Kubernetes での公開信頼の管理
最終検証: 2023年6月19日
このチュートリアルでは、trust-manager を使用して、Kubernetes クラスタ内に公開的に信頼された認証局 (CA) 証明書を配布する方法を説明します。配布後、以下についても説明します。
- 信頼バンドルが変更されたときにアプリケーションを自動的に再読み込みする方法
- 配布された CA バンドルを使用するようにアプリケーションを強制する方法
次に、シンプルなcurl
ポッドを使用して、信頼されたCAバンドル
を自動的にマウントする方法を示します。これにより、curlを手動で構成する必要なく使用できます。これは、アプリケーションが信頼されたCA証明書バンドルを使用するために追加の設定を必要としない方法を模倣しています。
このチュートリアルでは、変更の影響範囲をteam-a
名前空間のみに限定します。これらの機能を最大限に活用するには、この制限を解除する必要があります。
注: 提供されるすべてのリソースはデモンストレーション用であり、本番環境で使用する前に適切にレビューする必要があります。
前提条件
💻 ソフトウェア
- kubectl: Kubernetesクラスターを構成するためのKubernetesコマンドラインツール。
- helm: Kubernetes用のパッケージマネージャー。
- yq: 便利なカラーリングを備えたYAMLを解析するためのコマンドラインツール。
パブリックCA信頼の配布
まず、trust-managerをセットアップし、パブリックCAをデモ名前空間team-a
に配布しましょう。
アプリケーションとバンドルのセットアップ
-
こちらの手順に従ってtrust-managerをインストールします。
-
パブリックCA証明書のみを含む最初の
バンドル
リソースを作成しますapiVersion: trust.cert-manager.io/v1alpha1kind: Bundlemetadata:name: public-bundlespec:sources:- useDefaultCAs: truetarget:configMap:key: "ca-certificates.crt"namespaceSelector:matchLabels:trust: enabledkubectl apply -f - <<EOFapiVersion: trust.cert-manager.io/v1alpha1kind: Bundlemetadata:name: public-bundlespec:sources:- useDefaultCAs: truetarget:configMap:key: "ca-certificates.crt"namespaceSelector:matchLabels:trust: enabledEOF -
アプリケーションを実行する名前空間を作成しましょう
kubectl apply -f - <<EOFapiVersion: v1kind: Namespacemetadata:labels:trust: enabledname: team-aEOFこの名前空間には、
trust: enabled
というラベルが付いていることに注意してください。これは、バンドル
リソースのnamespaceSelector
基準に一致します。namespaceSelector:matchLabels:trust: enabled注: これは、前述のように、信頼バンドルの範囲を
team-a
名前空間のみに限定するためのものです。 -
trust-managerコントローラーがCAバンドルを名前空間に正しく伝播したことを確認します
kubectl get configmap -n team-a public-bundle -o yamlこの出力は非常に長くなるはずです。これは、使用するデフォルトのパブリックバンドルに多くのパブリックCAが含まれているためです。
自動使用によるアプリケーションへの信頼バンドルのマウント
信頼されたCAを使用するには、ほとんどのアプリケーションがca-certificates.crt
ファイルを見つけると予想されるデフォルトの場所にマウントします。このアプローチの利点は、コンテナ内のほとんどのアプリケーションコードがこのファイルをデフォルトで使用し、追加の設定を必要としないことです。さらに、/etc/ssl/certs
の上にマウントするため、コンテナのベースイメージから通常存在する、またはCIビルド中にプルインされた既存のCA証明書が削除されるという利点もあります。
警告: この例では、alpineおよび
curl
が信頼されたCAのソースとして使用する、よく知られた場所を1つ選択しました。これは使用できる唯一の場所ではないため、コンテナには他のデフォルトの場所がある場合があります。デフォルトのCAがどこにあるかを確認する場合は、paranoiaを使用して、構築されたコンテナイメージを調べることができます。
-
アプリケーションデプロイメントを適用します
apiVersion: apps/v1kind: Deploymentmetadata:labels:app: sleep-autoname: sleep-autonamespace: team-aspec:replicas: 1revisionHistoryLimit: 3selector:matchLabels:app: sleep-autostrategy: {}template:metadata:labels:app: sleep-autospec:containers:- command:- /bin/sh- -c- sleep 1dimage: quay.io/zenlab/curl:latestname: curlresources: {}volumeMounts:- mountPath: /etc/ssl/certs/name: ca-certificate-onlyreadOnly: truevolumes:- name: ca-certificate-onlyconfigMap:name: public-bundledefaultMode: 0644optional: falseitems:- key: ca-certificates.crtpath: ca-certificates.crtkubectl apply -f - <<EOFapiVersion: apps/v1kind: Deploymentmetadata:labels:app: sleep-autoname: sleep-autonamespace: team-aspec:replicas: 1revisionHistoryLimit: 3selector:matchLabels:app: sleep-autotemplate:metadata:labels:app: sleep-autospec:containers:- command:- /bin/sh- -c- sleep 1dimage: quay.io/zenlab/curl:latestname: curlvolumeMounts:- mountPath: /etc/ssl/certs/name: ca-certificate-onlyreadOnly: truevolumes:- name: ca-certificate-onlyconfigMap:name: public-bundledefaultMode: 0644optional: falseitems:- key: ca-certificates.crtpath: ca-certificates.crtEOF -
実行中のポッド内にシェルを作成します
kubectl exec -n team-a -ti $(kubectl get po -n team-a -l app=sleep-auto -o jsonpath='{.items[0].metadata.name}') -- /bin/sh -
/etc/ssl/certs/
の内容をリストして、信頼されたca-certificates.crt
のみが存在することを確認します。ls -ltr /etc/ssl/certs/出力は次のようになります
~ $ ls -ltr /etc/ssl/certs/total 0lrwxrwxrwx 1 root root 26 Apr 14 15:12 ca-certificates.crt -> ..data/ca-certificates.crt通常、このコンテナイメージでは、このディレクトリを上書きするボリュームがない場合、出力は次のようになります。
~ $ ls -ltr /etc/ssl/certs/total 608-rw-r--r-- 1 root root 214222 Apr 14 01:11 ca-certificates.crtlrwxrwxrwx 1 root root 52 Apr 14 01:11 ca-cert-vTrus_Root_CA.pem -> /usr/share/ca-certificates/mozilla/vTrus_Root_CA.crtlrwxrwxrwx 1 root root 56 Apr 14 01:11 ca-cert-vTrus_ECC_Root_CA.pem -> /usr/share/ca-certificates/mozilla/vTrus_ECC_Root_CA.crt...lrwxrwxrwx 1 root root 53 Apr 14 01:11 02265526.0 -> ca-cert-Entrust_Root_Certification_Authority_-_G2.pemlrwxrwxrwx 1 root root 31 Apr 14 01:11 002c0b4f.0 -> ca-cert-GlobalSign_Root_R46.pem -
既知のサイトにHTTPS呼び出しを行い、追加の
--cacert
フラグを渡すことなくcurl
が動作することを確認します。curl -v https://bbc.co.uk/news成功すると、次のような有効なTLS接続になります
* Trying 151.101.0.81:443...* Connected to bbc.co.uk (151.101.0.81) port 443 (#0)* ALPN: offers h2,http/1.1* TLSv1.3 (OUT), TLS handshake, Client hello (1):* CAfile: /etc/ssl/certs/ca-certificates.crt* CApath: none* TLSv1.3 (IN), TLS handshake, Server hello (2):* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):* TLSv1.3 (IN), TLS handshake, Certificate (11):* TLSv1.3 (IN), TLS handshake, CERT verify (15):* TLSv1.3 (IN), TLS handshake, Finished (20):* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):* TLSv1.3 (OUT), TLS handshake, Finished (20):* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256* ALPN: server accepted h2* Server certificate:* subject: C=GB; ST=London; L=London; O=BRITISH BROADCASTING CORPORATION; CN=www.bbc.com* start date: Mar 14 06:16:13 2023 GMT* expire date: Apr 14 06:16:12 2024 GMT* subjectAltName: host "bbc.co.uk" matched cert's "bbc.co.uk"* issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018* SSL certificate verify ok.
- コンテナを終了します:
exit
実際のアプリケーションの構成
上記の例に基づいて、KubernetesはデフォルトのCA証明書バンドルの上にマウントできます。CA証明書を取得するデフォルトの場所がわかっている場合は、これをアプリケーションで使用できます。
たとえば、Go
では、アプリケーションは、デフォルトのCA証明書ファイルの場所を指すSSL_CERT_FILE
またはSSL_CERT_DIR
で構成できます。
詳細についてはこちらを参照してください。また、さまざまなOSベースのデフォルトの場所については、こちらを確認してください。
// Possible certificate files; stop after finding one.var certFiles = []string{"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc."/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6"/etc/ssl/ca-bundle.pem", // OpenSUSE"/etc/pki/tls/cacert.pem", // OpenELEC"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7"/etc/ssl/cert.pem", // Alpine Linux}// Possible directories with certificate files; all will be read.var certDirectories = []string{"/etc/ssl/certs", // SLES10/SLES11, https://go.dokyumento.jp/issue/12139"/etc/pki/tls/certs", // Fedora/RHEL"/
Pythonを調べたところ、ssl
ライブラリは、信頼されたCAを検索するために、同じ2つの環境変数:SSL_CERT_DIR
および/SSL_CERT_FILE
を使用していることがわかりました。 ドキュメントおよびpython3
ランタイムからこれを確認できます
>>> import ssl>>> ssl.get_default_verify_paths()DefaultVerifyPaths(cafile=None, capath='/usr/lib/ssl/certs', openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/lib/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/lib/ssl/certs')
これは、ファイルにマウントされたCAと、次のいずれかのファイルが、Go
と同様に、すべてのPythonアプリケーションランタイムによって信頼されることを意味します。
- '/usr/lib/ssl/cert.pem'
- '/usr/lib/ssl/certs/*'
同様のことは、他の言語でも実現できます。
自動化と強制
これで、trust-managerのバンドルを手動でマウントしました。あなたはこう考えているかもしれません。
- CAバンドルが変更された場合、その変更をアプリケーションに反映させるにはどうすればよいですか?
- テナントからの変更を要求することなく、CAバンドルがクラスター内のすべてのアプリケーションにマウントされるようにするにはどうすればよいですか?
追加のオープンソースツールを使用して、これらの両方のシナリオに取り組みましょう。
CAバンドル変更のロールアウト
CAバンドルが変更されると、それらの変更はかなり迅速に名前空間に同期されます。この変更はコンテナにアタッチされたボリュームに反映されますが、ほとんどのアプリケーションはファイルシステムの変更を認識しません。一般的なアプローチは、kubectl rollout restart deployment <DEPLOY_NAME>
を使用して、クライアントアプリケーションのデプロイを再起動することです。サードパーティ製のオープンソースソフトウェアを使用して、このプロセスを自動化するオプションがあります。
Stakater Reloaderを使用すると、ConfigMap
またはSecret
が変更されるたびに、デプロイメントをリロードまたはロールアウトできます。したがって、バンドル
のターゲットが同期されるたびに、Reloaderコンポーネントはこの変更を検出し、それらのリソースをボリュームまたは環境変数としてマウントするアプリケーションをロールアウトできます。
ご注意ください アプリケーションコンテナにバンドルしたり、書き込んだりできる代替ソフトウェアがたくさんあります。それらは単にファイルシステムの変更を監視し、アプリケーションプロセスのリロードをトリガーするだけです。このようなアプローチには、コンテナイメージまたはコードの変更が必要であり、多くのテナントでは実装が難しい場合があります。ここでリローダーを使用する利点は、クラスターで実行されているすべてのアプリケーションに適用できる汎用的なソリューションであることです。
-
リローダーを続行すると、helmでインストールできます
helm repo add stakater https://stakater.github.io/stakater-chartshelm repo updatehelm install reloader stakater/reloader -n stakater-reloader --create-namespace --set fullnameOverride=reloader -
前のセクションの
sleep-auto
デプロイメントを再利用し、リロード機能を有効にするように構成できます。kubectl annotate deployment -n team-a sleep-auto reloader.stakater.com/auto="true"注意: リローダーツールを設定するための構成オプションはいくつかありますが、これは最も基本的な例にすぎません。詳細な例については、ドキュメントを参照してください。
-
別のターミナルで、アプリケーションのロールアウトを監視してください。
kubectl get po -n team-a -w -
この変更をテストするために、
Bundle
リソースを編集して、デフォルトのすべてのパブリックCA証明書を削除し、代わりに1つのCA証明書のみを提供するようにします。apiVersion: trust.cert-manager.io/v1alpha1kind: Bundlemetadata:name: public-bundlespec:sources:- inLine: |-----BEGIN CERTIFICATE-----MIIETjCCAzagAwIBAgINAe5fFp3/lzUrZGXWajANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEQMA4GA1UECxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFsU2lnbiBSb290IENBMB4XDTE4MDkxOTAwMDAwMFoXDTI4MDEyODEyMDAwMFowTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMJXaQeQZ4Ihb1wIO2hMoonv0FdhHFrYhy/EYCQ8eyip0EXyTLLkvhYIJG4VKrDIFHcGzdZNHr9SyjD4I9DCuul9e2FIYQebs7E4B3jAjhSdJqYi8fXvqWaN+JJ5U4nwbXPsnLJlkNc96wyOkmDoMVxu9bi9IEYMpJpij2aTv2y8gokeWdimFXN6x0FNx04Druci8unPvQu7/1PQDhBjPogiuuU6Y6FnOM3UEOIDrAtKeh6bJPkC4yYOlXy7kEkmho5TgmYHWyn3f/kRTvriBJ/K1AFUjRAjFhGV64l++td7dkmnq/X8ET75ti+w1s4FRpFqkD2m7pg5NxdsZphYIXAgMBAAGjggEiMIIBHjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUj/BLf6guRSSuTVD6Y5qL3uLdG7wwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290cjEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9yb290LmNybDBHBgNVHSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBACNw6c/ivvVZrpRCb8RDM6rNPzq5ZBfyYgZLSPFAiAYXof6r0V88xjPy847dHx0+zBpgmYILrMf8fpqHKqV9D6ZX7qw7aoXW3r1AY/itpsiIsBL89kHfDwmXHjjqU5++BfQ+6tOfUBJ2vgmLwgtIfR4uUfaNU9OrH0Abio7tfftPeVZwXwzTjhuzp3ANNyuXlava4BJrHEDOxcd+7cJiWOx37XMiwor1hkOIreoTbv3Y/kIvuX1erRjvlJDKPSerJpSZdcfL03v3ykzTr1EhkluEfSufFT90y1HonoMOFm8b50bOI7355KKL0jlrqnkckSziYSQtjipIcJDEHsXo4HA=-----END CERTIFICATE-----target:configMap:key: "ca-certificates.crt"namespaceSelector:matchLabels:trust: enabledkubectl apply -f - <<EOFapiVersion: trust.cert-manager.io/v1alpha1kind: Bundlemetadata:name: public-bundlespec:sources:- inLine: |-----BEGIN CERTIFICATE-----MIIETjCCAzagAwIBAgINAe5fFp3/lzUrZGXWajANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEQMA4GA1UECxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFsU2lnbiBSb290IENBMB4XDTE4MDkxOTAwMDAwMFoXDTI4MDEyODEyMDAwMFowTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMJXaQeQZ4Ihb1wIO2hMoonv0FdhHFrYhy/EYCQ8eyip0EXyTLLkvhYIJG4VKrDIFHcGzdZNHr9SyjD4I9DCuul9e2FIYQebs7E4B3jAjhSdJqYi8fXvqWaN+JJ5U4nwbXPsnLJlkNc96wyOkmDoMVxu9bi9IEYMpJpij2aTv2y8gokeWdimFXN6x0FNx04Druci8unPvQu7/1PQDhBjPogiuuU6Y6FnOM3UEOIDrAtKeh6bJPkC4yYOlXy7kEkmho5TgmYHWyn3f/kRTvriBJ/K1AFUjRAjFhGV64l++td7dkmnq/X8ET75ti+w1s4FRpFqkD2m7pg5NxdsZphYIXAgMBAAGjggEiMIIBHjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUj/BLf6guRSSuTVD6Y5qL3uLdG7wwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290cjEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9yb290LmNybDBHBgNVHSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBACNw6c/ivvVZrpRCb8RDM6rNPzq5ZBfyYgZLSPFAiAYXof6r0V88xjPy847dHx0+zBpgmYILrMf8fpqHKqV9D6ZX7qw7aoXW3r1AY/itpsiIsBL89kHfDwmXHjjqU5++BfQ+6tOfUBJ2vgmLwgtIfR4uUfaNU9OrH0Abio7tfftPeVZwXwzTjhuzp3ANNyuXlava4BJrHEDOxcd+7cJiWOx37XMiwor1hkOIreoTbv3Y/kIvuX1erRjvlJDKPSerJpSZdcfL03v3ykzTr1EhkluEfSufFT90y1HonoMOFm8b50bOI7355KKL0jlrqnkckSziYSQtjipIcJDEHsXo4HA=-----END CERTIFICATE-----target:configMap:key: "ca-certificates.crt"namespaceSelector:matchLabels:trust: enabledEOF別のターミナルで、アプリケーションのデプロイメントがすぐにロールアウトされるはずです。
-
新しいポッドが実行されたら、以下を使用して、適用したばかりの1つのCA証明書
ca-certificates.crt
ファイルのみがあることを確認します。kubectl exec -ti -n team-a $(kubectl get po -n team-a -l app=sleep-auto -o jsonpath='{.items[0].metadata.name}') -- cat /etc/ssl/certs/ca-certificates.crt正確にこの出力が得られるはずです。
-----BEGIN CERTIFICATE-----MIIETjCCAzagAwIBAgINAe5fFp3/lzUrZGXWajANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEQMA4GA1UECxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFsU2lnbiBSb290IENBMB4XDTE4MDkxOTAwMDAwMFoXDTI4MDEyODEyMDAwMFowTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMJXaQeQZ4Ihb1wIO2hMoonv0FdhHFrYhy/EYCQ8eyip0EXyTLLkvhYIJG4VKrDIFHcGzdZNHr9SyjD4I9DCuul9e2FIYQebs7E4B3jAjhSdJqYi8fXvqWaN+JJ5U4nwbXPsnLJlkNc96wyOkmDoMVxu9bi9IEYMpJpij2aTv2y8gokeWdimFXN6x0FNx04Druci8unPvQu7/1PQDhBjPogiuuU6Y6FnOM3UEOIDrAtKeh6bJPkC4yYOlXy7kEkmho5TgmYHWyn3f/kRTvriBJ/K1AFUjRAjFhGV64l++td7dkmnq/X8ET75ti+w1s4FRpFqkD2m7pg5NxdsZphYIXAgMBAAGjggEiMIIBHjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUj/BLf6guRSSuTVD6Y5qL3uLdG7wwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290cjEwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9yb290LmNybDBHBgNVHSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBACNw6c/ivvVZrpRCb8RDM6rNPzq5ZBfyYgZLSPFAiAYXof6r0V88xjPy847dHx0+zBpgmYILrMf8fpqHKqV9D6ZX7qw7aoXW3r1AY/itpsiIsBL89kHfDwmXHjjqU5++BfQ+6tOfUBJ2vgmLwgtIfR4uUfaNU9OrH0Abio7tfftPeVZwXwzTjhuzp3ANNyuXlava4BJrHEDOxcd+7cJiWOx37XMiwor1hkOIreoTbv3Y/kIvuX1erRjvlJDKPSerJpSZdcfL03v3ykzTr1EhkluEfSufFT90y1HonoMOFm8b50bOI7355KKL0jlrqnkckSziYSQtjipIcJDEHsXo4HA=-----END CERTIFICATE----- -
このCA証明書は、ウェブサイト
https://bbc.co.uk
の信頼性を検証するために使用できます。これは、そのコンテナからcurl
を使用して検証できます。kubectl exec -ti -n team-a $(kubectl get po -n team-a -l app=sleep-auto -o jsonpath='{.items[0].metadata.name}') -- curl -v https://bbc.co.ukまた、このポッドからgoogle.comに接続できなくなったことも確認できます。
kubectl exec -ti -n team-a $(kubectl get po -n team-a -l app=sleep-auto -o jsonpath='{.items[0].metadata.name}') -- curl -v https://google.comTLSエラーの例
* Trying 142.250.200.46:443...* Connected to google.com (142.250.200.46) port 443 (#0)* ALPN: offers h2,http/1.1* TLSv1.3 (OUT), TLS handshake, Client hello (1):* CAfile: /etc/ssl/certs/ca-certificates.crt* CApath: none* TLSv1.3 (IN), TLS handshake, Server hello (2):* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):* TLSv1.3 (IN), TLS handshake, Certificate (11):* TLSv1.3 (OUT), TLS alert, unknown CA (560):* SSL certificate problem: unable to get local issuer certificate* Closing connection 0curl: (60) SSL certificate problem: unable to get local issuer certificateMore details here: https://curl.se/docs/sslcerts.htmlcurl failed to verify the legitimacy of the server and therefore could notestablish a secure connection to it. To learn more about this situation andhow to fix it, please visit the web page mentioned above.command terminated with exit code 60
CAバンドルの使用を強制する
GatekeeperやKyvernoなどのツールを使用すると、アプリケーションがKubernetesにデプロイされるときに、特定のvolume
とvolumeMount
の構成が強制されるようにできます。この方法を使用すると、クラスター管理者は、すべてのポッドに関連する構成を自動的に挿入するルールを設定できます。これは構成を強制するのに役立つかもしれませんが、クラスターのアプリケーションチームやテナントにとってはより不透明になる可能性があります。
このチュートリアルでは、Gatekeeperの使用方法を示します。
Gatekeeper
Gatekeeperディレクトリには、各名前空間でtrust-managerが生成するconfigMap
から、すべてのポッドにCAバンドルがマウントされるように設計された2つのAssign
ポリシーの例があります。
-
Gatekeeperをクラスターにインストールします。
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/chartshelm repo updatehelm install gatekeeper/gatekeeper --name-template=gatekeeper --namespace gatekeeper-system --create-namespace --version v3.11.0 -
team-a
名前空間内のすべてのpod
リソースに適用されるポリシーを作成します。これにより、必要なvolumes
構成が適用されるときに、Pod
リソースが変更されます。apiVersion: mutations.gatekeeper.sh/v1kind: Assignmetadata:name: demo-trust-ca-volumespec:applyTo:- groups: [""]kinds: ["Pod"]versions: ["v1"]match:scope: Namespacedkinds:- apiGroups: ["*"]kinds: ["Pod"]namespaces: ["team-a"]excludedNamespaces: ["kube-system", "public", "kyverno", "gatekeeper-system"]# Mounting the volume named "ca-certificates" from ConfigMaplocation: "spec.volumes[name:ca-certificates]"parameters:assign:value:name: ca-certificatesconfigMap:name: public-bundledefaultMode: 0644optional: falseitems:- key: ca-certificates.crtpath: ca-certificates.crtkubectl apply -f gatekeeper/gatekeeper-trust-pod-ca-volume.yaml -
team-a
名前空間内のすべてのpod
リソースに適用されるポリシーを作成します。これにより、必要なvolumeMounts
構成で変更されます。apiVersion: mutations.gatekeeper.sh/v1kind: Assignmetadata:name: demo-trust-ca-volumemountspec:applyTo:- groups: [""]kinds: ["Pod"]versions: ["v1"]match:scope: Namespacedkinds:- apiGroups: ["*"]kinds: ["Pod"]namespaces: ["team-a"]excludedNamespaces: ["kube-system", "public", "kyverno", "gatekeeper-system"]# All containers in a pod mounting to volumeMount named "ca-certificates"location: "spec.containers[name:*].volumeMounts[name:ca-certificates]"parameters:assign:value:mountPath: /etc/ssl/certs/name: ca-certificatesreadOnly: truekubectl apply -f gatekeeper/gatekeeper-trust-pod-ca-volumemount.yaml -
team-a
名前空間に切り替え、以前のvolume
またはvolumeMount
構成なしでデプロイメントを作成し、ポッドが実行されたときに変更が有効になることを確認します。apiVersion: apps/v1kind: Deploymentmetadata:labels:app: test-assignname: test-assignnamespace: team-aspec:replicas: 1revisionHistoryLimit: 3selector:matchLabels:app: test-assignstrategy: {}template:metadata:labels:app: test-assignspec:containers:- command:- /bin/sh- -c- sleep 1dimage: quay.io/zenlab/curl:latestname: curlresources: {}volumeMounts: []volumes: []kubectl apply -f gatekeeper/deploy-novol.yaml -
適用後、
volume
とvolumeMount
が適用されたことを検証します。kubectl get po -n team-a -l app=test-assign -o yaml | yq '.items[0].spec' - -
ポッドへのシェルを実行し、公開的に信頼されている任意のウェブサイト(例:
https://bbc.co.uk
)へのHTTPS接続を試みます。kubectl exec -n team-a -ti $(kubectl get pod -n team-a -l app=test-assign -o jsonpath='{.items[0].metadata.name}') -- curl -v https://bbc.co.uk成功は、Webページからの有効な200応答のように見えます。
これは追加の構成なしで動作するはずであることに注意してください。その時点でSSLエラーが発生する場合は、
volumes
セクションで、正しいconfigMap
が参照されていることを確認してください。 -
最後に、同様のポッドを適用できますが、今回はCA証明書が明示的にマウントされています。これは、Gatekeeperポリシーを使用すると、関連する構成がすでに存在する場合、アクションが実行されないことを示すためです。
apiVersion: apps/v1kind: Deploymentmetadata:labels:app: test-assign-noopname: test-assign-noopnamespace: team-aspec:replicas: 1revisionHistoryLimit: 3selector:matchLabels:app: test-assign-nooptemplate:metadata:labels:app: test-assign-noopspec:containers:- command:- /bin/sh- -c- sleep 1dimage: quay.io/zenlab/curl:latestname: curlvolumeMounts:- mountPath: /etc/ssl/certs/name: ca-certificatesreadOnly: truevolumes:- name: ca-certificatesconfigMap:name: exampledefaultMode: 0644optional: falseitems:- key: ca-certificates.crtpath: ca-certificates.crtkubectl apply -f gatekeeper/deploy-withvol.yamlkubectl exec -n team-a -ti $(kubectl get pod -n team-a -l app=test-assign-noop -o jsonpath='{.items[0].metadata.name}') -- curl -v https://bbc.co.uk
注: Assign
ポリシーリソースに問題がある場合は、Kubernetesイベント(kubectl get events
)で問題を確認してください。
trust-managerを使用したパブリック信頼
このチュートリアルでは、trust-managerを使用してクラスターレベルで認証局証明書を管理する方法と、この信頼されたBundle
を手動で、またはGatekeeperで強制的に使用する方法を示しました。信頼できるCAの変更に応じて、アプリケーションを自動デプロイする方法を見てきました。
これは、現在環境で「動作する」ものにとっては、より多くの作業のように思えるかもしれませんが、このソリューションが、特定の認証局を信頼しなくなった場合にどのように対応できるかを検討してください。
次回は、プライベート認証局をこの信頼管理プロセスに統合するのがいかに簡単かを見ていきます。
クリーンアップ
このチュートリアルでデプロイされたすべてのリソースを削除するには
kubectl delete deployment -n team-a sleep-auto test-assign test-assign-noopkubectl delete bundle public-bundlekubectl delete assign demo-trust-ca-volume demo-trust-ca-volumemounthelm uninstall -n gatekeeper-system gatekeeperhelm uninstall -n stakater-reloader reloaderhelm uninstall -n cert-manager trust-managerhelm uninstall -n cert-manager cert-managerkubectl delete namespace cert-manager team-a stakater-reloader gatekeeper-systemkubectl delete crd -l gatekeeper.sh/system=yes