离线安装k8s 1.22.12版本

一、环境准备

本次k8s集群环境的搭建,选择是的模式支持docker作为容器运行时的1.22.x版本,因为之后的版本就不在默认支持docker。新版本kubernets环境搭建过程会在别人文章中详细介绍,这里不在赘述。

本次Kubernetes集群环境搭建,采用的是一个管理节点和一个工作节点的方式,因此集群环境不具备高可用性,仅能用于开发和测试使用。

操作系统选择:6.6.0-72.0.0.76.oe2403sp1.aarch64

准备两台虚拟机,本次是在HIS平台申请ARM架构的虚拟机,信息如下:

主机名 角色 操作系统 节点IP
k8s-master01 管理节点 oe2403sp1.aarch64 xx.xx.xx.71
k8s-worker01 工作节点 oe2403sp1.aarch64 xx.xx.xx.47

说明:

  1. 主机之间的操作系统版本不强制要求相同,不同的操作系统或者相同操作系统版本不同的主机之间也是可以用来搭建k8s集群环境的。例如:集群环境添加新的工作节点,不要求新的节点的操作系统,安装的软件版本等和集群节点保持一致。
  2. 主机名称建议设置自定义名称,方便记忆和识别主机的用途。如果新增工作节点,也可以只在管理节点和待添加的新工作节点配置/etc/hosts文件。推荐的做法还是集群内所有节点都添加相关信息。

二、集群部署前准备

2.1 修改主机名(可选)

登录节点,执行如下命令设置主机名称

bash 复制代码
# 管理节点
hostnamectl set-hostname k8s-master01
# 工作节点
hostnamectl set-hostname k8s-worker01

登录管理节点和工作节点,编辑/etc/hosts文件,添加配置信息如下:

bash 复制代码
xx.xx.xx.47    k8s-worker01
xx.xx.xx.71    k8s-master01

注意:请使用实际IP地址替换xx

2.2 配置源(所有节点)

在安装docker之前,首先要配置源。内网环境可以使用华为开源镜像仓来配置,链接地址如下:

https://mirrors.tools.huawei.com/home

配置操作系统镜像源

根据操作系统版本选择对应的源进行配置

在/etc/yum.repos.d/ 目录下,创建文件 openEuler.repo,根据版本及系统架构选择配置内容。

bash 复制代码
[openEuler-everything]
name=openEuler-everything
baseurl=http://mirrors.tools.huawei.com/openeuler/openEuler-24.03-LTS-SP1/everything/aarch64/
enabled=1
gpgcheck=0
gpgkey=http://mirrors.tools.huawei.com/openeuler/openEuler-24.03-LTS-SP1/everything/aarch64/RPM-GPG-KEY-openEuler
        
[openEuler-EPOL]
name=openEuler-epol
baseurl=http://mirrors.tools.huawei.com/openeuler/openEuler-24.03-LTS-SP1/EPOL/main/aarch64/
enabled=1
gpgcheck=0

[openEuler-update]
name=openEuler-update
baseurl=http://mirrors.tools.huawei.com/openeuler/openEuler-24.03-LTS-SP1/update/aarch64/
enabled=1
gpgcheck=0

执行yum clean all清除原有 yum 缓存

执行yum makecache生成新的缓存。

注意:还需要关闭证书验证,需要修改/etc/yum.conf,添加sslverify=False或者sslverify=0

配置docker源

https://mirrors.tools.huawei.com/mirrorDetail/5ea6333ddd222d7ab6ecfcf1?mirrorName=docker-ce&catalog=docker

推荐使用dnf命令,因为yum后续不在更新,会逐渐被dnf替代。如果使用yum安装,有些软件包会无法安装,比如在安装yum-utils的时候就是提示找不到。

  1. 卸载原有的docker组件,以免冲突
bash 复制代码
dnf remove docker docker-common docker-selinux docker-engine
  1. 安装依赖
bash 复制代码
dnf install -y dnf-utils device-mapper-persistent-data lvm2
  1. 获取docker仓库源配置文件
bash 复制代码
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.tools.huawei.com/docker-ce/linux/centos/docker-ce.repo --no-check-certificate

注意:--no-check-certificate参数的作用是未加载证书需要忽略证书验证,不添加这个无法正常下载配置文件。

  1. 修改docker源的配置文件

OpenEuler 24.03 属于 RH EL9 系列(对应 RHEL 9.4 左右),与 CentOS Stream 9 属于同一级别。

OpenEuler 22.03 相当于 RHEL 9(大约 RHEL 9.0 ~ 9.2 左右),与 CentOS Stream 9 属于同一级别。

所以建议使用docker镜像源中的centos 9的进行替换

首先是替换仓库地址,命令如下

