mirror of https://github.com/istio/istio.io.git
zh: update docs/setup/kubernetes/multicluster/gateways/index.md (#3510)
This commit is contained in:
parent
fd79604ea9
commit
a14137cb65
|
|
@ -5,65 +5,83 @@ weight: 2
|
|||
keywords: [kubernetes,multicluster,federation,gateway]
|
||||
---
|
||||
|
||||
跨越多个集群安装 Istio 网格的说明,每个集群中的 pod 均只能访问远程 gateway IP。
|
||||
安装 Istio [多集群网格](/zh/docs/concepts/multicluster-deployments/)的介绍。这种情况下,Kubernetes 集群服务和每个集群中的应用都只能使用网关 IP 进行远程通信。
|
||||
|
||||
此配置中,每个集群都安装了一个**完全相同的** Istio 控制平面,用于管理自己的 endpoint,而不是使用一个中心 Istio 控制平面来管理网格。 出于策略应用和安全的考虑,每个集群都处于共享管理控制之下。
|
||||
此配置中,每个集群都安装了一个**完全相同的** Istio 控制平面,用于管理自己的网格,而不是使用一个中心 Istio。 出于策略应用和安全的考虑,每个集群都处于共享管理控制之下。
|
||||
|
||||
为了实现跨集群部署单一 Istio 服务网格,需要在所有集群中复制共享的 service 和 namespace,并使用公共的 root CA。
|
||||
为了实现跨集群部署单一 Istio 服务网格,需要在所有集群中复制共享的服务和命名空间,并使用公共的根证书。
|
||||
跨集群通信发生在相应集群的 Istio Gateway 上。
|
||||
|
||||
{{< image width="80%"
|
||||
link="/docs/setup/kubernetes/multicluster/gateways/multicluster-with-gateways.svg"
|
||||
caption="Istio 网格使用 Istio Gateway 跨越多个 Kubernetes 集群访问远程 pod"
|
||||
caption="Istio 网格使用 Istio Gateway 跨越多个 Kubernetes 集群访问远程 Pod"
|
||||
>}}
|
||||
|
||||
## 先决条件
|
||||
|
||||
* 两个或以上安装 **1.10 或更新**版本的 Kubernetes 集群。
|
||||
|
||||
* 在**每个** Kubernetes 集群上授权[使用 Helm 部署 Istio 控制平面](/zh/docs/setup/kubernetes/install/helm/)。
|
||||
* 在**每个** Kubernetes 集群上都有[使用 Helm 部署 Istio 控制平面](/zh/docs/setup/kubernetes/install/helm/)的权限。
|
||||
|
||||
* 一个 **Root CA**。跨集群通信需要在 service 之间使用 mutual TLS 连接。为了启用跨集群 mutual TLS 通信,每个集群的 Citadel
|
||||
都将被配置使用共享 root CA 生成的中间 CA 凭证。出于演示目的,我们将使用 `samples/certs` 目录下的简单 root CA
|
||||
证书,该证书作为 Istio 安装的一部分提供。
|
||||
* `istio-ingressgateway` 服务的 IP 地址必须能够从其它集群中进行访问。
|
||||
|
||||
* 一个 **Root CA**。跨集群通信需要在服务之间使用双向 TLS 连接。为了启用跨集群的双向 TLS 通信,每个集群的 Citadel 都将被配置使用共享根证书所生成的中间 CA 凭证。出于演示目的,我们将使用 `samples/certs` 目录下的简单 root CA 证书,该证书作为 Istio 安装的一部分提供。
|
||||
|
||||
## 在每个集群中部署 Istio 控制平面
|
||||
|
||||
1. 从您的组织 root CA 生成每个集群 Citadel 使用的中间证书。使用共享的 root CA 启用跨越不同集群的 mutual TLS 通信。
|
||||
出于演示目的,我们将使用相同的简单 root 证书作为中间证书。
|
||||
1. 从您的组织 root CA 生成每个集群 Citadel 使用的中间证书。使用共享的 root CA 启用跨越不同集群的双向 TLS 通信。
|
||||
|
||||
1. 在每个集群中,使用类似如下的命令,为您生成的 CA 证书创建一个 Kubernetes secret:
|
||||
{{< tip >}}
|
||||
处于演示目的,下面的介绍中会在不同的集群中使用来自 Istio sample 目录中的同样的证书。在真实部署中,建议为不同集群使用不同的 CA,所有 CA 都从同样的根 CA 签发。
|
||||
{{< /tip >}}
|
||||
|
||||
{{< text bash >}}
|
||||
$ 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
|
||||
{{< /text >}}
|
||||
1. 使用 `helm` 生成多网关的 Istio 配置:
|
||||
|
||||
1. 使用以下命令在每个集群中安装 Istio 控制平面:
|
||||
{{< warning >}}
|
||||
如果不清楚你的 `helm` 依赖是否过期,在开始之前可以使用 [Helm 安装步骤](/zh/docs/setup/kubernetes/install/helm/#安装步骤)中的命令进行更新。
|
||||
{{< /warning >}}
|
||||
|
||||
{{< text bash >}}
|
||||
$ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \
|
||||
<<<<<<< HEAD
|
||||
-f @install/kubernetes/helm/istio/values-istio-multicluster-gateways.yaml@ > $HOME/istio.yaml
|
||||
=======
|
||||
-f install/kubernetes/helm/istio/example-values/values-istio-multicluster-gateways.yaml > $HOME/istio.yaml
|
||||
$ kubectl create namespace istio-system
|
||||
$ kubectl apply -f $HOME/istio.yaml
|
||||
>>>>>>> master
|
||||
{{< /text >}}
|
||||
|
||||
更多细节和自定义选项请参考[使用 Helm 安装](/zh/docs/setup/kubernetes/install/helm/)的说明。
|
||||
要了解更多细节以及参数定制方法,请阅读:[用 Helm 进行安装](/zh/docs/setup/kubernetes/install/helm)。
|
||||
|
||||
1. 在**每个集群**中运行下面的命令,从而为所有集群生成一致的 Istio 控制面部署配置。
|
||||
|
||||
* 使用如下命令,用新生成的 CA 证书,创建一个 Kubernetes Secret,阅读 [CA 证书](/zh/docs/tasks/security/plugin-ca-cert/#插入现有密钥和证书)一节,其中有更多的相关细节。
|
||||
|
||||
{{< text bash >}}
|
||||
$ 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@
|
||||
{{< /text >}}
|
||||
|
||||
* 依照 [Helm 安装步骤](/zh/docs/setup/kubernetes/install/helm/#安装步骤)中的介绍完成 Istio 的安装。必须使用参数 `--values install/kubernetes/helm/istio/values-istio-multicluster-gateways.yaml`,来启用正确的多集群设置。例如:
|
||||
|
||||
{{< text bash >}}
|
||||
$ helm install istio --name istio --namespace istio-system --values install/kubernetes/helm/istio/values-istio-multicluster-gateways.yaml
|
||||
{{< /text >}}
|
||||
|
||||
## 配置 DNS
|
||||
|
||||
为远程集群中的 service 提供 DNS 解析,可以使现有的应用程序不经修改便能继续运行,因为应用程序通常通过解析 service
|
||||
的 DNS 名称并按结果 IP 地址访问。Istio 本身并不使用 DNS 路由 service 间的请求。属于同一个集群的 service
|
||||
共享相同的 DNS 后缀(例如 `svc.cluster.local`)。Kubernetes 为这些 service 提供 DNS 解析。
|
||||
应用通常会使用 DNS 名称来获取 IP,然后进行访问,如果在远程集群中为服务提供 DNS 解析,就能让现存应用保持原样。Istio 在完成服务之间的请求路由的过程中,并不会使用 DNS。集群本地的服务会使用一个通用的 DNS 后缀(例如 `svc.cluster.local`)。Kubernetes DNS 为这些服务提供了 DNS 解析能力。
|
||||
|
||||
为了给远程集群中的 service 提供相似的设置,我们将远程集群中的 service 以 `<name>.<namespace>.global`
|
||||
的格式命名。Istio 还附带了一个 CoreDNS 服务器,该服务器将为这些 service 提供 DNS 解析。为了利用这个 DNS,
|
||||
需要配置 Kubernetes 的 DNS 指向 CoreDNS,该 CoreDNS 将作为 `.global` DNS domain 的 DNS 服务器。请创建
|
||||
以下 ConfigMap(或更新现有的):
|
||||
为了给远程集群提供一个类似的配置,我们给远端集群的服务用 `<name>.<namespace>.global` 的形式进行命名。Istio 提供了一个 CoreDNS 服务器,用来给这些服务提供 DNS 解析。为了使用这个 DNS 服务,需要对 Kubernetes 的 DNS 进行配置,要求使用这一 CoreDNS 服务器来为 `.global` DNS 域提供解析。
|
||||
|
||||
在每个需要调用远端服务的集群中,创建下列 ConfigMap 中的一个,如果已经存在,就进行更新。
|
||||
|
||||
使用 `kube-dns` 的集群:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl apply -f - <<EOF
|
||||
|
|
@ -78,128 +96,55 @@ data:
|
|||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
## 添加其它集群的 service
|
||||
使用 CoreDNS 的集群:
|
||||
|
||||
从给定集群访问远程集群中的每个 service 都需要一个 `ServiceEntry` 配置。service entry 中使用的
|
||||
host 应该具有 `<name>.<namespace>.global` 的形式,其中 name 和 namespace 分别对应远程 service 的
|
||||
name 和 namespace。为了给 `*.global` domain 下的 service 提供 DNS 解析,您需要为这些 service 分配
|
||||
一个 IP 地址。我们假设从 127.255.0.0/16 子网分配。这些 IP 在 pod 外是不可路由的。这些 IP 的应用流量将被
|
||||
sidecar 捕获并路由到恰当的远程 service。
|
||||
|
||||
{{< text yaml >}}
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: ServiceEntry
|
||||
{{< text bash >}}
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: bar-ns2
|
||||
spec:
|
||||
hosts:
|
||||
# 必须为 name.namespace.global 的格式
|
||||
- bar.ns2.global
|
||||
# 将远程集群 service 视为服务网格的一部分
|
||||
# 因为服务网格中的所有集群共享相同的信任根(root of trust)。
|
||||
location: MESH_INTERNAL
|
||||
ports:
|
||||
- name: http1
|
||||
number: 8080
|
||||
protocol: http
|
||||
- name: tcp2
|
||||
number: 9999
|
||||
protocol: tcp
|
||||
resolution: DNS
|
||||
addresses:
|
||||
# 在给定的集群中,bar.ns2.global 解析为的 IP 地址对每个远程 service 都必须唯一。
|
||||
# 这些地址需要不能被路由到。到此 IP 的流量将被 sidecar 捕获并恰当的路由。
|
||||
- 127.255.0.2
|
||||
endpoints:
|
||||
# 这是 cluster2 中可路由的 ingerss gateway 地址,位于 bar.ns2 service 前端。
|
||||
# 从 sidecar 而来的流量将被路由到此地址。
|
||||
- address: <IPofCluster2IngressGateway>
|
||||
ports:
|
||||
http1: 15443 # Do not change this port value
|
||||
tcp2: 15443 # Do not change this port value
|
||||
name: coredns
|
||||
namespace: kube-system
|
||||
data:
|
||||
Corefile: |
|
||||
.:53 {
|
||||
errors
|
||||
health
|
||||
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
upstream
|
||||
fallthrough in-addr.arpa ip6.arpa
|
||||
}
|
||||
prometheus :9153
|
||||
proxy . /etc/resolv.conf
|
||||
cache 30
|
||||
loop
|
||||
reload
|
||||
loadbalance
|
||||
}
|
||||
global:53 {
|
||||
errors
|
||||
cache 30
|
||||
proxy . $(kubectl get svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP})
|
||||
}
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
如果您希望通过专用的 egress gateway 路由所有从 `cluster1` 过来的 egress 流量,请为 `bar.ns2`
|
||||
使用如下 service entry:
|
||||
## 配置应用服务
|
||||
|
||||
{{< text yaml >}}
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: ServiceEntry
|
||||
metadata:
|
||||
name: bar-ns2
|
||||
spec:
|
||||
hosts:
|
||||
# must be of form name.namespace.global
|
||||
- bar.ns2.global
|
||||
location: MESH_INTERNAL
|
||||
ports:
|
||||
- name: http1
|
||||
number: 8080
|
||||
protocol: http
|
||||
- name: tcp2
|
||||
number: 9999
|
||||
protocol: tcp
|
||||
resolution: DNS
|
||||
addresses:
|
||||
- 127.255.0.2
|
||||
endpoints:
|
||||
- address: <IPofCluster2IngressGateway>
|
||||
network: external
|
||||
ports:
|
||||
http1: 15443 # Do not change this port value
|
||||
tcp2: 15443 # Do not change this port value
|
||||
- address: istio-egressgateway.istio-system.svc.cluster.local
|
||||
ports:
|
||||
http1: 15443
|
||||
tcp2: 15443
|
||||
如果一个集群中的服务需要访问远端集群中的服务,就需要创建一个 `ServiceEntry`。`ServiceEntry` 中的主机名应该是 `<name>.<namespace>.global` 的格式,其中的 `name` 和 `namespace` 需要根据服务名称和命名空间进行替换。
|
||||
|
||||
为了检查多集群配置是否生效,可以参考示例[通过网关进行多集群连接](/zh/docs/examples/multicluster/gateways/)来进行测试。
|
||||
|
||||
## 清理
|
||||
|
||||
在**每个集群**上运行下面的命令,删除 Istio:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl delete -f $HOME/istio.yaml
|
||||
$ kubectl delete ns istio-system
|
||||
{{< /text >}}
|
||||
|
||||
为了验证设置,请尝试从 `cluster1` 上的任意 pod 访问 `bar.ns2.global` 或 `bar.ns2`。
|
||||
两个 DNS 名称都应该被解析到 127.255.0.2 这个在 service entry 配置中使用的地址。
|
||||
|
||||
以上配置将使得 `cluster1` 中所有到 `bar.ns2.global` 和*任意端口*的流量通过 mutual TLS 连接路由到
|
||||
endpoint `<IPofCluster2IngressGateway>:15443`。
|
||||
|
||||
端口 15443 的 gateway 是一个特殊的 SNI 感知 Envoy,它已经预先进行了配置,并作为前提条件中描述的 Istio
|
||||
安装步骤的一部分进行了安装。进入 15443 端口的流量将在目标集群中恰当的内部 service pod 中进行负载均衡。
|
||||
|
||||
{{< text yaml >}}
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: ServiceEntry
|
||||
metadata:
|
||||
name: bar-ns2
|
||||
spec:
|
||||
hosts:
|
||||
# 必须为 name.namespace.global 的形式
|
||||
- bar.ns2.global
|
||||
location: MESH_INTERNAL
|
||||
ports:
|
||||
- name: http1
|
||||
number: 8080
|
||||
protocol: http
|
||||
- name: tcp2
|
||||
number: 9999
|
||||
protocol: tcp
|
||||
resolution: DNS
|
||||
addresses:
|
||||
# bar.ns2.global 解析为的 IP 地址对每个 service 必须唯一。
|
||||
- 127.255.0.2
|
||||
endpoints:
|
||||
- address: <IPofCluster2IngressGateway>
|
||||
labels:
|
||||
version: beta
|
||||
some: thing
|
||||
foo: bar
|
||||
ports:
|
||||
http1: 15443 # 不要修改此端口值
|
||||
tcp2: 15443 # 不要修改此端口值
|
||||
{{< /text >}}
|
||||
|
||||
使用 destination rule 为具有适当 label selector 的 `bar.ns2` service 创建子集。
|
||||
要遵循的步骤与用于本地 service 的步骤完全相同。
|
||||
|
||||
## 总结
|
||||
|
||||
通过使用 Istio gateway、一个通用 root CA 以及 service entry,您可以跨越多个 Kubernetes
|
||||
集群配置单一的 Istio 服务网格。虽然上诉过程包含了一定的手动操作,整个过程可以通过为系统中每个 service
|
||||
创建 service entry(从 127.255.0.0/16 子网分配一个唯一 IP 地址) 实现自动化。一旦这样配置,流量就可以被透明的路由到远程集群,无需任何(其它)应用介入。
|
||||
使用 Istio 网关,结合一个通用根证书以及 `ServiceEntry`,就能够让单一的 Istio 服务网格跨越多个 Kubernetes 集群。使用这种配置,无需对应用进行任何改动,流量就能够透明的路由到远端集群。虽然这种方式需要一部分的手工操作来配置远程的服务访问,但是 `ServiceEntry` 的创建过程也是可以自动化的。
|
||||
|
|
|
|||
Loading…
Reference in New Issue