查看原文
其他

一篇文章让你了解Service Mesh的明星项目Istio

吴迪 RancherLabs 2019-12-18

早在去年,Service Mesh 这个概念就开始火起来了,今年的时候 Service Mesh 更是爆发式地发展,Service Mesh 中的明星项目 Istio 更是只用了几个月的时间就已经从 0.1 到了 1.0 了。


Istio 的背景本文不再赘述,G 家等大厂开发出来并且在后面推动支持的肯定不会弱。

 

根据 Istio 的官方文档,是这么定义自己的:一个用来连接、管理和加密微服务(流量)的开放平台。

 

an open platform to connect, manage, and secure microservices

 

Istio 可以让你在不修改微服务源代码的情况之下,很轻松地给微服务加上诸如负载均衡、身份验证、监控等等的功能。Istio 通过在你的微服务中部署一个 sidecar 作为所有流量的代理来达成这个目标。

 

总结下来,Istio 提供了以下功能:

  • 流量管理(Traffic Management)

  • 服务的身份认证和安全(Service Identity and Security)

  • 策略配置(Policy Enforcement)

  • 遥感(Telemetry)

除了这些之外,Istio 还支持很多不同的平台(尤其是 Kubernetes),并且支持自定义的组件和集成。


通过这些功能,微服务的开发和迁移变得更加容易,对于运维人员来说,也可以更方便地更改部署策略。


接下来介绍Istio的架构。Istio 是两层架构的,分别是数据层和控制层:

 

数据层是由所有的部署为 sidecar 的 Envoy 所组成的。

控制层有三个组件:Pilot、Mixer 和 Citadel,顾名思义是用来控制 Service Mesh 的行为的。


总体的架构如下图:



首先来看数据层的Envoy。Istio 用了一个扩展版本的 Envoy 作为底层的代理。Envoy 是一个用 C++ 开发的高性能的代理,具有非常多功能,具体的可以参考官方文档,在此不做赘述。

 

Envoy 在 Istio 中是以 sidecar 模式部署在 pod 里面的,Istio 通过控制 Envoy 来控制所有的流量,获取监控数据等。


接着,来看控制层的Pilot、Mixer和Citadel。Pilot 为 Envoy 提供服务发现、智能路由(如 AB 测试、金丝雀部署)和弹性流量管理功能(如超时、重试、熔断)。它负责将高层的抽象的路由规则转化成低级的 envoy 的配置。

 

Mixer 是一个平台无关的组件,用来控制访问策略和使用策略,同时会收集监控信息,将收集到的信息传给用户可以自定义的后端进行处理。

 

Citadel 提供了服务间和服务到终端用户的认证,同时可以直接将 http 流量升级成 https 流量。具体的可以查看官方文档。


下面简要介绍一下安装。在这里我打算使用 helm 进行安装。

 

Prerequisite


首先,你得有一个可运行的 Kubernetes 集群,我是在 GKE上开了一个三节点的集群作为测试使用。


其次,你得需要有 helm 的客户端。mac 用户可以通过 brew 来安装。


下载 release


Istio 提供了一个很方便的脚本来下载并解压最新版的 Istio,如下:

  1. $ curl -L https://git.io/getLatestIstio | sh -

等下载完之后,我们可以进入文件夹,并把 bin 目录加到 path 里面:

  1. $ cd istio-0.8.0

  2. $ export PATH=$PWD/bin:$PATH


使用 helm 进行安装


要使用 helm 来安装 istio,首先需要在集群里面配置好 helm 和 tiller,如下:

  1. $ kubectl create -f install/kubernetes/helm/helm-service-account.yaml

  2. $ helm init --service-account tiller


等 helm 和 tiller 配置完之后,就可以使用 helm 来一键安装 Istio 了:

  1. $ helm install install/kubernetes/helm/istio --name istio --namespace istio-system


这样,Istio 就安装好了。