bash 复制代码
sed -i 's+https://download.docker.com+https://mirrors.tools.huawei.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

接下来替换配置文件中的$releasever的值为9

bash 复制代码
sed -i 's+$releasever+9+' /etc/yum.repos.d/docker-ce.repo
  1. 生成缓存
bash 复制代码
dnf makecache

2.3 安装docker(所有节点)

在 Kubernetes(k8s)中,Docker 作为容器运行时的支持情况如下:

  • 从 Kubernetes 1.20 版本开始,Docker 容器运行时被标记为 已弃用(deprecated)。
  • 从 Kubernetes 1.24 版本开始,Docker 容器运行时不再被默认支持,kubelet 中移除了对 Docker 的内置支持(dockershim 被移除)。

因此,最后一个默认支持 Docker 作为容器运行时的 Kubernetes 版本是 1.23。

在 Kubernetes 1.24 及更高版本中,如果需要使用 Docker,需要通过外部的 dockershim 适配器(如 cri-dockerd)来支持。

本次离线部署的k8s版本是1.22.12版本,因此默认是支持docker作为容器运行时的。

如果节点已经安装了docker,可以跳过安装。需要检查一下已经安装的docker版本是否满足要求,k8s 1.22.x版本通常推荐的版本是20.10.x系列docker版本,是当时最稳定和使用最广泛的版本。当然也支持以下版本:19.03.12以上、Docker 20.10.x、Docker 21.06.x、Docker 23.0.x

bash 复制代码
# 安装 docker-ce
dnf -y install docker-ce-20.10.17 docker-ce-cli-20.10.17

# 安装 containerd(如果需要)
dnf -y install containerd.io

# 安装其他插件(可选)
dnf -y install docker-buildx-plugin docker-compose-plugin

启动docker

bash 复制代码
# 重新加载守护进程
systemctl daemon-reload
# 启动docker
systemctl start docker
# 设置开机自启动
systemctl enable docker

检查docker

bash 复制代码
# 检查客户端
docker -v
# 检查服务端
docker info

三、部署k8s集群

本文安装参考来自:

https://3ms.huawei.com/next/groups/index.html#/wiki/detail?groupId=3225441\&wikiId=7342135

上传软件压缩包至服务器任意目录下,例如/opt,服务包中包含以下文件内容:

软件包链接:https://onebox.huawei.com/p/041c2ffd85e4a34fa42ab5bee018947e

bash 复制代码
k8s1.22.12/
├── kubeadm    k8s组件的二进制执行文件
├── kubectl    k8s组件的二进制执行文件
├── kubelet    k8s组件的二进制执行文件
├── kube-images    k8s组件所需的镜像
│   ├── coredns_v1.8.4.tar
│   ├── etcd_3.5.0-0.tar
│   ├── kube-apiserver_v1.22.12.tar
│   ├── kube-controller-manager_v1.22.12.tar
│   ├── kube-proxy_v1.22.12.tar
│   ├── kube-scheduler_v1.22.12.tar
│   └── pause_3.5.tar
├── kubelet-service-config    kubelet服务所需的配置
│   ├── 10-kubeadm.conf
│   └── kubelet.service
└── plugin
    ├── calico    网络插件calico所需的镜像
    │   ├── calico-cni-v3.17.6.tar
    │   ├── calico-kube-controllers-v3.17.6.tar
    │   ├── calico-node-v3.17.6.tar
    │   ├── calico-pod2daemon-flexvol-v3.17.6.tar
    │   └── calico.yaml
    ├── cni-plugins-linux-arm64-v1.1.1.tgz   CNI插件包
    └── crictl-v1.25.0-linux-arm64.tar.gz    crictl插件包

将离线安装包上传规划的目录下进行解压即可。

3.1 导入k8s镜像(kube-images目录)

bash 复制代码
# 切换到k8s镜像所在目录
cd k8s1.22.12/kube-images/
# 执行如下命令导入所有镜像
docker load -i coredns_v1.8.4.tar
docker load -i etcd_3.5.0-0.tar
docker load -i kube-apiserver_v1.22.12.tar
docker load -i kube-controller-manager_v1.22.12.tar
docker load -i kube-proxy_v1.22.12.tar
docker load -i kube-scheduler_v1.22.12.tar
docker load -i pause_3.5.tar

3.2 导入calico镜像(plugin/calico目录)

bash 复制代码
# 切换到calico镜像目录
cd ../plugin/calico/
# 导入所有镜像
docker load -i calico-cni-v3.17.6.tar
docker load -i calico-kube-controllers-v3.17.6.tar
docker load -i calico-node-v3.17.6.tar
docker load -i calico-pod2daemon-flexvol-v3.17.6.tar

3.3 cni和crictl插件安装

