(一)kubernetes1.29.4离线部署之-安装文件准备
(二)kubernetes1.29.4离线部署之-镜像文件准备
(三)kubernetes1.29.4离线部署之-环境初始化
(四)kubernetes1.29.4离线部署之-组件安装
(五)kubernetes1.29.4离线部署之-初始化第一个控制平面
(六)kubernetes1.29.4离线部署之-加入Node节点
(七)kubernetes1.29.4离线部署之-网络插件
(八)kubernetes1.29.4离线部署之-测试验证
友情提示: 由于本文过长,不便于阅读,已经拆分为多个章节,可以点击上面的地址单独阅读
本文容器运行时采用的时Containerd
本文网络插件采用的时calico tigera-operator
本文涉及的所有脚本文件可以从如下地址获取:
https://gitee.com/qingplus/qingcloud-platform/tree/develop/qingcloud-deploy/service
前情提要:
本文不介绍K8S架构及细节,仅仅分享Kubernetes部署实施完整过程。
本文主要采用kubeadm方式安装部署。另外本文直接采用单控制平面方式快速完成版本部署,etcd的部署方式为堆叠方式,独立方式的切换后续完成文档说明。
高可用集群拓扑的两个选项介绍:
高可用集群拓扑的两个选项:
- 使用堆叠(stacked)控制平面节点,其中 etcd 节点与控制平面节点共存
- 使用外部 etcd 节点,其中 etcd 在与控制平面不同的节点上运行
本文主要采用第一种堆叠方式:
环境准备
硬件环境
服务器由6台ESXi虚拟化服务器组成,详情参考《ESXi网络配置与物理交换机VLAN ID规划》
本文为单控制平面部署,非高可用集群部署,并未用到规划中的所有节点。后续集群部署会继续使用。
主机名称 | ESXi 节点名 | 角色 | IP地址 | 资源配置 | 安装组件 |
---|---|---|---|---|---|
itserver-master1 | xenserver01 | master | 10.0.0.10 | 8C/16G/200G | |
itserver-master2 | xenserver02 | master | 10.0.0.13 | 8C/16G/200G | |
itserver-node01 | xenserver01 | node | 10.0.0.11 | 16C/64G/500G | |
itserver-node02 | xenserver01 | node | 10.0.0.12 | 16C/64G/500G | |
itserver-node03 | xenserver02 | node | 10.0.0.14 | 16C/64G/500G | |
itserver-node04 | xenserver02 | node | 10.0.0.15 | 16C/64G/500G |
物理服务器节点(安装ESXi)
三台物理服务器 | |||
---|---|---|---|
ESXi 节点名 | ip地址 | 用户名 | 备注 |
xenserver01 | 192.168.3.50 | root | |
xenserver02 | 192.168.3.60 | root | |
xenserver03 | 192.168.3.100 | root |
网络分配
角色 | IP地址 | 备注 |
---|---|---|
node网络 | 10.0.0.0/24 | |
Service 网络 | 10.96.0.0/16 | |
Pod网络 | 172.16.0.0/16 |
网络部署图
离线安装文件准备
需要准备如下几个必须的安装文件,可以离线下载后通过本地nginx代理供其他节点下载使用
- kubernetes_server
直接下载最新版二进制文件
- containerd
本文容器运行时采用containerd而非docker,如果容器运行时采用docker,需要另外的部署版本。本文直接下载三合一版本cri_containerd_cni
- cni_plugins
- crictl
命令行执行工具 。类似docker命令行
- runc
需要单独下载完整版,只是需要检查本地环境是否存在libcommp.so
- etcd
采用外部 etcd 节点部署时需要用到,如果使用的是堆叠的方式,直接用默认的etcd容器即可,可以不用下载。
完整的离线文件下载脚本:
#!/bin/bash
ENV_CFG=./env.cfg
if [ -f ${ENV_CFG} ] ; then
chmod 777 ${ENV_CFG}
source ${ENV_CFG}
fi
# Internet URLs
kernel_url="http://mirrors.tuna.tsinghua.edu.cn/elrepo/kernel/el7/x86_64/RPMS/${kernel_name}"
cni_plugins_url="https://github.com/containernetworking/plugins/releases/download/${cni_plugins_version}/${cni_plugins_name}"
cri_containerd_cni_url="https://github.com/containerd/containerd/releases/download/v${cri_containerd_cni_version}/${cri_containerd_cni_name}"
crictl_url="https://github.com/kubernetes-sigs/cri-tools/releases/download/${crictl_version}/${crictl_name}"
runc_url="https://github.com/opencontainers/runc/releases/download/v${runc_version}/${runc_name}"
etcd_url="https://github.com/etcd-io/etcd/releases/download/${etcd_version}/${etcd_name}"
kubernetes_server_url="https://storage.googleapis.com/kubernetes-release/release/${KUBERNETES_VERSION}/${kubernetes_server_name}"
nginx_url="http://nginx.org/download/${nginx_name}"
# Download packages
packages=(
$kernel_url
$runc_url
$cni_plugins_url
$cri_containerd_cni_url
$crictl_url
$cri_dockerd_url
$etcd_url
$kubernetes_server_url
)
for package_url in "${packages[@]}"; do
filename=$(basename "$package_url")
if curl -k -L -C - -o "$filename" "$package_url"; then
echo "Downloaded $filename"
else
echo "Failed to download $filename"
exit 1
fi
done
离线镜像文件准备
注意:离线安装需要准备大量的镜像,这一步千万要仔细否则会出现各种意想不到的问题
需要准备的镜像文件
- kube-apiserver
- kube-controller-manager
- kube-scheduler
- kube-proxy
- kube-proxy
- coredns
- pause
- etcd
以上镜像文件可以从: registry.cn-hangzhou.aliyuncs.com/google_containers下载
- calico/node
- calico/kube-controllers
- calico/node
- calico/typha
- calico/node-driver-registrar
- calico/csi
- calico/cni
- calico/ctl
- calico/pod2daemon-flexvol
- calico/apiserver
以上可以直接从docker.io下载即可
注意: 以上所有的镜像文件务必准备到位。本文脚本中的几个版本便令注意修改到位:
KUBERNETES_VERSION=${KUBERNETES_VERSION:-“v1.29.4”}
COREDNS_VERSION=${COREDNS_VERSION:-‘v1.11.1’}
PAUSE_VERSION=${PAUSE_VERSION:-‘3.9’}
ETCD_VERSION=${ETCD_VERSION:-‘3.5.12-0’}
REGISTRY_VERSION=${REGISTRY_VERSION:-‘2.8.3’}
CALICO_VERSION=${CALICO_VERSION:-‘v3.27.3’}
完整的镜像下载脚本
#!/bin/bash
ENV_CFG=./env.cfg
if [ -f ${ENV_CFG} ] ; then
chmod 777 ${ENV_CFG}
source ${ENV_CFG}
fi
image_list="${IMAGE_DOMAIN}/${IMAGE_NAMESPACE}/kube-apiserver:${KUBERNETES_VERSION}
${IMAGE_DOMAIN}/${IMAGE_NAMESPACE}/kube-controller-manager:${KUBERNETES_VERSION}
${IMAGE_DOMAIN}/${IMAGE_NAMESPACE}/kube-scheduler:${KUBERNETES_VERSION}
${IMAGE_DOMAIN}/${IMAGE_NAMESPACE}/kube-proxy:${KUBERNETES_VERSION}
${IMAGE_DOMAIN}/${IMAGE_NAMESPACE}/coredns:${COREDNS_VERSION}
${IMAGE_DOMAIN}/${IMAGE_NAMESPACE}/pause:${PAUSE_VERSION}
${IMAGE_DOMAIN}/${IMAGE_NAMESPACE}/etcd:${ETCD_VERSION}
calico/node:${CALICO_VERSION}
calico/kube-controllers:${CALICO_VERSION}
calico/node:${CALICO_VERSION}
calico/typha:${CALICO_VERSION}
calico/node-driver-registrar:${CALICO_VERSION}
calico/csi:${CALICO_VERSION}
calico/cni:${CALICO_VERSION}
calico/ctl:${CALICO_VERSION}
calico/pod2daemon-flexvol:${CALICO_VERSION}
calico/apiserver:${CALICO_VERSION}
"
#${IMAGE_DOMAIN}/${IMAGE_NAMESPACE}/registry:${REGISTRY_VERSION}
newimage_list=()
for image in ${image_list}; do
docker pull "${image}"
newimage=$(echo $image | sed -e "s/calico/${LOCAL_IMAGE_DOMAIN}\/calico/")
newimage=$(echo $newimage | sed -e "s/${IMAGE_DOMAIN}\/${IMAGE_NAMESPACE}/${LOCAL_IMAGE_DOMAIN}\/${LOCAL_IMAGE_NAMESPACE}/")
newimage_list+="${newimage} "
docker tag $image $newimage
docker push $newimage
done
docker save -o qinghub-kube-"${VERSION}".tar ${newimage_list}
轻云官方下载
https:/qingplus.cn/pkg/kubernetes/v1.29.4/qinghub-kube-v1.29.4.tar
下载完成后再手动导入所有的镜像即可。详细过程不在细说。
环境初始化
检查步骤
- 关闭防火墙
- 关闭 swap partition permanently
- 配置检查时间同步
- 配置安装时间同步组件
- 配置检查 nfs-utils kubeadmin方式安装不需要检查
- 配置检查内核版本
- 配置检查资源情况
- 配置检查SSH
- 配置检查系统配置
- 配置检查转发 IPv4
- 配置检查Docker用户并添加ssh免密认证<authoirzed_keys> (建议手动执行)
- 配置检查Docker (容器运行时为Containerd时,不需要检查)
- 配置检查Docker用户权限 (容器运行时为Containerd时,不需要检查)
- 配置检查网络
完整的初始化脚本
#!/bin/bash
###############################################
# QingHub K8S Install 版本: $VERSION
# 架构: $ARCH_TYPE 目前版本主要支持amd64,其他待敬请期待
# 操作系统: $os_type
# QingHub Studio官网: https://qinghub.net
# 如过您安装遇到问题,请到官网查找官方联系方式或加支持群:
# https://qinghub.net
###############################################
ENV_CFG=./env.cfg
if [ -f ${ENV_CFG} ] ; then
chmod 777 ${ENV_CFG}
source ${ENV_CFG}
fi
export CONSOLE=${CONSOLE:-false}
os_type=$(cat /etc/os-release | grep "^ID=" | awk -F= '{print $2}' | tr -d [:punct:])
os_version_id=$(cat /etc/os-release | grep "VERSION_ID=" | awk -F= '{print $2}' | tr -d [:punct:])
if [ "$EUID" -ne 0 ]; then
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${RED}[ERROR] 当前用户不是 root 用户,请切换到 root 用户执行该脚本.${NC}"
exit 1
else
echo -e "${RED}[ERROR] Current user is not root user, please switch to root user to execute the script.${NC}"
exit 1
fi
fi
if [ -z "$SSH_RSA" ]; then
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${RED}[ERROR] 请设置环境变量 SSH_RSA, 该变量为 SSH 公钥.${NC}"
exit 1
else
echo -e "${RED}[ERROR] Please set the environment variable SSH_RSA, the variable is SSH public key.${NC}"
exit 1
fi
fi
###############################################
# 新增ubuntu 用户
# QingHub Studio官网: https://qinghub.net
# 如过您安装遇到问题,请到官网查找官方联系方式或加支持群:
# https://qinghub.net
###############################################
function add_user_in_ubuntu() {
useradd --create-home -s /bin/bash -g root "$1"
echo "$1":"$2" | chpasswd
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] 用户 $1 已经创建.${NC}"
else
echo -e "${GREEN}[INFO] User $1 has been created.${NC}"
fi
}
###############################################
# 新增redhat 用户
# QingHub Studio官网: https://qinghub.net
# 如过您安装遇到问题,请到官网查找官方联系方式或加支持群:
# https://qinghub.net
###############################################
function add_user_in_redhat() {
adduser -g root "$1"
echo "$1":"$2" | chpasswd
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] 用户 $1 已经创建.${NC}"
else
echo -e "${GREEN}[INFO] User $1 has been created.${NC}"
fi
}
###############################################
# 描述: 检查并新增用户, 有些版本可以不用检查,请使用时根据
# 情况自行注释掉
# QingHub Studio官网: https://qinghub.net
# 如过您安装遇到问题,请到官网查找官方联系方式或加支持群:
# https://qinghub.net
###############################################
function check_user() {
if ! grep -q docker /etc/group; then
groupadd --force docker
fi
if id -u "${DOCKER_USER}" >/dev/null 2>&1; then
if ! id -nG "${DOCKER_USER}" | grep -qw "docker"; then
gpasswd -a "${DOCKER_USER}" docker
fi
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] 用户 ${DOCKER_USER} 已经存在.${NC}"
else
echo -e "${GREEN}[INFO] User ${DOCKER_USER} already exists.${NC}"
fi
else
case $os_type in
centos|redhat|euleros|fusionos|anolis|kylin|rhel|rocky|fedora|openEuler)
add_user_in_redhat "${DOCKER_USER}" "${DOCKER_PASS}"
;;
ubuntu|debian)
add_user_in_ubuntu "${DOCKER_USER}" "${DOCKER_PASS}"
;;
*)
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${RED}[ERROR] 暂不支持 $os_type 操作系统.${NC}"
exit 1
else
echo -e "${RED}[ERROR] The $os_type operating system is temporarily not supported.${NC}"
exit 1
fi
;;
esac
fi
$CONSOLE
$CONSOLE || add_ssh_rsa "${DOCKER_USER}"
}
function add_ssh_rsa() {
if id -u "$user" >/dev/null 2>&1; then
if [ ! -d "/home/$1/.ssh" ]; then
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] 创建 /home/$1/.ssh 目录.${NC}"
else
echo -e "${GREEN}[INFO] Create /home/$1/.ssh directory.${NC}"
fi
mkdir -p /home/"$1"/.ssh
fi
if [ -f "/home/$1/.ssh/authorized_keys" ]; then
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] /home/$1/.ssh/authorized_keys 已经存在.${NC}"
else
echo -e "${GREEN}[INFO] /home/$1/.ssh/authorized_keys already exists.${NC}"
fi
chmod 777 /home/"$1"/.ssh/authorized_keys
if ! < /home/"$1"/.ssh/authorized_keys grep -q "$SSH_RSA"; then
echo "$SSH_RSA" >> /home/"$1"/.ssh/authorized_keys
fi
else
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] 创建 /home/$1/.ssh/authorized_keys.${NC}"
else
echo -e "${GREEN}[INFO] Create /home/$1/.ssh/authorized_keys.${NC}"
fi
touch /home/"$1"/.ssh/authorized_keys
chmod 777 /home/"$1"/.ssh/authorized_keys
echo "$SSH_RSA" > /home/"$1"/.ssh/authorized_keys
fi
if < /home/"$1"/.ssh/authorized_keys grep -q "$SSH_RSA"; then
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] 成功将 SSH 公钥添加到 /home/$1/.ssh/authorized_keys.${NC}"
else
echo -e "${GREEN}[INFO] Successfully added ssh public key to /home/$1/.ssh/authorized_keys.${NC}"
fi
else
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${RED}[ERROR] 将 SSH 公钥添加到 /home/$1/.ssh/authorized_keys 失败.${NC}"
exit 1
else
echo -e "${RED}[ERROR] Add ssh public key to /home/$1/.ssh/authorized_keys failed.${NC}"
exit 1
fi
fi
chmod 600 /home/"$1"/.ssh/authorized_keys
chown -R "$1":"$1" /home/"$1"/.ssh
fi
}
function check_user_permission(){
if su ${DOCKER_USER} -c "docker ps" >/dev/null 2>&1; then
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] Docker 用户有权限执行 docker 命令.${NC}"
else
echo -e "${GREEN}[INFO] Docker users have the permission to execute docker commands.${NC}"
fi
else
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${RED}[ERROR] Docker 用户无权限执行 docker 命令, 请尝试重启docker 'systemctl restart docker'. 重启 docker 后, 再次执行该脚本.${NC}"
exit 1
else
echo -e "${RED}[ERROR] Docker users have no permission to execute docker commands, Please try to restart docker 'systemctl restart docker'. After restarting docker, execute the script again.${NC}"
exit 1
fi
fi
}
###############################################
# 描述: 关闭防火墙
# QingHub Studio官网: https://qinghub.net
# 如过您安装遇到问题,请到官网查找官方联系方式或加支持群:
# https://qinghub.net
###############################################
function disable_firewalld() {
if systemctl status firewalld | grep Active | grep -q running >/dev/null 2>&1; then
systemctl stop firewalld >/dev/null 2>&1
systemctl disable firewalld >/dev/null 2>&1
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] 检测到 Firewalld 服务已启动,正在将 Firewalld 服务关闭并禁用.${NC}"
else
echo -e "${GREEN}[INFO] The Firewalld service has been started, Firewalld service is being turned off and disabled.${NC}"
fi
else
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] Firewalld 服务已经停止或未安装.${NC}"
else
echo -e "${GREEN}[INFO] Firewalld service is not installed.${NC}"
fi
fi
}
###############################################
# 描述: 关闭swap
# QingHub Studio官网: https://qinghub.net
# 如过您安装遇到问题,请到官网查找官方联系方式或加支持群:
# https://qinghub.net
###############################################
function disable_swap() {
if swapoff -a; then
sed -i '/swap/s/^/#/' /etc/fstab
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] swap 已经禁用.${NC}"
else
echo -e "${GREEN}[INFO] swap has been disabled.${NC}"
fi
fi
}
function check_time_sync() {
if timedatectl status | grep "NTP synchronized" | grep -q "yes" >/dev/null 2>&1 || timedatectl show | grep "NTPSynchronized=yes" >/dev/null 2>&1; then
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] NTP 时间同步已经启用.${NC}"
else
echo -e "${GREEN}[INFO] NTP time synchronization has been enabled.${NC}"
fi
else
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${YELLOW}[WARN] NTP 时间同步未启用.${NC}"
else
echo -e "${YELLOW}[WARN] NTP time synchronization is not enabled.${NC}"
fi
fi
}
###############################################
# 描述: 安装时钟同步,请酌情修改并安装
# QingHub Studio官网: https://qinghub.net
# 如过您安装遇到问题,请到官网查找官方联系方式或加支持群:
# https://qinghub.net
###############################################
install_chrony(){
case $os_type in
ubuntu|debian)
if dpkg -l | grep -q chrony >/dev/null 2>&1; then
echo -e "${GREEN}[INFO] chrony 已经安装在主机上.${NC}"
else
echo -e "${YELLOW}[WARN] chrony 未安装在主机上, 请执行命令安装 'apt -y install chrony'.${NC}"
apt -y install chrony &> /dev/null;
systemctl restart chronyd && systemctl enable --now chronyd &> /dev/null
systemctl is-active chronyd &> /dev/null
fi
;;
*)
if rpm -qa | grep -q chrony >/dev/null 2>&1; then
if [ "$LANG" == "zh_CN.UTF-8" ]; then
echo -e "${GREEN}[INFO] chrony 已经安装在主机上.${NC}"
else
echo -e "${GREEN}[INFO] chrony has been installed on the host.${NC}"