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 治理的多云环境蕴含两类集群:
host 集群:即由 karmada 管制面形成的集群,承受用户提交的工作负载部署需要,将之同步到 member 集群,并从 member 集群同步工作负载后续的运行状况。
member 集群:由一个或多个 k8s 集群形成,负责运行用户提交的工作负载
架构图如下:
本文形容 karmada 的上手流程,应用的 karmada 版本为 v0.7.0 后的 commit:c4835e1f,与 8 月公布的 v0.8.0 差了二十几个 commit。
-
karmada 装置
1.1. 装置 docker
依照 docker 官网文档在本机装置 docker,对 debian 来说流程如下:
装置根底工具sudo apt-get update sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release
装置 docker 的 gpg key:
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
装置 docker 源
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
装置 docker
apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io
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:GO111MODULE=on GOPROXY=goproxy.cn go get sigs.k8s.io/kind@v0.11.1
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-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 尝试 -
karmada 管制面形成
部署 karmada 实现后,在切换到 karmada-host context 后,执行 kubectl get po –all-namespaces 能够失去曾经部署的组件列表:NAMESPACE NAME READY STATUS RESTARTS AGE karmada-system etcd-0 1/1 Running 0 98m karmada-system karmada-apiserver-75b5dc6fb7-l6hdv 1/1 Running 0 98m karmada-system karmada-controller-manager-7d66968445-nnnpp 1/1 Running 0 98m karmada-system karmada-kube-controller-manager-5456fd756d-sf9xk 1/1 Running 0 98m karmada-system karmada-scheduler-7c8d678979-bgq4f 1/1 Running 0 98m karmada-system karmada-webhook-5bfd9fb89d-msqnw 1/1 Running 0 98m kube-system coredns-f9fd979d6-4bc2l 1/1 Running 0 99m kube-system coredns-f9fd979d6-s7jc6 1/1 Running 0 99m kube-system etcd-karmada-host-control-plane 1/1 Running 0 99m kube-system kindnet-cq6kv 1/1 Running 0 99m kube-system kube-apiserver-karmada-host-control-plane 1/1 Running 0 99m kube-system kube-controller-manager-karmada-host-control-plane 1/1 Running 0 99m kube-system kube-proxy-ld9t8 1/1 Running 0 99m kube-system kube-scheduler-karmada-host-control-plane 1/1 Running 0 99m local-path-storage local-path-provisioner-78776bfc44-d9fvv 1/1 Running 0 99m
能够看到部署在两个 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)。 -
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 实现:kubectl get clusters
失去输入为:NAME VERSION MODE READY AGE member1 v1.19.1 Push True 88s
下面的 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:apiVersion: policy.karmada.io/v1alpha1 kind: PropagationPolicy metadata: name: nginx-propagation spec: resourceSelectors: - apiVersion: apps/v1 kind: Deployment name: nginx placement: clusterAffinity: clusterNames: - member1
这个 progation policy 将之前部署的 nginx deployment 资源(由 resourceSelectors 指定)同步到 member1 集群(由 placement 指定)中。
这时不必切换到 member1 context,对 karmada 管制面执行 kubectl get deploy 能够看到名叫 nginx 的 deployment 曾经失常运行:NAME READY UP-TO-DATE AVAILABLE AGE nginx 1/1 1 1 21m
上述后果阐明 karmada 有能力从 member 集群同步工作负载状态到 host 集群。作为验证,咱们能够切换到 member1 集群,执行 kubectl get po 能够看到 deployment 对应的 nginx pod 曾经在 member1 集群内失常运行:
NAME READY STATUS RESTARTS AGE nginx-6799fc88d8-7tgmb 1/1 Running 0 8m27s
- 结尾并非完结
在 Gartner 的一份钻研报告中,私有云用户有 81% 都采纳了多云架构。近年来蓬勃发展的云原生社区对多云挑战给也几次给出本人的思考和解决方案,远有 CNCF 社区 sig multicluster 提出的 Federation v1 和 v2,近有华为开源的 karmada 以及 Red Hat 开源的 Open Cluster Management(OCM)。尽管尚未在 API 层面达成统一,但各开源我的项目都在汲取前人的经验教训的根底上优化演进。百家争鸣而非闭门造车,这正是开源的魅力所在。
后续咱们会对 karmada 我的项目进行更为深刻的剖析。