博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从docker到istio之四 - istio分流应用
阅读量:6894 次
发布时间:2019-06-27

本文共 14068 字,大约阅读时间需要 46 分钟。

前言

容器化,云原生越演越烈,新概念非常之多。信息爆炸的同时,带来层层迷雾。我尝试从扩容出发理解其脉路,经过实践探索,整理形成一个入门教程,包括下面四篇文章。

这是第四篇,istio分流应用。

istio

服务网格(Service Mesh)这个术语通常用于描述构成这些应用程序的微服务网络以及应用之间的交互。随着规模和复杂性的增长,服务网格越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、指标收集和监控以及通常更加复杂的运维需求,例如 A/B 测试、金丝雀发布、限流、访问控制和端到端认证等。

Istio 提供了一个完整的解决方案,通过为整个服务网格提供行为洞察和操作控制来满足微服务应用程序的多样化需求。

安装istio

istio1.1支持kubernetes1.11,1.12,1.13,Docker for mac的stable版本太低,需要切换Docker for mac 到 edge版本,kubernetes会升级到1.13。使用 kubectl version 确认kubernetes版本:

Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.0", GitCommit:"ddf47ac13c1a9483ea035a79cd7c10005ff21a6d", GitTreeState:"clean", BuildDate:"2018-12-03T21:04:45Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"darwin/amd64"}Server Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.0", GitCommit:"ddf47ac13c1a9483ea035a79cd7c10005ff21a6d", GitTreeState:"clean", BuildDate:"2018-12-03T20:56:12Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"linux/amd64"}复制代码

按照安装istio到k8s。 kubectl get svc -n istio-system 查看isto服务(svc是service的速记别名)

NAME                     TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                                                                                      AGEgrafana                  ClusterIP      10.96.238.84     
3000/TCP 19sistio-citadel ClusterIP 10.110.233.235
8060/TCP,15014/TCP 19sistio-egressgateway ClusterIP 10.107.81.184
80/TCP,443/TCP,15443/TCP 20sistio-galley ClusterIP 10.108.48.185
443/TCP,15014/TCP,9901/TCP 20sistio-ingressgateway LoadBalancer 10.99.64.197 localhost 15020:31681/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:32145/TCP,15030:31376/TCP,15031:30092/TCP,15032:31491/TCP,15443:32689/TCP 19sistio-pilot ClusterIP 10.101.105.130
15010/TCP,15011/TCP,8080/TCP,15014/TCP 19sistio-policy ClusterIP 10.107.208.244
9091/TCP,15004/TCP,15014/TCP 19sistio-sidecar-injector ClusterIP 10.104.152.19
443/TCP 19sistio-telemetry ClusterIP 10.102.233.77
9091/TCP,15004/TCP,15014/TCP,42422/TCP 19sjaeger-agent ClusterIP None
5775/UDP,6831/UDP,6832/UDP 18sjaeger-collector ClusterIP 10.100.208.250
14267/TCP,14268/TCP 18sjaeger-query ClusterIP 10.104.246.180
16686/TCP 18skiali ClusterIP 10.100.34.9
20001/TCP 19sprometheus ClusterIP 10.103.238.247
9090/TCP 19stracing ClusterIP 10.103.49.38
80/TCP 18szipkin ClusterIP 10.105.126.70
9411/TCP复制代码

查看isto的pod是否全部正常启动:

➜  kubectl get pods -n istio-systemNAME                                      READY   STATUS      RESTARTS   AGEgrafana-749c78bcc5-jczt2                  1/1     Running     1          20mistio-citadel-899dfb67c-r6cmx             1/1     Running     0          20mistio-cleanup-secrets-1.1.3-d42jx         0/1     Completed   0          20mistio-egressgateway-748d5fd794-zkcjs      1/1     Running     1          20mistio-galley-555dd7c7d7-t9fhz             1/1     Running     0          20mistio-grafana-post-install-1.1.3-2qzg5    0/1     Completed   0          20mistio-ingressgateway-55dd86767f-n5v7m     1/1     Running     1          20mistio-pilot-7979d58649-lg6vq              2/2     Running     0          20mistio-policy-f89c945dc-8d6mn              2/2     Running     0          55sistio-security-post-install-1.1.3-4ggpf   0/1     Completed   0          20mistio-sidecar-injector-998dd6cbb-fbdgw    1/1     Running     0          20mistio-telemetry-7d9d866c65-2pngr          2/2     Running     0          16sistio-tracing-595796cf54-mp6tp            1/1     Running     1          20mkiali-5df77dc9b6-jq26m                    1/1     Running     0          20mprometheus-7f87866f5f-p2568               1/1     Running     0          20m复制代码

