解決 Cloud Service Mesh 中的工作負載啟動問題
本文說明常見的 Cloud Service Mesh 問題,以及如何解決這些問題。如需其他協助,請參閱「取得支援」。
公開具備權限的通訊埠時,閘道無法使用 Distroless Proxy 啟動
根據預設,無發行版代理程式會以非根權限啟動,在某些情況下,這可能會導致特殊權限通訊埠發生繫結失敗。如果在 Proxy 啟動期間看到類似下列的錯誤,則必須為閘道部署項目套用額外的 securityContext。
Error adding/updating listener(s) 0.0.0.0_80: cannot bind '0.0.0.0:80': Permission denied
以下範例是輸出閘道部署作業的 YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: istio-egressgateway
spec:
selector:
matchLabels:
app: istio-egressgateway
istio: egressgateway
template:
metadata:
annotations:
# This is required to tell Anthos Service Mesh to inject the gateway with the
# required configuration.
inject.istio.io/templates: gateway
labels:
app: istio-egressgateway
istio: egressgateway
spec:
containers:
- name: istio-proxy
image: auto # The image will automatically update each time the pod starts.
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
# Allow binding to all ports (such as 80 and 443)
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: istio-egressgateway
連線至 Cloud Service Mesh 端點時遭到拒絕
叢集與端點 (例如 Memorystore Redis、Cloud SQL,或應用程式工作負載需要連線的任何外部服務) 通訊時,可能會間歇性發生連線遭拒 (ECONNREFUSED) 錯誤。
如果應用程式工作負載的啟動速度比 istio-proxy (Envoy) 容器快,並嘗試連線至外部端點,就可能發生這種情況。因為 istio-init (initContainer) 已在這個階段執行,所以 iptables 規則會將所有外送流量重新導向至 Envoy。由於 istio-proxy 尚未準備就緒,iptables 規則會將流量重新導向至尚未啟動的 Sidecar Proxy,因此應用程式會收到 ECONNREFUSED 錯誤。
請按照下列步驟操作,確認是否遇到這個錯誤:
使用下列篩選器檢查 stackdriver 記錄,找出有問題的 Pod。
以下範例顯示典型的錯誤訊息:
Error: failed to create connection to feature-store redis, err=dial tcp 192.168.9.16:19209: connect: connection refused [ioredis] Unhandled error event: Error: connect ECONNREFUSED搜尋問題的發生次數。如果您使用的是舊版 Stackdriver,請改用
resource.type="container"。resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"展開最新事件,取得 Pod 名稱,然後記下
pod_name下方的resource.labels。取得該 Pod 的第一個問題:
resource.type="k8s_container" resource.labels.pod_name="$POD_NAME$"輸出內容範例:
E 2020-03-31T10:41:15.552128897Z post-feature-service post-feature-service-v1-67d56cdd-g7fvb failed to create connection to feature-store redis, err=dial tcp 192.168.9.16:19209: connect: connection refused post-feature-service post-feature-service-v1-67d56cdd-g7fvb請記下這個 Pod 的第一個錯誤時間戳記。
使用下列篩選器查看 Pod 啟動事件。
resource.type="k8s_container" resource.labels.pod_name="$POD_NAME$"輸出內容範例:
I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Container image "docker.io/istio/proxyv2:1.3.3" already present on machine spec.containers{istio-proxy} I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Created container spec.containers{istio-proxy} I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Started container spec.containers{istio-proxy} I 2020-03-31T10:41:15Z spec.containers{APP-CONTAINER-NAME} Created container spec.containers{APP-CONTAINER-NAME} W 2020-03-31T10:41:17Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503 spec.containers{istio-proxy} W 2020-03-31T10:41:26Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503 spec.containers{istio-proxy} W 2020-03-31T10:41:28Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503 spec.containers{istio-proxy} W 2020-03-31T10:41:31Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503 spec.containers{istio-proxy} W 2020-03-31T10:41:58Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503 spec.containers{istio-proxy}使用錯誤和 istio-proxy 啟動事件的時間戳記,確認錯誤發生時
Envoy尚未準備就緒。如果 istio-proxy 容器尚未準備就緒時發生錯誤,取得連線遭拒錯誤是正常現象。在前面的範例中,pod 嘗試在
2020-03-31T10:41:15.552128897Z時連接到 Redis,但到2020-03-31T10:41:58Z時 istio-proxy 仍然無法進行就緒偵測。即使 istio-proxy 容器最先啟動,但它可能在應用程式嘗試連接到外部端點之前沒有足夠快地準備就緒。
如果您遇到的問題是這樣的,請繼續按照以下故障排除步驟進行操作。
在 Pod 層級為設定加上註解。這項功能僅適用於 Pod 層級,不適用於全域層級。
annotations: proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'修改應用程式程式碼,確保應用程式先檢查
Envoy是否已準備就緒,再嘗試向外部服務發出任何其他要求。例如,在應用程式啟動時,啟動一個循環,向 istio-proxy 健康端點發出請求,並且只有在獲得 200 後才繼續。istio-proxy 健康狀態端點如下:http://localhost:15020/healthz/ready
Vault 和 Cloud Service Mesh 之間邊車注入期間的競爭情況
使用 vault 管理密鑰時,vault 有時會在 istio 前注入 Sidecar,導致 Pod 停滯在 Init 狀態。發生這種情況時,重新啟動或部署新的 Deployment 後,建立的 Pod 會停留在 Init 狀態。例如:
E 2020-03-31T10:41:15.552128897Z
post-feature-service post-feature-service-v1-67d56cdd-g7fvb failed to create
connection to feature-store redis, err=dial tcp 192.168.9.16:19209: connect:
connection refused post-feature-service post-feature-service-v1-67d56cdd-g7fvb
這個問題是由競爭狀況所致,Istio 和 vault 都會插入 Sidecar,但 Istio 必須是最後一個執行這項作業的服務,且 istio Proxy 不會在 Init 容器期間執行。istio 初始化容器設定 iptables 規則,將所有流量重新導向至代理程式。由於尚未執行,這些規則不會重新導向任何內容,因此會封鎖所有流量。因此,初始化容器必須是最後一個,這樣在設定 iptables 規則後,Proxy 就能立即啟動並運作。很抱歉,由於順序不確定,如果 Istio 先注入,就會發生中斷。
如要排解這個情況,請允許 vault 的 IP 位址,這樣前往 Vault IP 的流量就不會重新導向至尚未準備就緒的 Envoy Proxy,進而封鎖通訊。為此,需要新增一個名為 excludeOutboundIPRanges 的新註解。
如果是代管 Cloud Service Mesh,只能在 spec.template.metadata.annotations 下的 Deployment 或 Pod 層級執行這項操作,例如:
apiVersion: apps/v1
kind: Deployment
...
...
...
spec:
template:
metadata:
annotations:
traffic.sidecar.istio.io/excludeOutboundIPRanges:
對於叢集內 Cloud Service Mesh,可以選擇將其設定為全域服務網格,並在 spec.values.global.proxy.excludeIPRanges 下使用 IstioOperator,例如:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
proxy:
excludeIPRanges: ""
新增註解後,請重新啟動工作負載。
找出叢集中使用的 Proxy 圖片類型
如要判斷特定 Pod 使用的 Proxy 圖片類型 (default 或 distroless),可以檢查 Pod 規格。
執行下列指令,檢查 istio-proxy 容器使用的映像檔:
kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.spec.containers[?(@.name=="istio-proxy")].image}'
- 如果圖片路徑在代碼或後置字串中不含
-distroless,則會使用default圖片。 - 如果圖片路徑在標記或後置字元中包含
-distroless,則會使用distroless圖片。
驗證設定意圖
您可以透過兩種方式設定圖片類型 (註解優先於 MeshConfig):
Pod 註解:檢查 Pod 是否有
sidecar.istio.io/proxyImageType註解。kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.metadata.annotations["sidecar.istio.io/proxyImageType"]}'MeshConfig:檢查
istio-system命名空間中istio-RELEASE_CHANNELConfigMap 的defaultConfig.image.imageType設定。
注意:如果是使用代管 TRAFFIC_DIRECTOR 控制層的叢集:
- 如果是直接使用受管理
TRAFFIC_DIRECTOR控制層佈建的叢集,則僅支援distroless映像檔。系統會忽略其他圖片類型的覆寫。 - 對於遷移至
TRAFFIC_DIRECTOR控制層的叢集 (例如從 CSM-ISTIOD 遷移的叢集),映像檔類型預設為default映像檔,但您可以使用MeshConfig或 Pod 註解選擇加入distroless。系統不支援覆寫其他圖片類型 (例如debug)。