Kubernetes介绍
1. 介绍
1.1 什么是Kubernetes
Kubernetes是Google公司在2014年6月开源的一个容器集群管理系统,使用Go语言开发,也叫K8S。Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。Kubernetes一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着(比如用户想让apache一直运行,用户不需要关心怎么去做,Kubernetes会自动去监控,然后去重启,新建,总之,让apache一直提供服务),管理员可以加载一个微型服务,让规划器来找到合适的位置,同时,Kubernetes也系统提升工具以及人性化方面,让用户能够方便的部署自己的应用。
下文中Kubernetes以K8s简称表示
1.2 K8s主要功能
- 自动装箱
- 自我修复(自愈能力)
- 水平扩展
- 服务发现
- 滚动更新
- 版本回退
- 密钥和配置管理
- 存储编排
- 批处理
-
自动装箱
基于容器对应用运行环境的资源配置要求,自动部署应用容器
-
自我修复(自愈能力)
- 当容器失败时,会对容器进行重启
- 当所部署的Node节点有问题时,会对容器进行重新部署和重新调度
- 当容器未通过监控检查时,会关闭此容器直到容器正常运行时,才会对外提供服务
如果某个服务器上的应用不响应了,Kubernetes会自动在其它的地方创建一个
-
水平扩展
通过简单的命令、用户UI 界面或基于CPU 等资源使用情况,对应用容器进行规模扩大或规模剪裁
当我们有大量的请求来临时,我们可以增加副本数量,从而达到水平扩展的效果
-
服务发现
用户不需使用额外的服务发现机制,就能够基于Kubernetes 自身能力实现服务发现和负载均衡
对外提供统一的入口,让它来做节点的调度和负载均衡
-
滚动更新
可以根据应用的变化,对应用容器运行的应用,进行一次性或批量式更新
添加应用的时候,不是加进去就马上可以进行使用,而是需要判断这个添加进去的应用是否能够正常使用
-
版本回退
可以根据应用部署情况,对应用容器运行的应用,进行历史版本即时回退
类似于Git中的回滚
-
密钥和配置管理
在不需要重新构建镜像的情况下,可以部署和更新密钥和应用配置,类似热部署。
-
存储编排
自动实现存储系统挂载及应用,特别对有状态应用实现数据持久化非常重要
存储系统可以来自于本地目录、网络存储(NFS、Gluster、Ceph 等)、公共云存储服务
-
批处理
提供一次性任务,定时任务;满足批量数据处理和分析的场景
1.3 K8s架构
官方架构设计简要示意图
架构图
k8s生态圈
K8S架构主要包含两部分:Master(主控节点)和 Node(工作节点)
官网介绍https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/
k8s 集群控制节点,对集群进行调度管理,接受集群外用户去集群操作请求
-
Master node:主控节点(主要消耗cpu,生产环境2个+)
-
API Server:集群统一入口,以restful风格进行操作,同时交给etcd存储
-
提供认证、授权、访问控制、API注册和发现等机制
-
默认端口
6443
,可以通过--secure-port
的值来修改默认值 -
默认
IP
地址为非本地(Non-Localhost
)网络地址,通过启动参数--bind-address
设置该值 -
该端口用于接收客户端、dashboard等外部
HTTPS
请求 -
用于基于
Token
文件或客户端证书及HTTP Base
的认证 -
用于基于策略的授权RBAC
API版本:
- Alpha:预览版,不建议使用
- Beta:测试版,不建议生产使用
- v1:稳定版,建议使用
-
-
kube-scheduler:Kubernetes调度器是一个控制面进程,负责将Pods指派到节点上
- 通过调度算法为带调度Pod列表的每个Pod从可用Node列表中选择一个最合适的Node,并将信息写入etcd中
- node节点上的kubelet通过API server监听到kubernetes Scheduler产生的Pod绑定信息(事件绑定),然后获取对应的pod清单,下载image,并启动容器
- 调度策略:
- LeastRequestedPriority,优先从备选节点列表中选择资源消耗最小的节点(CPU+内存)
-
- 先排除不符合条件的节点
-
- 在剩余的可用节点中选出一个最符合条件的节点
-
- CalculateNodeLabelPriority,优先选择含有指定Label的节点
- BalancedResourceAllocation,优先从备选节点列表中选择各项资源使用率最均衡的节点
- LeastRequestedPriority,优先从备选节点列表中选择资源消耗最小的节点(CPU+内存)
-
controller-manager:处理集群中常规后台任务,一个资源对应一个控制器
- 包括一些子控制器(副本控制器、节点控制器、命名空间控制器和服务账号控制器等),控制器作为集群内部的管理控制中心,负责集群内的Node、pod副本、服务端点(endpoint)、命名空间(namespace)、服务账号(serviceAccount)、资源定额(ResourceQuota)的管理,当某个node意外宕机时,controller-manager会及时发现并执行自动化修复流程,确保集群中的pod副本始终处于预期的工作状态
- 控制器每间隔5秒检查一次节点的状态
- 如果controller-manager没有收到自节点的心跳,则将该node标记为不可达,controller-manager将在标记为无法访问之前等待40秒。
- 如果该node节点被标记为无法访问后5分钟还没有恢复,controller-manager会删除当前node的所有pod并在其他可用节点重新创建这些pod
-
-
etcd node:存储系统,用于保存集群中的相关数据,生产环境3个+
-
work Node:工作节点
-
Kubelet:master派到node节点代表,管理本机容器。是运行在每个worker节点的代理组件,它会监视已分配给节点的pod,具体功能如下:
- 向master汇报node节点的状态信息
- 接受指令并在pod中创建docker容器
- 准备pod所需的数据卷
- 返回pod的运行状态
- 在node节点执行容器健康检查
负责维护容器的生命周期,同时也负责Volume(CSI) 和 网络(CNI)的管理
-
kube-proxy:主要就是为 Service 提供服务的,来实现内部从 Pod 到 Service 和外部 NodePort 到 Service 的访问。k8s网络代理运行在node上,它反映了node上k8s API端进行循环TCP、UDP和SCTP转发,用户必须使用apiserver API创建一个服务来配置代理,其实就是kube-proxy通过在主机上维护网络规划执行连接转发来实现k8s服务访问。
- kube-proxy运行在每个节点上,监听api server中服务对象变化,再通过管理IPtables或者IPVS规则来实现网络转发
- kube-proxy不同版本支持的三种模式:
- UserSpace:k8s v1.1之前使用,1.2以后就已经淘汰
- iptables:k8s v1.1版本开始支持,1.2开始为默认(
iptables -t nat -vnL
) - IPVS:k8s 1.9引入,到1.11为正式版本,需要按照ipvsadm、ipset工具包和加载ip_vs内核模块(不建议修改)(
ipvsadm -Ln
),并未完全取代iptables,并存,仅替换了iptables中的service部分。
- 维护3个网络(overlay),网络叠加:
- pod网络
- node网络
- service网络
-
-
其他组件
- kubectl:是一个通过命令行对k8s集群进行管理的客户端工具,运行该工具会加载当前用户家目录的
/root/.kube/config
(以root为例)文件,获取相关配置信息,包括有户及其key。这里仅需要一个可以访问k8s node网络的客户端机器即可,而并非必须在master或node上安装 - etcd:是CoreOS公司开发,目前是k8s默认使用的key-value数据存储系统,用于保存k8s的所有集群数据,etcd支持分布式集群功能,生产环境使用时需要为etcd数据提供定期备份机制
数量推荐1,3,5,7等奇数,涉及到投票选举,但是大于3,可能出现写瓶颈
https://etcd.io/ - DNS:负责为整个集群提供DNS服务,从而实现服务之间的访问
- coredns(现在)
- kube-dns(1.18及以前)
- dashboard:基于网页的k8s用户界面,可以使用dashboard获取运行在集群中的应用的概览信息,也可以创建或修改k8s资源(如deployment,job,daemonset等等),也可以对deployment实现弹性伸缩,发起滚动升级、重启pod或者使用向导创建新的应用
- kubectl:是一个通过命令行对k8s集群进行管理的客户端工具,运行该工具会加载当前用户家目录的
-
Container Runtime:容器运行环境
- 容器运行环境是负责运行容器的软件
- Kubernetes支持多个容器运行环境:Docker、containerd、cri-o、rktlet以及任何实现Kubernetes CRI (容器运行环境接口) 的软件
-
fluentd:是一个守护进程,它有助于提升集群层面日志
Fluentd简介
基本配置要求:
master:
- 8C8G 60G 几百个POD
- 16C16G 100G 数千个POD
- 32C32G或物理机 上万个POD
etcd:
- 8C8G 60G(性能型SSD)
node:
- 16C16G 80G(系统盘) 300G视实际情况(数据盘性能性)
- 32C64G 80G 、300G(数据盘性能性)
- 48C128G 80G(数据盘性能性)
- 96C1T/8T(intel 企业级SSD)
1.4 K8S核心概念
- Pod
- Volume
- Controller
- Deployment
- Service
- Label
- Namespace
- API
- 其它组件
可以参考笔者另一篇文章 kubernetes详细介绍
Pod
- Pod是K8s中最小的单元
- 一组容器的集合
- 共享网络【一个Pod中的所有容器共享同一网络】
- 生命周期是短暂的(服务器重启后,就找不到了)
Volume
- 声明在Pod容器中可访问的文件目录
- 可以被挂载到Pod中一个或多个容器指定路径下
- 支持多种后端存储抽象【本地存储、分布式存储、云存储】
Controller
-
确保预期的pod副本数量【ReplicaSet】
-
无状态应用部署【Deployment】
- 无状态就是指,不需要依赖于网络或者ip
-
有状态应用部署【StatefulSet】
- 有状态需要特定的条件
-
确保所有的node运行同一个pod 【DaemonSet】
-
一次性任务和定时任务【Job和CronJob】
Deployment
- 定义一组Pod副本数目,版本等
- 通过控制器【Controller】维持Pod数目【自动回复失败的Pod】
- 通过控制器以指定的策略控制版本【滚动升级、回滚等】
Service
-
定义一组pod的访问规则
-
Pod的负载均衡,提供一个或多个Pod的稳定访问地址
-
支持多种方式【ClusterIP、NodePort、LoadBalancer】
可以用来组合pod,同时对外提供服务
Label
label:标签,用于对象资源查询,筛选
Namespace
命名空间,逻辑隔离
- 一个集群内部的逻辑隔离机制【鉴权、资源】
- 每个资源都属于一个namespace
- 同一个namespace所有资源不能重复
- 不同namespace可以资源名重复
API
我们通过Kubernetes的API来操作整个集群
同时我们可以通过 kubectl 、ui、curl 最终发送 http + json/yaml 方式的请求给API Server,然后控制整个K8S集群,K8S中所有的资源对象都可以采用 yaml 或 json 格式的文件定义或描述
其它组件:
- CoreDNS:主要就是用来给 K8s 的 Service 提供一个域名和 IP 的对应解析关系。
- Dashboard:主要就是用来给 K8s 提供一个 B/S 结构的访问体系(即,我们可以通过 Web 界面来对 K8s 进行管理)
- Ingress Controller:主要就是用来实现 HTTP 代理(七层),官方的 Service 仅支持 TCP\UDP 代理(四层),据了解主要是用来负载均衡的。了解负载均衡,可以参考LB
- Prometheus:主要就是用来给 K8s 提供一个监控能力,使我们能够更加清晰的看到 K8s 相关组件及 Pod 的使用情况。
- ELK:主要就是用来给 K8s 提供一个日志分析平台。
1.5 完整流程
- 通过Kubectl提交一个创建RC(Replication Controller)的请求,该请求通过APlserver写入etcd
- 此时Controller Manager通过API Server的监听资源变化的接口监听到此RC事件
- 分析之后,发现当前集群中还没有它所对应的Pod实例
- 于是根据RC里的Pod模板定义一个生成Pod对象,通过APIServer写入etcd
- 此事件被Scheduler发现,它立即执行执行一个复杂的调度流程,为这个新的Pod选定一个落户的Node,然后通过API Server讲这一结果写入etcd中
- 目标Node上运行的Kubelet进程通过APiserver监测到这个"新生的Pod".并按照它的定义,启动该Pod并任劳任怨地负责它的下半生,直到Pod的生命结束
- 随后,我们通过Kubectl提交一个新的映射到该Pod的Service的创建请求
- ControllerManager通过Label标签查询到关联的Pod实例,然后生成Service的Endpoints信息,并通过APIServer写入到etcd中,
上运行的Kubelet进程通过APiserver监测到这个"新生的Pod.并按照它的定义,启动该Pod并任劳任怨地负责它的下半生,直到Pod的生命结束 - 随后,我们通过Kubectl提交一个新的映射到该Pod的Service的创建请求
- ControllerManager通过Label标签查询到关联的Pod实例,然后生成Service的Endpoints信息,并通过APIServer写入到etod中,
- 接下来,所有Node上运行的Proxy进程通过APIServer查询并监听Service对象与其对应的Endponts信息,建立一个软件方式的负载均衡器来实现Service访问到后端Pod的流量转发功能
2. K8S安装方式选择
2.1 kubeadm
kubeadm官方推荐方案,也在大力发展。小问题比较多,扩展还是需要配合其它方案一起做。高可用上面还是需要自己花一些精力 如果只是玩玩,还是非常推荐的,但是想要正式环境使用,我还是推荐大家三思。
由于kubeadm更像是一套完整的脚本封装,所以想要扩展它,还是需要配合其它的方案一起做。升级之类的,可以参考官方的升级指南,还是比较容易的。
目前支持的操作系统主要有:Ubuntu 16.04+ /Debian 9/ CentOS 7 / RHEL 7 / Fedora/HypriotOS/Container Linux 对于云平台的支持一般,还是推荐大家在安装完毕后,手动扩展吧。
2.2 手动部署(二进制)
手动部署完全看喜好,推荐大家都尝试一遍,成功与不成功不要紧,最主要的是了解一下Kubernetes的组件。会为你调试其它方案有很好的帮助。理论上,如果对Kubernetes足够了解,完全可以把他创建成与kops 或者 kubespray 一样的方案。
使用二进制方式安装 Kubernetes
https://github.com/easzlab/kubeasz 开源项目
2.3 Rancher
如果说kuernetes类似于IaaS+,那么Rancher就是标准的PaaS,如果你愿意按照Rancher的项目结构思路走,如果你团队不大,我还是比较推荐的。
Rancher 使用介绍
2.4 kubespray
kubespray最推荐的方案有kops的集成度(还差一些,但是该有的都有了),升级方便。只要对它不爽,随时可以fork一份,按照自己意愿进行修改。
kubespray是一个基于Ansible的部署方案,所以部署过程大家都能看得懂(如果你看不懂,请问你们公司还需要人吗?我这个小研发最近打算转运维)
操作系统支持绝大部分基于systemd的系统,什么Container Linux/Debian/Ubuntu/CentOS/RHEL/Fedora/CentOS Atomic/openSUSE 支持绝大部分的云平台(阿里云,腾讯云什么的,目前还不支持。),也支持OpenStack,vSphere等虚拟化方案。所以自建机房什么的也完全不用担心啦。
kubespray也为我们准备好了高可用方案,支持绝大部分网络插件,DNS也支持很多类型,你可以根据自己的需要选择。
文档上,目前也很完整。国内如果想要部署,仅仅需要写一下部署配置,声明一些镜像地址(替换从国外拉镜像的尴尬)。就可以愉快的一键执行了。