Istio 的配置分析


Istio 的配置分析

Analyzer 的消息格式

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前綴。

ConflictingMeshGatewayVirtualServiceHosts

Message Name ConflictingMeshGatewayVirtualServiceHosts
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
---

ConflictingSidecarWorkloadSelectors

Message Name ConflictingSidecarWorkloadSelectors
Message Code IST0110
Description A Sidecar resource selects the same workloads as another Sidecar resource
Level Error

當一個命名空間中的多個sidecar選擇相同的負載實例時會出現該消息,可能導致不可預知的行為。更多信息參見Sidecar資源。

為了解決該問題,需要一個命名空間中的Sidecar負載選擇器(workloadSelector)選擇的負載實例不會出現重疊。

GatewayPortNotOnWorkload

Message Name GatewayPortNotOnWorkload
Message Code IST0104
Description Unhandled gateway port
Level 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.

為了解決該問題,可以修改網關的配置,使用一個有效的負載端口,並重新部署即可。

InternalError

Message Name InternalError
Message Code IST0001
Description There was an internal error in the toolchain. This is almost always a bug in the implementation.
Level Error

極有可能是因為Istio的內部錯誤造成的。可以參見Istio的issue頁面來了解會提交問題。

IstioProxyImageMismatch

Message Name IstioProxyImageMismatch
Message Code IST0105
Description The image of the Istio proxy running on the pod does not match the image defined in the injection configuration.
Level Warning

當一個Pod出現如下條件時會發生該問題:

  • 啟用sidecar自動注入(默認是啟用的,除非在安裝時禁用)
  • pod運行在一個啟用sidecar注入的命名空間中(給命名空間打上標簽istio-injection=enabled)
  • 運行在sidecar中的代理版本與自動注入的版本不匹配

該問題通常會發生在更新Istio的控制面之后,在升級Istio后,所有帶Istio sidecar運行的負載必須重啟來注入新版本的sidecar。

為了解決該問題,可以通過滾動策略來重新部署應用的sidecar。對於kubernetes的deployment:

  1. 如果使用kubernetes 1.15或更高版本,可以運行 kubectl rollout restart <my-deployment>來觸發滾動
  2. 或者,可以修改deployment的template字段來強制觸發滾動。這通常是通過在模板的pod定義中添加諸如force-redeploy = <current-timestamp>之類的標簽來觸發deployment滾動的。

JwtFailureDueToInvalidServicePortPrefix

Message Name JwtFailureDueToInvalidServicePortPrefix
Message Code IST0119
Description Authentication policy with JWT targets Service with invalid port specification.
Level Warning

當一個認證策略使用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: "testing@secure.istio.io"
        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>]即可。

MisplacedAnnotation

Message Name MisplacedAnnotation
Message Code IST0107
Description An Istio annotation is applied to the wrong kind of resource.
Level Warning

當Istio的annotation附加到一個無效的資源或錯誤的位置上時會出現該消息。例如,如果創建一個deployment,然后將annotation附加到該deployment,而不是pods上時就會出現該錯誤提示。

將annotation放到正確的位置即可修改該問題。

MTLSPolicyConflict

Message Name MTLSPolicyConflict
Message Code IST0113
Description A DestinationRule and Policy are in conflict with regards to mTLS.
Level Error

當一個destination rule資源和一個策略資源因為mutual TLS沖突時會出現該消息。當兩個資源選擇的TLS模式不匹配時就會出現這種情況。該沖突意味着,匹配到destination rule的流量將會被拒絕。

該消息已經被廢棄,僅在使用alpha認證策略的服務網格中使用。(了解該問題仍然可以避免配置錯誤)

哪些destination rules和策略與服務相關

為了有效解決mutual TLS的沖突,需要同時了解destination rule和策略是如何影響到一個服務的流量的。考慮一個my-namespace命名空間中的名為my-service的服務。為了確定應用到my-service上的是哪個策略對象,按順序匹配以下資源:

  1. my-namespace命名空間中的策略資源包含一個target,指定了my-service
  2. my-namespace命名空間中的一個名為default的策略資源不包含一個target,意味着該策略適用於整個命名空間。
  3. 名為default的網格策略資源

