kubeadm 部署 =================== centos安装k8s ---------------- 设置k8s的yum仓库地址,然后使用yum命令进行安装 :: cat < /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 setenforce 0 yum install -y kubelet kubeadm kubectl systemctl enable -now kubelet * kubeadm:用来初始化集群的命令行工具。 * kubelet:在集群中的每个节点上用来启动 pod 和容器等的后台进程。 * kubectl:用来与集群通信的命令行工具。 安装完成后启动kubelet。 k8s集群运行先决条件 --------------------- 1, cpu数量大于等于2, 否则会报以下错误 :: [ERROR NumCPU]: the number of available CPUs 1 is less than the required 2 2, docker服务必须首先运行 systemctl start docker.service 3, 必须关闭swap, 否则报以下错误 :: [ERROR Swap]: running with swap on is not supported. Please disable swap 关闭swap方法,在 /etc/fstab 中,将含有swap的一行开头以#注释, 然后重启系统即可。 可以使用top命令来查看,swap 内存为零。 通过命令直接关闭swap : swapoff -a 4, 设置bridge调用iptables, 否则会出现以下错误: :: [ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1 设置方法,在/etc/sysctl.conf 增加以下一行: net.bridge.bridge-nf-call-iptables = 1 5, etcd提示目录非空, 错误输出如下 :: [ERROR DirAvailable--var-lib-etcd]: /var/lib/etcd is not empty 解决方法: rm /var/lib/etcd/* -rf 6, 关闭selinux 在 /etc/sysconfig/selinux 中将SELINUX值改为disabled, 然后重启系统 关闭selinux的原因是允许容器访问宿主机的文件系统, 重启后运行 sestatus 命令查看是否生效。 :: [zhang@zhang1 ~]$ sestatus SELinux status: disabled kubeadm -------------- kubeadm是k8s集群的一个配置工具。 初始化集群 ------------ kubeadm init 命令启动一个 Kubernetes 主节点(管理节点) :: kubeadm init --apiserver-advertise-address=192.168.101.180 --image-repository registry.aliyuncs.com/google_containers --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16 --v=5 这是控制面初始化,执行时,需要从网络上下载镜像,因此需要一定的时间。192.168.101.180为服务器的IP, 需要更换为自己服务器的地址。启动成功后会输出以下类似信息 :: 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.56.128:6443 --token 983c4t.obppxddoze3n4tsf \ --discovery-token-ca-cert-hash sha256:186259c430f7d89d96ba63691ba625149c80abfbd510cfcd351f4330b1c43146 kubeadm join 192.168.56.128:6443 --token e6rnfa.d0igvvnsd8o25isa \ --discovery-token-ca-cert-hash sha256:5cd1d0b61cc18dca9964e0c2827a9f72ef30ffca54bf8acaf5ce03c38cb66055 最后两行的输出包含密码等私有信息,不能泄漏,否则有可能导致恶意攻击及信息被盗等风险。 各选项含义如下: * "--apiserver-advertise-address", api服务器地址。使用与默认网关关联的网络接口来设置此控制平面节点 API server 的广播地址。如果服务器有多个IP, 使用该选项来修改api服务器地址。 * --image-repository registry.aliyuncs.com/google_containers * --service-cidr=10.1.0.0/16 * --pod-network-cidr=10.244.0.0/16 * -control-plane-endpoint 可用于为所有控制平面节点设置共享端点。 允许 IP 地址和可以映射到 IP 地址的 DNS 名称。 可以使用以下命令来查看其默认参数 :: kubeadm config print init-defaults 拉取镜像命令 :: kubeadm config images pull 如果计划将单个控制平面 kubeadm 集群升级成高可用, 应该指定 --control-plane-endpoint 为所有控制平面节点设置共享端点。 端点可以是负载均衡器的 DNS 名称或 IP 地址。 管理节点创建完成后可以获取令牌 :: kubeadm token list 如果管理节点创建不正确,可以通过以下命令进行删除,这将对控制平面进行清理。 运行这个命令一定要慎重。 :: $ kubeadm reset 通过 netstat 来查看提供的tcp服务。 :: [root@zhang1 ~]# netstat -ltnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:10248 0.0.0.0:* LISTEN 2724/kubelet tcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 2855/kube-proxy tcp 0 0 192.168.56.128:2379 0.0.0.0:* LISTEN 2575/etcd tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 2575/etcd tcp 0 0 192.168.56.128:2380 0.0.0.0:* LISTEN 2575/etcd tcp 0 0 127.0.0.1:2381 0.0.0.0:* LISTEN 2575/etcd tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 851/rpcbind tcp 0 0 127.0.0.1:10257 0.0.0.0:* LISTEN 2559/kube-controlle tcp 0 0 127.0.0.1:10259 0.0.0.0:* LISTEN 2481/kube-scheduler tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1129/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1498/master tcp 0 0 127.0.0.1:39778 0.0.0.0:* LISTEN 2724/kubelet tcp6 0 0 :::10250 :::* LISTEN 2724/kubelet tcp6 0 0 :::6443 :::* LISTEN 2513/kube-apiserver tcp6 0 0 :::111 :::* LISTEN 851/rpcbind tcp6 0 0 :::10256 :::* LISTEN 2855/kube-proxy tcp6 0 0 :::22 :::* LISTEN 1129/sshd tcp6 0 0 ::1:25 :::* LISTEN 1498/master * 10248, 检查健康服务的端口。 * 10250,kubelet 服务监听的端口,它接收并执行 Master 发来的指令。 * 6443, kube apiserver监听端口。 节点已经为Ready状态 :: [zhang@zhang1 ~]$ kubectl get node NAME STATUS ROLES AGE VERSION zhang1 Ready master 3d17h v1.19.4 获取所有的pod, 以下是各组件均运行正常的输出,STATUS字段均为"Running" :: [root@zhang1 zhang]# kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-6d56c8448f-55r84 1/1 Running 1 2d17h kube-system coredns-6d56c8448f-7smch 1/1 Running 1 2d17h kube-system etcd-zhang1 1/1 Running 37 2d17h kube-system kube-apiserver-zhang1 1/1 Running 35 2d17h kube-system kube-controller-manager-zhang1 1/1 Running 5 2d17h kube-system kube-flannel-ds-zlvkl 1/1 Running 1 2d16h kube-system kube-proxy-d8ndl 1/1 Running 1 2d17h kube-system kube-scheduler-zhang1 1/1 Running 5 2d17h 查看kubernetes默认的名字空间的节点 :: kubectl get pods -n kube-system 工作节点 --------- 工作节点加入到集群中, 需要服务器地址和token, token可以在服务器上生成,命令为 :: kubeadm token create 加入集群 :: kubeadm join 192.168.101.172:6443 --token rgpuv4.3f5otdr81civra5o \ --discovery-token-ca-cert-hash sha256:5cd1d0b61cc18dca9964e0c2827a9f72ef30ffca54bf8acaf5ce03c38cb66055 或 :: kubeadm join 192.168.101.172:6443 --token rgpuv4.3f5otdr81civra5o --discovery-token-unsafe-skip-ca-verification 节点加入后,可以拷贝其授权,便于后续查看配置:: cp -i /etc/kubernetes/kubelet.conf $HOME/.kube/config 如果该节点不使用,可以删除节点 :: kubectl delete node 问题及分析 ------------ * 问题, pods的状态始终为“Init:CrashLoopBackOff” 解决方法: 可能时未关闭swap导致。 关闭swap。 也可能是容器网络镜像未下载成功,使用docker命令进行下载 :: docker pull quay.io/coreos/flannel:v0.13.0-rc2 * 出现以下错误 8080 was refused 访问错误 :: [zhang@localhost ~]$ kubectl get nodes The connection to the server localhost:8080 was refused - did you specify the right host or port? 解决方法: 切换到普通用户,然后执行 :: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config * 节点状态为 NotReady, 如何定位解决 :: [root@zhang1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION zhang1 NotReady master 10m v1.19.2 解决方法: 通过部署flannel即可解决, 部署命令:: kubectl apply -f kube-flannel.yml 还有一种可能是防火墙的问题,则关闭防火墙看看问题是否解决 :: systemctl stop firewalld 如果出现问题,可以查看log输出来分析问题,log日志文件为 /var/log/messages :: [root@zhang1 zhang]# tail /var/log/messages -f Sep 24 22:31:53 zhang1 journal: I0925 02:31:53.588956 1 client.go:360] parsed scheme: "passthrough" Sep 24 22:31:53 zhang1 journal: I0925 02:31:53.589027 1 passthrough.go:48] ccResolverWrapper: sending update to cc: {[{https://127.0.0.1:2379 0 }] } Sep 24 22:31:53 zhang1 journal: I0925 02:31:53.589041 1 clientconn.go:948] ClientConn switching balancer to "pick_first" Sep 24 22:31:58 zhang1 journal: 2020-09-25 02:31:58.836057 I | etcdserver/api/etcdhttp: /health OK (status code 200) Sep 24 22:32:08 zhang1 journal: 2020-09-25 02:32:08.837435 I | etcdserver/api/etcdhttp: /health OK (status code 200) Sep 24 22:32:18 zhang1 journal: 2020-09-25 02:32:18.839329 I | etcdserver/api/etcdhttp: /health OK (status code 200) Sep 24 22:32:28 zhang1 journal: 2020-09-25 02:32:28.836484 I | etcdserver/api/etcdhttp: /health OK (status code 200) Sep 24 22:32:29 zhang1 journal: I0925 02:32:29.550966 1 client.go:360] parsed scheme: "passthrough" Sep 24 22:32:29 zhang1 journal: I0925 02:32:29.551020 1 passthrough.go:48] ccResolverWrapper: sending update to cc: {[{https://127.0.0.1:2379 0 }] } Sep 24 22:32:29 zhang1 journal: I0925 02:32:29.551033 1 clientconn.go:948] ClientConn switching balancer to "pick_first" Sep 24 22:32:38 zhang1 journal: 2020-09-25 02:32:38.836072 I | etcdserver/api/etcdhttp: /health OK (status code 200) 如果还不能解决,则通过 journalctl -f -u kubelet 命令查看输出,然后根据输出分析定位问题。 我这里出现启动两个etcd导致 kube-apiserver 进程运行异常的问题。首次运行正常,在重启了主机之后 发现kube-apiserver连接不上,原来是主机和虚拟机都启动了etcd,导致配置信息读取异常。 解决方法,将主机的etcd进程关闭,命令为 :: systemctl disable etcd systemctl stop etcd ----- 进入运行中的容器:: kubectl exec buildbot-zhang2-5413be -it /bin/bash proxy ------------- 指定地址--address, 指定端口--port kubectl proxy --address=0.0.0.0 --port=8009 debug ------------- 安装netstat, 这样可以查看k8s绑定的端口 :: yum -y install net-tools sudo mkdir /etc/cni/net.d -p systemctl restart docker 设置工作节点角色 ------------------- 如果没有设置,节点的ROLES状态为 设置前 :: $ kubectl get nodes NAME STATUS ROLES AGE VERSION node1 Ready 14d v1.19.2 node2 Ready 14d v1.19.2 zhang1 Ready master 14d v1.19.2 设置节点的角色命令为label, 原理就是给 node 打标签, 只不过是特殊的标签 :: kubectl label node node1 node-role.kubernetes.io/worker=worker 设置完成后,工作节点的角色从变为 worker :: kubectl get nodes NAME STATUS ROLES AGE VERSION node1 Ready worker 14d v1.19.2 node2 Ready worker 14d v1.19.2 zhang1 Ready master 14d v1.19.2 重新部署 --------- 如果遇到某种原因需要重新部署k8s集群,例如服务器IP地址发生了改变。 1, 先关闭kubelet :: systemctl stop kubelet 2, 停止docker容器和删除docker镜像 :: docker stop $(docker ps -q) docker rm $(docker ps -a -q) 3, 删除etcd 的配置 :: rm /etc/kubernetes -rf rm /var/lib/etcd/ -rf 4, 执行 kubeadm reset 5, 初始化管理节点 :: kubeadm init --apiserver-advertise-address=192.168.101.180 --image-repository registry.aliyuncs.com/google_containers --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16 our 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.101.180:6443 --token n0ffnu.kgll39ow235x3ort \ --discovery-token-ca-cert-hash sha256:7067bdcb4bf4694fa7cc590fd01d466ed152860ac69aaa0e145711f60f04bfd4 FAQ ---------------- 1, 后期想加入新的node, 如何加入。 答: 默认 token 的有效期为 24 小时。当过期之后,该 token 就不可用了, 我们可以重新生成新的token, 然后使用token list 命令来查看,如下 :: kubeadm token create kubeadm token list 加入方法 :: kubeadm join --token qrepul.kvk46vhw4vdd4lut 192.168.101.172:6443 --discovery-token-unsafe-skip-ca-verification 2, Failed to create pod sandbox pod创建状态始终为"Init:0/1", 使用kubectl describe命令查看pod提示以下错误 :: Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedCreatePodSandBox 4m5s (x740 over 164m) kubelet, bj-zhang1 Failed to create pod sandbox: open c: no such file or directory 解决方法: 我这里在centOs7遇到该错误,因为没有安装系统dns组件,安装 systemd-resolved后解决,安装命令 :: yum install -y systemd-resolved systemctl enable --now systemd-resolved 等待几分钟,程序会自动去创建POD 参考资料 --------- Kubernetes 官方文档 https://kubernetes.io/zh/docs/home/