k8s部署

https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/

教程来源于武汉誉天,本文章在实践中整理代码和说明

其他教程

https://juejin.cn/post/7107954026875977764

01 Docker和Containerd关系

Docker Engine核心组件Container,后将其开源并捐赠给CNCF(云原生计算基金会),作为独立的项目运营。也就是说Docker Engine里面是包含Containerd的,安装Docker后,就会有Containerd,Containerd也可以单独安装,无需安装Docker。

02 为什么要说明他们的关系——引入dockershim

早期,Kubernetes集成了Docker Engine这个容器启动时,之后k8s为了兼容更多容器运行时(比如containerd/CRI-O),创建了一个CRI(Container Runtime Interface)容器运行时接口标准,指定标准的目的是为了实现编排器(如Kubernetes)和其他不同的容器运行时之间交互操作。但是,Docker Engine本身就是一个完整的技术栈,没有实现(CRI)接口,也不可能为了迎合k8s编排工具指定的CRI标准而改变底层架构,于是,k8s引入了一个临时dockershim这个项目是k8是维护的项目,目的是为了解决Docker本身无法适配CRI而提出的。也就是通过dockershim,可以让k8s的代理kubelet通过CRI来调用Docker Engine进行容器的操作。

03 那为何在v1.24版本中删除dockershim

k8s在1.7版本中就已经将containerd和kubelet集成使用了。既然最终我们都是要调用containerd这个容器运行时。那干嘛非得多一个dockershim?而且dockershim本身就是作为一个临时过渡的产品来使用。如果剔除dockershim转而直接使用containerd,调用链岂不是更短?执行效率岂不是更高?而且维护dockershim已经成为kubernetes维护者的沉重负担。
于是Kubernetes官方发布公告,宣布自v1.20起放弃对Docker的支持,v1.20的版本中,会收到一个docker的弃用警告,在未来v1.22版本之前是不会删除的,这意味着2021年底的v1.23版本,还有1年的时间来寻找合适的CRI运行时来确保顺利过渡,比如containerd和CRI.
Docker没有被淘汰,也没有被弃用,只是在1.24.0中删除了dockershim而已。

0.环境

设置IP地址
使用hostname set-hostname修改主机名

1
2
3
hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2

1.装包

1
yum install -y yum-utils vim bash-completion net-tools wget

2.设置/etc/hosts

每台节点都需要设置

1
2
3
4
IP地址 主机名
xxx master
xxx node1
xxx node2

3.关闭防火墙和SElinux

1
2
3
4
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled /g' /etc/selinux/config

4.关闭swap

1
2
swapoff -a
sed -i "s/^.*swap/#&/g" /etc/fstab

5.安装docker-ce

1
2
3
4
5
6
7
8
9
10
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

echo 'list docker-ce version'

yum list docker-ce --showduplicates | sort -r

yum install -y docker-ce #默认安装最新版
#yum install -y docker-ce-20.10.0 指定20.10.0版本
systemctl start docker
systemctl enable docker

或者

1
2
3
yum install -y containerd
systemctl start containerd
systemctl enable containerd

6.iptables

转发 IPv4 并让 iptables 看到桥接流量

1
2
3
4
5
6
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sysctl -p /etc/sysctl.d/k8s.conf

初始化过程中,可能会遇到“/proc/sys/net/bridge/bridge-nf-call-iptables does not exist”的错误,这是因为之前配置的br_netfilter没有启动,运行一下命令即可

1
2
modprobe br_netfilter
echo 1 > /proc/sys/net/ipv4/ip_forward

7.设置 cgroup(systemd/cgroupfs)

1
2
3
4
5
6
containerd config default > /etc/containerd/config.toml
sed -i "s#registry.k8s.io/pause#registry.aliyuncs.com/google_containers/pause#g" /etc/containerd/config.toml

sed -i 's/SystemdCgroup = false/SystemdCgroup=true/g' /etc/containerd/config.toml

systemctl restart containerd

kubeadm默认使用的 cgroupfs.

linux系统初始化的时候默认用 systemd.

kubelet和底层容器运行时都需要对接控制组来强制执行为Pod和容器管理资源,并为诸如CPU、内存这类资源设置请求和限制。

8.kubernetes.repo

1
2
3
4
5
6
7
8
9
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

9.crictl 运行端点

1
2
3
4
5
6
cat << EOF > /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 5
debug: false
EOF

如果不配置执行crictl img报错

10.安装kube工具

1
2
3
yum install -y kubelet-1.26.0 kubeadm-1.26.0 kubectl-1.26.0 --disableexcludes=kubernetes

systemctl enable --now kubelet

操作完成提示

1
2
3
4
5
6
Installed:
conntrack-tools-1.4.5-17.el9_1.x86_64 cri-tools-1.26.0-0.x86_64
kubeadm-1.26.0-0.x86_64 kubectl-1.26.0-0.x86_64
kubelet-1.26.0-0.x86_64 kubernetes-cni-1.2.0-0.x86_64
libnetfilter_cthelper-1.0.0-22.el9.x86_64 libnetfilter_cttimeout-1.0.0-19.el9.x86_64
libnetfilter_queue-1.0.5-1.el9.x86_64 socat-1.7.4.1-5.el9.x86_64

