ASM自1.16.4版本起,支持使用ASMEgressTrafficPolicy CRD。本文介紹如何使用ASMEgressTrafficPolicy管理出口流量。
背景信息
實現原理
服務網格支持出口流量管理,通過創建ServiceEntry、VirtualService、Gateway以及Destination等多個資源,并且確保這些資源之間相互關聯,配置完成后即可實現將流量透明劫持到出口網關,并由出口網關轉發給外部服務。
這些配置比較復雜,需要您對相關字段的含義有較為深入的理解,而且容易配置出錯。為了降低出口流量配置門檻,ASM推出了ASMEgressTrafficPolicy資源。
ASMEgressTrafficPolicy將出口流量配置進行了抽象和簡化,您無需手動配置ServiceEntry、VirtualService、Gateway以及Destination等資源,只需要填寫一些必要配置,即可實現將流量透明劫持到出口網關,并且通過HTTP/HTTPS協議發送給外部服務。
由于ASMEgressTrafficPolicy對服務網格原生資源進行了簡化,可能并不能滿足您的一些高級需求(比如出口流量按比例路由、出口網關發起mTLS等)。如果您需要使用一些高級功能,例如添加自定義配置,請參見為網格內流量配置統一的出口網關。
功能介紹
ASM提供了一種統一的方式來連接、管理和保護應用程序之間的通信。與基于網絡IP的方法不同,ASM采用以應用程序為中心的方法,且無需修改現有的應用代碼。ASMEgressTrafficPolicy定義了如何通過出口網關來管理和訪問外部流量。通過結合ASM出口網關和AuthorizationPolicy,您可以更靈活地控制出口流量。
本文示例的流量鏈路可以分為兩大類:
1. 網格代理之間以及網格代理和網關之間的通信:通信默認開啟mTLS,證書完全由ASM管理。
2. 應用與網格代理之間以及網關和集群外服務之間:
a. 為了網格7層高級能力可以正常運行,應用與網格代理之間盡量采用明文通信。這樣網格代理可以獲取流量的L7信息,支持更多的高級功能。如果由于某些特殊原因,應用必須直接發起HTTPS,這時只能使用網格的L4能力。
b. 出口網關和外部服務之間的通信協議用戶可以自行配置,明文或者HTTPS都可以。
前提條件
準備工作
一、設置外部服務訪問策略
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 。
在全局頁簽,單擊外部服務訪問策略,然后在對外部服務的訪問策略OutboundTrafficPolicy右側,單擊REGISTRY_ONLY,然后單擊更新設置。
二、創建命名空間
創建istio-egress命名空間。具體操作,請參見管理全局命名空間。
在全局命名空間頁面,單擊同步自動注入至Kubernetes集群,將該命名空間同步至ASM實例管理的ACK集群。
三、創建出口網關
在ASM中創建一個名為egressgateway-a的出口網關,端口映射配置為HTTP 80、HTTPS 443和HTTPS 444,并開啟支持雙向TLS認證。具體操作,請參見創建出口網關服務。
請確保在生成的YAML文件中,spec字段中包含以下內容。若不存在,請進行添加。
spec:
podLabels:
security.istio.io/tlsMode: istio
四、創建應用示例
在ASM實例中,創建名為mytest的命名空間并開啟自動注入。具體操作,請參見管理全局命名空間。
在ACK集群中,在mytest命名空間中部署sleep-a服務,在default命名空間中部署nginx服務。
使用以下內容,創建test.yaml。
apiVersion: v1 kind: Service metadata: name: sleep-a namespace: mytest labels: app: sleep-a service: sleep-a spec: ports: - port: 80 name: http selector: app: sleep-a --- apiVersion: apps/v1 kind: Deployment metadata: name: sleep-a namespace: mytest spec: replicas: 1 selector: matchLabels: app: sleep-a template: metadata: labels: app: sleep-a spec: terminationGracePeriodSeconds: 0 containers: - name: sleep image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/curl:asm-sleep command: ["/bin/sleep", "infinity"] imagePullPolicy: IfNotPresent volumeMounts: - mountPath: /etc/sleep/tls name: secret-volume volumes: - name: secret-volume secret: secretName: sleep-secret optional: true --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx namespace: default spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app: nginx strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: nginx spec: containers: - image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/nginx:1.27.0 imagePullPolicy: Always name: nginx resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30
在ACK集群中,執行以下命令,部署sleep-a和nginx服務。
kubectl apply -f test.yaml
執行以下命令,通過sleep-a和nginx服務訪問
http://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果均返回
502
,表明訪問失敗。
sleep-a服務訪問HTTP外部服務
方案一:sidecar到出口網關之間使用HTTP明文
此方案在實際環境中并不合理,目前ASMEgressTrafficPolicy并不支持使用HTTP明文訪問出口網關。
流量管理主要在客戶端sidecar實施,并不需要出口網關。
可觀測不依賴出口網關。
安全能力依賴出口網關,但是如果沒有mTLS,基于客戶端身份的所有授權能力將不可用。出口網關只能無差別地拒絕所有請求。
方案二:sidecar到出口網關之間使用mTLS(推薦方案)
通過控制臺界面配置
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 。
單擊網關名稱,進入網關概覽頁。單擊左側出口流量策略。參照下圖進行配置。
驗證ASMEgressTrafficPolicy配置是否生效。
執行以下命令,通過default命名空間下的nginx服務訪問
http://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
502
,表明nginx服務訪問http://www.httpbin.org
失敗。執行以下命令,通過mytest命名空間下的sleep-a服務訪問
http://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
200
,符合預期。說明由于
http://www.httpbin.org
屬于海外站點,如果您在實際驗證過程中出現響應時間長的情況,可以考慮將ASMEgressTrafficPolicy
和測試命令中的hosts
更換為其他地址,例如aliyun.com
。如果您使用aliyun.com
作為實際驗證的host,由于aliyun站點默認強制使用HTTPS協議,此處的預期返回應為301
重定向。在網關出口流量策略頁面右側單擊清空規則,刪除ASMEgressTrafficPolicy配置。再次通過mytest命名空間下的sleep-a服務訪問
http://www.httpbin.org
。kubectl -n istio-egress delete ASMEgressTrafficPolicy egress-by-egressgateway kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
502
,表明刪除ASMEgressTrafficPolicy配置后,sleep-a服務http://www.httpbin.org
失敗。
輸出以上結果,表明ASMEgressTrafficPolicy配置生效。
通過kubectl配置
使用以下內容,創建egress-by-egressgateway.yaml。
關于字段的相關說明,請參見ASMEgressTrafficPolicy CRD說明。
apiVersion: istio.alibabacloud.com/v1 kind: ASMEgressTrafficPolicy metadata: name: egress-by-egressgateway # 名稱約定為egress-by-{出口網關名稱},與出口網關對應。 namespace: istio-egress # 命名空間約定:固定到istio-egress命名空間。 spec: byEgressGateway: name: egressgateway egressRules: - from: - namespace: mytest workloadSelector: app: sleep-a to: - name: httpbin-service-http hosts: - www.httpbin.org # 要求多個域名對應DNS解析返回的地址保持一致。 - httpbin.org # 要求多個域名對應DNS解析返回的地址保持一致。 port: name: http number: 80 protocol: HTTP byEgressGateway: port: 80 # Sidecar → 80 Gateway → 80 Service (httpbin.org)
在ACK集群中,執行以下命令,創建ASMEgressTrafficPolicy資源。
kubectl apply -f egress-by-egressgateway.yaml
驗證ASMEgressTrafficPolicy配置是否生效。
執行以下命令,通過default命名空間下的nginx服務訪問
http://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
502
,表明nginx服務訪問http://www.httpbin.org
失敗。執行以下命令,通過mytest命名空間下的sleep-a服務訪問
http://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
200
,符合預期。說明由于
http://www.httpbin.org
屬于海外站點,如果您在實際驗證過程中出現響應時間長的情況,可以考慮將ASMEgressTrafficPolicy
和測試命令中的hosts
更換為其他地址,例如aliyun.com
。如果您使用aliyun.com
作為實際驗證的host,由于aliyun站點默認強制使用HTTPS協議,此處的預期返回應為301
重定向。執行以下命令,刪除egress-by-egressgateway后,再次通過mytest命名空間下的sleep-a服務訪問
http://www.httpbin.org
。kubectl -n istio-egress delete ASMEgressTrafficPolicy egress-by-egressgateway kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
502
,表明刪除ASMEgressTrafficPolicy配置后,sleep-a服務http://www.httpbin.org
失敗。
輸出以上結果,表明ASMEgressTrafficPolicy配置生效。
sleep-a服務訪問HTTPS外部服務
方案一:sidecar到出口網關之間使用mTLS(推薦方案)
通過控制臺界面配置
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 。
單擊網關名稱,進入網關概覽頁。單擊左側出口流量策略。參照下圖進行配置。
驗證ASMEgressTrafficPolicy配置是否生效。
驗證mytest命名空間下的sleep-a服務。
執行以下命令,通過sleep-a服務訪問
http://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://httpbin.org
輸出結果返回
200
,表明sleep-a服務訪問http://www.httpbin.org
成功。執行以下命令,請求
httpbin.org
的anything
接口,驗證出口網關是否將HTTP請求升級為HTTPS請求。kubectl -n mytest exec deployment/sleep-a -- sh -c "curl -s http://httpbin.org/anything |grep url"
預期輸出:
"url": "https://httpbin.org/anything"
可以看到,
url
字段信息以https
開頭,表明出口網關將請求成功升級為https
,然后轉發給httpbin.org
。執行以下命令,通過mytest命名空間下的sleep-a服務訪問
https://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
輸出結果返回
200
,表明sleep-a服務訪問https://www.httpbin.org
成功。
驗證default命名空間下的Nginx服務。
執行以下命令,通過Nginx服務訪問
http://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
502
,表明nginx服務訪問http://www.httpbin.org
失敗。執行以下命令,通過Nginx服務訪問
https://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
輸出結果顯示請求連接被拒絕,表明Nginx服務訪問
https://www.httpbin.org
失敗。執行以下命令,查看Nginx工作負載對應的Sidecar的accesslog,了解連接被拒絕的原因。
kubectl -n default logs -f deployment/nginx -c istio-proxy --tail=1
預期輸出:
{"authority":"-","bytes_received":"0","bytes_sent":"0","downstream_local_address":"52.86.XX.XX:443","downstream_remote_address":"172.16.0.199:56748","duration":"0","istio_policy_status":"-","method":"-","path":"-","protocol":"-","request_id":"-","requested_server_name":"-","response_code":"0","response_flags":"UH","route_name":"-","start_time":"2023-04-11T02:00:07.409Z","trace_id":"-","upstream_cluster":"BlackHoleCluster","upstream_host":"-","upstream_local_address":"-","upstream_service_time":"-","upstream_transport_failure_reason":"-","user_agent":"-","x_forwarded_for":"-"}
預期輸出表明,請求轉發給
BlackHoleCluster
,因此導致連接被拒絕。
在網關出口流量策略頁面右側單擊清空規則,再次通過mytest命名空間下的sleep-a服務訪問
http://www.httpbin.org
和https://www.httpbin.org
。kubectl -n istio-egress delete ASMEgressTrafficPolicy egress-by-egressgateway kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
訪問
http://www.httpbin.org
時,返回502
;訪問https://www.httpbin.org
時,請求連接被拒絕。刪除ASMEgressTrafficPolicy配置后,sleep-a服務無法訪問http://www.httpbin.org
和https://www.httpbin.org
。輸出以上結果,表明ASMEgressTrafficPolicy配置生效。
通過kubectl配置
使用以下內容,更新egress-by-egressgateway.yaml。
在spec字段下增加了httpsUpgrade字段和直接訪問
https://www.httpbin.org
的相關定義。關于字段的相關說明,請參見ASMEgressTrafficPolicy CRD說明。apiVersion: istio.alibabacloud.com/v1 kind: ASMEgressTrafficPolicy metadata: name: egress-by-egressgateway # 名稱約定為egress-by-{出口網關名稱},與出口網關對應。 namespace: istio-egress # 命名空間約定:固定到istio-egress命名空間。 spec: byEgressGateway: name: egressgateway egressRules: - from: - namespace: mytest workloadSelector: app: sleep-a to: - name: httpbin-service-http hosts: - www.httpbin.org # 要求多個域名對應DNS解析返回的地址一致。 - httpbin.org # 要求多個域名對應DNS解析返回的地址一致。 port: name: http number: 80 protocol: HTTP byEgressGateway: port: 80 # Sidecar → 80 Gateway → 80 Service (httpbin.org) httpsUpgrade: enabled: true # 若enabled配置為false,則httpsUpgrade對應的port不生效。 port: 443 # Sidecar → 80 Gateway → 443 Service (httpbin.org)
在ACK集群中,執行以下命令,創建ASMEgressTrafficPolicy資源。
kubectl apply -f egress-by-egressgateway.yaml
驗證ASMEgressTrafficPolicy配置是否生效。
驗證mytest命名空間下的sleep-a服務。
執行以下命令,通過sleep-a服務訪問
http://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://httpbin.org
輸出結果返回
200
,表明sleep-a服務訪問http://www.httpbin.org
成功。執行以下命令,請求
httpbin.org
的anything
接口,驗證出口網關是否將HTTP請求升級為HTTPS請求。kubectl -n mytest exec deployment/sleep-a -- sh -c "curl -s http://httpbin.org/anything |grep url"
預期輸出:
"url": "https://httpbin.org/anything"
可以看到,
url
字段信息以https
開頭,表明出口網關將請求成功升級為https
,然后轉發給httpbin.org
。執行以下命令,通過mytest命名空間下的sleep-a服務訪問
https://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
輸出結果返回
200
,表明sleep-a服務訪問https://www.httpbin.org
成功。
驗證default命名空間下的Nginx服務。
執行以下命令,通過Nginx服務訪問
http://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
502
,表明nginx服務訪問http://www.httpbin.org
失敗。執行以下命令,通過Nginx服務訪問
https://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
輸出結果顯示請求連接被拒絕,表明Nginx服務訪問
https://www.httpbin.org
失敗。執行以下命令,查看Nginx工作負載對應的Sidecar的accessLog,了解連接被拒絕的原因。
kubectl -n default logs -f deployment/nginx -c istio-proxy --tail=1
預期輸出:
{"authority":"-","bytes_received":"0","bytes_sent":"0","downstream_local_address":"52.86.XX.XX:443","downstream_remote_address":"172.16.0.199:56748","duration":"0","istio_policy_status":"-","method":"-","path":"-","protocol":"-","request_id":"-","requested_server_name":"-","response_code":"0","response_flags":"UH","route_name":"-","start_time":"2023-04-11T02:00:07.409Z","trace_id":"-","upstream_cluster":"BlackHoleCluster","upstream_host":"-","upstream_local_address":"-","upstream_service_time":"-","upstream_transport_failure_reason":"-","user_agent":"-","x_forwarded_for":"-"}
預期輸出表明,請求轉發給
BlackHoleCluster
,因此導致連接被拒絕。
執行以下命令,刪除egress-by-egressgateway后,再次通過mytest命名空間下的sleep-a服務訪問
http://www.httpbin.org
和https://www.httpbin.org
。kubectl -n istio-egress delete ASMEgressTrafficPolicy egress-by-egressgateway kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
訪問
http://www.httpbin.org
時,返回502
;訪問https://www.httpbin.org
時,請求連接被拒絕。刪除ASMEgressTrafficPolicy配置后,sleep-a服務無法訪問http://www.httpbin.org
和https://www.httpbin.org
。
輸出以上結果,表明ASMEgressTrafficPolicy配置生效。
方案二:sidecar到出口網關之間使用HTTPS
通過控制臺界面配置
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 。
單擊網關名稱,進入網關概覽頁。單擊左側出口流量策略。參照下圖進行配置。
驗證ASMEgressTrafficPolicy配置是否生效。
驗證mytest命名空間下的sleep-a服務。
執行以下命令,通過sleep-a服務訪問
http://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://httpbin.org
輸出結果返回
502
,表明sleep-a服務訪問http://www.httpbin.org
失敗。執行以下命令,通過mytest命名空間下的sleep-a服務訪問
https://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
輸出結果返回
200
,表明sleep-a服務訪問https://www.httpbin.org
成功。
驗證default命名空間下的Nginx服務。
執行以下命令,通過Nginx服務訪問
http://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
502
,表明Nginx服務訪問http://www.httpbin.org
失敗。執行以下命令,通過Nginx服務訪問
https://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
輸出結果顯示請求連接被拒絕,表明Nginx服務訪問
https://www.httpbin.org
失敗。執行以下命令,查看Nginx工作負載對應的Sidecar的access log,了解連接被拒絕的原因。
kubectl -n default logs -f deployment/nginx -c istio-proxy --tail=1
預期輸出:
{"authority":"-","bytes_received":"0","bytes_sent":"0","downstream_local_address":"52.86.XX.XX:443","downstream_remote_address":"172.16.0.199:56748","duration":"0","istio_policy_status":"-","method":"-","path":"-","protocol":"-","request_id":"-","requested_server_name":"-","response_code":"0","response_flags":"UH","route_name":"-","start_time":"2023-04-11T02:00:07.409Z","trace_id":"-","upstream_cluster":"BlackHoleCluster","upstream_host":"-","upstream_local_address":"-","upstream_service_time":"-","upstream_transport_failure_reason":"-","user_agent":"-","x_forwarded_for":"-"}
預期輸出表明,請求轉發給
BlackHoleCluster
,因此導致連接被拒絕。
在網關出口流量策略頁面右側單擊清空規則,再次通過mytest命名空間下的sleep-a服務訪問
http://www.httpbin.org
和https://www.httpbin.org
。kubectl -n istio-egress delete ASMEgressTrafficPolicy egress-by-egressgateway kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
訪問
http://www.httpbin.org
時,返回502
;訪問https://www.httpbin.org
時,請求連接被拒絕。刪除ASMEgressTrafficPolicy配置后,sleep-a服務無法訪問http://www.httpbin.org
和https://www.httpbin.org
。輸出以上結果,表明ASMEgressTrafficPolicy配置生效。
通過kubectl配置
使用以下內容,更新egress-by-egressgateway.yaml。
在spec字段下增加了httpsUpgrade字段和直接訪問
https://www.httpbin.org
的相關定義。關于字段的相關說明,請參見ASMEgressTrafficPolicy CRD說明。apiVersion: istio.alibabacloud.com/v1 kind: ASMEgressTrafficPolicy metadata: name: egress-by-egressgateway # 名稱約定為egress-by-{出口網關名稱},與出口網關對應。 namespace: istio-egress # 命名空間約定:固定到istio-egress命名空間。 spec: byEgressGateway: name: egressgateway egressRules: - from: - namespace: mytest workloadSelector: app: sleep-a to: - name: httpbin-service-https hosts: - www.httpbin.org - httpbin.org port: name: https number: 443 protocol: HTTPS byEgressGateway: port: 444 # 準備工作的第三步中,出口網關定義的HTTPS 444端口。
在ACK集群中,執行以下命令,創建ASMEgressTrafficPolicy資源。
kubectl apply -f egress-by-egressgateway.yaml
驗證ASMEgressTrafficPolicy配置是否生效。
驗證mytest命名空間下的sleep-a服務。
執行以下命令,通過sleep-a服務訪問
http://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://httpbin.org
輸出結果返回
502
,表明sleep-a服務訪問http://www.httpbin.org
失敗。執行以下命令,通過mytest命名空間下的sleep-a服務訪問
https://www.httpbin.org
。kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
輸出結果返回
200
,表明sleep-a服務訪問https://www.httpbin.org
成功。
驗證default命名空間下的Nginx服務。
執行以下命令,通過Nginx服務訪問
http://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org
輸出結果返回
502
,表明Nginx服務訪問http://www.httpbin.org
失敗。執行以下命令,通過Nginx服務訪問
https://www.httpbin.org
。kubectl -n default exec deployment/nginx -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
輸出結果顯示請求連接被拒絕,表明Nginx服務訪問
https://www.httpbin.org
失敗。執行以下命令,查看Nginx工作負載對應的Sidecar的access log,了解連接被拒絕的原因。
kubectl -n default logs -f deployment/nginx -c istio-proxy --tail=1
預期輸出:
{"authority":"-","bytes_received":"0","bytes_sent":"0","downstream_local_address":"52.86.XX.XX:443","downstream_remote_address":"172.16.0.199:56748","duration":"0","istio_policy_status":"-","method":"-","path":"-","protocol":"-","request_id":"-","requested_server_name":"-","response_code":"0","response_flags":"UH","route_name":"-","start_time":"2023-04-11T02:00:07.409Z","trace_id":"-","upstream_cluster":"BlackHoleCluster","upstream_host":"-","upstream_local_address":"-","upstream_service_time":"-","upstream_transport_failure_reason":"-","user_agent":"-","x_forwarded_for":"-"}
預期輸出表明,請求轉發給
BlackHoleCluster
,因此導致連接被拒絕。
執行以下命令,刪除egress-by-egressgateway后,再次通過mytest命名空間下的sleep-a服務訪問
http://www.httpbin.org
和https://www.httpbin.org
。kubectl -n istio-egress delete ASMEgressTrafficPolicy egress-by-egressgateway kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" http://www.httpbin.org kubectl -n mytest exec deployment/sleep-a -- curl -s -o /dev/null -w "%{http_code}\n" https://www.httpbin.org
訪問
http://www.httpbin.org
時,返回502
;訪問https://www.httpbin.org
時,請求連接被拒絕。刪除ASMEgressTrafficPolicy配置后,sleep-a服務無法訪問http://www.httpbin.org
和https://www.httpbin.org
。
輸出以上結果,表明ASMEgressTrafficPolicy配置生效。
相關操作
拒絕來自指定命名空間下的POST請求
通過ASM出口網關結合ASMEgressTrafficPolicy,您可以靈活地控制集群內向外的外部流量。結合AuthorizationPolicy,您還可以進行更細粒度的訪問控制。例如,通過如下定義拒絕來自mytest命名空間下的POST請求。
kind: AuthorizationPolicy
apiVersion: security.istio.io/v1beta1
metadata:
name: sleep-a-egress-www-httpbin-org
namespace: istio-system
spec:
action: DENY
rules:
- to:
- operation:
hosts:
- www.httpbin.org
- httpbin.org
methods:
- POST
from:
- source:
namespaces: ["mytest"]
selector:
matchLabels:
istio: egressgateway-a
應用上述配置后,通過sleep-a服務采用POST方式的請求訪問www.httpbin.org,將返回RBAC: access
,通過GET方式的請求訪問www.httpbin.org則不受影響。