百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

kube on kube 实现思路分享(kube-scheduler)

liuian 2025-05-09 20:03 5 浏览

这里的 kube on kube , 是指建立 K8s 元集群,纳管其他业务 K8s 集群,通过声明式 API 管理集群的创建、增删节点等。

参考
https://github.com/kubean-io/kubean 源码进行编写,进行了裁剪。感谢
DaoCloud 开源!

背景

随着容器化覆盖率的逐步增加,越来越多的业务迁移到 K8s 集群中, 考虑到同城双活、不同业务的复杂性以及耦合度,需要部署维护多套 K8s 集群,如何高效、可靠的在数据中心管理多个 k8s 集群是我们面临的关键挑战。

以前集群的部署和扩缩容主要通过ansible编排任务,黑屏化操作、配置集群的inventoryvars执行ansible playbook

Kube on kube 整体架构

kubeonkube-controller 需要运行在一个已存在的 Kubernetes 集群,通过应用 kubeonkube-controller 提供的标准 CRD 资源和 Kubernetes 内建资源来控制和管理集群的生命周期(安装、卸载、升级、扩容、缩容等)。kubeonkube-controller 采用 ansible-playbook 作为底层技术依赖,一方面简化了集群部署的操作流程,降低了用户的使用门槛。另一方面在 ansibel-playbook 能力基础上增加了集群操作记录等。

控制器介绍:

  • Cluster Controller: 监视 Cluster Objects。唯一标识一个集群,拥有集群节点的访问信息、类型信息、部署参数信息,并且关联所有对此集群的操作(ClusterOperation Objects);
  • ClusterOperation Controller: 监视 ClusterOperation Objects。当 ClusterOperation Object 被创建时,控制器会组装一个 Job 去执行 CRD 对象里定义的操作;

kubeonkube-controller 执行流程

前置步骤说明:

需要提前创建好hosts-conf config(主机清单)、 vars-conf configmap(配置参数)、ssh-auth secret(SSH 私钥) 三个资源对象。

Cluster Controller 执行流程分析:

  1. 集群管理员或者容器平台触发创建Cluster 的CR,去定义当前集群的Spec。
  2. Cluster Contorller 感知到变化进行调谐。
  • 判断 Cluster 是否存在
  • 判断是否有多余的 Cluster Operation 对象需要清理
  • 更行 Cluster 状态,记录 Cluster Operator 的执行情况
  • 更新 hosts-conf / vars-conf / ssh-auth 的 ownerReferences 变为当前 Cluster 信息
  • 循环监听,当有新的 ClusterOps 任务进来后,继续记录 Cluster Operator 的执行情况等

ClusterOperation Controller 执行流程分析:

ClusterOperation 对象由 ClusterOps 别名。

  1. 集群管理员或者容器平台触发创建ClusterOperation 的CR,去定义当前 ClusterOperation 的Spec。
  2. ClusterOperation Contorller 感知到变化进行调谐(看图吧,太多了,看后面源码也行)。https://github.com/clay-wangzhi/kube-on-kube/blob/master/internal/controller/kubeonkube/clusteroperation_controller.go#L75
  3. Job Pod 创建,执行具体的 创建集群、增加节点等任务。
  4. 执行完成,返回状态,确定成功或失败,Cluster 和 ClusterOperation 都会记录状态及开始结束时间。

源码编写过程

环境说明

kubebuilder 3.10.0
go 1.20.3
  1. 初始化
kubebuilder init --domain clay.io --owner Clay --repo kube-on-kube
kubebuilder edit --multigroup=true
kubebuilder create api --group kubeonkube --version v1alpha1 --kind Cluster
Create Resource [y/n]
y
Create Controller [y/n]
y
kubebuilder create api --group kubeonkube --version v1alpha1 --kind ClusterOperation
Create Resource [y/n]
y
Create Controller [y/n]
y
  1. 改配置 Makefile 中 k8s 版本改为ENVTEST_K8S_VERSION = 1.18.10
make manifests
go mod vendor
  1. 定义 CRD 结构体,改完 make
  2. 新增 clientset,informer,lister
# 1. 新增 hack/tools.go 文件,安装依赖包,参考 https://github.com/kubernetes/sample-controller/blob/master/hack/tools.go
go get k8s.io/code-generator@v0.26.1
go mod vendor
chmod +x vendor/k8s.io/code-generator/generate-groups.sh
# 2. 新增hack/update-codegen.sh,参考 https://github.com/kubernetes/sample-controller/blob/master/hack/update-codegen.sh
注意修改几个变量:

MODULE和go.mod保持一致
API_PKG=api #和api目录保持一致
OUTPUT_PKG=generated #和生成Resource时指定的group一样
GROUP_VERSION=kubeonkube:v1alpha1 #和生成Resource时指定的group version对应

# 3. 新增 hack/verify-codegen.sh , 参考 https://github.com/kubernetes/sample-controller/blob/master/hack/verify-codegen.sh

