Istio Sidecar

理解Istio网格中Envoy代理Sidecar

Sidecar简介

alt

  • Sidecar设计模式允许你为应用程序添加许多功能,而无需额外第三方组件的配置和代码的修改。
  • Sidecar应用是连接到父应用并且为其扩展或者增强功能,可观察性、监控、日志记录、配置、断路器等。
  • Sidecar应用与主应用程序松散耦合。

注入方式

istio通过修改deployment配置完成相关内容注入

k8s自动注入

alt

  • Kubernetes通过Admission Controller可以拦截所有发往Api server的请求
  • Istio通过MutatingAdmissionWebhook(变更类型Admission Controller)完成对deployment的请求修改
  • 自定义配置通过ConfigMap获取
$ kubectl get configmap istio-sidecar-injector -n istio-system
NAME                     DATA   AGE
istio-sidecar-injector   2      28h

istioctl手工注入

istioctl kube-inject -f samples/sleep/sleep.yaml | kubectl apply -f -

注入内容

alt

Istio sidecar向应用pod中注入2个容器:

  • init,初始化Envoy环境,配置iptables规则,拦截所有进出口流量至proxy
  • istio-proxy,Envoy代理,运行pilot-agent和envoy进程

alt

  • Pilot-agent负责管理Envoy进程,重启、静态配置热加载等
  • Envoy动态配置通过xDS更新

未注入Sidecar的deployment:

$ kubectl describe pod productpage-v1-76589d9fdc-8wtsk -n book2
Name:           productpage-v1-76589d9fdc-8wtsk
Namespace:      book2
Priority:       0
Node:           docker-desktop/192.168.65.3
Start Time:     Sat, 04 Apr 2020 15:08:29 +0800
Labels:         app=productpage
                pod-template-hash=76589d9fdc
                version=v1