部署应用

调整pods符合istio规范

部署引用前,需要按照,进行微调。

微调后的istio\flaskapp.yaml如下:

apiVersion: v1kind: Servicemetadata:  name: flaskappspec:  ports:    - port: 5000      name: http  selector:    app: business---apiVersion: extensions/v1beta1 kind: Deploymentmetadata:  name: flaskappspec:  replicas: 1  template:    metadata:      labels:        app: business        version: v1    spec:      containers:      - image: flaskapp:0.0.2        name: flaskapp        ports:        - containerPort: 5000复制代码

微调后的istio\redis.yaml如下:

apiVersion: v1kind: Servicemetadata:  name: redisspec:  ports:    - port: 6379      name: redis  selector:    app: redis---apiVersion: extensions/v1beta1 kind: Deploymentmetadata:  name: redisspec:  replicas: 1  template:    metadata:      labels:        app: redis        version: v1    spec:      containers:      - image: redis:4-alpine3.8        name: redisdb        ports:        - containerPort: 6379复制代码

因为istio附带ingress,所以我们取消了前置的nginx负载,直接使用ingress。

启动istio的sidecar自动注入

istio通过在pod中输入sidecar,用来管理流量,设置default名称空间下默认注入:

➜  docker2istio kubectl label namespace default istio-injection=enablednamespace/default labeled复制代码

启动服务

启动服务方式和k8s没有区别

➜  docker2istio kubectl apply -f k8s/redis.yaml -f k8s/flaskapp.yamlservice/redis createddeployment.extensions/redis createdservice/flaskapp createddeployment.extensions/flaskapp created复制代码

使用kubectl describe pod/flaskapp-757cd47df4-zkzv2 确认istio正常管理app:

Name:               flaskapp-757cd47df4-zkzv2Namespace:          defaultPriority:           0PriorityClassName:  
Node: docker-desktop/192.168.65.3Start Time: Wed, 24 Apr 2019 18:43:16 +0800Labels: app=business pod-template-hash=757cd47df4 version=v1Annotations: sidecar.istio.io/status: {
"version":"3420543c87a5049f8ec099530c3992a5c1f06bf54fa56d7a3877e7ffc658ea8d","initContainers":["istio-init"],"containers":["istio-proxy"]...Status: RunningIP: 10.1.0.45Controlled By: ReplicaSet/flaskapp-757cd47df4Init Containers: istio-init: Container ID: docker://0bac5e70832c287a1c446d38034c75ebe5b8e66b9e2fb6d5a1fc3bcb8a9f644c Image: docker.io/istio/proxy_init:1.1.3 Image ID: docker-pullable://istio/proxy_init@sha256:000d022d27c198faa6cc9b03d806482d08071e146423d6e9f81aa135499c4ed3 Port:
Host Port:
Args: ... Containers: flaskapp: Container ID: docker://9cdf76e12c710f1d50c2b3a2ac349909f481975f220af5b31e1b76717bcabd95 Image: flaskapp:0.0.2 Image ID: docker://sha256:d52877069956696bb9009c0af43a0d339d2d253e67f5fb09c9f1f052a35528de Port: 5000/TCP Host Port: 0/TCP State: Running Started: Wed, 24 Apr 2019 18:43:19 +0800 Ready: True Restart Count: 0 Environment:
Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-ndv6q (ro) istio-proxy: Container ID: docker://84eecd89d7c203b7b97749d2a02c63cb8b4c57cfda96f0c7585547a8918344c1 Image: docker.io/istio/proxyv2:1.1.3 Image ID: docker-pullable://istio/proxyv2@sha256:b682918f2f8fcca14b3a61bbd58f4118311eebc20799f24b72ceddc5cd749306 Port: 15090/TCP Host Port: 0/TCP Args: ... State: Running Started: Wed, 24 Apr 2019 18:43:19 +0800 Ready: True Restart Count: 0 Limits: cpu: 2 memory: 128Mi Requests: cpu: 10m memory: 40Mi Readiness: http-get http://:15020/healthz/ready delay=1s timeout=1s period=2s #success=1 #failure=30 Environment: POD_NAME: flaskapp-757cd47df4-zkzv2 (v1:metadata.name) POD_NAMESPACE: default (v1:metadata.namespace) INSTANCE_IP: (v1:status.podIP) ISTIO_META_POD_NAME: flaskapp-757cd47df4-zkzv2 (v1:metadata.name) ISTIO_META_CONFIG_NAMESPACE: default (v1:metadata.namespace) ISTIO_META_INTERCEPTION_MODE: REDIRECT ISTIO_METAJSON_LABELS: {
"app":"business","pod-template-hash":"757cd47df4","version":"v1"} Mounts: /etc/certs/ from istio-certs (ro) /etc/istio/proxy from istio-envoy (rw) /var/run/secrets/kubernetes.io/serviceaccount from default-token-ndv6q (ro)...复制代码

