Kubernetes架构
Kubernetes是当今最流行的开源容器管理平台,来自Google Borg的开源版本,2014年推出。Kubernetes源于希腊语,意为舵手,K8S是一个简称,因为首尾字母中间正好有8个字母。
基于容器技术,Kubernetes可以方便的进行集群应用的部署、扩容、缩容、自愈机制、服务发现、负载均衡、日志、监控等功能,大大减少日常运维的工作量。
总体概览
从两个维度来看k8s。
Kubernets所有的操作都可以通过Kubernetes API来进行,通过API来操作Kubernetes中的对象,包括Pod、Service、Volume、Namespace等等。Kubernetes的整体结构如下图所示:
Master Node
Master 是 Cluster 的大脑,它的主要职责是调度,即决定将应用放在哪里运行。
Master节点上面主要由四个模块组成:APIServer、scheduler、controller manager、etcd。
APIServer 负责对外提供RESTful的Kubernetes API服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer处理后再提交给etcd。
scheduler 负责调度pod到合适的Node上。
controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。
etcd 保存了整个集群的状态。etcd是一个高可用的键/值存储系统,Kubernetes使用它来存储各个资源的状态,从而实现了Restful的API。
Worker Node
Worker Node 的职责是运行容器应用。
Node 可以是一个物理机也可以是虚拟机,每个节点上都运行了可以运行 Pods 的服务。通过Master节点来进行管理。
每个Node节点主要由三个模块组成:kubelet、kube-proxy、runtime。
runtime 容器运行环境,负责镜像管理以及Pod和容器的真正运行(CRI - Container Runtime Interface),Kubernetes支持docker(默认)和rkt等容器。
kube-proxy 该模块实现了Kubernetes中的服务发现和反向代理功能。
- 服务发现: 维护service到endpoint的映射关系
- 反向代理: 将客户端流量转发到与service对应的一组后端pod
kubelet Node节点上的agent, 负责维护容器的生命周期,同时也负责Volume(CVI - Container Volume Interface)和网络(CNI - Container Network Interface)的管理
Pod & Controllers
1. Pod
Pod 思维导图
Pod 是Kubernetes中可以创建和部署的最小单位。Pod包含了应用容器、存储资源、唯一的网络IP地址以及容器运行的参数。Pod内部的容器共享的网络、存储资源。Docker是Pod中最常用的容器运行环境,但仍允许用户使用其他的容器环境。
Pod使用有两种方式:
- 一个容器 container 一个Pod(常用)
- 一个Pod中运行多个容器 containers (这些容器联系必须 非常紧密,而且需要 直接共享资源。 web-db模式不行)
1.1 基本操作
创建kubectl create -f xxx.yaml
查询kubectl get pod yourPodName
kubectl describe pod yourPodName
删除kubectl delete pod yourPodName
更新kubectl replace /path/to/yourNewYaml.yaml
1.2 Pod与容器
在Docker中,容器是最小的处理单元,增删改查的对象是容器,容器是一种虚拟化技术,容器之间是隔离的,隔离是基于Linux Namespace实现的。而在Kubernetes中,Pod包含一个或者多个相关的容器,Pod可以认为是容器的一种延伸扩展,一个Pod也是一个隔离体,而Pod内部包含的一组容器又是共享的(包括PID、Network、IPC、UTS)。除此之外,Pod中的容器可以访问共同的数据卷来实现文件系统的共享。
1.3 镜像
在kubernetes中,镜像的下载策略为:
Always:每次都下载最新的镜像
Never:只使用本地镜像,从不下载
IfNotPresent:只有当本地没有的时候才下载镜像
Pod被分配到Node之后会根据镜像下载策略进行镜像下载,可以根据自身集群的特点来决定采用何种下载策略。无论何种策略,都要确保Node上有正确的镜像可用。
1.4 其他设置
通过yaml文件,可以在Pod中设置:
启动命令,如:spec-->containers-->command;
环境变量,如:spec-->containers-->env-->name/value;
端口桥接,如:spec-->containers-->ports-->containerPort/protocol/hostIP/hostPort(使用hostPort时需要注意端口冲突的问题,不过Kubernetes在调度Pod的时候会检查宿主机端口是否冲突,比如当两个Pod均要求绑定宿主机的80端口,Kubernetes将会将这两个Pod分别调度到不同的机器上);
Host网络,一些特殊场景下,容器必须要以host方式进行网络设置(如接收物理机网络才能够接收到的组播流),在Pod中也支持host网络的设置,如:spec-->hostNetwork=true;
数据持久化,如:spec-->containers-->volumeMounts-->mountPath;
重启策略,当Pod中的容器终止退出后,重启容器的策略。这里的所谓Pod的重启,实际上的做法是容器的重建,之前容器中的数据将会丢失,如果需要持久化数据,那么需要使用数据卷进行持久化设置。Pod支持三种重启策略:Always(默认策略,当容器终止退出后,总是重启容器)、OnFailure(当容器终止且异常退出时,重启)、Never(从不重启);
2. Controller
Kubernetes 通常不会直接创建 Pod,而是通过 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性,比如有几个副本,在什么样的 Node 上运行等。
为了满足不同的业务场景,Kubernetes 提供了多种 Controller,包括 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等。
2.1 Deployment
Deployment 是新一代用于 Pod 管理的对象,与 Replication Controller 相比,它提供了更加完善的功能,使用起来更加简单方便。(常用) . 实际运行方式:deployment -> ReplicaSet -> pod
2.2 StatefulSet
StatefulSet 有状态负载提供正确的控制器支持。(Mysql,Kafka等)
2.3 DaemonSet
DaemonSet 一个Node节点运行一个pod。(monitor, glustered, ceph, logstash, kube-proxy)
2.4 Job
工作类容器,一次性任务。通过Job运行一个容器,当其任务执行完以后,就自动退出,集群也不再重新将其唤醒。
2.5 CronJob
执行定时任务的控制器。
2.6 ReplicationController
k8s旧版,通过它实现了 Pod 的多副本管理(现在不建议用)
2.7 ReplicaSet
ReplicaSet 是新版 ReplicationController, 支持集合式的 selector。(很少直接使用)
ReplicaSet 实现了 Pod 的多副本管理。使用 Deployment 时会自动创建 ReplicaSet,也就是说 Deployment 是通过 ReplicaSet 来管理 Pod 的多个副本,我们通常不需要直接使用 ReplicaSet。
2.8 Garbage Collection
Kubernetes进行垃圾回收管理的控制器,Kubernetes的垃圾回收由kubelet进行管理,每分钟会查询清理一次容器,每五分钟查询清理一次镜像。在kubelet刚启动时并不会立即进行GC,即第一次进行容器回收为kubelet启动一分钟后,第一次进行镜像回收为kubelet启动五分钟后。(了解一下)
3. Service
Kubernetes Service 定义了外界访问一组特定 Pod 的方式。Service 有自己的 IP 和端口,Service 为 Pod 提供了负载均衡。
Kubernetes 运行容器(Pod)与访问容器(Pod)这两项任务分别由 Controller 和 Service 执行。
客户端只需要访问 Service 的 IP,Kubernetes 则负责建立和维护 Service 与 Pod 的映射关系。无论后端 Pod 如何变化,对客户端不会有任何影响,因为 Service 没有变。
3.1 服务的类型(type):
ClusterIP (默认)集群内部使用
NodePort 外部可以通过
<NodeIP>:<NodePort>
访问 Service。Loadbalancer 云平台提供(AWS, Azure)
Ingress 第三方插件。是一种HTTP方式的路由转发机制,由Ingress Controller和HTTP代理服务器组合而成。Ingress Controller实时监控Kubernetes API,实时更新HTTP代理服务器的转发规则。HTTP代理服务器有GCE Load-Balancer、HaProxy、Nginx等开源方案。
3.2 Service代理外部服务
Service不仅可以代理Pod,还可以代理任意其他后端,比如运行在Kubernetes外部Mysql、Oracle等。这是通过定义两个同名的service和endPoints来实现的。
3.3 Service内部负载均衡
当Service的Endpoints包含多个IP的时候,及服务代理存在多个后端,将进行请求的负载均衡。默认的负载均衡策略是轮训或者随机(有kube-proxy的模式决定)。同时,Service上通过设置Service-->spec-->sessionAffinity=ClientIP,来实现基于源IP地址的会话保持。
3.4 服务发现:
service可以将pod ip封装起来,即使pod发生重建,依然可以通过service来访问pod提供的服务,service还解决了负载均衡的问题. 运行在每个node上的kube-proxy进程其实就是一个智能的软件负载均衡器,它负责把service的请求转发到后端的某个pod实例。
kube-dns可以解决Service的发现问题:即把服务名解析为cluster IP。 k8s将Service的名称当做域名注册到kube-dns中,通过Service的名称就可以访问其提供的服务
3.5 servicede 自发性机制
Kubernetes中有一个很重要的服务自发现特性。一旦一个service被创建,该service的service IP和service port等信息都可以被注入到pod中供它们使用。Kubernetes主要支持两种service发现 机制:环境变量和DNS。
环境变量方式
Kubernetes创建Pod时会自动添加所有可用的service环境变量到该Pod中,如有需要.这些环境变量就被注入Pod内的容器里。需要注意的是,环境变量的注入只发送在Pod创建时,且不会被自动更新。这个特点暗含了service和访问该service的Pod的创建时间的先后顺序,即任何想要访问service的pod都需要在service已经存在后创建,否则与service相关的环境变量就无法注入该Pod的容器中,这样先创建的容器就无法发现后创建的service。
DNS方式
Kubernetes集群现在支持增加一个可选的组件——DNS服务器。这个DNS服务器使用Kubernetes的watchAPI,不间断的监测新的service的创建并为每个service新建一个DNS记录。如果DNS在整个集群范围内都可用,那么所有的Pod都能够自动解析service的域名。
3.6 service目前存在的不足
Kubernetes使用iptables和kube-proxy解析service的人口地址,在中小规模的集群中运行良好,但是当service的数量超过一定规模时,仍然有一些小问题。首当其冲的便是service环境变量泛滥,以及service与使用service的pod两者创建时间先后的制约关系。目前来看,很多使用者在使用Kubernetes时往往会开发一套自己的Router组件来替代service,以便更好地掌控和定制这部分功能。
4. Volumes
容器中的文件系统是临时的,一旦容器重新启动,所有运行时对文件的操作都会丢失。Kubernetes使用Volumes来解决这个问题。不同于Docker自身的Volume,Kubernetes提供了Volume的生命周期管理,另外还提供了多种存储形式的支持。在Pod的spec中指定volume的类型以及挂载的位置。
Kubernetes支持的volume的类型:awsElasticBlockStore、azureDisk、azureFile、cephfs、configMap、csi、downwardAPI、emptyDir、fc、local、nfs。
实际使用中,存储选择优先顺序:
- 云平台提供的存储。如:AWS EBS, Azure Disk, Azure File,OpenStack Cinder
- Block Device(SAN)。如:FC(Fibre Channel), RBD(Ceph Block Device), iSCSI, VsphereVolume
- File Storage。如:glusterfs, cephfs, nfs
- HostPath。 单机版用法
Add-ons
- kube-dns 负责为整个集群提供DNS服务
- Ingress Controller 为服务提供外网入口
- Heapster 提供资源监控
- Dashboard 提供GUI
- Federation 提供跨可用区的集群
- Fluentd-elasticsearch 提供集群日志采集、存储与查询