一、安装操作系统
操作系统选择Ubuntu22.04。官方系统镜像下载地址
https://releases.ubuntu.com/22.04.3/ubuntu-22.04.3-live-server-amd64.iso
关于是用虚拟机还是用云主机。这里不做限制, 只要能打通网络就行。
本文还是用传统的vm虚拟机
二、系统准备及IP分布
准备三台机器分别是
主机名 | ip |
---|---|
k8s-master01 | 192.168.44.11 |
k8s-worker01 | 192.168.44.12 |
k8s-worker02 | 192.168.44.13 |
三、通用逻辑
1. 新建配置文件 config.sh
#!/bin/bash
# 定义集群节点IP地址
MASTER_IP=192.168.44.11
WORKER1_IP=192.168.44.12
WORKER2_IP=192.168.44.13
# 定义集群节点主机名
MASTER_HOSTNAME=k8s-master01
WORKER1_HOSTNAME=k8s-worker01
WORKER2_HOSTNAME=k8s-worker02
# 容器镜像源地址
soft_source_addr=registry.cn-hangzhou.aliyuncs.com/google_containers
# 网卡名称,因为本文用了vmware虚拟机,所以网卡名好像都是这个
network_name=ens33
# 定义pod子网ip网段
pod_subnet=10.244.0.0/16
# 获取当前执行服务器的ip地址
ip=$(ip addr | grep ens33 | grep inet | grep -v inet6 | awk '{print $2}' | cut -d/ -f1)
# 定义kubernetes版本
kube_version=1.28.2
2. 通用执行步骤描述:
0)读取配置文件 config.sh
1)关闭防火墙
2)关闭swap
3)设置时区及添加同步时间服务器的定时任务
4)启用 overlay、br_netfilter 模块
5)配置ipv4流量转发
6)启用 ip_vs、ip_vs_rr、ip_vs_wrr、ip_vs_sh、nf_conntrack相关模块
7)安装指定版本的k8s kubelet kubeadm kubectl 及安装containerd,并执行kube相关软件的版本锁定
8)配置containerd
以上步骤bash脚本如下,一下bash脚本直接使用时请使用root用户
#!/bin/bash
# 前置要求, 开启root用户登录, 下面的命令全部都直接使用root用户执行
# 前置要求, 开启root用户登录
# 前置要求, 开启root用户登录
# 执行命令遇到错误就退出
set -e
# 脚本中遇到不存在的变量就退出
# sudo set -u
# 执行指令的时候,同时把指令输出,方便观察结果
set -x
# 执行管道的时候,如果前面的命令出错,管道后面的命令会停止
set -o pipefail
cp /etc/apt/sources.list /etc/apt/sources.list.bak
sed -i "s@http://.*archive.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list
sed -i "s@http://.*security.ubuntu.com@https://mirrors.tuna.tsinghua.edu.cn@g" /etc/apt/sources.list
apt update
sed -i 's/#$nrconf{restart} = '"'"'i'"'"';/$nrconf{restart} = '"'"'a'"'"';/g' /etc/needrestart/needrestart.conf
apt full-upgrade -y
apt install -y net-tools telnet sysstat bridge-utils bash-completion vim jq tar openssl iputils-ping lsof lvm2 \
dnsutils curl gcc automake autoconf make tree stress htop atop sysbench chrony ipvsadm ipset conntrack ufw git \
ntpdate apt-transport-https ca-certificates
# 设置主机名
# 获取当前服务器ip
# ip=$(ip addr | grep ens33 | grep inet | grep -v inet6 | awk '{print $2}' | cut -d/ -f1)
# 定义变量 主节点ip 两个工作节点ip 主机名
# 注意:请根据实际情况修改
source config.sh
# 如果ip地址不属于 主节点ip也不属于工作节点ip, 则直接停止执行
if [ $ip != $MASTER_IP ] && [ $ip != $WORKER1_IP ] && [ $ip != $WORKER2_IP ];then
echo "请检查ip是否正确"
exit 1
fi
if [ $ip == $MASTER_IP ];then
hostnamectl set-hostname $MASTER_HOSTNAME
elif [ $ip == $WORKER1_IP ];then
hostnamectl set-hostname $WORKER1_HOSTNAME
elif [ $ip == $WORKER2_IP ];then
hostnamectl set-hostname $WORKER2_HOSTNAME
else
echo "请检查ip是否正确"]
fi
# 查看 /etc/hosts 是否解析 MASTER_IP WORKER1_IP WORKER2_IP, 如果没有解析就追加
if [ ! -z "$(cat /etc/hosts | grep $MASTER_IP)" ];then
echo "$MASTER_IP 已存在"
else
echo "$MASTER_IP $MASTER_HOSTNAME" >> /etc/hosts
fi
if [ ! -z "$(cat /etc/hosts | grep $WORKER1_IP)" ];then
echo "$WORKER1_IP 已存在"
else
echo "$WORKER1_IP $WORKER1_HOSTNAME" >> /etc/hosts
fi
if [ ! -z "$(cat /etc/hosts | grep $WORKER2_IP)" ];then
echo "$WORKER2_IP 已存在"
else
echo "$WORKER2_IP $WORKER2_HOSTNAME" >> /etc/hosts
fi
# 关闭防火墙
systemctl stop ufw
systemctl disable ufw
# 关闭swap
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 设置时区
timedatectl set-timezone Asia/Shanghai
apt install ntpdate -y
ntpdate time1.aliyun.com
# 添加crontab 定时任务 每一个小时执行一次 ntpdate time1.aliyun.com
if [ ! -f "/etc/crontab" ]; then
touch /etc/crontab
else
echo "文件已存在"
fi
if [ ! -z "$(cat /etc/crontab | grep \"time1.aliyun.com\")" ];then
echo "0 */1 * * * /usr/sbin/ntpdate time1.aliyun.com" >> /etc/crontab
else
echo "任务已存在"
fi
cat <<EOF > /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# 用于查看是否已开启
# lsmod | grep br_netfilter
# lsmod | grep overlay
mkdir -p /etc/sysctl.d
# ipv4流量转发
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
EOF
sysctl --system
mkdir -p /etc/sysconfig/modules-load.d
cat <<EOF > /etc/sysconfig/modules-load.d/ipvs.conf
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
apt update
version=`apt-cache madison kubeadm|grep ${kube_version}|awk -F ' ' '{print $3}'`
# 安装k8s
apt install -y containerd kubelet=${version} kubeadm=${version} kubectl=${version}
# 锁定版本
apt-mark hold kubelet kubeadm kubectl
mkdir -p /etc/containerd
# 如果 /etc/containerd/config.toml 不存在就执行 containerd config default > /etc/containerd/config.toml
# if [! -f "/etc/containerd/config.toml" ];then
# containerd config default > /etc/containerd/config.toml
# fi
containerd config default > /etc/containerd/config.toml
# 将sandbox_image = "registry.k8s.io/pause:3.8"这行 替换成 sanbox_image="registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9"
sed -i 's/sandbox_image = ".*"/sandbox_image = "registry.cn-hangzhou.aliyuncs.com\/google_containers\/pause:3.9"/g' /etc/containerd/config.toml
# 如果 /etc/containerd/config.toml 中 SystemdCgroup = false 就将其改为 SystemdCgroup = true
sed -i 's/SystemdCgroup = .*/SystemdCgroup = true/g' /etc/containerd/config.toml
systemctl restart containerd
systemctl enable containerd
systemctl restart kubelet
systemctl enable kubelet
kubeadm version
kubelet --version
kubectl version --client
ctr -v
四、主节点逻辑
1)生成kubeadm-config.yaml 备用于主节点init的配置文件
2)通过阿里云镜像查看k8s需要的镜像列表
3)通过阿里云镜像下载k8s镜像
4)预览主节点init检查
5)使用kubeadm-config.yaml进行主节点初始化
6)添加主节点相关的环境变量
7)下载网络组件 calico.yaml 本文中已经将这个文件作为脚本去生成你也可以自己下载根据bash脚本的逻辑进行修改即可
8)安装网络组件
一下为具体的脚本
generate_kubeadm-config.sh
#!/bin/bash
source config.sh
cat << EOF > kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: ${MASTER_IP}
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
name: ${MASTER_HOSTNAME}
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
controlPlaneEndpoint: "${MASTER_HOSTNAME}:6443"
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: ${soft_source_addr}
kind: ClusterConfiguration
kubernetesVersion: ${kube_version}
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: ${pod_subnet}
scheduler: {}
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
EOF
ls
generate_calico.sh
这个文件太大了,不在这里贴了, 可以去github官方下载
也可以到附录 参考博客 中找到下载地址 下载后找到CALICO_IPV4POOL_CIDR部分解注释
修改对应的val为 config.sh中pod_subnet的内容
大概是这样的
#!/bin/bash
### 如果要替换下面的文本注意需要将所有的反引号 即 ` 进行转义
### 内部有一个变量为 ${pod_subnet} 记得替换
source config.sh
cat << FFF > calico.yaml
# 此处省略1万行
- name: CALICO_IPV4POOL_CIDR
value: "${pod_subnet}"
# 此处省略1万行
FFF
exec_master_node.sh
#!/bin/bash
kubectl get nodes
res=`echo $?`
if [ $res -eq 0 ];then
echo "集群已经存在"
else
source config.sh
source generate_kubeadm-config.sh
kubeadm config images list --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
kubeadm config images pull --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
kubeadm init phase preflight --config kubeadm-config.yaml
kubeadm init --config kubeadm-config.yaml
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
#generate_calico.sh 脚本生成的yaml文件为calico.yaml
source generate_calico.sh
kubectl apply -f ./calico.yaml
fi
执行exec_master_node.sh后, 生成工作节点 join 相关的脚本,并判断工作节点是否在线,如果在线。则将所有脚本scp到工作节点中,并在工作节点执行通用逻辑脚本
所以在第二部分的脚本下添加逻辑
if [ $ip == $MASTER_IP ];then
source exec_master_node.sh
cat << EOF > join_command.sh
#!/bin/bash
`kubeadm token create --print-join-command`
mkdir -p \$HOME/.kube
cp -i /etc/kubernetes/admin.conf \$HOME/.kube/config
chown \$(id -u):\$(id -g) \$HOME/.kube/config
EOF
# 判断工作节点是否在线
if ping -c 1 "$WORKER1_IP" > /dev/null; then
ssh root@$WORKER1_IP mkdir -p /etc/kubernetes
scp /etc/kubernetes/admin.conf root@$WORKER1_IP:/etc/kubernetes/admin.conf
scp ./* root@$WORKER1_IP:/root/
ssh root@$WORKER1_IP bash /root/Ubuntu22.04三节点通用脚本.sh
else
echo "远程服务器$WORKER1_IP不可达。"
fi
# 判断工作节点是否在线
if ping -c 1 "$WORKER2_IP" > /dev/null; then
ssh root@$WORKER1_IP mkdir -p /etc/kubernetes
scp /etc/kubernetes/admin.conf root@$WORKER1_IP:/etc/kubernetes/admin.conf
scp ./* root@$WORKER1_IP:/root/
ssh root@$WORKER1_IP bash /root/Ubuntu22.04三节点通用脚本.sh
else
echo "远程服务器$WORKER2_IP不可达。"
fi
else
source join_command.sh
fi
五、工作节点逻辑
工作节点的执行已经由主节点远程执行了。不需要单独运行。
六、附录
参考地址:Ubuntu安装K8S(1.28版本,基于containrd)-CSDN博客
七、一键部署
根据上述脚本我已经整理了一键部署,转到gitee地址:https://gitee.com/azhw/ubuntu-install-k8s.git 使用分支 一主两从即可
另外我也用了一个优秀的开源项目kubeaze重写了二进制部署方式的部署脚本。
再次感谢博哥爱运维:离线安装下载我就盗用原文的了
https://cloud.189.cn/web/share?code=Yj6nEv6jQ3Mv(访问码:3pms)