天天看點

Istio 的配置分析

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:

  1. 如果使用kubernetes 1.15或更高版本,可以運作

    kubectl rollout restart <my-deployment>

    來觸發滾動
  2. 或者,可以修改deployment的

    template

    字段來強制觸發滾動。這通常是通過在模闆的pod定義中添加諸如

    force-redeploy = <current-timestamp>

    之類的标簽來觸發deployment滾動的。

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

上的是哪個政策對象,按順序比對以下資源:

  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

    my-service.my-namespace.svc.cluster.local

    (可能會通過完整比對或通配符比對)。注意為了進行比對,

    exportTo

    字段必須将該資源指定為公共的(即,值為

    *

    或不指定)。
  3. 根命名空間(預設為

    istio-system

    )中的destination rule會比對

    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

    使用

    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

    .

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