By 胡涛 (@daniel-hutao) | 18.04.2022
从零开始疾速搭建本地 Kubernetes 测试环境
从零开始?从零开始!
var 零 =99 // 别缓和,Just a jok。
Let’s Get Started!
概述
“Kubernetes 集群部署”严格来说是一个简单的技术活,有很多的可选计划。要交付一套聚拢“最佳实际”的高可用集群有很多须要思考的技术细节。对于如何部署“真正高可用的 Kubernetes 集群”不在本文的探讨范畴,所以明天咱们的指标是应用一种简略的形式疾速部署一个可用的 Kubernetes 环境。这套环境次要用于满足 DevStream 的开发测试需要。
疾速部署 Kubernetes 有好几种可选计划,比方 Minikube 和 Kind。Minikube 最先基于虚拟化实现(新版本也反对容器化实现了),也就是通过 virtualbox 或者 kvm 等工具在本地创立若干虚拟机,而后在虚拟机中运行 Kubernetes 集群,一个节点也就对应一台虚拟机。Kind 通过容器化实现,也就是通过 Docker 在本地启动若干容器,每个容器充当 Kubernetes 的一个节点,在容器内再运行容器化利用。本文咱们抉择用 Kind 这种“容器中跑容器”的形式来搭建 Kubernetes 环境。当然如果大家有其余善于的工具,也齐全能够用,咱们的目标仅仅是疾速部署一套可用的 Kubernetes 集群环境。
本文以 macOS 作为开发环境,应用 Linux 或者 Windows 零碎作为开发环境的同学能够参考本文的办法,相应地做一些灵便调整。
Docker 的装置
在 Linux 下装置 Docker 是一件非常简单的事件,Docker 的外围原理就是基于 Linux 的 Namespace 和 Cgroup 等机制。不过在 macOS 和 Windows 下就须要通过虚拟化技术间接应用 Docker 了。当然咱们当初曾经不须要先装置虚拟化软件而后本人装置 Linux 虚拟机,再应用 Docker 了。咱们能够间接在 docker.com 下载 Docker Desktop 来跑 Docker 程序。
咱们在 https://www.docker.com/produc… 寻找适合的 Docker Desktop 版本,次要是看清楚 cpu 架构是 Intel Chip 还是 Apple Chip,前者对应 amd64 架构版本 Mac,后者是 arm 架构的 M1 芯片版本 Mac。下载页面大抵如下:
下载实现后双击 Docker.dmg 文件,能够看到装置页面:
咱们把 Docker 图标拖到 Applications 里,稍等不到半分钟,就能够在“启动台”里看到 Docker 图标了,而后点击“启动台”里的 Docker 关上 Docker Desktop:
稍等几秒钟,就能够看到启动页面了:
咱们能够点击右上角的“齿轮⚙️”按钮来批改 Docker Desktop 的一些配置,比方调整 Docker 能够应用的资源等。如果前面咱们须要启动的容器稍多一些,内存不够用了,能够回到这里来调整,比方我这里把 Memory 调大到 4.00 GB:
批改后记得点击右下角的“Apply & Restart”才会失效。
Kind 介绍
Kind(Kubernetes-in-docker) 是一个应用 Docker 容器作为“节点”实现部署 Kubernetes 集群环境的工具。Kind 工具次要用于 Kubernetes 自身的测试,目前在很多须要部署到 Kubernetes 环境测试的我的项目在 ci 流程中都会抉择用 Kind 来疾速拉起一个 Kubernetes 环境,而后运行相干测试用例。
Kind 自身很简略,只蕴含一个简略的命令行工具“kind”和一个用来启动 Kubernetes 和 systemd 等的 Docker 镜像。咱们能够这样了解 Kind 的原理:它通过 Host 主机上的 Docker 应用封装了 Kubernetes 等工具的容器镜像拉起一个容器,这个容器里运行了 systemd,容器中的 systemd 进一步能够运行 Docker 和 Kubelet 等 Kubernetes 节点所需根底过程,而后这些过程就能够进一步运行 kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、CoreDNS 等集群所需组件,从而一个这样的容器就组成了一个 Kubernetes 集群的“节点”。
所以 Kind 能够通过一个容器运行“单节点 Kubernetes 集群”,也能够进一步通过运行三个或更多容器实现在一台主机上运行一个“多节点 Kubernetes 集群”。
一键搭建 Kind 测试环节
秘籍:
- 下载 DevStream 我的项目主库:https://github.com/devstream-…
- 在 devstream 目录内执行一条命令:
make e2e-up
完结了?完结了。
产生了啥?大家能够关上 Makefile,在外面能够看到 e2e-up 其实是执行了 sh hack/e2e/e2e-up.sh
这个命令,在 e2e-up.sh 这个脚本中,咱们实现了基于 Kind 的 Kubernetes 测试环境的搭建。
仿佛行文至此,曾经能够 AFK and have a cup of coffee 了!
然而如同没施展尽兴。
好吧,那就具体掰扯掰扯 Kind 的玩法吧。
明天不必系安全带,我要庄重起来了。
应用 Kind“两键”搭建 Kubernetes 环境
当初咱们来搭建 Kind 开发环境,在 GitHub 上能够看到 Kind 最新的 Release 版本和对应的 Node 镜像:https://github.com/kubernetes…
能够抉择编译好的版本,也能够间接通过 go get 命令来下载编译 Kind。咱们尽量抉择较新的版本,而后通过上面命令下载安装(记得改成你须要的版本号)。
# 形式一:抉择编译好的可执行文件
cd /tmp
curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.12.0/kind-darwin-arm64
chmod +x ./kind
sudo mv kind /usr/local/bin/
# 形式二:通过 go get 来下载编译
go get sigs.k8s.io/kind@v0.12.1
能够提前下载所需镜像,这里咱们抉择应用 1.22 版本的 Kubernetes 对应镜像:
kindest/node:v1.22.0@sha256:b8bda84bb3a190e6e028b1760d277454a72267a5454b57db34437c34a588d047
而后通过上面一条命令就能够疾速拉起来一套 Kubernetes 环境:
kind create cluster --image=kindest/node:v1.22.0 --name=dev
上述执行输入大抵如下:
Creating cluster "dev" ...
✓ Ensuring node image (kindest/node:v1.22.0) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-dev"
You can now use your cluster with:
kubectl cluster-info --context kind-dev
Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
依照命令行输入提醒,接着咱们须要执行 kubectl cluster-info –context kind-dev 来切换 context,其实以后间接执行 kubectl get 就能够看到新起来的 Kubernetes 环境了,多套集群的时候才须要这样切换。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
dev-control-plane Ready control-plane,master 7m4s v1.22.0
$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-78fcd69978-hch75 1/1 Running 0 10m
coredns-78fcd69978-ztqn4 1/1 Running 0 10m
etcd-dev-control-plane 1/1 Running 0 10m
kindnet-l8qxq 1/1 Running 0 10m
kube-apiserver-dev-control-plane 1/1 Running 0 10m
kube-controller-manager-dev-control-plane 1/1 Running 0 10m
kube-proxy-mzfgc 1/1 Running 0 10m
kube-scheduler-dev-control-plane 1/1 Running 0 10m
这样咱们就疾速播种了一个能够用来测试或者学习 Kubernetes 的环境了。
应用 Kind“三键”搭建多节点 Kubernetes 集群环境
最小的 Kubernetes HA 集群须要有 3 个 Master 节点,当然咱们也能够把 1 个节点的 all-in-one 环境称为“单节点集群”。这一大节咱们接着看一下如何通过 Kind 来疾速搭建多节点的 Kubernetes 集群环境。
Kind 集群配置文件
Kind 环境搭建的时候能够自定义配置,通过 –config 来指定自定义配置文件门路。Kind 反对的配置格局如下:
# this config file contains all config fields with comments
# NOTE: this is not a particularly useful config file
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
# patch the generated kubeadm config with some extra settings
kubeadmConfigPatches:
- |
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
evictionHard:
nodefs.available: "0%"
# patch it further using a JSON 6902 patch
kubeadmConfigPatchesJSON6902:
- group: kubeadm.k8s.io
version: v1beta2
kind: ClusterConfiguration
patch: |
- op: add
path: /apiServer/certSANs/-
value: my-hostname
# 1 control plane node and 3 workers
nodes:
# the control plane node config
- role: control-plane
# the three workers
- role: worker
- role: worker
- role: worker
能够看到这里的配置项分为两个局部,下面是和 Kubeadm 如何配置 Kubernetes 相干的配置项,上面是和 Nodes 角色和规模相干的配置项。不难猜到,咱们须要部署多个节点的 Kubernetes 集群,能够通过指定 nodes 局部配置的形式来实现。
一主三从集群搭建
咱们筹备一份对应的配置文件,命名为 multi-node-config.yaml,内容如下:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
接着执行如下命令拉起集群:
$ kind create cluster --config multi-node-config.yaml \
--image=kindest/node:v1.22.0 --name=dev4
期待命令执行完结,咱们能够看到相似后面单节点环境搭建时看到的输入后果,有个次要区别是步骤多了一个“Joining worker nodes”:
Creating cluster "dev4" ...
✓ Ensuring node image (kindest/node:v1.22.0) 🖼
✓ Preparing nodes 📦 📦 📦 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
✓ Joining worker nodes 🚜
Set kubectl context to "kind-dev4"
You can now use your cluster with:
kubectl cluster-info --context kind-dev4
Thanks for using kind! 😊
能够通过如下命令查看新创建的集群:
$ kubectl cluster-info --context kind-dev4
Kubernetes control plane is running at https://127.0.0.1:51851
CoreDNS is running at https://127.0.0.1:51851/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
$ kubectl get node
NAME STATUS ROLES AGE VERSION
dev4-control-plane Ready control-plane,master 3m28s v1.22.0
dev4-worker Ready <none> 2m54s v1.22.0
dev4-worker2 Ready <none> 2m54s v1.22.0
dev4-worker3 Ready <none> 2m54s v1.22.0
上述命令执行后果能够很清晰看到这个 dev4 集群有 1 个 Master 节点和 3 个 Worker 节点。
三主三从 HA 集群搭建
当然咱们这里的 HA 只是示意 Master 节点组件会运行 3 正本,肯定水平上实现 Master 节点没有单点故障,并不是严格意义上的“高可用”。
同样筹备一份配置文件 ha-config.yaml,内容如下:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker
接着执行如下命令拉起集群:
$ kind create cluster --config ha-config.yaml \
--image=kindest/node:v1.22.0 --name=dev6
期待命令执行完结,咱们仍旧能够看到相熟的日志输入后果,和下面稍有不同,这里次要是多了“Configuring the external load balancer”和“Joining more control-plane nodes”:
Creating cluster "dev6" ...
✓ Ensuring node image (kindest/node:v1.22.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-dev6"
You can now use your cluster with:
kubectl cluster-info --context kind-dev6
Have a nice day! 👋
这里也能够看到几个很乏味的细节,比方“Preparing nodes”步骤前面小盒子数量和节点数是相等的;另外最初一句问候语也不是固定的。比方后面是“Thanks for using kind! 😊”,这里又变成了“Have a nice day! 👋”,可见 Kind 背地的开发者是一群“可恶”又“乏味”的工程师!
同样咱们通过几个命令看一下方才创立的集群:
$ kubectl cluster-info --context kind-dev6
Kubernetes control plane is running at https://127.0.0.1:52937
CoreDNS is running at https://127.0.0.1:52937/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
$ kubectl get node
NAME STATUS ROLES AGE VERSION
dev6-control-plane Ready control-plane,master 8m19s v1.22.0
dev6-control-plane2 Ready control-plane,master 7m46s v1.22.0
dev6-control-plane3 Ready control-plane,master 7m20s v1.22.0
dev6-worker Ready <none> 7m v1.22.0
dev6-worker2 Ready <none> 7m v1.22.0
dev6-worker3 Ready <none> 7m v1.22.0
上述命令执行后果能够很清晰看到这个 dev6 集群有 3 个 Master 节点和 3 个 Worker 节点。
到这里咱们就把握了通过 Kind 来十分轻松地搭建多节点的 Kubernetes 集群环境,前面大家能够依据本人的须要来抉择节点规模和角色,搭建适合的测试环境。
Kind 用法进阶
通过后面几节的学习,咱们曾经把握了用 Kind 搭建各种类型的集群。然而要用好这些集群,还须要把握一些运维技巧,本大节咱们来学习一下 Kind 集群的的一些进阶操作。
端口映射
构想一种场景:咱们在 Kind 集群中运行一个 Nginx 容器服务,监听 80 端口对外裸露,这时候在另外一台机器上能不能拜访到 Kind 集群所在机器的 80 端口进而拜访到这个 Nginx 服务呢?其实不行,这两个 80 端口显著不在一个网络命名空间。咱们能够通过如下形式来配置端口映射,解决这类问题。
在配置文件中减少 extraPortMappings 配置项:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 80
hostPort: 80
listenAddress: "0.0.0.0"
protocol: tcp
这样咱们搭建进去到 Kubernetes 集群中应用 NodePort 裸露的 80 端口或者是 hostNetwork 形式裸露 80 端口的 Pod 就能够通过主机的 80 端口来拜访到了。
裸露 kube-apiserver
有时候咱们会在一台机子上应用 Kind 搭建一套 Kubernetes 环境,在另外一台机器上写代码,这时候会发现咱们无奈连贯到 Kind 集群中的 kube-apiserver 来调试程序。其实是因为默认配置下 kube-apiserver 监听 127.0.0.1 加随机端口,咱们要从内部拜访就须要把 kube-apiserver 监听的网卡改成非 lo 的对外网卡,比方 eth0。
同样咱们通过配置文件自定义来实现,增加 networking.apiServerAddress 配置项,值是本地网卡 ip,依据理论状况批改:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
apiServerAddress: "192.168.39.1"
启用 Feature Gates
如果咱们要应用一些 alpha 阶段的个性,就须要通过配置 Feature Gates 来实现了。在应用 kubeadm 搭建环境的时候,是能够通过配置 ClusterConfiguration 来实现这个需要的,kubeadm 被 Kind 封装后,咱们在 Kind 里如何启用 Feature Gates 呢?
计划如下,FeatureGateName 就是咱们须要启用的 Feature Gate 名字:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
FeatureGateName: true
导入镜像
通过 kind 搭建的环境实质是运行在一个容器内,宿主机上的镜像默认不能被 Kind 环境所辨认到,这时咱们能够通过如下形式导入镜像:
# 如果须要的镜像是 my-image:v1
kind load docker-image my-image:v1 --name dev
# 如果须要的镜像是一个 tar 包 my-image.tar
kind load image-archive my-image.tar --name dev
晓得了这个办法后,咱们构建一个新镜像须要放到 Kind 环境里运行,就能够通过相似如下步骤来实现了:
docker build -t my-image:v1 ./my-image-dir
kind load docker-image my-image:v1
kubectl apply -f my-image.yaml
怎么查看以后 Kind 环境里有哪些镜像呢?也很简略,能够这样:
docker exec -it dev-control-plane crictl images
其中 dev-control-plane 是 node 容器名,有多套环境时这个名字须要对应灵便切换。另外能够通过 crictl -h 查看 crictl 所反对的其余命令,比方 crictl rmi <image_name> 能够用于删除镜像等。
小结
没啥好总结的,总之心愿大家搭环境顺利!
I have to AFK and have a cup of coffee NOW!
欢送浏览原文!