K8S-使用Minikube部署

一、背景

徒手搭建过k8s的同学都晓得其中的煎熬,复杂的认证,配置环节相当折磨人,出错率相当高,而minikube就是为解决这个问题而衍生出来的工具,它基于go语言开发, 是一个易于在本地运行 Kubernetes 的工具,可在你的笔记本电脑上的虚拟机内轻松创建单机版 Kubernetes 集群。便于尝试 Kubernetes或使用 Kubernetes日常开发。可以在单机环境下快速搭建可用的k8s集群,非常适合测试和本地开发。如果没有服务器或在本地笔记本安装,则可以在线使用https://labs.play-with-k8s.com来体验K8s。

1.1 Kubernetes集群的架构

通常情况下,一套完整的Kubernetes集群至少需要包括master节点和node节点,下图是常规k8s的集群架构,master节点一般是独立的,用于协调调试其它节点之用,而容器实际运行都是在node节点上,kubectl位于 master节点。

Kubernetes 集群的架构
1.2 Minikube 的架构

下图是 Minikube 的架构,可以看出,master 节点与其它节点合为一体,而整体则通过宿主机上的 kubectl 进行管理,这样可以更加节省资源。

Minikube的架构

二、Minikube

2.1 Minikube介绍

Minikube 是一个二进制工具,项目源码或文档等内容可以在 https://github.com/kubernetes/minikube 中找到,已经编译好的二进制可执行文件,可以在仓库的 Release 中下载,Minikube 支持 Windows 、Linux、MacOS。

直接下载 minikube 最新版本的二进制文件。可以通过官方 Github 仓库下载,也可以使用国内代理下载。

下载地址(Linux版本):

注:如果要下载 Win 版本,把 minkube-linux-amd64 改成 minkube-windows-amd64.exe 即可;如果是 MacOS 则是 minikube-darwin-amd64。另外要注意下载的版本号 。

阿里云源下载的二进制工具,本身可以使用国内镜像,不需要代理,可以到仓库了解 https://github.com/AliyunContainerService/minikube

2.1.1 Minikube 的基本运作原理

简单来说就是,用户使用Minikube CLI管理虚拟机上的Kubernetes环境,比如:启动,停止,删除,获取状态等。一旦Minikube虚拟机启动,用户就可以使用熟悉的Kubectl CLI在Kubernetes集群上执行操作。

Minikube运作的基本原理如下所示:


Minikube运作的基本原理
  • A: Minikube 在PC本地生成 kubeconfig 配置文件
  • B: Minikube 在虚拟环境中创建 Minikube 虚拟机
  • C: Minikube 在虚拟机中构建 Kubernetes
  • D: Kubectl 通过 kubeconfig 对虚机中的 Kubernetes 进行管理
2.2 Ubuntu安装Minikube

参考Minikube官网进行以下操作

2.2.1 硬件&容器要求
硬件要求
  • CUP & 内存:最少是2核2GB,
  • 硬盘:需要20G,
  • 网络:能连因特网(需要下载安装包),
  • 容器:需要先安装Docker或其他容器。(本文用Docker容器)

本文使用的机器环境是:阿里云ECS,Ubuntu 18.04 64位,4核(vCPU) 8 GiB

容器说明:
从K8S 1.24开始,dockershim已经从kubelet中移除,但因为历史问题Docker却不支持K8S主推的CRI(容器运行时接口)标准,所以Docker不能再作为K8S的容器运行时了,即从K8S 1.24开始不再使用Docker了。

但是如果想继续使用Docker的话,可以在kubelet和Docker之间加上一个中间层cri-docker。cri-docker是一个支持CRI标准的shim(垫片)。一头通过CRI跟kubelet交互,另一头跟docker api交互,从而间接的实现了K8S以Docker作为容器运行时。但是这种架构缺点也很明显,调用链更长,效率更低。推荐使用containerd作为K8S的容器运行时。

常用驱动:
Minikube在不同操作系统上支持不同的驱动

  • macOS:xhyve driver , VirtualBox 或 VMware Fusion,Docker 缺省驱动

  • Linux:VirtualBox 或 KVM2,Docker 缺省驱动

  • Windows:VirtualBox 或 Hyper-V

注意:
1、由于minikube复用了docker-machine,在其软件包中已经支持了相应的VirtualBox, VMware Fusion驱动。