bash 复制代码
# 创建cni安装目录
mkdir -p /opt/cni/bin

# 解压cni和crictl软件包到相应目录
cd /opt/k8s1.22.12/plugin
tar -zxvf cni-plugins-linux-arm64-v1.1.1.tgz -C /opt/cni/bin/
tar -zxvf crictl-v1.25.0-linux-arm64.tar.gz -C /usr/local/bin/

3.4 安装kubeadm、kubelet、kubectl

bash 复制代码
# 将kubeadm、kubelet、kubectl二进制放入系统/usr/bin路径 
cd /opt/k8s1.22.12/
cp kubeadm kubectl kubelet /usr/bin/

# 添加可执行权限
cd /usr/bin/
chmod +x kubeadm kubectl kubelet

# 创建配置文件目录
mkdir -p /etc/systemd/system/kubelet.service.d/

# 将kubelet服务配置文件复制到相应目录
cd /opt/k8s1.22.12/kubelet-service-config/
cp 10-kubeadm.conf /etc/systemd/system/kubelet.service.d/
cp kubelet.service /etc/systemd/system/

# 设置开机自启
systemctl enable --now kubelet

3.5 检查cgroup driver配置

kubelet需要和docker拥有的相同的cgroup才能正常运行,kubelet默认配置文件中cgroup设置为systemd和docker默认的cgroupfs

由于多数linux发行版中cgroup驱动也为systemd,因此k8s社区推荐配置为与系统一致,检查/etc/docker/daemon.json路径下的配置文件是否配置为systemd,如果没有该文件,创建该文件并配置以下内容

bash 复制代码
# 编辑daemon.json配置文件
vim /etc/docker/daemon.json
# 添加如下内容
{
    "exec-opts": ["native.cgroupdriver=systemd"]
}
# 重新加载守护进程
systemctl daemon-reload
# 重启docker
systemctl restart docker

3.6 关闭swap

临时关闭swap命令如下

bash 复制代码
swapoff -a

永久关闭swap推荐一下两种方式

bash 复制代码
# 方式1、注释 /etc/fstab 中的 swap 行

# 方式2、设置 sysctl 参数
# 降低 swappiness(设为 0 表示尽量不使用 swap)
echo "vm.swappiness = 0" >> /etc/sysctl.conf
sysctl -p

3.7 检查并安装依赖

k8s部署依赖的软件检查,如果没有安装可以使用如下命令安装

bash 复制代码
yum install -y curl wget socat conntrack-tools ebtables ipvsadm ipset

3.8 关闭防火墙 和 SELinux(可选)

本次离线安装没有执行也能正常初始化kubeadm

bash 复制代码
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
 
# 关闭 SELinux
# 临时关闭 (重启后失效)
setenforce 0
 
# 永久关闭
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

3.9 配置内核参数(可选)

本次离线安装没有执行也能正常初始化kubeadm

配置内核参数之前,需要先检查一下需要的内核模块是否已经加载。比如初始化的时候就遇到过缺少br_netfilter的情况。详细请见FAQ中初始化常见报错介绍

bash 复制代码
立即加载模块:在终端执行以下命令,让当前内核会话加载 br_netfilter 模块。
modprobe br_netfilter
验证模块是否加载成功:执行以下命令,如果看到输出,就说明模块已经成功加载。
lsmod | grep br_netfilter
确保重启后模块自动加载:为了确保服务器重启后模块能自动加载,需要将它加入系统的模块配置文件中。
echo 'br_netfilter' | tee -a /etc/modules-load.d/k8s.conf
bash 复制代码
# 加载内核模块并设置必要的网络参数。
 
# 创建 K8s 内核参数配置文件
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
 
# 应用参数
sysctl --system

四、初始化kubeadm

4.1 初始化

登录管理节点,执行初始化操作。工作节点不需要执行。

初始化命令如下

bash 复制代码
kubeadm init \
    --kubernetes-version=v1.22.12 \
    --pod-network-cidr=192.168.0.0/16 \
    --apiserver-advertise-address=xx.xx.xx.71

初始化成功后的信息记录

