Kube #02.0 – 部署一个测试Kubernetes集群

在进入到Kubernetes之前,我们需要先搭建一个测试环境。本文介绍的都是可以在一台工作站上部署的单机Kubernetes环境。在多台服务器上部署Kubernetes比较复杂,所以我们一般依赖云服务商来提供生产环境的Kubernetes服务,比如腾讯云的TKE,Azure的AKS,谷歌的GKE,亚马逊的EKS等,也可以用这些云资源来进行测试。

需要注意的是,本地集群相比起真正的Kubernetes集群会缺失一些功能。这会导致一些指令无法使用。也会间接地导致一些服务无法使用,但通常影响不大。比如,Docker Desktop提供的Kubernetes Engine不支持Metrics API,无法测量集群内各个Pod的资源占用,也就自然无法支持HorizontalPodScaler,一个基于Pod资源占用来动态增减Pod数量的服务。

本章目标:配置好一个集群,并且让kubectl可以访问到它。

0. Kubernetes 集群是什么,kubectl是什么?

Kubernetes集群是一台或者很多台通过网络连接的计算机,上面跑着Kubernetes的后端(kubeadm, kubelet)等。它对外提供了一个API接口,可以通过网络访问这一个接口,并增删改查这个集群内的资源。

kubectl是一个命令行工具,运行在本地计算机或工作站上。它通过API连接到Kubernetes集群,并可以用命令行的方式配置集群上的资源。kubectl可以同时保存多个集群的连接方式,但是同时只能操作一个集群。可以使用kubectl config get-contexts 列出现有的集群列表 以及当前使用的集群,并使用kubectl config use-context 来切换当前的活动集群。

1. Docker Desktop (仅限 Windows 和 Mac,不推荐)

Docker Desktop本身提供了一个Kubernetes环境,我们可以直接利用它来做测试。使用Docker Desktop提供的Kubernetes时,这个本地的Kubernetes可以直接使用Docker的image。也就是说测试自己打包的容器镜像时,不需要将它发布到registry就可以直接在Kubernetes集群内使用,比较方便。但是这个部署经常出错而且没有任何log,特别是国内的网络环境让其变得更加难成功,因此不是很推荐使用。

进入Docker Desktop的设置,找到Kubernetes,启用,并选择Apply & Restart。国内网络环境且不设置镜像的话可能会部署失败。首次安装的时候Docker需要下载并部署一些Kubernetes服务所依赖的镜像,因此需要一段时间。Docker Desktop的左下角除了Docker的图标外还会多出一个Kubernetes的图标。橙色代表集群还在准备中;当Kubernetes的图标背景变绿的时候,就代表本地集群已经准备好了。

启用后

图标变绿后,使用kubectl config get-contexts查看当前kubectl连接到的集群

❯ kubectl config get-contexts
CURRENT   NAME             CLUSTER          AUTHINFO         NAMESPACE
*         docker-desktop   docker-desktop   docker-desktop
          minikube         minikube         minikube         default

可以看到我们现在有两个可用的环境:minikube以及docker-desktop,且目前连接到了Docker Desktop。如果显示的CURRENT不是docker-desktop,可以使用指令kubectl config use-context docker-desktop来切换到Docker Desktop的环境。再用kubectl cluster-info查看集群信息。

>kubectl cluster-info
Kubernetes control plane is running at https://kubernetes.docker.internal:6443
KubeDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

可以看到集群的地址是kubernetes.docker.internal:6443,是Docker自己的地址,至此部署完成。Docker本地拉取的和构建的镜像都可以直接在这个Kubernetes集群中使用。

Docker Desktop Kubernetes Engine的配置相对来说比较不灵活。如果需要更改Docker Desktop Kubernetes Engine所使用的CPU和内存数量,需要直接更改WSL 2的设置。WSL的配置文件在C:\Users\<username>\.wslconfig中,格式如下。文件不存在的话可以自己创建。

[wsl2]
memory=8GB
processors=4

更改保存后需要重启生效。

2. Minikube (全平台)

Minikube是一个全平台的单机Kubernetes环境。它由Kubernetes社区维护,版本相对较新。它占用的资源也比Docker Desktop的Kubernetes Engine要少一些。

安装后就可以启动了,以下是几个比较重要的参数。

❯ minikube start --help
Starts a local Kubernetes cluster

Options:
      --cache-images=true: If true, cache docker images for the current bootstrapper and load them into the machine.
Always false with --driver=none.
      --container-runtime='docker': The container runtime to be used (docker, cri-o, containerd).
      --cpus='2': Number of CPUs allocated to Kubernetes. Use "max" to use the maximum number of CPUs.
      --disk-size='20000mb': Disk size allocated to the minikube VM (format: <number>[<unit>], where unit = b, k, m or g).
      --image-mirror-country='': Country code of the image mirror to be used. Leave empty to use the global one. For