2、VT-x/AMD-v 虚拟化必须在 BIOS 中开启。

3、在Windows环境下,如果开启了Hyper-V,不支持VirtualBox方式

2.2.2 安装Docker

1、安装命令如下:

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

也可以使用国内 daocloud 一键安装命令:

curl -sSL https://get.daocloud.io/docker | sh

2、检查docker版本号

docker --version

3、用docker运行hello-world

$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete 
Digest: sha256:13e367d31ae85359f42d637adf6da428f76d75dc9afeb3c21faea0d976f5c651
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

root@iZ0jle7r7zuxdbg7z1oqi0Z:~# 

4、配置docker加速
由于国内访问直接访问Docker hub网速比较慢,拉取镜像的时间就会比较长。一般我们会使用镜像加速或者直接从国内的一些平台镜像仓库上拉取。

我比较常用的是网易的镜像中心和daocloud镜像市场。

创建/etc/docker/daemon.json文件并配置如下内容:

vi /etc/docker/daemon.json
{                     
  "registry-mirrors" : [
    "http://hub-mirror.c.163.com"],
    "exec-opts": ["native.cgroupdriver=systemd"]
}

重启docker

systemctl enable docker && systemctl restart docker
2.2.3 下载安装Minikube
参考官网安装

在Minikube官网上,根据选择的系统及版本,官网会生成下载安装命令

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

sudo install minikube-linux-amd64 /usr/local/bin/minikube

下载命令
安装命令

通过minikube version命令可以查看 minikube 的版本。

minikube版本
2.2.4 Minikube部署

直接执行 minikube start 命令即可进行部署,但是国内会被墙,可能拉取不了镜像,需要设置代理。

# 国外服务器
minikube start

# 使用阿里云版本时,指定国内源
minikube start --image-mirror-country=cn

# 使用阿里云版本时,指定镜像源
minikube start --image-mirror=registry.cn-hangzhou.aliyuncs.com/google_containers
2.2.4.1 问题一
问题一

如果启动不起来提示没有 docker 用户,这是因为默认不应该使用 root 用户执行命令和启动程序,可以创建一个 docker 用户,也可以使用 --driver=none 指定不用 docker 用户。如果要用 docker 用户:

    grouped docker
    useradd -m docker
    passed docker
    # 修改密码后,加入用户组
    gpasswd -a docker docker

打开 /etc/sudoers 文件,在 root ALL=(ALL:ALL) ALL 下 增加新的一行:

vi /etc/sudoers
docker ALL=(ALL)ALL
创建用户
修改配置

然后切换为 docker 用户:su docker
如果不用 docker 用户,只需要在初始化集群时加上 --driver=none

minikube start --image-mirror-country=cn --driver=none
2.2.4.2 问题二
image.png

如果报 X Exiting due to GUEST_MISSING_CONNTRACK: Sorry, Kubernetes 1.20.2 requires conntrack to be installed in root's path,则需要安装 construct。

apt install conntrack

再次执行

minikube start --image-mirror-country=cn --driver=none
2.2.4.3 问题三
问题三

错误信息Failed to enable unit: Unit file cri-docker.socket does not exist

需要安装cri-dockerd

1、下载cri-dockerd二进制文件
项目地址:https://github.com/Mirantis/cri-dockerd

cri-dockerd
cri-dockerd

2、拷贝cri-dockerd文件到远程服务器并安装

scp /Users/AC/cri-dockerd-0.2.3.amd64.tgz root@47.107.79.46:cri-dockerd-0.2.3.amd64.tgz

tar -xvf cri-dockerd-0.2.3.amd64.tgz

cp cri-dockerd/cri-dockerd /usr/bin/

chmod +x /usr/bin/cri-dockerd

# 确认已安装版本
cri-dockerd --version

3、配置启动文件
创建cri-docker.service配置文件

vi /lib/systemd/system/cri-docker.service

内容:

[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket

[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

StartLimitBurst=3

StartLimitInterval=60s

LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

TasksMax=infinity
Delegate=yes
KillMode=process

[Install]
WantedBy=multi-user.target

创建cri-docker.socket配置文件

vi /lib/systemd/system/cri-docker.socket

内容:

[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service

[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker

[Install]
WantedBy=sockets.target

也可以直接下载https://github.com/Mirantis/cri-dockerd/tree/master/packaging/systemd 注意,需要修改cri-docker.service中ExecStart启动参数,这里/usr/bin/cri-dockerd一定要加上参数–pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7用来指定所用的pause镜像是哪个,否则默认拉取k8s.gcr.io/pause:3.6,会导致安装失败。

4、启动cri-docker

systemctl daemon-reload

systemctl start docker.service

systemctl enable cri-docker

systemctl status docker.service

5、再次执行启动minikube

minikube start --image-mirror-country=cn --driver=none
2.2.4.4 问题四

错误信息:Exiting due to RUNTIME_ENABLE: Temporary Error: sudo crictl version: exit status 1

需要安装crictl,我们可以参考官方安装步骤:crictl官网安装步骤

安装crictl
VERSION="v1.24.1"

wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz

sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin

rm -f crictl-$VERSION-linux-amd64.tar.gz

再次执行启动minikube

minikube start --image-mirror-country=cn --driver=none

启动成功

root@iZwz91ofbggjr3fobspnv0Z:~# minikube start --image-mirror-country=cn --driver=none
😄  minikube v1.26.0 on Ubuntu 18.04 (amd64)
✨  Using the none driver based on existing profile
👍  Starting control plane node minikube in cluster qinikube
🔄  Restarting existing none bare metal machine for "minikube" ...
ℹ️  OS release is Ubuntu 18.04.6 LTS
🐳  Preparing Kubernetes v1.24.1 on Docker 20.10.17 ...
    ▪ kubelet.resolv-conf=/run/systemd/resolve/resolv.conf
    > kubectl.sha256: 64 B / 64 B [--------------------------] 100.00% ? p/s 0s
    > kubeadm.sha256: 64 B / 64 B [--------------------------] 100.00% ? p/s 0s
    > kubelet.sha256: 64 B / 64 B [--------------------------] 100.00% ? p/s 0s
    > kubectl: 43.59 MiB / 43.59 MiB [--------------] 100.00% 6.32 MiB p/s 7.1s
    > kubeadm: 42.31 MiB / 42.31 MiB [---------------] 100.00% 3.98 MiB p/s 11s
    > kubelet: 110.96 MiB / 110.96 MiB [-------------] 100.00% 7.29 MiB p/s 15s
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🤹  Configuring local host environment ...

❗  The 'none' driver is designed for experts who need to integrate with an existing VM
💡  Most users should use the newer 'docker' driver instead, which does not require root!
📘  For more information, see: https://minikube.sigs.k8s.io/docs/reference/drivers/none/

❗  kubectl and minikube configuration will be stored in /root
❗  To use kubectl or minikube commands as your own user, you may need to relocate them. For example, to overwrite your own settings, run:

    ▪ sudo mv /root/.kube /root/.minikube $HOME
    ▪ sudo chown -R $USER $HOME/.kube $HOME/.minikube

💡  This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true
🔎  Verifying Kubernetes components...
    ▪ Using image registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5
🌟  Enabled addons: default-storageclass, storage-provisioner
💡  kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
root@iZwz91ofbggjr3fobspnv0Z:~# 

查看minikube的运行状态

minikube status

运行结果

root@iZwz91ofbggjr3fobspnv0Z:~# minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

root@iZwz91ofbggjr3fobspnv0Z:~# 

查看container

docker container ls

可以看到minikube在docker中启动了很多k8s相关的container

container
2.2.5 查看集群状态

本身minikube带有一些简单的kubectl命令,可以查看集群状态信息。

获取集群所有节点(机器)

minikube kubectl get nodes

获取集群所有命名空间

minikube kubectl get namespaces

查看集群所有 Pod

minikube kubectl -- get pods -A
操作步骤

2.3 安装kubectl、kubelet

kubectl它是kubernetes的命令行工具,可以使用kubectl部署应用程序,检查和管理集群资源以及查看日志,通过kubectl对K8S进行操作。由于minikube不会自动下载kubectl、kubelet 等工具,我们需要手动安安装。

# 下载最新稳定版本的kubuctl二进制文件
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.0/bin/linux/amd64/kubectl

# 为kubectl赋予可执行权限
chmod +x ./kubectl

# 安装到/usr/local/bin/目录,将可执行文件放到系统的PATH目录
sudo mv ./kubectl /usr/local/bin/kubectl

# 成功
kubectl version --client

# 检查版本:
kubectl version -o json 

显示kubelet状态信息

systemctl status kubelet -l
2.3.1 问题一

问题描述:
查询集群中节点信息

kubectl get nodes

status显示NotReady

root@iZwz91ofbggjr3fobspnv0Z:~# kubectl get nodes
NAME                      STATUS     ROLES           AGE     VERSION
izwz91ofbggjr3fobspnv0z   NotReady   control-plane   3h53m   v1.24.1
root@iZwz91ofbggjr3fobspnv0Z:~# 

解决步骤:
1、实时滚动显示某个Unit的最新日志

journalctl -u kubelet -f
root@iZwz91ofbggjr3fobspnv0Z:~# journalctl -u kubelet -f
-- Logs begin at Sun 2022-07-10 08:50:15 CST. --
Jul 10 14:25:49 iZwz91ofbggjr3fobspnv0Z kubelet[8389]: E0710 14:25:49.570536    8389 kubelet.go:2344] "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized"
Jul 10 14:25:54 iZwz91ofbggjr3fobspnv0Z kubelet[8389]: E0710 14:25:54.580855    8389 kubelet.go:2344] "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized"

关键错误信息:"Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized"

2、安装flannel网络插件(简单易用)

# 下载flannel插件的yml
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
 
# 修改kube-flannel.yml中的镜像仓库地址为国内源
sed -i 's/quay.io/quay-mirror.qiniu.com/g' kube-flannel.yml
 
# 安装网络插件
kubectl apply -f kube-flannel.yml

3、重启kubelet服务

systemctl restart kubelet

4、再次查询节点状态

kubectl get nodes

已经变成Ready

root@iZwz91ofbggjr3fobspnv0Z:/opt/cni/bin# kubectl get nodes
NAME                      STATUS   ROLES           AGE     VERSION
izwz91ofbggjr3fobspnv0z   Ready    control-plane   4h49m   v1.24.1
root@iZwz91ofbggjr3fobspnv0Z:/opt/cni/bin# 

2.4 创建Deployment

Deployment可以部署应用并管理实例数量,它提供了一种故障的自我修复机制,当应用挂了后,Deployment可以自动启动一个新的实例,维护固定数量的Pod。

kubectl create deployment命令创建管理Pod的Deployment。

格式:

kubectl create deployment {deployment名称} {参数}

部署nginx

kubectl create deployment hello-nginx --image=nginx:latest

查看 Deployment

kubectl get deployments

查看 Pod

kubectl get pods

查看集群事件

kubectl get events

查看 kubectl 配置

kubectl config view
2.5 创建Service

Service为Pod提供了一种外网访问能力,默认情况下,Pod 只能在 Kubernetes 集群的同一节点访问,如果要外部网络访问,则需要为 Pod 暴露一个Kubnetes Service,Service 为 Pod 提供了外网访问能力。现在我们就把刚才创建的nginx pod暴露出去。

nginx镜像会暴露一个80 端口,通过 80 端口我们可以访问到nginx 服务。但是在Kubernetes 中,则可能有些麻烦。每个Pod 在集群中都有一个唯一 IP,我们可以查看详细的 Pod 信息:

kubectl get pods -o wide

为了能够在外网访问,我们创建 Service

kubectl expose deployment hello-nginx --port=6001 --target-port=80 --type=LoadBalancer

然后查看刚刚创建的 service

kubectl get service hello-nginx

# 或
minikube service hello-nginx
2.6 清理集群资源

由于 Minikube 创建的资源只是单机的,同时会产生很多 Docker 容器,我们练习完毕后,就要清除环境,以免影响后续实践环境。首先清除 service、deployment (可以跳过这个步骤)。

kubectl delete service hello-nginx

kubectl delete deployment hello-nginx

然后停止 Minikube 虚拟机(VM)

minikube stop

接着删除 Minikube 虚拟机(VM)

minikube delete
2.6 启动minikube dashboard

1、Enable dashboard

minikube addons enable dashboard

2、查看所有的addons

minikube addons list

3、启动dashboard

minikube dashboard

参考资料:
使用 Minikube 部署

kubeadm 部署Kubernetes1.24_cri-docker版本

kubernetes-sigs/cri-tools

Kubernetes容器运行时弃用Docker转型Containerd

k8s节点为NotReady的常见原因

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容