Kubernetes安装与踩坑

OS:Ubuntu 20.04.2 LTS
Kubernetes:1.23.6 (1.24+已经弃用了docker,初始化时会有超时异常)

官方文档:Creating a cluster with kubeadm
参考博客:使用Kubeadm(1.13+)快速搭建Kubernetes集群 - 雨夜朦胧

一、准备

两台虚拟机(CPU最少2核)

禁用swap

Kubernetes 1.8开始要求必须禁用Swap(内存交换),如果不关闭,默认配置下kubelet将无法启动

sudo vim /etc/fstab
"""
UUID=8be04efd-f7c5-11e8-be8b-00155d000500 / ext4 defaults 0 0
UUID=C0E3-6A72 /boot/efi vfat defaults 0 0
# 注释下面这行
#/swap.img      none    swap    sw      0       0 
"""
free -m
# 确认swap已经关闭:若swap行都显示 0 则表示关闭成功 

hosts配置

sudo vim /etc/hosts

"""
自己本地ip
192.168.10.110 k8s-master k8s-master.ubuntu.peppa-pig.info  
192.168.10.111 k8s-node-1 k8s-node-1.ubuntu.peppa-pig.info  
"""
reboot # 重启

安装docker

Kubernetes从1.6开始使用CRI(Container Runtime Interface)容器运行时接口。默认的容器运行时仍然是Docker,是使用kubelet中内置dockershim CRI来实现的

docker详细安装教程

sudo apt-get install docker-ce=18.03.1~ce~3-0~ubuntu

配置docker

sudo vim /etc/docker/daemon.json

"""
{
	"registry-mirrors": [
		"https://docker.mirror.ustc.edu.cn",
		"https://registry.docker-cn.com"
	],
	"exec-opts": ["native.cgroupdriver=systemd"], # 最重要的是这行配置cgroups
	"log-driver": "json-file",
	"log-opts": {
		"max-size": "100m"
	},
	"storage-driver": "overlay2"
}
"""
sudo systemctl daemon-reload
sudo systemctl restart docker.service 
sudo docker info  # 查看是否设置成功

为什么要修改为使用systemd
Kubernetes 推荐使用 systemd 来代替 cgroupfs,因为systemd是Kubernetes自带的cgroup管理器,负责为每个进程分配cgroups,但docker的cgroup driver默认是cgroupfs,这样就同时运行有两个cgroup控制管理器,当资源有压力的情况时,有可能出现不稳定的情况

安装 kubeadm, kubelet, kubectl

  • kubeadm: 引导启动k8s集群的命令行工具。
  • kubelet: 在群集中所有节点上运行的核心组件, 用来执行如启动pods和containers等操作。
  • kubectl: 操作集群的命令行工具。
sudo apt update && sudo apt install -y apt-transport-https curl
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
sudo vim /etc/apt/sources.list.d/kubernetes.list
""" 
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main 
"""
sudo apt update
# k8s 已经弃用了docker了,如果安装的kubelet kubeadm kubectl 是V1.24就会出现以上错误,安装的时候指定一下1.23版本
sudo apt -y install kubeadm=1.23.6-00 kubelet=1.23.6-00 kubectl=1.23.6-00 
# 阻止自动更新(apt upgrade时忽略)。所以更新的时候先unhold,更新完再hold
sudo apt-mark hold kubelet kubeadm kubectl
# 开机自启
sudo systemctl enable kubelet.service

apt-mark 使用

功能

apt-mark 可以对软件包进行设置(手动/自动 )安装标记,也可以用来处理软件
包的 dpkg(1) 选中状态,以及列出或过滤拥有某个标记的软件包。

语法

apt-mark [选项] {auto|manual} 软件包1 [软件包2 …]

命令

auto – 标记指定软件包为自动安装
manual – 标记指定软件包为手动安装
minimize-manual – Mark all dependencies of meta packages as automatically installed.
hold – 标记指定软件包为保留(held back),阻止软件自动更新
unhold – 取消指定软件包的保留(held back)标记,解除阻止自动更新
showauto – 列出所有自动安装的软件包
showmanual – 列出所有手动安装的软件包
showhold – 列出设为保留的软件包

二、创建节点(master、node)

初始化 k8s-master

K8s的控制面板组件运行在Master节点上,包括etcd和API server(Kubectl便是通过API server与k8s通信)

sudo kubeadm init \
--kubernetes-version v1.23.6 \
--pod-network-cidr=10.244.0.0/16 \ 
--apiserver-advertise-address=192.168.88.221 \
--image-repository registry.aliyuncs.com/google_containers

–pod-network-cidr

选择一个Pod网络插件,并检查它是否需要在初始化Master时指定一些参数,它的值取决于你在下一步选择的哪个网络网络插件,这里选择Flannel的网络插件参数为 10.244.0.0/16。Calico网络为192.168.0.0/16。参考:Installing a pod network add-on

–apiserver-advertise-address=

kubeadm使用eth0的默认网络接口(通常是内网IP)做为Master节点的advertise address,如果我们想使用不同的网络接口,该参数来设置。
如果适应IPv6,则必须使用IPv6d的地址,如:--apiserver-advertise-address=fd00::101

–image-repository

使用kubeadm config images pull来预先拉取初始化需要用到的镜像,用来检查是否能连接到KubenetesRegistries
Kubenetes默认Registries地址是k8s.gcr.io,很明显,在国内并不能访问gcr.io,因此在kubeadm v1.13之前的版本,安装起来非常麻烦,但是在1.13版本中终于解决了国内的痛点,其增加了一个--image-repository参数,默认值是k8s.gcr.io,我们将其指定为国内镜像地址:registry.aliyuncs.com/google_containers