# 4. 改type
添加上tag // +genclient
新增 doc.go
新增 register.go

chmod +x ./hack/update-codegen.sh
./hack/update-codegen.sh
  1. 编写调谐代码,改完,make install, 安装 crd
# 需要再本地配置 kubeconfig 
make install
# 实际执行的是, 可以导出 crd 文件,在其他集群上 apply
kustomize build config/crd | kubectl apply -f -
  1. make run 临时测试,安装 controller
make run
  1. 将 controller 封装成镜像,并进行镜像上传 Dockerfile 如下
# Build the manager binary
FROM golang:1.20 as builder
ARG TARGETOS
ARG TARGETARCH
ENV GOPROXY="https://goproxy.cn"

WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go mod download

# Copy the go source
COPY cmd/main.go cmd/main.go
COPY api/ api/
COPY pkg/ pkg/
COPY generated/ generated/
COPY internal/ internal/
COPY vendor/ vendor/

# Build
# the GOARCH has not a default value to allow the binary be built according to the host where the command
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532

ENTRYPOINT ["/manager"]
# 镜像打包上传
docker build -t wangzhichidocker/kubeonkube-controller:v0.1 .
docker push wangzhichidocker/kubeonkube-controller:v0.1
  1. 将 ansible-playbook 的运行环境封装成镜像,Dockerfile 如下
# syntax=docker/dockerfile:1

# Use imutable image tags rather than mutable tags (like ubuntu:22.04)
FROM ubuntu:22.04@sha256:149d67e29f765f4db62aa52161009e99e389544e25a8f43c8c89d4a445a7ca37

# Some tools like yamllint need this
# Pip needs this as well at the moment to install ansible
# (and potentially other packages)
# See: https://github.com/pypa/pip/issues/10219
ENV LANG=C.UTF-8 \
DEBIAN_FRONTEND=noninteractive \
PYTHONDONTWRITEBYTECODE=1

WORKDIR /kubespray

