Bootstrap

Kubernetes v1.28.15 本地化部署(亲测有效,每一步都是真实操作记录)

Kubernetes v1.28.15 本地化部署详细指南

一、引言

在当今云计算和容器技术蓬勃发展的时代,Kubernetes(简称 k8s)作为一款强大的容器编排与管理平台,已成为众多企业和开发者构建、部署和管理容器化应用的首选。它能够高效地自动化应用的部署、扩展和管理,显著提升开发和运维的效率。本文将详细阐述一个 Kubernetes 集群的部署过程,旨在帮助读者深入理解并成功搭建自己的 k8s 集群。

在进行 Kubernetes 安装时,部分用户可能会因为网络或其他各种原因,导致安装过程非常缓慢。为了解决这一问题,我们尝试进行 Kubernetes v1.28.15 的本地化部署,以下是详细的部署步骤和说明。

二、A 集群信息

(一)节点规划

在部署 k8s 集群时,节点按照用途可划分为以下 2 类角色:

  • master 节点

    • 作为集群的 master 节点,承担着集群的初始化任务,是整个集群的核心控制节点。
    • 基础配置要求不低于 2C4G,以确保其能够稳定运行,高效处理集群的管理和调度任务。
  • node 节点(即 slave 节点)

    • 作为集群的工作节点,负责运行用户部署的各种应用容器。
    • 可以根据实际需求部署多台,基础配置同样不低于 2C4G,以保证能够承载相应的工作负载。

为了演示 slave 节点的添加过程,本次部署方案为 1 台 master 节点和 2 台 slave 节点,具体规划如下:

主机名节点 IP角色部署组件
k8s - master192.168.64.128masteretcd, kube - apiserver, kube - controller - manager, kubeadm
kubectl,kubelet, kube - proxy, flannel
k8s - slave1192.168.64.129slavekubectl, kubelet, kube - proxy, flannel
k8s - slave2192.168.64.130slavekubectl, kubelet, kube - proxy, flannel
Centos7192.168.64.131hostrpm, *.tar, *.sh, *.yaml,主要用于存放安装集群所需的所有包

(二)组件版本

本次部署所使用的各组件的具体版本信息如下:

组件版本说明
CentOSCentOS Linux release 7.9.2009 (Core)操作系统版本
KernelLinux 3.10.0 - 1160.71.1.el7.x86_64内核版本
etcd3.5.15 - 0使用容器方式部署,默认数据挂载到本地路径
corednsv1.10.1DNS 服务组件版本
kubeadmv1.28.15用于初始化集群的工具版本
kubectlv1.28.15Kubernetes 命令行工具版本
kubeletv1.28.15节点上运行的代理版本
kube - proxyv1.28.15服务网络代理版本
flannelv0.26.4网络插件版本

三、安装前准备工作

之前的文章中已经对部分准备工作进行了说明,此处不再赘述。如有需要,可查看详细信息:https://blog.csdn.net/sido777/article/details/145665158。现在我们主要关注 host 这台主机的操作步骤。

(一)设置 yum 源

以下是设置 yum 源的详细步骤及命令:

# 删除原有的 CentOS 基础 yum 源文件,避免可能存在的冲突
rm -f /etc/yum.repos.d/CentOS-Base.repo 

# 从阿里云镜像源下载 CentOS 7 的 yum 源文件,替换原有的基础源
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

# 从阿里云镜像源下载 Docker CE 的 yum 源文件,以便后续安装 Docker 相关组件
curl -o /etc/yum.repos.d/Docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 创建 Kubernetes 的 yum 源文件,指定相关信息
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/repodata/repomd.xml.key
EOF

# 清除 yum 缓存并重新生成缓存,使新的 yum 源生效
yum clean all && yum makecache

(二)下载安装包

使用 yum -y --downloadonly 命令可以只下载软件包而不进行安装,方便我们在本地进行管理和部署。

# 先移除 yum-utils 以避免可能的版本冲突
yum remove yum-utils -y

# 下载 Docker 相关组件和工具到指定目录,仅下载不安装
yum -y --downloadonly --downloaddir /root/Docker/ install yum-utils docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 从 GitHub 下载 cri-dockerd 的 RPM 包到 Docker 目录
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.14/cri-dockerd-0.3.14-3.el7.x86_64.rpm -O Docker/cri-dockerd-0.3.14-3.el7.x86_64.rpm

下载完成后,可进行查看。如果发现 createrepo 命令未找到,说明该工具未安装,需要进行下载和安装。

