关于kubernetes:如何使用Istio-16管理多集群中的微服务

44次阅读

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

如果你正在一家典型的企业里工作,须要与多个团队一起工作,并为客户提供一个独立的软件,组成一个应用程序。你的团队遵循微服务架构,并领有由多个 Kubernetes 集群组成的宽泛基础设施。

因为微服务散布在多个集群中,你须要设计一个解决方案来集中管理所有微服务。侥幸的是,你正在应用 Istio,提供这个解决方案只不过是另一个配置的变动。

像 Istio 这样的服务网格技术能够帮忙你平安地发现和连贯散布在多个集群和环境中的微服务。明天咱们来讨论一下应用 Istio 治理托管在多个 Kubernetes 集群中的微服务。

架构阐明

Istio 应用以下组件提供跨集群服务发现:

  • Istio CoreDNS:每个 Istio 管制立体都有一个 CoreDNS。Istio 应用它来发现全局范畴上定义的服务。例如,如果一个托管在集群 1 上的微服务须要连贯到另一个托管在集群 2 上的微服务,你须要为运行在集群 2 上的微服务在 Istio CoreDNS 上做一个全局条目。
  • Root CA:因为 Istio 须要在不同集群上运行的服务之间建设 mTLS 连贯,因而须要应用共享的 Root CA 为两个集群生成两头 CA 证书。这就在不同集群上运行的微服务之间建设了信赖,因为两头 CA 共享同一个 Root CA。
  • Istio Ingress 网关:集群间的通信通过 Ingress 网关进行,服务之间没有间接连贯。因而,你要确保 Ingress 网关是可发现的,并且所有集群都能够连贯到它。

服务发现

Istio 应用以下步骤来促成服务发现:

  1. 集群上都有雷同的管制立体,以促成高可用性。
  2. Kube DNS 与 Istio CoreDNS 为支点,以提供全局服务发现。
  3. 用户通过 Istio CoreDNS 中的 ServiceEntries 定义近程服务的路由,格局为 name.namespace.global。
  4. 源 sidecar 应用全局 CoreDNS 条目将流量路由到指标 Istio Ingress 网关。
  5. 指标 Istio Ingress 网关将流量路由到正确的微服务 pod。

后期筹备

本文假如你曾经对 Kubernetes 以及 Istio 的工作原理有一个根本的理解。如果你想理解 Istio 1.5 和 1.6 的具体内容,点击此处即可查看相干视频。为了可能跟上咱们接下来的演示,请确保:

  • 你有至多两个 Kubernetes 集群,Kubernetes 的版本为 1.14、1.15 或 1.16
  • 你领有在集群内装置和配置 Istio 的权限
  • 你在两个 Kubernetes 集群上都有集群管理权限。
  • Ingress 网关可通过网络负载均衡器或相似配置连贯到其余集群。扁平网络是不必要的。

装置 Istio

在两个集群上,应用以下命令装置 Istio 1.6.1:

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.1 sh -
cd istio-1.6.1
export PATH=$PWD/bin:$PATH

因为咱们须要用共享的根证书生成的两头证书来启动咱们的 Istio 服务网格,所以应用两头证书创立一个 secret。

在这个例子中,咱们应用提供的样本证书。然而,我不倡议你在生产中应用这些证书,因为它们个别都是可轻松获取的,而且是家喻户晓的。最好是应用你的组织的 Root CA 来生成两头 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
secret/cacerts created

因为咱们须要装置 Istio 进行多集群设置,所以在两个集群上应用提供的 Istio 多集群网关 manifest 文件。

$ istioctl manifest apply -f install/kubernetes/operator/examples/multicluster/values-istio-multicluster-gateways.yaml
- Applying manifest for component Base...
✔ Finished applying manifest for component Base.
- Applying manifest for component Pilot...
✔ Finished applying manifest for component Pilot.
  Waiting for resources to become ready...
- Applying manifest for component AddonComponents...
- Applying manifest for component IngressGateways...
- Applying manifest for component EgressGateways...
✔ Finished applying manifest for component EgressGateways.
✔ Finished applying manifest for component IngressGateways.
✔ Finished applying manifest for component AddonComponents.
✔ Installation complete

配置 KubeDNS

下一步是将 DNS 解析从 Kube DNS 联邦到 Istio CoreDNS。让咱们通过为 kube-dns 定义一个 ConfigMap 来配置一个存根域。在两个集群上利用以下 manifest:

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-dns
  namespace: kube-system
