Chapter 8. Kubernetes Building Blocks
Introduction and Learning Objectives
在本章中,我们将探讨Kubernetes对象模型,并讨论它的一些基本构建块,如Pods、ReplicaSets、Deployments、Namespaces等。我们还将讨论Labels和Selectors在微服务驱动的体系结构中扮演的重要角色,因为它们将分离的对象组合在一起。
Kubernetes Building Blocks
Kubernetes Object Model
Kubernetes有一个非常丰富的对象模型,表示Kubernetes集群中不同的持久实体。这些实体描述:
- 我们在哪个节点上运行哪些容器化应用程序
- 应用程序资源消耗情况
- 附加到应用程序的不同策略,如重新启动/升级策略、容错等。对于每个对象,我们在spec部分声明我们的意图或期望的状态。Kubernetes系统管理对象的status部分,其中记录了对象的实际状态。在任何给定的时间点上,Kubernetes控制平台都会尝试将对象的实际状态与对象的期望状态相匹配。
Kubernetes对象有Pods、ReplicaSets、Deployments、Namespaces等,我们将在下一步对它们进行探讨。
创建对象时,必须将spec字段下面对象的配置数据部分提交给Kubernetes API Server。spec部分描述了目标状态以及一些基本信息,比如对象的名称。创建对象的API请求必须包含spec部分以及其他详细信息。尽管API服务器接受JSON格式的对象定义文件,但我们通常以YAML格式提供这些文件,kubectl将这些文件转成JSON并将其发送到API服务器。
下面是YAML格式的部署对象配置示例:
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deployment labels: app: nginxspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15.11 ports: - containerPort: 80
apiVersion是第一个必填字段,它指定API服务器上的我们想要连接到的API端点,它必须与已定义的对象类型的现有版本匹配。第二个必需字段是kind,指定对象类型——在我们的示例中是Deployment,但它可以是Pod、Replicaset、Namespace、Service等。第三个必需字段metadata保存对象的基本信息,如name, labels, namespace等。我们的示例显示了两个spec字段(spec和spec.template.spec)。第四个必需的字段spec标记定义部署对象所需状态的块的开始。在我们的例子中,我们希望在任何给定的时间确保运行3个pod。Pods是使用spec.Template中定义的Pods模板创建的。嵌套的对象(如作为部署一部分的Pod)将保留其metadata和spec,但去掉apiVersion和kind——两者都将被template替换。在spec.template.spec中,我们定义了Pod的期望状态。我们的Pod创建了一个运行来自Docker Hub的nginx:1.15.11镜像的容器。一旦创建了部署对象,Kubernetes系统就会将status字段附加到该对象;我们稍后将对其进行研究。接下来,我们将更深入地研究一些Kubernetes对象以及其他组成部分。
Pods
Pod是最小最简单的Kubernetes对象。它是Kubernetes中的部署单元,表示应用程序的单个实例。Pod是一个或多个容器的逻辑集合,容器有如下特点:
- 一个/多个Container与Pod编排在同一主机上
- 共享相同的网络命名空间
- 访问相同的外部存储(卷)。
Pods是一个或多个容器的集合
事实上Pod是短暂的,它们没有自我恢复能力。这就是为什么它们需要与处理Pod的复制、容错、恢复等的控制器一起使用。控制器有Deployments, ReplicaSets, ReplicationControllers等。我们使用Pod模板将嵌套Pod的spec附加到控制器对象,如前一节所示。
下面是YAML格式的Pod对象配置示例:
apiVersion: v1kind: Podmetadata: name: nginx-pod labels: app: nginxspec: containers: - name: nginx image: nginx:1.15.11 ports: - containerPort: 80
apiVersion字段为Pod对象定义指定"v1"。第二个必需字段是指定Pod对象类型的kind。第三个必需的字段元数据包含对象的名称和标签。第四个必需的字段spec定义Pod对象所需状态,也称为Pod spec。我们的Pod创建了一个运行来自Docker Hub的nginx:1.15.11 镜像的容器。
Labels
Label是附加到Kubernetes对象(例如Pods、ReplicaSets)的键值对。标签用于根据现有需求组织和选择对象的子集。许多对象可以具有相同的标签。标签不能为对象提供唯一性。控制器使用标签将分离的对象逻辑地组合在一起,而不是使用对象的名称或id。
在上图中,我们使用了两个Label的Key:app和env。根据我们的要求,我们给了四个吊舱不同的价值。Label env=dev在逻辑上选择并分组前两个pod,而Lable app=frontend在逻辑上选择并分组左两个pod。我们可以从左下角的四个pod中选择一个,方法是使用两个标签:app=frontend和env=qa。
Label Selectors
Controllers使用标签选择器选择对象的子集。Kubernetes支持两种类型的选择器:
- 基于等式的选择器基于相等的选择器允许基于标签键和值筛选对象。使用=,(等于,可替换使用)或!=(不等于)运算符实现匹配。例如,对于envdev或env=dev,我们选择env Label键设置为value dev的对象。
- 基于集合的选择器基于集合的选择器允许基于一组值筛选对象。我们可以使用In,NOTIN操作符中筛选标签Value,以及用exist/not exist操作符筛选标签的Key。例如,使用env in(dev,qa),我们选择env标签设置为dev或qa的对象; !app选择没有标签app的对象应用程序。
ReplicationControllers
虽然不再推荐,但ReplicationController是一种控制器,它可以用于确保在任何给定时间运行指定数量的Pod副本。如果pod多于所需数量,则ReplicationController将终止额外的pod;如果pod较少,则复制控制器将创建更多的pod以匹配所需数量。通常,我们不会独立部署Pod,因为如果因为错误终止,它将无法自己重新启动。推荐的方法是使用某种类型的ReplicationController来创建和管理pod。默认控制器是一个Deployment ,它将配置ReplicaSet 为管理Pods的生命周期。
ReplicaSets I
ReplicaSet是下一代复制控制器。replicationset支持基于等式和集合的选择器,而replicationcontroller只支持基于等式的选择器。目前,这是唯一的区别。在ReplicaSet的帮助下,我们可以扩展运行特定容器应用程序映像的pod的数量。缩放可以手动完成,也可以通过使用autoscaler完成。接下来,您可以看到一个replicaSet的图形表示,我们将Pod的replicas count设置为3。
ReplicaSets II
现在,让我们继续同一个示例,假设其中一个pod被强制终止(由于资源不足、超时等),并且当前状态不再与所需状态匹配。
ReplicaSets III
ReplicaSet将检测到当前状态不再与所需状态匹配。ReplicaSet将创建一个额外的Pod,从而确保当前状态与所需状态匹配。
ReplicaSet可以独立用作Pod控制器,但它们只提供有限的一组功能。Deployment提供了一组补充功能,这是pod编排的推荐控制器。Deployment管理pod的创建、删除和更新。Deployment会自动创建一个ReplicaSet,然后创建一个Pod。不需要单独管理ReplicaSet和pod,Deployment将代表我们管理它们。下一步我们将更仔细地研究Deployment。
Deployments I
Deployment对象为pod和ReplicaSet提供声明性更新。DeploymentController是master node的控制器管理器的一部分,它确保当前状态始终与所需状态匹配。它允许通过rollouts和rollbacks无缝地更新和降级应用程序,并直接管理其ReplicaSet以进行应用程序扩展。在下面的示例中,一个新的Deployment创建了ReplicaSet A,然后它创建了3个Pod,每个Pod模板配置为运行一个nginx:1.7.9容器映像。在本例中,ReplicaSetA与nginx:1.7.9相关联,nginx:1.7.9表示部署的状态。此特定状态记录为修订版1。
Deployments II
现在,在Deployment中,我们更改了Pods的Template,并将容器映像从nginx:1.7.9更新为nginx:1.9.1。部署为1.9.1版本的新容器映像触发新的ReplicaSet B,此关联表示部署的新记录状态,版本2。这两个ReplicaSet之间的无缝转换是Deployment滚动更新,从带有3个Pods版本1.7.9的ReplicaSet A到带有3个Pods版本1.9.1的新ReplicaSet B,或者说从修订版1到修订版2。当我们为Deployment更新Pods Template时,会触发滚动更新。scaling或labeling等操作不会触发滚动更新,因此不会更改修订号。一旦滚动更新完成,Deployment将同时显示ReplicaSets A和B,其中A被缩放为0 pod,B被缩放为3 pod。这就是Deployment如何将其先前的状态配置设置记录为修订版的方式。
Deployments III
一旦ReplicaSet B及其版本为1.9.1的3个Pods准备就绪,Deployments就开始积极地管理它们。但是,Deployment将其先前的配置状态保存为历史修订版,修订版在Deployment的回滚功能中起着关键作用—返回到先前已知的配置状态。在我们的示例中,如果新nginx:1.9.1的性能不令人满意,则可以将部署回滚到以前的版本,在本例中,从版本2回滚到运行nginx:1.7.9的版本1。
Namespaces
如果多个用户和团队使用同一个Kubernetes集群,我们可以使用名称空间将集群划分为虚拟子集群。在命名空间中创建的资源/对象的名称是唯一的,但在群集中的命名空间中不是唯一的。要列出所有命名空间,可以运行以下命令:
$ kubectl get namespacesNAME STATUS AGEdefault Active 11hkube-node-lease Active 11hkube-public Active 11hkube-system Active 11h
通常,Kubernetes创建四个默认名称空间:kube system、kube public、kube node lease和default。kube system名称空间包含由Kubernetes系统创建的对象,主要是控制平面代理。default命名空间包含管理员和开发人员创建的对象和资源。默认情况下,我们连接到default命名空间。kube public是一个特殊的名称空间,任何人都可以对其进行安全和可读,用于特殊目的,例如公开集群的公共(非敏感)信息。最新的名称空间是kube node lease,它保存用于节点心跳数据的节点租约对象。然而,好的做法是创建更多的名称空间来为用户和开发团队虚拟化集群。通过Resource Quotas,我们可以在名称空间内划分集群资源。我们将在未来的一章中简要介绍Resource Quotas。
Deployment Rolling Update and Rollback (Demo)
推荐阅读:怎么查找我的iphone