1-10在全部节点上操作


11.集群初始化(仅在master节点操作)

1
kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.26.0 --pod-network-cidr=10.244.0.0/16

镜像–创建容器(pod)

提示(按照字面意思操作)

1
2
3
4
5
6
7
8
9
To start using your cluster, you need to run the following as a regular user:

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

Alternatively, if you are the root user, you can run:

export KUBECONFIG=/etc/kubernetes/admin.conf #临时生效(退出当前窗口重连环境变量失效)

root用户将KUBECONFIG环境变量添加到/etc/profile里

1
2
echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> /etc/profile #永久生效
source /etc/profile

如果不执行添加环境变量会出现以下错误

1
couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused

12.将节点加入集群

在master中执行集群初始化后会得到kubeadm join –token,将命令在其他node节点中执行。

1
2
kubeadm join 10.10.102.11:6443 --token 6kjfp7.f9r6v7jzq5s2vawf \
--discovery-token-ca-cert-hash sha256:8a3058f9a116c8147098ca905a59823aa027b34a92cfcd25540069f023b579d5

查看集群节点情况

1
kubectl get nodes

如果token忘记可以重新生成加入命令

生成新的token旧的依然可以用

1
kubeadm token create --print-join-command

重置集群

重置集群命令如下

1
2
3
4
5
6
7
8
9
10
11
12
#删除配置文件
kubeadm reset
rm /etc/cni/net.d/* -f
systemctl daemon-reload
systemctl restart kubelet


#在master上重新初始化集群
kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.26.0 --pod-network-cidr=10.244.0.0/16

#在node上重新加入集群
kubeadm join......

查询集群

查询集群命令如下

1
2
#查询默认的命名空间,默认只有四个(ns是namespace)
kubectl get ns
1
2
3
4
5
6
7
#输出结果
NAME STATUS AGE
default Active 16m
kube-node-lease Active 16m
kube-public Active 16m
kube-system Active 16m
#支撑当前集群的pod都在kube-system里

查询集群pod

1
kubectl get pod -n kube-system
1
2
3
4
5
6
7
8
9
10
11
12
13
#输出结果
NAME READY STATUS RESTARTS AGE
coredns-5bbd96d687-6cnh9 0/1 Pending 0 20m
coredns-5bbd96d687-wpxpn 0/1 Pending 0 20m
etcd-k8smaster 1/1 Running 2 21m
kube-apiserver-k8smaster 1/1 Running 2 20m
kube-controller-manager-k8smaster 1/1 Running 2 20m
kube-proxy-m75hv 1/1 Running 0 20m
kube-proxy-nv72f 1/1 Running 0 11m
kube-proxy-vmn6w 1/1 Running 0 8m27s
kube-scheduler-k8smaster 1/1 Running 2 20m
#STATUS Pending是挂起
#STATUS Running是正在运行

13.安装calico网络

https://docs.tigera.io/calico/3.25/getting-started/kubernetes/quickstart#install-calico

网络问题可能无法直接安装
两步骤:

1.Install the Tigera Calico operator and custom resource definitions.

1
2
3
4
5
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/tigera-operator.yaml
#完成后会启动一个rigera-operator的命名空间
#kubectl get ns
#查看pod运行情况
#kubectl get pod -n tigera-operator

2.Install Calico by creating the necessary custom resource. For more information on configuration options available in this manifest, see the installation reference.

1
2
#需要修改yaml文件中的cidr,可以先下载
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/custom-resources.yaml
1
2
3
4
5
6
7
8
9
10
11
#本地下载
wget https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/custom-resources.yaml
#修改yaml中的cidr
cidr: 10.244.0.0/16
#通过yaml文件创建
kubectl create -f custom-resources.yaml
#查看镜像列表
crictl img

#安装完成后有6个
#cni、csi、kube-controllers、node-driver-registrar、node、pod2daemon-flexvol、typha、apiserver
1
2
3
4
5
6
7
8
#此时查询集群状态
kubectl get nodes
#输出
#NAME STATUS ROLES AGE VERSION
#k8smaster Ready control-plane 35m v1.26.0
#k8snode1 Ready <none> 25m v1.26.0
#k8snode2 Ready <none> 22m v1.26.0
#node1,node2的STATUS变为Ready.

1.24版本后crictl与docker相互独立,crictl拉取的镜像docker无法获取,docker拉取的镜像crictl也看不到

1
2
#查看某个节点的明细(NAME是查询集群输出的NAME)
kubectl describe node NAME

问题 k8s从节点不能运行kubectl命令的解决方法

运行命令:

1
kubectl get pod

报错:
The connection to the server localhost:8080 was refused - did you specify the right host or port?

解决方法:

1
2
cat  /etc/kubernetes/kubelet.conf 
clusters.cluster.server 中显示的是master的地址

登陆到master节点,复制主节点文件/etc/kubernetes/admin.conf到从节点的相同路径即可

参考资料

https://blog.csdn.net/qq_17303159/article/details/110221074

https://blog.csdn.net/lfm940624/article/details/84706118