data:
  stubDomains: |
    {"global": ["$(kubectl get svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP})"]}
EOF

configmap/kube-dns configured

设置上下文(context)

因为咱们须要为不同得流动连贯两个集群,因而获取上下文并将其存储在环境变量中会很有意义。有了这些,咱们只有在 kubectl 命令中退出上下文,就能够在咱们抉择得集群中运行 kubectl 命令。

获取上下文:

$ kubectl config get-contexts
CURRENT   NAME        CLUSTER     AUTHINFO      NAMESPACE
          cluster-1   cluster-1   cluster-1
*         cluster-2   cluster-2   cluster-2

设置环境变量以应用上下文:

$ 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 = cluster-1, CTX_CLUSTER2 = cluster-2

部署示例微服务

咱们先在集群 1 的 foo 命名空间上部署 sleep 微服务。

$ kubectl create --context=$CTX_CLUSTER1 namespace foo
namespace/foo created
$ kubectl label --context=$CTX_CLUSTER1 namespace foo istio-injection=enabled
namespace/foo labeled
$ kubectl apply --context=$CTX_CLUSTER1 -n foo -f samples/sleep/sleep.yaml
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created
$ export SLEEP_POD=$(kubectl get --context=$CTX_CLUSTER1 -n foo pod -l app=sleep -o jsonpath={.items..metadata.name})

当初咱们在集群 2 的 bar 命名空间上部署 httpbin 微服务:

$ kubectl create --context=$CTX_CLUSTER2 namespace bar
namespace/bar created
$ kubectl label --context=$CTX_CLUSTER2 namespace bar istio-injection=enabled
namespace/bar labeled
$ kubectl apply --context=$CTX_CLUSTER2 -n bar -f samples/httpbin/httpbin.yaml
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created

创立服务条目

当初咱们须要在 Istio CoreDNS 上创立一个服务条目以便于咱们能够从集群 1 中发现集群 2 上的服务。因为所有的通信都会通过 Ingress 网关,导出集群 2 Ingress 网关地址。

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

为了让集群 1 上的服务可能发现集群 2 上的 httpbin,咱们须要在集群 1 上为httpbin.bar.global 创立一个 ServiceEntry。这样能够保障集群 1 上的 Istio Core DNS 在集群 1 上的服务达到httpbin.bar.global 这个端点时,能够达到集群 2 的 Ingress 网关。上面的 yaml:

  • 在 hosts 局部定义服务域名
  • 地位是mesh_INTERNAL,因为咱们须要把其余服务当作同一个服务网格的一部分
  • 将服务裸露在 8000 端口上
  • 咱们须要给该服务提供一个独特的 IP 地址。该 IP 地址不须要可路由,并且你能够应用 240.0.0.0/16 范畴内的任意地址
  • 咱们在端点地址局部上定义集群 2 ingress 网关地址,以便于申请能够路由给它。端口 15443 是 Ingress 网关的 SNI 辨认的 Envoy 代理端口,用于在指标群集服务的 Pod 之间路由流量。

利用 yaml 文件:

$ kubectl apply --context=$CTX_CLUSTER1 -n foo -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: httpbin-bar
spec:
  hosts:
  - httpbin.bar.global
  location: MESH_INTERNAL
  ports:
  - name: http1
    number: 8000
    protocol: http
  resolution: DNS
  addresses:
  - 240.0.0.2
  endpoints:
  - address: ${CLUSTER2_GW_ADDR}
    ports:
      http1: 15443 # Do not change this port value
EOF

serviceentry.networking.istio.io/httpbin-bar created

测试服务

当初让咱们从 sleep 微服务中产生一些流量,看看它是否能达到集群 2 上运行的 httpbin 微服务。

$ kubectl exec --context=$CTX_CLUSTER1 $SLEEP_POD -n foo -c sleep -- curl -I httpbin.bar.global:8000/headers
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0HTTP/1.1 200 OK
  0   519    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
server: envoy
date: Sat, 16 May 2020 23:03:22 GMT
content-type: application/json
content-length: 519
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 37

咱们失去一个胜利的响应!祝贺你,咱们曾经胜利地应用 Istio 在多个 Kubernetes 集群之间配置了服务发现。

结 论

感激你的浏览,心愿你能喜爱这篇文章。

这是一个在多个集群上运行的高可用 Istio 服务网格配置的演示。你也能够有一个共享的管制立体配置,但这并不举荐用于生产——如果你因为中断而失去一个集群,你也会失去对正在运行的集群的管制。

正文完
 0