目的

从内嵌到应用的SDK模式转成istio servicemesh,再到最新提出来的proxyless可谓是发展太快了。刚开始我只是围绕着服务注册和发现是怎么转变来展开研究,但是发现这个话题有点大,还是得一步步来:

  • sidecar如何接管流量?
  • 如果不考虑现有的微服务体系,注册和发现怎么实现,有几种方式?
  • 结合现有的微服务体系,注册和发现该如何融合?

先一步步研究吧,抓着这个主方向不断地探寻,肯定有所收获。

今天和大家分享第一个,sidecar如何接管流量

整个istio的bookinfo环境搭建如下

按照官网

  • 首先安装k8s(我用minikube)
  • 再安装istio
  • 开启默认namespace:default的sidecar注入然后跑samples的bookinfo

image

下图是使用 Istio 管理的 bookinfo 示例的访问请求路径图

image

sidecar注入

先开启sidecar注入

kubectl label namespace default istio-injection=enabled

部署bookinfo


kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

成功后

  • 会创建svc:

image
  • 和创建pods:

image

sidecar注入是依赖k8s的webhook功能来实现的,在创建pod的Crd资源增加了istio的配置

pod资源被webhook修改成啥样了

先来分析下productpage


##################################################################################################
# Productpage services
##################################################################################################
apiVersion: v1
kind: Service
metadata:
  name: productpage
  labels:
    app: productpage
    service: productpage
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: productpage
apiVersion: apps/v1
kind: Deployment
metadata:
  name: productpage-v1
  labels:
    app: productpage
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: productpage
      version: v1
  template:
    metadata:
      labels:
        app: productpage
        version: v1
    spec:
      serviceAccountName: bookinfo-productpage
      containers:
      - name: productpage
        image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
        volumeMounts:
        - name: tmp
          mountPath: /tmp
        securityContext:
          runAsUser: 1000
      volumes:
      - name: tmp
        emptyDir: {}
---    

对应productpage镜像的DockerFile:

image

productpage是一个Flask写的python应用

image

通过命令查看sidecar注入后的productpage配置是怎么样的

kubectl describe pod -l app=productpage


Name:         productpage-v1-6b746f74dc-59t8d
Namespace:    default
Priority:     0
Node:         minikube/192.168.49.2
Start Time:   Sat, 25 Dec 2021 16:53:08 +0800
Labels:       app=productpage
              pod-template-hash=6b746f74dc
              security.istio.io/tlsMode=istio
              service.istio.io/canonical-name=productpage
              service.istio.io/canonical-revision=v1
              version=v1
Annotations:  kubectl.kubernetes.io/default-container: productpage
              kubectl.kubernetes.io/default-logs-container: productpage
              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","istio-token","istiod-...
Status:       Running
IP:           172.17.0.7
IPs:
  IP:           172.17.0.7
