ReplicationController是一种Kubernetes资源,可确保它的pod始终保持运行状态。如果pod因任何原因消失(例如节点从集群中消失或由于该pod已从节点中逐出),则ReplicationController 会注意到缺少了pod并创建新pod来代替它。ReplicationController 旨在创建和管理一个pod的多个副本(replicas)。 这就是ReplicationController名字的由来。image.png

4.2.1 ReplicationController的操作

ReplicationController会持续监控正在运行的pod列表, 并保证相应“类型”(指匹配相同的标签选择器) 的 pod的数目与期望相符。

出现多余的副本的可能原因:

  • 有人会手动创建相同类型的pod。
  • 有人更改现有的pod的“类型”。
  • 有人减少了所需的pod的数量, 等等。

介绍控制器的协调流程

ReplicationController的工作是确保pod的数量始终与其标签选择器匹配。 如果不匹配, 则ReplicationController将根据所需,采取适当的操作来协调pod的数量。
image.png

了解ReplicationController的三部分

  • label selector (标签选择器),用于确定ReplicationController作用域中有哪些pod。
  • replica count (副本个数),指定应运行的pod 数量 。
  • pod template (pod模板),用于创建新的pod 副本。

image.png
ReplicationController的标签选择器、副本个数、pod模板都可以随时修改,但只有副本个数(replica count)的变更会影响现有的 pod。

更改控制器的标签选择器或 pod 模板的效果

更改标签选择器和 pod 模板对现有 pod 没有影响。 更改标签选择器会使现有的pod 脱离ReplicationController的范围, 因此控制器会停止关注它们。 在创建 pod后,ReplicationController 也不关心其 pod的实际“ 内容 ”(容器镜像、 环境变量及其他)。因此, 该pod模板仅影响由此ReplicationController 创建的新 pod。 可以将其视为创建新pod的曲奇切模 (cookie cutter,饼干成型切割刀) 。

使用 ReplicationController 的好处

  • 确保一个 pod (或多个pod副本)持续运行,方法是在现有 pod 丢失时启动一个新 pod。
  • 集群节点发生故障时, 它将为故障节点上运行的所有 pod (即受ReplicationController 控制的节点上的那些 pod) 创建替代副本。
  • 它能轻松实现 pod的水平伸缩(horizontal scaling),手动和自动都可以(参见第 15 章中的pod的水平自动伸缩)。

注意:pod 实例永远不会重新安置到另一个节点。 相反,ReplicationController 会创建一个全新的 pod 实例, 它与正在替换的实例无关。

4.2.2 创建一个 ReplicationControllerimage.png

上传YAML文件到API Server时,Kubernetes会创 一个名为kubia的新ReplicationController, 它确保符合标签选择器app=kubia的pod实例始终是三个。当没有足够的pod时,根据提供的pod模板创建新的pod。

模板中的pod标签显然必须和ReplicationController的标签选择器匹配,否则控制器将无休止地创建新的容器。因为启动新 pod不会使实际的副本数量接近期望的副本数量。为了防止出现这种情况,API服务会校验ReplicationController的定义,不会接收错误配置。

根本不指定选择器也是一种选择。在这种情况下,它会自动根据pod模板中的标签自动配置。

提示:定义ReplicationController时不要指定pod选择器,让Kubernetes从pod模板中提取它。这样YAML更简短。

代码演示:

  1. cd /root/k8s/
  2. cat >kubia-rc.yaml <<'EOF'
  3. apiVersion: v1
  4. kind: ReplicationController
  5. metadata:
  6. name: kubia
  7. spec:
  8. replicas: 3
  9. selector:
  10. app: kubia
  11. template:
  12. metadata:
  13. labels:
  14. app: kubia
  15. spec:
  16. containers:
  17. - name: kubia
  18. image: 10.0.0.10:5000/luksa/kubia
  19. ports:
  20. - containerPort: 8080
  21. EOF
  22. kubectl create -f kubia-rc.yaml

4.2.3 使用ReplicationController

image.png

查看 ReplicationController 对已删除的 pod 的响应

image.png
image.png

获取有关 ReplicationController 的信息

image.png

  • DESIRED 表示期望的pod数量;
  • CURRENT 表示实际的pod数量;
  • READY 表示已经准备就绪的pod数量;

image.png

当前的副本数与所需的数量相符,因为控制器已经创建了一个新的pod。它显示了四个处理Running状态的pod, 因为被终止的pod仍在运行中,尽管它并未计入当前的副本个数中。底部的事件列表显示了ReplicationController的行——它到目前为止创建了四个pod。

控制器如何创建新的pod

控制器通过创建一个新的替代pod(replacement pod)来响应pod的删除操作(见图4.4)。从技术上讲,它并没有对删除本身做出反应,而是针对由此产生的状态——pod数量不足。

