本文记录了完整的在虚拟机中搭建K8S集群遇到的问题及解决方法,仅供大家学习。
部分教程可参考:https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/nd7yOvdY
硬件准备
1. 准备安装一个master 节点和3个worker节点(强烈推荐为1核CPU,2G以上内存,如果设置为2核CPU,则本地打开多虚拟机会非常卡顿并得到内核软件锁死等错误信息),,本人首先只创建了一个master和worker1两台虚拟机,其他node 节点可以在worker1节点完成后通过虚拟机自带的克隆(clone)功能快速复制一模一样的环境(ip,hostname等信息需要自己更新),克隆时需要选择生成全新的网卡和mac地址等信息。
虚拟机创建好后通过以下命令 设置相应的hostname:
hostnamectl set-hostname master hostnamectl set-hostname worker1
master : 192.168.50.50
worker1:192.168.50.51
worker1:192.168.50.52
worker1:192.168.50.53
2. Oracle VM 设置:网卡连接都设置为桥接模式,通过宿主机(windows10)输入ipconfig /all 命令得到宿主机IP 和网关,DNS 等信息。以便在虚拟机中/etc/sysconfig/network-scripts/目录下网卡信息文件中配置中增加网络配置信息,在文件中增加IPADDR 和宿主机在同一网段,增加NETMASK 和GATEWAY,DNS1 等信息,这样可用保证虚拟机之间可以和宿主机在同一网段中,并能通过桥接连接访问外部互联网,方便k8s组件安装包的下载。
重启后route -n查看
注意:有些公司网络会对桥接模式的IP dhcp 获取有限制,如果需要宿主机访问虚拟机,则可以使用NAT 网络适配模式并进行端口映射。需要在全局设置中创建新的NAT network并分配好IP 网络段
3.修改各个虚拟机/etc/hosts文件,配置映射信息。
安装K8S组件 (每台主机需要安装docker-ce组件,此文docker安装步骤略过)
1.所有节点关闭和禁用各节点的防火墙:
systemctl stop firewalld && systemctl disable firewalld
临时关闭SELINUX:setenforce 0
查看SELINUX状态:sestatus -v
查看状态:getenforce
永久关闭 vi /etc/selinux/config
关闭交换分区:swapoff -a
也可以使用这命令修改: sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
2. 下载最新版本K8S kubectl
curl -LO https://dl.k8s.io/release/v1.23.4/bin/linux/amd64/kubectl
下载校验文件:curl -LO "https://dl.k8s.io/1.23.4/bin/linux/amd64/kubectl.sha256"
校验文件: echo "$(<kubectl.sha256) kubectl" | sha256sum --check
通过:kubectl: OK
安装:install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
查看安装版本是否最新 :kubectl version --client
3.所有节点主机添加安装源(进入网址操作)
https://developer.aliyun.com/mirror/kubernetes?spm=a2c6h.13651102.0.0.3e221b11kIpGBF
通过如下命令生成k8s repo文件
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
安装所需组件( 在所有节点)
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet #启用和开启kubelet服务
查看状态用 systemctl status kubelet,如果失败 则查看失败日志:journalctl -xefu kubelet
kubernetes 官方推荐docker等使用systemd 作为cgroupdriver,否则kubelet启动不了。
cat <<EOF > daemon.json { "exec-opts":["native.cgroupdriver=systemd"] } EOF
生成文件后通过命令移动到docker配置目录下
mv daemon.json /etc/docker
systemctl daemon-reload #重加载配置
systemctl restart docker #重启docker服务
如果kubelet启动仍然失败 提示 :failed to load Kubelet config file /var/lib/kubelet/config.yaml 则需要查看是否执行了kubeadm init命令(仅在主节点跑),
如果swap分区没关闭 需要swapoff -a 关闭分区 并进入文件 注释掉加载swap分区那行 /etc/fstab ,完毕后reboot重启。
4. 用kubeadm初始化一个集群(仅在主节点执行),失败了可用kubeadm reset重置 :
kubeadm init --image-repository=registry.aliyuncs.com/google_containers --ignore-preflight-errors=NumCPU
增加 --ignore-preflight-errors=NumCPU 命令是为了跳过要求cpu核高于2的限制,上文提到如果设置虚拟机cpu为2个则会很卡。
不增加则运行kubeadm init 会出现错误: [ERROR NumCPU]: the number of available CPUs 1 is less than the required 2
另外一种解决方法:临时增加虚拟机为2个也可以,完成安装后可恢复为1个。
安装过程中当出现字样 :Your Kubernetes control-plane has initialized successfully! 说明安装成功!
TIPS: 如果更换了虚拟机的 ip地址则需要更改相应的hosts文件和/etc/kubernetes路径下很多conf 文件里的ip地址,需要 kubeadm reset后重新安装,
否则会出现kubectl 各种命令失效连接不上server的错误。如果reset不行 ,则可以yum remove 删除之前的kubectl keubelet kubeadm 等组件。
安装过程中还会打印出token信息,便于其他节点连接master主机加入K8S集群。注意保存该包含token的命令行信息 ,命令行中IP信息为master节点,下列命令是在worker节点中执行的。
kubeadm join 192.168.50.50:6443 --token 6vzabt.3zp3cbs7f7wmw4r8 --discovery-token-ca-cert-hash sha256:04abedbba674eab570cad77abc4f2ac61e029fa31c666493670ad958b74a2f3d
如果丢失或者过期,则可以重新获取,执行命令
kubeadm token create --print-join-command
TIPS: 正常集群都是局域网内的机器,如果是用外网别的云平台机器加入当前集群,则需要配置iptables :iptables -t nat -A OUTPUT -d TX云外网ip -j DNAT --to-destination TX云内网ip
iptables -t nat -A OUTPUT -d Ali内网ip -j DNAT --to-destination Ali外网ip
两台机子需要相反得操作,网上搜下iptables就差不多了,如果是使用TX云部署的时候,在端口转发。
5.# 复制授权文件,以便 kubectl 可以有权限访问集群 # 如果你其他节点需要访问集群,需要从主节点复制这个文件过去其他节点
mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config
6. 把其他工作节点加入到集群中
kubeadm join 192.168.50.50:6443 --token 6vzabt.3zp3cbs7f7wmw4r8 --discovery-token-ca-cert-hash sha256:04abedbba674eab570cad77abc4f2ac61e029fa31c666493670ad958b74a2f3d
7.安装网络插件calico.yaml
此时start 然后查看master节点 systemctl start kubelet systemctl status kubelet,发现服务已经running了,但是有错:Unable to update cni config" err="no networks found in /etc/cni/net.d
在老版本1.21之前可安装的是 kube-flannel(被墙了,需要自己网上搜索文件下载)
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
我当前安装的是1.23.4 ,所以安装calico
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
如果报错:Port 10250 is in use 则执行以下:
kubeadm reset 重置配置
在将worker 节点加入master时报错:It seems like the kubelet isn't running or healthy,无法加入master节点
journalctl -xefu kubelet查看kubelet日志 发现swap未关闭 ,则需要关闭。
8.安装完成后查看安装信息
通过命令kubectl get node 查看集群节点信息, 通过kubectl get configmap -n kube-system 命令查看已安装插件信息,如果出现NotReady的节点,极可能是忘记安装了网络插件。
如果开启两个虚拟主机很卡 而且经常 出现soft lockup cpu#1 stuck 等错误,则需要改回虚拟机处理器设置为1个即可,之前安装k8s组件时 设置了2个。
9. worker node 节点加入进master节点后 ,通过命令查看关键pod运行状态
kubectl get pod -n kube-system
如果有发现coredns两个pod无法启动 一直为ContainerCreating 状态,kubectl edit cm coredns -n kube-system 命令进入文件删除loop 所在行 退出后 重启 coredns pods并删除那2个运行失败的 ,再次查看 他们会自动创建运行。如果此种方法仍然失败,则kubectl delete pod coredns-xxx-xxx -n kube-system 删除
那2个失败的容器,如果还是无法重新创建成功 则输入命令查看pod日志信息:
kubectl describe pods -n kube-system coredns-6d8c4cb4d-jgxwb
更大的可能是忘记安装了网络插件 :我在安装过程中复制错了插件地址kubectl apply -f https://projectcalico.docs.tigera.io/manifests/flannel-migration/calico.yaml,导致calico没有安装成功。正确的是 kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
删除文件,可以用命令 kubectl delete -f xxxx.yaml
kubectl get cs 查询健康状态
10. 安装dashboard
注意该文件地址有时会无法访问
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml
可以下载到本地保存比如保存k8s-dashboar.yaml.
vim k8s-dashboar.yaml 增加type: nodeport 模式
执行变化 :
kubectl apply -f k8s-dashboar.yaml
如果不增加nodeport模式,则用kubectl 命令行工具来启用 Dashboard 访问:
kubectl proxy
查看clusterIP 信息
get svc -n kubernetes-dashboard
安装成功后 通过master IP 访问
http://192.168.50.50:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login
出现 Token和KubeConfig ,根据提示操作即可
11. 生成admin 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}')
复制下方token
如果使用nodeport 模式,则查看NodePort服务端口位32275
kubectl get service --all-namespaces |grep dash
则通过https://192.168.50.50:32275/#/login 访问,复制上方步骤11生成的admin token
登录成功
TIPS:如果重启机器后Dashboard 没有及时up,可能是在下载安装..... 意外的机器重启可能会导致一些docker容器出现异常 ,需要手动查看 docker ps -a 删掉不在运行的容器,否则K8S 服务会有问题。
kubectl get pods --all-namespace 查看所有的pod
配置使用overlay2
# cat /etc/docker/daemon.json
{
"storage-opts": [
"overlay2.override_kernel_check=true",
"overlay2.size=10G"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m"
}
}
systemctl daemon-reload systemctl restart docker
这样就可以把每个容器磁盘大小限制在10G了
12.同步K8S 集群网络时间
做时间同步
之前的版本:yum install -y ntp
centos8:yum -y install chrony
查看同步状态 chronyc sourcestats
查看ntp详细的同步状态 chronyc sources -v
查看时间同步状态 timedatectl status
# 开启网络时间同步
timedatectl set-ntp true
# 查看时区列表
timedatectl list-timezones
timedatectl list-timezones | grep -E "Asia/S.*"
设定为上海时区timedatectl set-timezone Asia/Shanghai
13.查看全属性pod 状态信息
kubectl get pods --all-namespaces -o wide
查看所有kind资源类型
kubectl api-resources -o wide --namespaced=true 或者kubectl api-resources -o wide --namespaced=false
创建nginxpod
kubectl create deployment web --image=nginx
暴露对外接口
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
定义一个service并导出yaml文件类型(Type如果没做设置,默认ClusterIP) :kubectl expose deployment web --port=80 --target-port=80 --dry-run -o yaml >service1.yaml,
基于这个service1.yaml可通过kubectl apply -f service1.yaml 创建service
查看service kubectl get svc
删除service kubectl delete service nginx-web
显示完成的docker描述信息,不显示省略号:docker search kube-webhook-certgen:v1.1.1 --no-trunc
14.设置swap
****************************设置swap*****************
free -m
swapon -s
dd if=/dev/zero of=/tmp/swap bs=1M count=4096 通过dd命令在/tmp/目录下新增加一个4G大小的空文件。
chmod 600 /tmp/swap 修改文件权限,只有root读写
mkswap /tmp/swap 使用mkswap命令把创建的文件格式化为swap
ls -lh /tmp/swap #查看创建的文件大小和权限
swapon /tmp/swap 使用swapon命令使swap生效
编辑fatab文件加入下面swap 便于下次启用
/tmp/swap swap swap defaults 0 0