# hadolint ignore=DL3008
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
apt-get update -q \
&& apt-get install -yq --no-install-recommends \
curl \
python3 \
python3-pip \
python3-dev \
gcc \
sshpass \
vim \
rsync \
openssh-client \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /var/log/*


RUN --mount=type=bind,source=requirements.txt,target=requirements.txt \
--mount=type=cache,sharing=locked,id=pipcache,mode=0777,target=/root/.cache/pip \
pip install --no-compile --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ \
&& find /usr -type d -name '*__pycache__' -prune -exec rm -rf {} \;


COPY *.yml ./
COPY *.cfg ./
COPY roles ./roles
# 镜像打包上传
docker build -t wangzhichidocker/kubeonkube:v0.1 .
docker push wangzhichidocker/kubeonkube:v0.1
  1. 在其他集群安装
# 生成 crd 
bin/kustomize build config/crd > deploy/crd.yaml
# 生成 rbac, rbac 中roles 和 rolebing 没有指定 ns,需要修改, secrect、cm、job 权限需要添加
bin/kustomize build config/rbac > deploy/rbac.yaml
# 生成 deployment,需要改镜像
bin/kustomize build config/manager > deploy/deployment.yaml
# 部署
kubectl apply -f crd.yaml
kubectl apply -f deployment.yaml
kubectl apply -f rbac.yaml
  1. 测试,安装 cluster yaml 和 clusterops yaml

准备配置文件 SSHAuthSec.yml、HostsConfCM.yml、VarsConfCM.yml

SSHAuthSec.yml

kubectl -n kubeonkube create secret generic sample-ssh-auth --type='kubernetes.io/ssh-auth' --from-file=ssh-privatekey=/home/clay/.ssh/id_rsa --dry-run=client -o yaml > SSHAuthSec.yml 

HostsConfCM.yml

apiVersion: v1
kind: ConfigMap
metadata:
name: sample-hosts-conf
namespace: kubeonkube
data:
hosts.yml: |
all:
hosts:
master01:
ip: 10.100.xx.xx
access_ip: 10.100.xx.xx
ansible_host: 10.100.xx.xx
ansible_user: root
worker01:
ip: 10.100.xx.xx
access_ip: 10.100.xx.xx
ansible_host: 10.100.xx.xx
ansible_user: root
children:
kube_control_plane:
hosts:
master01:
kube_node:
hosts:
worker01:

准备 VarsConfCM.yml,根据实际情况,填写变量文件

准备 Cluster.yml

apiVersion: kubeonkube.clay.io/v1alpha1
kind: Cluster
metadata:
name: sample
namespace: kubeonkube
spec:
hostsConfRef:
namespace: kubeonkube
name: sample-hosts-conf
varsConfRef:
namespace: kubeonkube
name: sample-vars-conf
sshAuthRef:
namespace: kubeonkube
name: sample-ssh-auth

准备 ClusterOperation.yml

apiVersion: kubeonkube.clay.io/v1alpha1
kind: ClusterOperation
metadata:
name: sample-node-add
namespace: kubeonkube
spec:
cluster: sample
image: wangzhichidocker/kubeonkube:v0.1
actionType: playbook
action: scale.yml
  1. 将以上 Yaml 文件,apply 执行即可。

源码编写过程,可以参考 commit 进行串联:
https://github.com/clay-wangzhi/kube-on-kube

参考:

  • kubean:https://github.com/kubean-io/kubean
  • vivo大规模 Kubernetes 集群自动化运维实践:https://mp.weixin.qq.com/s/L9z1xLXUnz52etw2jDkDkw

相关推荐

GCI: Another key public good for international community

MembersofadelegationofhighschoolstudentsfromtheU.S.stateofWashingtonposeforaphotoa...

kube on kube 实现思路分享(kube-scheduler)

这里的kubeonkube,是指建立K8s元集群,纳管其他业务K8s集群,通过声明式API管理集群的创建、增删节点等。参考https://github.com/kubean-i...

China and India hold the key to a more inclusive global future

ByMayaMajueranLead:AsChinaandIndiamark75yearsofdiplomaticties,theircooperationcouldse...

日本真子公主的婚礼又要提上日程了吗?未婚夫:债务问题已解决

日本明仁天皇将于今年3月31日退位,德仁皇太子即将成为新一任的天皇。在平成时代最后的倒计时中,明仁天皇的孙女真子公主的婚事却又一次进入了人们的视野。(viaTheTelegraph)关注日本皇室的...

kratos源码分析系列(1)(kvm源码解析与应用 pdf)

https://github.com/go-kratos/kratos是b站开源的一个微服务框架,整体来看它结合grpc生态中的grpc-gateway,以及wire依赖注入和众多常用的trace,m...

【2.C#基础】6.循环语句(c#循环语句例子)

6.循环语句当需要多次执行同一个处理时,就需要用到循环语句。一般情况下,循环的流程图如下:6.1while循环C#中的while循环语句在给定的条件为真的情况下会重复执行目标语句。格式如下:...

使用 Google Wire 在 Go 中进行依赖注入

关注点分离、松耦合系统和依赖反转原则等概念在软件工程中是众所周知的,并且在创建良好的计算机程序过程中至关重要。在本文中,我们将讨论一个同时应用了这三个原则的技术,称为依赖注入。我们将尽可能地实践,更加...

用 Golang封装你的API(golang封装dll)
用 Golang封装你的API(golang封装dll)

每日分享最新,最流行的软件开发知识与最新行业趋势,希望大家能够一键三连,多多支持,跪求关注,点赞,留言。@头条创作挑战赛本文探讨了在用Golang封装你的API的过程以及几个不同的编程步骤。我做了一个非常有限的时间来证明如何为客户正在开...

2025-05-09 20:03 liuian

Terraform 实战 | 万字长文(terrify是什么意思中文)

Terraform是什么Terraform(https://www.terraform.io/)是HashiCorp旗下的一款开源(Go语言开发)的DevOps基础架构资源管理运维工具,可...

Go 语言入门:环境安装(go语言安装 window)

一、前言这里不同于其他人的Go语言入门,环境安装我向来注重配置,比如依赖包、缓存的默认目录。因为前期不弄好,后面要整理又影响这影响那的,所以就干脆写成文章,方便后期捡起。二、安装1.安装包htt...

Go语言进阶之Go语言高性能Web框架Iris项目实战-项目结构优化EP05

前文再续,上一回我们完成了用户管理模块的CURD(增删改查)功能,功能层面,无甚大观,但有一个结构性的缺陷显而易见,那就是项目结构过度耦合,项目的耦合性(Coupling),也叫耦合度,进而言之,模块...

如何将Go项目与Docker结合实现高效部署

在现代软件开发中,使用Docker部署应用程序已经成为一种标准实践。本文将深入探讨如何将Go项目与Docker结合,实现高效、可靠的部署过程。通过详细的步骤和丰富的示例,你将能够迅速掌握这一流程。准备...

五分钟轻松熟悉一个k8s Operator应用制作

简介:operator是一种kubernetes的扩展形式,可以帮助用户以Kubernetes的声明式API风格自定义来管理应用及服务,operator已经成为分布式应用在k8s集群部...

程序员的副业秘籍!一款可以快速搭建各类系统的后台管理系统

系统简介这是一个基于Gin+Vue+ElementUI(或ArcoDesign、AntDesign)的系统快速开发平台,采用了前后端分离,旨在帮助用户快速完成各类系统的基础功能搭建。平...

使用 Go 语言开发区块链钱包的项目目录结构设计

在开发区块链钱包时,项目的目录结构应该清晰、模块化,确保代码的可维护性和扩展性。基于Go的惯例,结合区块链钱包的功能需求,以下是一个较为合理的目录结构示例:1.目录结构blockchain-wa...