From 1f287e103389bba66672046f4cc648a3a15f81da Mon Sep 17 00:00:00 2001 From: "huanqing.shao" Date: Thu, 7 Nov 2019 11:52:35 +0800 Subject: [PATCH] disruption --- .vuepress/config-sidebar.js | 4 +- .vuepress/public/landing.html | 6 + .../statics/learning/obj/gc-replicaset.yaml | 17 ++ docker-compose.yaml | 17 ++ install/install-k8s-dashboard.md | 4 +- install/install-kubectl.md | 112 +++++++++-- .../k8s-intermediate/workload/disruption.md | 180 ++++++++++++++++++ learning/k8s-intermediate/workload/gc.md | 126 ++++++++++++ .../workload/wl-statefulset/index.md | 2 +- .../k8s-intermediate/workload/wl-ttl/index.md | 32 ++++ support/change-log/change-log-on-the-way.md | 19 +- support/change-log/v1.0.x.md | 21 ++ 12 files changed, 507 insertions(+), 33 deletions(-) create mode 100644 .vuepress/public/statics/learning/obj/gc-replicaset.yaml create mode 100644 learning/k8s-intermediate/workload/disruption.md diff --git a/.vuepress/config-sidebar.js b/.vuepress/config-sidebar.js index 97e857b..70e11cd 100644 --- a/.vuepress/config-sidebar.js +++ b/.vuepress/config-sidebar.js @@ -158,6 +158,7 @@ module.exports = { 'k8s-intermediate/workload/init-container', 'k8s-intermediate/workload/init-config', 'k8s-intermediate/workload/init-debug', + 'k8s-intermediate/workload/disruption', 'k8s-intermediate/workload/workload', { title: '控制器 - Deployment', @@ -217,7 +218,8 @@ module.exports = { 'k8s-intermediate/workload/wl-cronjob/', 'k8s-intermediate/workload/wl-cronjob/run', ] - } + }, + 'k8s-intermediate/workload/gc', ] }, { diff --git a/.vuepress/public/landing.html b/.vuepress/public/landing.html index f77f5df..a835d8e 100755 --- a/.vuepress/public/landing.html +++ b/.vuepress/public/landing.html @@ -558,6 +558,12 @@ + + diff --git a/.vuepress/public/statics/learning/obj/gc-replicaset.yaml b/.vuepress/public/statics/learning/obj/gc-replicaset.yaml new file mode 100644 index 0000000..e5dfdf6 --- /dev/null +++ b/.vuepress/public/statics/learning/obj/gc-replicaset.yaml @@ -0,0 +1,17 @@ +apiVersion: apps/v1 +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 diff --git a/docker-compose.yaml b/docker-compose.yaml index 2d2cef7..ea35e7f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -17,5 +17,22 @@ services: - ./docs:/usr/share/nginx/html networks: - webnet + kubetrain: + # replace username/repo:tag with your name and image details + image: eipwork/kuboard-press:latest + deploy: + replicas: 1 + resources: + limits: + cpus: "0.1" + memory: 500M + restart_policy: + condition: on-failure + ports: + - "8082:80" + volumes: + - /Users/shaohuanqing/Kuboard/kuboard-workspace/kubetrain/root:/usr/share/nginx/html + networks: + - webnet networks: webnet: diff --git a/install/install-k8s-dashboard.md b/install/install-k8s-dashboard.md index f9b8e81..0388270 100644 --- a/install/install-k8s-dashboard.md +++ b/install/install-k8s-dashboard.md @@ -1,6 +1,6 @@ --- vssueId: 126 -description: Kubernetes升级_使用kubeadm升级K8S集群_到Kubernetes_v1.15.3 +description: Kubernetes_Dashboard_是Kubernetes的官方WebUI_本文描述了如何在K8S集群上安装Kuberentes_Dashboard meta: - name: keywords content: Kubernetes Dashboard,安装Kubernetes Dashboard,K8S Dashboard,K8S管理界面 @@ -93,6 +93,8 @@ Kubernetes Dashboard 当前,只支持使用 Bearer Token登录。 访问路径: `http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/` + > 我曾经尝试过将 kubernetes-dashboard 的访问当时修改为 nodePort 的访问,但是一直未能成功,如果有朋友解决了此问题,请告知我一下。 + * 将上一个步骤中获得的 Token 输入到登录界面中,点击 **Sign in** 按钮,完成登录 ![Kubernetes教程_安装KubernetesDashboard](./install-k8s-dashboard.assets/signin.png) diff --git a/install/install-kubectl.md b/install/install-kubectl.md index 704fe5d..db46f7c 100644 --- a/install/install-kubectl.md +++ b/install/install-kubectl.md @@ -55,18 +55,54 @@ yum install -y kubectl kubectl version ``` - - + + + +* 从下面的链接下载 kubectl 可执行文件 + + ` + https://storage.googleapis.com/kubernetes-release/release/v1.16.2/bin/windows/amd64/kubectl.exe + ` + > * 请将其中的 v1.16.2 替换为最新的版本号 + > * 通过此链接可获取最新的版本号 `https://storage.googleapis.com/kubernetes-release/release/stable.txt` -待完善 +* 将下载的可执行文件添加到 PATH 环境变量 - - -待完善 +* 执行命令查看已安装的 kubectl 版本号 + ``` + kubectl version + ``` - + + + +* 下载最新的可执行文件 + + ```sh + curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl" + ``` + +* 添加可执行权限 + + ```sh + chmod +x ./kubectl + ``` + +* 复制到 PATH 路径 + + ```sh + sudo mv ./kubectl /usr/local/bin/kubectl + ``` + +* 检查已安装版本 + + ``` sh + kubectl version + ``` + + @@ -137,17 +173,65 @@ kubectl get pods -n kube-system ``` - - + + -待完善 +**执行命令** - - +用记事本(或其他文本编辑器)创建文件 `~/.kube/config`,其中 `~` 代表当前的用户目录 -待完善 +将前面获得的 `/etc/kubernetes/admin.conf` 文件的内容粘贴进该文件并保存 - +**配置 hosts** + +用记事本打开 C:\windows\System32\drivers\etc\hosts 文件(需要管理员权限),在该文件末尾添加一行记录: + +``` +x.x.x.x apiserver.demo +``` + +> * 将 x.x.x.x 替换成 demo-master-a-1 的实际 IP 地址 +> * 将 apiserver.demo 替换成前面获得 `/etc/kubernetes/admin.conf` 文件中 `clusters/cluster/server` 中 URL 里 host 对应的部分 + +**验证安装结果** + +执行命令 + +```sh +kubectl get nodes +kubectl get pods -n kube-system +``` + + + + +**执行命令** + +```sh +vi ~/.kube/config +``` + +将前面获得的 `/etc/kubernetes/admin.conf` 文件的内容粘贴进该文件并保存 + +**配置 hosts** + +```sh +echo "x.x.x.x apiserver.demo" >> /etc/hosts +``` + +> * 将 x.x.x.x 替换成 demo-master-a-1 的实际 IP 地址 +> * 将 apiserver.demo 替换成前面获得 `/etc/kubernetes/admin.conf` 文件中 `clusters/cluster/server` 中 URL 里 host 对应的部分 + +**验证安装结果** + +执行命令 + +```sh +kubectl get nodes +kubectl get pods -n kube-system +``` + + diff --git a/learning/k8s-intermediate/workload/disruption.md b/learning/k8s-intermediate/workload/disruption.md new file mode 100644 index 0000000..49105e7 --- /dev/null +++ b/learning/k8s-intermediate/workload/disruption.md @@ -0,0 +1,180 @@ +--- +vssueId: 155 +layout: LearningLayout +description: Kubernetes教程_Kubernetes_garbage_collector_垃圾回收器的作用是删除那些曾经有owner_后来又不再有owner的对象。 +meta: + - name: keywords + content: Kubernetes教程,K8S教程,K8S培训,K8S垃圾回收,K8S Garbage Collection +--- + +# 容器组_毁坏Disruptions + + + +> 参考文档: [Disruptions](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/) + +本文面向想要构建高可用的应用程序的应用程序管理员,为此,您需要理解有哪些毁坏(disruption)可能发生在Pod上。 + +本文也是为集群管理员准备的,如果集群管理员想要将集群的部分管理任务自动化的话,例如,升级、自动伸缩等。 + +::: tip +Disruption ---> 毁坏。 暂时没想到合适的词,如果您有想法,请联系我。 +::: + +[[TOC]] + + + + +## 自愿的和非自愿的毁坏 + +除非有人(人或者控制器)销毁Pod,或者出现不可避免的硬件/软件故障,Pod不会凭空消失。此类不可避免的情况,我们称之为非自愿的毁坏(involuntary disruption)。例如: +* 节点所在物理机的硬件故障 +* 集群管理员误删了虚拟机 +* 云供应商或管理程序故障导致虚拟机被删 +* Linux 内核故障 +* 集群所在的网络发生分片,导致节点不可用 +* 节点资源耗尽,导致 Pod 被驱逐 + + + +除了节点资源耗尽这种情况以外,大部分人对其他情况都十分熟悉,因为这并不是 Kubernetes 所特有的情况。 + +还有一类毁坏,我们称之为自愿的毁坏(voluntary disruptions)。主要包括由应用管理员或集群管理员主动执行的操作。应用管理员可能执行的操作有: +* 删除 Deployment 或其他用于管理 Pod 的控制器 +* 修改 Deployment 中 Pod 模板的定义,导致 Pod 重启 +* 直接删除一个 Pod + +集群管理员可能执行的操作有: +* [排空节点](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/) 以便维修或升级 +* 排空节点,以将集群缩容 +* 从节点上删除某个 Pod,以使得其他的 Pod 能够调度到该节点上 + + + + +这些操作可能直接由集群管理员执行,或者由执行管理员运行的自动化脚本执行,也可能由您的集群托管商执行。 + +向您的集群管理员、云供应商询问,您的集群是否激活了任何形式的自愿的毁坏。如果没有激活,您无需创建 Pod Disruption Budgets。 + +::: danger 警告 +并非所有自愿的毁坏都受 Pod Disruption Budgets 限制,例如,删除 Deployment 或 Pod。 +::: + +## 处理毁坏(Disruptions) + +弥补非自愿的毁坏可以采取的方法有: + +* 确保您的 Pod [申请合适的计算资源](/learning/k8s-intermediate/config/computing-resource.html) +* 如果需要高可用,为您的程序运行多个副本,参考 [Deployment](/learning/k8s-intermediate/workload/wl-deployment/)、[StatefulSet](/learning/k8s-intermediate/workload/wl-statefulset/) +* 如果需要更高的高可用性,将应用程序副本分布到多个机架上(参考 [anti-affinity](/learning/k8s-intermediate/config/assign-pod-node.html#affinity-and-anti-affinity))或分不到多个地区(使用 [multi-zone cluster](https://kubernetes.io/docs/setup/multiple-zones)) + +自愿的毁坏,发生频率不定。在一个基础的 Kubernetes 集群中,可能不会发生自愿的毁坏。当你的集群管理员或者托管供应商运行某些额外的服务是可能导致自愿的毁坏发生。例如: +* 更新节点上的软件 +* 自定义实现的自动伸缩程序 + +集群管理员或托管供应商应该为您提供这方面的文档。 + +Kubernetes 提供了 Disruption Budget 这一特性,以帮助我们在高频次自愿的毁坏会发生的情况下,仍然运行高可用的应用程序。 + +## Disruption Budget如何工作 + +应用程序管理员可以为每一个应用程序创建 `PodDisruptionBudget` 对象(PDB)。PDB限制了多副本应用程序在自愿的毁坏情况发生时,最多有多少个副本可以同时停止。例如,一个 web 前端的程序需要确保可用的副本数不低于总副本数的一定比例。 + +集群管理员以及托管供应商在进行系统维护时,应该使用兼容 PodDisruptionBudget 的工具(例如 `kubectl drain`,此类工具调用 [Eviction API](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/#the-eviction-api))而不是直接删除 Pod 或者 Deployment。 + +`kubectl drain` 命令会尝试将节点上所有的 Pod 驱逐掉。驱逐请求可能会临时被拒绝,`kubectl drain` 将周期性地重试失败的请求,直到节点上所有的 Pod 都以终止,或者直到超过了预先配置的超时时间。 + +PDB 指定了应用程序最少期望的副本数(相对于总副本数)。例如,某个 Deployment 的 `.spec.replicas` 为 5,期望的副本数是 5个。如果他对应的 PDB 允许最低 4个副本数,则 Eviction API(`kubectl drain`)在同一时刻最多会允许1个自愿的毁坏,而不是2个或更多: + +* PDB 通过 Pod 的 `.metadata.ownerReferences` 查找到其对应的控制器(Deployment、StatefulSet) +* PDB 通过 控制器(Deployment、StatefulSet)的 `.spec.replicas` 字段来确定期望的副本数 +* PDB 通过控制器(Deployment、StatefulSet)的 label selector 来确定哪些 Pod 属于同一个应用程序 +* PDB 不能阻止 [非自愿的毁坏](#自愿的和非自愿的毁坏) 发生,但是当这类毁坏发生时,将被计入到当前毁坏数里 +* 通过 `kubectl drain` 驱逐 Pod 时,Pod 将被优雅地终止(gracefully terminated,参考 [terminationGracePeriodSeconds](/learning/k8s-intermediate/workload/pod.html#termination-of-pods)) + +在滚动更新过程中被删除的 Pod 也将计入到 PDB 的当前毁坏数,但是控制器(例如 Deployment、StatefulSet)在执行滚动更新时,并不受 PDB 的约束。滚动更新过程中,同时可以删除的 Pod 数量在控制器对象(Deployment、StatefulSet等)的定义中规定,参考[滚动更新](/learning/k8s-intermediate/workload/wl-deployment/update.html)。 + +## PDB Example + +假设有一个集群共有三个工作节点,`node-1`、`node-2`、`node-3`,集群上运行了多个应用程序,其中一个 Deployment 有 3个 Pod 副本 `pod-a`、`pod-b`、`pod-c`,并且对应了 PDB 限定 3 个 Pod 中至少要有 2 个可用。另外有一个无关的 `pod-x` 没有对应的PDB。最开始时,Pod 在节点上的分布如下表所示: + +| node-1 | node-2 | node-3 | +| ---------------------- | ---------------------- | ---------------------- | +| pod-a ***available*** | pod-b ***available*** | pod-c ***available*** | +| pod-x ***available*** | | | + +此时,假设集群管理员想要重启机器,以便更新 Linux 内核版本修复其中的一个漏洞。集群管理员首先尝试使用 `kubectl drain` 命令排空 `node-`,此时 `kubectl drain` 将尝试驱逐 `pod-a` 和 `pod-x`。这个操作将立刻能够执行成功,两个 Pod 都将同时进入 `terminating` 状态,集群的状态将如下所示: + +| node-1 ***draining*** | node-2 | node-3 | +| ---------------------- | ---------------------- | ---------------------- | +| pod-a ***terminating*** | pod-b ***available*** | pod-c ***available*** | +| pod-x ***terminating*** | | | + +Deployment控制器发现其中的一个 Pod 正在终止,因此,将立刻创建一个新的 Pod 以替代该 Pod,假设其为 `pod-d`。由于 `node-1` 已经被标记不可用(cordoned 警戒线),`pod-d` 将调度到另外一个节点上。另外一个控制器同样也为 `pod-x` 创建了一个替代 Pod `pod-y`。 + +此时,集群状态如下所示: + +| node-1 ***draining*** | node-2 | node-3 | +| ---------------------- | ---------------------- | ---------------------- | +| pod-a ***terminating*** | pod-b ***available*** | pod-c ***available*** | +| pod-x ***terminating*** | pod-d ***starting*** | pod-y | + +当 `pod-a` 和 `pod-x` 终止以后,集群状态如下所示: + +| node-1 ***drained*** | node-2 | node-3 | +| ---------------------- | ---------------------- | ---------------------- | +| | pod-b ***available*** | pod-c ***available*** | +| | pod-d ***starting*** | pod-y | + + +此时,如果集群管理员不够耐心,立刻尝试排空 `node-2` 或 `node-3`,则 `kubectl drain` 命令将被组织阻止,因为当前该 Deployment 只有 2个可用的 Pod,而其 PDB 要求至少有 2个可用的 Pod。 + +当 `pod-d` 完成启动后,集群的状态将如下所示: + + +| node-1 ***drained*** | node-2 | node-3 | +| ---------------------- | ---------------------- | ---------------------- | +| | pod-b ***available*** | pod-c ***available*** | +| | pod-d ***available*** | pod-y | + + +此时,集群管理员尝试排空 `node-2`。`kubectl drain` 将按照某种顺序尝试驱逐 node-2 上的两个 Pod,假设先是 `pod-b` 然后是 `pod-d`。驱逐 `pod-b` 的操作将执行成功,但是,当 `kubectl drain` 尝试驱逐 `pod-d` 时,该请求将被拒绝,否则该 Deployment 将只剩下一个可用的 Pod。 + +Deployment 此时将创建一个 Pod `pod-e` 用于替换 Pod `pod-b`。由于集群中没有足够的资源来调度 `pod-e`,`kubectl drain` 将再次被阻止。集群状态如下所示: + +| node-1 ***drained*** | node-2 | node-3 | no node | +| ---------------------- | ---------------------- | ---------------------- | ---------------------- | +| | pod-b ***available*** | pod-c ***available*** | pod-3 ***pending*** | +| | pod-d ***available*** | pod-y | | + + +此时,集群管理员需要向集群中添加节点,才能继续集群的升级操作。 + +Kubernetes中,如下因素决定了毁坏发生的频率: +* 应用程序所需要的副本数 +* 对一个 Pod 执行优雅终止(gracefully shutdown)所需要的时间 +* 新的 Pod 实例启动所需要的时间 +* 控制器的类型 +* 集群资源的容量 + +## 区分集群管理员和应用管理员的角色 + +通常,我们认为集群管理员和应用管理员是不同的角色,且相互之间所共有的知识并不多。对这两个角色的职责进行区分,在如下场景中是非常有用的: +* 多个应用程序团队共享一个 Kubernetes 集群 +* 第三方工具或服务将集群的管理自动化 + +Pod Disruption Budget 是区分两种角色时的必要的界面,双方要就此概念达成共识。如果你所在的组织中,并不严格区分集群管理员和应用程序管理员,则,您并不需要使用 Pod Disruption Budget。 + +## 如何执行毁坏性的操作(Disruptive Action) + +如果您是集群管理员,且需要在所有节点上执行毁坏性的操作(disruptive action),例如节点或系统软件的升级,此时,可能的选择有: + +* 接受升级过程中的停机时间 +* 故障转移(Failover)到另外一个集群副本 + * 无停机时间,但是将有额外的代价,因为需要由双份的节点以及更多的人力成本来管理集群之间的切换 +* 编写容错的应用程序(disruption tolerant application)并使用 PDB + * 无停机时间 + * 最少的资源冗余 + * 支持更多的集群管理自动化 + * 编写容错的应用程序(disruption-tolerant application)非常需要技巧,但是要容忍自愿的毁坏所做的工作与支持自动伸缩(autoscaling)与容忍非自愿的毁坏(tolerating involuntary disruption)所做的工作是大量重叠的 diff --git a/learning/k8s-intermediate/workload/gc.md b/learning/k8s-intermediate/workload/gc.md index e69de29..6900e0f 100644 --- a/learning/k8s-intermediate/workload/gc.md +++ b/learning/k8s-intermediate/workload/gc.md @@ -0,0 +1,126 @@ +--- +vssueId: 155 +layout: LearningLayout +description: Kubernetes教程_Kubernetes_garbage_collector_垃圾回收器的作用是删除那些曾经有owner_后来又不再有owner的对象。 +meta: + - name: keywords + content: Kubernetes教程,K8S教程,K8S培训,K8S垃圾回收,K8S Garbage Collection +--- + +# 垃圾回收 + + + +> 参考文档: [Garbage Collection](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/) + +Kubernetes garbage collector(垃圾回收器)的作用是删除那些曾经有 owner,后来又不再有 owner 的对象。 + +[[TOC]] + + + +## 所有者和从属对象 + +某些 Kubernetes 对象是其他 Kubernetes 对象的所有者(owner),同时,我们称被拥有的对象为拥有者的从属对象(dependent)。例如,ReplicaSet 是一组 Pod 的所有者,在这里 Pod 是 ReplicaSet 的从属对象。每一个从属对象都有一个 `metadata.ownerReferences` 字段,标识其拥有者是哪一个对象。 + +某些情况下,Kubernetes将自动设置 `ownerReferences` 字段。例如,当您创建一个 ReplicaSet 时,Kubernetes 自动设置该 ReplicaSet 创建的 Pod 中的 `ownerReferences` 字段。自版本 1.8 开始,对于 ReplicationController、ReplicaSet、StatefulSet、DaemonSet、Deployment、Job、CronJob等创建或管理的对象,Kubernetes 都将自动为其设置 `ownerReference` 的值。 + +也可以通过修改 `ownerReference` 字段,手动设置所有者和从属对象的关系。 + +下面例子中的 ReplicaSet 包含三个 Pod: + +<<< @/.vuepress/public/statics/learning/obj/gc-replicaset.yaml + +执行命令以创建该 ReplicaSet,然后查看 Pod 的 `.metadata.ownerReferences` 字段的值: +```sh +kubectl apply -f https://kuboard.cn/statics/learning/obj/gc-replicaset.yaml +kubectl get pods --output=yaml +``` + +输出结果如下所示: +``` yaml {8,11} +apiVersion: v1 +kind: Pod +metadata: + ... + ownerReferences: + - apiVersion: apps/v1 + controller: true + blockOwnerDeletion: true + kind: ReplicaSet + name: my-repset + uid: d9607e19-f88f-11e6-a518-42010a800195 + ... +``` + +::: tip 跨名称空间 +在 Kubernetes 的设计里,跨名称空间的所有者-从属对象的关系是不被允许的。这意味着: +* 名称空间内的从属对象只能指定同名称空间的对象作为其所有者 +* 集群级别的对象只能指定集群级别的对象作为其所有者 +::: + +## 垃圾收集器如何删除从属对象 + +当删除某个对象时,可以指定该对象的从属对象是否同时被自动删除,这种操作叫做级联删除(cascading deletion)。级联删除有两种模式:后台(background)和前台(foreground) + +如果删除对象时不删除自动删除其从属对象,此时,从属对象被认为是孤儿(或孤立的 orphaned)。 + +### Foreground级联删除 + +在 foreground 级联删除模式下,根对象(直接被删除的对象)先进入“正在删除”(deletion in progress)状态,此时: +* 对象仍然可以通过 REST API 查询到(可通过 kubectl 或 kuboard 查询到) +* 对象的 `deletionTimestamp` 字段被设置 +* 对象的 `metadata.finalizers` 包含值 `foregroundDeletion` + +一旦对象被设置为 “deletion in progress” 状态,垃圾回收器将删除其从属对象。当垃圾回收器已经删除了所有的“blocking”从属对象(`ownerReference.blockOwnerDeletion=true` 的对象)以后,将删除所有者对象。 + +此处需要注意的是,在“foregroundDeletion” 模式下,只有 `ownerReference.blockOwnerDeletion=true` 的对象将阻止所有者对象的删除。在 Kubernetes 版本 1.7 开始,增加了 [admission controller](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement) ,可以基于所有者对象的删除权限配置限制用户是否可以设置 `blockOwnerDeletion` 字段为 true,因此,未经授权的从属对象将不能阻止所有者对象的删除。 + +如果对象的 `ownerReferences` 字段由控制器自动设置(例如,Deployment、ReplicaSet),`blockOwnerDeletion` 也将被自动设置,您无需手工修改该字段的取值。 + +### Background级联删除 + +在 background 级联删除模式下,Kubernetes将立刻删除所有者对象,并由垃圾回收器在后台删除其从属对象。 + +### 设置级联删除策略 + +在删除对象时,通过参数 `deleteOptions` 的 `propagationPolicy` 字段,可以设置级联删除的策略。可选的值有: `Orphan`、`Foreground`、`Background`。 + +默认值: +* 在 Kubernetes 1.9 之前,许多类型控制器的默认垃圾回收策略都是 `orphan`,例如,ReplicationController、ReplicaSet、StatefulSet、DaemonSet、Deployment。 +* 对于 apiVersion 为 `extensions/v1beta1`、`apps/v1beta1`、和 `apps/v1beta2` 的对象,除非特殊指定,垃圾回收策略默认为 `orphan` +* 在 Kubernetes 1.9 中,对于所有 apiVersion 为 `apps/v1` 的对象,从属对象默认都将被删除 + +下面的例子中,使用了 background 级联删除: + +``` sh +kubectl proxy --port=8080 +curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \ + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Background"}' \ + -H "Content-Type: application/json" +``` + +下面的例子中,使用了 foreground 级联删除: +``` sh +kubectl proxy --port=8080 +curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \ + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \ + -H "Content-Type: application/json" +``` + +下面的例子中,使用 orphan 级联删除策略(不删除从属对象): +``` sh +kubectl proxy --port=8080 +curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \ + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \ + -H "Content-Type: application/json" +``` + +通过参数 `--cascade`,kubectl delete 命令也可以选择不同的级联删除策略: +* --cascade=true 级联删除 +* --cascade=false 不级联删除 orphan + +下面的例子中,删除 ReplicaSet 时,将不删除其从属对象: +``` sh +kubectl delete replicaset my-repset --cascade=false +``` diff --git a/learning/k8s-intermediate/workload/wl-statefulset/index.md b/learning/k8s-intermediate/workload/wl-statefulset/index.md index 5ce665d..6fb1872 100644 --- a/learning/k8s-intermediate/workload/wl-statefulset/index.md +++ b/learning/k8s-intermediate/workload/wl-statefulset/index.md @@ -28,7 +28,7 @@ StatefulSet 管理 Pod 时,确保其 Pod 有一个按顺序增长的 ID。 对于有如下要求的应用程序,StatefulSet 非常适用: * 稳定、唯一的网络标识(dnsname) -* 稳定、不变的持久化路径(或存储卷) +* 每个Pod始终对应各自的存储路径(PersistantVolumeClaimTemplate) * 按顺序地增加副本、减少副本,并在减少副本时执行清理 * 按顺序自动地执行滚动更新 diff --git a/learning/k8s-intermediate/workload/wl-ttl/index.md b/learning/k8s-intermediate/workload/wl-ttl/index.md index 890c4a5..ca8a4e3 100644 --- a/learning/k8s-intermediate/workload/wl-ttl/index.md +++ b/learning/k8s-intermediate/workload/wl-ttl/index.md @@ -11,4 +11,36 @@ meta: +> 参考文档: [TTL Controller for Finished Resources](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/) + +**FEATURE STATE:** `Kubernetes v1.12` alpha + +TTL(Time to Live)控制器可以限制已经结束执行的对象的存活时间,目前 TTL 控制器只处理 [Job](/learning/k8s-intermediate/workload/wl-job) 对象,将来可能增加对其他类型资源的支持,例如 Pod 和 Custom Resource。 + +Alpha 声明:此特性当前处于 alpha 状态,可以通过 [feature gate](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/) `TTLAfterFinished` 激活该特性。 + +[[TOC]] + + +## TTL 控制器 + +TTL控制器当前只支持 Job。集群管理员可以通过指定 Job 的 `.spec.ttlSecondsAfterFinished` 来自动清理已经结束的 Job(`Complete`或者`Failed`),参考例子 [Job的自动清理](/learning/k8s-intermediate/workload/wl-job/auto-cleanup.html)。TTL控制器将认为对象执行结束后超过 TTL 指定的时间,就可以被清理掉,TTL控制器将以 [级联删除](/learning/k8s-intermediate/workload/gc.html#垃圾收集器如何删除从属对象)(删除该对象及其从属对象)的方式将其删除。在删除对象时,其生命周期函数将被调用,例如 finalizer。 + +Job 的 `.spec.ttlSecondsAfterFinished` 任何时间都可以设置,例如: +* 在定义 Job 时指定该字段 +* 为已经结束执行的 Job 对象指定该字段 +* 在创建 Job 对象时,通过 [mutating admission webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks) 指定该字段。集群管理员可以通过这种方式为已结束的对象强制添加 TTL 策略 +* 在 Job 对象结束执行时,通过 [mutating admission webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks) 指定该字段,此时可以根据 Job 对象的状态、标签等信息为其指定不同的 TTL 值 + +## 警告 + +### 修改TTL值 + +在对象被创建或对象结束执行后,TTL值(例如 Job 的 `.spec.ttlSecondsAfterFinished` 字段)是可以被修改的。然而,一旦 Job 符合被清理的条件(TTL过期),系统将不再确保该 Job 被保留,即便此时您成功修改了 TTL 的值,也并不能使其保留更长的时间。 + +### 时间偏差Time Skew + +TTL 控制器使用对象的时间戳(timestamp)来决定该对象是否已经超过了 TTL 指定的时间,集群中的时间偏差对此特性的影响特别大,可能导致 TTL 控制器在一个错误的时间清理了对象。 + +在 Kubernetes 集群中,是要求所有节点运行 [NTP](https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E6%97%B6%E9%97%B4%E5%8D%8F%E8%AE%AE?fromtitle=NTP&fromid=1100433) 以避免时间偏差(time skew)的,参考 [#6159](https://github.com/kubernetes/kubernetes/issues/6159#issuecomment-93844058)。系统的时钟并非总是正确的,但是实际的差异会很小。在指定 TTL 值为 0 时,尤其要考虑这个因素的影响。 diff --git a/support/change-log/change-log-on-the-way.md b/support/change-log/change-log-on-the-way.md index cdad5a3..8f32a35 100644 --- a/support/change-log/change-log-on-the-way.md +++ b/support/change-log/change-log-on-the-way.md @@ -1,27 +1,15 @@ Kuboard v1.0.x 的更新说明 -## v1.0.4 +## v1.0.5-beta.1 **发布日期** -2019年11月?日 +2019年11月5日 **新特性** +* HostAliases -**优化** - -* 日志下载功能优化: - * 可指定起始时间 - * 可指定日志文件大小 - * 可显示下载进度 - * 可取消下载 -* 将监控套件的安装脚本从 github 迁移到 https://addons.kuboard.cn -* 进入终端界面前选择 sh / bash - -**BUG 修复** - -* 终端界面已经连接上以后,切换 sh / bash 失败的问题 * EndPoint @@ -29,7 +17,6 @@ Kuboard v1.0.x 的更新说明 * 表单校验:数据卷名不能带小数点 * Prometheus 监控 * 工作负载编辑器 --> 容器组 --> 容忍 -- 正在开发 -* HostAliases * Limit Range * 容器组列表,筛选结果为空时,提示筛选 “其他” diff --git a/support/change-log/v1.0.x.md b/support/change-log/v1.0.x.md index d3d5ba4..1aa4580 100644 --- a/support/change-log/v1.0.x.md +++ b/support/change-log/v1.0.x.md @@ -9,6 +9,27 @@ description: 本文描述了Kuboard_v1.0.x的版本变更说明 Kuboard v1.0.x 的更新说明 + +## v1.0.4 + +**发布日期** + +2019年11月5日 + +**优化** + +* 日志下载功能优化: + * 可指定起始时间 + * 可指定日志文件大小 + * 可显示下载进度 + * 可取消下载 +* 将监控套件的安装脚本从 github 迁移到 https://addons.kuboard.cn +* 进入终端界面前选择 sh / bash + +**BUG 修复** + +* 终端界面已经连接上以后,切换 sh / bash 失败的问题 + ## v1.0.4-beta.6 **发布日期**