istio-csr のインストール
インストール手順
このガイドでは、istio-csrをゼロからインストールして使用する方法を説明します。ここでは、Dockerでローカルに新しいクラスターを作成するためにkindを使用しますが、関連するIstioのプラットフォームのセットアップが実行されていれば、このガイドはどのクラスターでも機能するはずです。
OpenShift向けのプラットフォームセットアップガイドに従う場合は、ガイドに記載されているistioctl install
コマンドを実行しないでください。後で独自のコマンドを実行します。
0. 背景
Issuerの設定
istio-csrは、cert-managerを使用してIstio証明書を発行するため、発行者リソースを参照できる必要があります。
Helmチャートでインストールする際に発行者を設定したり、実行時に発行者を設定するために使用できるConfigMapを監視するように設定したりできます。
発行者の詳細についてConfigMapを設定することを「ランタイム設定」と呼び、Helmチャートで発行者が指定されていない場合は必須です。
チャートで発行者を設定すると、istio-csrポッドがオンラインになったらすぐに発行を開始できますが、事前にcert-managerをインストールし、発行者を作成しておく必要があります。
チャートで発行者を設定しない場合、istio-csrはランタイム設定で発行者が指定されるまで準備完了になりませんが、cert-managerとistio-csrを同時にインストールできます。
チャートにはデフォルトの発行者名が含まれているため、ランタイム設定を使用するには明示的なオプトインが必要です。以下のガイドでは、ランタイム設定なしで発行者が設定された後にistio-csrをインストールすることを想定しています。ランタイム設定に関する注記は、一番下にあります。
Istio Ambient
v0.12.0
の時点で、istio-csrはIstio Ambientモードをサポートしており、サイドカーコンテナなしでポッドをIstioメッシュに含めることができます。
Istio Ambientモードのサポートを有効にするには、app.server.caTrustedNodeAccounts
Helm値を渡します。これは、ノード認証の使用を許可されているサービスアカウントを示す、カンマ区切りのnamespace/service-accounts
値のリストです。
例としては、--set app.server.caTrustedNodeAccounts=istio-system/ztunnel
となります。
1. 初期設定
マシンに次のツールがインストールされている必要があります。
さらに、Istioがクラスターにまだインストールされていない必要があります。Istio の後にistio-csrをインストールすることはサポートされていません。
2. クラスターの作成とcert-managerのインストール
Kindは、新しく作成されたクラスターを指すようにkubectlを自動的に設定します。
ここでは、helmを使用してcert-managerをインストールしますが、好みの方法がある場合は、任意の方法でインストールできます。
kind create cluster# Helm setuphelm repo add jetstack https://charts.jetstack.io --force-update# install cert-manager; this might take a little timehelm install \cert-manager jetstack/cert-manager \--namespace cert-manager \--create-namespace \--version v1.16.1 \--set crds.enabled=true# We need this namespace to exist since our cert will be placed therekubectl create namespace istio-system
3. cert-manager発行者と発行証明書の作成
発行者は、cert-managerに証明書の発行方法を指示します。ここでは、構成が非常に簡単なため、クラスター内に自己署名ルートCAを作成します。
ローカルで生成されたルート証明書を使用する方法は、本番環境のデプロイメントでも機能しますが、cert-managerにはいくつかの他の発行者も使用できる可能性があります。ACME発行者は、発行された証明書に必要なフィールドを追加できないため、機能しないことに注意してください。
example-issuerにも、詳細が少し記載されています。また、このガイドでは、ClusterIssuer
ではなくIssuer
のみを使用することにも注意してください。ClusterIssuer
を使用することはドロップインの代替ではなく、いずれにしても、本番環境のデプロイメントでは、より簡単なアクセス制御とスコープ設定のために発行者を使用することをお勧めします。
kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/7f5b2be9dd67831574b9bde2407bed4a920b691c/content/docs/tutorials/istio-csr/example/example-issuer.yaml
4. ルートCAをローカルファイルにエクスポートする
IstioがルートCAを自動的に「検出」できるように構成することは可能ですが、他のセキュリティホールに関連する特定のシナリオでは危険な可能性があり、署名者ハイジャック攻撃を可能にする可能性があります。
そのため、ルートCAをエクスポートし、後でその静的証明書を使用してIstioを構成します。
# Export our cert from the secret it's stored in, and base64 decode to get the PEM data.kubectl get -n istio-system secret istio-ca -ogo-template='{{index .data "tls.crt"}}' | base64 -d > ca.pem# Out of interest, we can check out what our CA looks likeopenssl x509 -in ca.pem -noout -text# Add our CA to a secretkubectl create secret generic -n cert-manager istio-root-ca --from-file=ca.pem=ca.pem
5. istio-csrのインストール
istio-csrはHelmを使用してインストールするのが最適であり、インストールは簡単かつ迅速である必要があります。Helmチャートには他の多くの構成オプションがあり、こちらで確認できます。
helm repo add jetstack https://charts.jetstack.io --force-update# We set a few helm template values so we can point at our static root CAhelm upgrade cert-manager-istio-csr jetstack/cert-manager-istio-csr \--install \--namespace cert-manager \--wait \--set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \--set "volumeMounts[0].name=root-ca" \--set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \--set "volumes[0].name=root-ca" \--set "volumes[0].secret.secretName=istio-root-ca"# Check to see that the istio-csr pod is running and readykubectl get pods -n cert-managerNAME READY STATUS RESTARTS AGEcert-manager-aaaaaaaaaa-11111 1/1 Running 0 9m46scert-manager-cainjector-aaaaaaaaaa-22222 1/1 Running 0 9m46scert-manager-istio-csr-bbbbbbbbbb-00000 1/1 Running 0 63scert-manager-webhook-aaaaaaaaa-33333 1/1 Running 0 9m46s
6. Istioのインストール
kindで実行していない場合は、Istioをインストールする前にいくつかの追加の設定タスクが必要になる場合があります。
ここでは、カスタムのIstioOperatorマニフェストを使用して構成されたistioctl
CLIを使用してIstioをインストールします。
カスタムマニフェストは次のことを行います。
- istiodのCAサーバーを無効にします。
- Istioワークロードがistio-csrから証明書を要求するようにします。
- istiodの証明書とキーが、istio-csrをインストールする際に作成された証明書からマウントされるようにします。
まず、デモマニフェストをダウンロードしてから適用します。
curl -sSL https://raw.githubusercontent.com/cert-manager/website/7f5b2be9dd67831574b9bde2407bed4a920b691c/content/docs/tutorials/istio-csr/example/istio-config-getting-started.yaml > istio-install-config.yaml
必要に応じて、istio-install-config.yaml
を検査して調整することもできますが、このマニフェストは例示目的でそのまま使用できます。
以前にhelmを介してistio-csrをインストールするときにカスタムのapp.tls.trustDomain
を設定した場合は、istio-install-config.yaml
にその値が繰り返されていることを確認する必要があります。
この最後のコマンドはIstioをインストールします。必要な正確なコマンドはプラットフォームによって異なる可能性があり、OpenShiftでは確実に異なります。
# This takes a little time to completeistioctl install -f istio-install-config.yaml# If you're on OpenShift, you need a different profile:# istioctl install --set profile=openshift -f istio-install-config.yaml
Istioプロファイルの選択を確認するための入力を求められます。
This will install the Istio 1.14.1 demo profile with ["Istio core" "Istiod" "Ingress gateways" "Egress gateways"] components into the cluster. Proceed? (y/N)
インストールを進めるには、コンソールにy
を入力して選択を確認します。
インストールの検証
次の手順はオプションですが、すべてが正しく接続されていることを検証するために実行できます。
- サンプルアプリケーションをデプロイし、
certificaterequests.cert-manager.io
リソースを監視します。 - 新しい
certificaterequests
と応答について、cert-manager
のログを確認します。 istio-proxy
サイドカーコンテナで使用されているCAエンドポイントを確認します。istioctl
を使用して、istio-proxy
コンテナの証明書情報をフェッチします。
実際に動作を確認するために、Istioサンプルから非常にシンプルなサンプルアプリケーションをデプロイしましょう。
まず、必要に応じて値を変更できる環境変数をいくつか設定します。
# Set namespace for sample applicationexport NAMESPACE=default# Set env var for the value of the app label in manifestsexport APP=httpbin# Grab the installed version of istioexport ISTIO_VERSION=$(istioctl version -o json | jq -r '.meshVersion[0].Info.version')
ここでは簡単にするためにdefault
ネームスペースを使用するので、Istioインジェクションのためにネームスペースにラベルを付けましょう。
kubectl label namespace $NAMESPACE istio-injection=enabled --overwrite
別のターミナルで、cert-manager
のログを監視する必要があります。
kubectl logs -n cert-manager $(kubectl get pods -n cert-manager -o jsonpath='{.items..metadata.name}' --selector app=cert-manager) --since 2m -f
さらに別のターミナルで、istio-system
ネームスペースのcertificaterequests
を監視しましょう。
kubectl get certificaterequests.cert-manager.io -n istio-system -w
次に、ラベル付けされたネームスペースにサンプルアプリケーションhttpbin
をデプロイします。インストール済みのIstioバージョンに合わせてマニフェストのバージョンを一致させるために変数が使用されていることに注意してください。
kubectl apply -n $NAMESPACE -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/httpbin/httpbin.yaml
certificaterequests
の出力として、ここに示されているものと同様のものが表示されるはずです。
NAME APPROVED DENIED READY ISSUER REQUESTOR AGEistio-ca-74bnl True True selfsigned system:serviceaccount:cert-manager:cert-manager 2d2histiod-w9zh6 True True istio-ca system:serviceaccount:cert-manager:cert-manager 27mistio-csr-8ddcs istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0sistio-csr-8ddcs True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0sistio-csr-8ddcs True True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0sistio-csr-8ddcs True True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s
重要なリクエストは、この出力例ではistio-csr-8ddcs
です。cert-manager
のログ出力を確認し、このリクエストが「Approved」および「Ready」になっている2つのログ行を確認する必要があります。
I0113 16:51:59.186482 1 conditions.go:261] Setting lastTransitionTime for CertificateRequest "istio-csr-8ddcs" condition "Approved" to 2022-01-13 16:51:59.186455713 +0000 UTC m=+3507.098466775I0113 16:51:59.258876 1 conditions.go:261] Setting lastTransitionTime for CertificateRequest "istio-csr-8ddcs" condition "Ready" to 2022-01-13 16:51:59.258837897 +0000 UTC m=+3507.170859959
アプリケーションコンテナとサイドカーの両方でアプリケーションが実行されていることが確認できるはずです。
~ kubectl get pods -n $NAMESPACENAME READY STATUS RESTARTS AGEhttpbin-74fb669cc6-559cg 2/2 Running 0 4m
istio-proxy
サイドカーコンテナが正しいサービスから証明書をリクエストしていることを検証するために、コンテナログを確認してください。
kubectl logs $(kubectl get pod -n $NAMESPACE -o jsonpath="{.items...metadata.name}" --selector app=$APP) -c istio-proxy
この例のような初期ログが表示されるはずです。
Istio v1.12以前のバージョン
2022-01-13T16:51:58.495493Z info CA Endpoint cert-manager-istio-csr.cert-manager.svc:443, provider Citadel2022-01-13T16:51:58.495817Z info Using CA cert-manager-istio-csr.cert-manager.svc:443 cert with certs: var/run/secrets/istio/root-cert.pem2022-01-13T16:51:58.495941Z info citadelclient Citadel client using custom root cert: cert-manager-istio-csr.cert-manager.svc:443
Istio v1.13+
2022-01-13T16:51:58.495493Z info CA Endpoint cert-manager-istio-csr.cert-manager.svc:443, provider Citadel2022-01-13T16:51:58.495817Z info Using CA cert-manager-istio-csr.cert-manager.svc:443 cert with certs: var/run/secrets/istio/root-cert.pem2022-01-13T16:51:58.495941Z info citadelclient Citadel client using custom root cert: var/run/secrets/istio/root-cert.pem
最後に、Envoyがメモリで使用している証明書を調べることができます。このワンライナーを実行すると、使用されている証明書が返されます。
istioctl proxy-config secret $(kubectl get pods -n $NAMESPACE -o jsonpath='{.items..metadata.name}' --selector app=$APP) -o json | jq -r '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' | base64 --decode | openssl x509 -text -noout
特に、以下のセクションを探してください。
Signature Algorithm: ecdsa-with-SHA256Issuer: O=cert-manager, O=cluster.local, CN=istio-caValidityNot Before: Jan 13 16:51:59 2022 GMTNot After : Jan 13 17:51:59 2022 GMT...X509v3 Subject Alternative Name:URI:spiffe://cluster.local/ns/default/sa/httpbin
発行者の中に、関連するトラストドメインが表示されるはずです。デフォルトの場合、上記のようにcluster.local
である必要があります。異なるネームスペースまたはアプリケーションを使用した場合は、SPIFFE URIが異なる可能性があることに注意してください。
クリーンアップ
kind内で実行している場合は、単純にクラスターを削除できます。
kind delete cluster
ランタイム構成によるインストール
ランタイム構成でインストールするには、2つのオプションがあります。
- cert-managerの後にインストールし、Helmチャートで明示的な
issuerRef
を引き続き指定します。 - Helmチャートの
issuerRef
を空白にし、純粋なランタイム構成を使用します。
どちらのオプションでも、発行者を指すConfigMapを作成する必要があります。このConfigMapはインストール前または後に作成でき、istio-csrポッドと同じネームスペースに作成する必要があります。
ConfigMapの作成
発行者の名前、種類、グループを指定する3つのキーが必要です。ConfigMapを作成する任意の方法を使用できます。例えば
kubectl create configmap -n cert-manager istio-issuer \--from-literal=issuer-name=my-issuer-name \--from-literal=issuer-kind=ClusterIssuer \--from-literal=issuer-group=cert-manager.io
Helmチャートには、必要に応じてインストール時にランタイム構成ConfigMapを作成する機能が、app.runtimeConfiguration.issuer
の値を通じて含まれています。
app:runtimeConfiguration:issuer:name: my-issuer-namekind: Issuergroup: cert-manager.io
オプション1:cert-manager後のインストール
cert-managerがすでにインストールされている場合は、上記のhelm upgrade
コマンドを使用できますが、ランタイム構成ConfigMapの名前も指定します。
helm upgrade cert-manager-istio-csr jetstack/cert-manager-istio-csr \--install \--namespace cert-manager \--wait \...--set "app.runtimeConfiguration.name=istio-issuer"
このシナリオでは、app.certmanager.issuer
で定義された発行者が起動時に使用され、istiod
証明書を作成するために使用されます。
istio-csrがランタイムConfigMapを検出すると、そこで構成された発行者を使用します。ConfigMapが更新されると、istio-csrは更新を動的に反映します。
ランタイムConfigMapが削除された場合、istio-csrはapp.certmanager.issuer
の値を使用するように戻ります。
オプション2:純粋なランタイム構成
純粋なランタイム構成は、istio-csr v0.11.0
以降でのみ実用的です。
純粋なランタイム構成では、より多くの値を設定する必要があります。
app.certmanager.issuer
の値は、(チャートでデフォルト値に設定されているため) 空白にする必要があります。istiod
証明書は、istio-csrリソースと一緒にプロビジョニングしないでください。app.tls.istiodCertificateEnable=dynamic
を渡すことで、ランタイム構成が利用可能になると、istiodが動的に生成されます。app.runtimeConfiguration.name
を設定する必要があります。
純粋なランタイム構成のvalues.yaml
ファイルの例を次に示します。
app:runtimeIssuanceConfigMap: istio-issuercertmanager:issuer:enabled: false # Important: the default issuer is enabled by defaulttls:rootCAFile: "/var/run/secrets/istio-csr/ca.pem"istiodCertificateEnable: dynamicvolumeMounts:- name: root-camountPath: /var/run/secrets/istio-csrvolumes:- name: root-casecret:secretName: istio-root-ca
このファイルは、次のコマンドで使用できます。
helm upgrade cert-manager-istio-csr jetstack/cert-manager-istio-csr \--install \--namespace cert-manager \--wait \--values values.yaml
純粋なランタイムインストールの完了
cert-managerと一緒にistio-csrをインストールしやすくするために、純粋なランタイム構成では、istio-csrのヘルスチェックの動作をわずかに変更します。これは、Helmがヘルスチェックが合格するまでインストールを完了しないためです。
純粋なランタイム構成を使用している場合に限り、istio-csrのヘルスチェックは、ランタイム構成が初めて利用可能になるまで正常として報告します。
ランタイム構成が初めて利用可能になった後、ヘルスチェックは通常の動作に戻ります。
使用法
📖 istio-csrドキュメントをご覧ください。