05.资源对象

应用对象

K8s 对象协作图

类别 名称
资源对象 Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaling、Node、Namespace、Service、Ingress、Label、CustomResourceDefinition
存储对象 Volume、PersistentVolume、Secret、ConfigMap
策略对象 SecurityContext、ResourceQuota、LimitRange
身份对象 ServiceAccount、Role、ClusterRole

对象基础

Kubernetes使用对象去描述整个集群的状态,集群的状态包括了:什么容器化应用在运行以及在哪个Node上、可以被应用使用的资源、关于应用如何表现的策略,比如重启策略、升级策略,以及容错策略等。一旦创建对象,Kubernetes系统将持续工作以确保对象存在。通过创建对象,可以有效地告知Kubernetes系统,所需要的集群工作负载看起来是什么样子的,这就是Kubernetes集群的期望状态。 API对象是Kubernetes集群中的管理操作单元。Kubernetes集群系统每支持一项新功能,引入一项新技术,一定会新引入对应的API对象,支持对该功能的管理操作。例如副本集Replica Set对应的API对象是RS。每个API对象都有3大类属性:元数据metadata、规范spec和状态status

  • 元数据是用来标识API对象的,每个对象都至少有3个元数据:namespace,nameuid;除此以外还有各种各样的标签labels用来标识和匹配不同的对象,例如用户可以用标签env来标识区分不同的服务部署环境,分别用env=dev、env=testing、env=production来标识开发、测试、生产的不同服务。

  • spec规范描述了用户期望Kubernetes集群中的分布式系统达到的理想状态(Desired State,例如用户可以通过复制控制器Replication Controller设置期望的Pod副本数为3

  • status描述了系统实际当前达到的状态(Status,例如系统当前实际的Pod副本数为2;那么复制控制器当前的程序逻辑就是自动启动新的Pod,争取达到副本数为3

spec必须提供,它描述了对象的期望状态,即希望对象所具有的特征,而status描述了对象的实际状态,它是由Kubernetes系统提供和更新。在任何时刻,Kubernetes控制平面一直处于活跃状态,管理着对象的实际状态以与我们所期望的状态相匹配。当创建Kubernetes对象时,必须提供对象的spec,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如,名称。当使用Kubernetes API创建对象时(或者直接创建,或者基于kubectlAPI请求必须在请求体中包含JSON格式的信息。更常用的是,需要在.yaml文件中为kubectl提供这些信息。kubectl在执行API请求时,将这些信息转换成JSON格式。这里有一个.yaml示例文件,展示了Kubernetes Deployment的必需字段和对象spec

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
            - containerPort: 80

资源对象

Basic

Pod

Pod可谓Kubernetes中最为基础与重要的概念,Pod是在Kubernetes集群中运行部署应用或服务的最小单元,可以支持包含多容器。Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。

每个Pod都包含一个“根容器”(Pause容器)和多个紧密相关的用户业务容器。每个Pod都会提供一个独立的Endpoint(Pod IP + Container Port)以供调用方访问。在一组容器作为一个单元的情况下难以对这个“整体”简单进行判断以及进行行动。Pod内用一个业务无关的容器来代表这个整体的状态。业务容器之间的通信与文件共享问题。Pod基于虚拟二层网络技术(Flannel)实现任意两个跨主机的Pod之间可直接通信;同一个Pod里的容器共享同一个网络命名空间,可以使用localhost互相通信。Pod是短暂的,不是持续性实体。

命名空间(Namespace)

命名空间为Kubernetes集群提供虚拟的隔离作用,Kubernetes集群初始有两个命名空间,分别是默认命名空间default和系统命名空间kube-system,除此以外,管理员可以可以创建新的命名空间满足需要。

节点(Node)

Kubernetes集群中的计算能力由Node提供,最初Node称为服务节点Minion,后来改名为NodeKubernetes集群中的Node也就等同于Mesos集群中的Slave节点,是所有Pod运行所在的工作主机,可以是物理机也可以是虚拟机。不论是物理机还是虚拟机,工作主机的统一特征是上面要运行kubelet管理节点上运行的容器。

Label

一个LabelattachPod的一对键/值对,用来传递用户定义的属性。比如,你可能创建了一个"tier"和“app”标签,通过Label(tier=frontend, app=myapp)来标记前端Pod容器,使用Label(tier=backend, app=myapp)标记后台Pod。然后可以使用Selectors选择带有特定LabelPod,并且将Service或者Replication Controller应用到上面。

一个Label是一个key=value的键值对,由用于自行指定。Label可以附加到各种Kubernetes资源上,例如Node、Pod、Service、RC等,Label与资源对象是多对多的关系,其可以在资源对象定义是确定,也可以在资源对象创建后动态添加、删除。Kubernetes中非常核心重要的功能之一,用于分类、检索资源。重要使用场景有以下几处:

  • kube-controller进程通过RC上定义的Label Selector来筛选要监控的Pod副本数量,从而实现Pod副本数量始终符合预期设定的全自动控制流程。

  • kube-proxy进程通过ServiceLabel Selector来选择对应的Pod,自动建立起每个Service到对应Pod的请求转发路由表,从而实现Service的智能负载均衡机制。

  • kube-scheduler基于PodNodeSelector标签调度策略实现Pod“定向调度”的特性。

Workloads

Pods通常由更高级的抽象对象进行控制,进行常见的副本、认证、持久化存储、自定义调度、滚动更新等操作。

  • Deployments (Stateless Applications): replication + rollouts

  • StatefulSets (Stateful Applications): replication + rollouts + persistent storage + identity

  • Jobs (Batch Work): run to completion

  • CronJobs (Scheduled Batch Work): scheduled run to completion

  • DaemonSets (Per-Machine): per-Node scheduling

RC & RS

副本控制器(Replication Controller,RC)是Kubernetes集群中最早的保证Pod高可用的API对象。通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。即使在指定数目为1的情况下,通过RC运行Pod也比直接运行Pod更明智,因为RC也可以发挥它高可用的能力,保证永远有1Pod在运行。RCKubernetes较早期的技术概念,只适用于长期伺服型的业务类型。

副本集(Replication Set,RS)是新一代RC,提供同样的高可用能力,区别主要在于RS后来居上,能支持更多种类的匹配模式。副本集对象一般不单独使用,而是作为Deployment的理想状态参数使用。

部署(Deployment)

部署表示用户对Kubernetes集群的一次更新操作。部署是一个比RS应用模式更广的API对象,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的RS,然后逐渐将新RS中副本数增加到理想状态,将旧RS中的副本数减小到0的复合操作;这样一个复合操作用一个RS是不太好描述的,所以用一个更通用的Deployment来描述。以Kubernetes的发展方向,未来对所有长期伺服型的的业务的管理,都会通过Deployment来管理。

任务(Job)&定时任务(CronJob)

JobKubernetes用来控制批处理型任务的API对象。批处理业务与长期伺服业务的主要区别是批处理业务的运行有头有尾,而长期伺服业务在用户不停止的情况下永远运行。Job管理的Pod根据用户的设置把任务成功完成就自动退出了。成功完成的标志根据不同的spec.completions策略而不同:单Pod型任务有一个Pod成功就标志完成;定数成功型任务保证有N个任务全部成功;工作队列型任务根据应用确认的全局成功而标志成功。

后台支撑服务集(DaemonSet)

长期伺服型和批处理型服务的核心在业务应用,可能有些节点运行多个同类业务的Pod,有些节点上又没有这类Pod运行;而后台支撑型服务的核心关注点在Kubernetes集群中的节点(物理机或虚拟机,要保证每个节点上都有一个此类Pod运行。节点可能是所有集群节点也可能是通过nodeSelector选定的一些特定节点。典型的后台支撑型服务包括,存储,日志和监控等在每个节点上支持Kubernetes集群运行的服务。

有状态服务集(StatefulSet)

RCRS主要是控制提供无状态服务的,其所控制的Pod的名字是随机设置的,一个Pod出故障了就被丢弃掉,在另一个地方重启一个新的Pod,名字变了。名字和启动在哪儿都不重要,重要的只是Pod总数;而StatefulSet是用来控制有状态服务,StatefulSet中的每个Pod的名字都是事先确定的,不能更改。

对于RCRS中的Pod,一般不挂载存储或者挂载共享存储,保存的是所有Pod共享的状态,Pod像牲畜一样没有分别(这似乎也确实意味着失去了人性特征;对于StatefulSet中的Pod,每个Pod挂载自己独立的存储,如果一个Pod出现故障,从其他节点启动一个同样名字的Pod,要挂载上原来Pod的存储继续以它的状态提供服务。

适合于StatefulSet的业务包括数据库服务MySQLPostgreSQL,集群化管理服务ZooKeeperetcd等有状态服务。StatefulSet的另一种典型应用场景是作为一种比普通容器更稳定可靠的模拟虚拟机的机制。传统的虚拟机正是一种有状态的宠物,运维人员需要不断地维护它,容器刚开始流行时,我们用容器来模拟虚拟机使用,所有状态都保存在容器里,而这已被证明是非常不安全、不可靠的。使用StatefulSetPod仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性,StatefulSet做的只是将确定的Pod与确定的存储关联起来保证状态的连续性。

服务发现与负载均衡(Service Discovery & Load Balancing)

服务发现与负载均衡往往是由某个Service对象所管理,Service听了某个虚拟IP地址,并且允许以Label等选择方式将流量重定向到后端的Pods

  • Services Resources (L4) may expose Pods internally within a cluster or externally through an HA proxy.

  • Ingress Resources (L7) may expose URI endpoints and route them to Services.

服务(Service)

RC、RSDeployment只是保证了支撑服务的微服务Pod的数量,但是没有解决如何访问这些服务的问题。如果说Deployment是负责保证Pod组的正常运行,那么Service就是用于保证以合理的网络来连接到该组Pod。一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。要稳定地提供服务需要服务发现和负载均衡能力。服务发现完成的工作,是针对客户端访问的服务,找到对应的的后端服务实例。

K8集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。Servicekube-proxy实现软件负载均衡器,负责将对Service的请求转发到后端的某个Pod实例上。且Kubernetes为每个Service分配了一个全局唯一的虚拟IP地址(Cluster IP),每个服务在Kubernetes架构上即变成了具备唯一IP地址的通信节点。Service有三种类型:

  • ClusterIP:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP

  • NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过 <NodeIP>:NodePort 来访问该服务。

  • LoadBalancer:在NodePort的基础上,借助Cloud Provider创建一个外部的负载均衡器,并将请求转发到 <NodeIP>:NodePort

基于上述这点,KubernetesService NameService Cluster IP做一个DNS域名映射,优雅的解决了服务发现的问题。Kubernetes提供了内置的dns机制和ClusterIP机制,每个Service都自动注册域名,分配ClusterIP,这样服务间的依赖可以从IP变为nameDNS server通过kubernetes api server来观测是否有新Service建立,并为其建立对应的dns记录。如果集群已经enable DNS,那么Pod可以自动对Servicename解析。

Ingress

Ingress是从Kubernetes集群外部访问集群内部服务的入口。Service虽然解决了服务发现和负载均衡的问题,但它在使用上还是有一些限制,比如对外访问的时候,NodePort类型需要在外部搭建额外的负载均衡,而LoadBalancer要求Kubernetes必须跑在支持的Cloud Provider上面。

Ingress 访问架构

Ingress就是为了解决这些限制而引入的新资源,主要用来将服务暴露到Cluster外面,并且可以自定义服务的访问策略。比如想要通过负载均衡器实现不同子域名到不同服务的访问:

foo.bar.com --|                 |-> foo.bar.com s1:80
              | 178.91.123.132  |
bar.foo.com --|                 |-> bar.foo.com s2:80

存储对象

存储卷(Volume)

Kubernetes集群中的存储卷跟Docker的存储卷有些类似,只不过Docker的存储卷作用范围为一个容器,而Kubernetes的存储卷的生命周期和作用范围是一个Pod。每个Pod中声明的存储卷由Pod中的所有容器共享。Kubernetes支持非常多的存储卷类型,特别的,支持多种公有云平台的存储,包括AWSGoogleAzure云;支持多种分布式存储包括GlusterFSCeph;也支持较容易使用的主机本地目录emptyDir, hostPathNFS

Kubernetes还支持使用Persistent Volume ClaimPVC这种逻辑存储,使用这种存储,使得存储的使用者可以忽略后台的实际存储技术(例如AWSGoogleGlusterFSCeph,而将有关存储实际技术的配置交给存储管理员通过Persistent Volume来配置。

持久存储卷(Persistent Volume,PV)和持久存储卷声明(Persistent Volume Claim,PVC)

PVPVC使得Kubernetes集群具备了存储的逻辑抽象能力,使得在配置Pod的逻辑里可以忽略对实际后台存储技术的配置,而把这项配置的工作交给PV的配置者,即集群的管理者。存储的PVPVC的这种关系,跟计算的NodePod的关系是非常类似的;PVNode是资源的提供者,根据集群的基础设施变化而变化,由Kubernetes集群管理员配置;而PVCPod是资源的使用者,根据业务服务的需求变化而变化,有Kubernetes集群的使用者即服务的管理员来配置。

配置对象(ConfigMap)

Pod提供了非敏感的数据。

密钥对象(Secret)

Secret是用来保存和传递密码、密钥、认证凭证这些敏感信息的对象。使用Secret的好处是可以避免把敏感信息明文写在配置文件里。在Kubernetes集群中配置和使用服务不可避免的要用到各种敏感信息实现登录、认证等功能,例如访问AWS存储的用户名密码。为了避免将类似的敏感信息明文写在所有需要使用的配置文件中,可以将这些信息存入一个Secret对象,而在配置文件中通过Secret对象引用这些敏感信息。这种方式的好处包括:意图明确,避免重复,减少暴漏机会。

身份对象

用户帐户(User Account)和服务帐户(Service Account)

顾名思义,用户帐户为人提供账户标识,而服务账户为计算机进程和Kubernetes集群中运行的Pod提供账户标识。用户帐户和服务帐户的一个区别是作用范围;用户帐户对应的是人的身份,人的身份与服务的namespace无关,所以用户账户是跨namespace的;而服务帐户对应的是一个运行中程序的身份,与特定namespace是相关的。

RBAC访问授权

Kubernetes1.3版本中发布了alpha版的基于角色的访问控制(Role-based Access Control,RBAC)的授权模式。相对于基于属性的访问控制(Attribute-based Access Control,ABACRBAC主要是引入了角色(Role)和角色绑定(RoleBinding)的抽象概念。在ABAC中,Kubernetes集群中的访问策略只能跟用户直接关联;而在RBAC中,访问策略可以跟某个角色关联,具体的用户在跟一个或多个角色相关联。显然,RBAC像其他新功能一样,每次引入新功能,都会引入新的API对象,从而引入新的概念抽象,而这一新的概念抽象一定会使集群服务管理和使用更容易扩展和重用。

集群联邦(Federation)

Kubernetes1.3版本里发布了beta版的Federation功能。在云计算环境中,服务的作用距离范围从近到远一般可以有:同主机(Host,Node、跨主机同可用区(Available Zone、跨可用区同地区(Region、跨地区同服务商(Cloud Service Provider、跨云平台。Kubernetes的设计定位是单一集群在同一个地域内,因为同一个地区的网络性能才能满足Kubernetes的调度和计算存储连接要求。而联合集群服务就是为提供跨Region跨服务商Kubernetes集群服务而设计的。

每个Kubernetes Federation有自己的分布式存储、API ServerController Manager。用户可以通过FederationAPI Server注册该Federation的成员Kubernetes Cluster。当用户通过FederationAPI Server创建、更改API对象时,Federation API Server会在自己所有注册的子Kubernetes Cluster都创建一份对应的API对象。在提供业务请求服务时,Kubernetes Federation会先在自己的各个子Cluster之间做负载均衡,而对于发送到某个具体Kubernetes Cluster的业务请求,会依照这个Kubernetes Cluster独立提供服务时一样的调度模式去做Kubernetes Cluster内部的负载均衡。而Cluster之间的负载均衡是通过域名服务的负载均衡来实现的。

Federation V1的设计是尽量不影响Kubernetes Cluster现有的工作机制,这样对于每个子Kubernetes集群来说,并不需要更外层的有一个Kubernetes Federation,也就是意味着所有现有的Kubernetes代码和机制不需要因为Federation功能有任何变化。

上一页
下一页