侧边栏壁纸
博主头像
船长博主等级

专注于云原生运维,致敬每个爱学习的你

  • 累计撰写 35 篇文章
  • 累计创建 10 个标签
  • 累计收到 10 条评论

Istio Sidecar自动注入详解

船长
2022-02-09 / 2 评论 / 1 点赞 / 1,630 阅读 / 19,526 字
温馨提示:
本文最后更新于 2022-04-18,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

背景

当通过执行kubectl label namespace sample istio-injection=enabled此命令后(为sample命名命名空间开启自动注入Sidecar),在sample命名空间进行部署应用时,会发现每个Pod都会自动注入Sidecar,是不是很神奇,接下来我们一步一步分析一下!

什么是 Admission

Admission是Kubernetes中的一个术语,指的是Kubernetes API Server资源请求过程中的一个阶段。它会在请求通过认证和授权之后、对象被持久化之前拦截到达 API 服务器的请求,然后经过Admission处理( 根据 API 中的配置,分别执行变更和验证准入控制 webhook,最后再保存到etcd。

从上图看出,Admission有两个重要的阶段:Mutating和Validating,这两个阶段中执行的逻辑如下:

  • Mutating,从字面上可以知道,在Mutating阶段可以对请求内容进行修改。
  • Validating,指在该阶段不允许修改请求内容,但可以根据请求的内容判断是继续执行该请求还是拒绝该请求。

Kubernetes 1.9版本开始引入了Admission Webhook扩展机制,通过Webhook回调功能,开发者可以非常灵活地对Kubernetes API Server的功能进行扩展,在API Server创建资源时对资源进行验证或者修改。

使用Webhook的优势是不需要对API Server的源码进行修改和重新编译就可以扩展其功能。插入的逻辑实现为一个独立的进程,通过参数方式传入到Kubernetes中,由Kubernetes在进行自身逻辑处理时对扩展逻辑进行回调。

通过Admission Webhook,可以加入Mutation和Validation两种类型的Webhook插件:

  • MutatingAdmissionWebhook允许你在Webhook中对资源对象进行修改。

  • ValidatingAdmissionWebhook执行一些检查操作,可以拒绝用户的请求来增加额外的准入策略。

    当集群管理员需要强制对某些请求(或所有请求)都进行校验(或者修改)的时候,就可以考虑使用ValidatingAdmissionWebhook或MutatingAdmissionWebhook。

启用 Webhook

WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通过 HTTP POST 发送的简单事件通知。一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL。

在Kubernetes API Server种的有个配置参数:--enable-admission-plugins,其值为一串用逗号连接的有序的准入模块列表,设置后就可在对象操作前执行一定顺序的准入模块调用。

# 修改api server的启动参数即可
--enable-admission-plugins=NodeRestriction CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, LimitRanger, MutatingAdmissionWebhook, NamespaceLifecycle, PersistentVolumeClaimResize, Priority, ResourceQuota, RuntimeClass, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook

Webhook自动注入Sidecar

Istio是利用了Kubernets Webook机制来实现Envoy Proxy Sidecar的自动注入。

分析注入配置

首先,创建Sidecar注入的配置文件istio-sidecar-injector:

#  kubectl get cm -n istio-system istio-sidecar-injector -o yaml 
apiVersion: v1
data:
  config: |-
    defaultTemplates: [sidecar]
    policy: enabled
    alwaysInjectSelector:
    .....
    templates:
      sidecar: |
        {{- $containers := list }}
        {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}}
        metadata:
          labels:
            security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio"  | quote }}
            service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name  | quote }}
            service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest"  | quote }}
            istio.io/rev: {{ .Revision | default "default" | quote }}
          annotations: {
            {{- if eq (len $containers) 1 }}
            kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}",
            kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}",
            {{ end }}
        {{- if .Values.istio_cni.enabled }}
            {{- if not .Values.istio_cni.chained }}
            k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `istio-cni` }}',
            {{- end }}
            sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}",
            {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }}
            {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }}
            traffic.sidecar.istio.io/includeInboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` `*` }}",
            traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}",
            {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }}
            traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}",
            {{- end }}
            {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }}
            traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}",
            {{- end }}
            {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }}
        {{- end }}
          }

可以看出该configmap保存了默认的注册策略和Sidecar注入模板

策略参数:

  • disabled:Sidecar注入器默认不会注入pod中。pod模板定义中的注解sidecar.istio.io/inject值为true,会启用注入功能。
  • enabled:Sidecar注入器默认会注入pod中。pod模板定义中的注解sidecar.istio.io/inject值为false,会禁止注入功能。

分析注入的Webhook

# kubectl get MutatingWebhookConfiguration -n istio-system -o yaml
apiVersion: v1
items:
- apiVersion: admissionregistration.k8s.io/v1
  kind: MutatingWebhookConfiguration
  metadata:
    generation: 2
    labels:
      app: sidecar-injector
      install.operator.istio.io/owning-resource: unknown
      install.operator.istio.io/owning-resource-namespace: istio-system
      istio.io/rev: default
      operator.istio.io/component: Pilot
      operator.istio.io/managed: Reconcile
      operator.istio.io/version: 1.10.6
      release: istio
      manager: istio-operator
      operation: Apply
      time: "2021-12-31T03:27:02Z"
      manager: pilot-discovery
      operation: Update
      time: "2021-12-31T03:27:32Z"
    name: istio-sidecar-injector
    resourceVersion: "3291680"
    selfLink: /apis/admissionregistration.k8s.io/v1/mutatingwebhookconfigurations/istio-sidecar-injector
    uid: 89d137e5-fc47-4069-b9ba-a8f71e4d1cc6
  webhooks:
  - admissionReviewVersions:
    - v1beta1
    - v1
    clientConfig:  # webhook指定连接信息
      caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvVENDQWVXZ0F3SUJBZ0lSQUtlRksvQmphOGVWR3VSelAzcTdXODh3RFFZSktvWklodmNOQVFFTEJRQXcKR0RFV01CUUdBMVVFQ2hNTlkyeDFjM1JsY2k1c2IyTmhiREFlRncweU1URXlNekV3TXpJM016RmFGdzB6TVRFeQpNamt3TXpJM016RmFNQmd4RmpBVUJnTlZCQW9URFdOc2RYTjBaWEl1Ykc5allXd3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFp0SmxBMkhqQURBamVlNGpUTjlOK0FjRFJybmxjT2k2SmZqOWEKQWdUSFBxcmo1MGo1aUQ5SERUbXlOOXlkeS8yR2pUUStQaFB3UkxyUG9UUjV3Q1ZVTk5JbGdUelZpSE03d3JOWQo2V2N6bVpRQ0Zxd1hEbHBnZkRFUFhjUjQ5OUwzUXp1c3phczE4S2pEckFVTFdkT3NOL2k1SS9tbGJOdVlKSnpPCnFDQ0swRnFiemtBUU9oaGduZHdQMVdoUHZHSWVXTy96d3BOQUluVXpFck5LcW8ya2tQbHZwRmQydGhlWVY2cU8KRFBtZE9LQVRwb0xqR3dVSnIraWUyWlJXbjlSeUp4ZW4wTlhKcWZRMmg1WGp3MThCaXBNUVQ2WGhTVGtkUktibApDOHk0Z0tJY2xmc2lSckUwTER5dnVtSUhDMEFucTl2eDZ2VHo3elVFMFdPcEFZVVBBZ01CQUFHalFqQkFNQTRHCkExVWREd0VCL3dRRUF3SUNCREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFDYko3VkZOK3QKTWZCa0t4K2NVNXZObnhqNDFEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUF6cDdmTGR0S20vTzRwTGNNWWd3aApKZFJHSGlVOEU4bmJzWU1HamU3bEFockl0R2JoWURhT3NTRGMrc2NrUkVScDF4dDM1NnJsU1ZINGo4S2NWNnJZClRIUFM2NWdrNm1uMmEyT1A1aFQxUDdiYk8wVTQyaFM4WUpUR0IvTzRreThsYnRZWFBhRTFCbTQrOUw1eHlQMHkKSllJaDFqTVFKQ1UrOTdzS002V2xOZzh1NzMvZ2xhamJrOUNFRmJkUUVGRmVCVEJlVS9IOTY4SWFDL0txNlQ0SAo4VTBEc3hqQnZyN0gxRnpTY3lKQk8zSEdBTkhzWkRtdm9vMDk5WFdteElvSHRDb3dDdExjWFQ0cktPbmt2SERHCjZlalhuNzBjbUp5dFIrVzFJazc2VldjMXUwM2ZQZVB5WE4wOC85THFkS0J3L2dFQndTamkwanYwTVJSczZnWnUKOXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
      service:
        name: istiod
        namespace: istio-system
        path: /inject
        port: 443
    failurePolicy: Fail
    matchPolicy: Equivalent
    name: rev.namespace.sidecar-injector.istio.io
    namespaceSelector:
      matchExpressions:
      - key: istio.io/rev
        operator: In
        values:
        - default
      - key: istio-injection
        operator: DoesNotExist
    objectSelector:
      matchExpressions:
      - key: sidecar.istio.io/inject
        operator: NotIn
        values:
        - "false"
    reinvocationPolicy: Never
    rules:
    - apiGroups:
      - ""
      apiVersions:
      - v1
      operations:
      - CREATE
      resources:
      - pods
      scope: '*'
    sideEffects: None
    timeoutSeconds: 10
  - admissionReviewVersions:
    - v1beta1
    - v1
    clientConfig:
      caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvVENDQWVXZ0F3SUJBZ0lSQUtlRksvQmphOGVWR3VSelAzcTdXODh3RFFZSktvWklodmNOQVFFTEJRQXcKR0RFV01CUUdBMVVFQ2hNTlkyeDFjM1JsY2k1c2IyTmhiREFlRncweU1URXlNekV3TXpJM016RmFGdzB6TVRFeQpNamt3TXpJM016RmFNQmd4RmpBVUJnTlZCQW9URFdOc2RYTjBaWEl1Ykc5allXd3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFp0SmxBMkhqQURBamVlNGpUTjlOK0FjRFJybmxjT2k2SmZqOWEKQWdUSFBxcmo1MGo1aUQ5SERUbXlOOXlkeS8yR2pUUStQaFB3UkxyUG9UUjV3Q1ZVTk5JbGdUelZpSE03d3JOWQo2V2N6bVpRQ0Zxd1hEbHBnZkRFUFhjUjQ5OUwzUXp1c3phczE4S2pEckFVTFdkT3NOL2k1SS9tbGJOdVlKSnpPCnFDQ0swRnFiemtBUU9oaGduZHdQMVdoUHZHSWVXTy96d3BOQUluVXpFck5LcW8ya2tQbHZwRmQydGhlWVY2cU8KRFBtZE9LQVRwb0xqR3dVSnIraWUyWlJXbjlSeUp4ZW4wTlhKcWZRMmg1WGp3MThCaXBNUVQ2WGhTVGtkUktibApDOHk0Z0tJY2xmc2lSckUwTER5dnVtSUhDMEFucTl2eDZ2VHo3elVFMFdPcEFZVVBBZ01CQUFHalFqQkFNQTRHCkExVWREd0VCL3dRRUF3SUNCREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFDYko3VkZOK3QKTWZCa0t4K2NVNXZObnhqNDFEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUF6cDdmTGR0S20vTzRwTGNNWWd3aApKZFJHSGlVOEU4bmJzWU1HamU3bEFockl0R2JoWURhT3NTRGMrc2NrUkVScDF4dDM1NnJsU1ZINGo4S2NWNnJZClRIUFM2NWdrNm1uMmEyT1A1aFQxUDdiYk8wVTQyaFM4WUpUR0IvTzRreThsYnRZWFBhRTFCbTQrOUw1eHlQMHkKSllJaDFqTVFKQ1UrOTdzS002V2xOZzh1NzMvZ2xhamJrOUNFRmJkUUVGRmVCVEJlVS9IOTY4SWFDL0txNlQ0SAo4VTBEc3hqQnZyN0gxRnpTY3lKQk8zSEdBTkhzWkRtdm9vMDk5WFdteElvSHRDb3dDdExjWFQ0cktPbmt2SERHCjZlalhuNzBjbUp5dFIrVzFJazc2VldjMXUwM2ZQZVB5WE4wOC85THFkS0J3L2dFQndTamkwanYwTVJSczZnWnUKOXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
      service:
        name: istiod
        namespace: istio-system
        path: /inject
        port: 443
    failurePolicy: Fail
    matchPolicy: Equivalent
    name: rev.object.sidecar-injector.istio.io
    namespaceSelector:
      matchExpressions:
      - key: istio.io/rev
        operator: DoesNotExist
      - key: istio-injection
        operator: DoesNotExist
    objectSelector:
      matchExpressions:
      - key: sidecar.istio.io/inject
        operator: NotIn
        values:
        - "false"
      - key: istio.io/rev
        operator: In
        values:
        - default
    reinvocationPolicy: Never
    rules:
    - apiGroups:
      - ""
      apiVersions:
      - v1
      operations:
      - CREATE
      resources:
      - pods
      scope: '*'
    sideEffects: None
    timeoutSeconds: 10
  - admissionReviewVersions:
    - v1beta1
    - v1
    clientConfig:
      caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvVENDQWVXZ0F3SUJBZ0lSQUtlRksvQmphOGVWR3VSelAzcTdXODh3RFFZSktvWklodmNOQVFFTEJRQXcKR0RFV01CUUdBMVVFQ2hNTlkyeDFjM1JsY2k1c2IyTmhiREFlRncweU1URXlNekV3TXpJM016RmFGdzB6TVRFeQpNamt3TXpJM016RmFNQmd4RmpBVUJnTlZCQW9URFdOc2RYTjBaWEl1Ykc5allXd3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFp0SmxBMkhqQURBamVlNGpUTjlOK0FjRFJybmxjT2k2SmZqOWEKQWdUSFBxcmo1MGo1aUQ5SERUbXlOOXlkeS8yR2pUUStQaFB3UkxyUG9UUjV3Q1ZVTk5JbGdUelZpSE03d3JOWQo2V2N6bVpRQ0Zxd1hEbHBnZkRFUFhjUjQ5OUwzUXp1c3phczE4S2pEckFVTFdkT3NOL2k1SS9tbGJOdVlKSnpPCnFDQ0swRnFiemtBUU9oaGduZHdQMVdoUHZHSWVXTy96d3BOQUluVXpFck5LcW8ya2tQbHZwRmQydGhlWVY2cU8KRFBtZE9LQVRwb0xqR3dVSnIraWUyWlJXbjlSeUp4ZW4wTlhKcWZRMmg1WGp3MThCaXBNUVQ2WGhTVGtkUktibApDOHk0Z0tJY2xmc2lSckUwTER5dnVtSUhDMEFucTl2eDZ2VHo3elVFMFdPcEFZVVBBZ01CQUFHalFqQkFNQTRHCkExVWREd0VCL3dRRUF3SUNCREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFDYko3VkZOK3QKTWZCa0t4K2NVNXZObnhqNDFEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUF6cDdmTGR0S20vTzRwTGNNWWd3aApKZFJHSGlVOEU4bmJzWU1HamU3bEFockl0R2JoWURhT3NTRGMrc2NrUkVScDF4dDM1NnJsU1ZINGo4S2NWNnJZClRIUFM2NWdrNm1uMmEyT1A1aFQxUDdiYk8wVTQyaFM4WUpUR0IvTzRreThsYnRZWFBhRTFCbTQrOUw1eHlQMHkKSllJaDFqTVFKQ1UrOTdzS002V2xOZzh1NzMvZ2xhamJrOUNFRmJkUUVGRmVCVEJlVS9IOTY4SWFDL0txNlQ0SAo4VTBEc3hqQnZyN0gxRnpTY3lKQk8zSEdBTkhzWkRtdm9vMDk5WFdteElvSHRDb3dDdExjWFQ0cktPbmt2SERHCjZlalhuNzBjbUp5dFIrVzFJazc2VldjMXUwM2ZQZVB5WE4wOC85THFkS0J3L2dFQndTamkwanYwTVJSczZnWnUKOXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
      service:
        name: istiod
        namespace: istio-system
        path: /inject
        port: 443
    failurePolicy: Fail
    matchPolicy: Equivalent
    name: namespace.sidecar-injector.istio.io
    namespaceSelector:
      matchExpressions:
      - key: istio-injection
        operator: In
        values:
        - enabled
    objectSelector:
      matchExpressions:
      - key: sidecar.istio.io/inject
        operator: NotIn
        values:
        - "false"
    reinvocationPolicy: Never
    rules:
    - apiGroups:
      - ""
      apiVersions:
      - v1
      operations:
      - CREATE
      resources:
      - pods
      scope: '*'
    sideEffects: None
    timeoutSeconds: 10
  - admissionReviewVersions:
    - v1beta1
    - v1
    clientConfig:
      caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvVENDQWVXZ0F3SUJBZ0lSQUtlRksvQmphOGVWR3VSelAzcTdXODh3RFFZSktvWklodmNOQVFFTEJRQXcKR0RFV01CUUdBMVVFQ2hNTlkyeDFjM1JsY2k1c2IyTmhiREFlRncweU1URXlNekV3TXpJM016RmFGdzB6TVRFeQpNamt3TXpJM016RmFNQmd4RmpBVUJnTlZCQW9URFdOc2RYTjBaWEl1Ykc5allXd3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFp0SmxBMkhqQURBamVlNGpUTjlOK0FjRFJybmxjT2k2SmZqOWEKQWdUSFBxcmo1MGo1aUQ5SERUbXlOOXlkeS8yR2pUUStQaFB3UkxyUG9UUjV3Q1ZVTk5JbGdUelZpSE03d3JOWQo2V2N6bVpRQ0Zxd1hEbHBnZkRFUFhjUjQ5OUwzUXp1c3phczE4S2pEckFVTFdkT3NOL2k1SS9tbGJOdVlKSnpPCnFDQ0swRnFiemtBUU9oaGduZHdQMVdoUHZHSWVXTy96d3BOQUluVXpFck5LcW8ya2tQbHZwRmQydGhlWVY2cU8KRFBtZE9LQVRwb0xqR3dVSnIraWUyWlJXbjlSeUp4ZW4wTlhKcWZRMmg1WGp3MThCaXBNUVQ2WGhTVGtkUktibApDOHk0Z0tJY2xmc2lSckUwTER5dnVtSUhDMEFucTl2eDZ2VHo3elVFMFdPcEFZVVBBZ01CQUFHalFqQkFNQTRHCkExVWREd0VCL3dRRUF3SUNCREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFDYko3VkZOK3QKTWZCa0t4K2NVNXZObnhqNDFEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUF6cDdmTGR0S20vTzRwTGNNWWd3aApKZFJHSGlVOEU4bmJzWU1HamU3bEFockl0R2JoWURhT3NTRGMrc2NrUkVScDF4dDM1NnJsU1ZINGo4S2NWNnJZClRIUFM2NWdrNm1uMmEyT1A1aFQxUDdiYk8wVTQyaFM4WUpUR0IvTzRreThsYnRZWFBhRTFCbTQrOUw1eHlQMHkKSllJaDFqTVFKQ1UrOTdzS002V2xOZzh1NzMvZ2xhamJrOUNFRmJkUUVGRmVCVEJlVS9IOTY4SWFDL0txNlQ0SAo4VTBEc3hqQnZyN0gxRnpTY3lKQk8zSEdBTkhzWkRtdm9vMDk5WFdteElvSHRDb3dDdExjWFQ0cktPbmt2SERHCjZlalhuNzBjbUp5dFIrVzFJazc2VldjMXUwM2ZQZVB5WE4wOC85THFkS0J3L2dFQndTamkwanYwTVJSczZnWnUKOXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
      service:
        name: istiod
        namespace: istio-system
        path: /inject
        port: 443
    failurePolicy: Fail
    matchPolicy: Equivalent
    name: object.sidecar-injector.istio.io
    namespaceSelector:
      matchExpressions:
      - key: istio-injection
        operator: DoesNotExist
      - key: istio.io/rev
        operator: DoesNotExist
    objectSelector:
      matchExpressions:
      - key: sidecar.istio.io/inject
        operator: In
        values:
        - "true"
      - key: istio.io/rev
        operator: DoesNotExist
    reinvocationPolicy: Never
    rules:
    - apiGroups:
      - ""
      apiVersions:
      - v1
      operations:
      - CREATE
      resources:
      - pods
      scope: '*'
    sideEffects: None
    timeoutSeconds: 10
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

如果enableNamespacesByDefault设置为true时,会根据命名空间选择器的匹配规则来决定是否默认启用Sidecar自动注入,即istio-injection不为disabled;反之,如果enableNamespacesByDefault设置为false时,只有命令空间中设置了标签istio-injection并且值为enabled,才会启用Sidecar自动注入。

匹配请求-规则

  • operations 列出一个或多个要匹配的操作。 可以是 CREATEUPDATEDELETECONNECT* 以匹配所有内容。
  • apiGroups 列出了一个或多个要匹配的 API 组。"" 是核心 API 组。"*" 匹配所有 API 组。
  • apiVersions 列出了一个或多个要匹配的 API 版本。"*" 匹配所有 API 版本。
  • resources 列出了一个或多个要匹配的资源。
  • "*" 匹配所有资源,但不包括子资源。
  • "*/*" 匹配所有资源,包括子资源。
  • "pods/*" 匹配 pod 的所有子资源。
  • "*/status" 匹配所有 status 子资源。
  • scope 指定要匹配的范围。有效值为 "Cluster""Namespaced""*"。 子资源匹配其父资源的范围。在 Kubernetes v1.14+ 版本中才被支持。 默认值为 "*",对应 1.14 版本之前的行为。
  • "Cluster" 表示只有集群作用域的资源才能匹配此规则(API 对象 Namespace 是集群作用域的)。
  • "Namespaced" 意味着仅具有名字空间的资源才符合此规则。
  • "*" 表示没有范围限制。

注入条件

  • Webhook的namespaceSelector机制。
  • 默认策略。
  • 每个pod的可覆盖注解。

案例

Sidecar自动注入的规则,enableNamespacesByDefault设置为false时,命名空间中设置了标签istio-injection并且值为enabled,才会启用Sidecar自动注入。

# 为命名空间default增加标签istio-injection且值设为enabled
$ kubectl label namespaces default istio-injection=enabled
namespace/default labeled

$  cat nginx-deployment.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
$ kubectl apply -f nginx-deployment.yml 
deployment.apps/nginx-deployment created


# 通过查看pod详情可以发现sidecar已注入
$ kubectl describe pods nginx-deployment-66b6c48dd5-swz7j 
Name:         nginx-deployment-66b6c48dd5-swz7j
Namespace:    default
Priority:     0
Node:         k8s-node02/192.168.1.105
Start Time:   Thu, 20 Jan 2022 16:37:28 +0800
Labels:       app=nginx
              istio.io/rev=default
              pod-template-hash=66b6c48dd5
              security.istio.io/tlsMode=istio
              service.istio.io/canonical-name=nginx
              service.istio.io/canonical-revision=latest
Annotations:  cni.projectcalico.org/podIP: 100.125.152.31/32
              cni.projectcalico.org/podIPs: 100.125.152.31/32
              kubectl.kubernetes.io/default-container: nginx
              kubectl.kubernetes.io/default-logs-container: nginx
              prometheus.io/path: /stats/prometheus
              prometheus.io/port: 15020
              prometheus.io/scrape: true
              sidecar.istio.io/status:
                {"initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["istio-envoy","istio-data","istio-podinfo","istiod-ca-cert"],"ima...
Status:       Running
IP:           100.125.152.31
IPs:
  IP:           100.125.152.31
Controlled By:  ReplicaSet/nginx-deployment-66b6c48dd5
Init Containers:
  istio-init:
    Container ID:  docker://3d1d8f5c7840df4e680b222a44d5597c2f1363aeddf75337c84a5d31349fece5
    Image:         docker.io/istio/proxyv2:1.10.6
    Image ID:      docker-pullable://istio/proxyv2@sha256:c26d5a662ffb9e931b71198c1c5647466e0423e5408a37acb92d97dadcf00f2c
    Port:          <none>
    Host Port:     <none>
    Args:
      istio-iptables
      -p
      15001
      -z
      15006
      -u
      1337
      -m
      REDIRECT
      -i
      *
      -x
      
      -b
      *
      -d
      15090,15021,15020
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Thu, 20 Jan 2022 16:37:29 +0800
      Finished:     Thu, 20 Jan 2022 16:37:29 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     2
      memory:  1Gi
    Requests:
      cpu:        100m
      memory:     128Mi
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-xr52f (ro)
Containers:
  nginx:
    Container ID:   docker://4deec4c4a8573445fc086275ae8665e75778e1c615e33fa12e9014eb5f721db0
    Image:          nginx:1.14.2
    Image ID:       docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 20 Jan 2022 16:37:30 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-xr52f (ro)
  istio-proxy:
    Container ID:  docker://9b183d318f0b73ec8d42bf69abc7cf41ff2290f59ed9e2cca6e513e1a85ac775
    Image:         docker.io/istio/proxyv2:1.10.6
    Image ID:      docker-pullable://istio/proxyv2@sha256:c26d5a662ffb9e931b71198c1c5647466e0423e5408a37acb92d97dadcf00f2c
    Port:          15090/TCP
    Host Port:     0/TCP
    Args:
      proxy
      sidecar
      --domain
      $(POD_NAMESPACE).svc.cluster.local
      --serviceCluster
      nginx.$(POD_NAMESPACE)
      --proxyLogLevel=warning
      --proxyComponentLogLevel=misc:error
      --log_output_level=default:info
      --concurrency
      2
    State:          Running
      Started:      Thu, 20 Jan 2022 16:37:30 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     2
      memory:  1Gi
    Requests:
      cpu:      100m
      memory:   128Mi
    Readiness:  http-get http://:15021/healthz/ready delay=1s timeout=3s period=2s #success=1 #failure=30
    Environment:
      JWT_POLICY:                    first-party-jwt
      PILOT_CERT_PROVIDER:           istiod
      CA_ADDR:                       istiod.istio-system.svc:15012
      POD_NAME:                      nginx-deployment-66b6c48dd5-swz7j (v1:metadata.name)
      POD_NAMESPACE:                 default (v1:metadata.namespace)
      INSTANCE_IP:                    (v1:status.podIP)
      SERVICE_ACCOUNT:                (v1:spec.serviceAccountName)
      HOST_IP:                        (v1:status.hostIP)
      CANONICAL_SERVICE:              (v1:metadata.labels['service.istio.io/canonical-name'])
      CANONICAL_REVISION:             (v1:metadata.labels['service.istio.io/canonical-revision'])
      PROXY_CONFIG:                  {}
                                     
      ISTIO_META_POD_PORTS:          [
                                         {"containerPort":80,"protocol":"TCP"}
                                     ]
      ISTIO_META_APP_CONTAINERS:     nginx
      ISTIO_META_CLUSTER_ID:         Kubernetes
      ISTIO_META_INTERCEPTION_MODE:  REDIRECT
      ISTIO_META_WORKLOAD_NAME:      nginx-deployment
      ISTIO_META_OWNER:              kubernetes://apis/apps/v1/namespaces/default/deployments/nginx-deployment
      ISTIO_META_MESH_ID:            cluster.local
      TRUST_DOMAIN:                  cluster.local
    Mounts:
      /etc/istio/pod from istio-podinfo (rw)
      /etc/istio/proxy from istio-envoy (rw)
      /var/lib/istio/data from istio-data (rw)
      /var/run/secrets/istio from istiod-ca-cert (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-xr52f (ro

小结

Istio 自动注入Sidecar是根据kubernets Apiserver准入Webook实现。当请求通过认证和授权后, 对象被持久化之前拦截到达 API 服务器的请求,会根据Api sever中的配置,分配去执行变更和验证准入的Webhook。这时istio-sidecar-injector Webhook会根据注入条件进行更改Pod模板达到目的。

1

评论区