使用 Istio 进行多集群部署管理及单控制平面Gateway连接拓扑的示例分析

78次阅读
没有评论

共计 6419 个字符,预计需要花费 17 分钟才能阅读完成。

行业资讯    
服务器    
云计算    
使用 Istio 进行多集群部署管理及单控制平面 Gateway 连接拓扑的示例分析

本篇文章给大家分享的是有关使用 Istio 进行多集群部署管理及单控制平面 Gateway 连接拓扑的示例分析,丸趣 TV 小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着丸趣 TV 小编一起来看看吧。

单控制平面拓扑下,多个  Kubernetes  集群共同使用在其中一个集群上运行的单个  Istio  控制平面。控制平面的  Pilot  管理本地和远程集群上的服务,并为所有集群配置  Envoy Sidecar  代理。

集群感知的服务路由

Istio 1.1  中引入了集群感知的服务路由能力,在单一控制平面拓扑配置下,使用  Istio  的  Split-horizon EDS(水平分割端点发现服务)功能可以通过其入口网关将服务请求路由到其他集群。基于请求源的位置,Istio  能够将请求路由到不同的端点。

在该配置中,从一个集群中的  Sidecar  代理到同一集群中的服务的请求仍然被转发到本地服务  IP。如果目标工作负载在其他集群中运行,则使用远程集群的网关  IP  来连接到该服务。

(集群感知的服务路由)

如图所示,主集群  cluster1  运行全套的  Istio  控制平面组件,同时集群  cluster2  仅运行  Istio Citadel、Sidecar Injector  和  Ingress  网关。不需要  VPN  连接,不同集群中的工作负载之间也不需要直接网络访问。

从共享的根  CA  为每个集群的  Citadel  生成中间  CA  证书,共享的根  CA  启用跨不同集群的双向  TLS  通信。为了便于说明,我们将  samples/certs  目录下  Istio  安装中提供的示例根  CA  证书用于两个集群。在实际部署中,你可能会为每个集群使用不同的  CA  证书,所有  CA  证书都由公共根  CA  签名。

在每个  Kubernetes  集群中(包括示例中的集群  cluster1  与  cluster2)使用以下命令为生成的  CA  证书创建  Kubernetes  密钥:

kubectl
create namespace istio-system
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

Istio  控制平面组件

在部署全套  Istio  控制平面组件的集群  cluster1  中,按照以下步骤执行:

1. 安装  Istio  的  CRD  并等待几秒钟,以便将它们提交给  Kubernetes API  服务器,如下所示:

for
i in install/kubernetes/helm/istio-init/files/crd*yaml; do kubectl apply -f $i;
done

2. 然后开始在集群  cluster1  中部署  Istio  控制平面。

如果  helm  依赖项缺失或者不是最新的,可以通过  helm dep update  来更新这些依赖项。需要注意的是,因为没有使用  istio-cni,可以暂时将其从依赖项  requirements.yaml  中去掉再执行更新操作。具体命令如下所示:

helm
template --name=istio --namespace=istio-system \
--set
global.mtls.enabled=true \
--set
security.selfSigned=false \
--set
global.controlPlaneSecurityEnabled=true \
--set
global.meshExpansion.enabled=true \
--set
global.meshNetworks.network2.endpoints[0].fromRegistry=n2-k8s-config \
--set
global.meshNetworks.network2.gateways[0].address=0.0.0.0 \
--set
global.meshNetworks.network2.gateways[0].port=15443 \
install/kubernetes/helm/istio
  ./istio-auth.yaml

请注意,网关地址设置为  0.0.0.0。这是一个临时占位符值,在集群  cluster2  部署之后将更新为其网关的公共  IP  值。

将  Istio  部署到  cluster1,如下所示:

kubectl
apply -f ./istio-auth.yaml

确保上述步骤在  Kubernetes  集群中执行成功。

3. 创建网关以访问远程服务,如下所示:

kubectl
create -f -  EOF
apiVersion:
networking.istio.io/v1alpha3
kind:
Gateway
metadata:
 name: cluster-aware-gateway
 namespace: istio-system
spec:
 selector:
 istio: ingressgateway
 servers:
 - port:
 number: 15443
 name: tls
 protocol: TLS
 tls:
 mode: AUTO_PASSTHROUGH
 hosts:
 -  * 
EOF

上述网关配置了一个专用端口  15443  用来将传入流量传递到请求的  SNI  标头中指定的目标服务,从源服务到目标服务一直使用双向  TLS  连接。

请注意虽然该网关定义应用于集群  cluster1,但因为两个集群都与同一个  Pilot  进行通信,此网关实例同样也适用于集群  cluster2。

istio-remote  组件

在另一集群  cluster2  中部署  istio-remote  组件,按照以下步骤执行:

1. 首先获取集群  cluster1  的入口网关地址,如下所示:

export
LOCAL_GW_ADDR=$(kubectl get svc --selector=app=istio-ingressgateway \
 -n istio-system -o
jsonpath= {.items[0].status.loadBalancer.ingress[0].ip} )

