相互 TLS 遷移
此任務展示如何在將工作負載遷移到 Istio 時,確保其僅使用雙向 TLS 進行通訊。
當呼叫其他工作負載時,Istio 會自動配置工作負載 Sidecar 以使用雙向 TLS。預設情況下,Istio 使用 PERMISSIVE
模式配置目標工作負載。啟用 PERMISSIVE
模式時,服務可以接受純文字和雙向 TLS 流量。為了僅允許雙向 TLS 流量,需要將配置更改為 STRICT
模式。
您可以使用Grafana 儀表板來檢查哪些工作負載仍在向 PERMISSIVE
模式下的工作負載發送純文字流量,並在遷移完成後選擇鎖定它們。
開始之前
了解 Istio 身份驗證策略和相關的雙向 TLS 身份驗證概念。
閱讀身份驗證策略任務以了解如何配置身份驗證策略。
擁有已安裝 Istio 的 Kubernetes 叢集,且未啟用全域雙向 TLS(例如,使用安裝步驟中描述的
default
配置設定檔)。
在此任務中,您可以透過建立範例工作負載並修改策略以在工作負載之間強制執行 STRICT 雙向 TLS 來嘗試遷移過程。
設定叢集
建立兩個命名空間,
foo
和bar
,並在這兩個命名空間上部署帶有 Sidecar 的 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 $ 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
,並部署沒有 Sidecar 的 curl$ kubectl create ns legacy $ kubectl apply -f @samples/curl/curl.yaml@ -n legacy
透過從
foo
、bar
和legacy
命名空間中的 curl Pod 發送 HTTP 請求(使用 curl)到httpbin.foo
和httpbin.bar
來驗證設定。所有請求都應該成功,並返回代碼 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 Sidecar 後,您可以將 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.legacy
和 curl.foo
發送時,您將在輸出中看到純文字和加密文字。
如果您無法將所有服務遷移到 Istio(即,在所有服務中注入 Envoy Sidecar),則需要繼續使用 PERMISSIVE
模式。但是,當配置為 PERMISSIVE
模式時,預設情況下不會對純文字流量執行任何身份驗證或授權檢查。我們建議您使用 Istio 授權來配置具有不同授權策略的不同路徑。
限制整個網格使用雙向 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
現在,foo
和 bar
命名空間都強制僅使用雙向 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
清除範例
移除網格範圍的身份驗證策略。
$ kubectl delete peerauthentication -n foo default $ kubectl delete peerauthentication -n istio-system default
移除測試命名空間。
$ kubectl delete ns foo bar legacy Namespaces foo bar legacy deleted.