Knative cert-manager 連携の構成¶
Knative Serving は、自動証明書プロビジョニングに cert-manager を使用するためのブリッジコンポーネントに依存しています。この機能を使用する場合は、Knative cert-manager 連携を有効にする必要があります。
前提条件¶
Knative クラスターに以下がインストールされている必要があります。
- Knative Serving.
cert-manager
バージョン1.0.0
以上。
警告
cert-manager がインストールされていることを確認してください。そうしないと、Serving コントローラーが正しく起動しません。
発行者の構成¶
Knative cert-manager 連携では、cert-manager 発行者への 3 つの参照を定義して、3 つの Knative Serving 暗号化機能に異なる CA を構成します。
issuerRef
: イングレスに使用される外部ドメイン証明書の発行者。clusterLocalIssuerRef
: イングレスに使用されるクラスターローカルドメイン証明書の発行者。systemInternalIssuerRef
: Knative 内部コンポーネントで使用されるシステム内部 TLS 証明書の発行者。
次の例では、自己署名された ClusterIssuer
を使用し、Knative cert-manager 連携では、3 つの構成すべてでその ClusterIssuer
を参照しています。これは本番環境で使用すべきではなく(また、ダウンタイムなしで CA をローテーションすることをサポートしていない)ため、ユースケースごとにどの CA を使用すべきか、暗号化されたサービスを呼び出すクライアントに信頼がどのように分散されるかを検討する必要があります。Knative システムコンポーネントについては、Knative は信頼される CA のバンドルを指定する方法を提供します(詳細については下記を参照)。
これをどのように構造化するかについては一般的な答えはありません。以下に、それがどのように見えるかの例を示します。
機能 | 認証局 | 信頼方法 |
---|---|---|
external-domain-tls | Let's Encrypt | ブラウザークライアントには Let's Encrypt チェーンが既に存在し、すべてのルート CA は DevOps チームによって企業全体の Docker ベースイメージに追加されます。 |
cluster-local-domain-tls | クラスターオペレーターが提供する CA | CA は DevOps チームによって管理され、企業全体の Docker ベースイメージに追加されます。 |
system-internal-tls | 自己署名 Cert-Manager ClusterIssuer |
CA は cert-manager によって設定されます。DevOps チームは trust-manager を使用して、Knative システムコンポーネントに CA を配布します。 |
発行者の選択¶
一般に、cert-manager ドキュメントを参照できます。利用可能な例としては、次のものがあります。
重要
すべての発行者の種類がすべての Knative 機能で動作するわけではないことに注意してください。
cluster-local-domain-tls
は、myapp.<namespace>
、myapp.<namespace>.svc
、myapp.<namespace>.svc.cluster.local
などのクラスターローカルドメインの証明書に署名できる必要があります。通常、CA はクラスターの外部にあるため、ACME プロトコル (DNS01/HTTP01) を介した検証は不可能です。これらの証明書の作成を許可する発行者 (例: CA 発行者) を使用できます。
system-internal-tls
は、Knative が検証する特定の SAN に署名できる必要があります。定義された SAN のセットは次のとおりです。
kn-routing
kn-user-<名前空間>
((Knative サービスが作成される/される予定の各名前空間) data-plane.knative.dev
これも ACME プロトコル (DNS01/HTTP01) では不可能であるため、これらの証明書の作成を許可する発行者 (例: CA 発行者) を構成する必要があります。
発行者の構成¶
警告
自己署名クラスター発行者は本番環境で使用すべきではありません。詳細については、上記の発行者の構成を参照してください。
-
次の自己署名
ClusterIssuer
を作成してクラスターに適用します。# this issuer is used by cert-manager to sign all certificates apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: cluster-selfsigned-issuer spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer # this issuer is specifically for Knative, it will use the CA stored in the secret created by the Certificate below metadata: name: knative-selfsigned-issuer spec: ca: secretName: knative-selfsigned-ca --- apiVersion: cert-manager.io/v1 kind: Certificate # this creates a CA certificate, signed by cluster-selfsigned-issuer and stored in the secret knative-selfsigned-ca metadata: name: knative-selfsigned-ca namespace: cert-manager # If you want to use it as a ClusterIssuer the secret must be in the cert-manager namespace. spec: secretName: knative-selfsigned-ca commonName: knative.dev usages: - server auth isCA: true issuerRef: kind: ClusterIssuer name: cluster-selfsigned-issuer
-
ClusterIssuer
が準備完了状態であることを確認します。結果:kubectl get clusterissuer cluster-selfsigned-issuer -o yaml kubectl get clusterissuer knative-selfsigned-issuer -o yaml
Status.Conditions
にReady=True
が含まれている必要があります。 -
次に、
config-certmanager
ConfigMap でClusterIssuer
を参照します。kubectl edit configmap config-certmanager -n knative-serving
data
セクション内にフィールドを追加します。apiVersion: v1 kind: ConfigMap metadata: name: config-certmanager namespace: knative-serving labels: networking.knative.dev/certificate-provider: cert-manager data: issuerRef: | kind: ClusterIssuer name: knative-selfsigned-issuer clusterLocalIssuerRef: | kind: ClusterIssuer name: knative-selfsigned-issuer systemInternalIssuerRef: | kind: ClusterIssuer name: knative-selfsigned-issuer
ファイルが正常に更新されたことを確認します。
kubectl get configmap config-certmanager -n knative-serving -o yaml
ダウンタイムなしで信頼とローテーションを管理する¶
上記で指摘したように、HTTPS を使用して Knative サービスを呼び出す各クライアントは、CA または中間チェーンを信頼する必要があります。暗号化の概要を見ると、信頼を分散する必要がある場所が複数あることがわかります。
- クラスター外部クライアント (ブラウザーやその他のアプリケーション): これは Knative の範囲外と見なされます。
- クラスター内部クライアント (例: Knative または Vanilla K8s ワークロード): 下記を参照してください。
- Knative システムコンポーネント (例: アクティベーター、キュープロキシ、イングレスコントローラー): 下記を参照してください。
クラスター内部クライアント (例: Knative または Vanilla K8s ワークロード) の信頼¶
Knative はすべてのワークロードを制御せず、設定はランタイムや言語に大きく依存するため、これは Knative の範囲外です。ただし、アプリケーションに CA を提供する方法はいくつかあるため、考慮すべき点をいくつか示します。
- ビルド時に CA バンドルをコンテナーイメージに追加する (これにより CA ローテーションが複雑になることに注意してください。基本的にはすべてのアプリケーションをリビルドする必要があります)。
- CA バンドルをファイルシステムにマウントする (例:
Secret
またはConfigMap
から)。 - 環境変数から読み取る。
- K8s API を介して
Secret
/ConfigMap
からアクセスする。
ダウンタイムなしで証明書をリロードすることがクライアントにとって重要な場合、ワークロードは K8s リソース (Secret/ConfigMap) の変更を監視するか、ファイルシステムを監視する必要があります。ワークロードがファイルシステムを監視している場合、変更する Secret/ConfigMap をキャッチするために ionotify
を使用することは、K8s ではあまり信頼できないことに注意することが重要です。テストでは、ファイルシステムの証明書を定期的にポーリングして変更をチェックする方が信頼性が高いことが示されています。
以下にGo言語のいくつかの例を示します。
- バンドルを定義されたパスにファイルとして保存する:https://go.dokyumento.jp/src/crypto/x509/root_linux.go (再起動なしではリロードされないことに注意)
- K8s API経由で動的にリロードする:https://github.com/knative/serving/blob/main/pkg/activator/certificate/cache.go
- watcherプロセスでファイルシステムからリロードする:https://github.com/knative/serving/blob/main/pkg/queue/certificate/watcher.go
Knativeシステムコンポーネントのための信頼¶
Knativeシステムコンポーネントは、ConfigMaps
から1つまたは複数のCAバンドルを信頼するように構成できます。クラスターオペレーターは、ローテーション中にダウンタイムが発生しないように、適切に構成する必要があります。Knativeコンポーネントは、コンポーネントが実行されている名前空間でConfigMap
を探します。例えば、
- knative-serving
- istio-system(net-istioを使用している場合)
- kourier-system(net-kourierを使用している場合)
- Knativeサービスが実行される各名前空間
Knativeは、ラベルnetworking.knative.dev/trust-bundle: "true"
を持つConfigMap
を探し、すべてのdata
キー(名前に関係なく)を読み取ります。1つのキーに、1つまたは複数のCA/中間証明書を含めることができます。それらが有効であれば、Knativeコンポーネントのトラストストアに追加されます。
以下は、ConfigMap
がどのように見えるかの例です。
apiVersion: v1
data:
cacerts.pem: |
-----BEGIN CERTIFICATE-----
MIIDDTCCAfWgAwIBAgIQMQuip05h7NLQq2TB+j9ZmTANBgkqhkiG9w0BAQsFADAW
MRQwEgYDVQQDEwtrbmF0aXZlLmRldjAeFw0yMzExMjIwOTAwNDhaFw0yNDAyMjAw
OTAwNDhaMBYxFDASBgNVBAMTC2tuYXRpdmUuZGV2MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA3clC3CV7sy0TpUKNuTku6QmP9z8JUCbLCPCLACCUc1zG
FEokqOva6TakgvAntXLkB3TEsbdCJlNm6qFbbko6DBfX6rEggqZs40x3/T+KH66u
4PvMT3fzEtaMJDK/KQOBIvVHrKmPkvccUYK/qWY7rgBjVjjLVSJrCn4dKaEZ2JNr
Fd0KNnaaW/dP9/FvviLqVJvHnTMHH5qyRRr1kUGTrc8njRKwpHcnUdauiDoWRKxo
Zlyy+MhQfdbbyapX984WsDjCvrDXzkdGgbRNAf+erl6yUm6pHpQhyFFo/zndx6Uq
QXA7jYvM2M3qCnXmaFowidoLDsDyhwoxD7WT8zur/QIDAQABo1cwVTAOBgNVHQ8B
Af8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAd
BgNVHQ4EFgQU7p4VuECNOcnrP9ulOjc4J37Q2VUwDQYJKoZIhvcNAQELBQADggEB
AAv26Vnk+ptQrppouF7yHV8fZbfnehpm07HIZkmnXO2vAP+MZJDNrHjy8JAVzXjt
+OlzqAL0cRQLsUptB0btoJuw23eq8RXgJo05OLOPQ2iGNbAATQh2kLwBWd/CMg+V
KJ4EIEpF4dmwOohsNR6xa/JoArIYH0D7gh2CwjrdGZr/tq1eMSL+uZcuX5OiE44A
2oXF9/jsqerOcH7QUMejSnB8N7X0LmUvH4jAesQgr7jo1JTOBs7GF6wb+U76NzFa
8ms2iAWhoplQ+EHR52wffWb0k6trXspq4O6v/J+nq9Ky3vC36so+G1ZFkMhCdTVJ
ZmrBsSMWeT2l07qeei2UFRU=
-----END CERTIFICATE-----
kind: ConfigMap
metadata:
labels:
networking.knative.dev/trust-bundle: "true"
name: knative-bundle
namespace: knative-serving
trust-managerを使用してバンドルを配布する¶
CAバンドルをすべての名前空間に配布するのは面倒な作業になる可能性があるため、trust-managerを使用してCAバンドルを自動的に配布できます。この方法の詳細については、ドキュメントを参照してください。
ローテーション中の信頼¶
CAおよび/または中間証明書のローテーション中、クライアントはローテーションが完了するまで、古いCA/チェーンと新しいCA/チェーンを信頼する必要があります。上記の信頼アプローチを使用すると、ダウンタイムなしでフルチェーンローテーションを実行できます。
- 既存のセットアップが稼働していることを確認してください。
- すべてのKnativeサービスに関連する証明書があり、期限切れになっていないことを確認してください。
- CA(およびフルチェーン)が期限切れになっていないことを確認してください。
- 既存のおよび新しいCA(およびフルチェーン)をトラストバンドルに追加します(手動またはtrust-manager経由)。
- 新しいCAを使用するようにcert-managerの
ClusterIssuers
またはIssuers
を再構成します。 - すべての証明書が期限切れになり、cert-managerによって更新されるまで待ちます。
- すべての証明書が新しいCAによって署名されるようになりました。
- すべてのコンポーネントがすべての変更を拾い上げたことを確認するために、猶予期間を追加します。
- トラストバンドルから古いCAを削除します。