!!!注意 这里的pod,会被自动注入名为istio-init的initContainer和名为**istio-proxy的container。具有这2个container,标志pod接受istio流量管理。

确认服务正常启动

➜  docker2istio kubectl get svcNAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGEflaskapp     ClusterIP   10.107.67.44     
5000/TCP 4m31skubernetes ClusterIP 10.96.0.1
443/TCP 36mredis ClusterIP 10.100.210.72
6379/TCP 4m31s复制代码

确认pod正常启动

➜  docker2istio kubectl get podsNAME                        READY   STATUS    RESTARTS   AGEflaskapp-77ddb9698c-xb2gm   1/1     Running   0          4m2sredis-c5dd6fcfc-8tqwm       1/1     Running   0          4m2s复制代码

部署istio的gateway

因为取消了前置的nginx负载,需要设置gateway,集群外部才能够访问服务。istio\gateway.yaml:

apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:  name: flaskapp-gatewayspec:  selector:    istio: ingressgateway # use istio default controller  servers:  - port:      number: 80      name: http      protocol: HTTP    hosts:    - "*"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: flaskappspec:  hosts:  - "*"  gateways:  - flaskapp-gateway  http:  - match:    - uri:        exact: /    route:    - destination:        host: flaskapp        port:          number: 5000复制代码

kubectl apply -f istio/gateway.yaml提交后,查看gameway的端口:

➜  docker2istio kubectl get svc istio-ingressgateway -n istio-systemNAME                   TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                                                                                                      AGEistio-ingressgateway   LoadBalancer   10.99.64.197   localhost     15020:31681/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:32145/TCP,15030:31376/TCP,15031:30092/TCP,15032:31491/TCP,15443:32689/TCP   179m复制代码

这里的服务类型为LoadBalancer,可以直接使用80端口访问服务:

➜  docker2istio curl http://localhostHello World by 10.1.0.40 from 10.1.0.30 ! 该页面已被访问 1 次。复制代码

金丝雀发布

istio的流量管理提供了非常便捷的金丝雀发布功能。

首先,我们调整app/flaskapp.py,将域名获取调整成为主机名称:

#-*- coding:utf-8 -*-import socketfrom flask import Flaskfrom redis import Redisapp = Flask(__name__)redis = Redis(host='redis', port=6379)def get_host_ip():    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    try:        s.connect(('8.8.8.8', 80))        ip = s.getsockname()[0]    except:        ip = '127.0.0.1'    finally:        s.close()    return ipdef get_hostname():    return socket.gethostname()@app.route('/')def hello():    app.logger.debug('hello in')    from flask import request    count = redis.incr('hits')    # host_ip = get_host_ip()    host_id = get_hostname()    client_ip= request.headers['X-Real-Ip'] if 'X-Real-Ip' in request.headers else request.remote_addr     app.logger.debug("Hello out {} {} {}:".format(host_id,client_ip,count))    return 'Hello World by {} from {} ! 该页面已被访问 {} 次。\n'.format(host_id,client_ip,count)if __name__ == "__main__":    app.run(host="0.0.0.0", debug=True)复制代码

