NEW: プロジェクトの最新情報をTwitterMastodonで入手してください

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 setup
helm repo add jetstack https://charts.jetstack.io --force-update
# install cert-manager; this might take a little time
helm 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 there
kubectl 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 like
openssl x509 -in ca.pem -noout -text
# Add our CA to a secret
kubectl 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 CA
helm 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 ready
kubectl get pods -n cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-aaaaaaaaaa-11111 1/1 Running 0 9m46s
cert-manager-cainjector-aaaaaaaaaa-22222 1/1 Running 0 9m46s
cert-manager-istio-csr-bbbbbbbbbb-00000 1/1 Running 0 63s
cert-manager-webhook-aaaaaaaaa-33333 1/1 Running 0 9m46s

6. Istioのインストール

kindで実行していない場合は、Istioをインストールする前にいくつかの追加の設定タスクが必要になる場合があります。

ここでは、カスタムのIstioOperatorマニフェストを使用して構成されたistioctlCLIを使用して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 complete
istioctl 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を入力して選択を確認します。

インストールの検証

次の手順はオプションですが、すべてが正しく接続されていることを検証するために実行できます。

  1. サンプルアプリケーションをデプロイし、certificaterequests.cert-manager.ioリソースを監視します。
  2. 新しいcertificaterequestsと応答について、cert-managerのログを確認します。
  3. istio-proxyサイドカーコンテナで使用されているCAエンドポイントを確認します。
  4. istioctlを使用して、istio-proxyコンテナの証明書情報をフェッチします。

実際に動作を確認するために、Istioサンプルから非常にシンプルなサンプルアプリケーションをデプロイしましょう。

まず、必要に応じて値を変更できる環境変数をいくつか設定します。

# Set namespace for sample application
export NAMESPACE=default
# Set env var for the value of the app label in manifests
export APP=httpbin
# Grab the installed version of istio
export 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 AGE
istio-ca-74bnl True True selfsigned system:serviceaccount:cert-manager:cert-manager 2d2h
istiod-w9zh6 True True istio-ca system:serviceaccount:cert-manager:cert-manager 27m
istio-csr-8ddcs istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s
istio-csr-8ddcs True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s
istio-csr-8ddcs True True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s
istio-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.098466775
I0113 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 $NAMESPACE
NAME READY STATUS RESTARTS AGE
httpbin-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 Citadel
2022-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.pem
2022-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 Citadel
2022-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.pem
2022-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-SHA256
Issuer: O=cert-manager, O=cluster.local, CN=istio-ca
Validity
Not Before: Jan 13 16:51:59 2022 GMT
Not 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つのオプションがあります。

  1. cert-managerの後にインストールし、Helmチャートで明示的なissuerRefを引き続き指定します。
  2. 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-name
kind: Issuer
group: 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以降でのみ実用的です。

純粋なランタイム構成では、より多くの値を設定する必要があります。

  1. app.certmanager.issuerの値は、(チャートでデフォルト値に設定されているため) 空白にする必要があります。
  2. istiod証明書は、istio-csrリソースと一緒にプロビジョニングしないでください。app.tls.istiodCertificateEnable=dynamicを渡すことで、ランタイム構成が利用可能になると、istiodが動的に生成されます。
  3. app.runtimeConfiguration.nameを設定する必要があります。

純粋なランタイム構成のvalues.yamlファイルの例を次に示します。

app:
runtimeIssuanceConfigMap: istio-issuer
certmanager:
issuer:
enabled: false # Important: the default issuer is enabled by default
tls:
rootCAFile: "/var/run/secrets/istio-csr/ca.pem"
istiodCertificateEnable: dynamic
volumeMounts:
- name: root-ca
mountPath: /var/run/secrets/istio-csr
volumes:
- name: root-ca
secret:
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ドキュメントをご覧ください。