diff --git a/.vuepress/config-sidebar.js b/.vuepress/config-sidebar.js
index bd1c7b2..2a803eb 100644
--- a/.vuepress/config-sidebar.js
+++ b/.vuepress/config-sidebar.js
@@ -206,6 +206,8 @@ module.exports = {
'k8s-intermediate/workload/wl-job/cleanup',
'k8s-intermediate/workload/wl-job/auto-cleanup',
'k8s-intermediate/workload/wl-job/pattern',
+ 'k8s-intermediate/workload/wl-job/usage',
+ 'k8s-intermediate/workload/wl-job/when',
]
}
]
diff --git a/learning/k8s-intermediate/workload/wl-job/index.md b/learning/k8s-intermediate/workload/wl-job/index.md
index 407833b..b7eb119 100644
--- a/learning/k8s-intermediate/workload/wl-job/index.md
+++ b/learning/k8s-intermediate/workload/wl-job/index.md
@@ -11,6 +11,8 @@ meta:
+> 参考文档: [Jobs - Run to Completion](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/)
+
Kubernetes中的 Job 对象将创建一个或多个 Pod,并确保指定数量的 Pod 可以成功执行到进程正常结束:
diff --git a/learning/k8s-intermediate/workload/wl-job/spec.md b/learning/k8s-intermediate/workload/wl-job/spec.md
index 56d854a..62975f8 100644
--- a/learning/k8s-intermediate/workload/wl-job/spec.md
+++ b/learning/k8s-intermediate/workload/wl-job/spec.md
@@ -31,7 +31,7 @@ Job 对象的 YAML 文件,还需要一个 `.spec` 字段。
## Pod Selector
-`.spec.selector` 字段是可选的。绝大部分情况下,您不需要指定该字段。
+`.spec.selector` 字段是可选的。绝大部分情况下,您不需要指定该字段。只有在少数情况下,您才需要这样做,请参考 [Job 的特殊操作](./usage.html)
## Parallel Jobs
diff --git a/learning/k8s-intermediate/workload/wl-job/usage.md b/learning/k8s-intermediate/workload/wl-job/usage.md
new file mode 100644
index 0000000..fec7c4f
--- /dev/null
+++ b/learning/k8s-intermediate/workload/wl-job/usage.md
@@ -0,0 +1,62 @@
+---
+vssueId: 151
+layout: LearningLayout
+description: Kubernetes中的Job对象将创建一个或多个Pod_并确保指定数量的Pod可以成功执行到进程正常结束_本文描述Job相关的特殊操作
+meta:
+ - name: keywords
+ content: Kubernetes培训,K8S教程,K8S培训,Kubernetes Job
+---
+
+# Job的特殊操作
+
+
+
+
+
+在创建 Job 时,系统默认将为其指定一个 `.spec.selector` 的取值,并确保其不会与任何其他 Job 重叠。
+
+在少数情况下,您仍然可能需要覆盖这个自动设置 `.spec.selector` 的取值。在做此项操作时,您必须十分小心:
+* 如果指定的 `.spec.selector` 不能确定性的标识出该 Job 的 Pod,并可能选中无关的 Pod (例如,selector 可能选中其他控制器创建的 Pod),则:
+ * 与该 Job 不相关的 Pod 可能被删除
+ * 该 Job 可能将不相关的 Pod 纳入到 `.spec.completions` 的计数
+ * 一个或多个 Job 可能不能够创建 Pod,或者不能够正常结束
+* 如果指定的 `.spec.selector` 不是唯一的,则其他控制器(例如,Deployment、StatefulSet 等)及其 Pod 的行为也将难以预测
+
+在 Kubernetes 中,系统并不能帮助你避免此类型的错误,您需要自己关注所指定的 `.spec.selector` 的取值是否合理。
+
+让我们来看一个实际使用 `.spec.selector` 的例子:假设 Job `old` 已经运行,您希望已经创建的 Pod 继续运行,但是您又想要修改该 Job 的 名字,同时想要使该 Job 新建的 Pod 使用新的 template。此时您不能够修改已有的 Job 对象,因为这些字段都是不可修改的。此时,您可以执行命令 `kubectl delete jobs/old --cascade=false`,以删除 Job `old` 但是保留其创建的 Pod。
+
+* 在删除之前,先记录 Job `old` 的 selector,执行命令:
+ ``` sh
+ kubectl get job old -o yaml
+ ```
+ 输出结果如下所示:
+ ``` yaml {8}
+ kind: Job
+ metadata:
+ name: old
+ ...
+ spec:
+ selector:
+ matchLabels:
+ controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
+ ...
+ ```
+
+* 创建新的 Job `new`,并使用已有的 selector。由于已创建的 Pod 带有标签 `controller-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`,这些 Pod 也将被新的 Job `new` 所管理。使用类似如下的 yaml 文件创建 Job `new`:
+ ``` yaml {6,9}
+ kind: Job
+ metadata:
+ name: new
+ ...
+ spec:
+ manualSelector: true
+ selector:
+ matchLabels:
+ controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
+ ...
+ ```
+ ::: tip
+ * 当您不使用系统自动创建的 `.spec.selector` 时,需要在 Job `new` 中指定 `.spec.manualSelector: true`
+ * 新建的 Job `new` 其 uid 将不同于 `a8f3d00d-c6d2-11e5-9f87-42010af00002`。设置 `.spec.manualSelector: true` 意味着,您知道这个设定是有意为之,系统将使用您指定的 `.spec.selector`,而不是使用 Job `new` 的 uid 作为 `.spec.selector` 的取值
+ :::
diff --git a/learning/k8s-intermediate/workload/wl-job/when.md b/learning/k8s-intermediate/workload/wl-job/when.md
new file mode 100644
index 0000000..2b44906
--- /dev/null
+++ b/learning/k8s-intermediate/workload/wl-job/when.md
@@ -0,0 +1,43 @@
+---
+vssueId: 151
+layout: LearningLayout
+description: Kubernetes中的Job对象将创建一个或多个Pod_并确保指定数量的Pod可以成功执行到进程正常结束_本文描述Job有哪些替代选项
+meta:
+ - name: keywords
+ content: Kubernetes培训,K8S教程,K8S培训,Kubernetes Job
+---
+
+# Job的替代选项
+
+
+
+
+
+## 直接创建的Pod(Bare Pod)
+
+当 Pod 所在的节点重启或者出现故障,Pod 将被终止,且不会被自动重启。如果使用 Job,则 Job 控制器将会创建新的 Pod 以替代已经故障节点上的 Pod。基于此原因,即使您的应用实际只需要一个 Pod 执行某项任务,仍然推荐您使用 Job,而不是直接创建 Pod。
+
+## Replication Controller
+
+Job 是对 [Replication Controller](https://kubernetes.io/docs/user-guide/replication-controller)、[Deployment](/learning/k8s-intermediate/workload/wl-deployment/) 的一种有效补充。Replication Controller 和 Deployment 用来管理那些我们期望其一直运行的应用(例如,web server),Job 则用于管理那些我们期望其执行并结束的应用(例如,批处理任务)
+
+
+参考 [Pod容器组的生命周期](/learning/k8s-intermediate/workload/pod-lifecycle.html), Job 的 Pod 中,`RestartPolicy` 必须为 `OnFailure` 或者 `Never`。(如果不设定 `RestartPolicy`,其默认值为 `Always`)
+
+## 通过Job启动控制器Pod
+
+存在这样一种操作模式:使用一个 Job 创建一个 Pod,该 Pod 接着创建其他的 Pod,并作为一种自定义的[控制器](/learning/k8s-bg/architecture/controller.html) 来管理这些 Pod。这种做法提供了最大程度的自由度和灵活性,但是某种程度上,非常难以上手,且与 Kubernetes 的相关度不高。
+
+这种模式的一个例子有:某个 Job 创建一个 Pod,该 Pod 执行一段脚本,在脚本中:
+* 启动 Spark master controller(参考 [spark example](https://github.com/kubernetes/examples/tree/master/staging/spark/README.md))
+* 运行 spark driver
+* 执行清理操作
+
+这种做法的优点在于,通过 Job 可以确保整个过程最终能够完成执行,但是您需要自己编写脚本,以控制应该创建什么样的 Pod,如何在 Pod 上分配执行任务。
+
+> 此做法不是 [Operator 模式](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/),但是与之有相似之处。
+
+
+## Cron Jobs
+
+可以使用 [CronJob](/learning/k8s-intermediate/workload/wl-cronjob/) 来创建 Job,与 Unix/Linux 工具 `cron` 相似,CronJob 将在指定的日期和时间执行。