27.垃圾收集

垃圾收集

Kubernetes垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有Owner了。

OwnerDependent

一些Kubernetes对象是其它一些的Owner。例如,一个ReplicaSet是一组PodOwner。具有Owner的对象被称为是OwnerDependent。每个Dependent对象具有一个指向其所属对象的 metadata.ownerReferences 字段。

有时,Kubernetes会自动设置 ownerReference 的值。例如,当创建一个ReplicaSet时,Kubernetes自动设置ReplicaSet中每个PodownerReference 字段值。在1.6版本,Kubernetes会自动为一些对象设置 ownerReference 的值,这些对象是由ReplicationController、ReplicaSet、StatefulSet、DaemonSetDeployment所创建或管理。

也可以通过手动设置 ownerReference 的值,来指定OwnerDependent之间的关系。

这有一个配置文件my-repset.yaml,表示一个具有3PodReplicaSet

# k8s >= 1.16 使用下面注释 https://stackoverflow.com/questions/64412740/no-matches-for-kind-replicaset-in-version-extensions-v1beta1/64412990#64412990
# apiVersion: apps/v1
# k8s < 1.16 使用下面配置
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,然后查看Podmetadata字段,能够看到OwnerReferences字段:

kubectl create -f my-repset.yaml
kubectl get pods --output=yaml

输出显示了PodOwner是名为my-repsetReplicaSet

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

控制垃圾收集器删除Dependent

当删除对象时,可以指定是否该对象的Dependent也自动删除掉。自动删除Dependent也称为 级联删除Kubernetes中有两种 级联删除 的模式:background模式和foreground模式。

如果删除对象时,不自动删除它的Dependent,这些Dependent被称作是原对象的 孤儿

Background级联删除

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

Foreground级联删除

foreground级联删除 模式下,根对象首先进入 “删除中” 状态。在 “删除中” 状态会有如下的情况:

  • 对象仍然可以通过REST API可见
  • 会设置对象的 deletionTimestamp 字段
  • 对象的 metadata.finalizers 字段包含了值 “foregroundDeletion”

一旦被设置为 “删除中” 状态,垃圾收集器会删除对象的所有Dependent。垃圾收集器删除了所有 “Blocking” 的Dependent(对象的 ownerReference.blockOwnerDeletion=true)之后,它会删除Owner对象。

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

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

设置级联删除策略

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

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

注意:本段所指的默认值是指REST API的默认值,并非kubectl命令的默认值,kubectl默认为级联删除,后面会讲到。

下面是一个在后台删除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也支持级联删除。通过设置 --cascadetrue,可以使用kubectl自动删除Dependent对象。设置 --cascadefalse,会使Dependent对象成为孤儿Dependent对象。--cascade 的默认值是true

下面是一个例子,使一个ReplicaSetDependent对象成为孤儿Dependent

kubectl delete replicaset my-repset --cascade=false
上一页
下一页