# 安装 createrepo 工具,用于创建本地 yum 仓库,顺便得tree也安装一下了
yum -y install createrepo tree

# 测试 createrepo 是否安装成功,查看其版本信息
createrepo --version

(三)创建 Docker Yum 软件源

进入 Docker 安装包所在目录,使用 createrepo 命令创建本地 yum 仓库。

# 切换到 Docker 目录
cd /root/Docker

# 创建 Docker 本地 yum 仓库,生成 repodata 索引文件
createrepo . 
cd /root

使用 ls 命令查看生成情况,会发现 Docker 目录下多了一个 repodata 文件夹,该文件夹包含 RPM 软件包的索引信息,客户端通过这些索引信息可以方便地访问软件包。

接下来创建 Docker 的 repo 文件,具体命令如下:

# 备份原有的 Docker-ce.repo 文件,防止误操作
mv /etc/yum.repos.d/Docker-ce.repo /etc/yum.repos.d/Docker-ce.repo.bak

# 创建新的 Docker 本地 yum 源配置文件
cat << "EOT" > /etc/yum.repos.d/Loaddocker.repo
[docker]
name=Load Docker File
baseurl=file:///root/Docker
enabled=1
gpgcheck=0
EOT

# 清除 yum 缓存并重新生成缓存,使新的 Docker yum 源生效
yum clean all && yum makecache

现在 Docker 的 yum 源已经准备好了,我们可以在本机进行测试安装。

# 安装 Docker 及其相关组件,包括 cri-dockerd
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin cri-dockerd

# 配置 Docker 加速,创建 Docker 配置文件目录
mkdir -p /etc/docker

# 写入 Docker 配置文件,设置执行选项和镜像加速器
cat <<EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://hub.urlsa.us.kg",
    "https://docker.urlsa.us.kg"
  ]
}
EOF

# 配置 cri-docker.service,添加 pod 基础容器镜像
sed -i '/ExecStart/s/$/ --pod-infra-container-image=registry.aliyuncs.com\/google_containers\/pause:3.9/' /usr/lib/systemd/system/cri-docker.service

# 重载系统服务管理器配置,使新的服务配置生效
systemctl daemon-reload 

# 启用并重启 cri-docker 和 Docker 服务
systemctl enable cri-docker && systemctl restart cri-docker
systemctl enable docker && systemctl restart docker

(四)下载 Kubernetes 相关包并创建 yum 源

使用 yum -y --downloadonly 命令下载 Kubernetes 相关组件的安装包到指定目录。

# 下载 ipset、ipvsadm、kubelet、kubeadm 和 kubectl 到指定目录,仅下载不安装,且不进行 GPG 签名检查
yum -y --downloadonly --downloaddir /root/Kubernetes/ install ipset ipvsadm kubelet kubeadm kubectl --nogpgcheck

下载完成后,进入 Kubernetes 安装包所在目录,创建本地 yum 仓库。

# 切换到 Kubernetes 目录
cd /root/Kubernetes/

# 创建 Kubernetes 本地 yum 仓库,生成 repodata 索引文件
createrepo . 
cd /root

创建 repo 文件并安装 Kubernetes 相关组件,具体命令如下:

# 备份原有的 kubernetes.repo 文件,防止误操作
mv /etc/yum.repos.d/kubernetes.repo /etc/yum.repos.d/kubernetes.repo.bak

# 创建新的 Kubernetes 本地 yum 源配置文件
cat << "EOT" > /etc/yum.repos.d/LoadKubernetes.repo
[kubernetes]
name=Load Kubernetes File
baseurl=file:///root/Kubernetes
enabled=1
gpgcheck=0
EOT

# 清除 yum 缓存并重新生成缓存,使新的 Kubernetes yum 源生效
yum clean all && yum makecache

# 安装 ipset、ipvsadm、kubelet、kubeadm 和 kubectl,不进行 GPG 签名检查
yum install -y install ipset ipvsadm kubelet kubeadm kubectl --nogpgcheck

(五)pull 镜像包脚本

创建一个用于 pull 镜像包的脚本 pull.sh

vim /root/pull.sh

按 i 进入编辑模式,把下面内容贴进去,再按 esc 键退出编辑模式,输入 :wq 保存退出。