为了验证安装是否成功,我们可以看一下是否部署了以下的 service:

  1. $ kubectl get svc -n istio-system

  2. NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                                                               AGE

  3. istio-citadel              ClusterIP      10.19.247.33    <none>            8060/TCP,9093/TCP                                                     2m

  4. istio-egressgateway        ClusterIP      10.19.244.143   <none>            80/TCP,443/TCP                                                        2m

  5. istio-ingress              LoadBalancer   10.19.248.42    104.199.155.220   80:32000/TCP,443:30434/TCP                                            2m

  6. istio-ingressgateway       LoadBalancer   10.19.254.155   35.229.183.83     80:31380/TCP,443:31390/TCP,31400:31400/TCP                            2m

  7. istio-pilot                ClusterIP      10.19.252.30    <none>            15003/TCP,15005/TCP,15007/TCP,15010/TCP,15011/TCP,8080/TCP,9093/TCP   2m

  8. istio-policy               ClusterIP      10.19.242.187   <none>            9091/TCP,15004/TCP,9093/TCP                                           2m

  9. istio-sidecar-injector     ClusterIP      10.19.252.155   <none>            443/TCP                                                               2m

  10. istio-statsd-prom-bridge   ClusterIP      10.19.246.99    <none>            9102/TCP,9125/UDP                                                     2m

  11. istio-telemetry            ClusterIP      10.19.240.18    <none>            9091/TCP,15004/TCP,9093/TCP,42422/TCP                                 2m

  12. prometheus                 ClusterIP      10.19.255.53    <none>            9090/TCP                                                              2m


并且确认以下的 Pod 是否在 running 状态:

  1. $ kubectl get pods -n istio-system

  2. NAME                                       READY     STATUS      RESTARTS   AGE

  3. istio-citadel-7bdc7775c7-ntfkf             1/1       Running     0          3m

  4. istio-egressgateway-795fc9b47-2hw69        1/1       Running     0          3m

  5. istio-ingress-84659cf44c-dkgf4             1/1       Running     0          3m

  6. istio-ingressgateway-7d89dbf85f-9kgth      1/1       Running     0          3m

  7. istio-mixer-post-install-vg5gh             0/1       Completed   0          3m

  8. istio-pilot-66f4dd866c-nwr2j               2/2       Running     0          3m

  9. istio-policy-76c8896799-7l9nz              2/2       Running     0          3m

  10. istio-sidecar-injector-645c89bc64-6rs5k    1/1       Running     0          3m

  11. istio-statsd-prom-bridge-949999c4c-mpk6d   1/1       Running     0          3m

  12. istio-telemetry-6554768879-vqmjd           2/2       Running     0          3m

  13. prometheus-86cb6dd77c-vhf9s                1/1       Running     0          3m


当然,我们也可以自定义一些参数,具体的请看官方文档 –name istio –namespace istio-system)。


接下来我们部署一个应用,看看Istio是如何运作的。我们的样例应用叫做 BookInfo,这个应用由四个微服务所组成,具体架构图如下:


这个应用是用不同的语言所写的,让我们来见识一下 Istio 的魔力吧。

 

安装这个应用非常简单,我们只要执行以下命令即可:

  1. $ kubectl apply -f samples/bookinfo/kube/bookinfo.yaml

  2. $ istioctl create -f samples/bookinfo/routing/bookinfo-gateway.yaml


我们可以注意一下,在bookinfo.yaml中的 manifest 如下:

  1. # Copyright 2017 Istio Authors

  2. #

  3. #   Licensed under the Apache License, Version 2.0 (the "License");

  4. #   you may not use this file except in compliance with the License.

  5. #   You may obtain a copy of the License at

  6. #

  7. #       http://www.apache.org/licenses/LICENSE-2.0

  8. #

  9. #   Unless required by applicable law or agreed to in writing, software

  10. #   distributed under the License is distributed on an "AS IS" BASIS,

  11. #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  12. #   See the License for the specific language governing permissions and

  13. #   limitations under the License.

  14. ##################################################################################################

  15. # Details service

  16. ##################################################################################################

  17. apiVersion: v1

  18. kind: Service

  19. metadata:

  20.  name: details

  21.  labels:

  22.    app: details

  23. spec:

  24.  ports:

  25.  - port: 9080

  26.    name: http

  27.  selector:

  28.    app: details

  29. ---

  30. apiVersion: extensions/v1beta1

  31. kind: Deployment

  32. metadata:

  33.  name: details-v1

  34. spec:

  35.  replicas: 1

  36.  template:

  37.    metadata:

  38.      labels:

  39.        app: details

  40.        version: v1

  41.    spec:

  42.      containers:

  43.      - name: details

  44.        image: istio/examples-bookinfo-details-v1:1.5.0

  45.        imagePullPolicy: IfNotPresent

  46.        ports:

  47.        - containerPort: 9080

  48. ---

  49. ...


