下文的 Tanzu 特指 ​​vSphere with Tanzu​​​(简称 TKGs),除此之外,Tanzu 还有另一个版本 ​​Tanzu Kubernetes Grid​​​,一般简称 TKGm。


Tanzu 架构说明

Tanzu 和市面上其他的 Kubernetes 发行版有个很大不同,即其他发行版更类似于 K8s 安装程序,而 Tanzu 则是一个 K8s 调度平台,Tanzu 下用户需要先部署出一个主管集群(Supervisor Cluster),此集群基于 K8s 构建,但是并非用于生产,而是专门用来创建和管理其他 K8s 集群,其他集群专门用于交付给最终的业务部门来使用,这里的其他集群在 Tanzu 下被称作客户集群(Guest Cluster)。

Tanzu 的这种架构很类似于公有云的交付模式,当用户需要 K8s 跑业务时,管理员可以快速通过主管集群拉起一个 K8s 给到用户,当用户使用完此集群后,又可以快速进行回收,使得 K8s 集群变成一项可即时获取的服务

这种模型并非一时兴起,而是能预见的一种趋势,即 K8s 最终会是以集群的形式交付给使用者,而非仅给使用者使用资源的权限。这里面的原因多种多样,笔者仅列举几项:

  • 众口难调:在传统 VM 架构下,无论是谁需要资源,都可以直接交付个 VM 给对方,差异无非是资源大小;而在 Kubernetes 下,用户可能不止需要资源,还会需要 API 的掌控权,因为 K8s 的核心就是 API Server,开发者常常需要将 K8s 与其他平台进行集成,而不同系统的开发者常常使用不同的开发平台,很难统一,这时候,做一个集中式的大集群然后做好权限/API/资源管理的复杂度远远大于直接交付一整个平台;
  • 鸡蛋放在多个篮子里:在以前 vSphere 的世界里,每个客户都会建立很多集群来承载不同业务,每个集群都会是一个单独的故障域,同理,K8s 环境下也可以建立多个集群,单个集群故障只会影响部分系统,不会影响其他业务;
  • 运维复杂度:从 K8s 大规模使用开始,就有很多人的观念是 K8s 太复杂了,所以只能部署一两套来运维,多个集群管理不过来,但这种观点存在一些疏漏,比如:单个集群上势必会承载非常多的业务,随便做一个集群变更可能都需要与非常多的部门打招呼设置变更窗口,如果协调不一致最终整个集群会变成不敢维护,时间长了就会成为历史包袱,未来扩容时考虑到产品更新和硬件支持,只能新建集群..这样反复恶性循环(现在部分企业里的 OpenStack 就是这样的不可维护状态)。Tanzu 针对 K8s 的升级运维做了很多改进,使得升级过程无风险且自动化,再加上多集群的架构,使得 Tanzu 可运维性非常强。

OK,回到正题。

Tanzu 从网络层面有​​两类​​​,一类是使用 NSX-T 作为底层承载网,另一类是使用 vDS 作为承载网,本文介绍前者的一些细节。

在 NSX+Tanzu 架构下,网络会划分为两类:

  • 管理网:
  • ESXi、vCenter、NSX Manager、DNS 等管理型组件之间通信的网络
  • Tanzu 主管集群会有一张网卡接入管理网,与上述组件进行通信,调度 vSphere 资源
  • 业务网:
  • 所有未来承载业务的网络,包括 K8s node 以及其中的 Pod,都会通过此网络通信
  • 主管集群 API Server 也会运行在此网络内(很重要)
  • 客户集群的 API Server 也会运行在此网络内(很重要)
  • 所有业务网最终都会由 NSX 自动置备,用户需要预先规划好 IP 地址范围

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由


部署 Tanzu 主管集群前期准备

在部署 Tanzu 主管集群前,需要预先完成下列工作:

