プラグインCA証明書
このタスクでは、管理者がルート証明書、署名証明書、および鍵を使用してIstio認証局(CA)を設定する方法を示します。
デフォルトでは、Istio CAは自己署名ルート証明書と鍵を生成し、それらを使用してワークロード証明書に署名します。ルートCA鍵を保護するには、安全なマシンでオフラインで実行されるルートCAを使用し、そのルートCAを使用して、各クラスタで実行されるIstio CAに中間証明書を発行する必要があります。Istio CAは、管理者指定の証明書と鍵を使用してワークロード証明書に署名し、管理者指定のルート証明書を信頼のルートとしてワークロードに配布できます。
次のグラフは、2つのクラスタを含むメッシュにおける推奨CA階層を示しています。
このタスクでは、Istio CAの証明書と鍵を生成してプラグインする方法を示します。これらの手順を繰り返して、各クラスタで実行されているIstio CAの証明書と鍵をプロビジョニングできます。
証明書と鍵をクラスタにプラグインする
Istioインストールパッケージのトップレベルディレクトリに、証明書と鍵を格納するディレクトリを作成します。
$ mkdir -p certs $ pushd certs
ルート証明書と鍵を生成します。
$ make -f ../tools/certs/Makefile.selfsigned.mk root-ca
これにより、以下のファイルが生成されます。
root-cert.pem
:生成されたルート証明書root-key.pem
:生成されたルート鍵root-ca.conf
:ルート証明書を生成するためのopenssl
の設定root-cert.csr
:生成されたルート証明書のCSR
クラスタごとに、Istio CAの中間証明書と鍵を生成します。
cluster1
の例を以下に示します。$ make -f ../tools/certs/Makefile.selfsigned.mk cluster1-cacerts
これにより、
cluster1
という名前のディレクトリに以下のファイルが生成されます。ca-cert.pem
:生成された中間証明書ca-key.pem
:生成された中間鍵cert-chain.pem
:istiodで使用される生成された証明書チェーンroot-cert.pem
:ルート証明書
cluster1
は任意の文字列に置き換えることができます。たとえば、引数cluster2-cacerts
を使用すると、cluster2
というディレクトリに証明書と鍵を作成できます。オフラインマシンでこれを実行している場合は、生成されたディレクトリをクラスタにアクセスできるマシンにコピーします。
各クラスタで、入力ファイル
ca-cert.pem
、ca-key.pem
、root-cert.pem
、およびcert-chain.pem
を含むシークレットcacerts
を作成します。cluster1
の例を以下に示します。$ kubectl create namespace istio-system $ kubectl create secret generic cacerts -n istio-system \ --from-file=cluster1/ca-cert.pem \ --from-file=cluster1/ca-key.pem \ --from-file=cluster1/root-cert.pem \ --from-file=cluster1/cert-chain.pem
Istioインストールのトップレベルディレクトリに戻ります。
$ popd
Istioのデプロイ
demo
プロファイルを使用してIstioをデプロイします。IstioのCAは、シークレットマウントファイルから証明書と鍵を読み取ります。
$ istioctl install --set profile=demo
サンプルサービスのデプロイ
サンプルサービス
httpbin
とcurl
をデプロイします。$ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo $ kubectl apply -f <(istioctl kube-inject -f samples/curl/curl.yaml) -n foo
foo
名前空間のワークロードが相互TLSトラフィックのみを受け入れるようにポリシーをデプロイします。$ kubectl apply -n foo -f - <<EOF apiVersion: security.istio.io/v1 kind: PeerAuthentication metadata: name: "default" spec: mtls: mode: STRICT EOF
証明書の検証
このセクションでは、ワークロード証明書がCAにプラグインした証明書によって署名されていることを確認します。これには、マシンにopenssl
がインストールされている必要があります。
httpbin
の証明書チェーンを取得する前に、mTLSポリシーが有効になるまで20秒間待機します。この例で使用されているCA証明書は自己署名されているため、opensslコマンドによって返されるverify error:num=19:self signed certificate in certificate chain
エラーは予期されています。$ sleep 20; kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo -- openssl s_client -showcerts -connect httpbin.foo:8000 > httpbin-proxy-cert.txt
証明書チェーンの証明書を解析します。
$ sed -n '/-----BEGIN CERTIFICATE-----/{:start /-----END CERTIFICATE-----/!{N;b start};/.*/p}' httpbin-proxy-cert.txt > certs.pem $ awk 'BEGIN {counter=0;} /BEGIN CERT/{counter++} { print > "proxy-cert-" counter ".pem"}' < certs.pem
ルート証明書が管理者によって指定されたものと同じであることを確認します。
$ openssl x509 -in certs/cluster1/root-cert.pem -text -noout > /tmp/root-cert.crt.txt $ openssl x509 -in ./proxy-cert-3.pem -text -noout > /tmp/pod-root-cert.crt.txt $ diff -s /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt Files /tmp/root-cert.crt.txt and /tmp/pod-root-cert.crt.txt are identical
CA証明書が管理者によって指定されたものと同じであることを確認します。
$ openssl x509 -in certs/cluster1/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt $ openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt $ diff -s /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt Files /tmp/ca-cert.crt.txt and /tmp/pod-cert-chain-ca.crt.txt are identical
ルート証明書からワークロード証明書までの証明書チェーンを確認します。
$ openssl verify -CAfile <(cat certs/cluster1/ca-cert.pem certs/cluster1/root-cert.pem) ./proxy-cert-1.pem ./proxy-cert-1.pem: OK
クリーンアップ
ローカルディスクから証明書、鍵、および中間ファイルを削除します。
$ rm -rf certs
シークレット
cacerts
を削除します。$ kubectl delete secret cacerts -n istio-system
foo
名前空間から認証ポリシーを削除します。$ kubectl delete peerauthentication -n foo default
サンプルアプリケーション
curl
とhttpbin
を削除します。$ kubectl delete -f samples/curl/curl.yaml -n foo $ kubectl delete -f samples/httpbin/httpbin.yaml -n foo
クラスタからIstioをアンインストールします。
$ istioctl uninstall --purge -y
クラスタから名前空間
foo
とistio-system
を削除します。$ kubectl delete ns foo istio-system