kubenetes 集群二进制安装之node节点docker-ce和kubenetes组件安装部署 – 21运维
通知: .-...

kubenetes 集群二进制安装之node节点docker-ce和kubenetes组件安装部署

K8S 21运维 17847浏览

一,安装docker-ce
1,更新yum源
本文采用阿里云yum源和docker-ce 18.06版本

wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum clean all  && yum makecache fast

2,安装docker-ce
首先安装依赖:

yum install  yum-utils device-mapper-persistent-data lvm2 -y
yum list docker-ce.x86_64 --showduplicates | sort -r #可以选择指定版本,默认最新
yum install docker-ce  -y

 

我们之前安装了flannel,如用到里边设置的网段信息,那么我们需要修改一下docker服务的配置文件,加载flannel的环境变量才能配合flannel一起使用。
编辑docker.service在service字段下添加一行并修改docker启动加载参数 如下信息(部分人使用的是flannel二进制安装,这里请确认自己的环境变量位置):

EnvironmentFile=/run/flannel/docker  #添加的参数,这样docker启动就可以读取flannel里边的网段参数信息
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS  #通过ps -ef查看docker加载网段信息
ExecStartPost=/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT  #解决跨node 容器不通信问题

 

配置docker加速以及仓库:

mkdir -p /etc/docker
vim /etc/docker/daemon.json 
{
  "registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"],#配置docker加速,采用阿里云
  "insecure-registries":["10.1.14.16:5000"] #这里是配置的自己的一个私有仓库
}

systemctl daemon-reload
systemctl restart docker

docker安装完毕。
说明:这里最好ip a 查看下docker 网桥ip,如果还是默认的172.17则说明flannel与docker配合有问题。

二,检查tls证书和kubeconfig配置文件
1,配置node之前,需要确认之前的工作tls证书以及kubeconfig文件是否都传入到node节点的 /etc/kubernetes/目录:

[root@node02 kubernetes]# tree  /etc/kubernetes/
/etc/kubernetes/
├── bootstrap.kubeconfig
├── config
├── kube-proxy.kubeconfig
└── ssl
    ├── admin-key.pem
    ├── admin.pem
    ├── ca-key.pem
    ├── ca.pem
    ├── kube-proxy-key.pem
    ├── kube-proxy.pem
    ├── kubernetes-key.pem
    └── kubernetes.pem

1 directory, 10 files

2,将安装包里的kubelet kube-proxy分发到node节点

scp  kubelet node01:/usr/local/bin/
scp  kubelet node02:/usr/local/bin/
scp  kube-proxy  node01:/usr/local/bin/
scp  kube-proxy  node02:/usr/local/bin/

三,配置kubelet
1.创建kubelet的service配置文件
文件位置/usr/lib/systemd/system/kubelet.service

[Unit]
Description=Kubernetes Kubelet Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service

[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/kubelet
ExecStart=/usr/local/bin/kubelet \
            $KUBE_LOGTOSTDERR \
            $KUBE_LOG_LEVEL \
            $KUBELET_ADDRESS \
            $KUBELET_PORT \
            $KUBELET_HOSTNAME \
            $KUBE_ALLOW_PRIV \
            $KUBELET_POD_INFRA_CONTAINER \
            $KUBELET_ARGS
Restart=on-failure

[Install]
WantedBy=multi-user.target

说明:
(1)kubelet的配置文件/etc/kubernetes/kubelet。其中的IP地址更改为你的每台node节点的IP地址。
(2)在启动kubelet之前,需要先手动创建/var/lib/kubelet目录。

2,/etc/kubernetes/kubelet

[root@node01 kubernetes]# cat   /etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=0.0.0.0"
KUBELET_HOSTNAME="--hostname-override=10.1.14.25"
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1"
KUBELET_ARGS="--cgroup-driver=cgroupfs --cluster-dns=10.254.0.2 --bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig --kubeconfig=/etc/kubernetes/kubelet.kubeconfig  --cert-dir=/etc/kubernetes/ssl --cluster-domain=cluster.local --hairpin-mode promiscuous-bridge --serialize-image-pulls=false --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice  --fail-swap-on=false"

说明:
如果使用systemd方式启动,则需要额外增加两个参数–runtime-cgroups=/systemd/system.slice –kubelet-cgroups=/systemd/system.slice
–experimental-bootstrap-kubeconfig 在1.9版本已经变成了–bootstrap-kubeconfig
–address 不能设置为 127.0.0.1,否则后续 Pods 访问 kubelet 的 API 接口时会失败,因为 Pods 访问的 127.0.0.1 指向自己而不是 kubelet;
如果设置了 –hostname-override 选项,则 kube-proxy 也需要设置该选项,否则会出现找不到 Node 的情况;
“–cgroup-driver 配置成 systemd,不要使用cgroup,否则在 CentOS 系统中 kubelet 将启动失败(保持docker和kubelet中的cgroup driver配置一致即可,不一定非使用systemd)。
–bootstrap-kubeconfig 指向 bootstrap kubeconfig 文件,kubelet 使用该文件中的用户名和 token 向 kube-apiserver 发送 TLS Bootstrapping 请求;
管理员通过了 CSR 请求后,kubelet 自动在 –cert-dir 目录创建证书和私钥文件(kubelet-client.crt 和 kubelet-client.key),然后写入 –kubeconfig 文件;

–cluster-dns 指定 kubedns 的 Service IP(可以先分配,后续创建 kubedns 服务时指定该 IP),–cluster-domain 指定域名后缀,这两个参数同时指定后才会生效;
–cluster-domain 指定 pod 启动时 /etc/resolve.conf 文件中的 search domain ,起初我们将其配置成了 cluster.local.,这样在解析 service 的 DNS 名称时是正常的,可是在解析 headless service 中的 FQDN pod name 的时候却错误,因此我们将其修改为 cluster.local,去掉最后面的 ”点号“ 就可以解决该问题,关于 kubernetes 中的域名/服务名称解析请参见我的另一篇文章。
–kubeconfig=/etc/kubernetes/kubelet.kubeconfig中指定的kubelet.kubeconfig文件在第一次启动kubelet之前并不存在,请看下文,当通过CSR请求后会自动生成kubelet.kubeconfig文件,如果你的节点上已经生成了~/.kube/config文件,你可以将该文件拷贝到该路径下,并重命名为kubelet.kubeconfig,所有node节点可以共用同一个kubelet.kubeconfig文件,这样新添加的节点就不需要再创建CSR请求就能自动添加到kubernetes集群中。同样,在任意能够访问到kubernetes集群的主机上使用kubectl –kubeconfig命令操作集群时,只要使用~/.kube/config文件就可以通过权限认证,因为这里面已经有认证信息并认为你是admin用户,对集群拥有所有权限。
KUBELET_POD_INFRA_CONTAINER 是基础镜像容器,这里我用的aliyun的基础镜像registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1。

3,启动kubelet

systemctl daemon-reload
systemctl enable kubelet
systemctl start kubelet
systemctl status kubelet

(1)这里可能会有个报错导致启动失败:error: failed to run Kubelet: cannot create certificate signing request: certificatesigningrequests.certificates.k8s.io is forbidden: User “kubelet-bootstrap” cannot create certificatesigningrequests.certificates.k8s.io at the cluster scope

原因是:kubelet-bootstrap并没有权限创建证书。所以要创建这个用户的权限并绑定到这个角色上。

解决方法是在master上执行:

kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap


(2)如下报错解决办法:

Nov 12 13:51:09 node01 kubelet: I1112 13:51:09.024227    9739 kubelet_node_status.go:70] Attempting to register node 10.1.14.25
Nov 12 13:51:09 node01 kubelet: E1112 13:51:09.028046    9739 kubelet_node_status.go:92] Unable to register node "10.1.14.25" with API server: nodes is forbidden: User "system:node:10.1.14.25" cannot create resource "nodes" in API group "" at the cluster scope

1.8版本之前.开启rbac后,apiserver默认绑定system:nodes组到system:node的clusterrole。v1.8之后,此绑定默认不存在,需要手工绑定,否则kubelet启动后会报认证错误,使用kubectl get nodes查看无法成为Ready状态。
解决办法:

kubectl create clusterrolebinding kubelet-node-clusterbinding --clusterrole=system:node --group=system:nodes

查看集群角色绑定:

[root@master01 .kube]#  kubectl describe clusterrolebindings kubelet-node-clusterbinding
Name:         kubelet-node-clusterbinding
Labels:       
Annotations:  
Role:
  Kind:  ClusterRole
  Name:  system:node
Subjects:
  Kind   Name          Namespace
  ----   ----          ---------
  Group  system:nodes 

再次观察journalctl -xe或者tailf /var/log/message查看报错信息。

4,通过kublet的TLS证书请求
kubelet 首次启动时向 kube-apiserver 发送证书签名请求,必须通过后 kubernetes 系统才会将该 Node 加入到集群。

[root@master01 kubernetes]# kubectl  get node
No resources found.

通过master查看未授权的 CSR 请求:

[root@master01 kubernetes]# kubectl  get csr
NAME                                                   AGE   REQUESTOR           CONDITION
node-csr-AfvPdwMOXgGcUG1jdFrwIZpyFoIGSAY2_PV1Llupxpo   14s   kubelet-bootstrap   Pending

通过 CSR 请求

[root@master01 kubernetes]# kubectl certificate approve node-csr-AfvPdwMOXgGcUG1jdFrwIZpyFoIGSAY2_PV1Llupxpo
certificatesigningrequest.certificates.k8s.io/node-csr-AfvPdwMOXgGcUG1jdFrwIZpyFoIGSAY2_PV1Llupxpo approved
[root@master01 kubernetes]# kubectl  get csr
NAME                                                   AGE     REQUESTOR           CONDITION
node-csr-AfvPdwMOXgGcUG1jdFrwIZpyFoIGSAY2_PV1Llupxpo   2m46s   kubelet-bootstrap   Approved,Issued

