kubernetes 1.24 安装步骤
参考文档
使用 kube-vip 搭建高可用的 Kubernetes 集群(完整版)
安装前准备
修改hosts文件
3个节点,每个节点上添加hosts信息:
vi /etc/hosts
192.168.2.81 master1
192.168.2.82 node1
192.168.2.83 node2
外网 | hostname | 说明 |
---|---|---|
192.168.2.81 | master1 | |
192.168.2.82 | node1 | |
192.168.2.83 | node2 |
修改hostname
#master1
hostnamectl set-hostname master1
#node1
hostnamectl set-hostname node1
#node2
hostnamectl set-hostname node1
重启服务器
关闭 swap 交换区
# 查看交换分区的状态
sudo free -m
# 临时关闭
sudo swapoff -a
# 永久关闭: 把 /etc/fstab 中的swap注释掉
sudo sed -i 's/.*swap.*/#&/' /etc/fstab
或编辑文件 /etc/fstab
,将 swap
注释掉即可;
禁用 selinux
# 临时关闭
setenforce 0
# 永久关闭
sudo sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
或编辑文件 /etc/selinux/config
:
SELINUX=disabled
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
允许 iptables 检查桥接流量
由于开启内核 ipv4 转发需要加载 br_netfilter 模块,所以加载下该模块
modprobe br_netfilter
编辑文件 /etc/sysctl.d/k8s.conf
vi /etc/sysctl.d/k8s.conf
在文件中添加以下内容:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
执行命令
sysctl -p /etc/sysctl.d/k8s.conf
安装docker
使用阿里源
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装docker
yum install docker-ce docker-ce-cli containerd.io
设置加速器并修改docker驱动
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ovj8fg0z.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
重启并设置自启动
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
安装 Containerd
我们已经了解过容器运行时 containerd 的一些基本使用,接下来在各个节点上安装 Containerd。
由于 containerd 需要调用 runc,所以我们也需要先安装 runc,不过 containerd 提供了一个包含相关依赖的压缩包 cri-containerd-cni-${VERSION}.${OS}-${ARCH}.tar.gz,可以直接使用这个包来进行安装。
此处我们使用1.5.5 版本
下载压缩包
#下载压缩包
wget https://github.com/containerd/containerd/releases/download/v1.5.5/cri-containerd-cni-1.5.5-linux-amd64.tar.gz
#直接将压缩包解压到系统的各个目录中
tar -C / -xzf cri-containerd-cni-1.5.5-linux-amd64.tar.gz
#然后要将 /usr/local/bin 和 /usr/local/sbin 追加到 ~/.bashrc 文件的 PATH 环境变量中
export PATH=$PATH:/usr/local/bin:/usr/local/sbin
#然后执行下面的命令使其立即生效
source ~/.bashrc
修改配置文件
生成默认配置
containerd 的默认配置文件为 /etc/containerd/config.toml,我们可以通过如下所示的命令生成一个默认的配置
# 生成默认的配置文件
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
设置SystemdCgroup = true
对于使用 systemd 作为 init system 的 Linux 的发行版,使用 systemd 作为容器的 cgroup driver 可以确保节点在资源紧张的情况更加稳定,所以推荐将 containerd 的 cgroup driver 配置为 systemd。修改前面生成的配置文件 /etc/containerd/config.toml,在 plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options 配置块下面将 SystemdCgroup 设置为 true:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
# 或使用命令
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
配置镜像加速器
然后再为镜像仓库配置一个加速器,需要在 cri 配置块下面的 registry 配置块下面进行配置
registry.mirrors:
[plugins."io.containerd.grpc.v1.cri"]
...
sandbox_image = "registry.aliyuncs.com/k8sxio/pause:3.5"
...
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://bqr1dr1n.mirror.aliyuncs.com"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
endpoint = ["https://registry.aliyuncs.com/k8sxio"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.2.82:19800"]
endpoint = ["http://192.168.2.82:19800"]
由于上面我们下载的 containerd 压缩包中包含一个 etc/systemd/system/containerd.service 的文件,这样我们就可以通过 systemd 来配置 containerd 作为守护进程运行了,现在我们就可以启动 containerd 了,直接执行下面的命令即可:
systemctl daemon-reload
systemctl enable containerd --now
systemctl restart containerd
检查服务是否可用
# 启动完成后就可以使用 containerd 的本地 CLI 工具 ctr 和 crictl 了,比如查看版本:
ctr version
crictl version
安装k8s
配置安装源
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum makecache fast
安装kubelet,kubeadm,kubectl
yum install -y kubeadm-1.24.2 kubelet-1.24.2 kubectl-1.24.2
启动设置自启
systemctl enable kubelet
systemctl start kubelet
自动补全
kubeadm completion bash > /etc/bash_completion.d/kubeadm
kubectl completion bash > /etc/bash_completion.d/kubectl
source /usr/share/bash-completion/bash_completion
master节点初始化
单节点master
kubeadm init \
--apiserver-advertise-address=192.168.100.142 \
--image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.244.0.0/16 \
--token-ttl=0
# --apiserver-cert-extra-sans=82.156.31.11
可选参数说明:
--kubernetes-version
: 指定版本
--apiserver-advertise-address
: master 和 worker 间能互相通信的 IP--image-repository
: 设置国内镜像仓库--pod-network-cidr
:指定 pod 网络的 IP 地址范围。如果设置,控制平面将自动为每个节点分配 CIDR。--token-ttl=0
:token 永不过期
外网ip地初始化
去掉--apiserver-advertise-address参数,增加--apiserver-cert-extra-sans
参数
- --apiserver-cert-extra-sans:主题备用名称 (SAN) 用于 API 服务器服务证书。可以是 IP 地址和 DNS 名称。
错误解决
如发生
SystemVerification
错误时可加上--ignore-preflight-errors=SystemVerification
重新执行。
如果初始化失败了,自行百度解决,然后执行reset重新初始化:
kubeadm reset
成功信息
-
进行初始化成功后返回如下信息:
..... ..... [addons] Applied essential addon: CoreDNS [addons] Applied essential addon: kube-proxy 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 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.2.151:6443 --token v2r5a4.veazy2xhzetpktfz \ --discovery-token-ca-cert-hash sha256:daded8514c8350f7c238204979039ff9884d5b595ca950ba8bbce80724fd65d4
记录生成的最后一部分内容,此内容在配置worker节点时需要用到。
如果是高可用初始化,成功信息中会有带
--control-plane
参数的kubeadm join
命令,在其他控制平面节点执行即可 -
执行以下命令,使kubectl可以自动补充
[root@master01 ~]# source <(kubectl completion bash)
-
查看node 及pod 状态
[root@master01 ~]# kubectl get node NAME STATUS ROLES AGE VERSION master01.paas.com NotReady master 2m29s v1.18.0 [root@master01 ~]# kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-7ff77c879f-fsj9l 0/1 Pending 0 2m12s kube-system coredns-7ff77c879f-q5ll2 0/1 Pending 0 2m12s kube-system etcd-master01.paas.com 1/1 Running 0 2m22s kube-system kube-apiserver-master01.paas.com 1/1 Running 0 2m22s kube-system kube-controller-manager-master01.paas.com 1/1 Running 0 2m22s kube-system kube-proxy-th472 1/1 Running 0 2m12s kube-system kube-scheduler-master01.paas.com 1/1 Running 0 2m22s [root@master01 ~]#
节点未就绪,因为
coredns pod
没有启动, 缺少相关的网络插件。
node节点加入
复制出kubeadm join命令
kubeadm join 192.168.2.251:6443 --token jisk5d.sdfasldfgjdifk123 \
--discovery-token-ca-cert-hash sha256:abb1f4ad2430bdf0b32ce6e2dac23bcedefeac397f09ce0a3631c3cc49548f65
安装网络插件flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
如果执行失败且错误为raw.githoursercontent.com无法访问,可浏览器访问下载或自行创建粘贴。
vi kube-flannel.yml
kubectl appl -f kube-flannel.yml
也可配置其他网络插件,如: calico, weave , CNI bridge ...
隔一会儿查看 Pod 运行状态:
kubectl get pods -n kube-system
安装Dashboard
安装Kubernetes-Dashboard
官方部署仪表板的服务没使用nodeport,将yaml文件下载到本地,在service里添加nodeport
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc7/aio/deploy/recommended.yaml
如果此方式无法下载可通过浏览器访问自行创建
# 编辑文件
vim recommended.yaml
# ------------------------
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort #新增
ports:
- port: 443
targetPort: 8443
nodePort: 30000 #新增
selector:
k8s-app: kubernetes-dashboard
# 部署Dashboard
kubectl create -f recommended.yaml
创建完成后,检查相关服务运行状态
kubectl get deployment kubernetes-dashboard -n kubernetes-dashboard
kubectl get pods -n kubernetes-dashboard -o wide
kubectl get services -n kubernetes-dashboard
netstat -ntlp|grep 30001
在浏览器中访问Dashboard
创建token
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
1.24版本创建不过期token
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin
namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dashboard-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
---
# 上面均为正常的建立ServiceAccount并与集群默认角色cluster-admin进行绑定
# 下面为手动建立secret文件进行永久token建立
apiVersion: v1
kind: Secret
metadata:
name: secret-admin
namespace: kube-system
annotations:
kubernetes.io/service-account.name: "dashboard-admin"
type: kubernetes.io/service-account-token
# 查看token
kubectl describe -n kube-system secret/secret-admin
安装Kuboard
-
使用 hostPath 提供持久化存储
kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml
-
等待kuboard v3就绪
watch kubectl get pods -n kuboard
如果结果中没有出现
kuboard-etcd-xxxxx
的容器,或者kuboard v3一直在重启,有可能是Master Role
问题 -
常见错误
-
缺少 Master Role
当您的集群是通过二进制方式安装时,您的集群中可能缺少 Master Role,或者当您删除了 Master 节点的
node-role.kubernetes.io/master=
标签时,此时执行kubectl get nodes
,结果如下所示:[root@k8s-19-master-01 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-19-master-01 Ready <none> 19d v1.24.2 k8s-19-node-01 Ready <none> 19d v1.24.2 k8s-19-node-02 Ready <none> 19d v1.24.2 k8s-19-node-03 Ready <none> 19d v1.24.2
在集群中缺少 Master Role 节点时,您也可以为一个或者三个 worker 节点添加
k8s.kuboard.cn/role=etcd
的标签,来增加 kuboard-etcd 的实例数量;执行如下指令,可以为
your-node-name
节点添加所需要的标签kubectl label nodes your-node-name k8s.kuboard.cn/role=etcd
-
-
Master可调度
#master节点设置taint
kubectl taint nodes master node-role.kubernetes.io/master=:NoSchedule
#master去污
kubectl taint nodes master node-role.kubernetes.io/master=:NoSchedule-
#去除污点,允许master节点部署pod
kubectl taint nodes --all node-role.kubernetes.io/master-
配置 Ingress-nginx
ingress-nginx官网
https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#a-pure-software-solution-metallb
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.40.2/deploy/static/provider/cloud/deploy.yaml
在裸金属服务器使用ingress-controller时不支持LoadBlancer类型,可参考ingress-nginx官网的说明,解决方案有一下几种
自建LB服务:metalLB、openelb
使用NodePort方式部署ingress-controller
使用hostNetwork
推荐使用 metaLB kubernetes外部负载均衡器使用,或者使用nodePort方式(因kubernets默认端口范围为30000-32767,因此无法使用80/443,可以通过上层网络的80转发到kubernetes的ingress-nginx端口)
kubeadm 证书续期
查看k8s某一证书过期时间
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep Not
可使用脚本更新:更新证书脚本
git clone https://github.com/yuyicai/update-kube-cert.git
cd update-kube-cert
chmod 755 update-kubeadm-cert.sh
如果提示sh找不到可能是文件编码问题
vi
:set ff=unix
:wq
使用kubeadm默认的续期命令
新建renew_certs.sh文件并复制到所有master节点
vim renew_certs.sh
\#!/bin/bash
usage() {
echo "Usage: sh 执行脚本.sh [renew]"
exit 1
}
#输出运行状态
renew() {
kubeadm certs check-expiration
current_time=$(date +%Y%m%d%H%M%S);
echo "current time $current_time";
current_year=$(date +%Y);
echo "current year:$current_year";
current_month=$(date +%m);
echo "current month:$current_month";
current_day=$(date +%d);
echo "current day:$current_day";
if [ -d "/backups/$current_year/$current_month/$current_day/" ];
then
rm -rf /backups/$current_year/$current_month/$current_day
mkdir -p /backups/$current_year/$current_month/$current_day/
else
mkdir -p /backups/$current_year/$current_month/$current_day/
fi
cp -r /etc/kubernetes/pki /backups/$current_year/$current_month/$current_day/
cp -r /etc/kubernetes/admin.conf /backups/$current_year/$current_month/$current_day/admin.conf
kubeadm certs renew all --v=10
rm -rf $HOME/.kube/config
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
systemctl restart kubelet
kubeadm certs check-expiration
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"renew")
renew
;;
*)
usage
;;
esac
遇到的问题
pod中无法访问外网
在node节点执行
cat /var/run/flannel/subnet.env
iptables -t nat -I POSTROUTING -s 10.244.0.1/24 -j MASQUERADE
flannel与cni网卡网段不一致
参考文档:https://www.qikqiak.com/k8strain2/containerd/install-cluster/
检查cni网卡与flannel是否网段不同,如果不同则可能是存在两个cni配置文件
ls -la /etc/cni/net.d/
可以看到里面包含两个配置,一个是 10-containerd-net.conflist
,另外一个是我们上面创建的 Flannel 网络插件生成的配置,我们的需求肯定是想使用 Flannel 的这个配置。
查看containerd 这个自带的 cni 插件配置可以看到上面的 IP 段恰好就是 10.88.0.0/16
,但是这个 cni 插件类型是 bridge
网络,网桥的名称为 cni0
但是使用 bridge 网络的容器无法跨多个宿主机进行通信,跨主机通信需要借助其他的 cni 插件,比如上面我们安装的 Flannel,或者 Calico 等等,由于我们这里有两个 cni 配置,所以我们需要将 10-containerd-net.conflist
这个配置删除,因为如果这个目录中有多个 cni 配置文件,kubelet 将会使用按文件名的字典顺序排列的第一个作为配置文件,所以前面默认选择使用的是 containerd-net
这个插件。
mv /etc/cni/net.d/10-containerd-net.conflist /etc/cni/net.d/10-containerd-net.conflist.bak
ifconfig cni0 down && ip link delete cni0
systemctl daemon-reload
systemctl restart containerd kubelet
重建 coredns 和 dashboard 的 Pod,重建后 Pod 的 IP 地址就正常了,或者直接重启kubelet或者重启服务器。
清理
如果你的集群安装过程中遇到了其他问题,我们可以使用下面的命令来进行重置:
kubeadm reset
ifconfig cni0 down && ip link delete cni0
ifconfig flannel.1 down && ip link delete flannel.1
rm -rf /var/lib/cni/