搭建Kubernetes(k8s)集群
本文章针对cka考试,目的为使用containerd和kubeadm搭建cka考试环境。
需要kubernetes官方文档作参考。
默认情况下,Kubernetes 使用 容器运行时接口(Container Runtime Interface,CRI) 来与你所选择的容器运行时交互。
如果你不指定运行时,则 kubeadm 会自动尝试检测到系统上已经安装的运行时, 方法是扫描一组众所周知的 Unix 域套接字。
如果同时检测到 Docker 和 containerd,则优先选择 Docker。 这是必然的,因为 Docker 18.09 附带了 containerd 并且两者都是可以检测到的, 即使你仅安装了 Docker。 如果检测到其他两个或多个运行时,kubeadm 输出错误信息并退出。 kubelet 通过内置的 dockershim CRI 实现与 Docker 集成。
基础介绍
containerd简介
containerd是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性。containerd可以在宿主机中管理完整的容器生命周期,包括容器镜像的传输和存储、容器的执行和管理、存储和网络等。
Docker vs containerd
containerd是从Docker中分离出来的一个项目,可以作为一个底层容器运行时,现在它成了Kubernete容器运行时更好的选择。
K8S为什么要放弃使用Docker作为容器运行时,而使用containerd呢?
-
如果你使用Docker作为K8S容器运行时的话,kubelet需要先要通过 dockershim 去调用Docker,再通过Docker去调用containerd。
-
如果你使用containerd作为K8S容器运行时的话,由于containerd内置了 CRI (Container Runtime Interface:容器运行时接口)插件,kubelet可以直接调用containerd。
环境准备
- 三台兼容的 Linux 主机。Kubernetes 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令
- 每台机器 2 GB 或更多的 RAM (如果少于这个数字将会影响你应用的运行内存), 2 CPU 核或更多
- 集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)
- 节点之中不可以有重复的主机名、MAC 地址。
- 开启机器上的某些端口。
- 禁用交换分区。为了保证 kubelet 正常工作,必须 禁用交换分区。
- 虚拟机联网!
禁用交换分区
kubelet 在 1.8 版本以后强制要求 swap 必须关闭。要不然kubelet 无法正常启动
[root@master yum.repos.d]# swapoff -a
[root@master yum.repos.d]# vim /etc/fstab
#/dev/mapper/rhel-swap swap swap defaults 0 0
关闭 SELinux
将 SELinux 设置为 disabled模式
临时关闭
sudo setenforce 0
永久禁用
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
安装 Containerd
安装和配置的先决条件:
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
设置必需的 sysctl 参数,这些参数在重新启动后仍然存在。
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
# 应用 sysctl 参数而无需重新启动
sudo sysctl --system
安装 containerd:
从官方Docker仓库安装 containerd.io 软件包。可以在 安装 Docker 引擎 中找到有关为各自的 Linux发行版设置 Docker 存储库和安装 containerd.io 软件包的说明。
使用阿里云yum源
[root@master yum.repos.d]# vim docker-ce.repo
[docker-ce]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
gpgcheck=0
enabled=1
[root@master yum.repos.d]# yum install -y containerd.io
发现有报错!
Error: Package: containerd.io-1.6.4-3.1.el7.x86_64 (docker-ce)
Requires: container-selinux >= 2:2.74
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest
原因是因为用的rhel7.3的操作系统。centos则不需要。
[root@master yum.repos.d]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.3 (Maipo)
rhel7.3版本较低,后来使用了阿里云的centos的扩展yum源发现安装还是有依赖性,报错版本低。
因此直接使用centos的yum源。
[root@master ~]# cat /etc/yum.repos.d/
centos.repo docker-ce.repo redhat.repo
[root@master ~]# cat /etc/yum.repos.d/centos.repo
[rhrl7.3]
name=rhel7.3
baseurl=https://mirrors.aliyun.com/centos/7/os/x86_64/
gpgcheck=0
enabled=1
[root@master ~]# cat /etc/yum.repos.d/docker-ce.repo
[docker-ce]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
gpgcheck=0
[centos]
name=centos
baseurl=https://mirrors.aliyun.com/centos/7/extras/x86_64/
gpgcheck=0
containerd.io安装成功!
配置 containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
修改配置文件
[root@master ~]# cd /etc/containerd/
[root@master containerd]# ls
config.toml
[root@master containerd]# vim config.toml
在文件 config.toml 中找到该行并修改镜像源。
sandbox_image = “k8s.gcr.io/pause:3.6”
默认使用的镜像是k8s的,不科学上网连不上,改为国内阿里云镜像仓库。否则建立k8s集群时会报错。
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"
注意这条 systemd_cgroup = false 不能改为true,否则后面在node节点kubeadm
join时会报错,具体报错为:[root@node1 lib]# tail /var/log/messages Jun 11 21:37:11 localhost
kubelet: E0611 21:37:11.711773 8321 server.go:205] “Failed to load
kubelet config file” err=“failed to load Kubelet config file
/var/lib/kubelet/config.yaml, error failed to read kubelet config file
“/var/lib/kubelet/config.yaml”, error: open
/var/lib/kubelet/config.yaml: no such file or directory”
path=“/var/lib/kubelet/config.yaml” Jun 11 21:37:11 localhost systemd:
kubelet.service: main process exited, code=exited, status=1/FAILURE
Jun 11 21:37:11 localhost systemd: Unit kubelet.service entered failed
state. Jun 11 21:37:11 localhost systemd: kubelet.service failed.没有/var/lib/kubelet/config.yaml这个文件。
使用 systemd cgroup 驱动程序
结合 runc 使用 systemd cgroup 驱动,在 /etc/containerd/config.toml 中设置,
SystemdCgroup改为true。
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
如果您应用此更改,重新启动 containerd:
sudo systemctl restart containerd
安装 kubeadm kubelet kubectl
在所有机器上安装以下的软件包:
kubeadm:用来初始化集群的指令。
kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
kubectl:用来与集群通信的命令行工具。
kubeadm 不能帮你安装或者管理 kubelet 或 kubectl,所以你需要 确保它们与通过 kubeadm 安装的控制平面的版本相匹配。 如果不这样做,则存在发生版本偏差的风险,可能会导致一些预料之外的错误和问题。
一定要指定版本,否则会安装最新版。
yum install -y kubeadm-1.23.1-0 kubelet-1.23.1-0 kubectl-1.23.1-0
设置开机自启并立即启动kubelet
systemctl enable --now kubelet
kubeadm初始化:
[root@master ~]# kubeadm config print init-defaults > kubeadm-init.yaml
[root@master ~]# vim kubeadm-init.yaml
修改以下地方
提示:低版本的操作系统注意升级systemd(yum upgrade systemd
),否则会报错。
[root@master ~]# kubeadm init --config kubeadm-init.yaml
初始化成功!
Your Kubernetes control-plane has initialized successfully!
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
(
i
d
−
u
)
:
(id -u):
(id−u):(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run “kubectl apply -f [podnetwork].yaml” with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 172.25.254.1:6443 --token abcdef.0123456789abcdef
–discovery-token-ca-cert-hash sha256:14fbb510c5d836b637665f8bb451ce2de51d568ae2a574becf932998f2afe48f
[root@master ~]# export KUBECONFIG=/etc/kubernetes/admin.conf
将kubeadm init 初始化完成后的这个命令写入到下面文件,使用环境变量。
vim .bash_profile
export KUBECONFIG=/etc/kubernetes/admin.conf
[root@master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
master NotReady control-plane,master 26m v1.23.1
[root@master ~]# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6d8c4cb4d-frkfl 0/1 Pending 0 26m
kube-system coredns-6d8c4cb4d-x85ct 0/1 Pending 0 26m
kube-system etcd-master 1/1 Running 0 26m
kube-system kube-apiserver-master 1/1 Running 0 26m
kube-system kube-controller-manager-master 1/1 Running 0 26m
kube-system kube-proxy-rt476 1/1 Running 0 26m
kube-system kube-scheduler-master 1/1 Running 0 26m
缺少网络组件。
安装flannel网络插件,采用离线安装
浏览器打开 https://kubernetes.io/docs/concepts/cluster-administration/addons/
找到flannel,
下载kube-flannel.yml
wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
[root@master ~]# kubectl apply -f kube-flannel.yml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
[root@master ~]# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6d8c4cb4d-jnk68 0/1 Pending 0 6h18m
kube-system coredns-6d8c4cb4d-wxmc7 0/1 Pending 0 6h18m
kube-system etcd-master 1/1 Running 2 6h18m
kube-system kube-apiserver-master 1/1 Running 2 6h18m
kube-system kube-controller-manager-master 1/1 Running 2 6h18m
kube-system kube-flannel-ds-jjr2q 0/1 Init:0/2 0 33s
kube-system kube-proxy-w9fsp 1/1 Running 0 6h18m
kube-system kube-scheduler-master 1/1 Running 2 6h18m
该行可看到正在下载网络组件,等待下载完毕后,coredns就绪了:
kube-system kube-flannel-ds-jjr2q 0/1 Init:0/2 0 33s
查看tocken,注意这个tocken是24小时的,过期需要重新创建:
[root@master ~]# kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
abcdef.0123456789abcdef 17h 2022-06-12T06:47:01Z authentication,signing <none> system:bootstrappers:kubeadm:default-node-token
将node节点加入到集群中
node节点执行:
kubeadm join 172.25.254.1:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:14fbb510c5d836b637665f8bb451ce2de51d568ae2a574becf932998f2afe48f --v=5
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 50m v1.23.1
node1 NotReady <none> 17m v1.23.1
node2 Ready <none> 49m v1.23.1
STATUS一直为NotReady,是因为kube-flannel还未拉取成功,
[root@master ~]# kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-flannel-ds-mklgj 0/1 Init:1/2 0 2m33s 172.25.254.2 node1 <none> <none>
等待全部拉取完成后,所有节点也变为ready状态。
至此,k8s集群搭建完毕。