Annotations:    <none>
Status:         Running
IP:             10.1.0.158
Controlled By:  ReplicaSet/productpage-v1-76589d9fdc
Containers:
  productpage:
    Container ID:   docker://258b46f265776451f075ddba845461ed496cd38242f5d8fec008c05f1e714de3
    Image:          docker.io/istio/examples-bookinfo-productpage-v1:1.15.0
    Image ID:       docker-pullable://istio/examples-bookinfo-productpage-v1@sha256:0a5eb4795952372251d51f72834bccb7ea01a67cb72fd9b58b757cca103b7524
    Port:           9080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sat, 04 Apr 2020 15:08:30 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /tmp from tmp (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from bookinfo-productpage-token-jhdhv (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  tmp:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
  bookinfo-productpage-token-jhdhv:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  bookinfo-productpage-token-jhdhv
    Optional:    false

注入Sidecar的deployment:

$ kubectl describe pod productpage-v1-76589d9fdc-knv7t -n book
Name:           productpage-v1-76589d9fdc-knv7t
Namespace:      book
Priority:       0
Node:           docker-desktop/192.168.65.3
Start Time:     Fri, 03 Apr 2020 11:02:55 +0800
Labels:         app=productpage
                pod-template-hash=76589d9fdc
                security.istio.io/tlsMode=istio
                service.istio.io/canonical-name=productpage
                service.istio.io/canonical-revision=v1
                version=v1
Annotations:    sidecar.istio.io/status:
                  {"version":"64f53c7f7e9dca50ddb9767390392872119f042c4a541dbbb6a973d5638bd264","initContainers":["istio-init"],"containers":["istio-proxy"]...
Status:         Running
IP:             10.1.0.152
Controlled By:  ReplicaSet/productpage-v1-76589d9fdc
Init Containers:
  istio-init:
    Container ID:  docker://0b4b26c5019d9695d71005898423efbbe654875e54e7790e0145ce809771d5f7
    Image:         docker.io/istio/proxyv2:1.5.1
    Image ID:      docker-pullable://istio/proxyv2@sha256:3ad9ee2b43b299e5e6d97aaea5ed47dbf3da9293733607d9b52f358313e852ae
    Port:          <none>
    Host Port:     <none>
    Command:
      istio-iptables
      -p
      15001
      -z
      15006
      -u
      1337
      -m
      REDIRECT
      -i
      *
      -x

      -b
      *
      -d
      15090,15020
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Fri, 03 Apr 2020 11:02:56 +0800
      Finished:     Fri, 03 Apr 2020 11:02:57 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     100m
      memory:  50Mi
    Requests:
      cpu:        10m
      memory:     10Mi
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from bookinfo-productpage-token-tdzd2 (ro)
Containers:
  productpage:
    Container ID:   docker://8a3472e912f947431294aa2d9c59471f5351813769942454101e75cb150c29d7
    Image:          docker.io/istio/examples-bookinfo-productpage-v1:1.15.0
    Image ID:       docker-pullable://istio/examples-bookinfo-productpage-v1@sha256:0a5eb4795952372251d51f72834bccb7ea01a67cb72fd9b58b757cca103b7524
    Port:           9080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Fri, 03 Apr 2020 11:02:58 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /tmp from tmp (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from bookinfo-productpage-token-tdzd2 (ro)
  istio-proxy:
    Container ID:  docker://38a1aa9ab4b563c7c933bf96ff9f27b00c0203e1b60cc63decfd6663c702ff9e
    Image:         docker.io/istio/proxyv2:1.5.1
    Image ID:      docker-pullable://istio/proxyv2@sha256:3ad9ee2b43b299e5e6d97aaea5ed47dbf3da9293733607d9b52f358313e852ae
    Port:          15090/TCP
    Host Port:     0/TCP
    Args:
      proxy
      sidecar
      --domain
      $(POD_NAMESPACE).svc.cluster.local
      --configPath
      /etc/istio/proxy
      --binaryPath
      /usr/local/bin/envoy
      --serviceCluster
      productpage.$(POD_NAMESPACE)
      --drainDuration
      45s
      --parentShutdownDuration
      1m0s
      --discoveryAddress
      istiod.istio-system.svc:15012
      --zipkinAddress
      zipkin.istio-system:9411
      --proxyLogLevel=warning
      --proxyComponentLogLevel=misc:error
      --connectTimeout
      10s
      --proxyAdminPort
      15000
      --concurrency
      2
      --controlPlaneAuthPolicy
      NONE
      --dnsRefreshRate
      300s
      --statusPort
      15020
      --trust-domain=cluster.local
      --controlPlaneBootstrap=false
    State:          Running
      Started:      Fri, 03 Apr 2020 11:02:58 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     2
      memory:  1Gi
    Requests:
      cpu:      10m
      memory:   40Mi
    Readiness:  http-get http://:15020/healthz/ready delay=1s timeout=1s period=2s #success=1 #failure=30
    Environment:
      JWT_POLICY:                    first-party-jwt
      PILOT_CERT_PROVIDER:           istiod
      CA_ADDR:                       istio-pilot.istio-system.svc:15012
      POD_NAME:                      productpage-v1-76589d9fdc-knv7t (v1:metadata.name)
      POD_NAMESPACE:                 book (v1:metadata.namespace)
      INSTANCE_IP:                    (v1:status.podIP)
      SERVICE_ACCOUNT:                (v1:spec.serviceAccountName)
      HOST_IP:                        (v1:status.hostIP)
      ISTIO_META_POD_PORTS:          [
                                         {"containerPort":9080,"protocol":"TCP"}
                                     ]
      ISTIO_META_CLUSTER_ID:         Kubernetes
      ISTIO_META_POD_NAME:           productpage-v1-76589d9fdc-knv7t (v1:metadata.name)
      ISTIO_META_CONFIG_NAMESPACE:   book (v1:metadata.namespace)
      ISTIO_META_INTERCEPTION_MODE:  REDIRECT
      ISTIO_META_WORKLOAD_NAME:      productpage-v1
      ISTIO_META_OWNER:              kubernetes://apis/apps/v1/namespaces/book/deployments/productpage-v1
      ISTIO_META_MESH_ID:            cluster.local
    Mounts:
      /etc/istio/pod from podinfo (rw)
      /etc/istio/proxy from istio-envoy (rw)
      /var/run/secrets/istio from istiod-ca-cert (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from bookinfo-productpage-token-tdzd2 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  tmp:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
  bookinfo-productpage-token-tdzd2:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  bookinfo-productpage-token-tdzd2
    Optional:    false
  istio-envoy:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     Memory
    SizeLimit:  <unset>
  podinfo:
    Type:  DownwardAPI (a volume populated by information about the pod)
    Items:
      metadata.labels -> labels
      metadata.annotations -> annotations
  istiod-ca-cert:
    Type:        ConfigMap (a volume populated by a ConfigMap)
    Name:        istio-ca-root-cert
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s

增加:

  • Init Containers: istio-init
  • Containers:istio-proxy

网络控制

Init 容器通过向 iptables nat 表中注入转发规则来劫持流量

alt

  • 将应用容器的所有入口流量都转发到Envoy的15006端口。
  • 将应用容器的所有出口流量都转发到Envoy的15001端口。
  • 使用istio-proxy默认用户身份运行,UID为1337。
  • 使用默认的REDIRECT模式来重定向流量。
  • 将所有出站流量都重定向到Envoy代理。
  • 将所有访问应用容器端口的流量重定向到Envoy代理。

参考