bash 复制代码
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 $(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 7.212.76.71:6443 --token w7pxpt.wxamtph9xgax0p24 \
        --discovery-token-ca-cert-hash sha256:63b40a84848f8e77e9a84baac8486ab95edae3c08ad2ff1754dbf4c52ac65fe4

初始化成功后根据提示执行如下命令:

bash 复制代码
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

查看组件的运行状态

bash 复制代码
[root@k8s-master01 kubelet-service-config]# kubectl get pod -A
NAMESPACE     NAME                                   READY   STATUS    RESTARTS   AGE
kube-system   coredns-78fcd69978-qk6dk               0/1     Pending   0          5m37s
kube-system   coredns-78fcd69978-w8kwc               0/1     Pending   0          5m37s
kube-system   etcd-k8s-master01                      1/1     Running   0          5m51s
kube-system   kube-apiserver-k8s-master01            1/1     Running   0          5m51s
kube-system   kube-controller-manager-k8s-master01   1/1     Running   0          5m51s
kube-system   kube-proxy-8r6nh                       1/1     Running   0          5m37s
kube-system   kube-scheduler-k8s-master01            1/1     Running   0          5m51s

此时的coredns的pod还是未就绪的状态,原因是还没有部署网络插件calico。所以可以吧网络插件的部署放在查询组件运行状态之前执行。

4.2 部署网络插件calico

bash 复制代码
# 切换到网络插件calico的目录
cd /opt/k8s1.22.12/plugin/calico/
# 部署calico应用
kubectl apply -f calico.yaml
bash 复制代码
[root@k8s-master01 bin]#  cd /opt/k8s1.22.12/plugin/calico/
[root@k8s-master01 calico]#  kubectl apply -f calico.yaml
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
Warning: policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget
poddisruptionbudget.policy/calico-kube-controllers created

部署完成后查询组件状态

bash 复制代码
[root@k8s-master01 calico]# kubectl get pod -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-567bf7f654-lcwdc   1/1     Running   0          30s
kube-system   calico-node-kd79l                          1/1     Running   0          30s
kube-system   coredns-78fcd69978-qk6dk                   1/1     Running   0          15m
kube-system   coredns-78fcd69978-w8kwc                   1/1     Running   0          15m
kube-system   etcd-k8s-master01                          1/1     Running   0          16m
kube-system   kube-apiserver-k8s-master01                1/1     Running   0          16m
kube-system   kube-controller-manager-k8s-master01       1/1     Running   0          16m
kube-system   kube-proxy-8r6nh                           1/1     Running   0          15m
kube-system   kube-scheduler-k8s-master01                1/1     Running   0          16m
[root@k8s-master01 calico]# kubectl get nodes
NAME           STATUS   ROLES                  AGE   VERSION
k8s-master01   Ready    control-plane,master   16m   v1.22.12

五、添加工作节点

管理节点初始化完成后,输出的有一条命令就是用来给k8s集群添加工作节点的

bash 复制代码
Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 7.212.76.71:6443 --token w7pxpt.wxamtph9xgax0p24 \
        --discovery-token-ca-cert-hash sha256:63b40a84848f8e77e9a84baac8486ab95edae3c08ad2ff1754dbf4c52ac65fe4

待加入的工作节点,必须完成前面步骤的准备工作,才能执行该命令。

bash 复制代码
[root@k8s-worker01 kubelet-service-config]# systemctl enable --now kubelet
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service → /etc/systemd/system/kubelet.service.
[root@k8s-worker01 kubelet-service-config]# kubeadm join 7.212.76.71:6443 --token w7pxpt.wxamtph9xgax0p24 \
        --discovery-token-ca-cert-hash sha256:63b40a84848f8e77e9a84baac8486ab95edae3c08ad2ff1754dbf4c52ac65fe4
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

[root@k8s-worker01 kubelet-service-config]#

执行完成后,可以到管理节点查询状态

bash 复制代码
[root@k8s-master01 calico]# kubectl get nodes
NAME           STATUS   ROLES                  AGE   VERSION
k8s-master01   Ready    control-plane,master   27m   v1.22.12
k8s-worker01   Ready    <none>                 32s   v1.22.12
相关推荐
涛声依旧-底层原理研究所2 小时前
Docker+K8s:云原生应用基石
docker·kubernetes
yn002 小时前
Docker 一键部署加密支付网关:从零开始完整教程
运维·docker·容器
2301_780029042 小时前
互联网架构演进精读:从单机到云原生
云原生·架构
IT策士2 小时前
第14篇 Docker Compose 开发环境最佳实践:热重载与调试
运维·docker·容器
运维老郭2 小时前
【Kubernetes 性能排查】线上服务突然变慢?SRE 的 4 层排查法
运维·云原生·kubernetes
正在走向自律2 小时前
架构进阶:从 Docker 环境变量到 Nacos 统一配置中心实战
docker·容器·架构
Hui Baby2 小时前
K8S自定义API
容器·贪心算法·kubernetes
炸炸鱼.10 小时前
Kubernetes高级调度02:Taint/Toleration、Cordon/Drain、亲和性与反亲和性完全指南
云原生·容器·kubernetes
海兰14 小时前
Kibana Dashboard as Code:Elastic 9.4 如何用 Terraform 和类型化 API 终结“JSON 垃圾袋“
云原生·json·terraform