共计 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 行业资讯频道。