ベストプラクティス
このセクションでは、CIS Kubernetes ベンチマーク、NSA Kubernetes ハードニングガイド、またはBSI Kubernetes セキュリティ推奨事項などの一般的なセキュリティ標準に準拠するように cert-manager を設定する方法について説明します。
また、Datree とその組み込みルールなどのツールによって適用されるものや、Learnk8s の「Kubernetes プロダクションベストプラクティス」チェックリストなどで説明されているものなど、本番環境で cert-manager をデプロイするためのベストプラクティスについても説明します。
概要
HelmチャートまたはYAMLマニフェスト(Deployment、Pod、ServiceAccountなど)内のcert-managerリソースのデフォルト設定は、ベストプラクティスや最大限のセキュリティではなく、後方互換性を重視して設計されています。デフォルトのリソースがKubernetesクラスタのセキュリティポリシーに準拠していない場合があり、その場合は、Helmチャートの値を使用してインストール設定を変更し、デフォルト値を上書きできます。
ネットワーク要件とネットワークポリシー
各cert-manager Podのネットワーク要件の概要を以下に示します。ネットワーク要件の一部は、特定のIssuer/ClusterIssuerの設定や特定の設定オプションによって異なります。
ご自身の cert-managerインストールのネットワーク要件を理解したら、Kubernetesネットワーク(CNI)プラグイン(例:Calico)を使用して、「最小権限」のネットワークポリシーを実装することを検討してください。
ネットワークポリシーにより、信頼できないクライアントがcert-manager Podに接続すること、およびcert-managerが信頼できないサーバーに接続することを防止する必要があります。
この推奨事項の例は、Calicoドキュメントにあります。
Calicoを使用する場合でも、Kubernetesネットワークポリシーを使用する場合でも、Kubernetes Podに対する暗黙的なデフォルト拒否ポリシーを作成することをお勧めします。これにより、不要なトラフィックがデフォルトで拒否されます。
任意のKubernetesネットワーク(CNI)プラグインで認識されるため、移植可能なKubernetes組み込みのNetworkPolicy
リソースを使用できます。または、CNIソフトウェアによって提供されるカスタムリソースを使用することもできます。
📖 Kubernetes組み込みNetworkPolicy APIについて学び、ポリシーの例を参照してください。
ネットワーク要件
ネットワーク要件の概要を以下に示します。
-
UDP/TCP: cert-manager(すべて)-> Kubernetes DNS:すべてのcert-managerコンポーネントは、クラスタと外部ドメイン名の両方に対してUDP DNSクエリを実行します。TCPを使用するDNSクエリもあります。
-
TCP: Kubernetes(APIサーバー)-> cert-manager(webhook):Kubernetes APIサーバーは、cert-manager webhookコンポーネントへのHTTPS接続を確立します。webhookのネットワーク要件を理解するには、cert-managerのwebhookトラブルシューティングガイドを参照してください。
-
TCP: cert-manager(webhook、controller、cainjector、startupapicheck)-> Kubernetes APIサーバー:cert-managerのwebhook、controller、cainjector、startupapicheckは、cert-managerカスタムリソースおよびKubernetesリソースと対話するために、Kubernetes APIサーバーへのHTTPS接続を確立します。cert-manager webhookは特別なケースであり、
SubjectAccessReview
APIを使用してKubernetes APIサーバーに接続し、CertificateRequest
リソースのApproved
またはDenied
条件を変更しようとするクライアントを検証します。 -
TCP: cert-manager(controller)-> HashiCorp Vault(認証とリソースAPIエンドポイント):Vault Issuerを使用している場合、cert-manager controllerは1つ以上のVault APIエンドポイントへのHTTPS接続を確立する場合があります。Vaultエンドポイントのターゲットホストとポートは、IssuerまたはClusterIssuerリソースで構成されます。
-
TCP: cert-manager(controller)-> Venafi TLS Protect(認証とリソースAPIエンドポイント):Venafi Issuerを使用している場合、cert-manager controllerは1つ以上のVenafi APIエンドポイントへのHTTPS接続を確立する場合があります。Venafi APIエンドポイントのターゲットホストとポートは、IssuerまたはClusterIssuerリソースで構成されます。
-
TCP: cert-manager(controller)-> DNS APIエンドポイント(ACME DNS01の場合):DNS01ソルバーを使用するACME Issuerを使用している場合、cert-manager controllerは、Amazon Route53などのDNS APIエンドポイントと、関連する認証エンドポイントへのHTTPS接続を確立する場合があります。
-
UDP/TCP: cert-manager(controller)-> 外部DNS:ACME Issuerを使用する場合、cert-manager controllerは、ACMEチャレンジの自己チェックプロセスの一環として、再帰的なDNSサーバーにDNSクエリを送信する場合があります。これは、ACMEサーバーにチェックを実行するよう依頼する前に、DNS01またはHTTP01チャレンジが解決可能であることを確認するためです。
DNS01の場合、DNS01チャレンジレコードを追加するDNSゾーンを計算するために、権威DNSサーバーへの一連のDNSクエリを実行する場合もあります。DNS01の場合、cert-managerはDNS over HTTPSもサポートしています。
次のcontrollerフラグを使用して、DNSサーバーのホストとポートを選択できます。
--acme-http01-solver-nameservers
、--dns01-recursive-nameservers
、および--dns01-recursive-nameservers-only
。 -
TCP: ACME(Let's Encrypt)-> cert-manager(acmesolver):HTTP01用に構成されたACME Issuerを使用する場合、cert-managerは、Issuerの名前空間またはClusterIssuerの場合はcert-managerの名前空間に、
acmesolver
Pod、Service、およびIngress(またはGateway API)リソースをデプロイします。ACME実装は、選択したIngressロードバランサーを介してこのPodへのHTTP接続を確立するため、ネットワークポリシーでこれを許可する必要があります。ℹ️ acmesolver Podは、Kubernetes APIサーバーへのアクセスを必要としません。
-
TCP: Metrics Server -> cert-manager(controller):cert-manager controllerには、TCPポート9402でHTTP接続をリッスンするメトリクスサーバーがあります。選択したメトリクスコレクターからこのサービスへのアクセスを許可するネットワークポリシーを作成してください。
専用のノードプールでcert-managerを分離する
cert-managerはクラスタスコープのオペレーターであり、プラットフォームの制御プレーンの一部として扱う必要があります。cert-manager controllerはKubernetes Secretリソースを作成および変更し、controllerとcainjectorはどちらもメモリにTLS Secretリソースをキャッシュします。これらは、cert-managerコンポーネントを他の特権レベルの低いワークロードから分離することを検討する必要がある2つの理由です。たとえば、信頼できないワークロードまたは悪意のあるワークロードがcert-manager controllerと同じノードで実行され、何らかの方法で基盤となるノードへのrootアクセス権を取得した場合、controllerがメモリにキャッシュしたSecret内の秘密鍵を読み取ることができる可能性があります。
信頼できるプラットフォームオペレーター用に予約されたノードでcert-managerを実行することにより、このリスクを軽減できます。
cert-managerのHelmチャートには、各コンポーネントのPod tolerations
とnodeSelector
を構成するためのパラメーターがあります。これらのパラメーターの正確な値は、クラスタによって異なります。
📖 KubernetesドキュメントのPodのノードへの割り当てを参照してください。
📖 Kubernetesドキュメントの汚染と許容について読んでください。
例
この例では、taints
を使用してプラットフォーム以外のPodをプラットフォームの制御プレーン用に予約したノードからはじく方法、tolerations
を使用してcert-manager Podがこれらのノードで実行されるようにする方法、およびnodeSelector
を使用してcert-manager Podをこれらのノードに配置する方法を示します。
ノードにラベルを付ける
kubectl label node ... node-restriction.kubernetes.io/reserved-for=platform
ノードに汚染を適用する
kubectl taint node ... node-restriction.kubernetes.io/reserved-for=platform:NoExecute
次に、次のHelmチャート値を使用してcert-managerをインストールします。
nodeSelector:kubernetes.io/os: linuxnode-restriction.kubernetes.io/reserved-for: platformtolerations:- key: node-restriction.kubernetes.io/reserved-foroperator: Equalvalue: platformwebhook:nodeSelector:kubernetes.io/os: linuxnode-restriction.kubernetes.io/reserved-for: platformtolerations:- key: node-restriction.kubernetes.io/reserved-foroperator: Equalvalue: platformcainjector:nodeSelector:kubernetes.io/os: linuxnode-restriction.kubernetes.io/reserved-for: platformtolerations:- key: node-restriction.kubernetes.io/reserved-foroperator: Equalvalue: platformstartupapicheck:nodeSelector:kubernetes.io/os: linuxnode-restriction.kubernetes.io/reserved-for: platformtolerations:- key: node-restriction.kubernetes.io/reserved-foroperator: Equalvalue: platform
ℹ️ この例では、Podを配置するために
nodeSelector
を使用していますが、affinity.nodeAffinity
を使用することもできます。nodeSelector
は、構文が単純なためここで選択されています。ℹ️ デフォルトの
nodeSelector
値kubernetes.io/os: linux
は、混合OSクラスタでcert-manager PodがWindowsノードに配置されるのを回避するため、これも明示的に含める必要があります。📖 EKSベストプラクティスガイドの特定のノードへのテナントワークロードの分離に関するガイドで、これらの手法の詳細な説明を参照してください。
📖 Google Kubernetes Engineで専用のノードプールでワークロードを分離する方法について学びます。
📖 RedHat OpenShiftを使用したノードセレクターによる特定のノードへのPodの配置について学びます。
📖
node-restriction.kubernetes.io/
プレフィックスとNodeRestriction
アドミッションプラグインの詳細を参照してください。ℹ️ マルチテナントクラスタでは、テナントがPodに追加できる許容値を制限するために、
PodTolerationRestriction
プラグインを有効にすることを検討してください。cert-manager
名前空間にデフォルトの許容値を追加するためにそのプラグインを使用することもできます。これにより、Helmチャートで許容値を明示的に設定する必要がなくなります。ℹ️ 代わりに、Kyverno を使用して、Pod で使用できる許容値を制限することもできます。コントロールプレーンのスケジューリングの制限 を出発点として読んでください。
高可用性
cert-managerには、コントローラー、cainjector、webhookの3つの長時間実行コンポーネントがあります。これらの各コンポーネントにはDeploymentがあり、デフォルトでは各Deploymentにレプリカが1つありますが、これは高可用性を提供しません。cert-managerのHelmチャートには、各DeploymentのreplicaCount
を構成するためのパラメーターがあります。本番環境では、次のreplicaCount
パラメーターを推奨します。
replicaCount: 2webhook:replicaCount: 3cainjector:replicaCount: 2
コントローラーとcainjector
コントローラーとcainjectorコンポーネントは、リーダー選挙を使用して、アクティブなレプリカが1つだけになるようにします。これは、複数のレプリカが同じAPIリソースを調整しようとした場合に発生する競合を防ぎます。そのため、これらのコンポーネントでは、水平スケーリングではなく、高可用性を実現するために複数のレプリカを使用できます。
2つのレプリカを使用すると、現在のリーダーが中断に遭遇した場合に、リーダーシップを引き継ぐ準備ができているノードにスタンバイPodがスケジュールされていることが保証されます。たとえば、リーダーPodがノードからドレインされた場合や、リーダーPodが予期しないデッドロックに遭遇した場合などです。
これらのコンポーネントのレプリカを2つ以上使用する正当な理由はほとんどありません。
webhook
デフォルトでは、cert-manager webhook Deploymentにはレプリカが1つありますが、本番環境では3つ以上を使用する必要があります。cert-manager webhookが利用できない場合、cert-managerカスタムリソースに対するすべてのAPI操作が失敗し、cert-managerカスタムリソースを作成、更新、または削除するソフトウェア(cert-manager自体を含む)を中断し、クラスタに他の中断を引き起こす可能性があります。そのため、常に複数のcert-manager webhookレプリカを実行することが特に重要です。
ℹ️ 対照的に、cert-managerコントローラーのレプリカが1つしかない場合、中断のリスクは低くなります。たとえば、単一cert-managerコントローラーマネージャーPodをホストしているノードがドレインされた場合、別のノードで新しいPodが起動されるまで遅延が発生し、その間に作成または変更されたcert-managerリソースは、新しいPodが起動するまで調整されません。しかし、コントローラーマネージャーは非同期的に動作するため、cert-managerカスタムリソースに依存するアプリケーションは、この状況に耐えられるように設計されています。とはいえ、クラスタに十分なリソースがある場合は、各コントローラーのレプリカを2つ以上実行することをお勧めします。
📖 Google Kubernetes Engine(GKE)のドキュメントでWebhookを使用する場合のコントロールプレーンの安定性の確保を読んで、Webhookの中断がクラスタをどのように中断する可能性があるかの例を確認してください。
📖 Cisco Tech BlogのKubernetes Admission Webhookのダークサイドを読んで、Webhookによって引き起こされる可能性のある問題とそれらを回避する方法の詳細について学習してください。
トポロジースプレッド制約
トポロジースプレッド制約を使用することを検討して、ノードまたはデータセンターの中断がcert-managerの動作を低下させないようにしてください。
高可用性のために、レプリカPodが同じノードにスケジュールされないようにする必要があります。そのノードに障害が発生した場合、アクティブなPodとスタンバイPodの両方が終了し、別のノードに十分な空きリソースを持つノードがあるまで、そしてそのPodが準備完了になるまで、そのコントローラーによるリソースの調整は行われなくなります。
クラスタにゾーン間に分散されたノードがある場合は、Podが別々のデータセンター(アベイラビリティゾーン)で実行されることも望ましいです。そうすれば、アクティブなPodをホストするデータセンターに障害が発生した場合、スタンバイPodはすぐにリーダーシップを引き継ぐことができます。
幸いなことに、Kubernetes >= 1.24には組み込みのデフォルトの制約があります。そのため、上記の高可用性スケジューリングは暗黙的に行われます。
ℹ️ クラスタで組み込みのデフォルトの制約を使用していない場合。トポロジースプレッド制約をHelmチャート値を使用してcert-managerコンポーネントのそれぞれに追加できます。
PodDisruptionBudget
高可用性のために、minAvailable=1
のPodDisruptionBudget
リソースもデプロイする必要があります。
これにより、ノードのドレインなど、任意の中断が、少なくとも別のレプリカが別のノードに正常にスケジュールおよび開始されるまで続行されないことが保証されます。Helmチャートには、長時間実行されるcert-managerコンポーネントのそれぞれについてPodDisruptionBudgetを有効化および構成するためのパラメーターがあります。次のパラメーターをお勧めします。
podDisruptionBudget:enabled: trueminAvailable: 1webhook:podDisruptionBudget:enabled: trueminAvailable: 1cainjector:podDisruptionBudget:enabled: trueminAvailable: 1
📖 Kubernetesドキュメントでアプリケーションのディスラプション予算の指定について読んでください。
⚠️ これらのPodDisruptionBudget設定は、高可用性デプロイメントにのみ適しています。
minAvailable
値よりも多くのreplicaCount
を各Deploymentに増やす必要があります。そうでない場合、PodDisruptionBudgetによってcert-manager Podのドレインを防ぐことになります。
優先順位クラス名
優先順位クラスを設定する理由は、KubernetesブログのPriorityClass
を使用してミッションクリティカルなPodを退避から保護するで次のように要約されています。
Podの優先順位とプリエンプションは、スケジューリングと退避の順序を決定することで、リソース不足の場合にミッションクリティカルなPodが稼働していることを保証するのに役立ちます。
cert-managerがプラットフォームにとってミッションクリティカルな場合は、Kubernetesノードのリソースが不足した場合にプリエンプションから保護するために、cert-manager PodにpriorityClassName
を設定します。priorityClassName
がない場合、cert-manager Podは他のPodのためにリソースを解放するために退避される可能性があり、これにより、cert-managerに依存するアプリケーションに中断が発生する可能性があります。
ほとんどのKubernetesクラスタには、system-cluster-critical
とsystem-node-critical
という2つの組み込み優先順位クラス名が付属しており、Kubernetesコアコンポーネントに使用されます。これらは、cert-managerなどの重要なアドオンにも使用できます。
すべてのcert-manager PodにpriorityClassName: system-cluster-critical
を設定するには、次のHelmチャート値を使用することをお勧めします。
global:priorityClassName: system-cluster-critical
一部のクラスタでは、ResourceQuota
アドミッションコントローラーが特定の優先順位クラスの使用を特定のネームスペースに制限するように構成されている可能性があります。たとえば、Google Kubernetes Engine(GKE)は、デフォルトでkube-system
ネームスペースのPodに対してのみpriorityClassName: system-cluster-critical
を許可します。
📖 Kubernetes PR #93121を読んで、これがどのようにしてなぜ実装されたかを確認してください。
このような場合は、cert-manager
ネームスペースにResourceQuota
を作成する必要があります。
# cert-manager-resourcequota.yamlapiVersion: v1kind: ResourceQuotametadata:name: cert-manager-critical-podsnamespace: cert-managerspec:hard:pods: 1GscopeSelector:matchExpressions:- operator: InscopeName: PriorityClassvalues:- system-node-critical- system-cluster-critical
kubectl apply -f cert-manager-resourcequota.yaml
📖 Kubernetesブログの投稿である
PriorityClass
を使用してミッションクリティカルなPodを退避から保護するを読んで、Podの優先順位とプリエンプションがリソース不足の場合にミッションクリティカルなPodが稼働していることを保証するのにどのように役立つのかを確認してください。📖 クリティカルなアドオンPodの保証されたスケジューリングを読んで、完全に機能するクラスタにとってクリティカルなアドオンに
system-cluster-critical
を使用する理由を学習してください。📖 デフォルトで優先順位クラスの消費量を制限するを読んで、プラットフォーム管理者が特定の高優先順位クラスの使用を限られた数のネームスペースに制限する理由を学習してください。
📖
system-cluster-critical
優先度クラス名を使用するその他の重要なアドオンの例:NVIDIA GPU Operator、OPA Gatekeeper、Cilium。
スケーラビリティ
cert-managerには、コントローラー、cainjector、webhookの3つの長時間実行コンポーネントがあります。Helmチャートには、これらのいずれにもリソース要求と制限が含まれていないため、クラスタに適したリソース要求と制限を指定する必要があります。
コントローラーとcainjector
コントローラーとcainjectorコンポーネントは、リーダー選挙を使用して、アクティブなレプリカが1つだけになるようにします。これにより、複数のレプリカが同じAPIリソースを調整する場合に発生する競合を防ぎます。これらのコンポーネントには水平スケーリングを使用できません。代わりに垂直スケーリングを使用してください。
メモリ
垂直スケーリングを使用して、これらのコンポーネントに十分なメモリリソースを割り当てます。メモリ要件は、非常に多くのAPIリソースがあるクラスタ、または大きなAPIリソースがあるクラスタで高くなります。これは、各コンポーネントが1つ以上のKubernetes APIリソースを調整し、各コンポーネントがメタデータ、場合によってはリソース全体をメモリにキャッシュして、Kubernetes APIサーバーの負荷を軽減するためです。
クラスタにCertificateRequest
リソースが大量に含まれている場合(多くの短命の証明書を頻繁にローテーションする場合など)、コントローラーPodのメモリ制限を増やす必要があります。
cainjector
のメモリ消費量を削減するには、cert-manager
名前空間のリソースのみを監視するように構成し、Certificate
リソースを監視しないように構成します。Helmチャートの値を使用してcainjectorコマンドラインフラグを構成する方法を以下に示します。
cainjector:extraArgs:- --namespace=cert-manager- --enable-certificates-data-source=false
⚠️️ この最適化は、
cainjector
がcert-manager webhook専用に使用されている場合にのみ適切です。cainjector
が他のソフトウェアのWebhookのTLS証明書の管理にも使用されている場合は適切ではありません。たとえば、一部のKubebuilder派生プロジェクトは、cainjector
を使用してWebhookにTLS証明書を挿入する必要がある場合があります。
CPU
垂直スケーリングを使用して、これらのコンポーネントに十分なCPUリソースを割り当てます。CPU要件は、これらのコンポーネントによって調整されるリソースの更新が非常に頻繁に行われるクラスタで高くなります。リソースが変更されるたびに、コンポーネントによって再調整されるようにキューに入れられます。CPUリソースが多いほど、コンポーネントはキューをより高速に処理できます。
Webhook
cert-manager webhookはリーダー選挙を使用しないため、レプリカ数を増やすことで水平方向にスケールできます。Kubernetes APIサーバーは、すべての準備完了レプリカ間の接続をロードバランスするサービスを介してcert-manager webhookに接続します。このため、cert-managerカスタムリソースのインタラクションの頻度が高いクラスタでは、webhookレプリカの数を3以上に増やすことで明確な利点があります。さらに、webhookはキャッシュを使用しないため、メモリ要件が控えめです。このため、webhookをスケールアウトするリソースコストは比較的低くなります。
ライブネスプローブの使用
この推奨事項の例は、Datreeドキュメントにあります。 各コンテナに構成されたライブネスプローブがあることを確認する
ライブネスプローブにより、KubernetesはPodをいつ置き換えるべきかを判断できます。それらは、復元力のあるクラスタアーキテクチャを構成する上で基本です。
cert-manager webhookとコントローラーPodにはライブネスプローブがあります。cainjector Podには、まだライブネスプローブがありません。詳細を以下に示します。
Webhook
cert-manager webhookにはデフォルトで有効になっているライブネスプローブがあり、タイミングと閾値はHelm値を使用して構成できます。
コントローラー
📢 cert-managerコントローラーのライブネスプローブは、cert-managerリリース
1.12
で導入され、リリース1.14
でデフォルトで有効になりました。現場で問題が発生した場合は、お問い合わせください。
cert-managerコントローラーのライブネスプローブは、ポート9443でリッスンし、独自のthreadで実行されるhealthzサーバーの/livez
エンドポイントに接続するHTTPプローブです。/livez
エンドポイントは現在、次のサブシステムの結合状態を報告し、各サブシステムには独自の/livez
エンドポイントがあります。
/livez/leaderElection
:リーダー選挙レコードが更新されていない場合、またはリーダー選挙スレッドが親プロセスをクラッシュさせずに終了した場合にエラーを返します。/livez/clockHealth
:システムクロックとGoがタイマーのスケジュールに使用している単調クロックとの間にクロックスキューが検出された場合にエラーを返します。
ℹ️ 今後、Kubernetesがロギングがブロックされていないことを確認する方法や各コントローラーのヘルスチェックを行う方法と同様に、
/livez
エンドポイントによってより多くのサブシステムをチェックできる可能性があります。📖 個々のヘルスチェックと詳細なステータス情報へのアクセス方法について読んでください(cert-managerはKubernetesと同じhealthzエンドポイントマルチプレクサを使用します)。
Cainjector
cainjector Podには、ライブネスプローブや/livez
healthzエンドポイントはありませんが、GitHubの問題に正当な理由があります。シャットダウンを試行した後、ゾンビ状態になったcainjector。この特定の問題も経験した場合は、その問題にコメントを追加し、Helm:作成されたすべてのPodのreadiness、liveness、startupプローブの構成を許可するにコメントを追加してください。cainjectorのライブネスプローブに関する一般的なリクエストがある場合。
背景情報
cert-manager controller
プロセスとcainjector
プロセスはどちらも、Kubernetes リーダー選挙ライブラリを使用して、一度にアクティブにできる各プロセスのレプリカが1つだけになるようにします。Kubernetesコントロールプレーンコンポーネントもこのライブラリを使用します。
リーダー選出コードは、別のスレッド(Goルーチン)内でループして実行されます。最初にリーダー選出手続きで勝利し、その後リーダー選出リースの更新に失敗した場合、終了します。リーダー選出スレッドが終了すると、他のすべてのスレッドは正常にシャットダウンされ、その後プロセスが終了します。同様に、他のメインスレッドのいずれかが予期せず終了した場合、残りのスレッドの順序正しいシャットダウンがトリガーされ、プロセスは終了します。
これは、致命的エラーが発生した場合はコンテナをクラッシュさせるべきであるという原則に従っています。Kubernetesはクラッシュしたコンテナを再起動し、繰り返しクラッシュする場合は、連続する再起動間の時間が徐々に長くなります。
このため、この順序正しいシャットダウンプロセスにバグがある場合、または他のスレッドのいずれかにプロセスをデッドロックさせてシャットダウンさせないバグがある場合にのみ、Livenessプローブが必要となります。
📖 KubernetesドキュメントのLiveness、Readiness、Startupプローブの設定をお読みください。特に、そのドキュメントの注意事項と警告にご注意ください。
📖 Livenessプローブに関するさらに注意すべき情報については、Livenessプローブで自らを窮地に陥れるをお読みください。
Service Accountトークンの自動マウントの制限
この推奨事項は、Kyvernoポリシーカタログで次のように記述されています。
Kubernetesは、各PodにServiceAccountの認証情報を自動的にマウントします。ServiceAccountには、PodがAPIリソースにアクセスできるようにする役割が割り当てられている場合があります。この機能をブロックすることは、最小権限のベストプラクティスの拡張であり、Podが機能するためにAPIサーバーと通信する必要がない場合は従う必要があります。このポリシーは、これらのServiceAccountトークンのマウントをブロックすることを保証します。
cert-managerコンポーネントはAPIサーバーと通信する必要がありますが、それでもautomountServiceAccountToken: false
を設定することをお勧めします。その理由は以下のとおりです。
automountServiceAccountToken: false
を設定すると、Kyverno(またはその他のポリシーシステム)がこのフィールドがtrue
に設定されているPodを拒否するように構成されているクラスタにcert-managerをインストールできます。Kubernetesのデフォルト値はtrue
です。automountServiceAccountToken: true
の場合、Pod内のすべてのコンテナ(サイドカーコンテナや、Kubernetesアドミッションコントローラによってcert-manager Podリソースに注入された可能性のあるinitコンテナを含む)にServiceAccountトークンがマウントされます。最小権限の原則から、ServiceAccountトークンをcert-managerコンテナに明示的にマウントする方が優れています。
そのため、automountServiceAccountToken: false
を設定し、ServiceAccountトークン、CA証明書、および通常はKubernetes ServiceAccountコントローラによって自動的に追加されるネームスペースファイルを含む、投影されたVolume
を各cert-manager Deploymentリソースに手動で追加し、各cert-managerコンテナに読み取り専用のVolumeMount
を明示的に追加することをお勧めします。
この設定の例は、以下のHelmチャート値ファイルに含まれています。
ベストプラクティスHelmチャート値
以下のHelmチャート値ファイルをダウンロードし、helm install
、helm upgrade
、またはhelm template
に--values
フラグを使用して指定してください。
# Helm chart values which make cert-manager comply with CIS, BSI and NSA# security benchmarks and other best practices for deploying cert-manager in# production.## Read the rationale for these values in:# * https://cert-manager.dokyumento.jp/docs/installation/best-practice/global:priorityClassName: system-cluster-criticalreplicaCount: 2podDisruptionBudget:enabled: trueminAvailable: 1automountServiceAccountToken: falseserviceAccount:automountServiceAccountToken: falsevolumes:- name: serviceaccount-tokenprojected:defaultMode: 0444sources:- serviceAccountToken:expirationSeconds: 3607path: token- configMap:name: kube-root-ca.crtitems:- key: ca.crtpath: ca.crt- downwardAPI:items:- path: namespacefieldRef:apiVersion: v1fieldPath: metadata.namespacevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: serviceaccount-tokenreadOnly: truewebhook:replicaCount: 3podDisruptionBudget:enabled: trueminAvailable: 1automountServiceAccountToken: falseserviceAccount:automountServiceAccountToken: falsevolumes:- name: serviceaccount-tokenprojected:defaultMode: 0444sources:- serviceAccountToken:expirationSeconds: 3607path: token- configMap:name: kube-root-ca.crtitems:- key: ca.crtpath: ca.crt- downwardAPI:items:- path: namespacefieldRef:apiVersion: v1fieldPath: metadata.namespacevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: serviceaccount-tokenreadOnly: truecainjector:extraArgs:- --namespace=cert-manager- --enable-certificates-data-source=falsereplicaCount: 2podDisruptionBudget:enabled: trueminAvailable: 1automountServiceAccountToken: falseserviceAccount:automountServiceAccountToken: falsevolumes:- name: serviceaccount-tokenprojected:defaultMode: 0444sources:- serviceAccountToken:expirationSeconds: 3607path: token- configMap:name: kube-root-ca.crtitems:- key: ca.crtpath: ca.crt- downwardAPI:items:- path: namespacefieldRef:apiVersion: v1fieldPath: metadata.namespacevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: serviceaccount-tokenreadOnly: truestartupapicheck:automountServiceAccountToken: falseserviceAccount:automountServiceAccountToken: falsevolumes:- name: serviceaccount-tokenprojected:defaultMode: 0444sources:- serviceAccountToken:expirationSeconds: 3607path: token- configMap:name: kube-root-ca.crtitems:- key: ca.crtpath: ca.crt- downwardAPI:items:- path: namespacefieldRef:apiVersion: v1fieldPath: metadata.namespacevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: serviceaccount-tokenreadOnly: true
その他
この推奨事項のリストは現在作成中です。他のベストプラクティスの推奨事項がありましたら、このページに貢献してください。