Kubernete导图
Kubernete简介
建于 Docker 之上的 Kubernetes 可以构建一个容器的调度服务,其目的是让用户透过Kubernetes集群来进行云端容器集群的管理,而无需用户进行复杂的设置工作。系统会自动选取合适的工作节点来执行具体的容器集群调度处理工作。
Kubernetes架构
etcd
Kubernetes默认使用etcd作为集群整体存储。etcd是一个简单的、分布式的、一致的key-value存储,主要被用来共享配置和服务发现。etcd提供了一个CRUD操作的REST API,以及提供了作为注册的接口,以监控指定的Node。集群的所有状态都存储在etcd实例中,并具有监控的能力,因此当etcd中的信息发生变化时,就能够快速的通知集群中相关的组件。
Master Node
API Server (资源操作入口)
提供了资源对象的唯一操作入口,其它所有组件都必须通过它提供的 API 来操作资源数据。只有 API Server 会与存储通信,其它模块都必须通过 API Server 访问集群状态。 API Server 作为 Kubernetes 系统的入口,封装了核心对象的增删改查操作。API Server 以 RESTFul 接口方式提供给外部客户和内部组件调用,API Server 再对相关的资源数据(全量查询 + 变化监听)进行操作,以达到实时完成相关的业务功能。
Controller Manager (内部管理控制中心)
Controller Manager 用于实现 Kubernetes 集群故障检测和恢复的自动化工作。Controller Manager 主要负责执行以下各种控制器:
Scheduler (集群分发调度器)
scheduler组件为容器自动选择运行的主机。依据请求资源的可用性,服务请求的质量等约束条件,scheduler监控未绑定的pod,并将其绑定至特定的node节点。Kubernetes也支持用户自己提供的调度器,Scheduler负责根据调度策略自动将Pod部署到合适Node中,调度策略分为预选策略和优选策略,Pod的整个调度过程分为两步:
预选Node:遍历集群中所有的Node,按照具体的预选策略筛选出符合要求的Node列表。如没有Node符合预选策略规则,该Pod就会被挂起,直到集群中出现符合要求的Node。
优选Node:预选Node列表的基础上,按照优选策略为待选的Node进行打分和排序,从中获取最优Node。
Worker node
Kubelet
Kubelet是Kubernetes中最主要的控制器,它是Pod和Node API的主要实现者,Kubelet负责驱动容器执行层。在Kubernetes中,应用容器彼此是隔离的,并且与运行其的主机也是隔离的,这是对应用进行独立解耦管理的关键点。
Kubelet 在 Node 上做的主要工作具体如下:
- 设置容器的环境变量、给容器绑定 Volume、给容器绑定 Port、根据指定的 Pod 运行一个单一容器、给指定的 Pod 创建 Network 容器。
- 同步 Pod 的状态,从 cAdvisor 获取 Container Info、 Pod Info、 Root Info、 Machine info。
- 在容器中运行命令、杀死容器、删除 Pod 的所有容器。
kube proxy
基于一种公共访问策略(例如:负载均衡),服务提供了一种访问一群pod(集群中容器提供的应用服务)的途径。此方式通过创建一个虚拟的IP来实现,客户端能够访问此IP,并能够将服务透明的代理至Pod。每一个Node都会运行一个kube-proxy,kube proxy通过iptables规则引导访问至服务IP,并将重定向至正确的后端应用,通过这种方式kube-proxy提供了一个高可用的负载均衡解决方案。
核心概念
Namespace&ResourceQuota
Namespace物理集群上的虚拟集群,用户级别的资源限制
Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services, replication controllers和deployments等都是属于某一个namespace的,而node, persistentVolumes等则不属于任何namespace。
资源配额(Resource Quotas)是用来限制用户资源用量的一种机制。资源配额应用在Namespace上,并且每个Namespace最多只能有一个ResourceQuota对象,开启计算资源配额后,创建容器时必须配置计算资源请求或限制。并且用户超额后禁止创建新的资源。
资源配额的类型包括:计算资源(cpu和memory),存储资源(存储资源的总量以及指定storage class的总量),对象数(可创建的对象的个数)。
Lable& Selector
Label以key/value键值对的形式附加到任何对象上,如Pod,Service,Node,RC(ReplicationController)/RS(ReplicaSet)等。Label可以在创建对象时就附加到对象上,也可以在对象创建后通过API进行额外添加或修改。
我们通常使用metadata.labels字段,来为对象添加Label。Label可以为多个。一般来说,我们会给一个Pod(或其他对象)定义多个Label,以便于配置,部署等管理工作。
带有Label的对象创建好之后,我们就可以通过Label Selector来引用这些对象。
Kubernetes目前支持两种类型的Label Selector:
基于等式的Selector(Equality-based)
基于集合的Selector(Set-based)[RC不支持]
Pod
一个pod相当于一个共享context的配置组,在同一个context下,应用可能还会有独立的cgroup隔离机制,一个Pod是一个容器环境下的“逻辑主机”,它可能包含一个或者多个紧密相连的应用,这些应用可能是在同一个物理主机或虚拟机上。同一个Pod中的应用可以共享磁盘,磁盘是Pod级的。
Pod 的context可以理解成多个linux命名空间的联合
PID 命名空间(同一个Pod中应用可以看到其它进程)
网络 命名空间(同一个Pod的中的应用对相同的IP地址和端口有权限)
IPC 命名空间(同一个Pod中的应用可以通过VPC或者POSIX进行通信)
UTS 命名空间(同一个Pod中的应用共享一个主机名称)
和相互独立的容器一样,Pod是一种相对短暂的存在,而不是持久存在的,正如我们在Pod的生命周期中提到的,Pod被安排到结点上,并且保持在这个节点上直到被终止(根据重启的设定)或者被删除,当一个节点死掉之后,上面的所有Pod均会被删除。
资源限制
Kubernetes通过cgroups限制容器的CPU和内存等计算资源,包括requests(请求,调度器保证调度到资源充足的Node上)和limits(上限)
环境变量
环境变量为容器提供了一些重要的资源,包括容器和Pod的基本信息以及集群中服务的信息等。如hostName,Pod的名字、命名空间、IP以及容器的计算资源限制等可以以Downward API的方式获取并存储到环境变量中。
Docker中程序的配置文件可以通过配置环境变量或者将配置文件挂载到宿主机上实现一个容器在不同的场景下使用不同的配置文件。Kubernetes中也已通过配置环境变量为Pod中容器传递参数。
Volume
为容器提供持久化存储
健康检查
为了确保容器在部署后确实处在正常运行状态,Kubernetes提供了两种探针(Probe,支持exec、tcp和httpGet方式)来探测容器的状态:
LivenessProbe:探测应用是否处于健康状态,如果不健康则删除重建改容器
ReadinessProbe:探测应用是否启动完成并且处于正常服务状态,如果不正常则更新容器的状态
ImagePullPolicy
Always:不管镜像是否存在都会进行一次拉取。
Never:不管镜像是否存在都不会进行拉取
IfNotPresent:只有镜像不存在时,才会进行镜像拉取。
Capabilities
默认情况下,容器都是以非特权容器的方式运行。比如,不能在容器中创建虚拟网卡、配置虚拟网络。Kubernetes提供了修改Capabilities的机制。
Node
Node是Pod真正运行的主机,可以物理机,也可以是虚拟机。为了管理Pod,每个Node节点上至少要运行container runtime(比如docker或者rkt)、kubelet和kube-proxy服务。
Service
k8s的Service定义了一个服务的访问入口地址(k8s分配给Service一个固定IP,这是一个虚拟IP),前端的应用通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,来自外部的访问请求被负载均衡到后端的各个容器应用上。Service与其后端Pod副本集群之间则是通过Label Selector来实现对接的。而RC的作用相当于是保证Service的服务能力和服务质量始终处于预期的标准。Service 定义可以基于 POST 方式,请求 apiserver 创建新的实例。一个 Service 在 Kubernetes 中是一个 REST 对象。
Replication Controller
Replication Controller 保证了在所有时间内,都有特定数量的Pod副本正在运行。一个RC通过模版来创建pod,这个是RC对象内置的功能,RC 创建的的Pod 是可以相互替代和语义上相同的。
ReplicaSet
ReplicaSet是下一代复本控制器。ReplicaSet和 Replication Controller之间的唯一区别是现在的选择器支持。Replication Controller只支持基于等式的selector(env=dev或environment!=qa),但ReplicaSet还支持新的,基于集合的selector(version in (v1.0, v2.0)或env notin (dev, qa))。
Deployment
Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新。你只需要在Deployment中描述你想要的目标状态是什么,Deployment controller就会帮你将Pod和Replica Set的实际状态改变到你的目标状态。你可以定义一个全新的Deployment,也可以创建一个新的替换旧的Deployment。
一个典型的用例如下:
使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
扩容Deployment以满足更高的负载。
暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
根据Deployment 的状态判断上线是否hang住了。
清除旧的不必要的ReplicaSet。
Volumes
Volumes:在Kubernetes中,当Pod重建的时候,数据是会丢失的,Kubernetes也是通过数据卷挂载来提供Pod数据的持久化的。Kubernetes数据卷是对Docker数据卷的扩展,是Pod级别的,可以用来实现Pod中容器的文件共享。
Kubernete 支持的volume类型:
本地数据卷: emptyDir, hostPath
网络数据卷: NFS、iSCISI、GlusterFS、RBD(Ceph Block Device)、Flocker、AWS Elastic Block Store、GCE Persistent Disk
Persistent Volume和Persistent Volume Claim**
信息数据卷: Secret, Downward API, Git Repo
StatefulSet
RC、Deployment、DaemonSet都是面向无状态的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所有有状态的服务,比如MySQL、MongoDB集群等。 StatefulSet本质上是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。 在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的headless service,headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。 除此之外,StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod副本创建了一个DNS域名,这个域名的格式为:
$(podname).(headless server name)
FQDN: $(podname).(headless server name).namespace.svc.cluster.loca