注:以下講述的按理環(huán)境場(chǎng)景是基于Kubernetes環(huán)境基礎(chǔ)上部署的Istio環(huán)境。
公司主營(yíng)業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。成都創(chuàng)新互聯(lián)公司推出海豐免費(fèi)做網(wǎng)站回饋大家。
涉及到Envoy概念介紹請(qǐng)參考深度解析Istio系列之流量控制篇。本文重點(diǎn)針對(duì)Envoy初始化場(chǎng)景進(jìn)行拆解。
Istio-proxy(Envoy)作為Istio數(shù)據(jù)平面的重要組件,基于sidecar方式與業(yè)務(wù)應(yīng)用混合部署到同一pod,為應(yīng)用提供代理服務(wù)。Pilot作為控制平面組件,基于元數(shù)據(jù)的抽象層,屏蔽底層具體容器環(huán)境(Kubernetes或者docker),同時(shí)為Envoy的策略執(zhí)行提供有效的數(shù)據(jù)支撐。那么Envoy如何獲取Pilot所在地址的信息呢?
下面通過(guò)官網(wǎng)BookInfo案例中Productpage服務(wù)的配置文件來(lái)說(shuō)明。
執(zhí)行kubectl get deploy productpage-v1 -o yaml,獲取productpage部署模板,如下所示:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "2"
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"annotations":{},"creationTimestamp":null,"name":"productpage-v1","namespace":"default"},"spec":{"replicas":1,"strategy":{},"template":{"metadata":{"annotations":{"sidecar.istio.io/status":"{\"version\":\"50128f63e7b050c58e1cdce95b577358054109ad2aff4bc4995158c06924a43b\",\"initContainers\":[\"istio-init\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-certs\"],\"imagePullSecrets\":null}"},"creationTimestamp":null,"labels":{"app":"productpage","version":"v1"}},"spec":{"containers":[{"image":"istio/examples-bookinfo-productpage-v1:1.8.0","imagePullPolicy":"IfNotPresent","name":"productpage","ports":[{"containerPort":9080}],"resources":{}},{"args":["proxy","sidecar","--configPath","/etc/istio/proxy","--binaryPath","/usr/local/bin/envoy","--serviceCluster","productpage","--drainDuration","45s","--parentShutdownDuration","1m0s","--discoveryAddress","istio-pilot.istio-system:15007","--discoveryRefreshDelay","1s","--zipkinAddress","zipkin.istio-system:9411","--connectTimeout","10s","--proxyAdminPort","15000","--controlPlaneAuthPolicy","NONE"],"env":[{"name":"POD_NAME","valueFrom":{"fieldRef":{"fieldPath":"metadata.name"}}},{"name":"POD_NAMESPACE","valueFrom":{"fieldRef":{"fieldPath":"metadata.namespace"}}},{"name":"INSTANCE_IP","valueFrom":{"fieldRef":{"fieldPath":"status.podIP"}}},{"name":"ISTIO_META_POD_NAME","valueFrom":{"fieldRef":{"fieldPath":"metadata.name"}}},{"name":"ISTIO_META_INTERCEPTION_MODE","value":"REDIRECT"},{"name":"ISTIO_METAJSON_LABELS","value":"{\"app\":\"productpage\",\"version\":\"v1\"}\n"}],"image":"docker.io/istio/proxyv2:1.0.5","imagePullPolicy":"IfNotPresent","name":"istio-proxy","ports":[{"containerPort":15090,"name":"http-envoy-prom","protocol":"TCP"}],"resources":{"requests":{"cpu":"10m"}},"securityContext":{"readOnlyRootFilesystem":true,"runAsUser":1337},"volumeMounts":[{"mountPath":"/etc/istio/proxy","name":"istio-envoy"},{"mountPath":"/etc/certs/","name":"istio-certs","readOnly":true}]}],"initContainers":[{"args":["-p","15001","-u","1337","-m","REDIRECT","-i","*","-x","","-b","9080","-d",""],"image":"docker.io/istio/proxy_init:1.0.5","imagePullPolicy":"IfNotPresent","name":"istio-init","resources":{},"securityContext":{"capabilities":{"add":["NET_ADMIN"]},"privileged":true}}],"volumes":[{"emptyDir":{"medium":"Memory"},"name":"istio-envoy"},{"name":"istio-certs","secret":{"optional":true,"secretName":"istio.default"}}]}}},"status":{}}
creationTimestamp: 2018-12-18T01:51:18Z
generation: 2
labels:
app: productpage
version: v1
name: productpage-v1
namespace: default
resourceVersion: "17402700"
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/productpage-v1
uid: 695ba22c-0267-11e9-8475-0050569c62d0
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: productpage
version: v1
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
annotations:
sidecar.istio.io/status: '{"version":"50128f63e7b050c58e1cdce95b577358054109ad2aff4bc4995158c06924a43b","initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["istio-envoy","istio-certs"],"imagePullSecrets":null}'
creationTimestamp: null
labels:
app: productpage
version: v1
spec:
containers:
- image: istio/examples-bookinfo-productpage-v1:1.8.0
imagePullPolicy: IfNotPresent
name: productpage
ports:
- containerPort: 9080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
- args:
- proxy
- sidecar
- --configPath
- /etc/istio/proxy
- --binaryPath
- /usr/local/bin/envoy
- --serviceCluster
- productpage
- --drainDuration
- 45s
- --parentShutdownDuration
- 1m0s
- --discoveryAddress
- istio-pilot.istio-system:15007
- --discoveryRefreshDelay
- 1s
- --zipkinAddress
- zipkin.istio-system:9411
- --connectTimeout
- 10s
- --proxyAdminPort
- "15000"
- --controlPlaneAuthPolicy
- NONE
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: ISTIO_META_POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
- name: ISTIO_METAJSON_LABELS
value: |
{"app":"productpage","version":"v1"}
image: docker.io/istio/proxyv2:1.0.5
imagePullPolicy: IfNotPresent
name: istio-proxy
ports:
- containerPort: 15090
name: http-envoy-prom
protocol: TCP
resources:
requests:
cpu: 10m
securityContext:
readOnlyRootFilesystem: true
runAsUser: 1337
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /etc/certs/
name: istio-certs
readOnly: true
DNSPolicy: ClusterFirst
initContainers:
- args:
- -p
- "15001"
- -u
- "1337"
- -m
- REDIRECT
- -i
- '*'
- -x
- ""
- -b
- "9080"
- -d
- ""
image: docker.io/istio/proxy_init:1.0.5
imagePullPolicy: IfNotPresent
name: istio-init
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- emptyDir:
medium: Memory
name: istio-envoy
- name: istio-certs
secret:
defaultMode: 420
optional: true
secretName: istio.default
status:
availableReplicas: 1
conditions:
- lastTransitionTime: 2018-12-18T01:51:19Z
lastUpdateTime: 2018-12-18T01:51:19Z
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: 2018-12-18T01:51:18Z
lastUpdateTime: 2018-12-18T03:48:52Z
message: ReplicaSet "productpage-v1-7b96bbf89f" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 2
readyReplicas: 1
replicas: 1
updatedReplicas: 1
模板中可見(jiàn),除業(yè)務(wù)應(yīng)用外,還包括istio-init,istio-proxy兩個(gè)容器。istio-init作為Init Container類型,在應(yīng)用容器啟動(dòng)之前啟動(dòng),用來(lái)執(zhí)行初始化任務(wù)。Istio-init主要初始化iptables規(guī)則,用于服務(wù)間調(diào)用時(shí)的請(qǐng)求攔截及轉(zhuǎn)發(fā)。Istio-proxy是代理容器(即Envoy),容器中包含兩個(gè)進(jìn)程,分別是Pilot-agent進(jìn)程和Envoy進(jìn)程。前者負(fù)責(zé)生成Envoy啟動(dòng)所需的配置文件,啟動(dòng)Envoy進(jìn)程。后者在服務(wù)調(diào)用發(fā)生時(shí)負(fù)責(zé)具體的策略執(zhí)行。
Envoy啟動(dòng)后,執(zhí)行kubectl exec -it productpage-v1-7b96bbf89f-pj28l -c istio-proxy /bin/sh,進(jìn)入istio-proxy容器內(nèi)部,在/etc/istio/proxy目錄下存在envoy-rev0.json配置文件,如圖2所示:
該文件是Pilot是Pilot-agent進(jìn)程根據(jù)服務(wù)啟動(dòng)參數(shù)以及Kubernetes Server API的信息生成,配置文件框架如圖3所示:
Node包含的信息如圖4所示:
這里重點(diǎn)說(shuō)明cluster屬性,該屬性值為productpage,說(shuō)明當(dāng)前的istio-proxy服務(wù)為productpage應(yīng)用的代理服務(wù),iptables將調(diào)用productpage服務(wù)請(qǐng)求攔截后,直接轉(zhuǎn)發(fā)到該istio-proxy進(jìn)行處理。
stats_config包含的信息如圖5所示:
static_config重點(diǎn)設(shè)定部分屬性的命名規(guī)則。
admin包含的信息如圖6所示:
admin類似Envoy內(nèi)部的一個(gè)管理器,暴露出的15000端口只能在容器內(nèi)部被訪問(wèn)。
通過(guò)curl http://127.0.0.1:15000/help訪問(wèn)能獲取其他接口信息,如下圖7所示:
dynamic_resources包含的信息如圖8所示:
dynamic_resources中記錄pilot調(diào)取XDS接口采用ADS聚合發(fā)現(xiàn)服務(wù),這種方式能更好的保證從pilot上獲取到的數(shù)據(jù)的一致性。
static_resources包含的部分信息如圖9所示:
static_resources name屬性值為xds-grpc,與上述dynamic_resources模塊的信息里cluster_name的值一致。同時(shí)xds-grpc對(duì)象信息中包括pilot組件的服務(wù)地址“istio-pilot.istio-system:15010”,即為istio-proxy從pilot獲取動(dòng)態(tài)信息的服務(wù)地址。Istio-proxy(Envoy)通過(guò)該地址調(diào)取XDS接口,獲取服務(wù)信息。除此之外,static_resources中提供zipkin服務(wù)的地址,zipkin是用于服務(wù)分布式跟蹤。
綜上可知Envoy啟動(dòng)時(shí),pilot-agent進(jìn)程生成Envoy啟動(dòng)所需的配置文件,Envoy基于配置文件中攜帶的pilot地址信息動(dòng)態(tài)獲取服務(wù)信息,并且基于pilot提供的XDS接口,動(dòng)態(tài)獲取服務(wù)的listener,cluster,endpoint和route信息。