Mutual TLSマイグレーション

このタスクでは、ワークロードをIstioに移行する際に、相互TLSのみを使用してワークロードが通信するようにする方法を示します。

Istioは、他のワークロードを呼び出す際に、ワークロードサイドカーが相互TLSを使用するように自動的に構成します。デフォルトでは、IstioはPERMISSIVEモードを使用して宛先ワークロードを構成します。PERMISSIVEモードが有効になっている場合、サービスはプレーンテキストと相互TLSトラフィックの両方を受け入れることができます。相互TLSトラフィックのみを許可するには、構成をSTRICTモードに変更する必要があります。

Grafanaダッシュボードを使用して、PERMISSIVEモードのワークロードにプレーンテキストトラフィックを送信しているワークロードを確認し、移行が完了したらそれらをロックダウンすることを選択できます。

始める前に

  • Istioの認証ポリシーと関連する相互TLS認証の概念を理解してください。

  • 認証ポリシーのタスクを読んで、認証ポリシーを構成する方法を学んでください。

  • グローバル相互TLSが無効になっているIstioがインストールされたKubernetesクラスタが必要です(たとえば、インストール手順で説明されているdefault構成プロファイルを使用します)。

このタスクでは、サンプルワークロードを作成し、ワークロード間でSTRICTな相互TLSを強制するようポリシーを変更することで、移行プロセスを試すことができます。

クラスタのセットアップ

  • foobarという2つの名前空間を作成し、それぞれにサイドカー付きのhttpbincurlをデプロイします。

    ZipZipZipZip
    $ 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
    $ kubectl create ns bar
    $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n bar
    $ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@) -n bar
    
  • 別の名前空間legacyを作成し、サイドカーなしでcurlをデプロイします。

    Zip
    $ kubectl create ns legacy
    $ kubectl apply -f @samples/curl/curl.yaml@ -n legacy
    
  • foobarlegacy名前空間のcurlポッドからhttpbin.foohttpbin.barにhttpリクエスト(curlを使用)を送信して、設定を検証します。すべてのリクエストは、リターンコード200で成功する必要があります。

    $ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=curl -n ${from} -o jsonpath={.items..metadata.name})" -c curl -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "curl.${from} to httpbin.${to}: %{http_code}\n"; done; done
    curl.foo to httpbin.foo: 200
    curl.foo to httpbin.bar: 200
    curl.bar to httpbin.foo: 200
    curl.bar to httpbin.bar: 200
    curl.legacy to httpbin.foo: 200
    curl.legacy to httpbin.bar: 200
    

名前空間ごとの相互TLSへのロックダウン

すべてのクライアントをIstioに移行し、Envoyサイドカーを注入した後、foo名前空間のワークロードを相互TLSトラフィックのみを受け入れるようにロックダウンできます。

$ kubectl apply -n foo -f - <<EOF
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
spec:
  mtls:
    mode: STRICT
EOF

これで、curl.legacyからhttpbin.fooへのリクエストが失敗するはずです。

$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=curl -n ${from} -o jsonpath={.items..metadata.name})" -c curl -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "curl.${from} to httpbin.${to}: %{http_code}\n"; done; done
curl.foo to httpbin.foo: 200
curl.foo to httpbin.bar: 200
curl.bar to httpbin.foo: 200
curl.bar to httpbin.bar: 200
curl.legacy to httpbin.foo: 000
command terminated with exit code 56
curl.legacy to httpbin.bar: 200

values.global.proxy.privileged=trueでIstioをインストールした場合、tcpdumpを使用して、トラフィックが暗号化されているかどうかを確認できます。

$ kubectl exec -nfoo "$(kubectl get pod -nfoo -lapp=httpbin -ojsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port 80  -A
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

curl.legacycurl.fooからそれぞれリクエストが送信されると、出力に平文と暗号化されたテキストが表示されます。

すべてのサービスをIstioに移行できない場合(つまり、すべてにEnvoyサイドカーを注入できない場合)、PERMISSIVEモードを引き続き使用する必要があります。ただし、PERMISSIVEモードで構成した場合、デフォルトでは、平文トラフィックに対して認証または承認チェックは実行されません。Istio Authorizationを使用して、異なる承認ポリシーを持つ異なるパスを構成することをお勧めします。

メッシュ全体の相互TLSのロックダウン

Istioインストールのシステム名前空間にポリシーを配置することで、すべての名前空間のワークロードを相互TLSトラフィックのみを受け入れるようにロックダウンできます。

$ kubectl apply -n istio-system -f - <<EOF
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
spec:
  mtls:
    mode: STRICT
EOF

これで、foobarの両方の名前空間で相互TLSのみのトラフィックが強制されるため、curl.legacyからのリクエストが両方とも失敗するはずです。

$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=curl -n ${from} -o jsonpath={.items..metadata.name})" -c curl -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "curl.${from} to httpbin.${to}: %{http_code}\n"; done; done

例のクリーンアップ

  1. メッシュ全体の認証ポリシーを削除します。

    $ kubectl delete peerauthentication -n foo default
    $ kubectl delete peerauthentication -n istio-system default
    
  2. テスト名前空間を削除します。

    $ kubectl delete ns foo bar legacy
    Namespaces foo bar legacy deleted.
    
この情報は役に立ちましたか?
改善のためのご提案はありますか?

フィードバックありがとうございます!