1、部署一套完整的 NSX-T(具体方法见:​​https://blog.51cto.com/sparkgo/5478574​​ 中的传统模式

2、准备内容库:内容库用于存放 Kubernetes 发行版的 OVA,可以手动去​​这里​​​下载再上传到内容库,或者直接让 vCenter 能够访问互联网,订阅在线的内容库地址并在线拉取 OVA(方法见​​这里​​​)。

3、准备 vSphere 存储策略:在传统 VM 环境下,一般用户很少去使用存储策略,需要创建 VM 时直接将 VM 指定到相应的 Datastore 中,但是在 Tanzu 下,所有存储相关的调度均是由系统自动完成的,存储策略在此处的作用就是设置 Tanzu 可以使用的存储。比如集群里有 4 个 Datastore,我可以使用基于标记的存储策略,仅设置 Tanzu 可以使用其中的两个 Datastore。

4、集群需要开启 HA 模式和 DRS 全自动模式:开启这两者是为了保证 Tanzu 可以正确调度 VM 的创建,以及保证高可用。

相关配置截图如下:


1、NSX-T 部署后检查

NSX-T 与 vCenter 对接正常:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_02

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_03

主机准备状态正常:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_04

T0 配置正确,关联了 Edge Cluster:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_05

在 vCenter 侧可以看到 VDS 被标识为 NSX 交换机:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_06

2、准备内容库

创建内容库(此处使用在线按需拉取方式):

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_07

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_08

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_09

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_10

3、准备虚拟机存储策略

本文为了可控性,使用基于标记的虚拟机存储策略。

在 vCenter 的下列位置可以找到添加标记类别以及标记的地方:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_11

添加存储类别:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_12

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Kubernetes_13

添加存储标记,关联上述类别:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Tanzu_14

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Tanzu_15

为 Datastore 分配标记:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_16

配置基于标记的存储策略:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_17

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_18

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_19

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_20

4、集群 HA 及 DRS 配置

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_21

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_22

网络规划

名称

网段

描述

命名空间网络

10.40.0.0/18

供 Guest Cluster VM 及 Native Pod 使用

服务 CIDR

10.40.64.0/18

供主管集群内 Service 使用

输入 CIDR

10.40.128.0/18

供负载均衡器使用

主管集群管理网络

10.10.50.125~129

主管集群管理网络 IP 地址范围


部署 Tanzu 主管集群

在完成上述的前期准备后,即可按照向导进行主管集群的开启,配置截图如下:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Tanzu_23

1、设置网络模式为 NSX-T

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_24

2、选择相应的集群,如果此处提示集群不兼容,则需要查看 vCenter 系统中的 /storage/log/vmware/wcp/wcpsvc.log 文件获取具体报错信息

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_25

3、设置主管集群的存储策略

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Kubernetes_26

4、设置主管集群的管理网络,一般管理网络需要 5 个可用地址(3 个实地址 +1 个虚拟地址 +1 个滚动升级地址),这些地址需要能和 vCenter 以及其他管理网段通信,一般使用 vDS 端口组即可。如果 vCenter 等管理组件使用 .local 结尾的域名,则必须在 DNS 搜索域中加入域名后缀

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_27

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Kubernetes_28

5、设置工作负载网络。这些网络未来都会由 NSX 来自动创建,用户需要分配多个网段给 NSX,这些网段不能和已有网络重叠

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_29

6、设置全局内容库,内容库中存放的是未来部署 K8s 集群的 OVA 文件

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_30

7、设置主管集群的规模,一般 POC 环境使用小型即可

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_31

整个创建过程大致会有 20+ 分钟,耐心等待即可。

等待部署完成后,配置状态会变为“正在运行”,并且会有一个控制平面节点地址,此地址由 NSX 负载均衡器接管:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_32

在 vSphere 集群中会出现一个 Namespace 资源池,里面有三台控制虚拟机,每台分别有一张网卡接入之前配置的管理网络中,一张接入 NSX 自动创建的分段中:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_33

相应地,可以在 NSX 看到系统自动置备了 T1 网关:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Kubernetes_34

在 Tanzu+NSX 架构下,所有集群内的 ClusterIP 类型的 Service 均会由 NSX DLB (分布式 LB)来实现,所以在 NSX 界面中可以直接看到所有服务;集群内发布的 Loadbalancer 类型的 Service 均会由普通的运行在 Edge 节点的 LB 来实现,在 NSX 界面中也可以看到相关服务:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_35

最后,访问控制平面节点地址,可以正常访问,此处提供了 kubectl 和 kubectl-vsphere CLI 工具,用于连接到主管集群和业务集群:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_36

部署客户集群

本文会构建一个 Pod ​​可路由的 K8s 集群​​,部署全路由 K8s 集群有下列前置条件:

  • vCenter 版本 7.0U3 及以上
  • 主管集群 k8s 版本至少:v1.21.0+vmware.wcp.2
  • TanzuKubernetesCluster API 版本为 v1alpha2
  • 客户集群 K8s 版本至少:v1.21.2---vmware.1-tkg.1.ee25d55


为客户集群创建命名空间

选中 vSphere 集群,右键选择“新建命名空间”:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_37

设置命名空间名称:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Tanzu_38

在 7.0U3 版本之后,创建命名空间时多了一个“替代集群网络设置”的开关,通过此开关可以覆写默认的网络相关配置,做到不同租户(命名空间)有不同的网络设置:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_39

创建完成后需要为命名空间关联 VM 类和内容库:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_40

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Kubernetes_41

其中 VM 类用于表示未来租户可以使用的 VM 规格,VM 类可以按需创建或者使用默认的:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_42

内容库用于存放 Kubernetes 发行版 OVA 文件

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Tanzu_43

最后,为命名空间关联存储策略:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_44

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Kubernetes_45

登陆主管集群并检查

在上个章节的最后一部分,主管集群的 UI 中提供了两个 CLI 工具,其中一个名为 kubectl-vsphere 的工具用于登录主管集群,具体命令如下(此处使用 administrator@vsphere.local 用户登录):

kubectl-vsphere login --insecure-skip-tls-verify --server=https://10.40.160.1 -u administrator@vsphere.local

根据提示切换到相应的 context:

kubectl config use-context 10.40.160.1

查看 node 状态均为 Ready,可以看到环境中有三个 Master 节点,分别为三台主管集群 VM 节点,一台 ESXi 作为 Worker 节点:

kubectl get node

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_46

通过下列命令可以看到之前为客户集群创建的命名空间可以正常看到:

kubectl get ns

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_47

接着在 ns1 下分别查看 tkr(Kubernetes 发行版)、storageclass(存储策略)及 vmclass(VM 类),确认可以正常读取到:

kubectl -n ns1 get tkr
kubectl -n ns1 get sc
kubectl -n ns1 get vmclass

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Tanzu_48

创建客户集群

准备下列客户集群 YAML 文件:

#cat tkc.yaml
apiVersion: run.tanzu.vmware.com/v1alpha2
kind: TanzuKubernetesCluster
metadata:
name: tkgs-v2-cluster-routable-pods
spec:
topology:
controlPlane:
replicas: 1
# vmClass 需要与关联给命名空间的 VM 类匹配
vmClass: best-effort-medium
# storageClass 需要与关联给命名空间的存储策略一致
storageClass: tanzu-storage-profile
tkr:
reference:
name: v1.21.6---vmware.1-tkg.1.b3d708a
nodePools:
- name: worker-nodepool-a1
replicas: 1
vmClass: best-effort-medium
storageClass: tanzu-storage-profile
tkr:
reference:
name: v1.21.6---vmware.1-tkg.1.b3d708a
settings:
storage:
defaultClass: tanzu-storage-profile
network:
cni:
#使用全路由 pod 时,CNI 名称为 antrea-nsx-routed
name: antrea-nsx-routed
services:
cidrBlocks: ["10.96.0.0/12"]
serviceDomain: tanzukubernetescluster.local
pods:
#使用全路由 pod 时,cdir Blocks 处需要留空,此 cidr 将由 NSX 自动分配
cidrBlocks:
trust:
additionalTrustedCAs:
- name: CA
data: LS0tLS1CRUdJTi<此处省略>0NUM1ZHJveG1UaC9sS2NBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=

运行下列命令创建客户集群,并查看创建状态:

kubectl -n ns1 apply -f tkc.yaml
kubectl -n ns1 get tkc

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_49

之后在 vCenter 中即可看到有 VM 在创建中:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Tanzu_50

等待 5~10 分钟后,集群创建完毕:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_51

和主管集群类似,NSX 也会为客户集群自动置备网络,配置好相应的 T1 网关和路由:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_52

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Tanzu_53

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_54

同时会添加下列防火墙规则,这些规则默认只允许集群 CIDR 到 Node 节点的访问,其他所有入向会被拒绝(LB 服务除外),通过这种方式可以有效保护集群内节点的安全:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Kubernetes_55

登录客户集群

在集群创建完成后,可以参照​​此文章​​​来获取集群的 kubeconfig 文件。

具体方法为找到命名空间下的名称包含 kubeconfig 的 secret,然后将其转码并输出到指定文件,例如 tkc-kubeconfig-admin:

kubectl -n ns1 get secrets
kubectl -n ns1 get secret tkgs-v2-cluster-routable-pods-kubeconfig -o jsonpath='{.data.value}' | base64 -d > tkc-kubeconfig-admin

接着创建一个 clusterrolebinding,为默认的 admin 用户赋予 privileged 权限(详细参见​​此文章​​​和​​此文章​​​):

kubectl --kubeconfig tkc-kubeconfig-admin  create clusterrolebinding default-tkg-admin-privileged-binding --clusterrole=psp:vmware-system-privileged --group=system:authenticated

业务部署测试

通过上文导出的 kubeconfig 文件查看集群节点状态:

kubectl --kubeconfig tkc-kubeconfig-admin get nodes -o wide

通过 NSX-T 及 Tanzu 实现 Pod 全路由_VMware_56

准备下列 YAML 文件:

# cat avi-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: avi-demo
name: avi-demo
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: avi-demo
template:
metadata:
labels:
app: avi-demo
spec:
containers:
- env:
- name: hostinfo
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
image: dyadin/avi-demo:v2
imagePullPolicy: IfNotPresent
name: avi-demo
ports:
- containerPort: 80
name: http
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
annotations:
name: avi-demo-lb
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: avi-demo
type: LoadBalancer

应用此 YAML 文件,查看 Pod 状态及 IP:

kubectl --kubeconfig tkc-kubeconfig-admin apply -f avi-demo.yaml
kubectl --kubeconfig tkc-kubeconfig-admin get po -o wide

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_57

接着运行 traceroute 访问外部,可以观察到 Pod 能够直接和外部网络通信,中间未经过 NAT 转换。

kubectl --kubeconfig tkc-kubeconfig-admin exec -it <pod-name> -- traceroute -n 10.10.50.9

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Kubernetes_58

目标端抓包可以直接看到 Pod 真实 IP 地址:

通过 NSX-T 及 Tanzu 实现 Pod 全路由_全路由_59

查看相应业务发布情况,进行访问测试:

kubectl --kubeconfig tkc-kubeconfig-admin get svc

通过 NSX-T 及 Tanzu 实现 Pod 全路由_TKGs_60

通过 NSX-T 及 Tanzu 实现 Pod 全路由_Tanzu_61


本文完