Garbage Collection

苏晓林 [email protected]

Kubernetes的垃圾回收的作用是删除那些失去Owner的对象。

注意:垃圾回收是一个测试版功能,只在Kubernetes 1.4及更高版本中默认启用。

Owners和dependents

Kubernetes中,一些对象是另一些对象的Owner,如:ReplicaSet是一组Pod的Owner。属于该Owner的对象称为该Owner的dependent。每个dependent对象都拥有metadata.ownerReferences字段来指向其Owner。

一些情况下,Kubernetes会自动设置ownerReference字段的值。如:当创建ReplicaSet时,Kubernetes会自动该ReplicaSet所有Pod的ownerReference字段指向该ReplicaSet。在Kubernetes 1.8版本,由ReplicationController, ReplicaSet, StatefulSet, DaemonSet, Deployment, Job and CronJob创建或管理的对象都会自动设置ownerReference字段。Kubernetes也支持手动设置ownerReference字段来指定Owner和dependent的关系。

下面示例中,展示了一个拥有3个Pods的ReplicaSet的配置

//my-repset.yaml
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
  name: my-repset
spec:
  replicas: 3
  selector:
    matchLabels:
      pod-is-for: garbage-collection-example
  template:
    metadata:
      labels:
        pod-is-for: garbage-collection-example
    spec:
      containers:
      - name: nginx
        image: nginx

创建该ReplicaSet,并查看Pod的metadata.ownerReferences字段

kubectl create -f https://k8s.io/docs/concepts/controllers/my-repset.yaml
kubectl get pods --output=yaml

下面输出结果中可以看到,该Pod的Owner类型为ReplicaSet,名称为my-repset

apiVersion: v1
kind: Pod
metadata:
  ...
  ownerReferences:
  - apiVersion: extensions/v1beta1
    controller: true
    blockOwnerDeletion: true
    kind: ReplicaSet
    name: my-repset
    uid: d9607e19-f88f-11e6-a518-42010a800195
  ...

垃圾回收器删除dependents的方式

当删除某个对象时,可以设置是否自动删除该对象的dependents。自动删除dependents也称为级联删除。Kubernetes中有两种级联删除的模式:background和foreground。

非自动删除的dependents对象将变为孤儿对象。

Foreground级联删除

在foreground级联删除模式中,root对象会首先进入“删除中”状态,在该状态中:

  • 该对象在REST API中仍然可见
  • 对象的deletionTimestamp字段为已设置
  • 对象的metadata.finalizers字段将包含值“foregroundDeletion”

当该对象进入“删除中”状态时,垃圾回收器会删除该对象的所有dependents。当删除所有(ownerReference.blockOwnerDeletion=true)的dependents对象后,才能删除Owner对象。

注意,在 “foreground 删除” 模式下,Dependent 只有通过 ownerReference.blockOwnerDeletion 才能阻止删除 Owner 对象。在 Kubernetes 1.7 版本中增加了 admission controller,基于 Owner 对象上的删除权限来控制用户去设置 blockOwnerDeletion 的值为 true,未授权的 Dependent 不能够延迟 Owner 对象的删除。

如果一个对象的ownerReferences 字段被一个 Controller(例如 Deployment 或 ReplicaSet)设置,blockOwnerDeletion 会被自动设置,没必要手动修改这个字段。

Background级联删除

在 background 级联删除 模式下,Kubernetes 会立即删除 Owner 对象,然后垃圾收集器会在后台删除dependents。

设置级联删除策略

通过为 Owner 对象设置deleteOptions.propagationPolicy字段,可以控制级联删除策略。支持的值为:“orphan”、“Foreground” 或 “Background”。

对很多 Controller 资源,包括 ReplicationController、ReplicaSet、StatefulSet、DaemonSet 和 Deployment,默认的垃圾收集策略是 orphan。因此,除非指定其它的垃圾收集策略,否则所有 dependent 对象使用的都是 orphan 策略。

下面是一个在后台删除 dependent 对象的例子:

kubectl proxy --port=8080
curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Background"}' \
-H "Content-Type: application/json"

下面是一个在前台删除dependent 对象的例子:

kubectl proxy --port=8080
curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
-H "Content-Type: application/json"

下面是一个孤儿 Dependent 的例子:

kubectl proxy --port=8080
curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset \
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
-H "Content-Type: application/json"

kubectl 也支持级联删除。 通过设置 --cascade 为 true,可以使用 kubectl 自动删除 dependent 对象。设置 --cascade 为 false,会使 dependent 对象成为孤儿 dependent 对象。--cascade 的默认值是 true。

下面是一个例子,使一个ReplicaSet的dependent成为孤儿 dependent:

kubectl delete replicaset my-repset --cascade=false

关于Deployments的注意事项

当使用级联方式删除Deployments时,必须使用策略propagationPolicy: Foreground,不仅要删除创建的ReplicaSets,还要删除它们的Pods。如果未设置propagationPolicy字段,则只会删除ReplicaSets,Pods将变为孤儿对象。更多信息请点击kubeadm/#149

原文链接:https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/

results matching ""

    No results matching ""