#!/bin/bash
# master 下载镜像,imaweb 是镜像源,可使用阿里云镜像源或其他,images 为全部镜像列表
imaweb=registry.cn-hangzhou.aliyuncs.com/google_containers
images=(
kube-apiserver:v1.28.15
kube-controller-manager:v1.28.15
kube-scheduler:v1.28.15
kube-proxy:v1.28.15
pause:3.9
etcd:3.5.15-0
coredns:v1.10.1
)
for imageName in ${images[@]} ; do
docker pull $imaweb/$imageName  # 从阿里云拉取镜像
done
docker pull ghcr.io/flannel-io/flannel-cni-plugin:v1.6.2-flannel1
docker pull ghcr.io/flannel-io/flannel:v0.26.4
# 导出 docker 镜像
for imag in `docker images | awk '{print $1":"$2}'|grep -v TAG` ; do
imgname="`echo -e ${imag}|sed 's/^.*\///g'`.tar"
docker save -o $imgname $imag
done
mkdir -p /root/{master-tar,node-tar}
cp {flannel-cni-plugin\:v1.6.2-flannel1.tar,flannel\:v0.26.4.tar,kube-proxy\:v1.28.15.tar,pause\:3.9.tar} /root/node-tar
mv *.tar /root/master-tar

下载镜像执行命令:

bash /root/pull.sh

下面用 tree 看一下结果:

[root@localhost ~]# tree
.
├── anaconda-ks.cfg
├── Docker
│   ├── audit-libs-python-2.8.5-4.el7.x86_64.rpm
│   ├── checkpolicy-2.5-8.el7.x86_64.rpm
│   ├── containerd.io-1.6.33-3.1.el7.x86_64.rpm
│   ├── container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm
│   ├── cri-dockerd-0.3.14-3.el7.x86_64.rpm
│   ├── docker-buildx-plugin-0.14.1-1.el7.x86_64.rpm
│   ├── docker-ce-26.1.4-1.el7.x86_64.rpm
│   ├── docker-ce-cli-26.1.4-1.el7.x86_64.rpm
│   ├── docker-ce-rootless-extras-26.1.4-1.el7.x86_64.rpm
│   ├── docker-compose-plugin-2.27.1-1.el7.x86_64.rpm
│   ├── fuse3-libs-3.6.1-4.el7.x86_64.rpm
│   ├── fuse-overlayfs-0.7.2-6.el7_8.x86_64.rpm
│   ├── libcgroup-0.41-21.el7.x86_64.rpm
│   ├── libsemanage-python-2.5-14.el7.x86_64.rpm
│   ├── policycoreutils-python-2.5-34.el7.x86_64.rpm
│   ├── python-IPy-0.75-6.el7.noarch.rpm
│   ├── repodata
│   │   ├── 2117d0a813c83fe8b1fc3963d8cd3889ca518d582a47ac5fb6e2dc32b093e5f1-primary.sqlite.bz2
│   │   ├── 219a7502373818d2d7f7a56dcb7f8148329e021715e288f44b1344d09b3d8e4e-filelists.sqlite.bz2
│   │   ├── 3b261d49363be305bef5d503bf935d610957ec6bea125328726fc0bcb04b41cb-filelists.xml.gz
│   │   ├── 8497ead6997634741977c2bf8b35ddb6121879e2c07dd82047b18e5fb5b18a61-other.sqlite.bz2
│   │   ├── 912d217d31ccc56cb177df6de998254b37d03cd9f0d2063b599de70e6adf68d2-other.xml.gz
│   │   ├── d4f36866e943b573726d193e477e4c1e1a8776837fb6cbda97771a18339e0774-primary.xml.gz
│   │   └── repomd.xml
│   ├── setools-libs-3.3.8-4.el7.x86_64.rpm
│   ├── slirp4netns-0.4.3-4.el7_8.x86_64.rpm
│   └── yum-utils-1.1.31-54.el7_8.noarch.rpm
├── Kubernetes
│   ├── conntrack-tools-1.4.4-7.el7.x86_64.rpm
│   ├── cri-tools-1.28.0-150500.1.1.x86_64.rpm
│   ├── ipvsadm-1.27-8.el7.x86_64.rpm
│   ├── kubeadm-1.28.15-150500.1.1.x86_64.rpm
│   ├── kubectl-1.28.15-150500.1.1.x86_64.rpm
│   ├── kubelet-1.28.15-150500.1.1.x86_64.rpm
│   ├── kubernetes-cni-1.2.0-150500.2.1.x86_64.rpm
│   ├── libnetfilter_cthelper-1.0.0-11.el7.x86_64.rpm
│   ├── libnetfilter_cttimeout-1.0.0-7.el7.x86_64.rpm
│   ├── libnetfilter_queue-1.0.2-2.el7_2.x86_64.rpm
│   └── repodata
│       ├── 469f8b637f1527f2b1c75a7a91b739d04e3fd3206cbfff13b26365848152a7a5-filelists.xml.gz
│       ├── 64f215e3b81202440d5521cd0459006bf6e0f351e4f2fc5dd0f1a108426b3b93-primary.xml.gz
│       ├── 7c6485d1f5315c2b30ff68ff283b20b36ecbb4ac05600de11da7a4e6f1c48a3a-primary.sqlite.bz2
│       ├── 8a525f92bc137b93a93e223ae1aefcc9149da7b7732c7ec4c173a86a0b8cb444-other.xml.gz
│       ├── dda9540e844d829c76929c6546312726b9ac4ab3323a645daed2e6378e21894b-other.sqlite.bz2
│       ├── e3e5859bf9759d56613a5c853a2e607172870384ef4513ebc75748d80ceedec4-filelists.sqlite.bz2
│       └── repomd.xml
├── master-tar
│   ├── coredns:v1.10.1.tar
│   ├── etcd:3.5.15-0.tar
│   ├── flannel-cni-plugin:v1.6.2-flannel1.tar
│   ├── flannel:v0.26.4.tar
│   ├── kube-apiserver:v1.28.15.tar
│   ├── kube-controller-manager:v1.28.15.tar
│   ├── kube-proxy:v1.28.15.tar
│   ├── kube-scheduler:v1.28.15.tar
│   └── pause:3.9.tar
├── node-tar
│   ├── flannel-cni-plugin:v1.6.2-flannel1.tar
│   ├── flannel:v0.26.4.tar
│   ├── kube-proxy:v1.28.15.tar
│   └── pause:3.9.tar
└── pull.sh

