云原生多云容器编排平台 karmada 上手指南
karmada 是华为开源的云原生多云容器编排平台,目标是让开发者像使用单个 k8s 集群一样使用多 k8s 云。它的第一个 release(v0.1.0)出现在 2020 年 12 月,而正式发布则是在 2021 年 4 月 25 日,在深圳召开的华为开发者大会(HDC.Cloud)2021 上。
karmada 吸取了 CNCF 社区的 Federation v1 和 v2(也称为 kubefed)项目经验与教训,在保持原有 k8s 资源定义 API 不变的情况下,通过添加与分布式工作负载部署管理相关的一套新的 API 和控制面组件,方便用户将工作负载部署到多云环境中,实现扩容、高可用等目标。
官方网站:https://karmada.io/
代码地址:https://github.com/karmada-io/karmada
使用 karmada 管理的多云环境包含两类集群:
host 集群:即由 karmada 控制面构成的集群,接受用户提交的工作负载部署需求,将之同步到 member 集群,并从 member 集群同步工作负载后续的运行状况。
member 集群:由一个或多个 k8s 集群构成,负责运行用户提交的工作负载
架构图如下:
本文描述 karmada 的上手流程,使用的 karmada 版本为 v0.7.0 后的 commit:c4835e1f,与 8 月发布的 v0.8.0 差了二十几个 commit。
1. karmada 安装
1.1. 安装 docker
按照 docker 官网文档在本机安装 docker,对 debian 来说流程如下:
安装基础工具
安装 docker 的 gpg key:
安装 docker 源
安装 docker
1.2. 安装简易 k8s 开发集群管理工具:kind
kind 官网对其描述:kind is a tool for running local Kubernetes clusters using Docker container “nodes”. kind was primarily designed for testing Kubernetes itself, but may be used for local development or CI.
在本地已经安装好 go (1.11 以上) 和 docker 的情况下,执行下面指令安装 kind:
0.11.1 是当前 kind 最新的 release 的,也是后续部署 karmada 过程中指定要用的版本
kind 使用一个容器来模拟一个 node,在容器内部使用 systemd 托管 kubelet 和 containerd(不是 docker),然后通过被托管的 kubelet 启动其他 k8s 组件,比如 kube-apiserver、etcd、CNI 等跑起来。
由于 kind 使用 containerd 而非 docker 作为容器运行时,要查看 kind 启动的 k8s 节点内部容器运行情况,需要使用 containerd 的 cli 客户端ctr
。可以通过下面这条命令查看后续步骤中 karmada 调用 kind 启动的单节点 k8s 集群内部容器的运行情况:docker exec karmada-host-control-plane ctr --namespace k8s.io containers ls
。
ctr 的 flag
--namespace
不是 k8s 里的 namespace,也不是 linux 内核支持的 namespace,感兴趣的同学可以查看 containerd 的 namespace 相关概念
1.3. 启动本地 k8s 集群,安装 karmada 控制面
1.确保已经安装 make、gcc 工具
2.确保已经安装 kubectl,可以参考官方文档采用手动安装或包管理器的方式安装
3.clone karmada 源码: git clone https://github.com/karmada-io/karmada.git karmada-io/karmada
4.cd karmada-io/karmada
5.hack/local-up-karmada.sh
,这里包含一系列步骤:
1)检查 go、kind 等工具是否已经存在
2)调用 kind 创建 host k8s 集群,集群版本默认为 1.19.1,与 karmada 重用的 k8s 组件(kube-apiserver、kube-controllermanager)版本一致 。创建 k8s 集群需要的 kindest/node:v1.19.1 镜像较大,可以提前下载好,防止后续的local-up-karmada
等待集群启动超时(默认 5 分钟)
3)build karmada 控制面可执行文件及容器镜像,build 结束后本地可以找到如下镜像:karmada-agent、karmada-webhook、karmada-scheduler、karmada-controller-manager
4)部署 karmada 控制面组件到 host 集群
5)创建 CRD,也就是 karmada 自定义的多云工作负载 API 资源,包含:propgation policy,override policy,work,resource binding 等
6)创建 webhook
7)部署完成后,形成 kubeconfig 文件$HOME/kube/karmada.config
,包含 karmada-host 和 karmada-apiserver 两个 context,分别对应支撑 karmada 控制面运行的 host 集群,以及 karmada 控制面本身
注意:karmada 还提供了 remote-up-karmada.sh 脚本,用以把一个现有的 k8s 集群加入联邦。感兴趣的读者可以阅读 karmada 项目的 readme 尝试
2. karmada 控制面构成
部署 karmada 完成后,在切换到karmada-host
context 后,执行kubectl get po --all-namespaces
可以得到已经部署的组件列表:
可以看到部署在两个 namespace 中的两个 k8s 控制面:
karmada-host
context 对应的控制面运行在kube-system
namespace 中,用来运行管理 karmada 控制面,是个由 kind 启动的标准的 k8s 管理节点。karmada-apiserver
context 对应的控制面运行在karmada-system
namespace 中,是 karmada 控制面,也就是 karmada readme 中提到的 host 集群。它由local-up-karmada.sh
脚本部署到karmada-host
集群中。该控制面重用了 k8s 的两个组件:kube-apiserver
和kube-controllermanager
以及 etcd,其他 3 个为 karmada 组件,包括kamada-controller-manager
、karmada-scheduler
、karmada-webhook
前一个 k8s 集群只是为了支撑 karmada 控制面的运行。所有后续集群联邦相关的操作,包括用 karmadactl 发出的 member 集群管理请求,以及用 kubectl 发出的工作负载管理请求都发往 karmada 控制面。这些请求中创建的 API 资源也保存在 karmada 控制面自身的 etcd 中(对应上面列表中的etcd-0
pod)。
需要注意的是,虽然 karmada 控制面重用了部分 k8s 组件,被重用的 kube-controller-mamager 通过启动 flag 限制其只运行 namespace、garbagecollector、serviceaccount-token、serviceaccount 这几个 controller,所以当用户把Deployment
等 k8s 标准资源提交给 karmada apiserver 时,它们只是被记录在 karmada 控制面的 etcd 中,并在后续同步到 member 集群中,这些Deployment
资源并不会在 karmada 控制面管理的集群中发生 reconcile(如创建 pod)。
3. karmada 使用
用户可以用 karmadactl 和 kubectl 两个 cli 使用 karmada,其中:
1.karmadactl 用来执行 member 集群的加入(joint)/离开(unjoin)、标志一个 member 集群不可调度(cordon)或解除不可调度的标志(uncordon)
2.kubectl 用来向 karmada 集群提交标准的 k8s 资源请求,或由 karmada 定义的 CR 请求。用以管理 karmada 集群中的工作负载。
3.1 使用 karmadactl 管理 member 集群
1.执行hack/create-cluster.sh member1 $HOME/.kube/karmada.config
创建新的集群 member1
2.执行kubectl config use-context karmada-apiserver
切换到 karmada 控制面
3.执行karmadactl join member1 --cluster-kubeconfig=$HOME/.kube/karmada.config
以 push 的方式把 member1 加入 karmada 集群
注意:如果还没有编译过 karmadactl 可执行文件,可以在代码根目录执行 make karmadactl
注意:karmada 中的 host 集群和 member 集群之间的同步方式有 push 和 pull 两种,这里的上手过程采用 push 的方式,感兴趣的读者可以参考 karmada 的 readme 尝试 pull 同步方式
目前 karmadactl 没有 list member 集群的功能,对于已经加入的 member 集群,可以通过获取Cluster
类型的 CR 实现:
得到输出为:
上面的 create-cluster.sh 脚本默认创建最新版的 k8s 集群,为了避免再次拉下一个大镜像,可以修改 create-cluster.sh 脚本,为 kind create cluster 命令加上
--image="kindest/node:v1.19.1"
参数
3.2 使用 kubectl 管理工作负载
karmada 代码里自带一个 nginx 应用可以用来体验基于 karmada 的分布式工作负载管理:
1.执行kubectl config use-context karmada-apiserver
切换到 karmada 控制面
2.执行kubectl create -f samples/nginx/deployment.yaml
创建 deployment 资源如前面所述,由于 kamada 控制面没有部署 deployment controller,nginx 不会在 karmada 控制面所在集群跑起来,而是仅仅保存在 etcd 里这时候如果去 member1 集群查看 pod 资源的情况,可以发现 nginx 也没有在 member1 集群中运行起来
3.执行kubectl create -f samples/nginx/propagationpolicy.yaml
,定义如下的 propgation policy:
这个 progation policy 将之前部署的 nginx deployment 资源(由resourceSelectors
指定)同步到 member1 集群(由placement
指定)中。
这时不用切换到 member1 context,对 karmada 控制面执行kubectl get deploy
可以看到名叫 nginx 的 deployment 已经正常运行:
上述结果说明 karmada 有能力从 member 集群同步工作负载状态到 host 集群。作为验证,我们可以切换到 member1 集群,执行kubectl get po
可以看到 deployment 对应的 nginx pod 已经在 member1 集群内正常运行:
4. 结尾并非结束
在Gartner的一份研究报告中,公有云用户有 81%都采用了多云架构。近年来蓬勃发展的云原生社区对多云挑战给也几次给出自己的思考和解决方案,远有 CNCF 社区 sig multicluster 提出的 Federation v1 和 v2,近有华为开源的 karmada 以及 Red Hat 开源的 Open Cluster Management(OCM)。虽然尚未在 API 层面达成一致,但各开源项目都在吸取前人的经验教训的基础上优化演进。百家争鸣而非闭门造车,这正是开源的魅力所在。
后续我们会对 karmada 项目进行更为深入的分析。
版权声明: 本文为 InfoQ 作者【谐云】的原创文章。
原文链接:【http://xie.infoq.cn/article/cf0a52126ced5a25ecd262f93】。文章转载请联系作者。
评论