Sovereign Systems 是一家成立于 2007 年的技术咨询公司,帮助客户将传统数据中心技术和应用程序转换为更高效的、基于云的技术平台,以更好地应对业务挑战。曾连续 3 年提名 CRN,并且在 2012 年到 2016 年均被评为美国增长最快的私营公司之一。
本文由 Sovereign Systems 的解决方案架构师 Chip Zoller 根据客户的使用案例撰写而成
Rancher 是一个容器编排管理平台,它已经在这一领域深耕几年并且具备很多简单易用的实用功能。近几年,它经过重构已经完全拥抱 Kubernetes。在本文中,我将着重介绍如何在 VMware Enterprise PKS 之上构建一个企业级、高可用和安全的 Rancher Server 安装。同时,我将回答“为什么要在 PKS 上使用 Rancher”这一问题。此外,本文将包括整个构建流程、架构以及完整的安装指南。涉及的内容十分丰富,赶紧开始吧!
把 Rancher 部署在 PKS 上?
我知道这并不是一个普遍的搭配,特别是这两个解决方案还存在某种竞争关系。它们都能够在不同的云提供商部署 Kubernetes 集群,并可以在本地部署到诸如 vSphere 之类的堆栈。它们分别都有自己的长处和短处,但是在管理空间中两者没有重叠的地方。Enterprise PKS 使用 BOSH 部署 Kubernetes 集群,并且继续将其用于生命周期的事件——扩展、修复、升级等。而 Rancher 则是将自己的驱动程序用于各种云 PaaS 解决方案,甚至使用 vSphere 进行本地部署来执行类似的任务。但 Rancher 能够导入外部配置的集群并且为其提供可见性,至今 PKS 还没有实现这样的功能。而在 VMware 2019 大会上,VMware 宣布推出一款名为 Tanzu Mission Control 的产品,该产品在未来或许能实现 Rancher 现有的这些功能。但是,在那之前,Rancher 依旧代表着优秀的技术,它可以管理并且聚合不同的 Kubernetes 集群到单一的系统中。
这个案例从何而来?
和我之前写过的很多文章一样,这篇文章也是从客户项目中衍生出来的。而且由于找不到关于这个主题的 Enterprise PKS 指南,我决定自己写一个。这个客户计划使用裸机、小型硬件将在边缘的 Kubernetes 部署到全球数百个站点。他们需要将所有集群统一到一个工具中,从而方便管理、监控以及应用程序部署。他们在主要的数据中心运行 Enterprise PKS,来为其他业务需求部署 Kubernetes 集群。由于这些站点都与他们在世界各地的各个数据中心相连接,因此它们需要聚集在一个可以在本地运行的工具中,同时必须具有高可用性、安全性和高性能。将 Enterprise PKS 用于底层、专用的 Kubernetes 集群,然后在该集群上以 HA 模式在 Rancher Server 上分层,这样操作为我们两个方面的绝佳功能——通过 NSX- T 进行网络和安全性,通过 BOSH 进行集群生命周期维护,通过 Harbor 复制镜像仓库并且通过 Rancher 在边缘范围内对分散的 Kubernetes 集群在单一窗格进行统一管理。
架 构
我们先来看看架构图。
理论上说,我们在底部有一个 vSphere 栈,它在我们本地的 SDDC 中托管这个环境。接下来,我们通过 PKS 构建了一个 3 -master 和 3 -worker 的 Kubernetes 集群。除了许多其他系统容器(未在上图显示)之外,worker 还托管 Rancher pod 和 Nginx pod。基于以上,我们使用 NSX- T 提供的负载均衡器来提供两个主要虚拟的服务器:一个用于控制平面访问,另一个用于 ingress 访问。
然而,经过反复的试验并最终失败之后,我发现 NSX- T 的 L7 负载均衡器并不支持 Rancher 正常运行所需的必要请求头。具体来说,Rancher 需要在 HTTP 请求中传递 4 个请求头到 pod。这些请求头用于识别入站请求的来源,并确保在应用程序外部已经发生适当的 TLS 终止。其中一个请求头 X -Forwarded-Proto,它可以告诉 Rancher 用于与负载均衡器进行通信的协议,但 NSX- T 的负载均衡器无法传递这些请求头。基于此,我们必须使用第三方 ingress controller——nginx,它是目前最流行的解决方案之一,它对大部分的客户端选项提供了广泛的支持,并且可以直接发送请求头。
我们接着往下一个层次看,进入 Kubernetes 内部(如下图所示)。请记住,我们正在专门研究 worker,但正在抽象化诸如节点之类的物理层。
外部请求通过 Nginx controller 中的 LoadBalance 服务类型进入集群。从该服务构建的端点列表中选择一个 nginx controller,进而匹配 ingress controller 中的规则。该请求将转发到 Rancher Service,最后到与该服务上的标签 selector 匹配的 pod。
我们接下来一步一步完成安装过程,看完之后你将会有更深的理解。
安 装
请记住上文提到的架构,我们将开始将这些碎片拼在一起。一共有 6 个大步骤,每个步骤下都有详细的小步骤,我会详细说明。
1、配置新的自定义 PKS 集群
第一步,我们将专门为 Rancher 制定一个 plan,然后构建一个专门用于在 HA 模式下运行 Rancher 的集群。我们还将制作一个自定义的负载均衡器配置文件,以供构建中参考。
2、使用 Helm 准备集群
集群构建完成之后,我们需要进行准备,以便可以使用 Helm 的软件包,因为我们将使用它来安装 ingress controller 和 Rancher。
3、生成证书和 secret
这是一个企业级的部署,这意味着要使用自定义证书。所以我们需要创建那些证书并且使它们可供 Kubernetes 的各种 API 资源使用。
4、创建并配置 Ingress
既然我们无法使用 NSX- T 作为 Ingress controller,那么我们必须配置另一种类型并适当地配置它。然后我们将使用一个 NSX- T 的 Layer- 4 负载均衡器来发送流量到 ingress。
5、安装 Rancher
接下来,我们使用 Helm 安装 Rancher。
6、配置基础架构
一切都就位之后,我们需要执行一些部署后的配置任务,然后才完成所有的步骤。
接下来,我将详细解释每一个步骤具体如何操作。
配置新的自定义 PKS 集群
首先我们需要做的是设置 PKS 基础架构,以便我们可以将 Kubernetes 集群部署在任意地方。需要做两件最基础的事情:创建一个新 plan,创建中型负载均衡器。我们的 plan 需要指定 3 个 master 以使控制平面级别高可用,并且 3 个 worker 在工作负载级别高可用。在本例中,由于我们正在准备将大量集群安装到 Rancher 中,因此我们可能要继续进行操作,并指定一个中型负载均衡器,否则 PKS 会给我们一个很小的负载均衡器。这个负载均衡器将为控制平面 /API 访问提供虚拟服务器并将 traffic 发送到 Rancher。
在 PKS tile 中,我使用以下配置创建一个新 plan。
根据你自己的需求来创建 plan,但记住 master 和 worker 的数量。如果想要将其放入生产环境中,我建议你增加 master 永久磁盘的规格。既然每个主节点都是一个包含控制平面组件和 etcd 的组合节点,并且 Rancher 将充分利用 Kubernetes 集群的 etcd 安装作为其数据存储,因此我们要确保有足够的空间。
你可以使用底部的附加组件部分来自动加载任意 Kubernetes Manifest,使其可以在集群构建过程中运行。我将使用 pks-dns,它可以在控制平面启动后自动为其创建 DNS 记录。如果你之前尚未使用过,我强烈建议你试用一下。
最后,为了让 Rancher agent 能够正确运行,请务必在此集群上启动“允许特权”模式。
现在,使用之前保存的 plan 和提交的更改,你应该能够运行一个 pks plans 并且显示这个新的 plan。
$ pks plans
Name ID Description
dev-small 8A0E21A8-8072-4D80-B365-D1F502085560 1 master; 2 workers (max 4)
dev-large 58375a45-17f7-4291-acf1-455bfdc8e371 1 master; 4 workers (max 8)
prod-large 241118e5-69b2-4ef9-b47f-4d2ab071aff5 3 masters; 10 workers (20 max)
dev-tiny 2fa824527-318d-4253-9f8e-0025863b8c8a 1 master; 1 worker (max 2); auto-adds DNS record upon completion.
rancher fa824527-318d-4253-9f8e-0025863b8c8a Deploys HA configuration with 3 workers for testing Rancher HA builds.
有了这个,我们现在可以创建一个自定义负载均衡器 plan。目前,实现这个方法的唯一方式是通过 pks CLI 工具或通过创建自定义 JSON 规范文件创建 API。保存一下信息到名为 lb-medium.json.
的文件中,根据自己的需求替换“name”和”description”的值。
{
"name": "lb-medium",
"description": "Network profile for medium NSX-T load balancer",
"parameters": {"lb_size": "medium"}
}
运行以下命令来创建一个新的网络配置文件:
$ pks create-network-profile lb-medium.json
再次检查,确保 plan 是存在的。
$ pks network-profiles
Name Description
lb-medium Network profile for medium NSX-T load balancer
现在使用你的 plan 和中型负载均衡器创建一个新的 PKS 集群。
$ pks create-cluster czpksrancher05 -e czpksrancher05.sovsystems.com -p rancher --network-profile lb-medium
构建集群将会花费几分钟的时间,可以趁机休息一下。你可以监视集群创建过程,以了解什么时候创建完成。
$ watch -n 5 pks cluster czpksrancher05
Every 5.0s: pks cluster czpksrancher05
Name: czpksrancher05
Plan Name: rancher
UUID: 3373eb33-8c8e-4c11-a7a8-4b25fe17722d
Last Action: CREATE
Last Action State: in progress
Last Action Description: Instance provisioning in progress
Kubernetes Master Host: czpksrancher05.sovsystems.com
Kubernetes Master Port: 8443
Worker Nodes: 3
Kubernetes Master IP(s): In Progress
Network Profile Name: lb-medium
集群创建完成之后,如果你之前使用了我推荐的 pls-dns 工具,那么你的 DNS 记录现在也应该已经创建好了。
$ nslookup czpksrancher05
Server: 10.10.30.13
Address: 10.10.30.13#53
Name: czpksrancher05.sovsystems.com
Address: 10.50.0.71
现在,所有必要的工作都完成了,我们可以访问这个集群。首先让我们先配置 kubeconfig。
$ pks get-credentials czpksrancher05
然后确认我们是否具有访问权限。
$ kubectl cluster-info
Kubernetes master is running at https://czpksrancher05.sovsystems.com:8443
CoreDNS is running at https://czpksrancher05.sovsystems.com:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
使用 Helm 准备集群
既然现在我们已经可以访问我们的集群,我需要使用 Helm 来准备它。Helm 是一个用 chart 的打包格式来将整个应用程序部署到 Kubernetes 的一个工具。这些 chart 打包了完整部署应用程序所需的各种 Kubernetes manifest。网络上已经有大量的文章介绍了 Helm 及其入门,所以我将不再赘述。我假设你已经了解了这些,并将 Helm 二进制文件添加到了 PATH 中。我们需要在 Kubernetes 创建一个必要的对象,以供 Tiller(Helm 的服务器端组件)运行。这包括了一个 ServiceAccount、ClusterRoleBinding,然后初始化 Helm。
$ kubectl -n kube-system create serviceaccount tiller
serviceaccount/tiller created
创建 Tiller 帐户的绑定作为集群管理员。当你完成安装之后,你就可以解除绑定了。通常来说,绑定 service account 到集群管理员角色并不是一个好主意,除非它们真的需要集群范围的访问。如果你想的话,可以限制 Tiller 部署到单个命名空间中。幸运的是,在 Helm3 中将不会有 Tiller,这将进一步简化 Helm chart 的部署并提高了安全性。
$ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller
clusterrolebinding.rbac.authorization.k8s.io/tiller created
接下来,使用 service account 初始化 Helm,这将在 kube-system 命名空间创建一个 Tiller pod。
$ helm init --service-account tiller
$HELM_HOME has been configured at /home/chip/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
你现在应该能够检查并看到一个新的 Tiller pod 已经创建完成并且正在运行。
$ kubectl -n kube-system get po -l app=helm
NAME READY STATUS RESTARTS AGE
tiller-deploy-5d6cc99fc-sv6z6 1/1 Running 0 5m25s
helm version
要能确保客户端的 helm
二进制文件能够与新创建的 Tiller pod 通信。
$ helm version
Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
第二个步骤就完成,接下来我们需要做一些证书工作。
生成证书和 secret
现在,我们不得不创建我们的自定义证书并使它们可供 Kubernetes 使用。在本例中,我使用由内部企业证书颁发机构(CA)签名的证书,但是你可以只使用由第三方根签名的通用证书。Rancher 可以使用以上两种证书,也可以使用自签名证书。由于这是一个企业级部署,我们需要一个已经建立的信任链,因此我们将使用企业 CA。
创建证书的过程可能会有所不同,因此我无法一一列出所有情况,我只会简单介绍与本例所需证书创建和生成过程相同的证书。但是无论如何,我们都需要一个主机名,通过它可以访问集群中运行的 Rancher 应用程序。不要将之前我们在创建 PKS 集群时使用的外部主机名混淆,它们时两个单独的地址,并且作用也不一样。我将这个 Rancher 安装命名为“czrancherblog”,以便正确地生成并签名我的证书。
通过 Internet 的魔力,我们可以快速完成生成过程,直到获得证书,secret 和根 CA 证书文件。
确保运行 kubectl
的系统可以访问这些文件,然后继续。
我们将为 Rancher 创建一个新的命名空间,在命名空间内,我们需要创建 2 个 secret:一个用于签署我们的主机证书的根 CA 证书,以及实际生成的证书及其对应的私钥。
$ kubectl create ns cattle-system
namespace/cattle-system created
在创建第一个 secret 之前,确保根 CA 证书命名为 cacerts.pem,必须准确地使用这个名字,否则 Rancher pod 将启动失败。
$ kubectl -n cattle-system create secret generic tls-ca --from-file=cacerts.pem
secret/tls-ca created
接下来,创建 TLS secret,该 secret 将保存 czrancherblog 站点的主机证书。此外,在下一步创建的 nginx ingress controllerPod 也会需要这个 secret,以便正确认证客户请求。
$ kubectl -n cattle-system create secret tls czrancherblog-secret --cert=czrancherblog.cer --key=czrancherblog.key
secret/czrancherblog-secret created
验证已经创建的两个 secret
$ kubectl -n cattle-system get secret
NAME TYPE DATA AGE
czrancherblog-secret kubernetes.io/tls 2 2m7s
default-token-4b7xj kubernetes.io/service-account-token 3 5m1s
tls-ca Opaque 1 3m26s
你会注意到,创建了这些 secret,实际上只是创建两种不同类型的 secret 而已。tls-ca
这个 secret 是 Opaque 类型的 secret,而 czrancherblog-secret
是一个 TLS secret。如果你两相比较,你会注意到 tls-ca secret
会在数据部分为 cacerts.pem
列出一个 base64-encoded
证书。而czrancherblog-secret
将会列出其中的两个,每个文件分配一个。你同时还会注意到无论你提供哪种输入文件,都已经为 tls.crt
和tls.key
列出它们的值(经过 base64 编码以使它们模糊之后)。
现在我们已经完成证书的生成了,现在应该到 nginx ingress 的部分。
创建和配置 Ingress
既然 secret 和命名空间都已经创建,现在让我们来安装 nginx-ingress controller。如上文所提到的,尽管 Enterprise PKS 可以并且将使用 NSX- T 作为现成的 Ingress controller,但是 Rancher 有些特殊需求是这一 controller 无法满足的。因此在这一情况下,我们将使用其他的 controller。Nginx 有一个被广泛使用并且技术成熟的 ingress controller,恰好符合我们的需求。请注意在本例中,我使用的是 kubernetes/ingress-nginx,而不是 nginxinc/Kubernetes-ingress。尽管它们有些许差异,但其实在本例中两者都能使用。
在您的终端上,运行以下 Helm 命令以从稳定版本中安装 kubernetes / ingress-nginx controller:
helm install stable/nginx-ingress --name nginx --namespace cattle-system --set controller.kind=DaemonSet
在这个命令中,我们让 Helm 把 nginx 对象放入 cattle-system
命名空间中,并且将 pod 作为 DaemonSet 而不是 Deployment 来运行。我们希望每个 Kubernetes 节点都有一个 controller,进而节点故障不会消除通往 Rancher Pod 的入口数据路径。Rancher 将完成类似的任务,但将使用具有 pod 反关联规则的 deployment(这与 vSphere DRS 的工作原理相似)。
命令完成之后,你将会从 Helm 获得一连串的返回,包括所有它创建的对象。需要指出的是,几个 API 对象是 ConfigMap,它存储 nginx controller 的配置以及服务。
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-nginx-ingress-controllern LoadBalancer 10.100.200.48 <pending> 80:32013/TCP,443:32051/TCP 0s
nginx-nginx-ingress-default-backend ClusterIP 10.100.200.45 <none> 80/TCP 0s
第一个称为 nginx-nginx-ingress-controller
的类型为 LoadBalancer。从应用程序的角度来看,这实际上将是 Rancher 集群的切入点。如果你看到 External-IP 栏,你将会注意到它最初只报告了 <pending> 状态。这时候需要给你的 Kubernetes 集群一些时间来拉取镜像,然后再次检查命名空间的服务。
# kubectl -n cattle-system get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-nginx-ingress-controller LoadBalancer 10.100.200.48 10.50.0.79,100.64.128.125 80:32013/TCP,443:32051/TCP 6m35s
nginx-nginx-ingress-default-backend ClusterIP 10.100.200.45 <none> 80/TCP 6m35s
这一次,你将会发现它分配了两个 IP,因为 NSX 容器插件(NCP)注意到该对象的创建,并已与 NSX- T 进行通信,以使用为此集群指定的中型负载均衡器为我们创建新的虚拟服务器。
如果你跳到 NSX- T 管理器界面中的 Server Pool 选项卡,并找到此处引用的选项卡,那么可以检查 Pool Member 选项卡,并查看它已自动添加了该服务引用的端点。
Name 栏被截断了,但是 IP 栏依旧可见。让我们再次检查一下 Kubernetes。
$ kubectl -n cattle-system get po -o wide -L app
NAME READY IP NODE APP
nginx-nginx-ingress-controller-wjn2x 1/1 10.11.54.2 9aa90453-2aff-4655-a366-0ea8e366de4a nginx-ingress
nginx-nginx-ingress-controller-wkgms 1/1 10.11.54.3 f35d32a0-4dd3-42e4-995b-5daffe36dfee nginx-ingress
nginx-nginx-ingress-controller-wpbtp 1/1 10.11.54.4 e832528a-899c-4018-8d12-a54790aa4e15 nginx-ingress
nginx-nginx-ingress-default-backend-8fc6b98c6-6r2jh 1/1 10.11.54.5 f35d32a0-4dd3-42e4-995b-5daffe36dfee nginx-ingress
输出的内容被稍微修改了一点点,去除了不必要的栏,但除了正在运行的节点之外,你还可以清晰地看到 pod、它们的状态以及 IP 地址。
有了新虚拟服务器的 IP 地址,我们接下来需要创建一个 DNS 记录,可以与我们的 Rancher HA 安装的主机名对应。我决定将其命名为“czrancherblog”,因此我将在 DNS 中创建一个 A 记录,将在 czrancherblog 指向 10.50.0.79。
$ nslookup czrancherblog
Server: 10.10.30.13
Address: 10.10.30.13#53
Name: czrancherblog.sovsystems.com
Address: 10.50.0.79
这一阶段的最后一步是在 Kubernetes 上创建 ingress controller。尽管我们已经有 LoadBalancer 这一服务类型,我们依旧需要 ingress 资源来路由流量到 Rancher service。但该服务尚不存在,但很快就可以创建。
使用以下代码创建一个新的 manifest,命名为 ingress.yaml
,并且使用kubectl create -f ingress.yaml
对其进行应用:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
namespace: cattle-system
name: rancher-ingress
spec:
rules:
- host: czrancherblog.sovsystems.com
http:
paths:
- backend:
serviceName: rancher
servicePort: 80
tls:
- hosts:
- czrancherblog.sovsystems.com
secretName: czrancherblog-secret
现在我来解释一下这个 manifest。首先,我们的类型是 Ingress,接下来我们有一个注释。这一行实际上在做两件事:指示 NCP 不要告诉 NSX- T 创建和配置任何对象,并告诉 Nginx controller 将流量路由到端口 80 上尚未创建的名为 rancher
的服务。最后,当来自主机值为 czrancherblog.sovsystems.com 的请求中的任何流量进入系统时,它使用我们创建的包含证书及密钥的 TLS secret 应用到 controller 上。
尽管我们希望不会出错,但是我们仍然要将该地址放入网络浏览器中,以查看返回的内容。
我们将获得一些重要的信息。首先,非常明显的大字“503 Service Temporarily Unavailable”,考虑到目前尚无流量经过 nginx controller,这样的返回结果是符合期望的。其次,在地址栏我们看到了一个绿色锁的图标,这意味着我们创建的包含证书的 TLS secret 已经被接受并且应用于主机规则。
到目前为止,都在向预想的方向进行,让我们进行下一步。
安装 Rancher
终于到了期待已久的一刻——安装 Rancher。现在我们一切都准备好了,开始安装吧!
添加 Rancher stable 仓库到 Helm,然后进行更新并拉取最新 chart。
$ helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
"rancher-stable" has been added to your repositories
$ helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
local http://127.0.0.1:8879/charts
rancher-stable https://releases.rancher.com/server-charts/stable
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "rancher-stable" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete.
为什么在安装 nginx ingress 之前我们不需要添加一个仓库呢?因为那个 chart 实际上来自由谷歌托管的默认”stable”仓库,因此没有自定义仓库可以添加。对于 Rancher,我们必须添加 stable 或 latest 仓库以访问其管理的 chart。
如果你已经成功更新了,那么赶紧激活 Rancher 吧。从 stable repo 中安装最新的 chart,并检查输出。
$ helm install rancher-stable/rancher --name rancher --namespace cattle-system --set hostname=czrancherblog.sovsystems.com --set ingress.tls.source=secret --set privateCA=true
NAME: rancher
LAST DEPLOYED: Sun Sep 8 18:11:18 2019
NAMESPACE: cattle-system
STATUS: DEPLOYED
RESOURCES:
==> v1/ClusterRoleBinding
NAME AGE
rancher 1s
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
rancher 0/3 0 0 1s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
rancher-6b774d9468-2svww 0/1 ContainerCreating 0 0s
rancher-6b774d9468-5n8n7 0/1 Pending 0 0s
rancher-6b774d9468-dsq4t 0/1 Pending 0 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rancher ClusterIP 10.100.200.15 <none> 80/TCP 1s
==> v1/ServiceAccount
NAME SECRETS AGE
rancher 1 1s
==> v1beta1/Ingress
NAME HOSTS ADDRESS PORTS AGE
rancher czrancherblog.sovsystems.com 80, 443 1s
NOTES:
Rancher Server has been installed.
NOTE: Rancher may take several minutes to fully initialize. Please standby while Certificates are being issued and Ingress comes up.
Check out our docs at https://rancher.com/docs/rancher/v2.x/en/
Browse to https://czrancherblog.sovsystems.com
Happy Containering!
很好,现在 chart 为我们部署了大量的 Kubernetes 对象。然而,注意一下最后一个对象,它是另一个 ingress。我们不需要它,所以直接将其删除。
$ kubectl -n cattle-system delete ing rancher
ingress.extensions "rancher" deleted
检查 pod 以确保它们现在正在运行。
$ kubectl -n cattle-system get po -l app=rancher
NAME READY STATUS RESTARTS AGE
rancher-6b774d9468-2svww 1/1 Running 2 5m32s
rancher-6b774d9468-5n8n7 1/1 Running 2 5m32s
rancher-6b774d9468-dsq4t 1/1 Running 0 5m32s
非常棒,一切都起来了。如果你在 RESTARTS 列中看到的值不是零,也不要惊慌,Kubernetes 最终会与其 controller 和监控循环保持一致,因此只要采取适当的措施,就可以使得实际状态达到所需状态为止。
现在,这些工作都完成之后,让我们再次检查我们的网页,看看发生了什么。
正如我们所希望的那样,我们现在进入我们的 Rancher 集群了!让我们设置初始密码以及在下一页面中设置 server URL。如果不进行设置,它将自动填充我们的主机名。
这一步骤就算完成啦,接下来让我们进入最后一步。
配置基础架构
既然我们已经让一切都起来了并且正在运行,让我们做些事情。
首先,你可能已经注意到你的“local”集群卡在 Provisioning 的状态,正在等待设置主机名。通常这几分钟之后就会自动解决,但在本例中,则需要执行几个简单的步骤。
最快的修复步骤是点击最右边的设置按钮来编辑这个集群。
现在不做任何更改,直接点击保存。
然后回到主页,它应该已经起来了。
再次进入集群,确保你的节点正在汇报状态。
接下来,我们需要在主机之间分配我们的基础 PKS Kubernetes 节点。如果你的 plan 包括多个可用空间,你可能已经完成这一步了。但如果你像我一样,没有多个可用空间,你将需要某种方法来确保你的 master 和你的 worker 分布在 ESXi 主机上。如果你听说过我的 Optimize-VMwarePKS 项目,我强烈建议你使用它,该项目可以自动为你处理 master,但我们依旧需要手动把 worker 分开。请记住,我们不仅需要 API 和控制平面的高可用,我们也需要 Rancher 数据平面的高可用。这意味着任何管理程序的故障都不会影响我们应用程序的可访问性。
你使用 -ProcessDRSRules
标志运行 Optimize-VMware-PKS 之后,它应该检测到该集群的 master 并创建 DRS 反关联性规则。现在,你需要为 worker 节点手动创建一个新的节点。
为 worker 创建一个新的反关联规则,并添加所有规则。由于 BOSH 会使用 UUID 而不是实际名称来部署它们,因此在列表中找到它们十分困难,但是你可以在 vSphere VM 和模板清单视图中找到它们(如果你使用 -ProcessDRSRules 标志运行 Optimize-VMware-PKS),或者你可以在引用部署后,从 BOSH CLI 获取名称。
$ bosh -d service-instance_3373eb33-8c8e-4c11-a7a8-4b25fe17722d vms
Using environment 'czpcfbosh.sovsystems.com' as client 'ops_manager'
Task 55540. Done
Deployment 'service-instance_3373eb33-8c8e-4c11-a7a8-4b25fe17722d'
Instance Process State AZ IPs VM CID VM Type Active
master/00be5bab-649d-4226-a535-b2a8b15582ee running AZ1 10.50.8.3 vm-a8a0c53e-3358-46a9-b0ff-2996e8c94c26 medium.disk true
master/1ac3d2df-6a94-48d9-89e7-867c1f18bc1b running AZ1 10.50.8.2 vm-a6e54e16-e216-4ae3-8a99-db9100cf40c8 medium.disk true
master/c866e776-aba3-49c5-afe0-8bf7a128829e running AZ1 10.50.8.4 vm-33eea584-ff26-45ed-bce3-0630fe74f88a medium.disk true
worker/113d6856-6b4e-43ef-92ad-1fb5b610d28d running AZ1 10.50.8.6 vm-5508aaec-4253-4458-b2de-26675a1f049f medium.disk true
worker/c0d00231-4afb-4a4a-9a38-668281d9411e running AZ1 10.50.8.5 vm-e4dfc491-d69f-4404-8ab9-81d2f1f4bd0d medium.disk true
worker/ff67a937-8fea-4c13-8917-3d92533eaade running AZ1 10.50.8.7 vm-dcc29000-16c2-4f5a-b8f4-a5420f425400 medium.disk true
6 vms
Succeeded
无论你选择哪种方法,只要能保证规则创建即可。
现在你已经有了 master 和 worker 的反关联规则,那么请确保你在多个方面都具备高可用性。如果你愿意进行测试,那么让工作节点(或与此相关的主节点)发生故障,或删除 Rancher Pod,然后查看 Kubernetes 创建的新 pod。此时,Rancher 应该还保持工作状态。
结 语
你已经看到了我们如何从零开始创建了一个具备高可用性以及完整功能的 Rancher Server,并且你也应该采取了一些措施确保将其安全地分布在底层架构上。你需要牢记一个重要的考虑因素:当在 Enterprise PKS 上运行 Rancher 的时候,与 Kubernetes 命名空间有关。当在 Kubernetes 上安装 Rancher 时,通过创建 CRD 和其他对象,Rancher 从平台的角度将与 Kubernetes 深度集成。当用户创建一个新项目或导入一个新集群时,Kubernetes 将会在后台创建一个新的命名空间。在其他 Kubernetes 环境中,这样的操作流程会非常完美,但在 Enterprise PKS 中,一个新的命名空间则意味着新的 Tier-1 router、新的逻辑网段、新的 pod IP 块等。在 PKS 没有预先设置好的情况下,如果大量导入集群和创建项目,那么这些命名空间很快会耗尽诸如 pod IP 块之类的 NSX- T 对象。如果你正在考虑在生产环境中采用这样的架构,那么需要牢记这一点。现在,无法告诉 NCP 忽略这些命名空间创建命令,因此它不会在 NSX- T 内部生成对象。