Kubernetes 高可用部署 | 运维进阶

【导读】目前Kubernetes官方以及开源社区都提供了非常多的优秀部署工具,大大简化了Kubernetes的部署难度。本文不限于掌握如何选择合适的工具部署一套高可用的Kubernetes平台,而是在部署实践中学习Kubernetes,对Kubernetes有个初步的宏观认识,了解Kubernetes的组件以及架构、高可用方案设计的原理,为后续集群的管理、运维以及问题诊断打下基。

【分享者】付广平,中国民生银行股份有限公司,技术管理中心容器工程师。负责云基础架构、运维以及云计算相关技术研究。毕业于北京邮电大学,从2013开始从事OpenStack相关工作,参与了OpenStack Nova、Cinder、Cloud Custodian等项目社区开发,微信公众号int32ibt以及知乎专栏《OpenStack》作者。对Ceph、Docker、Kubernetes等技术也有一定的了解。

1 Kubernetes简介

Kubernetes是Google开源的分布式容器集群管理平台,支持跨多主机编排容器化应用,同时为容器化的应用提供快速的部署运行、灵活的资源调度、自动服务发现和动态伸缩等一系列完整功能。

1.1 Kubernetes组件

其中Kubernetes组件架构如图:

Master组件

Master节点运行Kubernetes控制平面服务,主要包括组件如下:

etcd是Kubernetes最重要的存储系统,Kubernetes几乎所有的元数据都存储在etcd中,因此etcd的高可用对Kubernetes的集群整体高可用至关重要。api-server: 提供开放的API接口,用户的所有请求以及组件之间交互均需要通过api-server服务,并提供认证、授权、访问控制、API 注册和发现等机制。kube-scheduler: Kubernetes集群的pod调度器,用于将pod调度到合适的node上。kube-controller-manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等,后台运行着各种控制器,控制器会不断地监听api-server的事件,比如replication controller用于管理和维护pod的副本,当监听到pod数量与期望不一致时会增加或者减少pod数量。

Node组件

Node组件是所有的master节点和worker节点都需要运行的组件,主要包括如下:

kubelet:运行在所有的节点,负责维护容器的生命周期,接收一组通过各类机制提供给它的PodSpecs,确保这些 PodSpecs中描述的容器处于运行状态且健康。kube-proxy:也需要运行在所有的节点,维护节点上的iptables或者ipvs网络规则。这些网络规则允许从集群内部或外部的网络会话与Pod进行网络通信。Kubernetes Service以及NodePort就是由kube-proxy实现的。

其他插件

coredns: CoreDNS其实就是一个DNS服务,很多开源项目都使用了CoreDNS为集群提供服务发现的功能,目前Kubernetes也是在集群中推荐使用CoreDNS代替之前kube-dns解决服务发现问题。flannel:Flannel是CoreOS团队提供的一种容器网络解决方案,目前Kubernetes可使用flannel实现pod的跨主机通信。当然flannel不是唯一的网络解决方案,其他的还有如calico、weave等。metrics-server: 用于监控Kubernetes的Node以及Pod性能数据。

命令行工具

kubectl:Kubernetes的命令行工具,方便在shell命令行与Kubernetes API进行交互,通过kubectl可以对Kubernetes Resources进行CURD操作。helm:Kubernetes的包管理工具。krew:Kubernetes的插件管理工具。

1.2 Kubernetes Resources介绍

Pod

Pod是Kubernetes管理和调度的最小单元,每个Pod可以包含一个或多个紧密关联的容器,Pod的所有容器共享PID、IPC、Network和UTS namespace,Pod内的多个容器共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。

Node

Node是Pod真正运行的主机,可以是物理机,也可以是虚拟机。为了管理 Pod,每个Node节点上至少要运行container runtime(比如 docker 或者 rkt)、kubelet 和kube-proxy服务。

Deployment

Deployment是在Pod这个抽象上更为上层的一个抽象,它可以定义一组Pod的副本数目、以及这个Pod的版本,pod是组成Deployment最小的单元。