–kubernetes-version

默认值是stable-1,会导致从https://dl.k8s.io/release/stable-1.txt下载最新的版本号,我们可以将其指定为固定版本来跳过网络请求。

如果我们想使用非root用户操作kubectl,可以使用以下命令,这也是kubeadm init输出的一部分

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

遇到的异常

1. [ERROR Port-10250]: Port 10250 is in use

端口被启动失败或者成功的kubeadm占用

sudo netstat -ntlup|grep 10250
"""
tcp6       0      0 :::10250                :::*                    LISTEN      27560/kubelet
"""

sudo kill -9 27560
sudo kubeadm reset

2. [ERROR FileAvailable–etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists

yaml文件已存在

sudo kubeadm reset

3. [kubelet-check] The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz’ failed with error: Get http://localhost:10248/healthz: dial tcp 127.0.0.1:10248: connect: connection refused.

使用tcp协议连接到127.0.0.1:10248的连接被拒绝。这是cgroup驱动问题。默认情况下Kubernetes cgroup驱动程序设置为system,但docker设置为systemd。我们需要更改Docker cgroup驱动。

sudo vim /etc/docker/daemon.json
"""
# 如果配置了daemon.json加上{}内的参数即可
{
	"exec-opts": ["native.cgroupdriver=systemd"]
}
"""

sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl restart kubelet
sudo kubeadm reset
sudo kubeadm init

4. [ERROR CRI]: container runtime is not running: output: E1021 15:03:22.662135

参考github大佬们的讨论

rm -rf /etc/containerd/config.toml
systemctl restart containerd

三、安装网络插件

为了让Pods间可以相互通信,我们必须安装一个网络插件,并且必须在部署任何应用之前安装,CoreDNS也是在网络插件安装之后才会启动的。
网络的插件完整列表,请参考 Networking and Network Polic

在安装之前,我们先查看一下当前Pods的状态:

kubectl get pods --all-namespaces
"""
NAMESPACE     NAME                                 READY   STATUS    RESTARTS       AGE
kube-system   coredns-6d8c4cb4d-9kqvq              0/1     Pending   0             2d17h
kube-system   coredns-6d8c4cb4d-ql7g9              0/1     Pending   0             2d17h
kube-system   etcd-k8s-master                      1/1     Running   4             2d17h
kube-system   kube-apiserver-k8s-master            1/1     Running   6 (24m ago)   2d17h
kube-system   kube-controller-manager-k8s-master   1/1     Running   4             2d17h
kube-system   kube-proxy-lv8td                     1/1     Running   4             2d17h
kube-system   kube-scheduler-k8s-master            1/1     Running   5             2d17h
"""

可以看到CoreDND状态是Pending,这是因为我们还没有安装网络插件。

安装 Flannel 网络插件(选择1)

K8s网络组件Flannel的介绍和部署

Flannel是用于解决容器跨节点通信问题的解决方案,兼容CNI插件API。它使用“虚拟网桥和veth设备”的方式为Pod创建虚拟网络接口,通过可配置的“后端”定义Pod间的通信网络,支持基于VXLAN和UDP的Overlay网络,以及基于三层路由的Underlay网络。

默认情况下,Flannel网络插件使用的的网段是10.244.0.0/16,在init的时候,通过--pod-network-cidr=10.244.0.0/16来适配Flannel,当然你也可以修改kube-flannel.yml文件来指定不同的网段。命令如下

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

稍等片刻,再使用kubectl get pods --all-namespaces命令来查看网络插件的安装情况:

NAMESPACE      NAME                                 READY   STATUS    RESTARTS       AGE
kube-flannel   kube-flannel-ds-q8htw                1/1     Running   0              3m
kube-system    coredns-6d8c4cb4d-9kqvq              1/1     Running   0              2d22h
kube-system    coredns-6d8c4cb4d-ql7g9              1/1     Running   0              2d22h
kube-system    etcd-k8s-master                      1/1     Running   4              2d22h
kube-system    kube-apiserver-k8s-master            1/1     Running   6 (5h6m ago)   2d22h
kube-system    kube-controller-manager-k8s-master   1/1     Running   4              2d22h
kube-system    kube-proxy-lv8td                     1/1     Running   4              2d22h
kube-system    kube-scheduler-k8s-master            1/1     Running   5              2d22h

安装 Calico 网络插件(选择2)

Calico是一个纯三层的虚拟网络方案,Calico 为每个容器分配一个 IP,每个 host 都是 router,把不同 host 的容器连接起来。与 VxLAN 不同的是,Calico 不对数据包做额外封装,不需要 NAT 和端口映射,扩展性和性能都很好。

默认情况下,Calico网络插件使用的的网段是192.168.0.0/16,在init的时候,通过--pod-network-cidr=192.168.0.0/16来适配Calico,当然你也可以修改calico.yml文件来指定不同的网段。命令如下:

kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml

# 上面的calico.yaml会去quay.io拉取镜像,如果无法拉取,可使用下面的国内镜像
kubectl apply -f http://mirror.faasx.com/k8s/calico/v3.3.2/rbac-kdd.yaml
kubectl apply -f http://mirror.faasx.com/k8s/calico/v3.3.2/calico.yaml

关于更多Canal的信息可以查看Calico官方文档:kubeadm quickstart。

稍等片刻,再使用kubectl get pods --all-namespaces命令来查看网络插件的安装情况。

修改 cidr 地址范围

kubectl -n kube-system edit cm kubeadm-config
vim /etc/kubernetes/manifests/kube-scheduler.yaml
kubectl cluster-info dump | grep -m 1 cluster-cidr  # 检查配置是否生效

未完待续…

你可能感兴趣的:(运维,kubernetes,docker,容器)