ReplicationController会立即收到删除pod的通知 (API Server允许客户端监听资源和资源列表的更改),但这不是它创建替代pod的原因。该通知会触发控制器检查实际的pod数量并采取适当的措施。
image.png

应对节点故障

如果一个节点不可用(发生故障或无法访问),则调度到该节点的pod的状态将变为Unknown。 此时,ReplicationController 将其他节点上立即启动一个新的pod。
image.png
image.png

4.2.4 将 pod 移入或移出 ReplicationController 的作用域

由ReplicationController 创建的pod并不是绑定到ReplicationController。在任何时刻,ReplicationController只管理与标签选择器匹配的pod。通过更改pod的标签,可以将它从ReplicationController的作用域 中添加或删除。它甚至可以从一个ReplicationController移动到另一个。

Usage:

查看pod由哪个rc控制
kubectl describe pod | grep Control

给ReplicationController管理的 pod 加标签

image.png
因为app=kubia标签还在,该pod还在rc的作用域中,对rc来说没发生任何更改。

更改己托管的 pod 的标签

现在,更改了 app=kubia 标签,这将使该 pod 不再与 ReplicationController 的标签选择器相匹配,只剩下两个匹配的 pod。 ReplicationController 会启动一个新的 pod,将数目恢复为三。
image.png
image.png

图4.5 说明了当你更改 pod 的标签,使得它们不再与 ReplicationController 的pod 选择器匹配时,发生的事情。现在kubia-dmdck pod是完全独立的,不再受到原来的rc的控制,并且会一直运行直到你手动删除它(现在可以这样做,因为你不再需要它)。
image.png

从控制器删除pod

如果你知道某个 pod 发生了故障, 就可以将它从 ReplicationController 的管理范围中移除(更改这个pod的标签), 让控制器将它替换为新 pod, 接着这个 pod 就任你处置了。 完成后删除该 pod 即可。

更改 ReplicationController 的标签选择器

如果不是更改某个 pod 的标签而是修改了 ReplicationController 的标签选择器, 你认为会发生什么?
答案:它会让所有原来由ReplicationController管理的 pod 脱离 ReplicationController 的管理, 导致它创建三个新的 pod。

你永远不会修改控制器的标签选择器, 但你会时不时会更改它的 pod 模板。 就让我们来了解一下吧。

4.2.5 修改 pod 模板

ReplicationController 的 pod模板可以随时修改。要修改旧的 pod, 你需要删除它们,并让 ReplicationController 根据新模板将其替换为新的 pod。
image.png

实验:向rc/kubia的pod模板中添加标签,观察新pod的改变。
#更改标签前查看pod
kubectl get pods —show-labels
image.png

向pod模板中添加一个标签 rel=beta (注意:无法更改pod模板的原标签,因为会与标签选择器不匹配)
kubectl edit rc kubia
image.png

再次查看pod(没有变化)
kubectl get pods —show-label
image.png
#删除一个pod
kubectl delete pod kubia-ld4lm

第三次查看pod(创建了一个新pod,并带有向模板中添加的rel=beta标签)
kubectl get pods —show-labels
image.png

像这样编辑一个ReplicationController, 来更改pod模板中的容器镜像,删除现有的容器,并让它们替换为新模板中的新容器, 可以用于升级pod, 但你将在第9章学到更好的方法。

4.2.6 水平伸缩(Horizontally scalling)pod

ReplicationController扩容

Usage:

将rc/kubia 的replicas数提高到10
kubectl scale rc kubia —replicas=10

通过编辑定义(definition)来伸缩ReplicationController

编辑rc的定义文件对其进行伸缩:更改spec.replicas的值:
kubectl edit rc kubia
image.png
image.png
注意:直接使用 vi 修改资源定义文件,无法生效。

用kubectl scale命令缩容

kubectl scale rc kubia —replicas=3

所有这些命令都会修改rc定义的 spec.replicas字段
image.png

伸缩集群的声明式方法

在 Kubernetes 中水平伸缩 pod 是陈述式的:"我想要运行x 个实例。”你不是告诉 Kubernetes 做什么或如何去做, 只是指定了期望的状态。

4.2.7 删除—个 ReplicationController

当你通过 kubectl delete 删除 ReplicationController 时,pod也会被删除。但是可以只删除 ReplicationController 并保待 pod 运行。
image.png
warning: —cascade=false is deprecated (boolean value) and can be replaced with —cascade=orphan.

Usage:

删除rc,同时让rc管理的pod保持运行:
kubectl delete rc kubia —cascade=orphan
—cascade=’background’: Must be “background”, “orphan”, or “foreground”. Selects the deletion
cascading strategy for the dependents (e.g. Pods created by a ReplicationController). Defaults to
background.

你已经删除了 ReplicationController, 所以这些 pod 独立了, 它们不再被管理。但是你始终可以使用适当的标签选择器创建新的 ReplicationController, 并再次将它们管理起来。