前言

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
    

image-20200615185936062

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

      docker ps
    

    image-20200615192425468

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

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

    image-20200615210354754

  • 拷贝kubectl二进制文件到docker宿主机

      id=$(docker ps |grep "kindest\/node"|awk '{print $1}')
      docker cp $id:/kind/bin/kubectl /usr/bin/
      kubectl get node
    

    image-20200615205748992

如上图,一个单节点的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
      

      image-20200615212535278

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

    • 获取集群节点

        kubectl get nodes
      

      image-20200615214720866

    • docker ps检查kind启动的容器

image-20200615224502822

minikue方式

  • 下载minikube二进制文件

      curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
      chmod +x ./minikube
      mv ./minikube  /usr/bin/
    

image-20200616111328599

也可以使用阿里云的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需要被安装”的提示:

image-20200616131354345

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

apt install -y conntrack

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

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

image-20200616132424907

我么可以通过如下方法解决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。

image-20200616200747569

注意,此处有个坑,在退出重新登录切换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里面。

image-20200616203224484

image-20200616203432067

image-20200616203611694

image-20200616204026581

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

image-20200616204314574

  • 检查创建的kubernetes集群状态

       kubectl get nodes
       kubectl get all -A
    

    image-20200616204907225

总结

标准KindMinikube
在WSL2上安装很容易有点复杂
多节点集群支持不支持
插件手动安装支持
持久化支持(但没有针对WSL2设计)支持
替代方案K3dMicrok8s
Logo

开源、云原生的融合云平台

更多推荐