使用 docker build -f app/Dockerfile -t flaskapp:0.0.3 app 编译新的镜像。

制作新的deployment,使其使用新的镜像:

apiVersion: extensions/v1beta1 kind: Deploymentmetadata:  name: flaskapp-v2spec:  replicas: 1  template:    metadata:      labels:        app: business        version: v2    spec:      containers:      - image: flaskapp:0.0.3        name: flaskapp        ports:        - containerPort: 5000复制代码

创建并确认新的部署生效:

➜  docker2istio kubectl apply -f istio/flaskappv2.yamldeployment.extensions/flaskapp-v2 created➜  docker2istio kubectl get deploymentNAME          READY   UP-TO-DATE   AVAILABLE   AGEflaskapp      3/3     3            3           72mflaskapp-v2   1/1     1            1           7sredis         1/1     1            1           129m复制代码

调整VirtualService,控制流量分发策略:

apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: flaskappspec:  hosts:  - "*"  gateways:  - flaskapp-gateway  http:  - match:    - uri:        exact: /    route:    - destination:        host: flaskapp        port:          number: 5000  - route:    - destination:        host: flaskapp        subset: v1      weight: 80    - destination:        host: flaskapp        subset: v2      weight: 20复制代码

这里重点是指定规则,按照8:2,将flaskapp的访问分配到deployment v1 和 deployment v2 上。

kubectl apply -f istio/gateway2.yaml 应用新的流量分配策略:

访问观察服务:

➜  docker2istio curl http://localhostHello World by 10.1.0.45 from 127.0.0.1 ! 该页面已被访问 7 次。➜  docker2istio curl http://localhostHello World by 10.1.0.45 from 127.0.0.1 ! 该页面已被访问 8 次。➜  docker2istio curl http://localhostHello World by flaskapp-v2-ff9f8cfdb-vh788 from 127.0.0.1 ! 该页面已被访问 9 次。➜  docker2istio curl http://localhostHello World by 10.1.0.45 from 127.0.0.1 ! 该页面已被访问 10 次。➜  docker2istio curl http://localhostHello World by 10.1.0.45 from 127.0.0.1 ! 该页面已被访问 11 次。➜  docker2istio curl http://localhostHello World by 10.1.0.45 from 127.0.0.1 ! 该页面已被访问 12 次。➜  docker2istio curl http://localhostHello World by 10.1.0.45 from 127.0.0.1 ! 该页面已被访问 13 次。➜  docker2istio curl http://localhostHello World by flaskapp-v2-ff9f8cfdb-vh788 from 127.0.0.1 ! 该页面已被访问 14 次。复制代码

可以看到,访问被按比例分配到v1和v2两个版本上。

总结

从上面实践过程空可见,istio完善了k8s提供的编排功能,在纵向扩容的基础上可以实现横向扩展。

转载于:https://juejin.im/post/5d02645e5188252dd2399938

你可能感兴趣的文章
sql数据库各个版本清除日志
查看>>
jQuery扩展两类函数(对象调用,静态调用)
查看>>
nofollow标签使用方法
查看>>
sqlite实现新闻收藏和取消收藏
查看>>
Unity中的基础光照
查看>>
Final发布——视频博客
查看>>
SqlHelper类
查看>>
服务器端控件Button会自动刷新页面
查看>>
Sass函数:Sass Maps的函数-map-get($map,$key)
查看>>
HDU 1230 火星A+B
查看>>
C# foreach 为什么循环使用Foreach 效率要高
查看>>
oracle创建透明网关出现的问题
查看>>
对象和类
查看>>
分布式事务
查看>>
udp,select超时和recvfrom收不到数据原因
查看>>
将任意程序(如.bat文件)作为Windows服务运行
查看>>
【ElasticSearch篇】--ElasticSearch从初识到安装和应用
查看>>
Java命令参数说明大全
查看>>
PIE SDK创建掩膜
查看>>
(四)springmvc+mybatis+dubbo+zookeeper分布式架构 整合 - maven代码结构
查看>>