k8s--kind 搭建 k8s 集群
介绍
Kind是一个使用 Docker 容器“节点”运行本地 Kubernetes 集群的工具。它主要用于测试 Kubernetes 本身,但也可用于本地开发或CI。顾名思义,就是将 Kubernetes 所需要的所有组件,全部部署在一个 Docker 容器中,可以很方便的搭建 Kubernetes 集群。
将 docker 容器作为一个 kubernetes 的 "node",并在该 "node" 中安装 kubernetes 组件
Kind 使用一个 container 来模拟一个 node,在 container 里面跑了 systemd ,并用 systemd 托管了 kubelet 以及 containerd,然后容器内部的 kubelet 把其他 Kubernetes 组件,比如 kube-apiserver,etcd,cni 等组件跑起来。
可以通过配置文件的方式,来通过创建多个 container 的方式,来模拟创建多个 Node,并以这些 Node 来构建一个多节点的 Kubernetes 集群。
Kind 内部使用了 kubeadm 这个工具来做集群的部署,包括 ha master 的高可用集群,也是借助 kubeadm 提供的aplha特性提供的。同时,在 ha master 下,额外部署了一个 nginx 用来提供负载均衡 vip。
在使用 kind 搭建 k8s 集群时,需要先安装好 docker 和 go
安装 kind
安装 kind
// 安装 kind,这里安装的是 v0.17.0
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.17.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
安装完成之后,查看 kind 的版本
[root@dce88 ~]# kind --version
kind version 0.17.0
使用 kind 创建集群
使用下面命令就可以创建一个 kind 集群
kind create cluster
[root@dce88 ~]# kind create cluster
Creating cluster "kind" ...
✓ Ensuring node image (kindest/node:v1.24.0) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:
kubectl cluster-info --context kind-kind
Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
上面我们已经安装好了 kind,接下来就可以使用 kind 搭建 k8s 集群了
解析安装过程
- 检查本地环境是否存在一个基础的安装镜像,默认是 kindest/node:v1.24.0,该镜像里面包含了所有需要安装的东西,包括:kubectl、kubeadm、kubelet 的二进制文件,以及安装对应版本 kubernetes 所需要的镜像
- 准备 kubernetes 节点,主要就是启动容器,解压镜像这类的操作
- 建立对应的 kubeadm 的配置,完成之后就通过 kubeadm 进行安装。安装完成后还会做一些清理操作,比如:删除主节点上的污点,否则对于没有容忍的 pod 无法完成部署
- 上面所有操作都完成后,就成功启动了一个 kubernetes 集群并输出一些操作集群的提示信息
默认情况下,kind 会先下载 kindest/node:v1.24.0 镜像。如果你想指定不同的版本,可以使用
--image
参数。类似于这样:kind create cluster --image=kindest/node:v1.21.1,kindest/node 这个镜像目前托管于 Docker Hub 上,下载时可能会比较慢,可以设置一个镜像加速器
安装完成之后执行 docker ps 查看下,可以看到新起了一个镜像
使用不同的 image
允许您更改创建的集群的 Kubernetes
版本
指定集群名称
默认情况下,集群将被命名为 name kind
。使用该--name
标志为集群分配不同的上下文名称
# 使用 --name 指定名称
[root@dce88 ~]# kind create cluster --name zouzou
Creating cluster "zouzou" ...
✓ Ensuring node image (kindest/node:v1.24.0) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-zouzou"
You can now use your cluster with:
kubectl cluster-info --context kind-zouzou
Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
默认情况下,如果未设置 $KUBECONFIG 环境变量,则集群访问配置存储在 ${HOME}/.kube/config 中
查看集群
要查看您创建的所有集群,您可以使用该kind get clusters
命令,上面我们已经创建了两个 kind 集群,执行命令看下输出
[root@dce88 ~]# kind get clusters
kind
zouzou
查看集群信息
查看集群我们需要进入到 docker 容器里面
# 查看 容器 id
[root@dce88 ~]# docker ps | grep kind
4793d90956bb kindest/node:v1.24.0 "/usr/local/bin/entr…" 10 minutes ago Up 10 minutes 127.0.0.1:45242->6443/tcp zouzou-control-plane
e50ae2c69984 kindest/node:v1.24.0 "/usr/local/bin/entr…" 15 minutes ago Up 15 minutes 127.0.0.1:34334->6443/tcp kind-control-plane
# 进入到 docker 容器里面
[root@dce88 ~]# docker exec -it 4793d90956bb /bin/bash
# 查看节点,可以看到,是单节点的
root@zouzou-control-plane:/# kubectl get node
NAME STATUS ROLES AGE VERSION
zouzou-control-plane Ready control-plane 10m v1.24.0
# 查看 pod
root@zouzou-control-plane:/# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6d4b75cb6d-fth7d 1/1 Running 0 10m
coredns-6d4b75cb6d-hcrfm 1/1 Running 0 10m
etcd-zouzou-control-plane 1/1 Running 0 10m
kindnet-frkjw 1/1 Running 0 10m
kube-apiserver-zouzou-control-plane 1/1 Running 0 10m
kube-controller-manager-zouzou-control-plane 1/1 Running 0 10m
kube-proxy-2wmdx 1/1 Running 0 10m
kube-scheduler-zouzou-control-plane 1/1 Running 0 10m
切换集群
上面我们是进入到容器里面查看的集群信息,我们可以使用 kubectl 来切换集群,首先要保证你的集群上安装了 kubectl,安装教程:https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-linux/
安装完成之后确保输入 kubectl 控制台有输出
上面我们已经搭建好了两个集群
[root@dce88 ~]# kind get clusters
kind
zouzou
以使用如下命令分别切换到集群kind
和zouzou
# kubectl cluster-info --context kind-kind
# kubectl cluster-info --context kind-zouzou
删除集群
创建了一个集群使用kind create cluster
那么删除同样简单,使用
# 删除集群,--name如果未指定标志,则 kind 将使用默认集群上下文名称kind并删除该集群
kind delete cluster
例如删除我们上面创建的集群,删除没有指定名称的
[root@dce88 ~]# docker ps | grep kind
4793d90956bb kindest/node:v1.24.0 "/usr/local/bin/entr…" 14 minutes ago Up 14 minutes 127.0.0.1:45242->6443/tcp zouzou-control-plane
e50ae2c69984 kindest/node:v1.24.0 "/usr/local/bin/entr…" 19 minutes ago Up 19 minutes 127.0.0.1:34334->6443/tcp kind-control-plane
# 删除集群
[root@dce88 ~]# kind delete cluster
Deleting cluster "kind" ...
# 在查看,已经被删除了
[root@dce88 ~]# docker ps | grep kind
4793d90956bb kindest/node:v1.24.0 "/usr/local/bin/entr…" 15 minutes ago Up 15 minutes 127.0.0.1:45242->6443/tcp zouzou-control-plane
删除指定名称的集群
[root@dce88 ~]# docker ps | grep kind
4793d90956bb kindest/node:v1.24.0 "/usr/local/bin/entr…" 18 minutes ago Up 18 minutes 127.0.0.1:45242->6443/tcp zouzou-control-plane
# 删除名称为 zouzou 的集群
[root@dce88 ~]# kind delete cluster --name=zouzou
Deleting cluster "zouzou" ...
# 在查看已经没有了
[root@dce88 ~]# docker ps | grep kind
将 docker 镜像 load 到 kind 集群里
kind 提供了将 docker 镜像加载到集群每个 node 节点上的操作命令,加载镜像之后,集群的每个节点都会具备该镜像文件,就不需要再从 docker hub 仓库 pull了,节约了下载带宽资源。当然,你使用 kubectl 命令创建 pod 也能够下载对应镜像,重复拉取镜像会拖慢 pod 创建速度。
创建集群
# 创建个 zouzou 的集群
kind create cluster --name zouzou
查看集群
[root@dce88 ~]# docker ps | grep kind
137642ca3186 kindest/node:v1.24.0 "/usr/local/bin/entr…" 2 minutes ago Up 2 minutes 127.0.0.1:42869->6443/tcp zouzou-control-plane
查看本地镜像,我本地有个 nginx 的镜像
[root@dce88 ~]# docker images | grep nginx
nginx latest 55f4b40fe486 2 weeks ago 142MB
先查看 kind 集群里是否有 nginx 镜像,从结果可以看出来是没有 nginx 镜像的
# zouzou-control-plane 这里要使用容器的名称,不能直接写 zouzou,zouzou 是 kind 的,不是 docker 的
[root@dce88 ~]# docker exec -it zouzou-control-plane crictl images
IMAGE TAG IMAGE ID SIZE
docker.io/goharbor/nginx-photon v2.5.1 c4c8eef437164 45MB
docker.io/kindest/kindnetd v20220510-4929dd75 6fb66cd78abfe 45.2MB
docker.io/kindest/local-path-helper v20220512-507ff70b 64623e9d887d3 2.86MB
docker.io/kindest/local-path-provisioner v0.0.22-kind.0 4c1e997385b8f 17.4MB
k8s.gcr.io/coredns/coredns v1.8.6 a4ca41631cc7a 13.6MB
k8s.gcr.io/etcd 3.5.3-0 aebe758cef4cd 102MB
k8s.gcr.io/kube-apiserver v1.24.0 9ef4b1de3be49 77.3MB
k8s.gcr.io/kube-controller-manager v1.24.0 efa8a439d1460 65.6MB
k8s.gcr.io/kube-proxy v1.24.0 6960c0e47829d 112MB
k8s.gcr.io/kube-scheduler v1.24.0 41f5241e3396e 52.3MB
k8s.gcr.io/pause 3.6 6270bb605e12e 302kB
然后将 docker 镜像 load 进 kind 集群里面
# 这里使用的是 kind 的名称 zouzou,将 nginx:latest 放到集群里面
[root@dce88 ~]# kind load docker-image nginx:latest --name zouzou
Image: "nginx:latest" with ID "sha256:55f4b40fe486a5b734b46bb7bf28f52fa31426bf23be068c8e7b19e58d9b8deb" not yet present on node "zouzou-control-plane", loading...
在查看 kind 集群里的镜像
# 可以看到有了,crictl 会显示仓库
[root@dce88 ~]# docker exec -it zouzou-control-plane crictl images
IMAGE TAG IMAGE ID SIZE
docker.io/goharbor/nginx-photon v2.5.1 c4c8eef437164 45MB
docker.io/kindest/kindnetd v20220510-4929dd75 6fb66cd78abfe 45.2MB
docker.io/kindest/local-path-helper v20220512-507ff70b 64623e9d887d3 2.86MB
docker.io/kindest/local-path-provisioner v0.0.22-kind.0 4c1e997385b8f 17.4MB
docker.io/library/nginx latest 55f4b40fe486a 146MB # 这个
k8s.gcr.io/coredns/coredns v1.8.6 a4ca41631cc7a 13.6MB
k8s.gcr.io/etcd 3.5.3-0 aebe758cef4cd 102MB
k8s.gcr.io/kube-apiserver v1.24.0 9ef4b1de3be49 77.3MB
k8s.gcr.io/kube-controller-manager v1.24.0 efa8a439d1460 65.6MB
k8s.gcr.io/kube-proxy v1.24.0 6960c0e47829d 112MB
k8s.gcr.io/kube-scheduler v1.24.0 41f5241e3396e 52.3MB
k8s.gcr.io/pause 3.6 6270bb605e12e 302kB
crictl 是 CRI 兼容的容器 runtime 命令行工具。在 kind 的 Kubernetes 集群节点上没有安装 docker 命令行工具,而是安装了 Kubernetes 的 crictl 工具。
安装多节点集群
上面我们创建的是单节点的集群,默认安装的集群只部署了一个控制节点,如果需要部署多节点集群,我们可以通过配置文件的方式来创建多个容器。这样就可以达到模拟多个节点的目的,并以这些节点来构建一个多节点的 kubernetes 集群
创建多节点 kubernetes 集群配置文件
kind 在创建集群的时候,支持通过 --config 参数传递配置文件给 kind,配置文件可修改的内容主要有 role 和 节点使用的镜像
创建一个 test1.yaml 的文件,内容如下
kind: Cluster
# 一共两个节点,一个主节点,一个从节点
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane # 主节点
- role: worker # 从节点
配置文件创建完成后,就可以使用下面的命令来完成多节点 Kubernetes 集群搭建。
# --config 指定 yaml 文件的路径
[root@dce88 ~]# kind create cluster --config=test1.yaml --name=my-cluster1
Creating cluster "my-cluster1" ...
✓ Ensuring node image (kindest/node:v1.24.0) 🖼
✓ Preparing nodes 📦 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
✓ Joining worker nodes 🚜
Set kubectl context to "kind-my-cluster1"
You can now use your cluster with:
kubectl cluster-info --context kind-my-cluster1
Thanks for using kind! 😊
使用 docker ps 就可以看到有两个容器在运行
进入到控制容器里面,查看节点信息
# 进入到控制节点容器里面
[root@dce88 ~]# docker exec -it da29f8c9c469 /bin/bash
root@my-cluster1-control-plane:/#
# 查看 node
root@my-cluster1-control-plane:/# kubectl get node
NAME STATUS ROLES AGE VERSION
my-cluster1-control-plane Ready control-plane 6m57s v1.24.0
my-cluster1-worker Ready <none> 6m33s v1.24.0
删除集群
# 执行后,两个 docker 容器都会被删除
[root@dce88 ~]# kind delete cluster --name=my-cluster1
[root@dce88 ~]# docker ps | grep kind
创建高可用的 k8s 集群
上面创建了一个控制节点,一个 work 节点,我们也可以创建高可用的 k8s 集群,创建一个 test2.yaml 文件,代码如下
一共六个节点,三个 control-plane 节点,三个 workers 节点
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
kubeadmConfigPatches:
- |
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
metadata:
name: config
networking:
serviceSubnet: 10.0.0.0/16
imageRepository: registry.aliyuncs.com/google_containers
nodeRegistration:
kubeletExtraArgs:
pod-infra-container-image: registry.aliyuncs.com/google_containers/pause:3.1
- |
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
metadata:
name: config
networking:
serviceSubnet: 10.0.0.0/16
imageRepository: registry.aliyuncs.com/google_containers
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker
创建集群
[root@dce88 ~]# kind create cluster --config=test2.yaml --name=my-cluuster2
Creating cluster "my-cluuster2" ...
✓ Ensuring node image (kindest/node:v1.24.0) 🖼
✓ Preparing nodes 📦 📦 📦 📦 📦 📦
✓ Configuring the external load balancer ⚖️
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
✓ Joining more control-plane nodes 🎮
✓ Joining worker nodes 🚜
Set kubectl context to "kind-my-cluuster2"
You can now use your cluster with:
kubectl cluster-info --context kind-my-cluuster2
Thanks for using kind! 😊
查看容器