我们在部署应用时通常使用Deployment这个抽象来做应用的真正的管理,不是而直接创建Pod。

Kubernetes通过ReplicaSet控制器维护Deployment中Pod的数量和版本,同时会去帮助 Deployment自动恢复失败的Pod。通过Deployment控制器,我们能够实施各种发布策略,比如滚动升级或者进行版本的回滚。

Service

Service是应用服务的抽象,通过labels为应用提供四层负载均衡和服务发现。匹配labels 的Pod IP和端口列表组成endpoints,由kube-proxy负责将服务IP负载均衡到这些endpoints上。

每个Service都会自动分配一个 cluster IP(仅在集群内部可访问的虚拟地址)和 DNS 名,其他容器可以通过该地址或DNS来访问服务,而不需要了解后端容器的运行。

Namespace

Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的Pod、Service以及Deployment等都是属于某一个namespace的(默认是 default),而node,persistentVolumes等属于集群共享资源,不属于任何一个namespace。

2 Kubernetes常见部署工具介绍

2.1 Minikube

Minikube是由Kubernetes社区维护的单机版的Kubernetes集群快速部署工具,目前支持MacOS、Linux以及Windows等多种操作系统平台,非常适合在自己的笔记本上作为Kubernetes入门环境或作为开发测试环境使用,当然由于只支持单节点不支持高可用因此不能用于生产部署。

由于支持跨平台,但是我们知道MacOS以及Windows是不支持直接运行容器的,因此Minikube默认会启动一个Linux虚拟机,然后在虚拟机上通过kubeadm部署Kubernetes集群,关于kubeadm工具下面将会介绍。当然如果运行的OS本身就是Linux系统,则可以通过指定–vm-driver=none参数直接部署Kubernetes集群在操作系统上,不需要虚拟机,不过需要自己手动部署Docker。使用Minikube部署单节点Kubernetes非常简单,可以参考官方文档,这里不再介绍。

2.2 kind

kind是Kubernetes社区新维护的一个本地测试环境快速部署工具,除了用于本地测试,未来还可能用于做Kubernetes本身的CI集成测试。目前kind工具仍处于开发阶段,可以查看版本1.0的roadmap。

如kind的官方Logo所示,kind把Kubernetes的Node节点运行在Docker容器上,因此需要提前安装Docker。

2.3 kops

kops是生产级别的Kubernetes集群部署、升级和管理命令行工具,它主要用于在公有云平台上通过Terraform自动创建虚拟机作为节点并自动化部署Kubernetes集群,目前官方支持的公有云平台为AWS,GCE、DigitalOcean、OpenStack目前处于beta阶段。

国内fitcloud开源的KubeOperator也是一个类似的工具,通过Web UI在VMware、OpenStack和物理机上规划、部署和运营生产级别的Kubernetes集群。

2.4 kubespray

Kubespray使用Ansible部署生产级别的Kubernetes集群。对于已经了解Ansible的人们来说,该工具是一个不错的选择,因为无需使用其他工具进行预配和编排。

2.5 kubeadm

kubeadm是和Kubernetes一块发布的集群部署工具,与Kubernetes在同一个代码仓库中,因此可以说kubeadm是Kubernetes最亲的部署工具,目前使用最多的,同时也是社区最为推荐的Kubernetes部署工具。

该工具的目标是实现尽可能简单地部署符合最佳实践、满足基本安全合规要求的Kubernetes高可用集群,因此基本不需要太多的配置,就能快速的部署一套生产可用的Kubernetes集群。另外其实很多其他的部署工具也都是基于kubeadm实现的,前面提到的minikube、kind等工具都是基于kubeadm实现的。

2.6 部署工具对比

除了以上介绍的部署工具,还有很多其他的部署工具,这些工具中:

