kubeadm简介
《使用kubeadm升级K8S集群》一文中,了解了k8s集群中常见组件,并且使用kubeadm对k8s集群进行了升级。本文中,会学习使用kubeadm安装部署k8s集群。
Kubeadm is a tool built to provide kubeadm init and kubeadm join as best-practice “fast paths” for creating Kubernetes clusters.
更多内容,参考Overview of kubeadm和Installing kubeadm。
安装流程
目标:搭建一个k8s集群,包括master和node01两个节点,节点系统为centos7.6.1810。
master节点ip为192.168.56.200,node01节点ip为192.168.56.201。
1、环境准备。
2、在master节点和node01节点安装kubeadm。
3、初始化master节点,创建k8s集群(记得安装网络插件)。
4、node01节点加入到k8s集群。
5、验证安装。
环境准备
1、配置主机名
2、配置IP地址
3、允许 iptables 检查桥接流量
1 | cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf |
4、参考Docker入门,安装Docker
安装kubeadm
参考安装kubeadm。
1、确认系统版本cat /etc/redhat-release
2、执行安装kubeadm、kubelet和kubectl(两个节点都要执行)
1 | cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo |
centos安装这些组件时如果报错:[Errno -1] repomd.xml signature could not be verified for kubernetes
不考虑安全性的话,最简单的解决办法是修改 /etc/yum.repos.d/kubernetes.repo 文件,设置 repo_gpgcheck=0
3、查看kubelet版本kubelet --version
初始化master节点
参考Installing kubeadm on your hosts。
下载镜像文件
下载必须的镜像文件(默认从gcr.io下载)kubeadm config images pull
下载失败处理办法
如果下载镜像文件失败,那么需要科学上网,或者更改为国内源。这里选择更改为国内源。
1、导出一份默认配置文件kubeadm config print init-defaults > kubeadm.conf
2、改为国内源
编辑kubeadm.conf,imageRepository改为:
1 | imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers |
3、指定配置文件,重新执行下载kubeadm config images pull --config kubeadm.conf
[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.0
[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.0
[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.0
[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.0
[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6
[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0
[config/images] Pulled registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.6
执行初始化
1 | kubeadm init |
完成后,屏幕输出会提示创建配置文件,以及添加worker node的join命令,记录下来。
例如:
1 | kubeadm join 192.168.56.200:6443 --token abcdef.0123456789abcdef \ |
PS:如果忘记了添加worker node的join命令,可以重新生成。
1 | kubeadm token create --help |
生成新的join命令后,之前的join命令同样可以使用。
初始化报错解决办法
执行初始化报错:
[kubelet-check] It seems like the kubelet isn’t running or healthy.
The kubelet is not running
The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)
看着是 cgroup 问题,确认一下。
1 | docker system info | grep -i driver |
发现 docker 和 kubelet 服务中的cgroup不一致。
方法一:修改docker配置和kubelet保持一致。
编辑 /etc/docker/daemon.json ,添加:
1 | { |
方法二:修改kubelet配置和docker保持一致。
kubeadm.conf中添加:
1 |
|
重启docker,然后重新执行初始化:
1 | systemctl daemon-reload |
还是报同样的错误。查看错误详情:
1 | systemctl status kubelet |
“–cgroups-per-qos enabled, but –cgroup-root was not specified. defaulting to /“
“Failed to run kubelet” err=”failed to run Kubelet: running with swap on is not supported, please disable swap!
看这个提示,问题就很明显了,不支持swap,需要关闭。swapoff -a
编辑 /etc/fstab,注释掉swap配置。
1 | #/dev/mapper/centos-swap swap swap defaults 0 0 |
再次重新执行初始化:
1 | kubeadm reset |
出现新的报错:
Error getting node” err=”node "node" not found
编辑kubeadm.conf,修改apiserver地址。
1 | advertiseAddress: 192.168.56.200 |
再次重新执行初始化:
1 | kubeadm reset |
至此,终于成功初始化!
避免初始化报错的方法
1、修改kubelet配置和docker保持一致。
kubeadm.conf中添加:
1 |
|
2、修改apiserver地址为本机地址
编辑kubeadm.conf,修改advertiseAddress字段。
1 | advertiseAddress: 192.168.56.200 |
3、关闭swapswapoff -a
编辑 /etc/fstab,注释掉swap配置。
1 | #/dev/mapper/centos-swap swap swap defaults 0 0 |
4、执行初始化
1 | kubeadm reset |
创建配置文件
1 | mkdir -p $HOME/.kube |
验证安装
1 | docker ps -a |
验证发现问题
问题一:master节点的名字叫node
问题不大,这是因为在初始化的时候没有指定节点名字。在kubeadm.conf里指定即可(需要重新安装)。
1 | nodeRegistration: |
不重新安装的话,是否可以直接编辑修改节点的名称?kubectl edit nodes/node
,修改如下:
1 | metadata: |
很遗憾,不可以,报错:
error: At least one of apiVersion, kind and name was changed
没关系,就这么着吧,不改了。
问题二:coredns处于pending状态
查看coredns报错信息:
1 | kubectl get deployment/coredns -n kube-system -o yaml |
Warning FailedScheduling 2m57s (x36 over 38m) default-scheduler 0/1 nodes are available: 1 node(s) had taint {node.kubernetes.io/not-ready: }, that the pod didn’t tolerate.
原来是coredns默认无法部署在master节点,因为没有配置容忍。参考污点和容忍度进行配置即可。kubectl edit deployment/coredns -n kube-system -o yaml
tolerations部分添加:
1 | tolerations: |
问题三:coredns无法启动
问题二解决后,coredns可以调度了,但是无法启动。kubectl describe pods/coredns-55b7b56cf8-jv2dc -n kube-system
network is not ready: container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
仔细研读使用 kubeadm 创建集群,原来问题二是符合预期的,master节点还没有ready,因为缺少cni插件。
参考集群网络系统选择一个cni插件,这里我们选择flannel。
1 | kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml |
问题四:kube-flannel无法启动
Error registering network: failed to acquire lease: node “node” pod cidr not assigned
看来是初始化的时候没有加 pod-network-cidr 参数导致的,在kubeadm.conf中添加配置即可(需要重新安装)。
1 | networking: |
不重新安装的话,怎么补救呢?
编辑 /etc/kubernetes/manifests/kube-controller-manager.yaml ,添加参数:
1 | - command: |
然后重启kubelet:systemctl restart kubelet
kubectl get pods --all-namespaces
至此,所有组件全部启动成功。
避免验证发现错误的办法
1、在kubeadm.conf里指定节点名称
1 | nodeRegistration: |
2、在kubeadm.conf中添加pod网络配置
1 | networking: |
3、安装cni插件
1 | kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml |
node01加入k8s集群
1、使用join命令,添加node01节点到集群
1 | kubeadm join 192.168.56.200:6443 --token abcdef.0123456789abcdef \ |
2、验证结果
在master节点执行:kubectl get nodes
看到master节点和node01节点都是Ready的状态,说明安装成功。
开发模式
出于安全原因,k8s集群默认不会在控制节点(master节点)上调度Pod。如果我们希望可以在master节点上调度Pod,比如在开发测试时,可以去掉master节点的污点。kubectl taint nodes --all node-role.kubernetes.io/master-
验证安装
手动验证
1 | kubectl get nodes |
1 | kubectl run nginx |
test-infra
1、拉取源码go get -u k8s.io/test-infra/kubetest
2、执行kubetest
1 | kubetest --extract=v1.11.3 |
Smoke Test
按照Smoke Test文档操作一遍。
sonobuoy
官网地址:sonobuoy
源码地址:vmware-tanzu/sonobuoy
节点重启后coredns启动问题
master节点重启后,发现coredns无法正常启动。
Warning Unhealthy 2m1s (x22 over 5m) kubelet Readiness probe failed: HTTP probe failed with statuscode: 503
[ERROR] plugin/errors: HINFO: read udp 10.244.0.7:48010->202.106.195.68:53: i/o timeout
[INFO] plugin/ready: Still waiting on: “kubernetes”
参考How to solve CoreDNS always stuck at “waiting for kubernetes”?,发现需要关闭防火墙,低级错误!
1 | systemctl status firewalld |