6 directories, 58 files

四、整理脚本

关键信息及逻辑关联

  1. yum 源整理脚本(/root/repo.sh)
    • 逻辑起点:该脚本以清除有问题的默认 CentOS 源文件为起点,为后续添加自定义 yum 源铺平道路。
    • 核心任务:创建 Docker 和 Kubernetes 的 yum 源,确保系统能够从指定的本地目录加载所需的软件包。这一步就像是为系统搭建了一个专属的“软件超市”,让系统能够方便快捷地获取所需的“商品”。
    • 后续铺垫:清理 yum 缓存、关闭 swap 分区、禁用 SELinux 和防火墙等操作,为后续的容器化和集群化部署消除潜在的障碍。这些操作就像是为系统进行一次全面的“体检”,排除可能影响系统性能的“隐患”。
    • 模块加载与内核参数调整:添加需要加载的模块并修改内核参数,为容器化和网络虚拟化提供必要的支持。这一步就像是为系统安装了“增强引擎”,提升系统的性能和稳定性。
  2. Docker 安装脚本(/root/docker.sh)
    • 依赖关系:依赖于前面的 yum 源整理脚本,确保系统能够从正确的源获取 Docker 相关的软件包。
    • 核心任务:安装 Docker 及其相关组件,配置 Docker 加速和 cri-docker.service,最后重载服务并启动 Docker。这一步就像是为系统搭建了一个强大的“容器工厂”,让系统能够高效地创建和管理容器。
  3. Kubernetes 安装脚本(/root/kubernetes.sh)
    • 依赖关系:依赖于前面的 Docker 安装脚本,确保 Docker 环境已经正确配置。
    • 核心任务:安装 Kubernetes 相关组件,配置 containerd,修改 kubelet 配置文件,最后设置 kubelet 开机自启。这一步就像是为系统搭建了一个“集群指挥中心”,让系统能够高效地管理和调度容器集群。

yum 源脚本

vim /root/repo.sh

按 i 进入编辑模式,把下面内容贴进去,再按 esc 键退出编辑模式,输入 :wq 保存退出。

