本文主要介绍多主集群istio service mesh,每个主集群都有自己的复制控制平面,并使用网关跨集群连接服务。

在此配置中,每个集群都具有自己的Istio控制平面部署,而不是使用共享的Istio控制平面来管理网格,每个集群管理自己的端点。为了执行策略和确保安全,所有集群都处于共享的管理控制之下。

通过复制共享服务和名称空间并在所有集群中使用公共根CA,可以在集群中实现单个Istio服务网格。跨集群通信在各个集群的Istio网关上进行。

使用Istio Gateway跨多个Kubernetes集群的Istio网格访问远程Pod

先决条件

  • 两个或多个Kubernetes集群,其支持版本分别为:1.16、1.17、1.18。
  • 在每个Kubernetes集群上部署Istio控制平面的权限。
  • 每个集群中的istio-ingressgateway服务的IP地址必须可以从其他每个集群访问,最好使用L4网络负载平衡器(NLB)。
  • 根CA。跨集群通信需要服务之间的相互TLS连接。为了在集群之间实现相互TLS通信,将为每个集群的Istio CA配置为共享根CA生成的中间CA凭据。

在每个集群中部署Istio控制平面

  1. 从组织的根CA为每个集群的Istio CA生成中间CA证书。共享的根CA允许跨不同集群的相互TLS通信。
    为便于说明,以下说明将Istio示例目录中的证书用于两个集群。在实际部署中,您可能会为每个集群使用不同的CA证书,所有证书均由公共根CA签名。
  2. 在每个集群中运行以下命令,以在所有集群中部署相同的Istio控制平面配置。
  • 使用类似于以下命令,为生成的CA证书创建Kubernetes 秘钥。有关更多详细信息,请参见证书颁发机构(CA)证书。
$ 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:
$ istioctl install 
    -f manifests/examples/multicluster/values-istio-multicluster-gateways.yaml

部署 DNS

为远程集群中的服务提供DNS解析将使现有应用程序能够正常运行,因为应用程序通常希望通过DNS名称解析服务并访问生成的IP。 Istio本身不使用DNS在服务之间路由请求。集群本地的服务共享一个通用的DNS后缀(例如svc.cluster.local)。 Kubernetes DNS为这些服务提供DNS解析。

要为远程集群中的服务提供类似的设置,请使用<name>.<namespace>.global格式命名远程集群中的服务。 Istio部署包含了CoreDNS服务器,该服务器将为这些服务提供DNS解析。为了利用此DNS,必须将Kubernetes的DNS配置为对.global进行域名存根。

一些云提供商为其Kubernetes服务具有不同的特定DNS域存根功能和过程。请参考云提供商的文档,以确定如何为每个唯一环境存根DNS域。目的是在端口53上为.global添加一个域,以引用或代理Istio服务名称空间中的istiocoredns服务。

在每个集群中,创建以下ConfigMap之一,或更新现有的ConfigMap,比如coredns1.4以上的版本:

kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        health
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           upstream
           fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }
    global:53 {
        errors
        cache 30
        forward . $(kubectl get svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP}):53
    }
EOF

配置应用服务

给定集群中需要从其他远程集群访问的每个服务都需要在远程群集中进行ServiceEntry配置。服务条目中使用的主机的格式应为<name>.<namespace>.global,其中名称和名称空间分别对应于服务的名称和名称空间。

为了演示跨集群访问,请将在一个集群中运行的睡眠服务配置为调用在第二个集群中运行的httpbin服务。在开始之前,我们需要完成以下工作:

  • 选择两个Istio集群,分别称为cluster1cluster2
  • 您可以使用kubectl命令通过--context标志访问cluster1cluster2集群,例如kubectl get pods --context cluster1。使用以下命令列出您的上下文:
$ kubectl config get-contexts
CURRENT   NAME       CLUSTER    AUTHINFO       NAMESPACE
*         cluster1   cluster1   user@foo.com   default
          cluster2   cluster2   user@foo.com   default
  • 将集群的上下文名称存储在环境变量中:
$ export CTX_CLUSTER1=$(kubectl config view -o jsonpath='{.contexts[0].name}')
$ export CTX_CLUSTER2=$(kubectl config view -o jsonpath='{.contexts[1].name}')
$ echo "CTX_CLUSTER1 = ${CTX_CLUSTER1}, CTX_CLUSTER2 = ${CTX_CLUSTER2}"
CTX_CLUSTER1 = cluster1, CTX_CLUSTER2 = cluster2

总结

使用Istio网关,公共根CA和服务条目,您可以在多个Kubernetes集群之间配置单个Istio服务网格。一旦以这种方式配置,流量就可以透明地路由到远程集群,而无需任何应用程序的参与。尽管此方法需要一定数量的手动配置才能进行远程服务访问,但是服务条目创建过程可以自动化。


iyacontrol
1.4k 声望2.7k 粉丝

专注kubernetes,devops,aiops,service mesh。