1. 下载istio发行版(https://storage.googleapis.com/istio-release/releases/1.4.3/istio-1.4.3-linux.tar.gz)
2.解压
3.切换到istio-1.4.3目录
4.部署
[root@master /root]# kubectl create ns istio-system
[root@master /root]# kubectl create secret generic cacerts -n istio-system --from-file=samples/certs/ca-cert.pem --from-file=samples/certs/ca-key.pem --from-file=samples/certs/root-cert.pem --from-file=samples/certs/cert-chain.pem
[root@master /root]# istioctl manifest apply -f install/kubernetes/operator/examples/multicluster/values-istio-multicluster-primary.yaml
等待k8s中的Istio pods就绪:
[root@master /root]# kubectl get pods -nistio-system
NAME READY STATUS RESTARTS AGE
istio-citadel-856b4c8cbb-ch777 1/1 Running 0 4d3h
istio-galley-fd9694b9c-8nk58 2/2 Running 0 4d3h
istio-ingressgateway-66f89856c8-b4lhn 1/1 Running 0 4d3h
istio-pilot-5c68bb85df-rfssq 2/2 Running 0 4d3h
istio-policy-587798bdcc-dtrvh 2/2 Running 0 4d3h
istio-sidecar-injector-7dd87d7989-slnml 1/1 Running 0 4d3h
istio-telemetry-75c64d988b-mnnzn 2/2 Running 0 4d3h
prometheus-66c5887c86-jl46f 1/1 Running 0 4d3h
#注意网关地址设置为 0.0.0.0。这些是临时的占位值,在后面集群部署后,将被更新为两个集群的网关公网IP。
[root@master /root]# kubectl apply -f - <
本例 Gateway 配置 443 端口来将流经的入口流量导向请求 SNI 头中指明的目标服务,其中 SNI 的顶级域名为 local(譬如:Kubernetes DNS域名)。 从源至目标 sidecar,始终使用双向 TLS 连接。
尽管应用于主集群,该网关实例也会影响 private集群,因为两个集群通过同一个 Pilot 通信。
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
[root@master /root]# echo The ingress gateway of cluster1: address=$INGRESS_HOST, port=$SECURE_INGRESS_PORT
The ingress gateway of cluster1: address=10.10.8.39, port=31216
[root@master /root]# kubectl edit cm -n istio-system istio
第一个地方:
120行 meshNetworks: |-
121 # Network config
122 networks:
123 network1:
124 endpoints:
125 - fromRegistry: Kubernetes
126 gateways:
127 - address: 10.10.8.39
128 port: 31216
第二个地方:
154行 meshNetworks:
155 networks:
156 network1:
157 endpoints:
158 - fromRegistry: Kubernetes
159 gateways:
160 - address: 10.10.8.39
161 port: 31216
将网关地址和 network1 的端口分别更新为 cluster1 的 ingress 主机和端口,然后保存并退出。注意该地址在配置文件中出现两次,第二次位于 values.yaml: 下方。 一旦保存,Pilot 将自动读取更新后的网络配置。
[root@master /root]# kubectl get svc --selector=app=istio-ingressgateway -n istio-system -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}'
10.10.8.39
该命令将网关地址设置为网关的公共 IP 并显示。若负载均衡配置没有设置 IP 地址,命令将执行失败。DNS 域名支持尚未实现,亟待解决。如果没有LoadBalancer,可参考这个文章 http://www.lampnick.com/php/910将主集群下载的istio-1.4.3文件复制到这台机器并解压,进入istio-1.4.3目录执行如下命令
[root@master ~]# export MASTER_GW_ADDR=10.10.8.39#主集群获取到的
[root@master ~]# kubectl create ns istio-system
[root@master ~]# kubectl create secret generic cacerts -n istio-system --from-file=samples/certs/ca-cert.pem --from-file=samples/certs/ca-key.pem --from-file=samples/certs/root-cert.pem --from-file=samples/certs/cert-chain.pem
[root@master ~]# CLUSTER_NAME=$(kubectl config view --minify=true -o jsonpath='{.clusters[].name}')
[root@master ~]# istioctl manifest apply \
--set profile=remote \
--set values.global.mtls.enabled=true \
--set values.gateways.enabled=true \
--set values.security.selfSigned=false \
--set values.global.createRemoteSvcEndpoints=true \
--set values.global.remotePilotCreateSvcEndpoint=true \
--set values.global.remotePilotAddress=${MASTER_GW_ADDR} \
--set values.global.remotePolicyAddress=${MASTER_GW_ADDR} \
--set values.global.remoteTelemetryAddress=${MASTER_GW_ADDR} \
--set values.gateways.istio-ingressgateway.env.ISTIO_META_NETWORK="network2" \
--set values.global.network="network2" \
--set values.global.multiCluster.clusterName=${CLUSTER_NAME} \
--set autoInjection.enabled=true
等待 cluster2 中的 Istio pods 就绪,istio-ingressgateway 除外。
[root@master ~]# kubectl get pods -n istio-system -l istio!=ingressgateway
NAME READY STATUS RESTARTS AGE
istio-citadel-64d4866c95-tnjtf 1/1 Running 0 4d
istio-sidecar-injector-75ff97b4d8-5tf4j 1/1 Running 0 4d
istio-ingressgateway目前无法就绪,直到在主集群prod的Istio控制面板中配置好 watch private cluster。
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
[root@master ~]# echo The ingress gateway of cluster1: address=$INGRESS_HOST, port=$SECURE_INGRESS_PORT
The ingress gateway of cluster1: address=10.5.24.224, port=32483
特别注意:这一步是在主集群prod中执行
[root@master /root]# kubectl edit cm -n istio-system istio
第一个地方:
129行 network2:
130 endpoints:
131 - fromRegistry: n2-k8s-config
132 gateways:
133 - address: 10.5.24.224
134 port: 32483
第二个地方:
162行 network2:
163 endpoints:
164 - fromRegistry: n2-k8s-config
165 gateways:
166 - address: 10.5.24.224
167 port: 32483
将 network2 的网关地址和端口分别更新为 private集群 的 ingress 主机和端口,然后保存并退出。注意该地址在配置文件中出现两次,第二次位于 values.yaml: 下方。一旦保存,Pilot 将自动读取更新后的网络配置。
CLUSTER_NAME=$(kubectl config view --minify=true -o jsonpath='{.clusters[].name}')
SERVER=$(kubectl config view --minify=true -o jsonpath='{.clusters[].cluster.server}')
SECRET_NAME=$(kubectl get sa istio-reader-service-account -n istio-system -o jsonpath='{.secrets[].name}')
CA_DATA=$(kubectl get secret ${SECRET_NAME} -n istio-system -o jsonpath="{.data['ca\.crt']}")
TOKEN=$(kubectl get secret ${SECRET_NAME} -n istio-system -o jsonpath="{.data['token']}" | base64 --decode)
cat < n2-k8s-config
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority-data: ${CA_DATA}
server: ${SERVER}
name: ${CLUSTER_NAME}
contexts:
- context:
cluster: ${CLUSTER_NAME}
user: ${CLUSTER_NAME}
name: ${CLUSTER_NAME}
current-context: ${CLUSTER_NAME}
users:
- name: ${CLUSTER_NAME}
user:
token: ${TOKEN}
EOF
[root@master /root]# kubectl create secret generic n2-k8s-secret --from-file n2-k8s-config -n istio-system
[root@master /root]# kubectl label secret n2-k8s-secret istio/multiCluster=true -n istio-system
[root@master ~]# kubectl get pods -n istio-system -l istio=ingressgateway
NAME READY STATUS RESTARTS AGE
istio-ingressgateway-5fb99d5694-dpqc5 1/1 Running 0 4d
现在,主集群prod和私有集群private均已安装完成,可以部署gRPC服务。
-rw-r--r-- 1 root root 940 Feb 26 20:05 mycaller-deploy.yaml
-rw-r--r-- 1 root root 275 Feb 27 18:09 mycaller-destinationrule.yaml
-rw-r--r-- 1 root root 228 Feb 28 10:28 mycaller-service.yaml
-rw-r--r-- 1 root root 215 Feb 27 18:09 mycaller-virtualservice.yaml
-rw-r--r-- 1 root root 1.1K Feb 28 15:53 myresponser-deploy-v1.yaml
-rw-r--r-- 1 root root 284 Feb 28 12:12 myresponser-destinationrule-v1-v2.yaml
-rw-r--r-- 1 root root 237 Feb 28 16:09 myresponser-service.yaml
-rw-r--r-- 1 root root 262 Feb 28 12:44 myresponser-virtualservice-type-all-v2.yaml
-rw-r--r-- 1 root root 406 Mar 2 10:57 myresponser-virtualservice-type-v1-v2.yaml
-rw-r--r-- 1 root root 1.6K Feb 28 09:27 sleep.yaml
-rw-r--r-- 1 root root 1048 Feb 28 16:04 myresponser-deploy-v2.yaml
-rw-r--r-- 1 root root 237 Feb 28 16:10 myresponser-service.yaml
[root@master /root]# kubectl exec -it -c sleep $(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}') -- curl "mycaller.default:59130/testCaller/GetHello?type=1&orgcode=private&port=53605"
{"res":"[2020-03-03 09:09:59] responser version:private, hostname:myresponser-v2-67d7f6d7f4-6fctl, req:1, orgcode:private"}
[root@master /root]# kubectl exec -it -c sleep $(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}') -- curl "mycaller.default:59130/testCaller/GetHello?type=1&orgcode=private&port=53605"
{"res":"[2020-03-03 09:10:04] responser version:private, hostname:myresponser-v2-67d7f6d7f4-6fctl, req:1, orgcode:private"}
[root@master /root]# kubectl exec -it -c sleep $(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}') -- curl "mycaller.default:59130/testCaller/GetHello?type=1&orgcode=private&port=53605"
{"res":"[2020-03-03 09:10:07] responser version:private, hostname:myresponser-v2-67d7f6d7f4-6fctl, req:1, orgcode:private"}
[root@master /root]# kubectl exec -it -c sleep $(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}') -- curl "mycaller.default:59130/testCaller/GetHello?type=1&orgcode=&port=53605"
{"res":"[2020-03-03 09:10:16] responser version:prod, hostname:myresponser-v1-6b9f79c64d-fwl79, req:1, orgcode:prod"}
[root@master /root]# kubectl exec -it -c sleep $(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}') -- curl "mycaller.default:59130/testCaller/GetHello?type=1&orgcode=ttt&port=53605"
{"res":"[2020-03-03 09:10:23] responser version:prod, hostname:myresponser-v1-6b9f79c64d-fwl79, req:1, orgcode:ttt"}
[root@master /root]# kubectl exec -it -c sleep $(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}') -- curl "mycaller.default:59130/testCaller/GetHello?type=1&orgcode=prod&port=53605"
{"res":"[2020-03-03 09:10:30] responser version:prod, hostname:myresponser-v1-6b9f79c64d-fwl79, req:1, orgcode:prod"}