Istio 的配置分析
目錄
-
- Analyzer 的消息格式
- ConflictingMeshGatewayVirtualServiceHosts
- 問題解決
- 舉例
- ConflictingSidecarWorkloadSelectors
- GatewayPortNotOnWorkload
- InternalError
- IstioProxyImageMismatch
- JwtFailureDueToInvalidServicePortPrefix
- MisplacedAnnotation
- MTLSPolicyConflict
- 哪些destination rules和政策與服務相關
- MultipleSidecarsWithoutWorkloadSelectors
- NamespaceNotInjected
- SchemaValidationError
- VirtualServiceDestinationPortSelectorRequired
- UnknownAnnotation
- ReferencedResourceNotFound
- PortNameIsNotUnderNamingConvention
- PodMissingProxy
istioctl analyze
指令提供了如下消息格式:
<level> [<code>] (<affected-resource>) <message-details>
字段可以展開為:
<resource-kind> <resource-name>.<resource-namespace>
例如:
Error [IST0101] (VirtualService httpbin.default) Referenced gateway not found: "httpbin-gateway-bogus"
<message-details>
字段包含關于解決問題的詳細資訊。當對于叢集範圍的資源(如
namespace
)時,會忽略namespace字首。
Message Name | |
---|---|
Message Code | IST0109 |
Description | Conflicting hosts on VirtualServices associated with mesh gateway |
Level | Error |
當Istio檢測到virtual service資源之間存在重疊導緻的沖突時,會出現該消息。例如,定義了多個使用相同的主機名的virtual service,并将其附加到網格網關上,這樣就會産生上述錯誤。注意,Istio支援合并附加到ingress網關的virtual services。
可以使用如下動作來解決該問題:
- 将多個沖突的virtual service合并為一個
- 将附加到一個網格網關的多個virtual service的主機名配置為唯一的
- 通過
字段将資源指定到某個指定的命名空間中exportTo
例如,
team1
命名空間中的
productpage
virtual service 與
team2
custom
virtual service因為同時設定了如下條件導緻了沖突:
- 都附加到了預設的
網關上(沒有指定使用者網關)mesh
- 定義了相同的host
productpage.default.svc.cluster.local
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: productpage namespace: team-1 spec: hosts: - productpage.default.svc.cluster.local http: - route: - destination: host: productpage --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: custom namespace: team-2 spec: hosts: - productpage.default.svc.cluster.local http: - route: - destination: host: productpage.team-2.svc.cluster.local ---
可以通過設定exportTo字段來解決該問題,這樣,virtual service的範圍就限制于其所在的命名空間。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: productpage namespace: team-1 spec: exportTo: - "." #目前命名空間 hosts: - productpage.default.svc.cluster.local http: - route: - destination: host: productpage --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: custom namespace: team-2 spec: exportTo: - "." #目前命名空間 hosts: - productpage.default.svc.cluster.local http: - route: - destination: host: productpage.team-2.svc.cluster.local ---
IST0110 | |
A Sidecar resource selects the same workloads as another Sidecar resource | |
當一個命名空間中的多個sidecar選擇相同的負載執行個體時會出現該消息,可能導緻不可預知的行為。更多資訊參見Sidecar資源。
為了解決該問題,需要一個命名空間中的Sidecar負載選擇器(
workloadSelector
)選擇的負載執行個體不會出現重疊。
IST0104 | |
Unhandled gateway port | |
Warning |
當一個網關(通常是
istio-ingressgateway
)提供的端口并不在網關選擇的kubernetes service負載上時會出現該消息。
例如,Istio的配置包含如下值:
# Gateway with bogus port apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: httpbin-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" - port: number: 8004 name: http2 protocol: HTTP hosts: - "*"
在上面例子中會出現
GatewayPortNotOnWorkload
消息,因為一個預設的IngressGateway僅會打開端口 80, 443, 31400, 和15443,并不包括8004。使用istioctl analyze分析的結果如下:
# istioctl analyze Warn [IST0104] (Gateway httpbin-gateway.default) The gateway refers to a port that is not exposed on the workload (pod selector istio=ingressgateway; port 8004) Info [IST0118] (Service mutatepodimages.default) Port name (port: 443, targetPort: 8443) doesn't follow the naming convention of Istio port. Error: Analyzers found issues when analyzing namespace: default.
為了解決該問題,可以修改網關的配置,使用一個有效的負載端口,并重新部署即可。
IST0001 | |
There was an internal error in the toolchain. This is almost always a bug in the implementation. | |
極有可能是因為Istio的内部錯誤造成的。可以參見Istio的issue頁面來了解會送出問題。
IST0105 | |
The image of the Istio proxy running on the pod does not match the image defined in the injection configuration. | |
當一個Pod出現如下條件時會發生該問題:
- 啟用sidecar自動注入(預設是啟用的,除非在安裝時禁用)
- pod運作在一個啟用sidecar注入的命名空間中(給命名空間打上标簽
)istio-injection=enabled
- 運作在sidecar中的代理版本與自動注入的版本不比對
該問題通常會發生在更新Istio的控制面之後,在更新Istio後,所有帶Istio sidecar運作的負載必須重新開機來注入新版本的sidecar。
為了解決該問題,可以通過滾動政策來重新部署應用的sidecar。對于kubernetes的deployment:
- 如果使用kubernetes 1.15或更高版本,可以運作
來觸發滾動kubectl rollout restart <my-deployment>
- 或者,可以修改deployment的
字段來強制觸發滾動。這通常是通過在模闆的pod定義中添加諸如template
之類的标簽來觸發deployment滾動的。force-redeploy = <current-timestamp>
IST0119 | |
Authentication policy with JWT targets Service with invalid port specification. | |
當一個認證政策使用JWT認證時,而目标kubernetes service配置不正确時會出現該消息。正确的kubernetes service要求port使用http|http2|https作為字首來命名(參見Protocol Selection),并且協定為TCP。預設的協定為TCP。
當叢集中存在如下政策時:
apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata: name: secure-httpbin namespace: default spec: targets: - name: httpbin origins: - jwt: issuer: "[email protected]" jwksUri: "https://raw.githubusercontent.com/istio/istio-1.4/security/tools/jwt/samples/jwks.json"
target的service配置如下:
apiVersion: v1 kind: Service metadata: name: httpbin namespace: default labels: app: httpbin spec: ports: - name: svc-8080 port: 8080 targetPort: 80 protocol: TCP selector: app: httpbin
在上面例子中,port
svc-8080
并沒有遵守文法:
name: <http|https|http2>[-<suffix>]
。将會接收到如下消息:
Warn [IST0119] (Policy secure-httpbin.default) Authentication policy with JWT targets Service with invalid port specification (port: 8080, name: svc-8080, protocol: TCP, targetPort: 80).
JWT認證僅支援http,https或http2,修改Service 端口名,使其遵守
<http|https|http2>[-<suffix>]
即可。
IST0107 | |
An Istio annotation is applied to the wrong kind of resource. | |
當Istio的annotation附加到一個無效的資源或錯誤的位置上時會出現該消息。例如,如果建立一個deployment,然後将annotation附加到該deployment,而不是pods上時就會出現該錯誤提示。
将annotation放到正确的位置即可修改該問題。
IST0113 | |
A DestinationRule and Policy are in conflict with regards to mTLS. | |
當一個destination rule資源和一個政策資源因為mutual TLS沖突時會出現該消息。當兩個資源選擇的TLS模式不比對時就會出現這種情況。該沖突意味着,比對到destination rule的流量将會被拒絕。
該消息已經被廢棄,僅在使用alpha認證政策的服務網格中使用。(了解該問題仍然可以避免配置錯誤)
為了有效解決mutual TLS的沖突,需要同時了解destination rule和政策是如何影響到一個服務的流量的。考慮一個
my-namespace
命名空間中的名為
my-service
的服務。為了确定應用到
my-service
上的是哪個政策對象,按順序比對以下資源:
-
命名空間中的政策資源包含一個my-namespace
,指定了target
my-service
-
命名空間中的一個名為my-namespace
的政策資源不包含一個default
,意味着該政策适用于整個命名空間。target
- 名為
的網格政策資源default
為了确定哪個destination rule應用到到達
my-service
的流量,首先要知道流量來自哪個命名空間。本例中,假設命名空間為
other-namespace
。destination rule按照如下方式進行比對:
-
命名空間中的destination rule會指定一個host來比對other-namespace
(可能會通過完整比對或通配符比對)。注意my-service.my-namespace.svc.cluster.local
字段,該字段控制了配置資源的可見性,當目标資源與源服務在相同的命名空間時會被忽略(相同命名空間下的服務總是可見的)。exportTo
-
my-namespace
(可能會通過完整比對或通配符比對)。注意為了進行比對,my-service.my-namespace.svc.cluster.local
字段必須将該資源指定為公共的(即,值為exportTo
或不指定)。*
- 根命名空間(預設為
)中的destination rule會比對istio-system
。my-service.my-namespace.svc.cluster.local
資源中的MeshConfig
屬性會控制根命名空間。注意為了進行比對,rootNamespace
exportTo
或不指定)。對*
的描述如下rootNamespace
The namespace to treat as the administrative root namespace for Istio configuration. When processing a leaf namespace Istio will search for declarations in that namespace first and if none are found it will search in the root namespace. Any matching declaration found in the root namespace is processed as if it were declared in the leaf namespace.
最後,注意在遵循這些規則時,Istio不會應用任何繼承概念,它将使用符合指定條件的第一個資源。
檢視如下輸出:
Error [IST0113] (DestinationRule default-rule.istio-system) A DestinationRule and Policy are in conflict with regards to mTLS for host myhost.my-namespace.svc.cluster.local:8080. The DestinationRule "istio-system/default-rule" specifies that mTLS must be true but the Policy object "my-namespace/my-policy" specifies Plaintext.
可以看出兩個資源是沖突的:
- 政策資源
使用my-namespace/my-policy
來支援mutual TLS模式Plaintext
- destination rule資源
,指定發送到hostistio-system/default-rule
的流量需要啟用mutual TLSmyhost.my-namespace.svc.cluster.local:8080
可以使用下面的方式之一來修複該問題:
- 修改政策資源
來啟用mutual TLS作為認證模式。my-namespace/my-policy
- 修改destination rule
,通過移除istio-system/default-rule
來禁用mutual TLS。注意ISTIO_MUTUAL
位于default-rule
命名空間,即預設的根命名空間中,意味着該destination rule會影響到網格中過的所有其他服務。istio-system
- 在與服務相同的命名空間(
)中添加一個新的destination rule,該destination rule不指定流量政策mutual TLS。由于該規則位于與服務相同的命名空間中,它不會覆寫全局destination rulemy-namespace
.istio-system/default-rule
IST0111 | |
More than one sidecar resource in a namespace has no workload selector | |
當一個命名空間中的多個sidecar資源沒有定義任何負載選擇器時會出現該消息,導緻不可預知的行為。更多參見Sidecar。
一個命名空間僅允許一個sidecar資源不指定負載選擇器。
IST0102 | |
A namespace is not enabled for Istio injection. | |
當一個命名空間沒有annotation(如
sidecar.istio.io/inject
.)指明該命名空間是否需要自動注入sidecar時會出現該提示。錯誤資訊如下:
Warn [IST0102] (Namespace default) The namespace is not enabled for Istio injection. Run 'kubectl label namespace default istio-injection=enabled' to enable it, or 'kubectl label namespace default istio-injection=disabled' to explicitly mark it as not needing injection Error: Analyzer found issues.
可以通過給命名空間打标簽來解決該問題,明确聲明是否需要啟用sidecar自動注入:
$ kubectl label namespace <namespace-name> istio-injection=enabled
強烈建議明确指定sidecar注入行為。忘記注釋命名空間是導緻錯誤的常見原因。
IST0106 | |
The resource has a schema validation error. | |
當Istio的配置沒有通過模式驗證時會出現該錯誤。如:
Error [IST0106] (VirtualService ratings-bogus-weight-default.default) Schema validation error: percentage 888 is not in range 0..100
Istio配置為:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings-bogus-weight-default namespace: default spec: hosts: - ratings http: - route: - destination: host: ratings subset: v1 weight: 999 - destination: host: ratings subset: v2 weight: 888
本例中可以看到
weight
元素為一個無效的值。可以通過消息的details字段來檢查哪個元素或值沒有符合模式要求,然後進行修正。
IST0112 | |
A VirtualService routes to a service with more than one port exposed, but does not specify which to use. | |
當一個virtual service路由到暴露多個port的服務,且沒有指定使用哪個端口時會出現該錯誤。這種模糊性可能導緻不确定的行為。
可以在virtual service Destination中增加port字段來解決該問題。
IST0108 | |
An Istio annotation is not recognized for any kind of resource | |
當将格式為
*.istio.io
的無法識别的注釋附加到名稱空間時,會出現此消息。Istio僅能識别特定的annotation名稱。
IST0101 | |
A resource being referenced does not exist. | |
當Istio資源相關的資源不存在時會出現該錯誤。當Istio嘗試查找引用的資源但無法找到時,将導緻錯誤。錯誤資訊如:
Error [IST0101] (VirtualService httpbin.default) Referenced gateway not found: "httpbin-gateway-bogus"
本例中,VirtualService引用了一個不存在的網關。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: httpbin-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http2 protocol: HTTP2 hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts: - "*" gateways: - httpbin-gateway-bogus # Should have been "httpbin-gateway" http: - route: - destination: host: httpbin-gateway
為了解決該問題,檢視detaild錯誤消息中的資源類型,然後修正Istio配置即可。
IST0118 | |
Port name is not under naming convention. Protocol detection is applied to the port. | |
Info |
當端口不遵守Istio服務端口命名規範或端口未命名時會出現該錯誤。錯誤資訊如:
Info [IST0118] (Service httpbin.default) Port name foo-http (port: 80, targetPort: 80) doesn't follow the naming convention of Istio port.
對應的Service為:
apiVersion: v1 kind: Service metadata: name: httpbin labels: app: httpbin spec: ports: - name: foo-http port: 8000 targetPort: 80 selector: app: httpbin
可以通過将port
foo-http
按照文法
name: <protocol>[-<suffix>]
修改即可。
- 如果知道服務端口的協定,使用
格式重命名即可<protocol>[-<suffix>]
- 如果不知道服務端口的協定,則需要從Prometheus請求metrics來擷取
- 執行請求
istio_requests_total
- 如果有輸出,可以在metrics的
字段中看到使用的協定request_protocol
- 如果沒有輸出,則可以保留端口不變。
- 執行請求
IST0103 | |
A pod is missing the Istio proxy. | |
當沒有sidecar或sidecar不正常時會出現該錯誤。
通常是因為啟用了自動注入,但後續沒有重新開機pod導緻sidecar不存在。
可以使用如下指令修複:
$ kubectl rollout restart deployment