kubeadm 部署

centos安装k8s

设置k8s的yum仓库地址,然后使用yum命令进行安装

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
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 <node_name>

问题及分析

  • 问题, 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  <nil> 0 <nil>}] <nil> <nil>}
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  <nil> 0 <nil>}] <nil> <nil>}
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状态为<none> 设置前

$ kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
node1    Ready    <none>   14d   v1.19.2
node2    Ready    <none>   14d   v1.19.2
zhang1   Ready    master   14d   v1.19.2

设置节点的角色命令为label, 原理就是给 node 打标签, 只不过是特殊的标签

kubectl label node node1 node-role.kubernetes.io/worker=worker

设置完成后,工作节点的角色从<none>变为 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/