Kubernetes之(二)核⼼技术概念和API对象
Kubernetes之(二)核⼼技术概念和API对象
API对象是Kubernetes集群中的管理操作单元。 Kubernetes集群系统每⽀持⼀项新功能, 引⼊⼀项新技术, ⼀定会新引⼊对应的API对象, ⽀持对该功能的管理操作。 例如副本集Replica Set对应的API对象是RS。
每个API对象都有3⼤类属性: 元数据metadata、 规范spec和状态status。 元数据是⽤来标识API对象的, 每个对象都⾄少有3个元数据: namespace, name和uid; 除此以外还有各种各样的标签labels⽤来标识和匹配不同的对象, 例如⽤户可以⽤标签env来标识区分不同的服务部署环境, 分别⽤env=dev、 env=testing、 env=production来标识开发、 测试、⽣产的不同服务。 规范描述了⽤户期望Kubernetes集群中的分布式系统达到的理想状态(Desired State) , 例如⽤户可以通过复制控制器Replication Controller设置期望的Pod副本数为3; status描述了系统实际当前达到的状态(Status) , 例如系统当前实际的Pod副本数为2; 那么复制控制器当前的程序逻辑就是⾃动启动新的Pod, 争取达到副本数为3。
Kubernetes中所有的配置都是通过API对象的spec去设置的, 也就是⽤户通过配置系统的理想状态来改变系统, 这是Kubernetes重要设计理念之⼀, 即所有的操作都是声明式(Declarative) 的⽽不是命令式(Imperative) 的。 声明式操作在分布式系统中的好处稳定, 不怕丢操作或运⾏多次, 例如设置副本数为3的操作运⾏多次也还是⼀个结果, ⽽给副本数加1的操作就不是声明式的, 运⾏多次结果就错了。
Pod
Kubernetes有很多技术概念, 同时对应很多API对象, 最重要的也是最基础的是Pod。 Pod是在Kubernetes集群中运⾏部署应⽤或服务的最⼩单元, 它是可以⽀持多容器的。 Pod的设计理念是⽀持多个容器在⼀个Pod中共享⽹络地址和⽂件系统, 可以通过进程间通信和⽂件共享这种简单⾼效的⽅式组合完成服务。 Pod对多容器的⽀持是K8最基础的设计理念, ⽐如你运⾏⼀个操作系统发⾏版的软件仓库, ⼀个Nginx容器⽤来发布软件, 另⼀个容器专⻔⽤来从源仓库做同步, 这两个容器的镜像不太可能是⼀个团队开发的, 但是他们⼀块⼉⼯作才能提供⼀个微服务; 这种情况下, 不同的团队各⾃开发构建⾃⼰的容器镜像, 在部署的时候组合成⼀个微服务对外提供服务。
Pod是Kubernetes集群中所有业务类型的基础, 可以看作运⾏在K8集群中的⼩机器⼈, 不同类型的业务就需要不同类型的⼩机器⼈去执⾏。 ⽬前Kubernetes中的业务主要可以分为⻓期伺服型(long-running) 、 批处理型(batch) 、 节点后台⽀撑型(node-daemon) 和有状态应⽤型(stateful application) ; 分别对应的⼩机器⼈控制器为Deployment、
Job、 DaemonSet和StatefulSet.
副本控制器(Replication Controller,RC)
RC是Kubernetes集群中最早的保证Pod高可用的API对象,通过监控运行中的Pod来保证集群中运行指定数量的Pod副本。指定的数目可以是1或多个,少于指定数目,RC会启动运行新的Pod副本,多余则会杀死多余的Pod副本,即使在数目为1的情况下实用RC运行Pod也要比直接运行Pod更明智,因为RC可以保证永远有1个Pod在运行,RC适用于场次伺服型的业务类型。
副本集(Replica Set,RS)
RS是新⼀代RC, 提供同样的⾼可⽤能⼒, 区别主要在于RS后来居上, 能⽀持更多种类的匹配模式。 副本集对象⼀般不单独使⽤, ⽽是作为Deployment的理想状态参数使⽤。
部署(Deployment)
部署表示⽤户对Kubernetes集群的⼀次更新操作。 部署是⼀个⽐RS应⽤模式更⼴的API对象, 可以是创建⼀个新的服
务, 更新⼀个新的服务, 也可以是滚动升级⼀个服务。 滚动升级⼀个服务, 实际是创建⼀个新的RS, 然后逐渐将新RS中副本数增加到理想状态, 将旧RS中的副本数减⼩到0的复合操作; 这样⼀个复合操作⽤⼀个RS是不太好描述的, 所以⽤⼀个更通⽤的Deployment来描述。 以Kubernetes的发展⽅向, 未来对所有⻓期伺服型的的业务的管理, 都会通过Deployment来管理。
服务(Service)
RC、 RS和Deployment只是保证了⽀撑服务的微服务Pod的数量, 但是没有解决如何访问这些服务的问题。 ⼀个Pod只是⼀个运⾏服务的实例, 随时可能在⼀个节点上停⽌, 在另⼀个节点以⼀个新的IP启动⼀个新的Pod, 因此不能以确定的IP和端⼝号提供服务。 要稳定地提供服务需要服务发现和负载均衡能⼒。 服务发现完成的⼯作, 是针对客户端访问的服务, 找到对应的的后端服务实例。 在K8集群中, 客户端需要访问的服务就是Service对象。 每个Service会对应⼀个集群内部有效的虚拟IP, 集群内部通过虚拟IP访问⼀个服务。 在Kubernetes集群中微服务的负载均衡是由Kube-proxy实现的。 Kube-proxy是Kubernetes集群内部的负载均衡器。 它是⼀个分布式代理服务器, 在Kubernetes的每个节点上都有⼀个; 这⼀设计体现了它的伸缩性优势, 需要访问服务的节点越多, 提供负载均衡能⼒的Kube-proxy就越多, ⾼可⽤节点也随之增多。 与之相⽐, 我们平时在服务器端做个反向代理做负载均衡, 还要进⼀步解决反向代理的负载均衡和⾼可⽤问题。
任务(Job)
Job是Kubernetes⽤来控制批处理型任务的API对象。 批处理业务与⻓期伺服业务的主要区别是批处理业务的运⾏有头
有尾, ⽽⻓期伺服业务在⽤户不停⽌的情况下永远运⾏。 Job管理的Pod根据⽤户的设置把任务成功完成就⾃动退出
了。 成功完成的标志根据不同的spec.completions策略⽽不同: 单Pod型任务有⼀个Pod成功就标志完成; 定数成功型
任务保证有N个任务全部成功; ⼯作队列型任务根据应⽤确认的全局成功⽽标志成功。
后台⽀撑服务集(DaemonSet)
长期伺服型和批处理型服务的核心在业务应用,可能有些节点运行多个同类服务的Pod,有些节点上又没有这类Pod运行,而后台支撑型服务的核心关注点在Kubernetes集群中的节点(物理机或虚拟机),要保证每个节点上都又一个此类Pod运行,节点可能是所有集群节点也可能是通过nodeSelector选定的一些特定节点,典型的后台支撑服务包括,存储,日志和监控等,在每个节点上支持kubernetes集群运行的服务。
有状态服务集(StatefulSet)
对于RC和RS中的Pod, ⼀般不挂载存储或者挂载共享存储, 保存的是所有Pod共享的状态, Pod像牲畜⼀样没有分别(这似乎也确实意味着失去了⼈性特征) ; 对于StatefulSet中的Pod, 每个Pod挂载⾃⼰独⽴的存储, 如果⼀个Pod出现故障, 从其他节点启动⼀个同样名字的Pod, 要挂载上原来Pod的存储继续以它的状态提供服务。
适合于StatefulSet的业务包括数据库服务MySQL和PostgreSQL, 集群化管理服务ZooKeeper、 etcd等有状态服务。StatefulSet的另⼀种典型应⽤场景是作为⼀种⽐普通容器更稳定可靠的模拟虚拟机的机制。 传统的虚拟机正是⼀种有状态的宠物, 运维⼈员需要不断地维护它, 容器刚开始流⾏时, 我们⽤容器来模拟虚拟机使⽤, 所有状态都保存在容器⾥, ⽽这已被证明是⾮常不安全、 不可靠的。 使⽤StatefulSet, Pod仍然可以通过漂移到不同节点提供⾼可⽤, ⽽存储也可以通过外挂的存储来提供⾼可靠性, StatefulSet做的只是将确定的Pod与确定的存储关联起来保证状态的连续性。
存储卷(Volume)
Kubernetes集群中的存储卷跟Docker的存储卷有些类似, 只不过Docker的存储卷作⽤范围为⼀个容器, ⽽Kubernetes的存储卷的⽣命周期和作⽤范围是⼀个Pod。 每个Pod中声明的存储卷由Pod中的所有容器共享。 Kubernetes⽀持⾮常多的存储卷类型, 特别的, ⽀持多种公有云平台的存储, 包括AWS, Google和Azure云; ⽀持多种分布式存储包括设计理念120GlusterFS和Ceph; 也⽀持较容易使⽤的主机本地⽬录emptyDir, hostPath和NFS。 Kubernetes还⽀持使⽤PersistentVolume Claim即PVC这种逻辑存储, 使⽤这种存储, 使得存储的使⽤者可以忽略后台的实际存储技术(例如AWS,Google或GlusterFS和Ceph) , ⽽将有关存储实际技术的配置交给存储管理员通过Persistent Volume来配置。
持久存储卷(Persistent Volume,PV)和持久存储生命(Persistent Volume Claim,PVC)
PV和PVC使得Kubernetes集群具备了存储的逻辑抽象能⼒, 使得在配置Pod的逻辑⾥可以忽略对实际后台存储技术的配置, ⽽把这项配置的⼯作交给PV的配置者, 即集群的管理者。 存储的PV和PVC的这种关系, 跟计算的Node和Pod的关系是⾮常类似的; PV和Node是资源的提供者, 根据集群的基础设施变化⽽变化, 由Kubernetes集群管理员配置; ⽽PVC和Pod是资源的使⽤者, 根据业务服务的需求变化⽽变化, 有Kubernetes集群的使⽤者即服务的管理员来配置。
节点(Node)
Kubernetes集群中的计算能⼒由Node提供, 最初Node称为服务节点Minion, 后来改名为Node。 Kubernetes集群中的Node也就等同于Mesos集群中的Slave节点, 是所有Pod运⾏所在的⼯作主机, 可以是物理机也可以是虚拟机。 不论是物理机还是虚拟机, ⼯作主机的统⼀特征是上⾯要运⾏kubelet管理节点上运⾏的容器。
密钥对象(Secret)
Secret是⽤来保存和传递密码、 密钥、 认证凭证这些敏感信息的对象。 使⽤Secret的好处是可以避免把敏感信息明⽂写在配置⽂⾥。 在Kubernetes集群中配置和使⽤服务不可避免的要⽤到各种敏感信息实现登录、 认证等功能, 例如访问AWS存储的⽤户名密码。 为了避免将类似的敏感信息明⽂写在所有需要使⽤的配置⽂件中, 可以将这些信息存⼊⼀个Secret对象, ⽽在配置⽂件中通过Secret对象引⽤这些敏感信息。 这种⽅式的好处包括: 意图明确, 避免重复, 减少暴漏机会。
用户账户(User Account)和服务账户(Service Account)
顾名思义, ⽤户帐户为⼈提供账户标识, ⽽服务账户为计算机进程和Kubernetes集群中运⾏的Pod提供账户标识。 ⽤户帐户和服务帐户的⼀个区别是作⽤范围; ⽤户帐户对应的是⼈的身份, ⼈的身份与服务的namespace⽆关, 所以⽤户账户是跨namespace的; ⽽服务帐户对应的是⼀个运⾏中程序的身份, 与特定namespace是相关的。
名称空间(Namespace)
名称空间为Kubernetes集群提供虚拟的隔离作用,Kubernetes集群初始化有两个名称空间,分别是default和kube-system,除此之外,管理员可以创建新的名称空间满足要求。
访问授权(RBAC)
Kubernetes在1.3版本中发布了alpha版的基于⻆⾊的访问控制(Role-based Access Control, RBAC) 的授权模式。 相对于基于属性的访问控制(Attribute-based Access Control, ABAC) , RBAC主要是引⼊了⻆⾊(Role) 和⻆⾊绑定(RoleBinding) 的抽象概念。 在ABAC中, Kubernetes集群中的访问策略只能跟⽤户直接关联; ⽽在RBAC中, 访问策略可以跟某个⻆⾊关联, 具体的⽤户在跟⼀个或多个⻆⾊相关联。 显然, RBAC像其他新功能⼀样, 每次引⼊新功能,都会引⼊新的API对象, 从⽽引⼊新的概念抽象, ⽽这⼀新的概念抽象⼀定会使集群服务管理和使⽤更容易扩展和重⽤。
参考文档
Kubernetes指南-倪朋飞
Kubernetes-handbook-jimmysong-20181218