minikube和kind主要用于单机测试,一般不用于生产部署。kops主要用于在IaaS云平台上部署集群,如果在公有云上部署可以尝试使用这个工具。kubespray需要依赖Ansible自动化工具,如果熟悉Ansible可以尝试使用。kubeadm是Kubernetes项目自带的部署工具,社区最为推荐并且目前使用最多的工具,该工具基本不依赖外部工具,也基本不需要额外配置就可以快速搭建一个符合最佳实践的Kubernetes平台。

本文接下来也主要以kubeadm为例详细介绍Kubernetes的集群搭建部署。

3 Kubernetes高可用架构拓扑

拓扑直接引用官网的图:

这里对高可用拓扑做如下说明:

◎ 高可用集群必须包含奇数个Master节点(control plane node),通常为3个。

◎ etcd是Kubernetes最重要的存储系统,Kubernetes几乎所有的元数据都存储在etcd中,因此etcd的高可用对Kubernetes的集群整体高可用至关重要。在该部署图中,kubeadm会自动部署etcd集群,如果已有etcd集群,也可以使用外部的etcd集群。

◎ apiserver是一个无状态的API服务,因此可以通过传统的四层或者七层负载均衡做高可用,比如haproxy、ngix、F5等,如果部署在公有云,则可以直接使用公有云上托管的负载均衡服务。

4 基础环境准备

4.1 操作系统配置

(1)所有节点至少需要4核CPU、8GB内存以及500GB硬盘存储,硬盘主要用于存储Docker镜像以及容器临时存储,实际根据需求调整。

(2)操作系统:必须是Linux操作系统,Ubuntu、CentOS都可以,本文档以Ubuntu 18.04为例。

(3)保证所有的节点网络可通,如果使用host gateway模式,所有节点还必须保证在同一个子网内。如果有防火墙,至少开放如下端口:

master节点:

work节点:

(4)所有节点的hostname必须是唯一的。

查看hostname方法:

hostname

修改hostname:

hostname k8s-master-1

echo “k8s-master-1” >/etc/hostname

(5) 关闭swap功能。

echo “vm.swappiness = 0”>> /etc/sysctl.conf

swapoff -a && swapon -a

sysctl -p

(6)所有的product_uuid必须都不一样,如果是一台台部署的不会有问题,如果使用虚拟机模板克隆的,特别需要注意这种情况。

查看product_uuid的方法如下:

sudo cat /sys/class/dmi/id/product_uuid

务必检查所有节点的uuid不一样。

4.2 基础组件部署

4.2.1 安装Docker

在所有的节点安装Docker,不同的操作系统安装不一样,Ubuntu可通过如下命令安装Docker:

通过如下命令可验证Docker是否运行OK。

sudo docker run –rm hello-world

4.2.2 安装Kubernetes基础组件

注意需要在所有节点节点安装Kubernetes基础组件。

为了加快下载软件包,可以使用国内阿里源:

安装kubeadm、kubelet以及kubectl:

apt-get install -y kubelet kubeadm kubectl

配置自动补全:

echo “. /etc/bash_completion” >>~/.bashrc

echo “source <(kubectl completion bash)” >>~/.bashrc

4.2.3 负载均衡

前面提到apiserver是一个无状态的API服务,因此可以通过传统的四层或者七层负载均衡做高可用,比如haproxy、ngix、F5等,如果部署在公有云,则可以直接使用公有云上托管的负载均衡服务。

另外Kubernetes的证书是与域名关联的,因此需要提前定义好Kubernetes的访问域名。

这里以AWS为例,首先创建一个负载均衡实例:

监听地址TCP 6443,其中target group添加Kubernetes三个master节点,监听端口为6443。

当然也可以自己通过nginx或者haproxy部署负载均衡,这里不再赘述。

5 Kubernetes集群部署

5.1 控制平面master节点配置

安装第一个master节点

首先初始化第一个master节点:

◎ –control-plane-endpoint配置api-server的负载均衡地址,端口一般为6443。

◎ –pod-network-cidr指定Pod使用的网段,如果使用Flannel网络,必须配置这个字段。

◎ –image-repository这里是配置镜像仓库地址,这是由于国内访问国外的镜像非常慢,因此配置使用阿里云的镜像仓库。

