官方原文: https://www.kubernetes.org.cn/5551.html
kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,kubeadm会对集群配置方面的一些实践做调整,通过实验kubeadm可以学习到Kubernetes官方在集群配置上一些新的最佳实践。
最近发布的Kubernetes 1.15中,kubeadm对HA集群的配置已经达到beta可用,说明kubeadm距离生产环境中可用的距离越来越近了。
Kubernetes集群组件:
etcd 一个高可用的K/V键值对存储和服务发现系统
flannel 实现夸主机的容器网络的通信
kube-apiserver 提供kubernetes集群的API调用
kube-controller-manager 确保集群服务
kube-scheduler 调度容器,分配到Node
kubelet 在Node节点上按照配置文件中定义的容器规格启动容器
kube-proxy 提供网络代理服务
主机名 | IP地址 |
k8s-master | 192.168.169.21 |
k8s-node1 | 192.168.169.24 |
k8s-node2 | 192.168.169.25 |
k8s-node3 | 192.168.169.26 |
在安装之前,需要先做如下准备。4台CentOS 7.6主机如下:
如果各个主机启用了防火墙,需要开放Kubernetes各个组件所需要的端口,可以查看Installing kubeadm中的”Check required ports”一节。 这里简单起见在各节点禁用防火墙:
由于ipvs已经加入到了内核的主干,所以为kube-proxy开启ipvs的前提需要加载以下的内核模块:
上面脚本创建了的/etc/sysconfig/modules/ipvs.modules文件,保证在节点重启后能自动加载所需模块。 使用lsmod | grep -e ip_vs -e nf_conntrack_ipv4命令查看是否已经正确加载所需的内核模块。
如果以上前提条件如果不满足,则即使kube-proxy的配置开启了ipvs模式,也会退回到iptables模式
Kubernetes从1.6开始使用CRI(Container Runtime Interface)容器运行时接口。默认的容器运行时仍然是Docker,使用的是kubelet中内置dockershim CRI实现。
安装指定版本docker
yum install -y –setopt=obsoletes=0 \ docker-ce-18.09.7-3.el7
确认一下iptables filter表中FOWARD链的默认策略(pllicy)为ACCEPT。
根据文档CRI installation中的内容,对于使用systemd作为init system的Linux的发行版,使用systemd作为docker的cgroup driver可以确保服务器节点在资源紧张的情况更加稳定,因此这里修改各个节点上docker的cgroup driver为systemd。
*如果机器是代理上网,需要配置docker的http代理:
# mkdir /etc/systemd/system/docker.service.d
# vim /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment=”HTTP_PROXY=http://192.168.1.1:3128″
从安装结果可以看出还安装了cri-tools, kubernetes-cni, socat三个依赖:
官方从Kubernetes 1.14开始将cni依赖升级到了0.7.5版本
socat是kubelet的依赖
cri-tools是CRI(Container Runtime Interface)容器运行时接口的命令行工具
运行kubelet –help可以看到原来kubelet的绝大多数命令行flag参数都被DEPRECATED了,如:
而官方推荐我们使用–config指定配置文件,并在配置文件中指定原来这些flag所配置的内容。具体内容可以查看这里Set Kubelet parameters via a config file。这也是Kubernetes为了支持动态Kubelet配置(Dynamic Kubelet Configuration)才这么做的,参考Reconfigure a Node’s Kubelet in a Live Cluster。
kubelet的配置文件必须是json或yaml格式,具体可查看这里。
使用kubeadm默认配置初始化的集群,会在master节点打上node-role.kubernetes.io/master:NoSchedule的污点,阻止master节点接受调度运行工作负载。这里测试环境只有两个节点,所以将这个taint修改为node-role.kubernetes.io/master:PreferNoSchedule。
在开始初始化集群之前可以使用kubeadm config images pull预先在各个节点上拉取所k8s需要的docker镜像。
注意这一条命令需要保存好(添加集群使用)
kubeadm join 192.168.169.21:6443 –token 4qcl2f.gtl3h8e5kjltuo0r \ –discovery-token-ca-cert-hash sha256:7ed5404175cc0bf18dbfe53f19d4a35b1e3d40c19b10924275868ebf2a3bbe6e
上面记录了完成的初始化输出的内容,根据输出的内容基本上可以看出手动初始化安装一个Kubernetes集群所需要的关键步骤。 其中有以下关键内容:
[kubelet-start] 生成kubelet的配置文件”/var/lib/kubelet/config.yaml”
[certs]生成相关的各种证书
[kubeconfig]生成相关的kubeconfig文件
[control-plane]使用/etc/kubernetes/manifests目录中的yaml文件创建apiserver、controller-manager、scheduler的静态pod
[bootstraptoken]生成token记录下来,后边使用kubeadm join往集群中添加节点时会用到
下面的命令是配置常规用户如何使用kubectl访问集群:
最后给出了将节点加入集群的命令kubeadm join 192.168.169.21:6443 –token 4qcl2f.gtl3h8e5kjltuo0r \ –discovery-token-ca-cert-hash sha256:7ed5404175cc0bf18dbfe53f19d4a35b1e3d40c19b10924275868ebf2a3bbe6e
这里注意kube-flannel.yml这个文件里的flannel的镜像是0.11.0,quay.io/coreos/flannel:v0.11.0-amd64
如果Node有多个网卡的话,参考flannel issues 39701,目前需要在kube-flannel.yml中使用–iface参数指定集群主机内网网卡的名称,否则可能会出现dns无法解析。需要将kube-flannel.yml下载到本地,flanneld启动参数加上–iface=<iface-name>
注:在此过程中可能会出现curl容器一直处于pending状态,报错信息如下:
0/1 nodes are available: 1 node(s) had taints that the pod didn’t tolerate.
解决方法:
# kubectl taint nodes –all node-role.kubernetes.io/master-
如何从集群中移除Node
如果需要从集群中移除node2这个Node执行下面的命令:
在master节点上执行:
# kubectl drain node2 –delete-local-data –force –ignore-daemonsets
# kubectl delete node node2
在node2上执行:
# kubeadm reset
# ifconfig cni0 down
# ip link delete cni0
# ifconfig flannel.1 down
# ip link delete flannel.1
# rm -rf /var/lib/cni/
报错:
error execution phase preflight: couldn’t validate the identity of the API Server: abort connecting to API servers after timeout of 5m0s
# kubeadm join ……
error execution phase preflight: couldn’t validate the identity of the API Server: abort connecting to API servers after timeout of 5m0
原因:master节点的token过期了
解决:重新生成新token
在master重新生成token
# kubeadm token create
424mp7.nkxx07p940mkl2nd
# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed ‘s/^.* //’
d88fb55cb1bd659023b11e61052b39bbfe99842b0636574a16c76df186fd5e0d
Node节点重新join就可以了
kubeadm join 192.168.169.21:6443 –token 424mp7.nkxx07p940mkl2nd \--discovery-token-ca-cert-hash sha256:d88fb55cb1bd659023b11e61052b39bbfe99842b0636574a16c76df186fd5e0d
四、kube-proxy开启ipvs
其中mode原来是空,默认为iptables模式,改为ipvs
scheduler默认是空,默认负载均衡算法为轮训
编辑完,保存退出
删除所有kube-proxy的pod
# kubectl delete pod xxx -n kube-system
日志中打印出了Using ipvs Proxier,说明ipvs模式已经开启。
越来越多的公司和团队开始使用Helm这个Kubernetes的包管理器,这里也将使用Helm安装Kubernetes的常用组件。
Helm由客户端命helm令行工具和服务端tiller组成,Helm的安装十分简单。 下载helm命令行工具到master节点node1的/usr/local/bin下,这里下载的2.14.1版本
为了安装服务端tiller,还需要在这台机器上配置好kubectl工具和kubeconfig文件,确保kubectl工具可以在这台机器上访问apiserver且正常使用。 这里的node1节点已经配置好了kubectl。
因为Kubernetes APIServer开启了RBAC访问控制,所以需要创建tiller使用的service account: tiller并分配合适的角色给它。 详细内容可以查看helm文档中的Role-based Access Control。 这里简单起见直接分配cluster-admin这个集群内置的ClusterRole给它。创建helm-rbac.yaml文件
注:如果tiller的状态一直是ErrImagePull的时候,需要更换国内helm源。
NAME READY STATUS RESTARTS AGE
tiller-deploy-7bf78cdbf7-fkx2z 0/1 ImagePullBackOff 0 79s
解决方法1:
1、删除默认源
# helm repo remove stable
2、 增加新的国内镜像源
#helm repo add stable https://burdenbear.github.io/kube-charts-mirror/
或
#helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
3、查看helm源情况
# helm repo list
4、搜索测试
# helm search mysql
解决方法2:
1、手动下载images
# docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.1
2、查看tiller需要的镜像名
# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-bccdc95cf-tb6pf 1/1 Running 3 5h21m
coredns-bccdc95cf-xpgm8 1/1 Running 3 5h21m
etcd-master 1/1 Running 3 5h20m
kube-apiserver-master 1/1 Running 3 5h21m
kube-controller-manager-master 1/1 Running 3 5h21m
kube-flannel-ds-amd64-b4ksb 1/1 Running 3 5h18m
kube-flannel-ds-amd64-vmv29 1/1 Running 0 127m
kube-proxy-67zn6 1/1 Running 2 37m
kube-proxy-992ns 1/1 Running 0 37m
kube-scheduler-master 1/1 Running 3 5h21m
tiller-deploy-7bf78cdbf7-fkx2z 0/1 ImagePullBackOff 0 33m
3、使用describe查看镜像名
# kubectl describe pods tiller-deploy-7bf78cdbf7-fkx2z -n kube-system
……….
Normal Scheduled 32m default-scheduler Successfully assigned kube-system/tiller-deploy-7bf78cdbf7-fkx2z to node1
Normal Pulling 30m (x4 over 32m) kubelet, node1 Pulling image “gcr.io/kubernetes-helm/tiller:v2.14.1”
Warning Failed 30m (x4 over 31m) kubelet, node1 Failed to pull image “gcr.io/kubernetes-helm/tiller:v2.14.1”: rpc error: code = Unknown desc = Error response from daemon: Get https://gcr.io/v2/: Service Unavailable
Warning Failed 30m (x4 over 31m) kubelet, node1 Error: ErrImagePull
Warning Failed 30m (x6 over 31m) kubelet, node1 Error: ImagePullBackOff
Normal BackOff 111s (x129 over 31m) kubelet, node1 Back-off pulling image “gcr.io/kubernetes-helm/tiller:v2.14.1”
4、使用docker tag 重命令镜像
# docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.1 gcr.io/kubernetes-helm/tiller:v2.14.1
5、删除多余的镜像
# docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.1
6、删除失败的pod
# kubectl delete deployment tiller-deploy -n kube-system
稍等一会儿就可以使用kubectl get pods -n kube-system查看状态已经正常了
注意由于某些原因需要网络可以访问gcr.io和kubernetes-charts.storage.googleapis.com,如果无法访问可以通过helm init –service-account tiller –tiller-image <your-docker-registry>/tiller:v2.13.1 –skip-refresh使用私有镜像仓库中的tiller镜像
为了便于将集群中的服务暴露到集群外部,需要使用Ingress。接下来使用Helm将Nginx Ingress部署到Kubernetes上。 Nginx Ingress Controller被部署在Kubernetes的边缘节点上,关于Kubernetes边缘节点的高可用相关的内容可以查看之前整理的Bare metal环境下Kubernetes Ingress边缘节点的高可用,Ingress Controller使用hostNetwork。
如果想删除一个node的label标记,使用以下命令
# kubectl label node node1 node-role.kubernetes.io/edge-
stable/nginx-ingress chart的值文件ingress-nginx.yaml如下:
nginx ingress controller的副本数replicaCount为1,将被调度到master这个边缘节点上。这里并没有指定nginx ingress controller service的externalIPs,而是通过hostNetwork: true设置nginx ingress controller使用宿主机网络。
如果发现nginx-ingress的容器状态是ContainersCreating/ImagePullBackOff,则需要手动下载镜像
# docker pull registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.25.0
# docker tag registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.25.0 quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0
# docker pull registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/defaultbackend-amd64:1.5
# docker tag registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/defaultbackend-amd64:1.5 k8s.gcr.io/defaultbackend-amd64:1.5
# docker rmi registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/defaultbackend-amd64:1.5
# docker rim registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.25.0
如果访问http://192.168.1.21返回default backend,则部署完成。
执行安装
注意:admin-token的pod名称
其中 admin-token-2tbzp 是 kubectl get secret -n kube-system 看到的admin-token名称
原文:https://www.cnblogs.com/yhq123/p/11300229.html