通过执行以下命令,使用  Helm  创建  Istio remote  部署  YAML  文件:

helm
template --name istio-remote --namespace=istio-system \
--values
install/kubernetes/helm/istio/values-istio-remote.yaml \
--set
global.mtls.enabled=true \
--set
gateways.enabled=true \
--set
security.selfSigned=false \
--set
global.controlPlaneSecurityEnabled=true \
--set
global.createRemoteSvcEndpoints=true \
--set
global.remotePilotCreateSvcEndpoint=true \
--set
global.remotePilotAddress=${LOCAL_GW_ADDR} \
--set
global.remotePolicyAddress=${LOCAL_GW_ADDR} \
--set
global.remoteTelemetryAddress=${LOCAL_GW_ADDR} \
--set
gateways.istio-ingressgateway.env.ISTIO_META_NETWORK= network2  \
--set
global.network= network2  \
install/kubernetes/helm/istio
  istio-remote-auth.yaml

2. 将  Istio remote  组件部署到  cluster2,如下所示:

kubectl
apply -f ./istio-remote-auth.yaml

确保上述步骤在  Kubernetes  集群中执行成功。

3. 更新集群  cluster1  的配置项  istio,获取集群  cluster2  的入口网关地址,如下所示:

export
REMOTE_GW_ADDR=$(kubectl get --context=$CTX_REMOTE svc --selector=app=
istio-ingressgateway
-n istio-system -o jsonpath= {.items[0].status.loadBalancer.ingress
[0].ip} )

在集群  cluster1  中编辑命名空间  istio-system  下的配置项  istio,替换  network2  的网关地址,从  0.0.0.0  变成集群  cluster2  的入口网关地址  ${REMOTE_GW_ADDR}。保存后,Pilot  将自动读取更新的网络配置。

4. 创建集群  cluster2  的  Kubeconfig。通过以下命令,在集群  cluster2  上创建服务账号  istio-multi  的  Kubeconfig,并保存为文件  n2-k8s-config:

CLUSTER_NAME= cluster2 
SERVER=$(kubectl
config view --minify=true -o  jsonpath={.clusters[].cluster.server} )
SECRET_NAME=$(kubectl
get sa istio-multi -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)
 EOF   n2-k8s-config
apiVersion:
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

5. 将集群  cluster2  加入到  Istio  控制平面。

在集群  clusterl  执行以下命令,将上述生成的集群  cluster2  的  kubeconfig  添加到集群  cluster1  的  secret  中,执行这些命令后,集群  cluster1  中的  Istio Pilot  将开始监听集群  cluster2  的服务和实例,就像监听集群  cluster1  中的服务与实例一样:

kubectl
create secret generic n2-k8s-secret --from-file n2-k8s-config -n istio-system
kubectl
label secret n2-k8s-secret istio/multiCluster=true -n istio-system

部署示例应用

为了演示跨集群访问,在第一个  Kubernetes  集群  cluster1  中部署  sleep  应用服务和版本  v1  的  helloworld  服务,在第二个集群  cluster2  中部署版本  v2  的  helloworld  服务,然后验证  sleep  应用是否可以调用本地或者远程集群的  helloworld  服务。

1. 部署  sleep  和版本  v1  的  helloworld  服务到第一个集群  cluster1  中,执行如下命令:

kubectl
create namespace app1
kubectl
label namespace app1 istio-injection=enabled
kubectl
apply -n app1 -f samples/sleep/sleep.yaml
kubectl
apply -n app1 -f samples/helloworld/service.yaml
kubectl
apply -n app1 -f samples/helloworld/helloworld.yaml -l version=v1
export
SLEEP_POD=$(kubectl get -n app1 pod -l app=sleep -o
jsonpath={.items..metadata.name})

2. 部署版本  v2  的  helloworld  服务到第二个集群  cluster2  中,执行如下命令:

kubectl
create namespace app1
kubectl
label namespace app1 istio-injection=enabled
kubectl
apply -n app1 -f samples/helloworld/service.yaml
kubectl
apply -n app1 -f samples/helloworld/helloworld.yaml -l version=v2

3. 登录到命名空间  istio-system  下的  istio-pilot  容器中,运行  curl localhost:8080/v1/registration | grep helloworld -A 11 -B 2  命令,如果得到如下类似的结果就说明版本  v1  与  v2  的  helloworld  服务都已经注册到  Istio  控制平面中了:

4. 验证在集群  cluster1  中的  sleep  服务是否可以正常调用本地或者远程集群的  helloworld  服务,在集群  cluster1  下执行如下命令:

kubectl
exec -it -n app1 $SLEEP_POD sh

登录到容器中,运行  curl helloworld.app1:5000/hello。

如果设置正确,则在返回的调用结果中可以看到两个版本的  helloworld  服务,同时可以通过查看  sleep  容器组中的  istio-proxy  容器日志来验证访问的端点  IP  地址,返回结果如下所示:

以上就是使用 Istio 进行多集群部署管理及单控制平面 Gateway 连接拓扑的示例分析,丸趣 TV 小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注丸趣 TV 行业资讯频道。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计6419字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)