#!/bin/bash
rm -f /etc/yum.repos.d/CentOS-Base.repo
# 此命令用于删除有问题的默认 CentOS 源文件,确保后续配置的 yum 源不会受到干扰。操作前请确认该文件确实存在,避免误删其他重要文件。
cat << "EOT" > /etc/yum.repos.d/Loaddocker.repo
[docker]
name=Load Docker File
baseurl=file:///root/Docker
enabled=1
gpgcheck=0
EOT
# 创建 Docker 的 yum 源文件,将 Docker 软件包的信息写入该文件,以便系统能够从指定的本地目录加载 Docker 软件包。
cat << "EOT" > /etc/yum.repos.d/LoadKubernetes.repo
[kubernetes]
name=Load Kubernetes File
baseurl=file:///root/Kubernetes
enabled=1
gpgcheck=0
EOT
# 创建 Kubernetes 的 yum 源文件,将 Kubernetes 软件包的信息写入该文件,以便系统能够从指定的本地目录加载 Kubernetes 软件包。
yum clean all && yum makecache
# 清理 yum 缓存并重新生成缓存,确保系统能够正确识别新添加的 yum 源。
swapoff -a 
# 关闭所有 swap 分区,避免在使用容器化技术时出现性能问题。
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab 
# 修改 /etc/fstab 文件,注释掉所有 swap 分区的挂载信息,防止开机自动挂载 swap 分区。
sed -ri 's#(SELINUX=).*#\1disabled#' /etc/selinux/config 
# 修改 SELinux 配置文件,将 SELINUX 设置为 disabled,禁用 SELinux。
systemctl disable firewalld && systemctl stop firewalld 
# 禁用并停止 firewalld 服务,简化开发和测试环境的配置。在生产环境中请谨慎使用此操作。
cat <<EOF > /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
# 创建 /etc/sysconfig/modules/ipvs.modules 文件,用于加载 IPVS 相关模块,为 Kubernetes 的 IPVS 模式提供支持。
chmod +x /etc/sysconfig/modules/ipvs.modules 
# 为 /etc/sysconfig/modules/ipvs.modules 文件添加执行权限,确保该脚本能够正常执行。
bash /etc/sysconfig/modules/ipvs.modules 
# 执行 /etc/sysconfig/modules/ipvs.modules 脚本,加载 IPVS 相关模块。
cat <<EOF> /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables =1
net.bridge.bridge-nf-call-iptables =1
net.ipv4.ip_forward=1
vm.max_map_count=262144
EOF
# 创建 /etc/sysctl.d/k8s.conf 文件,修改内核参数,为 Kubernetes 的网络功能提供支持。
sysctl -p /etc/sysctl.d/k8s.conf
# 使 /etc/sysctl.d/k8s.conf 文件中的内核参数设置立即生效。
modprobe br_netfilter 
# 加载网桥过滤模块,为容器网络提供支持。

Docker 安装脚本

vim /root/docker.sh

按 i 进入编辑模式,把下面内容贴进去,再按 esc 键退出编辑模式,输入 :wq 保存退出。

#!/bin/bash
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin cri-dockerd ipset ipvsadm # 此命令用于安装 Docker 及其相关组件,包括 Docker 引擎、命令行工具、容器运行时、构建插件、编排插件、cri-dockerd 以及网络管理工具。安装过程中可能需要联网,确保系统能够访问 yum 源。
mkdir -p /etc/docker # 创建 /etc/docker 目录,用于存放 Docker 的配置文件。
cat <<EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://hub.urlsa.us.kg",
    "https://docker.urlsa.us.kg"
    ]
}
EOF
# 创建 /etc/docker/daemon.json 文件,配置 Docker 加速,使用多个镜像源来提高 Docker 镜像的下载速度。
sed -i '/ExecStart/s/$/ --pod-infra-container-image=registry.aliyuncs.com\/google_containers\/pause:3.9/' /usr/lib/systemd/system/cri-docker.service # 修改 cri-docker.service 文件,指定 pod 基础容器镜像,确保容器能够正常启动。
# 重载 systemd 管理器的配置,使修改后的服务配置生效。启用并重启 cri-docker、Docker 服务,确保服务能够正常运行。
systemctl daemon-reload 
systemctl enable cri-docker && systemctl restart cri-docker
systemctl enable docker&& systemctl restart docker

Kubernetes 安装脚本

vim /root/kubernetes.sh

按 i 进入编辑模式,把下面内容贴进去,再按 esc 键退出编辑模式,输入 :wq 保存退出。

#!/bin/bash
yum install -y install kubelet kubeadm kubectl --nogpgcheck 
# 此命令用于安装 Kubernetes 相关组件,包括 kubelet、kubeadm 和 kubectl,同时忽略 GPG 签名检查。
containerd config default > /etc/containerd/config.toml 
# 生成 containerd 的默认配置文件。
sed -i -e 's/registry.k8s.io/registry.aliyuncs.com\/google_containers/g'  /etc/containerd/config.toml 
# 修改 containerd 配置文件,将镜像源替换为阿里云镜像源,提高镜像下载速度。
sed -i -e 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml 
# 修改 containerd 配置文件,启用 SystemdCgroup,确保 containerd 与 systemd 能够正常协作。
cat /etc/containerd/config.toml |egrep "sandbox_image|SystemdCgroup|disabled_plugins" 
# 查看 containerd 配置文件中的关键信息,确保配置正确。
systemctl restart containerd 
# 重启 containerd 服务,使配置生效。
cat <<EOF | tee /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--fail-swap-on=true"
KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
EOF
# 创建 /etc/sysconfig/kubelet 文件,配置 kubelet 的额外参数,包括禁止使用 swap 分区、使用 systemd 作为 cgroup 驱动以及使用 IPVS 模式。
systemctl enable kubelet 
# 设置 kubelet 开机自启,确保系统重启后 kubelet 能够自动启动。