Controlled By:  ReplicaSet/productpage-v1-6b746f74dc
Init Containers:
  istio-init:
    Container ID:  docker://81d9c7297737675de742388e54de51d21598da8e6a63b81d293c69b848e92ba7
    Image:         docker.io/istio/proxyv2:1.12.1
    Image ID:      docker-pullable://istio/proxyv2@sha256:4704f04f399ae24d99e65170d1846dc83d7973f186656a03ba70d47bd1aba88f
    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:      Sun, 26 Dec 2021 14:23:05 +0800
      Finished:     Sun, 26 Dec 2021 14:23:05 +0800
    Ready:          True
    Restart Count:  1
    Limits:
      cpu:     2
      memory:  1Gi
    Requests:
      cpu:        10m
      memory:     40Mi
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-clsdq (ro)
Containers:
  productpage:
    Container ID:   docker://421334a3a5262bdbb29158c423cce3464e19ac3267c7c6240ca5d89a1d38962a
    Image:          docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
    Image ID:       docker-pullable://istio/examples-bookinfo-productpage-v1@sha256:63ac3b4fb6c3ba395f5d044b0e10bae513afb34b9b7d862b3a7c3de7e0686667
    Port:           9080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sun, 26 Dec 2021 14:23:11 +0800
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Sat, 25 Dec 2021 16:56:01 +0800
      Finished:     Sat, 25 Dec 2021 22:51:12 +0800
    Ready:          True
    Restart Count:  1
    Environment:    <none>
    Mounts:
      /tmp from tmp (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-clsdq (ro)
  istio-proxy:
    Container ID:  docker://c3d8a9d57e632112f86441fafad64eb73df3ea4f7317dbfb72152107c493866b
    Image:         docker.io/istio/proxyv2:1.12.1
    Image ID:      docker-pullable://istio/proxyv2@sha256:4704f04f399ae24d99e65170d1846dc83d7973f186656a03ba70d47bd1aba88f
    Port:          15090/TCP
    Host Port:     0/TCP
    Args:
      proxy
      sidecar
      --domain
      $(POD_NAMESPACE).svc.cluster.local
      --proxyLogLevel=warning
      --proxyComponentLogLevel=misc:error
      --log_output_level=default:info
      --concurrency
      2
    State:          Running
      Started:      Sun, 26 Dec 2021 14:23:13 +0800
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Sat, 25 Dec 2021 16:56:01 +0800
      Finished:     Sat, 25 Dec 2021 22:51:15 +0800
    Ready:          True
    Restart Count:  1
    Limits:
      cpu:     2
      memory:  1Gi
    Requests:
      cpu:      10m
      memory:   40Mi
    Readiness:  http-get http://:15021/healthz/ready delay=1s timeout=3s period=2s #success=1 #failure=30
    Environment:
      JWT_POLICY:                    third-party-jwt
      PILOT_CERT_PROVIDER:           istiod
      CA_ADDR:                       istiod.istio-system.svc:15012
      POD_NAME:                      productpage-v1-6b746f74dc-59t8d (v1:metadata.name)
      POD_NAMESPACE:                 default (v1:metadata.namespace)
      INSTANCE_IP:                    (v1:status.podIP)
      SERVICE_ACCOUNT:                (v1:spec.serviceAccountName)
      HOST_IP:                        (v1:status.hostIP)
      PROXY_CONFIG:                  {}       ISTIO_META_POD_PORTS:          [
                                         {"containerPort":9080,"protocol":"TCP"}
                                     ]
      ISTIO_META_APP_CONTAINERS:     productpage
      ISTIO_META_CLUSTER_ID:         Kubernetes
      ISTIO_META_INTERCEPTION_MODE:  REDIRECT
      ISTIO_META_WORKLOAD_NAME:      productpage-v1
      ISTIO_META_OWNER:              kubernetes://apis/apps/v1/namespaces/default/deployments/productpage-v1
      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 kube-api-access-clsdq (ro)
      /var/run/secrets/tokens from istio-token (rw)
省略

可以看出来多了2个东西的配置

  • istio-init
  • istio-proxy

istio-init

init容器 给pod配置iptables 让流量进入pod和出pod都重定向sidecar指定端口

用的镜像:docker.io/istio/proxyv2:1.12.1

新版本的istio已经用go语言重写了,以前老版本是一个sh脚本来配置iptables的

看老本也许更容易明白 https://github.com/istio/istio/blob/0.5.0/tools/deb/istio-iptables.sh

启动参数:

 istio-iptables
      -p 15001 // 出站流量都重定向到此端口
      -z 15006 // 进站流量都重定向到此端口
      -u 1337
      -m REDIRECT
      -i * -x "" -b * // 匹配全部的IP地址范围和端口列表
      -d 15090,15021,15020 //这些内部用的端口排除不拦截(下表) 

image

istio-proxy

启动sidecar

用的镜像:docker.io/istio/proxyv2:1.12.1


 proxy
      sidecar
      --domain
      $(POD_NAMESPACE).svc.cluster.local
      --proxyLogLevel=warning
      --proxyComponentLogLevel=misc:error
      --log_output_level=default:info
      --concurrency

查看iptales是怎么配置的

//进入minikube
minikube ssh //切换为 root 用户,minikube 默认用户为 docker
sudo -i //拿到这个istio_proxy的启动的进程(一个是pilot-agent 一个是envoy)
docker top `docker ps|grep "istio-proxy_productpage"|cut -d " " -f1` 
 
 
//进入上条命令打印的PID(随意哪个)
nsenter -n --target 5141

image

被istio注入后pod下参与的容器如下:

  • k8s_infra(也叫pause容器 把它理解为pod的底)
  • istio_init(配置IpTables)
  • app(应用容器)
  • istio_proxy (启动pilot-agentenvoy如下图)

我理解的启动顺序也是按照从上到下的顺序,因为同一个pod下想要网络栈共享,必须得有一个底容器来兜底,其他容器指定-net=兜底容器id加入网络栈,所以我认为infra是最先启动才对

到底是init容器先启动,还是infra先启动,这块我没有找到相关资料,如果我理解有误望大佬教育!

总结

istio的sidecar注入,把pod的流量的出入用iptables的方式拦截了到了Envoy,

回到productpage的代码

//product_id默认为0
def getProductReviews(product_id, headers):
    # Do not remove. Bug introduced explicitly for illustration in fault injection task
    # TODO: Figure out how to achieve the same effect using Envoy retries/timeouts
    for _ in range(2):
        try:
            url = reviews['name'] + "/" + reviews['endpoint'] + "/" + str(product_id)
            res = requests.get(url, headers=headers, timeout=3.0)
        except BaseException:
            res = None
        if res and res.status_code == 200:
            return 200, res.json()
    status = res.status_code if res is not None and res.status_code else 500
    return status, {'error': 'Sorry, product reviews are currently unavailable for this book.'}

image

访问的reviews的url:http://reviews:9080/reviews/0

那么流量被sidecar拦截之后的流程如下图:

image

这里你肯定有一个疑问,

http://reviews:9080/reviews/0

这种域名式的访问是如何被envoy知道具体的请求地址的?是用kube-proxy吗? 下次再讲把!

感谢我的好朋友Raphael.Goh和istio大神dozer给予技术指导,让我慢慢走进内部去欣赏它的美!

istio的sidecar原理学习的更多相关文章

  1. 1.深入Istio:Sidecar自动注入如何实现的?

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的Istio源码是 release 1.5. 这篇文章打算讲一下sidecar, ...

  2. IIS原理学习

    IIS 原理学习 首先声明以下内容是我在网上搜索后整理的,在此只是进行记录,以备往后查阅只用. IIS 5.x介绍 IIS 5.x一个显著的特征就是Web Server和真正的ASP.NET Appl ...

  3. zookkeper原理学习

    zookkeper原理学习  https://segmentfault.com/a/1190000014479433   https://www.cnblogs.com/felixzh/p/58692 ...

  4. GIS原理学习目录

    GIS原理学习目录 内容提要 本网络教程是教育部“新世纪网络课程建设工程”的实施课程.系统扼要地阐述地理信息系统的技术体系,重点突出地理信息系统的基本技术及方法. 本网络教程共分八章:第一章绪论,重点 ...

  5. 转:SVM与SVR支持向量机原理学习与思考(一)

    SVM与SVR支持向量机原理学习与思考(一) 转:http://tonysh-thu.blogspot.com/2009/07/svmsvr.html 弱弱的看了看老掉牙的支持向量机(Support ...

  6. Android自复制传播APP原理学习(翻译)

     Android自复制传播APP原理学习(翻译) 1 背景介绍 论文链接:http://arxiv.org/abs/1511.00444 项目地址:https://github.com/Tribler ...

  7. 计算机原理学习(1)-- 冯诺依曼体系和CPU工作原理

    前言 对于我们80后来说,最早接触计算机应该是在95年左右,那个时候最流行的一个词语是多媒体. 依旧记得当时在同学家看同学输入几个DOS命令就成功的打开了一个游戏,当时实在是佩服的五体投地.因为对我来 ...

  8. Dubbo原理学习

    Dubbo源码及原理学习 阿里中间件团队博客 Dubbo官网 Dubbo源码解析 Dubbo源码解析-掘金 Dubbo源码解析-赵计刚 Dubbo系列 源码总结+最近感悟

  9. XGBoost原理学习总结

    XGBoost原理学习总结 前言 ​ XGBoost是一个上限提别高的机器学习算法,和Adaboost.GBDT等都属于Boosting类集成算法.虽然现在深度学习算法大行其道,但很多数据量往往没有太 ...

随机推荐

  1. 【豆科基因组】豇豆Cowpea,Vigna unguiculata [L.] Walp.基因组2019PJ

    目录 来源 结果 基因组大小估计 采用stitching方法组装 修改豇豆染色体编号 基因注释和重复DNA 豇豆遗传多样性 SNP和INDEL Vu03 上 4.2-Mb 染色体倒位的鉴定 与其他暖季 ...

  2. python-django-数据查询条件

    查询用户的状态是2或者是4的情况 空值和空字符串是不一样的东西!!! 需要注意的是: 项目setting.py里面的时区采用的是美国的时区,我们不要使用这个时区 使用这个时区的,我们输入的日期会进行转 ...

  3. zabbix监控php状态

    环境介绍: php /usr/loca/php nignx /usr/loca/nginx  配置文件都是放在extra中 修改php-fpm的配置文件启动状态页面 pm.status_path = ...

  4. Linux— file命令 用于辨识文件类型

    Linux file命令用于辨识文件类型. 通过file指令,我们得以辨识该文件的类型. 语法 file [-bcLvz][-f <名称文件>][-m <魔法数字文件>...] ...

  5. 10.Power of Two-Leetcode

    Given an integer, write a function to determine if it is a power of two. class Solution { public: bo ...

  6. 以DevExpress开发的WinFrom程序的多语言功能的实现

    以DevExpress开发的WinFrom程序的多语言功能的实现 写在前面: 多语言切换功能在Winform程序中是经常遇到的需求,尤其是需要给国外客户使用的情况下,多语言功能是必不可少的.前一段时间 ...

  7. UE4打包启动失败:RunUAT.bat ERROR: AutomationTool failed to compile.

    打包配置正常的情况下,出现下面Log: RunUAT.bat ERROR: AutomationTool failed to compile. 基本上,可以先排查下任务管理器中是不是有UE4Edito ...

  8. MapReduce02 序列化

    目录 MapReduce 序列化 概述 自定义序列化 常用数据序列化类型 int与IntWritable转化 Text与String 序列化读写方法 自定义bean对象实现序列化接口(Writable ...

  9. 如果通过 IP 判断是否是爬虫

    通过 IP 判断爬虫 如果你查看服务器日志,看到密密麻麻的 IP 地址,你一眼可以看出来那些 IP 是爬虫,那些 IP 是正常的爬虫,就像这样: 在这密密麻麻的日志里面,我们不仅要分辨出真正的爬虫 I ...

  10. JAVA中的六种日期类型使用

    基本的6种日期类 /** * 六种时间类型的类 * 数据库格式的时间三种格式 */ java.util.Date date = new java.util.Date();//年与日时分秒 //数据库的 ...