如果运行没问题会输出如下信息:

Your Kubernetes control-plane has initialized successfully!

如上信息告诉我们如何配置kube-config配置文件、如何添加新的master节点以及添加worker节点。首先我们先配置kube config:

mkdir -p $HOME/.kube

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

sudo chown $(id -u):$(id -g) $HOME/.kube/config

接下来安装网络插件,这里我们以Flannel为例:

kubectl apply -f

https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml

运行如下命令是否安装就绪:

此时如果STATUS为Ready,则表明安装就绪。

安装其他master节点

安装其他master节点非常简单,只需要复制kubeadm输出在其他节点运行即可:

如上的–token 、–certificate-key等参数请根据kubeadm输出进行配置。

最后运行如下命令检查所有的master节点运行状况:

此时如果所有的master节点STATUS为Ready ,则说明Kubernetes控制平面配置完成。

5.2 worker节点配置

使用kubeadm安装worker节点也很简单,根据前面的输出执行如下命令:

执行kubectl get node查看运行状态:

可见我们的第一个worker节点int32bit-k8s-worker-1已经成功加到集群中。

按照相同的方法,可以继续添加更多的worker节点,这里不再赘述。

6 其他组件安装(可选项)

6.1 helm

Helm是Kubernetes的包管理器,类似我们操作系统的apt-get、yum、pip等工具。

安装helm也非常简单:

可以配置使用aliyun的源:

helm add repo apphub https://apphub.aliyuncs.com

6.2 metrics-server

metrics-server用于获取node和pod的性能监控数据,如果要使用Kubernetes的弹性伸缩HPA(Horizontal Pod Autoscaler)功能必须安装该组件。

首先下载源码到本地:

git clone https://github.com/kubernetes-sigs/metrics-server.git

修改metrics-server/deploy/kubernetes/metrics-server-deployment.yaml,镜像修改为

http://registry.cn-shanghai.aliyuncs.com/hanchenglei/metrics-server-amd64:v0.3.6

如果使用的是kubeadm部署使用的自签证书,args需增加–kubelet-insecure-tls参数。

由于我们的主机是静态配置的,无法做DNS解析,因此需要手动生成coredns配置文件做hosts静态解析:

输出

把如上输出拷贝到coredns configmap中:

验证能否解析主机:

如果能正常解析int32bit-k8s-master-1的IP则说明配置完成。

最后部署metrics-server:

kubectl apply -f metrics-server/deploy/kubernetes/

等待几分钟后查看node性能数据:

通过kubectl top pod可以查看pod的资源使用情况。

6.3 nginx ingress controller

ingress是用于实现服务的七层负载均衡,管理集群外部访问集群内部的http/https服务。

和其他Kubernetes内置组件不一样,ingress控制器是作为Kubernetes扩展组件,由第三方实现,目前ingress控制器支持AWS ALB、Contour(envoy)、F5、Haproxy、ISTIO、Kong、Nginx、Traefik等作为后端实现。

如果Kubernetes集群运行在云平台,则建议使用公有云托管的负载均衡。这里我们为了通用部署,仅使用nginx作为ingress controller。

安装nginx ingress controller命令如下:

检查安装版本:

6.4 krew

krew是一个Kubernetes的插件管理工具,它的功能就是提供简单的方法下载、检索、管理其他插件,类似操作系统brew等工具,其命名也似乎模仿的brew工具。

安装krew的官方脚本如下:

此时可以通过kubectl krew search查询所有插件列表,使用install子命令可以安装插件,比如安装ns插件:

kubectl krew install ns

此时可以通过kubectl ns进行快速切换namespace了。

原文来自:Kubernetes 高可用部署 | 运维进阶

    THE END
    喜欢就支持一下吧
    点赞8 分享
    评论 抢沙发
    头像
    欢迎您留下宝贵的见解!
    提交
    头像

    昵称

    取消
    昵称表情代码图片

      暂无评论内容