背景資訊
為了確保Service MeshASM正常工作,Istio需要在網格中的每個Pod中配置一個Envoy代理,通過Iptables規則控制Pod的流量,以便通過注入的Envoy代理將流量重新導向到應用程式。因為每個Pod的Iptables規則都是網路命名,所以更改不會影響節點上的其他Pod。
預設情況下,Istio在Pod中注入istio-init容器,並在Pod中的其他容器啟動之前設定必要的Iptables規則。這就要求操作者部署容器時具有足夠的特權,包括部署具有NET_ADMIN功能的其他容器、重新設定網路等。
Service MeshASM支援使用CNI外掛程式,將Iptables規則配置移出Pod。CNI外掛程式不要求Istio使用者啟用Priviledge許可權,在Pod的網路設定階段執行流量重新導向,從而消除了對NET_ADMIN能力的依賴要求。CNI外掛程式啟用後,其配置將被插入到容器CNI外掛程式鏈中,從而在容器啟動時被調用執行。
CNI外掛程式根據以下條件進行尋找需要重新導向流量的Pod:
Pod的命名空間不在配置的excludeNamespaces列表中。
Pod中包含一個名為istio-proxy的容器。
Pod中有多個容器。
Pod中存在sidecar.istio.io/status
註解。
Pod中sidecar.istio.io/inject
的值不為false
。
啟用CNI外掛程式
您可以通過ASM控制台為ASM執行個體啟用CNI外掛程式,具體操作步驟如下:
登入ASM控制台。
在網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇。
在網格CNI外掛程式頁面,開啟是否啟用網格CNI外掛程式開關,選中需要排除的命名空間,然後單擊更新設定。
被排除的命名空間的Pod啟動時將通過istio-init進行網路設定,不通過CNI進行網路設定。當目標執行個體的狀態由更新中變為運行中,表示CNI外掛程式啟用成功。
驗證Iptables規則
本文以在叢集中部署bookinfo應用為例,驗證攔截規則是否生效。
使用以下內容,建立bookinfo.yaml。
展開查看bookinfo.yaml
##################################################################################################
# Details service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: details
labels:
app: details
service: details
spec:
ports:
- port: 9080
name: http
selector:
app: details
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-details
labels:
account: details
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: details-v1
labels:
app: details
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: details
version: v1
template:
metadata:
labels:
app: details
version: v1
spec:
serviceAccountName: bookinfo-details
containers:
- name: details
image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Ratings service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: ratings
labels:
app: ratings
service: ratings
spec:
ports:
- port: 9080
name: http
selector:
app: ratings
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-ratings
labels:
account: ratings
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ratings-v1
labels:
app: ratings
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: ratings
version: v1
template:
metadata:
labels:
app: ratings
version: v1
spec:
serviceAccountName: bookinfo-ratings
containers:
- name: ratings
image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Reviews service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: reviews
labels:
app: reviews
service: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-reviews
labels:
account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v1
labels:
app: reviews
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v1
template:
metadata:
labels:
app: reviews
version: v1
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v2
labels:
app: reviews
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v2
template:
metadata:
labels:
app: reviews
version: v2
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v3
labels:
app: reviews
version: v3
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v3
template:
metadata:
labels:
app: reviews
version: v3
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
##################################################################################################
# Productpage services
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: productpage
labels:
app: productpage
service: productpage
spec:
ports:
- port: 9080
name: http
selector:
app: productpage
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-productpage
labels:
account: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-v1
labels:
app: productpage
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v1
template:
metadata:
labels:
app: productpage
version: v1
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
securityContext:
runAsUser: 1000
volumes:
- name: tmp
emptyDir: {}
---
執行以下命令,部署bookinfo。
kubectl apply -f bookinfo.yaml
執行以下命令,擷取Productpage Pod的容器ID、節點名稱。
ns=default
podname=kubectl get pod |grep productpage
#容器運行時為Docker時,使用下面命令。
container_id=$(kubectl get pod -n ${ns} ${podname} -o jsonpath="{.status.containerStatuses[?(@.name=='istio-proxy')].containerID}" | sed -n 's/docker:\/\/\(.*\)/\1/p')
#容器運行時為Containerd時,使用下面命令。
container_id=$(kubectl get pod -n ${ns} ${podname} -o jsonpath="{.status.containerStatuses[?(@.name=='istio-proxy')].containerID}" | sed -n 's/containerd:\/\/\(.*\)/\1/p')
echo $container_id
#擷取節點名稱。
kubectl get pod ${podname} -o jsonpath="{.spec.nodeName}"
登入Productpage Pod的節點(例如使用SSH),執行以下命令,擷取映射到Conatiner ID的對應進程。
#容器運行時為Docker時,使用下面命令。
docker inspect --format '{{ .State.Pid }}' $container_id
#容器運行時為Containerd時,使用下面命令。
crictl inspect $container_id|jq ".info.pid"
執行以下命令,進入Productpage容器的網路命名空間,擷取當前配置。
nsenter -t $ -n iptables -L -t nat -n -v --line-numbers -x
展開查看預期輸出
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 34938 2096280 ISTIO_INBOUND tcp -- * * 0.0.0.0/0 0.0.0.0/0
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 17 1020 ISTIO_OUTPUT tcp -- * * 0.0.0.0/0 0.0.0.0/0
Chain ISTIO_INBOUND (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15008
2 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
3 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15020
4 34938 2096280 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15021
5 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15090
6 0 0 ISTIO_IN_REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0
Chain ISTIO_REDIRECT (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 15001
Chain ISTIO_IN_REDIRECT (3 references)
num pkts bytes target prot opt in out source destination
1 1 60 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 15006
Chain ISTIO_OUTPUT (1 references)
num pkts bytes target prot opt in out source destination
1 2 120 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15020
2 0 0 RETURN all -- * lo 127.0.X.X 0.0.0.0/0
3 1 60 ISTIO_IN_REDIRECT all -- * lo 0.0.0.0/0 !127.0.X.X owner UID match 1337
4 0 0 RETURN all -- * lo 0.0.0.0/0 0.0.0.0/0 ! owner UID match 1337
5 14 840 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner UID match 1337
6 0 0 ISTIO_IN_REDIRECT all -- * lo 0.0.0.0/0 !127.0.X.X owner GID match 1337
7 0 0 RETURN all -- * lo 0.0.0.0/0 0.0.0.0/0 ! owner GID match 1337
8 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner GID match 1337
9 0 0 RETURN all -- * * 0.0.0.0/0 127.0.X.X
10 0 0 RETURN all -- * * 0.0.0.0/0 192.168.0.1
11 0 0 ISTIO_REDIRECT all -- * * 0.0.0.0/0 0.0.0.0/0
由預期輸出得到,存在ISTIO_INBOUND
、ISTIO_REDIRECT
、ISTIO_IN_REDIRECT
、 ISTIO_OUTPUT
等規則,表明攔截規則已經生效。