但是我们真正部署出来后,变成了这样:

  1. apiVersion: v1

  2. kind: Pod

  3. metadata:

  4.  annotations:

  5.    sidecar.istio.io/status: '{"version":"55c9e544b52e1d4e45d18a58d0b34ba4b72531e45fb6d1572c77191422556ffc","initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["istio-envoy","istio-certs"],"imagePullSecrets":null}'

  6.  creationTimestamp: 2018-07-05T09:10:55Z

  7.  generateName: details-v1-5f94c6d66b-

  8.  labels:

  9.    app: details

  10.    pod-template-hash: "1950728226"

  11.    version: v1

  12.  name: details-v1-5f94c6d66b-jj6lz

  13.  namespace: default

  14.  ownerReferences:

  15.  - apiVersion: apps/v1

  16.    blockOwnerDeletion: true

  17.    controller: true

  18.    kind: ReplicaSet

  19.    name: details-v1-5f94c6d66b

  20.    uid: 528aa360-8033-11e8-8cec-0e04fb7e7092

  21.  resourceVersion: "15620"

  22.  selfLink: /api/v1/namespaces/default/pods/details-v1-5f94c6d66b-jj6lz

  23.  uid: 528d5618-8033-11e8-8cec-0e04fb7e7092

  24. spec:

  25.  containers:

  26.  - image: istio/examples-bookinfo-details-v1:1.5.0

  27.    imagePullPolicy: IfNotPresent

  28.    name: details

  29.    ports:

  30.    - containerPort: 9080

  31.      protocol: TCP

  32.    resources: {}

  33.    terminationMessagePath: /dev/termination-log

  34.    terminationMessagePolicy: File

  35.    volumeMounts:

  36.    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount

  37.      name: default-token-f9mls

  38.      readOnly: true

  39.  - args:

  40.    - proxy

  41.    - sidecar

  42.    - --configPath

  43.    - /etc/istio/proxy

  44.    - --binaryPath

  45.    - /usr/local/bin/envoy

  46.    - --serviceCluster

  47.    - details

  48.    - --drainDuration

  49.    - 45s

  50.    - --parentShutdownDuration

  51.    - 1m0s

  52.    - --discoveryAddress

  53.    - istio-pilot.istio-system:15007

  54.    - --discoveryRefreshDelay

  55.    - 10s

  56.    - --zipkinAddress

  57.    - zipkin.istio-system:9411

  58.    - --connectTimeout

  59.    - 10s

  60.    - --statsdUdpAddress

  61.    - istio-statsd-prom-bridge.istio-system:9125

  62.    - --proxyAdminPort

  63.    - "15000"

  64.    - --controlPlaneAuthPolicy

  65.    - NONE

  66.    env:

  67.    - name: POD_NAME

  68.      valueFrom:

  69.        fieldRef:

  70.          apiVersion: v1

  71.          fieldPath: metadata.name

  72.    - name: POD_NAMESPACE

  73.      valueFrom:

  74.        fieldRef:

  75.          apiVersion: v1

  76.          fieldPath: metadata.namespace

  77.    - name: INSTANCE_IP

  78.      valueFrom:

  79.        fieldRef:

  80.          apiVersion: v1

  81.          fieldPath: status.podIP

  82.    - name: ISTIO_META_POD_NAME

  83.      valueFrom:

  84.        fieldRef:

  85.          apiVersion: v1

  86.          fieldPath: metadata.name

  87.    - name: ISTIO_META_INTERCEPTION_MODE

  88.      value: REDIRECT

  89.    image: docker.io/istio/proxyv2:0.8.0

  90.    imagePullPolicy: IfNotPresent

  91.    name: istio-proxy

  92.    resources:

  93.      requests:

  94.        cpu: 100m

  95.        memory: 128Mi

  96.    securityContext:

  97.      privileged: false

  98.      readOnlyRootFilesystem: true

  99.      runAsUser: 1337

  100.    terminationMessagePath: /dev/termination-log

  101.    terminationMessagePolicy: File

  102.    volumeMounts:

  103.    - mountPath: /etc/istio/proxy

  104.      name: istio-envoy

  105.    - mountPath: /etc/certs/

  106.      name: istio-certs

  107.      readOnly: true

  108.    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount

  109.      name: default-token-f9mls

  110.      readOnly: true

  111.  dnsPolicy: ClusterFirst

  112.  initContainers:

  113.  - args:

  114.    - -p

  115.    - "15001"

  116.    - -u

  117.    - "1337"

  118.    - -m

  119.    - REDIRECT

  120.    - -i

  121.    - '*'

  122.    - -x

  123.    - ""

  124.    - -b

  125.    - 9080,

  126.    - -d

  127.    - ""

  128.    image: docker.io/istio/proxy_init:0.8.0

  129.    imagePullPolicy: IfNotPresent

  130.    name: istio-init

  131.    resources: {}

  132.    securityContext:

  133.      capabilities:

  134.        add:

  135.        - NET_ADMIN

  136.      privileged: true

  137.    terminationMessagePath: /dev/termination-log

  138.    terminationMessagePolicy: File

  139.    volumeMounts:

  140.    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount

  141.      name: default-token-f9mls

  142.      readOnly: true

  143.  nodeName: ip-172-31-39-23

  144.  restartPolicy: Always

  145.  schedulerName: default-scheduler

  146.  securityContext: {}

  147.  serviceAccount: default

  148.  serviceAccountName: default

  149.  terminationGracePeriodSeconds: 30

  150.  tolerations:

  151.  - effect: NoExecute

  152.    key: node.kubernetes.io/not-ready

  153.    operator: Exists

  154.    tolerationSeconds: 300

  155.  - effect: NoExecute

  156.    key: node.kubernetes.io/unreachable

  157.    operator: Exists

  158.    tolerationSeconds: 300

  159.  volumes:

  160.  - emptyDir:

  161.      medium: Memory

  162.    name: istio-envoy

  163.  - name: istio-certs

  164.    secret:

  165.      defaultMode: 420

  166.      optional: true

  167.      secretName: istio.default

  168.  - name: default-token-f9mls

  169.    secret:

  170.      defaultMode: 420

  171.      secretName: default-token-f9mls