為了確定哪個destination rule應用到到達my-service的流量,首先要知道流量來自哪個命名空間。本例中,假設命名空間為other-namespace。destination rule按照如下方式進行匹配:

  1. other-namespace命名空間中的destination rule會指定一個host來匹配 my-service.my-namespace.svc.cluster.local(可能會通過完整匹配或通配符匹配)。注意exportTo字段,該字段控制了配置資源的可見性,當目標資源與源服務在相同的命名空間時會被忽略(相同命名空間下的服務總是可見的)。

  2. my-namespace命名空間中的destination rule會指定一個host來匹配 my-service.my-namespace.svc.cluster.local(可能會通過完整匹配或通配符匹配)。注意為了進行匹配,exportTo字段必須將該資源指定為公共的(即,值為*或不指定)。

  3. 根命名空間(默認為istio-system)中的destination rule會匹配 my-service.my-namespace.svc.cluster.localMeshConfig 資源中的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使用Plaintext來支持mutual TLS模式
  • destination rule資源istio-system/default-rule,指定發送到host myhost.my-namespace.svc.cluster.local:8080的流量需要啟用mutual TLS

可以使用下面的方式之一來修復該問題:

  • 修改策略資源my-namespace/my-policy來啟用mutual TLS作為認證模式。
  • 修改destination rule istio-system/default-rule,通過移除ISTIO_MUTUAL來禁用mutual TLS。注意default-rule位於istio-system命名空間,即默認的根命名空間中,意味着該destination rule會影響到網格中過的所有其他服務。
  • 在與服務相同的命名空間(my-namespace)中添加一個新的destination rule,該destination rule不指定流量策略mutual TLS。由於該規則位於與服務相同的命名空間中,它不會覆蓋全局destination rule istio-system/default-rule.

MultipleSidecarsWithoutWorkloadSelectors

Message Name MultipleSidecarsWithoutWorkloadSelectors
Message Code IST0111
Description More than one sidecar resource in a namespace has no workload selector
Level Error

當一個命名空間中的多個sidecar資源沒有定義任何負載選擇器時會出現該消息,導致不可預知的行為。更多參見Sidecar

一個命名空間僅允許一個sidecar資源不指定負載選擇器。

NamespaceNotInjected

Message Name NamespaceNotInjected
Message Code IST0102
Description A namespace is not enabled for Istio injection.
Level Warning

當一個命名空間沒有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注入行為。忘記注釋命名空間是導致錯誤的常見原因。

SchemaValidationError

Message Name SchemaValidationError
Message Code IST0106
Description The resource has a schema validation error.
Level 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字段來檢查哪個元素或值沒有符合模式要求,然后進行修正。

VirtualServiceDestinationPortSelectorRequired

Message Name VirtualServiceDestinationPortSelectorRequired
Message Code IST0112
Description A VirtualService routes to a service with more than one port exposed, but does not specify which to use.
Level Error

當一個virtual service路由到暴露多個port的服務,且沒有指定使用哪個端口時會出現該錯誤。這種模糊性可能導致不確定的行為。

可以在virtual service Destination中增加port字段來解決該問題。

UnknownAnnotation

Message Name UnknownAnnotation
Message Code IST0108
Description An Istio annotation is not recognized for any kind of resource
Level Warning

當將格式為*.istio.io的無法識別的注釋附加到名稱空間時,會出現此消息。Istio僅能識別特定的annotation名稱

ReferencedResourceNotFound

Message Name ReferencedResourceNotFound
Message Code IST0101
Description A resource being referenced does not exist.
Level Error

當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配置即可。

PortNameIsNotUnderNamingConvention

Message Name PortNameIsNotUnderNamingConvention
Message Code IST0118
Description Port name is not under naming convention. Protocol detection is applied to the port.
Level 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字段中看到使用的協議
    • 如果沒有輸出,則可以保留端口不變。

PodMissingProxy

Message Name PodMissingProxy
Message Code IST0103
Description A pod is missing the Istio proxy.
Level Warning

當沒有sidecar或sidecar不正常時會出現該錯誤。

通常是因為啟用了自動注入,但后續沒有重啟pod導致sidecar不存在。

可以使用如下命令修復:

$ kubectl rollout restart deployment


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM