Kubernetes集群搭建、操作技巧和常见问题

Kubernetes集群搭建、操作技巧和常见问题

1. 集群的搭建

Kubernetes的集群是由若干个管理(master)节点和若干个工作(worker)节点组成的主机集群。这个主机集群可以通过kubectl运行docker中的镜像作为deployment,并自动地管理这些deployments,使它们能快速的部署pod到集群的每台主机中。这些pod和Docker的容器一样,是服务的最小单位,即使很多个pod运行在同一个节点上,也不会互相冲突。综上所述,Kubernetes融合了虚拟化和自动管理,是多主机面对高并发的一种很好的解决方案。

Kubernetes集群搭建的过程中,master节点是“群管理员”一样的角色,负责“建群”和发出“入群邀请”(即初始化并产生token),worker节点是“群员”一样的角色,负责“加群”并携带“入群验证信息”(即执行带有token的命令)。而一旦集群搭建完成,master节点就几乎不再运行实例了,新的deployment,会自动均匀地将pod部署在集群内的worker节点上,master节点无需运行服务但可以查看服务运行状况,worker节点运行服务但无需关心服务运行状况。

Kubernetes集群的搭建分为以下几个步骤(以使用kubeadm的1.15.1版本为例):

安装和启动Docker。Kubernetes创建deployment需要运行Docker的镜像,因此Docker是必不可少的。在所有master节点和worker节点都执行如下操作:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # 安装必要组件sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo  # 配置源sudo yum install -y docker-ce-18.09.7 docker-ce-cli-18.09.7 containerd.io # 安装Dockersudo systemctl enable docker # 注册服务sudo systemctl start docker # 启动服务

配置系统,关闭防火墙、selinux、swap。

配置Kubernetes的yum源(可选)。

安装kubelet、kubeadm、kubectl。在所有master节点和worker节点都执行如下操作:

yum install -y kubelet-1.15.1 kubeadm-1.15.1 kubectl-1.15.1

创建yaml文件初始化master节点。在所有master节点执行如下操作:

cat <<EOF > ./kubeadm-config.yaml # 创建kubeadm所需要的yaml文件apiVersion: kubeadm.k8s.io/v1beta1kind: ClusterConfigurationkubernetesVersion: v1.15.1imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containerscontrolPlaneEndpoint: "apiserver.demo:6443"networking:  podSubnet: "10.100.0.1/20"EOFkubeadm init --config=kubeadm-config.yaml --upload-certs # 初始化kubeadm

等待kubeadm初始化完成。

Kubectl初始化。在所有master节点执行如下操作,初始化结束后,通过kubectl version或kubectl get nodes命令就可以检查初始化结果,如果kubectl的server正确显示版本为1.15.1,或者master节点能找到本机节点,初始化就是成功的:

rm -rf /root/.kube/mkdir /root/.kube/cp -i /etc/kubernetes/admin.conf /root/.kube/config

节点互相连接。这时候kubectl已经正常运行了,是时候“建群”和“加群”了。在master节点上运行产生token的命令,在worker节点上运行这些带有token的命令就可以加入master节点所在的集群:

kubeadm token create --print-join-command # master节点生成加入集群的命令kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303 # worker节点执行加入集群的命令

验证集群搭建结果。如果执行kubectl get nodes命令能找到所有节点,表明集群搭建阶段结束。

以上的配置方式只是大概描述了集群的搭建过程,详细配置过程可以参考中文社区的文档。从配置过程来说,master和worker各自经历了如下的过程。

Master:安装docker -> 安装kubelet等组件 -> 初始化kubeadm -> 产生token等待节点加入集群

Worker:安装docker -> 安装kubelet等组件 -> 运行带有token的命令加入节点

PS:kubernetes1.16版本采用了更简化的集群部署方式,kubeadm的config文件可以不需要手动配置。

2. 操作技巧

2.1 简化组件的配置

Helm是Kubernetes的包管理器,它就像是centos的yum,debian的apt-get,python的pip一样,它可以快捷的为Kubernetes安装各种组件,大幅度降低了组件的配置难度。

Helm的安装分为配置命令行工具和安装tiller两个步骤。命令行工具的安装推荐使用wget获取离线包的方式安装,因为速度快一些。Tiller的角色是helm的服务端,负责分配节点部署helm安装的组件服务。

Helm可以为你的kubernetes集群安装Nginx Ingress、Dashboard、Metrics Server等组件。

2.2 简化yaml文件的创建

Kubernetes启动deployment的方式有两种。

一种是运行kubectl run命令,可以附加多种参数,实现一条语句运行docker镜像生成deployment。这种方法的优点是操作简洁,缺点是一条语句能够附加的参数有限,一旦有错误,整条语句都不能执行,而且语句很难保存下来。

另一种方式是运行kubectl create/apply命令,create命令会从指定的yaml文件中读取数据作为参数,并运行yaml文件中指定的镜像作为deployment,apply命令可以用来使修改过的yaml配置生效。这个方法的优点很明显,yaml文件可以非常详细的指明deployment的配置方式,甚至是pod的部署策略;yaml文件有一套相对宽松的标准,不容易出现语法错误;另外,yaml存储为文件,可读性高,可以随时修改。但缺点也很明显,yaml文件如果需要手动配置,就会非常麻烦,部署速度也会很慢。

Kubernetes提供了一种方法结合两种方法的有点,那就是dry-run。Dry-run类似于编码的debug操作,并不实际创建部署,但起到测试命令是否有效的作用。使用kubectl run xxx –dry-run -o yaml这一套完整的命令甚至可以将run命令附带的参数以yaml文本的方式输出在屏幕上,剪贴这些文本就可以快速创建一个可定制的yaml配置文件。

Kubernetes集群搭建、操作技巧和常见问题

3. 常见问题

3.1 镜像源问题

配置kubernetes集群及组件最容易出现的问题之一就是,当服务运行不正常时,去找kube-system命名空间的pods,发现各种pod出现ErrorImagePull。这是一个外部问题,或者说网络问题,因为kubernetes大部分组件都需要从镜像源k8s.gcr.io获取,而这个镜像源在国内是走不通的。想要解决这个问题,一般有两种方法:

修改公共镜像源。阿里巴巴和google都有能够从国内访问到的镜像源,可以修改这些服务的yaml文件中“image”参数的配置,使它们指向可以获取镜像的网络地址,重启服务或重新部署就可以回归正常了。

使用本地或私有镜像源。这种方法更加简单粗暴,就是干脆放弃去远程服务器中获取镜像,而是自己先手动从远程拉取,再保存到本地或上传到私有仓库。手动远程拉取也可以更换镜像源,更换之后,拉取到的镜像名字一定是不一样的(官方版本除外),使用docker tag命令创建一份名字和yaml的image字段一模一样的镜像,再将yaml文件中的image-pull-policy(镜像拉取策略)字段的值改为“IfNotPresent”即可。

3.2 loopback问题

运行一些镜像(例如centos),可能会发现服务的创建过程很快、很顺利,但是pod就是无法启动,显示CrashLoopBackOff,这可能是pod缺少一个前台进程导致的。一般情况下,一些自带有端口进程的服务(如apache、nginx等)对应的镜像不会触发这个问题,因为它们从创建起就开始有服务在运行了。同理,在docker中启动一些容器也容易出现这样的问题。

想要解决这个问题其实也不难,只要启动pod或容器时运行一条命令就可以。只要这条命令没有执行结束,pod或容器就不会挂掉。可以在run语句中加入一个附加项“-it xxx”指定你要执行的命令,top、ping等命令均可以持续挂起。当然,最简单的方法还是类似于“-it /bin/bash”之类的命令,它可以在启动pod或容器时以交互模式进入pod或容器,也可以指定一个能保持某些服务以守护态运行的脚本,令其在容器创建时直接开始执行,既能配置服务的开机运行,又避免了pod或容器启动后直接挂掉。

Kubernetes集群搭建、操作技巧和常见问题

3.3 系统组件失效问题

对于系统组件无法正常工作,可以通过查看命名空间为kube-system的pod(或deploy)的状况来定位问题。

Kubernetes支持用很快捷的命令查看pod或其他类型资源的运行状况,使用kubectl describe命令可以查看任何资源的详细信息:

Kubernetes集群搭建、操作技巧和常见问题

如果想查看组件的历史运行记录,则可以用kubectl logs命令:

Kubernetes集群搭建、操作技巧和常见问题

Kubernetes甚至支持在运行态,改变组件的配置信息,使用kubectl edit命令即可进入类似于vim的编辑界面,编辑后重启组件即可:

Kubernetes集群搭建、操作技巧和常见问题