一、前言|
安装kubernetes集群,有很多种方式,比如,minikube,kind,kubeadm,但是相较于kubeadm,前2种方式还是有各种不足之处,鉴于此,社区里就出现了一个专门用来在集群中安装 Kubernetes 的工具,名字就叫“kubeadm”,意思就是“Kubernetes 管理员”。
二、kubeadm的安装原理
kubeadm安装原理是用容器和镜像来封装 Kubernetes 的各种组件,但它的目标不是单机部署,而是要能够轻松地在集群环境里部署 Kubernetes,并且让这个集群接近甚至达到生产级质量。而在保持这个高水准的同时,kubeadm 只要很少的几条命令,如 init、join、upgrade、reset 就能够完成 Kubernetes 集群的管理维护工作,这让它不仅适用于集群管理员,也适用于开发、测试人员,具有较高的易用性。
三、集群安装
1,背景:
多节点集群,要求服务器应该有两台或者更多,为了简化我们只取最小值,所以这个 Kubernetes 集群就只有两台主机,一台是 Master 节点,另一台是 Worker 节点。当然,在完全掌握了 kubeadm 的用法之后,你可以在这个集群里添加更多的节点。Master 节点需要运行 apiserver、etcd、scheduler、controller-manager 等组件,管理整个集群,所以对配置要求比较高,至少是 2 核 CPU、4GB 的内存
本次实验条件拓扑如下:
2,安装前置条件
- 配置底层系统参数,<主机名、防火墙、iptables过滤组件、swap设置>
- 安装底层容器驱动,这里使用docker
3, 安装过程
首先,系统配置
- 配置主机名,确保节点主机名不一致,这里以master,work为列,修改文件:/etc/hostname
- 禁用防火墙
sudo ufw disable 禁止开机启动防火墙
sudo ufw status 查看状态
- 关闭swap交换分区
Kubernetes 1.8 开始要求关闭系统的 Swap,如果不关闭,默认配置下 kubelet 将无法启动
代码语言:javascript复制sed -i '/ swap / s/^/#/' /etc/fstab
通过free -mh 可以看到交换分区内存已经禁用了
如下:
其次,安装Docker
代码语言:javascript复制命令如下:
apt install docker.io
大致如下图:
到这里,docker一般就安装完了,但是鉴于国内的网站访问docker.hub,可能涉及到网络问题,这里一般建议加个国内源,绕开这个问题。设置如下:
代码语言:javascript复制更新 cgroupdriver 为 systemd,并更新下载源。
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://uy35zvn6.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
随后,重新加载一下docker ,让命令生效
代码语言:javascript复制systemctl reload docker
systemctl restart docker
我们可以通过docker version 查看当前的docker 版本。
第三,配置节点iptables链
代码语言:javascript复制cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
第四,安装kubeadm
kubeadm 可以直接从 Google 自己的软件仓库下载安装,但国内的网络不稳定,很难下载成功,需要改用其他的软件源,这里我选择了国内的某云厂商
代码语言:javascript复制
sudo apt install -y apt-transport-https ca-certificates curl
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
sudo apt update
sudo apt-get update
更新了软件仓库,我们就可以用 apt install 获取 kubeadm、kubelet 和 kubectl 这三个安装必备工具了。apt 默认会下载最新版本,比如使用和 minikube 相同的“1.23.3”:
命令如下:
代码语言:javascript复制sudo apt-get install -y kubeadm=1.23.3-00 kubelet=1.23.3-00 kubectl=1.23.3-00
截图如下:
安装完成之后,你可以用 kubeadm version、kubectl version 来验证版本是否正确:
kubeadm version
那么这样就安装成功。
注意 按照 Kubernetes 官网的要求,我们最好再使用命令 apt-mark hold ,锁定这三个软件的版本,避免意外升级导致版本错误:
代码语言:javascript复制sudo apt-mark hold kubeadm kubelet kubectl
第五 下载 Kubernetes 组件镜像
kubeadm 把 apiserver、etcd、scheduler 等组件都打包成了镜像,以容器的方式启动 Kubernetes,但这些镜像不是放在 Docker Hub 上,而是放在 Google 自己的镜像仓库网站 gcr.io,而它在国内的访问很困难,直接拉取镜像几乎是不可能的。
那怎么办?
我们可以提前在国内某云的镜像内,把此类的镜像提前下载下来,我们可以先查看此master节点需要下载那些组件?
可以通过如下API查看需要的组件详细信息
代码语言:javascript复制kubeadm config images list --kubernetes-version v1.23.3
大概需要的组件信息如下:
那么我们现在就去某镜像源去下载匹配这类的镜像资源。通过如下API
代码语言:javascript复制kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version v1.23.3
大概就让他下载就行
确认下载信息无误后,那么到这里,搭建集群的准备工作就完成了。
第六 安装Master节点
kubeadm 的用法非常简单,只需要一个命令 kubeadm init 就可以把组件在 Master 节点上运行起来,不过它还有很多参数用来调整集群的配置,你可以用 -h 查看。这里我只说一下我们实验环境用到的 3 个参数:--pod-network-cidr,设置集群里 Pod 的 IP 地址段。--apiserver-advertise-address,设置 apiserver 的 IP 地址,对于多网卡服务器来说很重要(比如 VirtualBox 虚拟机就用了两块网卡),可以指定 apiserver 在哪个网卡上对外提供服务。--kubernetes-version,指定 Kubernetes 的版本号
那我这里的设置如下:
代码语言:javascript复制kubeadm init
--kubernetes-version v1.23.3
--pod-network-cidr=10.10.0.0/16
--apiserver-advertise-address=192.168.50.101
--image-repository registry.aliyuncs.com/google_containers
--ignore-preflight-errors=all
截图如下:
根据提示,这步,也操作一下,大意就是要操作kubectl配置文件拷贝:
代码语言:javascript复制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
其他节点要加入集群必须要用指令里的 token 和 ca 证书,所以这条命令务必拷贝后保存好:
代码语言:javascript复制 sudo
kubeadm join 192.168.50.101:6443 --token 1ayc8g.kalx22bjd3rgmlat
--discovery-token-ca-cert-hash sha256:179175bde8bdc11b61185d78da1db56f94537df4890e9b1dd77b6caed5c1748a
安装完成后,你就可以使用 kubectl version、kubectl get node 来检查 Kubernetes 的版本和集群的节点状态了
第七 安装Flannel网络
机器如果没有安装网络插件,节点状态是不正常的。Kubernetes 定义了 CNI 标准,有很多网络插件,这里我选择最常用的 Flannel 它安装也很简单,只需要使用项目的“kube-flannel.yml”在 Kubernetes 里部署一下就好了。不过因为它应用了 Kubernetes 的网段地址,你需要修改文件里的“net-conf.json”字段,把 Network 改成刚才 kubeadm 的参数 --pod-network-cidr 设置的地址段。比如在这里,就要修改成“10.10.0.0/16” 参考:https://github.com/flannel-io/flannel/
代码语言:javascript复制
net-conf.json: |
{
"Network": "10.10.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
改好后,你就可以用 kubectl apply 来安装 Flannel 网络了:
代码语言:javascript复制kubectl apply -f kube-flannel.yml
也可以在后面加个 --v=9,打印详细过程
再通过kubectl get node ,我们就可以看到master节点状态恢复正常了
Master 节点的状态是“Ready”,表明节点网络也工作正常了,至此,Master节点工作搭建完成。
第七 安装work节点
除上面的第六步不执行外,其他操作都要全部执行一次。省略。
第八 加入master认证节点,搭建集群。
执行如下命令,一定sudo:
代码语言:javascript复制sudo
kubeadm join 192.168.50.101:6443 --token 1ayc8g.kalx22bjd3rgmlat
--discovery-token-ca-cert-hash sha256:179175bde8bdc11b61185d78da1db56f94537df4890e9b1dd77b6caed5c1748a
返回如下信息,表示节点加入成功。
它会连接 Master 节点,然后拉取镜像,安装网络插件,最后把节点加入集群.
Worker 节点安装完毕后,执行 kubectl get node ,就会看到两个节点都是“Ready”状态:
注意,如果加入后,发现work节点的status没有ready,可以重新kubeadm reset ,然后再加入就好了
四,集群测试
创建一个pod,命令如下:
代码语言:javascript复制kubectl run ngx --image=nginx:alpine
发现,pod建好了,分配在10.10.0.5这个节点上。
五、问题汇总
1,在work节点执行kubectl get node时,节点状态一直未好,解决办法:重新加入
2,若果出现port in use占用的情况,可以通过kubeadm reset进行重置
3,The connection to the server localhost:8080 was refused - did you specify the right host or port?
参考:https://www.cnblogs.com/Ao0216/p/15903134.html https://blog.csdn.net/CEVERY/article/details/108753379
4,创建容器时,一直在creating阶段,可能是网络问题,Failed to create sandbox for pod" err="rpc error: code = Unknown desc = failed to set up sandbox conta>
11月 02 17:16:50 Master kubelet[976180]: E1102 17:16:50.225069 976180 kuberuntime_manager.go:832] "CreatePodSandbox for pod failed" err="rpc error: code = Unknown desc = failed to set up sandbox conta>
11月 02 17:16:50 Master kubelet[976180]: E1102 17:16:50.225136 976180 pod_workers.go:918] "Error syncing pod, skipping" err="failed to "CreatePodSandbox
参考:https://www.likecs.com/show-305671586.html https://blog.csdn.net/sinat_28371057/article/details/113954836
5,the HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed wit 参考:
https://blog.csdn.net/qq_43762191/article/details/125567365
6,终极大招:
代码语言:javascript复制Kubernetes 还原
集群初始化如果遇到问题,可以使用下面的命令进行清理
# 1. 卸载服务
kubeadm reset
# 2. 删除相关容器 #删除镜像
docker rm $(docker ps -aq) -f
docker rmi $(docker images -aq) -f
# 3. 删除上一个集群相关的文件
rm -rf /var/lib/etcd
rm -rf /etc/kubernetes
rm -rf $HOME/.kube
rm -rf /var/etcd
rm -rf /var/lib/kubelet/
rm -rf /run/kubernetes/
rm -rf ~/.kube/
# 4. 清除网络
systemctl stop kubelet
systemctl stop docker
rm -rf /var/lib/cni/*
rm -rf /var/lib/kubelet/*
rm -rf /etc/cni/*
ifconfig cni0 down
ifconfig flannel.1 down
ifconfig docker0 down
ip link delete cni0
ip link delete flannel.1
systemctl start docker
# 5. 卸载工具
apt autoremove -y kubelet kubectl kubeadm kubernetes-cni
删除 /var/lib/kubelet/ 目录,删除前先卸载
for m in $(sudo tac /proc/mounts | sudo awk '{print $2}'|sudo grep /var/lib/kubelet);do
sudo umount $m||true
done
# 6. 删除所有的数据卷
sudo docker volume rm $(sudo docker volume ls -q)
# 7. 再次显示所有的容器和数据卷,确保没有残留
8,常见的调试API:
代码语言:javascript复制1,journalctl -xeu kubelet #查看运行日志
2,kubectl logs pod-id --namespace spaceid
3, kubectl describe podid
4, kubectl get pod -o yaml --查看pod的相关配置
5, kubectl get pod -A
6, kubectl get pod -o wide
7, kubectl describe pod pod-id
8, kubectl run xxx --v=9 详细打印其过程
9,如果是单master节点,需要去污才能使用。