脚本打包与分发

# 切换到 /root 目录,确保后续操作在正确的目录下进行。删除 /root/anaconda-ks.cfg  文件
cd /root  && rm -f /root/anaconda-ks.cfg 
# 将 /root 目录下的所有文件和文件夹打包成一个名为 /kubernetes.tar 的压缩文件。并将压缩文件移动到 /root 目录下,确保文件位置正确。
tar -czf /kubernetes.tar *  && mv /kubernetes.tar /root 
# 用 ls -h 查看一下 
[root@localhost ~]# ll -h
total 447M
drwxr-xr-x. 3 root root 4.0K Feb 21 11:37 Docker
-rw-r--r--. 1 root root 1.4K Feb 21 12:10 docker.sh
drwxr-xr-x. 3 root root 4.0K Feb 21 11:42 Kubernetes
-rw-r--r--. 1 root root 1.4K Feb 21 12:13 kubernetes.sh
-rw-r--r--. 1 root root 447M Feb 21 12:17 kubernetes.tar
drwxr-xr-x. 2 root root 4.0K Feb 21 12:02 master-tar
drwxr-xr-x. 2 root root  131 Feb 21 12:02 node-tar
-rw-r--r--. 1 root root  910 Feb 21 11:49 pull.sh
-rw-r--r--. 1 root root 2.6K Feb 21 12:09 repo.sh

# 将压缩文件复制到所有节点的 /root 目录下,下面最好一行一行执行。
scp /root/kubernetes.tar [email protected]:/root 
scp /root/kubernetes.tar [email protected]:/root
scp /root/kubernetes.tar [email protected]:/root

如果你不想做上面的操作

可以下载我准备好的安装包 kubernetes.tar
下载地址:https://download.csdn.net/download/sido777/90412490
将压缩文件下载下来,解压一下。
里面有两个文件,一个是 Mackdowns 格式的文件,写的是本文所有内容,一个是上面步骤操作下来的 kubernetes.tar 文件。
直接把解压得到的 kubernetes.tar 上传到所有的集群节点,就可以断续下面的操作了。

五、各节点具体部署步骤

Master 节点执行命令

在 Master 节点上,我们需要执行一系列命令来完成基础环境的配置和初始化工作。

# 修改主机名并切换到根目录,方便后续操作
hostnamectl set-hostname master
cd /root
# 解压 kubernetes 安装包,释放出所需的文件和目录
tar -xzvf kubernetes.tar

# 编辑 /etc/hosts 文件,添加集群节点的 IP 地址和主机名映射,确保节点之间可以通过主机名相互访问
cat >>/etc/hosts<<EOF
192.168.10.100 master 
192.168.10.100 cluster-endpoint
192.168.10.101 node1
192.168.10.102 node2
EOF

# 执行 repo.sh 和 docker.sh 脚本,这两个脚本通常用于配置软件仓库和安装 Docker 等必要软件
bash repo.sh && bash docker.sh

# 加载 Master 节点所需的 Docker 镜像,这些镜像包含了 k8s 运行所需的各种组件
for tar in `ls /root/master-tar` ; do docker load -i /root/master-tar/$tar; done

# 重启节点,使上述配置生效
reboot

Node 节点上执行命令

Node 节点的配置与 Master 节点有部分相似之处,但也有一些差异。

# 修改主机名,注意 node1、node2 名称要不一样,切换到根目录,方便后续操作
hostnamectl set-hostname node1
# 解压 kubernetes 安装包
tar -xzvf kubernetes.tar

# 编辑 /etc/hosts 文件,添加集群节点的 IP 地址和主机名映射
cat >>/etc/hosts<<EOF
192.168.10.100 master 
192.168.10.100 cluster-endpoint
192.168.10.101 node1
192.168.10.102 node2
EOF

# 执行 repo.sh 和 docker.sh 脚本,配置软件仓库和安装 Docker
bash repo.sh && bash docker.sh

