前言

Kubernetes成为事实上的云原生平台,用于在分布式环境中运行容器化服务和应用程序。尽管可以在在云环境(公有云,私有云或混合云)或裸机环境中部署Kubernetes,但有时仍然需要在本地部署和运行Kubernetes进行开发测试。

Kubernetes最初被设计为在Linux环境中部署和使用。但是,大量用户是使用Windows OS作为其日常驱动程序,本文探讨利用windows10的WLS2功能,使用Kind或Minikube在本地运行Kubernetes集群。

在安装windows版kubernetes集群时,需要先在win10上面开启WSL2功能和安装docker,可以参考这篇文章的姊妹篇- win10利用WSL2安装docker的2种方式,链接地址:https://www.toutiao.com/i6838436149912928772/

部署安装

kind方式

  • 启动docker服务(可选)
#使用的为linux原生docker方式,如果使用docker desktop for windows,此步骤可选
  service docker start
  • 下载kind二进制文件
curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.8.1/kind-$(uname)-amd64
  #标记为可执行文件
  chmod +x ./kind
  #移动到 PATH 目录下去
  mv ./kind /usr/bin/
  • 开始创建集群
kind create cluster --name wsl2-k8s

kubernetes 桌面版 kubernetes windows应用_docker

  • 检查启动kubernetes集群的容器启动正常
docker ps

kubernetes 桌面版 kubernetes windows应用_kubernetes_02

我们发现kind下载了kindest/node:v1.18.2镜像并用此镜像启动容器,kubernetes集群运行在此容器内,这也是kind名字的由来(kubernetes in docker)。如上图,kube-apiserver的6443端口暴露到docker宿主机的37293端口。

exec到该容器,我们发现容器内启动的kubernetes进程。

kubernetes 桌面版 kubernetes windows应用_linux_03

  • 拷贝kubectl二进制文件到docker宿主机
id=$(docker ps |grep "kindest\/node"|awk '{print $1}')
  docker cp $id:/kind/bin/kubectl /usr/bin/
  kubectl get node

kubernetes 桌面版 kubernetes windows应用_WSL2_04

如上图,一个单节点的kubernetes集群就创建好了,那如何创建多节点kubernetes集群呢

  • 创建多节点kubernetes集群
  • 删除现有集群
#获取创建的集群名字
  kind get clusters
  #删除集群
  kind delete cluster --name wsl2-k8s
  • 创建一个3节点集群的配置文件
cat << EOF > kind-3nodes.yaml
  kind: Cluster
  apiVersion: kind.x-k8s.io/v1alpha4
  nodes:
    - role: control-plane
    - role: worker
    - role: worker
  EOF
  • 使用配置文件创建新的集群
kind create cluster --name wsl2-3nodes --config ./kind-3nodes.yaml

在实际创建中,会报错“ docker: Error response from daemon: cgroups: cannot find cgroup mount destination: unknown”问题,这是因为使用的linux原生的docker会有此问题,如果使用docker desktop for windows,没有此问题出现,可以通过如下办法解决:

mkdir /sys/fs/cgroup/systemd
  mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd

kubernetes 桌面版 kubernetes windows应用_kubernetes_05

再次执行集群创建命令后,上述报错消失。

  • 获取集群节点
kubectl get nodes

kubernetes 桌面版 kubernetes windows应用_kubernetes 桌面版_06

  • docker ps检查kind启动的容器

kubernetes 桌面版 kubernetes windows应用_linux_07

minikue方式

  • 下载minikube二进制文件
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
  chmod +x ./minikube
  mv ./minikube  /usr/bin/

kubernetes 桌面版 kubernetes windows应用_linux_08

也可以使用阿里云的minikube版本:

curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.11.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
  • 创建集群
minikube start --vm-driver=none --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

值得注意的是,运行Kubernetes v 1.18时,我们会收到“conntrack需要被安装”的提示:

kubernetes 桌面版 kubernetes windows应用_linux_09

通过安装缺少的软件包来解决此问题:

apt install -y conntrack

同时发现WSL2下使用的ubuntu因为没有systemd,导致部署异常

System has not been booted with systemd as init system (PID 1). Can’t operate

kubernetes 桌面版 kubernetes windows应用_linux_10

我么可以通过如下方法解决systemd的问题,参考自 https://forum.snapcraft.io/t/running-snaps-on-wsl2-insiders-only-for-now/13033:

首先安装 Systemd 相关的依赖

apt install -yqq fontconfig daemonize

创建一个如下所示的脚本文件

# Create the starting script for SystemD
vi /etc/profile.d/00-wsl2-systemd.sh
SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')

if [ -z "$SYSTEMD_PID" ]; then
   sudo /usr/bin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
   SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')
fi

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    exec sudo /usr/bin/nsenter -t $SYSTEMD_PID -a su - $LOGNAME
fi

上面的脚本放置在 /etc/profile.d 目录下面,所以要让脚本生效,我们需要退出当前 session,重新进入即可,再次登录session,我们会发现系统PID为1的进程已经变成systemd。

kubernetes 桌面版 kubernetes windows应用_kubernetes_11

注意,此处有个坑,在退出重新登录切换session时,需在一个旧的session停掉原来旧的init方式启动的docker,否则新的session下,会再次用systemd启动docker,不在旧session停掉init方式启动的docker,新session用systemd接管的docker无法启动,因为使用的咨询冲突,报错 failed to start daemon: error while opening volume store metadata database: timeout。同时在新的session下,是无法看到dockerd服务端进程的,原因为通过上面/etc/profile.d/00-wsl2-systemd.sh脚本创建的systemd的session,其实是用nsenter创建的一个隔离的ns里面。

kubernetes 桌面版 kubernetes windows应用_WSL2_12

kubernetes 桌面版 kubernetes windows应用_docker_13

kubernetes 桌面版 kubernetes windows应用_kubernetes_14

kubernetes 桌面版 kubernetes windows应用_linux_15

继续执行先前的minikube集群创建命令,集群创建成功。

kubernetes 桌面版 kubernetes windows应用_WSL2_16

  • 检查创建的kubernetes集群状态
kubectl get nodes
   kubectl get all -A

kubernetes 桌面版 kubernetes windows应用_WSL2_17

总结

标准

Kind

Minikube

在WSL2上安装

很容易

有点复杂

多节点集群

支持

不支持

插件

手动安装

支持

持久化

支持(但没有针对WSL2设计)

支持

替代方案

K3d

Microk8s