Chinese mainland users, set it to cn.
      --image-repository='': Alternative image repository to pull docker images from. This can be used when you have
limited access to gcr.io. Set it to "auto" to let minikube decide one for you. For Chinese mainland users, you may use
local gcr.io mirrors such as registry.cn-hangzhou.aliyuncs.com/google_containers
      --memory='': Amount of RAM to allocate to Kubernetes (format: <number>[<unit>], where unit = b, k, m or g). Use
"max" to use the maximum amount of memory.

可以看到我们在启动minikube时,可以设置minikube的CPU、内存数量,还可以指定国内的Docker Registry镜像以加速部署。我们可以使用以下的命令来启动一个minikube。

minikube start --cpus=2 --memory=4g

在使用--image-repository=cn时,minikube会自动连接阿里云镜像,而这个镜像的更新速度不是很及时。如果出现The image 'registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0' was not found; unable to add it to cache. 之类的错误,表示有一个容器的镜像在阿里云上找不到,这时候需要移除此参数并设置梯子,让minikube直接从gcr.io下载。阿里云镜像刚开始下载时速度会卡在200K左右,但可以逐渐跑满带宽。

如果出现了安装失败的情况,需要使用minikube delete来删除上一次配置失败的资源,否则下一次start时会延续着上一次的配置继续跑。

在Windows上,minikube默认使用docker作为后端。也就是说minikube会启动一个或多个docker容器,并将它们作为Kubernetes的节点来使用,相当于在容器里跑容器。性能损失是无疑的,这也是为什么minikube只适合用来测试。

命令执行成功后,控制台输出类似如下。

❯ minikube start --cpus=2 --memory=4g
😄  minikube v1.22.0 on Microsoft Windows 10 Pro 10.0.22000 Build 22000
✨  Automatically selected the docker driver
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
💾  Downloading Kubernetes v1.21.2 preload ...
    > preloaded-images-k8s-v11-v1...: 502.14 MiB / 502.14 MiB  100.00%% 2.41 MiB
🔥  Creating docker container (CPUs=2, Memory=4096MB) ...
🐳  Preparing Kubernetes v1.21.2 on Docker 20.10.7 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

从以上信息可以看出minikube已经部署成功,且帮我们配置好了kubectl。可以使用kubectl config get-contexts查看可用的Kubernetes连接。

❯ kubectl config get-contexts
CURRENT   NAME             CLUSTER          AUTHINFO         NAMESPACE
          docker-desktop   docker-desktop   docker-desktop
*         minikube         minikube         minikube         default

可以看到,我们有docker-desktopminikube两个context,且minikube被标注为 CURRENT,代表现在的kubectl指令都会指向这一个环境。如果minikube没有被标记为current的话,可以使用kubectl config use-context minikube来切换到minikube集群。

这时我们可以执行kubectl cluster-info,查看集群信息

❯ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:1057
CoreDNS is running at https://127.0.0.1:1057/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

可以看到现在这个集群已经准备好了,后端地址是127.0.0.1:1057。minikube使用的是CoreDNS而不是KubeDNS,在实际应用中CoreDNS的应用也比KubeDNS要广。

2.1 将本地镜像转移进minikube

我们可以将主机上的镜像加到minikube里。假设我的镜像名为test-image,执行命令:minikube image load test-image。然后用minikube image list查看集群内镜像

❯ minikube image load test-image

❯ minikube image list
k8s.gcr.io/pause:3.4.1
k8s.gcr.io/kube-scheduler:v1.21.2
k8s.gcr.io/kube-proxy:v1.21.2
k8s.gcr.io/kube-controller-manager:v1.21.2
k8s.gcr.io/kube-apiserver:v1.21.2
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns/coredns:v1.8.0
gcr.io/k8s-minikube/storage-provisioner:v5
docker.io/library/test-image:latest
docker.io/kubernetesui/metrics-scraper:v1.0.4
docker.io/kubernetesui/dashboard:v2.1.0

可以看到镜像列表中出现了docker.io/library/test-image:latest,镜像已被成功载入。接下来再执行kubectl run testpod --image=test-image --image-pull-policy=Never,即可运行这个镜像。

需要注意的是,在使用本地镜像且taglatest时,必须在Kubernetes配置中加入imagePullPolicy: Never,否则kubernetes会强行尝试从远端pull镜像。

2.2 常用的Minikube命令

  • minikube dashboard:打开Kubernetes的网页端后台,查看各种资源的运行状况。
Kubernetes后`台
  • minikube stop:停止Kubernetes集群
  • minikube delete:删除Kubernetes集群
  • minikube kubectl --:可代替kubectl用来操作minikube集群。例如,kubectl get pods等同于minikube kubectl -- get pods。对于没有安装kubectl的人来说很方便。
  • minikube load image <image-name>:将一个镜像加载进minikube
  • minikube unload image <image-name>:从minikube里删除一个镜像

Leave A Comment