可以看到,本来只有一个 container 的,现在里面多了一个 container 和 initContainer。这个就是 Istio 的 Auto Injection,可以自动把 sidecar 注入到 Pod 里面,让我们不需要手动一个一个修改 yaml 文件,也防止手动修改过程中出错的可能。


使用实例


这里我们以路由设置为例子。

 

首先我们打开刚才部署好的这个应用的网页,可以看到页面右方的 Book Reviews 部分里面每次刷新都会随机性地出现黑星星、红星星和没有星星三种情况,这是因为我们有三个不同的 backend,路由在默认情况下会随机路由到任意一个 backend 上。


我们先尝试把所有的路由都路由到 v1 版本上(就是没有星星的版本),路由规则如下:

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: VirtualService

  3. metadata:

  4.  name: details

  5.  ...

  6. spec:

  7.  hosts:

  8.  - details

  9.  http:

  10.  - route:

  11.    - destination:

  12.        host: details

  13.        subset: v1

  14. ---

  15. apiVersion: networking.istio.io/v1alpha3

  16. kind: VirtualService

  17. metadata:

  18.  name: productpage

  19.  ...


命令如下:

  1. $ istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml

然后我们再去刷新,就会发现不管怎么刷新星星都不见了。


接着,假如我们有一个用户是 jason,我们希望他能测试 v2 的 backend,就可以用下面的路由规则:

  1. kind: VirtualService

  2. metadata:

  3.  name: reviews

  4.  ...

  5. spec:

  6.  hosts:

  7.  - reviews

  8.  http:

  9.  - match:

  10.    - headers:

  11.        cookie:

  12.          regex: ^(.*?;)?(user=jason)(;.*)?$

  13.    route:

  14.    - destination:

  15.        host: reviews

  16.        subset: v2

  17.  - route:

  18.    - destination:

  19.        host: reviews

  20.        subset: v1


命令如下:

  1. $ istioctl replace -f samples/bookinfo/routing/route-rule-reviews-test-v2.yaml


这时候,我们打开网页,以 jason 这个用户登录(密码随便填),就会发现每一次访问到的都是带有黑星星的版本。


这就是 Istio 提供的路由功能。


想要了解更多可以直接访问官网: https://istio.io/ 


本文转载自:K8S中文社区


 

Rancher Labs由硅谷云计算泰斗、CloudStack之父梁胜创建,致力于打造创新的开源软件,帮助企业在生产环境中运行容器与Kubernetes。旗舰产品Rancher是一个开源的企业级Kubernetes平台,是业界首个且唯一可以管理所有云上、所有发行版、所有Kubernetes集群的平台。解决了生产环境中企业用户可能面临的基础设施不同的困境,改善Kubernetes原生UI易用性不佳以及学习曲线陡峭的问题,是企业落地Kubernetes的不二之选。


Rancher在全球已有9000万次下载和超过20000个生产节点部署,且在全球范围内已经拥有包含迪斯尼、IBM、乐高、美国农业部、SONY、中国平安、海航集团在内数百家大中型政府及企业客户。




Rancher 北上深招聘进行时

↓↓↓

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存