# 加载 Node 节点所需的 Docker 镜像
for tar in `ls /root/node-tar` ; do docker load -i /root/node-tar/$tar; done

# 重启节点,使配置生效
reboot

在所有节点上执行命令

在完成 Master 和 Node 节点的基础配置后,需要在所有节点上执行以下命令:

# 执行 kubernetes.sh 脚本,该脚本通常用于完成 k8s 集群的一些通用配置
bash kubernetes.sh

初始化 master 节点

初始化 master 节点是整个部署过程中的关键步骤,这一步将启动 k8s 控制平面的各个组件。此步骤仅在 master 节点执行。

# kubeadm init 命令用于初始化 k8s 控制平面
# --apiserver-advertise-address 配置 k8s apiserver 地址,用于监听、响应其他节点请求,此处配置为 master 节点 ip 地址
# --image-repository 指定使用阿里云镜像仓库,以加速镜像下载
# --kubernetes-version 指定 k8s 版本为 v1.28.15
# --service-cidr 配置 k8s Service 的 IP 范围
# --pod-network-cidr 配置 k8s pod 的 IP 范围
# --cri-socket 使用 cri-dockerd.sock,不用默认的 containerd.sock
kubeadm init \
  --apiserver-advertise-address=192.168.10.100 \
  --image-repository=registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.28.15 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16 \
  --cri-socket=unix:///var/run/cri-dockerd.sock

[preflight] You can also perform this action in beforehand using ‘kubeadm config images pull’

这里会有好几分钟的等待时间,不要着急。如果初始化成功,会输出类似以下信息:


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 192.168.10.100:6443 --token vh0wjd.hk9z0g6sdsfys8z0 \
        --discovery-token-ca-cert-hash sha256:35032cc0fbc3aa2f268fa39c842719ead38f34ffdbb6243a811d9d2dc4571720 

接下来,在 master 节点上直接运行下面命令,以便普通用户可以使用 kubectl 命令管理集群:

# 创建.kube 目录,用于存放 kubeconfig 文件
mkdir -p $HOME/.kube
# 复制 admin.conf 文件到.kube 目录下
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# 修改 kubeconfig 文件的权限,确保当前用户可以访问
sudo chown $(id -u):$(id -g) $HOME/.kube/config

添加 node 节点

在所有的 node 节点上运行 kubeadm join 命令,将节点加入到 k8s 集群中。需要注意的是,tokensha256:... 这两个值只能用自己部署成功后提示的。最后加上 --cri-socket=unix:///var/run/cri-dockerd.sock

kubeadm join 192.168.10.100:6443 --token vh0wjd.hk9z0g6sdsfys8z0 \
        --discovery-token-ca-cert-hash sha256:35032cc0fbc3aa2f268fa39c842719ead38f34ffdbb6243a811d9d2dc4571720 \
        --cri-socket=unix:///var/run/cri-dockerd.sock

如果加入成功,会输出类似以下信息:

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.

安装网络插件 flannel

为了让 k8s 集群中的 Pod 能够相互通信,需要安装网络插件。这里我们选择安装 flannel。

下面的操作只在 Master 节点的进行

首先,编写 kube-flannel.yml 文件,该文件包含了 flannel 网络插件的配置信息。

vim /root/kube-flannel.yml

按 i 进入编辑模式,把下面内容贴进去,再按 esc 键退出编辑模式,输入 :wq 保存退出。

apiVersion: v1
kind: Namespace
metadata:
  labels:
    k8s-app: flannel
    pod-security.kubernetes.io/enforce: privileged
  name: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: flannel
  name: flannel
  namespace: kube-flannel
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: flannel
  name: flannel
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: flannel
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-flannel
---
apiVersion: v1
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "EnableNFTables": false,
      "Backend": {
        "Type": "vxlan"
      }
    }
kind: ConfigMap
metadata:
  labels:
    app: flannel
    k8s-app: flannel
    tier: node
  name: kube-flannel-cfg
  namespace: kube-flannel
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: flannel
    k8s-app: flannel
    tier: node
  name: kube-flannel-ds
  namespace: kube-flannel
