汇集 k8s 核心概念,帮助理解
复制控制器( `Replication Controlle
r,RC` )
RC
是 K8s
集群中保证 Pod
高可用的 API对象
。通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。
指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。即使在指定数目为1的情况下,通过RC运行Pod也比直接运行Pod更明智,因为RC也可以发挥它高可用的能力,保证永远有1个Pod在运行。RC是K8s较早期的技术概念,只适用于长期伺服型的业务类型,比如控制小机器人提供高可用的Web服务。
副本集( Replica Set,RS
)
RS
是新一代 RC
,提供同样的高可用能力,区别主要在于 RS
后来居上,能支持更多种类的匹配模式。副本集对象一般不单独使用,而是作为 Deployment
的理想状态参数使用。
部署( Deployment
)
部署表示用户对 K8s
集群的一次更新操作。部署是一个比 RS
应用模式更广的 API对象
,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。
滚动升级一个服务,实际是创建一个新的 RS
,然后逐渐将新 RS
中副本数增加到理想状态,将旧 RS
中的副本数减小到 0
的复合操作;这样一个复合操作用一个 RS
是不太好描述的,所以用一个更通用的 Deployment
来描述。
服务( Service
)
RC
、 RS
和 Deployment
只是保证了支撑服务的微服务 Pod
的数量,但是没有解决如何访问这些服务的问题。
一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。
要稳定地提供服务需要服务发现和负载均衡能力。服务发现完成的工作,是针对客户端访问的服务,找到对应的的后端服务实例。
在K8s集群中,客户端需要访问的服务就是 Service
对象。每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。在K8s集群中微服务的负载均衡是由 Kube-proxy
实现的。 Kube-proxy
是 K8s
集群内部的负载均衡器。它是一个分布式代理服务器,在K8s的每个节点上都有一个;这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的 Kube-proxy
就越多,高可用节点也随之增多。
与之相比,我们平时在服务器端做个反向代理做负载均衡,还要进一步解决反向代理的负载均衡和高可用问题。
任务( Job
)
Job
是 K8s
用来控制批处理型任务的API对象。
批处理业务与长期伺服业务的主要区别是批处理业务的运行有头有尾,而长期伺服业务在用户不停止的情况下永远运行。
Job
管理的 Pod
根据用户的设置把任务成功完成就自动退出了。
成功完成的标志根据不同的 spec.completions
策略而不同:
- 单Pod型任务有一个Pod成功就标志完成;
- 定数成功型任务保证有N个任务全部成功;
- 工作队列型任务根据应用确认的全局成功而标志成功。
后台支撑服务集( DaemonSet
)
长期伺服型和批处理型服务的核心在业务应用,可能有些节点运行多个同类业务的Pod,有些节点上又没有这类 Pod
运行;而后台支撑型服务的核心关注点在 K8s
集群中的节点(物理机或虚拟机),要保证每个节点上都有一个此类Pod运行。节点可能是所有集群节点也可能是通过 nodeSelector
选定的一些特定节点。
典型的后台支撑型服务包括存储,日志和监控等在每个节点上支持K8s集群运行的服务。
有状态服务集( PetSet
)
RC
和 RS
主要是控制提供无状态服务的,其所控制的Pod的名字是随机设置的,一个Pod出故障了就被丢弃掉,在另一个地方重启一个新的 Pod
,名字变了、名字和启动在哪儿都不重要,重要的只是 Pod
总数;而 PetSet
是用来控制有状态服务, PetSet
中的每个 Pod
的名字都是事先确定的,不能更改。 PetSet
中 Pod
的名字的作用,是关联与该 Pod
对应的状态。
对于 RC
和 RS
中的 Pod
,一般不挂载存储或者挂载共享存储,保存的是所有 Pod
共享的状态, Pod
像流水线产品一样没有分别(这似乎也确实意味着失去了人性特征);对于 PetSet
中的 Pod
,每个 Pod
挂载自己独立的存储,如果一个 Pod
出现故障,从其他节点启动一个同样名字的 Pod
,要挂载上原来 Pod
的存储继续以它的状态提供服务。
适合于 PetSet
的业务包括数据库服务 MySQL
和 PostgreSQL
,集群化管理服务 Zookeeper
、 etcd
等有状态服务。 PetSet
的另一种典型应用场景是作为一种比普通容器更稳定可靠的模拟虚拟机的机制。
传统的虚拟机正是一种有状态的宠物,运维人员需要不断地维护它,容器刚开始流行时,我们用容器来模拟虚拟机使用,所有状态都保存在容器里,而这已被证明是非常不安全、不可靠的。使用 PetSet
, Pod
仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性, PetSet
做的只是将确定的 Pod
与确定的存储关联起来保证状态的连续性。 PetSet
还只在Alpha阶段,后面的设计如何演变,我们还要继续观察。
集群联邦( Federation
)
K8s在1.3版本里发布了beta版的Federation功能。
在云计算环境中,服务的作用距离范围从近到远一般可以有:同主机( Host
, Node
)、跨主机同可用区( Available Zone
)、跨可用区同地区( Region
)、跨地区同服务商( Cloud Service Provider
)、跨云平台。
K8s的设计定位是单一集群在同一个地域内,因为同一个地区的网络性能才能满足K8s的调度和计算存储连接要求。而联合集群服务就是为提供跨Region跨服务商K8s集群服务而设计的。
每个 K8s Federation
有自己的分布式存储、 API Server
和 Controller Manager
。用户可以通过 Federation
的 API Server
注册该 Federation
的成员 K8s Cluster
。当用户通过 Federation
的 API Server
创建、更改 API
对象时, Federation API Server
会在自己所有注册的子 K8s Cluster
都创建一份对应的 API
对象。在提供业务请求服务时, K8s Federation
会先在自己的各个 子Cluster
之间做负载均衡,而对于发送到某个具体 K8s Cluster
的业务请求,会依照这个 K8s Cluster
独立提供服务时一样的调度模式去做 K8s Cluster
内部的负载均衡。而 Cluster
之间的负载均衡是通过域名服务的负载均衡来实现的。
所有的设计都尽量不影响K8s Cluster现有的工作机制,这样对于每个子K8s集群来说,并不需要更外层的有一个K8s Federation,也就是意味着所有现有的K8s代码和机制不需要因为Federation功能有任何变化。
存储卷( Volume
)
K8s
集群中的存储卷跟 Docker
的存储卷有些类似,只不过 Docker
的存储卷作用范围为一个容器,而 K8s
的存储卷的生命周期和作用范围是一个 Pod
。
每个 Pod
中声明的存储卷由 Pod
中的所有容器共享。 K8s
支持非常多的存储卷类型,特别的,支持多种公有云平台的存储,包括AWS,Google和Azure云;支持多种分布式存储包括 GlusterFS
和 Ceph
;也支持较容易使用的主机本地目录 hostPath
和 NFS
。 K8s
还支持使用 Persistent Volume Claim
即 PVC
这种逻辑存储,使用这种存储,使得存储的使用者可以忽略后台的实际存储技术(例如AWS,Google或GlusterFS和Ceph),而将有关存储实际技术的配置交给存储管理员通过 Persistent Volume
来配置。
持久存储卷( Persistent Volume,PV
)和持久存储卷声明( Persistent Volume Claim,PVC
)
PV
和 PVC
使得 K8s
集群具备了存储的逻辑抽象能力,使得在配置Pod的逻辑里可以忽略对实际后台存储技术的配置,而把这项配置的工作交给PV的配置者,即集群的管理者。
存储的 PV
和 PVC
的这种关系,跟计算的 Node
和 Pod
的关系是非常类似的:
PV
和Node
是资源的提供者,根据集群的基础设施变化而变化,由K8s
集群管理员配置;PVC
和Pod
是资源的使用者,根据业务服务的需求变化而变化,由K8s
集群的使用者即服务的管理员来配置。
节点( Node
)
K8s
集群中的计算能力由 Node
提供,最初 Node
称为服务节点 Minion
,后来改名为 Node
。
K8s
集群中的 Node
也就等同于 Mesos
集群中的 Slave
节点,是所有 Pod
运行所在的工作主机,可以是物理机也可以是虚拟机。
不论是物理机还是虚拟机,工作主机的统一特征是上面要运行 kubelet
管理节点上运行的容器。
密钥对象( Secret
)
Secret
是用来保存和传递密码、密钥、认证凭证这些敏感信息的对象。使用 Secret
的好处是可以避免把敏感信息明文写在配置文件里。在 K8s
集群中配置和使用服务不可避免的要用到各种敏感信息实现登录、认证等功能,例如访问AWS存储的用户名密码。
为了避免将类似的敏感信息明文写在所有需要使用的配置文件中,可以将这些信息存入一个 Secret
对象,而在配置文件中通过 Secret
对象引用这些敏感信息。这种方式的好处包括:意图明确,避免重复,减少暴漏机会。
用户帐户( User Account
)和服务帐户( Service Account
)
顾名思义, 用户帐户为人提供账户标识 ,而服务账户为计算机进程和 K8s
集群中运行的 Pod
提供账户标识。
用户帐户和服务帐户的一个区别是作用范围;用户帐户对应的是人的身份,人的身份与服务的namespace
无关,所以:
- 用户账户是跨namespace的
- 服务帐户对应的是一个运行中程序的身份,与特定namespace是相关的。
名字空间(Namespace)
名字空间为 K8s
集群提供虚拟的隔离作用, K8s
集群初始有两个名字空间,分别是 默认名字空间 default
和 系统名字空间 kube-system
,除此以外,管理员可以可以创建新的名字空间满足需要。
访问授权(Role-based Access Control,RBAC
)
K8s在1.3版本中发布了alpha版的基于角色的访问控制( Role-based Access Control,RBAC
)的授权模式。相对于基于属性的访问控制( Attribute-based Access Control,ABAC
),RBAC主要是引入了角色( Role
)和角色绑定( RoleBinding
)的抽象概念。
在 ABAC
中, K8s
集群中的访问策略只能跟用户直接关联;
而在 RBAC
中,访问策略可以跟某个角色关联,具体的用户在跟一个或多个角色相关联。
显然, RBAC
像其他新功能一样,每次引入新功能,都会引入新的 API
对象,从而引入新的概念抽象,而这一新的概念抽象一定会使集群服务管理和使用更容易扩展和重用。