K8s 多集群(一)---Karmada 初体验
本文主要记录了 Kubernetes 多集群项目 Karmada 部署及简单使用。
一句话简介:Karmada 是一个 Kubernetes 多集群领域的开源项目,旨在让用户像使用单集群一样使用多集群。
github repo:https://github.com/karmada-io/karmada
1. 环境准备
Karmada 本身也是运行在 k8s 上的,因此我们需要先准备一个 k8s 环境,同时为了体验多集群效果,最好能多建几个集群。
推荐使用 KubeClipper 来创建 k8s 集群,一条命令搞定:Kubernetes教程(十一)—使用 KubeClipper 通过一条命令快速创建 k8s 集群
本文将使用 3 台 2c4g 机器部署 3 个单 master 集群,其中 1 个用于运行 karmada,另外两个作为业务集群使用。
2. Karmada 部署
安装 kubectl-karmada 插件
karmada 提供了 kubectl 插件,通过该插件可以很轻松的安装 Karmada,因此我们先安装该插件。
可以使用以下命令一键安装
curl -s https://raw.githubusercontent.com/karmada-io/karmada/master/hack/install-cli.sh | sudo bash -s kubectl-karmada
或者手动下载
wget https://github.com/karmada-io/karmada/releases/download/v1.5.0/kubectl-karmada-linux-amd64.tgz
tar -zxvf kubectl-karmada-linux-amd64.tgz
cp kubectl-karmada /usr/local/bin
kubectl-karmada version
初始化karmada
正常情况下执行以下命令即可完成 Karmada 初始化
kubectl karmada init
不过该命令默认会去 github 下载 crd 压缩包,同时默认会去 k8s.io 拉镜像。
因此在国内使用时,由于网络问题导致还需要指定一些参数才行:
先手动下载 crd,实际上里面就是一些 crd 的 yaml 文件
wget https://github.com/karmada-io/karmada/releases/download/v1.5.0/crds.tar.gz
然后 init 时指定 crd 地址以及镜像仓库
kubectl karmada init \
--kube-image-registry registry.cn-hangzhou.aliyuncs.com/google_containers \
--crds crds.tar.gz
安装完成后输出如下:
------------------------------------------------------------------------------------------------------
█████ ████ █████████ ███████████ ██████ ██████ █████████ ██████████ █████████
░░███ ███░ ███░░░░░███ ░░███░░░░░███ ░░██████ ██████ ███░░░░░███ ░░███░░░░███ ███░░░░░███
░███ ███ ░███ ░███ ░███ ░███ ░███░█████░███ ░███ ░███ ░███ ░░███ ░███ ░███
░███████ ░███████████ ░██████████ ░███░░███ ░███ ░███████████ ░███ ░███ ░███████████
░███░░███ ░███░░░░░███ ░███░░░░░███ ░███ ░░░ ░███ ░███░░░░░███ ░███ ░███ ░███░░░░░███
░███ ░░███ ░███ ░███ ░███ ░███ ░███ ░███ ░███ ░███ ░███ ███ ░███ ░███
█████ ░░████ █████ █████ █████ █████ █████ █████ █████ █████ ██████████ █████ █████
░░░░░ ░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░░░░░░ ░░░░░ ░░░░░
------------------------------------------------------------------------------------------------------
Karmada is installed successfully.
Register Kubernetes cluster to Karmada control plane.
Register cluster with 'Push' mode
Step 1: Use "kubectl karmada join" command to register the cluster to Karmada control plane. --cluster-kubeconfig is kubeconfig of the member cluster.
(In karmada)~# MEMBER_CLUSTER_NAME=$(cat ~/.kube/config | grep current-context | sed 's/: /\n/g'| sed '1d')
(In karmada)~# kubectl karmada --kubeconfig /etc/karmada/karmada-apiserver.config join ${MEMBER_CLUSTER_NAME} --cluster-kubeconfig=$HOME/.kube/config
Step 2: Show members of karmada
(In karmada)~# kubectl --kubeconfig /etc/karmada/karmada-apiserver.config get clusters
Register cluster with 'Pull' mode
Step 1: Use "kubectl karmada register" command to register the cluster to Karmada control plane. "--cluster-name" is set to cluster of current-context by default.
(In member cluster)~# kubectl karmada register 10.0.0.58:32443 --token jcbljd.tfotd1ylodf7jtm6 --discovery-token-ca-cert-hash sha256:3bc5b22efbef8470f010f65b68388266e2b8f3ab62a0151900761cd12760d34f
Step 2: Show members of karmada
(In karmada)~# kubectl --kubeconfig /etc/karmada/karmada-apiserver.config get clusters
3. 集群管理
Karmada 初始化完成后就可以将业务集群添加到 Karmada 中进行管理了。
注册方式分为 Push 模式和 Pull 模式,二者的注册方式不相同。
- Push 模式下,karmada 控制面会直接访问 member 集群的 kube-apiserver 以获取集群状态和部署资源
- Pull 模式下,会在 member 集群部署 karmada-agent ,包含以下作用
- 注册集群到 karmada
- 维护集群状态并报告给 karmada
- Watch karmada 集群里对应 namespace 下的资源对象,并将其部署到 member 集群里。
Push 模式
Push 模式完整命令如下:
需要注意的是 push 模式下 join 命令是在 karmada 集群中执行
# 语法
# kubectl karmada join <member-cluster-name> --kubeconfig=<karmada kubeconfig> --cluster-kubeconfig=<member1 kubeconfig>
# join
kubectl karmada --kubeconfig /etc/karmada/karmada-apiserver.config join cluster1 --cluster-kubeconfig=$HOME/.kube/config
各个参数含义应该一眼就能看出来:
--kubeconfig /etc/karmada/karmada-apiserver.config
指定 Karmada kubeconfig,表示操作的是 karmada 的 apiserver,- 实际上 Karmada apiserver 也是基于 kube-apiserver 源码修改的,因此相关操作也基本一致。
--cluster-kubeconfig=$HOME/.kube/config
则是指定待注册到 karmada 的 member 集群的 kubeconfig。
添加好后可以使用 kubectl 命令进行查看
member 集群在 karmada 中使用 clusters 这个 CR 对象进行存储
[root@karmada ~]# kubectl --kubeconfig /etc/karmada/karmada-apiserver.config get clusters
NAME VERSION MODE READY AGE
Cluster1 v1.23.6 Push True 1m24s
可以看到 cluster1 已经成功添加进来了。
Pull 模式
Pull 模式完整命令如下:
需要注意的是 pull 模式下的 register 命令需要到 member 集群中执行
pull 模式下的注册命令格式如下:
kubectl karmada register <karmada-apiserver> --token <token> --discovery-token-ca-cert-hash <hash>
类似与 kubeadm join 命令,需要提供 token 以及 ca证书的 hash 值作为校验。
大家仔细观察的话,可以发现在执行 karmada init 之后输出的日志里实际上是有提供该命令的
kubectl karmada register 10.0.0.58:32443 --token jcbljd.tfotd1ylodf7jtm6 --discovery-token-ca-cert-hash sha256:3bc5b22efbef8470f010f65b68388266e2b8f3ab62a0151900761cd12760d34f
当然,我们也可以使用以下命令重新生成 token(有效期 24h):
kubectl karmada token create --print-register-command --kubeconfig /etc/karmada/karmada-apiserver.config
输出如下:
[root@lixd-tmp-1 ~]# kubectl karmada token create --print-register-command --kubeconfig /etc/karmada/karmada-apiserver.config
kubectl karmada register 10.0.0.58:32443 --token 7pn49b.d9xhhpn9x8haqraq --discovery-token-ca-cert-hash sha256:3bc5b22efbef8470f010f65b68388266e2b8f3ab62a0151900761cd12760d34f
在 member 集群执行该命令进行注册:
kubectl karmada register 10.0.0.58:32443 --token jcbljd.tfotd1ylodf7jtm6 --discovery-token-ca-cert-hash sha256:3bc5b22efbef8470f010f65b68388266e2b8f3ab62a0151900761cd12760d34f
注册的时候会在当前集群启动一个 karmada-agent pod,用于和 karmada apiserver 交互。
[root@lixd-tmp-2 ~]# kubectl karmada register 10.0.0.58:32443 --token jcbljd.tfotd1ylodf7jtm6 --discovery-token-ca-cert-hash sha256:3bc5b22efbef8470f010f65b68388266e2b8f3ab62a0151900761cd12760d34f
[preflight] Running pre-flight checks
[prefligt] All pre-flight checks were passed
[karmada-agent-start] Waiting to perform the TLS Bootstrap
[karmada-agent-start] Waiting to construct karmada-agent kubeconfig
[karmada-agent-start] Waiting the necessary secret and RBAC
[karmada-agent-start] Waiting karmada-agent Deployment
W0303 13:35:48.478036 21025 check.go:52] Pod: karmada-agent-5477cc77f7-qhfk4 not ready. status: ContainerCreating
...
I0303 13:36:34.484207 21025 check.go:49] pod: karmada-agent-5477cc77f7-qhfk4 is ready. status: Running
cluster(cluster1) is joined successfully
回到 karmada 查看,集群已经注册上了。
[root@lixd-tmp-1 ~]# kubectl --kubeconfig /etc/karmada/karmada-apiserver.config get clusters
NAME VERSION MODE READY AGE
cluster1 v1.23.6 Pull True 72s
cluster2 v1.23.6 Push True 3m
小结
- Push 模式是由 karmada 主动向 member 集群 apiserver 推送数据
- Pull 模式则是在 member 集群部署了 karmada-agent,由该 agent 主动向 karmada 拉取数据。
对比:
- 网络方面:Push 模式需要 karmada 能访问所有 member 集群 apiserver,Pull 模式需要 member 集群能访问 karmada apiserver 即可。
- 之前的 push 模式注册的集群显示没有 Ready 就是因为无法访问导致的。
- 效率方面:当规模较大时 Push 模式由于需要想所有 member 集群推送数据,可能效率会比较低。
4. 应用分发
前面已经分别使用 push 和 pull 模式添加了两个集群到 karmada 了,接下来就简单体验一下 karmada 是如何管理多集群应用的。
在这之前简单给大家讲解一下 Karmada 的运行逻辑:
我们只需要把平时 apply 到 kube-apiserver 的 资源对象 全部 apply 到 karmada-apiserver,然后搭配上 karmada 中的 CRD 对象 PropagationPolicy 即可完成多集群应用管理,Karmada 就会根据 PropagationPolicy 中指定的规则,将这些资源对象分发到各个集群里。
比如使用 PropagationPolicy 指定将某个 deploy 分发到 cluster1 和 cluster2
同时 Karmada 还提供了 OverridePolicy CR 对象,用于在不同集群间实现差异化分发。
比如 cluster1 为测试集群,那么可以通过 OverridePolicy 指定将分发到 cluster1 的资源对象中的 image 字段进行修改,添加 test 标记。
创建 PropagationPolicy
部署之前需要先定义 PropagationPolicy 以告知 karmada 需要把对应对应的资源部署到哪些集群里。
# propagationpolicy.yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: example-policy # The default namespace is `default`.
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx # If no namespace is specified, the namespace is inherited from the parent object scope.
placement:
clusterAffinity:
clusterNames:
- cluster1
- cluster2
这个 PropagationPolicy 表示把 default namespace 下的名叫 nginx 的 deployment 部署到 cluster1 和 cluster2。
将该 PropagationPolicy apply 到 karmada:
# kubectl apply -f propagationpolicy.yaml
kubectl --kubeconfig /etc/karmada/karmada-apiserver.config apply -f propagationpolicy.yaml
创建 deploy
在 defualt namespace 下创建一个名为 name 的 deploy 进行测试:
#kubectl create deployment nginx --image nginx
kubectl --kubeconfig /etc/karmada/karmada-apiserver.config create deployment nginx --image nginx
Karmada 就会根据 propagationpolicy 把我们刚创建的 deploy 分发到 cluster1 和 cluster2 上面。
查看 karmada 里的 deploy 状态
[root@karmada ~]# kubectl --kubeconfig /etc/karmada/karmada-apiserver.config get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 0/1 2 0 35s
去各个集群查看
[root@cluster1 ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 0/1 1 0 43s
[root@cluster2 ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 0/1 1 0 48s
等启动完成后再次查看 karmada 中的 deploy 状态
[root@karmada ~]# kubectl --kubeconfig /etc/karmada/karmada-apiserver.config get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 2/1 2 2 3m
cluster1 和 cluster2 都启动了一个,所以 karmada 这里显示的是 ready 2/1
创建 OverridePolicy
创建一个 OverridePolicy,把 cluster1 的镜像 tag 替换为 1.20
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
name: example
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
labelSelector:
matchLabels:
app: nginx
overrideRules:
- targetCluster:
clusterNames:
- cluster1
overriders:
imageOverrider:
- component: Tag
operator: replace
value: '1.20'
kubectl --kubeconfig /etc/karmada/karmada-apiserver.config apply -f op.yaml
然后去 cluster 查看,已经替换成功:
[root@cluster-2 ~]# kubecyl get deploy -oyaml|grep image
- image: nginx:1.20
imagePullPolicy: Always
5. 小结
本文主要记录了如何部署 Karmada 以及 Karmada 的基本使用,包括集群管理和应用分发功能。
部署:karmada 提供了 kubectl 插件 可以一键部署
集群管理:有 pull 和 push 两种模式可选
应用分发:需要创建 PropagationPolicy 以及 OverridePolicy 对象告知 karmada 如何进行应用分发
简单来说就是以前往 kube-apiserver 发请求创建 deploy、service 等对象,使用 karmada 之后就往 karmada-apiserver 创建这些对象,然后通过分发策略告知 karmada 需要将这些资源分发到哪些集群里,然后 karmada 就会往对应集群里写入这些资源对象了。
关于 Karmada 原理可以期待后续文章~