spec:
  selector:
    matchLabels:
      app: flannel
      k8s-app: flannel
  template:
    metadata:
      labels:
        app: flannel
        k8s-app: flannel
        tier: node
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      containers:
      - args:
        - --ip-masq
        - --kube-subnet-mgr
        command:
        - /opt/bin/flanneld
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: EVENT_QUEUE_DEPTH
          value: "5000"
        image: ghcr.io/flannel-io/flannel:v0.26.4
        name: kube-flannel
        resources:
          requests:
            cpu: 100m
            memory: 50Mi
        securityContext:
          capabilities:
            add:
            - NET_ADMIN
            - NET_RAW
          privileged: false
        volumeMounts:
        - mountPath: /run/flannel
          name: run
        - mountPath: /etc/kube-flannel/
          name: flannel-cfg
        - mountPath: /run/xtables.lock
          name: xtables-lock
      hostNetwork: true
      initContainers:
      - args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        command:
        - cp
        image: ghcr.io/flannel-io/flannel-cni-plugin:v1.6.2-flannel1
        name: install-cni-plugin
        volumeMounts:
        - mountPath: /opt/cni/bin
          name: cni-plugin
      - args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        command:
        - cp
        image: ghcr.io/flannel-io/flannel:v0.26.4
        name: install-cni
        volumeMounts:
        - mountPath: /etc/cni/net.d
          name: cni
        - mountPath: /etc/kube-flannel/
          name: flannel-cfg
      priorityClassName: system-node-critical
      serviceAccountName: flannel
      tolerations:
      - effect: NoSchedule
        operator: Exists
      volumes:
      - hostPath:
          path: /run/flannel
        name: run
      - hostPath:
          path: /opt/cni/bin
        name: cni-plugin
      - hostPath:
          path: /etc/cni/net.d
        name: cni
      - configMap:
          name: kube-flannel-cfg
        name: flannel-cfg
      - hostPath:
          path: /run/xtables.lock
          type: FileOrCreate
        name: xtables-lock

然后,执行 kubectl apply -f 命令安装 flannel:

# 应用 kube-flannel.yml 文件,创建 flannel 相关的资源,如命名空间、角色、服务账户等
kubectl apply -f kube-flannel.yml

验证安装结果

安装完成后,我们需要验证集群是否正常工作。可以通过以下命令查看节点和 Pod 的状态:

# 查看集群中所有节点的状态,确保节点都处于 Ready 状态
kubectl get nodes
# 查看所有命名空间下的 Pod 状态,确保 Pod 都正常运行
kubectl get pod -owide -A

正常情况下,会输出类似以下信息:

[root@master ~]# kubectl apply -f kube-flannel.yml
namespace/kube-flannel 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 -owide -A
NAMESPACE      NAME                             READY   STATUS    RESTARTS   AGE   IP               NODE 
kube-flannel   kube-flannel-ds-9wms9            1/1     Running   0          41s   192.168.10.102   node2
kube-flannel   kube-flannel-ds-fhgv6            1/1     Running   0          41s   192.168.10.101   node1
kube-flannel   kube-flannel-ds-q7ddx            1/1     Running   0          41s   192.168.10.100   master
kube-system    coredns-66f779496c-klf2k         1/1     Running   0          23m   10.244.0.3       master
kube-system    coredns-66f779496c-srqsc         1/1     Running   0          23m   10.244.0.2       master
kube-system    etcd-master                      1/1     Running   0          24m   192.168.10.100   master
kube-system    kube-apiserver-master            1/1     Running   0          24m   192.168.10.100   master
kube-system    kube-controller-manager-master   1/1     Running   0          24m   192.168.10.100   master
kube-system    kube-proxy-gbgqz                 1/1     Running   0          23m   192.168.10.100   master
kube-system    kube-proxy-k55n6                 1/1     Running   0          21m   192.168.10.102   node2
kube-system    kube-proxy-n7cc2                 1/1     Running   0          21m   192.168.10.101   node1
kube-system    kube-scheduler-master            1/1     Running   0          24m   192.168.10.100   master

六、常见问题及解决方法

在部署过程中,可能会遇到一些问题,以下是一些常见问题及解决方法:

1. 节点无法加入集群

如果 node 节点无法加入集群,可能是由于 token 过期或 sha256 值不正确。可以在 master 节点上重新生成 tokensha256 值,然后在 node 节点上使用新的值进行加入操作。

2. Pod 无法正常启动

如果 Pod 无法正常启动,可能是由于网络配置问题或资源不足。可以检查网络插件是否正确安装,以及节点的资源使用情况。

结论

通过以上步骤,我们可以成功部署一个 Kubernetes 集群,并安装网络插件 flannel。在部署过程中,需要注意各个节点的配置和命令的执行顺序,确保每个步骤都正确无误。同时,要注意常见问题的解决方法,以便在遇到问题时能够及时处理。希望本文能够帮助读者顺利搭建自己的 k8s 集群,为容器化应用的开发和管理提供有力支持。

;