自动生成了 kubelet kubeconfig 文件和公私钥:

[root@node01 kubernetes]# ll
total 28
-rw-------. 1 root root 2164 Nov 12 08:32 bootstrap.kubeconfig
-rw-r--r--. 1 root root  658 Nov 12 12:05 config
-rw-r--r--. 1 root root  856 Nov 12 13:12 kubelet
-rw-------. 1 root root 2293 Nov 12 13:03 kubelet.kubeconfig
-rw-------. 1 root root 6266 Nov 12 08:32 kube-proxy.kubeconfig
drwxr-xr-x. 2 root root 4096 Nov 12 13:03 ssl
[root@node01 kubernetes]# ll  ssl/kubelet*
-rw-------. 1 root root 1269 Nov 12 13:03 ssl/kubelet-client-2018-11-12-13-03-24.pem
lrwxrwxrwx. 1 root root   58 Nov 12 13:03 ssl/kubelet-client-current.pem -> /etc/kubernetes/ssl/kubelet-client-2018-11-12-13-03-24.pem
-rw-r--r--. 1 root root 2169 Nov 12 12:56 ssl/kubelet.crt
-rw-------. 1 root root 1675 Nov 12 12:56 ssl/kubelet.key

说明:
假如你更新kubernetes的证书,只要没有更新token.csv,当重启kubelet后,该node就会自动加入到kuberentes集群中,而不会重新发送certificaterequest,也不需要在master节点上执行kubectl certificate approve操作。前提是不要删除node节点上的/etc/kubernetes/ssl/kubelet*和/etc/kubernetes/kubelet.kubeconfig文件。否则kubelet启动时会提示找不到证书而失败。

注意:如果启动kubelet的时候见到证书相关的报错,有个trick可以解决这个问题,可以将master节点上的~/.kube/config文件(该文件在安装kubectl命令行工具这一步中将会自动生成)拷贝到node节点的/etc/kubernetes/kubelet.kubeconfig位置,这样就不需要通过CSR,当kubelet启动后就会自动加入的集群中。

四,配置kube-proxy

1,创建 kube-proxy 的service配置文件
文件路径/usr/lib/systemd/system/kube-proxy.service

[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target

[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/proxy
ExecStart=/usr/local/bin/kube-proxy \
        $KUBE_LOGTOSTDERR \
        $KUBE_LOG_LEVEL \
        $KUBE_MASTER \
        $KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

2,创建kube-proxy配置文件/etc/kubernetes/proxy

KUBE_PROXY_ARGS="--bind-address=10.1.14.25 --hostname-override=10.1.14.25 --proxy-mode=ipvs --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig --cluster-cidr=10.254.0.0/16"

3,启动

systemctl daemon-reload
systemctl enable kube-proxy
systemctl start kube-proxy
systemctl status kube-proxy

至此,集群搭建完毕。

[root@master01 kubernetes]# kubectl   get node  -o wide
NAME         STATUS   ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION          CONTAINER-RUNTIME
10.1.14.25   Ready       31h   v1.12.2   10.1.14.25            CentOS Linux 7 (Core)   3.10.0-862.el7.x86_64   docker://18.9.0
10.1.14.26   Ready       31h   v1.12.2   10.1.14.26            CentOS Linux 7 (Core)   3.10.0-862.el7.x86_64   docker://18.9.0

五,集群验证
简单验证一下集群:

kubectl run nginx --replicas=2 --labels="run=load-balancer-example" --image=nginx  --port=80

可以查看两个node上已经分别有pod创建:

[root@master01 .kube]# kubectl  get pod  -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP           NODE         NOMINATED NODE
nginx-774d74897-rf76m   1/1     Running   0          77s   172.17.0.2   10.1.14.26   
nginx-774d74897-zg8rm   1/1     Running   0          77s   172.17.0.2   10.1.14.25   

暴露服务:

kubectl expose deployment nginx --type=NodePort --name=example-service
[root@master01 .kube]# kubectl describe svc example-service
Name:                     example-service
Namespace:                default
Labels:                   run=load-balancer-example
Annotations:              
Selector:                 run=load-balancer-example
Type:                     NodePort
IP:                       10.254.116.62
Port:                       80/TCP
TargetPort:               80/TCP
NodePort:                   31837/TCP
Endpoints:                172.17.0.2:80,172.17.0.2:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   

由此可见Nodepoints对外暴露的端口为31837(也可以自己定义端口),于是我们就可以通过http://10.1.14.25:31837/ 和http://10.1.14.26:31837/就都可以访问到nginx欢迎页面了。

参考文章: 部署node节点

转载请注明:21运维 » kubenetes 集群二进制安装之node节点docker-ce和kubenetes组件安装部署