【云原生|Kubernetes】14-DaemonSet資源控制器詳解
簡介
? 在 Kubernetes 中,DaemonSet 是一種用于在節(jié)點上運行指定的 Pod 的控制器(Controller)。與 ReplicaSet 或 Deployment 不同,DaemonSet 不是為了擴展 Pod 數(shù)量而創(chuàng)建的,而是為了在每個節(jié)點上運行一個實例或多個實例的 Pod。
? DaemonSet 通常用于在 Kubernetes 集群中運行一些系統(tǒng)級別的服務(wù)或者網(wǎng)絡(luò)代理,例如日志收集器、監(jiān)控代理、網(wǎng)絡(luò)插件等。通過使用 DaemonSet,可以確保每個節(jié)點上都運行了指定的 Pod,從而保證了這些服務(wù)或者代理的高可用性和穩(wěn)定性。
? 與其他控制器類似,DaemonSet 也會監(jiān)視 Pod 的狀態(tài),并在 Pod 出現(xiàn)故障或者被刪除時自動進行替換。當(dāng)一個新的節(jié)點加入到 Kubernetes 集群中時,DaemonSet 也會自動在該節(jié)點上創(chuàng)建所需的 Pod。如果需要更新 DaemonSet 中的 Pod 版本或者配置,可以通過更新 DaemonSet 的 YAML 配置文件來實現(xiàn)。
? 需要注意的是,DaemonSet 中的 Pod 通常會創(chuàng)建在 kube-system 命名空間下,因為這些服務(wù)或者代理通常是與 Kubernetes 集群本身相關(guān)聯(lián)的。在創(chuàng)建 DaemonSet 時,可以使用 nodeSelector、tolerations 和 affinity 等方式來控制 DaemonSet 在哪些節(jié)點上運行、不在哪些節(jié)點上運行以及如何分配 Pod 到節(jié)點上。
典型用法
DaemonSet 的一些典型用法:
- 在每個節(jié)點上運行集群守護進程
- 在每個節(jié)點上運行日志收集守護進程
- 在每個節(jié)點上運行監(jiān)控守護進程
一種簡單的用法是為每種類型的守護進程在所有的節(jié)點上都啟動一個 DaemonSet。 一個稍微復(fù)雜的用法是為同一種守護進程部署多個 DaemonSet;每個具有不同的標(biāo)志, 并且對不同硬件類型具有不同的內(nèi)存、CPU 要求。
DaemonSet語法規(guī)則
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# 這些容忍度設(shè)置是為了讓該守護進程集在控制平面節(jié)點上運行
# 如果你不希望自己的控制平面節(jié)點運行 Pod,可以刪除它們
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
與所有其他 Kubernetes 配置一樣,DaemonSet 也需要 apiVersion
、kind
和 metadata
字段。DaemonSet 對象的名稱必須是一個合法的 DNS 子域名;DaemonSet 也需要 .spec
節(jié)區(qū)。
Pod模板
.spec
中唯一必需的字段是 .spec.template
。
.spec.template
是一個 Pod 模板。 除了它是嵌套的,因而不具有 apiVersion
或 kind
字段之外,它與 Pod 具有相同的 schema。
除了 Pod 必需字段外,在 DaemonSet 中的 Pod 模板必須指定合理的標(biāo)簽。
在 DaemonSet 中的 Pod 模板必須具有一個值為 Always
的 RestartPolicy
。 當(dāng)該值未指定時,默認(rèn)是 Always
。
Pod 選擇算符
.spec.selector
字段表示 Pod 選擇算符,它與 Job的 .spec.selector
的作用是相同的。
你必須指定與 .spec.template
的標(biāo)簽匹配的 Pod 選擇算符。 此外,一旦創(chuàng)建了 DaemonSet,它的 .spec.selector
就不能修改。 修改 Pod 選擇算符可能導(dǎo)致 Pod 意外懸浮,并且這對用戶來說是費解的。
spec.selector
是一個對象,如下兩個字段組成:
-
matchLabels
- 與 ReplicationController 的.spec.selector
的作用相同。 -
matchExpressions
- 允許構(gòu)建更加復(fù)雜的選擇器,可以通過指定 key、value 列表以及將 key 和 value 列表關(guān)聯(lián)起來的 Operator。
當(dāng)上述兩個字段都指定時,結(jié)果會按邏輯與(AND)操作處理。.spec.selector
必須與 .spec.template.metadata.labels
相匹配。 如果配置中這兩個字段不匹配,則會被 API 拒絕。
在選定的節(jié)點上運行 Pod
? 如果指定了 .spec.template.spec.nodeSelector
,DaemonSet 控制器將在能夠與 Node 選擇算符匹配的節(jié)點上創(chuàng)建 Pod。 類似這種情況,可以指定 .spec.template.spec.affinity
,之后 DaemonSet 控制器將在能夠與節(jié)點親和性匹配的節(jié)點上創(chuàng)建 Pod。 如果根本就沒有指定,則 DaemonSet Controller 將在所有節(jié)點上創(chuàng)建 Pod。
DaemonSet的 Pods 是如何被調(diào)度的
DaemonSet 確保所有符合條件的節(jié)點都運行該 Pod 的一個副本。 DaemonSet 控制器為每個符合條件的節(jié)點創(chuàng)建一個 Pod,并添加 Pod 的 spec.affinity.nodeAffinity
字段以匹配目標(biāo)主機。Pod 被創(chuàng)建之后,默認(rèn)的調(diào)度程序通常通過設(shè)置 .spec.nodeName
字段來接管 Pod 并將 Pod 綁定到目標(biāo)主機。如果新的 Pod 無法放在節(jié)點上,則默認(rèn)的調(diào)度程序可能會根據(jù)新 Pod 的優(yōu)先級搶占 (驅(qū)逐)某些現(xiàn)存的 Pod。
用戶通過設(shè)置 DaemonSet 的 .spec.template.spec.schedulerName
字段,可以為 DaemonSet 的 Pod 指定不同的調(diào)度程序。
當(dāng)評估符合條件的節(jié)點時,原本在 .spec.template.spec.affinity.nodeAffinity
字段上指定的節(jié)點親和性將由 DaemonSet 控制器進行考量,但在創(chuàng)建的 Pod 上會被替換為與符合條件的節(jié)點名稱匹配的節(jié)點親和性。
ScheduleDaemonSetPods
允許你使用默認(rèn)調(diào)度器而不是 DaemonSet 控制器來調(diào)度這些 DaemonSet, 方法是將 NodeAffinity
條件而不是 .spec.nodeName
條件添加到這些 DaemonSet Pod。 默認(rèn)調(diào)度器接下來將 Pod 綁定到目標(biāo)主機。 如果 DaemonSet Pod 的節(jié)點親和性配置已存在,則被替換 (原始的節(jié)點親和性配置在選擇目標(biāo)主機之前被考慮)。 DaemonSet 控制器僅在創(chuàng)建或修改 DaemonSet Pod 時執(zhí)行這些操作, 并且不會更改 DaemonSet 的 spec.template
。
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchFields:
- key: metadata.name
operator: In
values:
- target-host-name
在這個例子中,Pod 指定了一個 requiredDuringSchedulingIgnoredDuringExecution 的調(diào)度限制條件,要求 Pod 只能被調(diào)度到帶有標(biāo)簽 example-label 并且值為 example-value 的節(jié)點上運行。如果沒有符合條件的節(jié)點,Pod 就無法被調(diào)度到節(jié)點上運行。
requiredDuringSchedulingIgnoredDuringExecution 的調(diào)度限制條件,它可以用于指定必須滿足的調(diào)度要求。具體來說,requiredDuringSchedulingIgnoredDuringExecution 是一個 PodSpec 的字段,它包含一組要求,如果這些要求不能滿足,Pod 就無法被調(diào)度到節(jié)點上運行。
與其他調(diào)度限制條件不同,requiredDuringSchedulingIgnoredDuringExecution 是一個硬性要求,即如果不能滿足,Pod 就無法被調(diào)度到節(jié)點上運行。同時,該限制條件在 Pod 運行過程中仍然會被忽略,因此在節(jié)點上的運行狀態(tài)不會受到該限制條件的影響。
污點和容忍度
DaemonSet 控制器會自動將一組容忍度添加到 DaemonSet Pod。
容忍度鍵名 | 效果 | 描述 |
---|---|---|
node.kubernetes.io/not-ready |
NoExecute | DaemonSet Pod 可以被調(diào)度到不健康或還不準(zhǔn)備接受 Pod 的節(jié)點上。在這些節(jié)點上運行的所有 DaemonSet Pod 將不會被驅(qū)逐。 |
node.kubernetes.io/unreachable |
NoExecute | DaemonSet Pod 可以被調(diào)度到從節(jié)點控制器不可達的節(jié)點上。在這些節(jié)點上運行的所有 DaemonSet Pod 將不會被驅(qū)逐。 |
node.kubernetes.io/disk-pressure |
NoSchedule | DaemonSet Pod 可以被調(diào)度到具有磁盤壓力問題的節(jié)點上。 |
node.kubernetes.io/memory-pressure |
NoSchedule | DaemonSet Pod 可以被調(diào)度到具有內(nèi)存壓力問題的節(jié)點上。 |
node.kubernetes.io/memory-pressure |
NoSchedule | DaemonSet Pod 可以被調(diào)度到具有內(nèi)存壓力問題的節(jié)點上。 |
node.kubernetes.io/pid-pressure |
NoSchedule | DaemonSet Pod 可以被調(diào)度到具有進程壓力問題的節(jié)點上。 |
node.kubernetes.io/unschedulable |
NoSchedule | DaemonSet Pod 可以被調(diào)度到不可調(diào)度的節(jié)點上。 |
node.kubernetes.io/network-unavailable |
NoSchedule |
僅針對請求主機聯(lián)網(wǎng)的 DaemonSet Pod 添加此容忍度,即 Pod 具有 spec.hostNetwork: true 。這些 DaemonSet Pod 可以被調(diào)度到網(wǎng)絡(luò)不可用的節(jié)點上。 |
你也可以在 DaemonSet 的 Pod 模板中定義自己的容忍度并將其添加到 DaemonSet Pod。
因為 DaemonSet 控制器自動設(shè)置 node.kubernetes.io/unschedulable:NoSchedule
容忍度, 所以 Kubernetes 可以在標(biāo)記為不可調(diào)度的節(jié)點上運行 DaemonSet Pod。
如果你使用 DaemonSet 提供重要的節(jié)點級別功能, 例如集群聯(lián)網(wǎng), Kubernetes 在節(jié)點就緒之前將 DaemonSet Pod 放到節(jié)點上會很有幫助。 例如,如果沒有這種特殊的容忍度,因為網(wǎng)絡(luò)插件未在節(jié)點上運行,所以你可能會在未標(biāo)記為就緒的節(jié)點上陷入死鎖狀態(tài), 同時因為該節(jié)點還未就緒,所以網(wǎng)絡(luò)插件不會在該節(jié)點上運行。
DaemonSet更新和回滾
DaemonSet更新策略
DaemonSet 有兩種更新策略:
-
OnDelete
: 使用OnDelete
更新策略時,在更新 DaemonSet 模板后,只有當(dāng)你手動刪除老的 DaemonSet pods 之后,新的 DaemonSet Pod 才會被自動創(chuàng)建。跟 Kubernetes 1.6 以前的版本類似。 -
RollingUpdate
: 這是默認(rèn)的更新策略。使用RollingUpdate
更新策略時,在更新 DaemonSet 模板后, 老的 DaemonSet Pod 將被終止,并且將以受控方式自動創(chuàng)建新的 DaemonSet Pod。 更新期間,最多只能有 DaemonSet 的一個 Pod 運行于每個節(jié)點上。
執(zhí)行滾動更新
要啟用 DaemonSet 的滾動更新功能,必須設(shè)置 .spec.updateStrategy.type
為 RollingUpdate
。
-
updateStrategy.type (string)
守護進程集更新的類型。可以是 “RollingUpdate” 或 “OnDelete”。默認(rèn)為 RollingUpdate。
-
updateStrategy.rollingUpdate (RollingUpdateDaemonSet)
滾動更新配置參數(shù)。僅在 type 值為 “RollingUpdate” 時出現(xiàn)。
用于控制守護進程集滾動更新的預(yù)期行為的規(guī)約。
-
updateStrategy.rollingUpdate.maxSurge (
IntOrString
)對于擁有可用 DaemonSet Pod 的節(jié)點而言,在更新期間可以擁有更新后的 DaemonSet Pod 的最大節(jié)點數(shù)。 屬性值可以是絕對數(shù)量(例如:5)或所需 Pod 的百分比(例如:10%)。 如果 maxUnavailable 為 0,則該值不能為 0。絕對數(shù)是通過四舍五入從百分比計算得出的,最小值為 1。 默認(rèn)值為 0。示例:當(dāng)設(shè)置為 30% 時,最多為節(jié)點總數(shù)的 30% 節(jié)點上應(yīng)該運行守護進程 Pod (即 status.desiredNumberScheduled) 可以在舊 Pod 標(biāo)記為已刪除之前創(chuàng)建一個新 Pod。更新首先在 30% 的節(jié)點上啟動新的 Pod。 一旦更新的 Pod 可用(就緒時長至少 minReadySeconds 秒),該節(jié)點上的舊 DaemonSet pod 就會被標(biāo)記為已刪除。 如果舊 Pod 因任何原因變得不可用(Ready 轉(zhuǎn)換為 false、被驅(qū)逐或節(jié)點被騰空), 則會立即在該節(jié)點上創(chuàng)建更新的 Pod,而不考慮激增限制。 允許激增意味著如果就緒檢查失敗,任何給定節(jié)點上的守護進程集消耗的資源可能會翻倍, 因此資源密集型守護進程集應(yīng)該考慮到它們可能會在中斷期間導(dǎo)致驅(qū)逐。
IntOrString 是一種可以容納 int32 或字符串的類型。在 JSON 或 YAML 編組和解組中使用時,它會生成或使用內(nèi)部類型。 例如,這允許你擁有一個可以接受名稱或數(shù)字的 JSON 字段。
-
updateStrategy.rollingUpdate.maxUnavailable (IntOrString)
更新期間不可用的 DaemonSet Pod 的最大數(shù)量。值可以是絕對數(shù)(例如:5)或更新開始時 DaemonSet Pod 總數(shù)的百分比(例如:10%)。 絕對數(shù)是通過四舍五入的百分比計算得出的。如果 maxSurge 為 0,則此值不能為 0 默認(rèn)值為 1。 例如:當(dāng)設(shè)置為 30% 時,最多節(jié)點總數(shù) 30% 的、應(yīng)該運行守護進程的節(jié)點總數(shù)(即 status.desiredNumberScheduled) 可以在任何給定時間停止更新。更新首先停止最多 30% 的 DaemonSet Pod, 然后在它們的位置啟動新的 DaemonSet Pod。 一旦新的 Pod 可用,它就會繼續(xù)處理其他 DaemonSet Pod,從而確保在更新期間至少 70% 的原始 DaemonSet Pod 數(shù)量始終可用。
IntOrString 是一種可以保存 int32 或字符串的類型。在 JSON 或 YAML 編組和解組中使用時,它會生成或使用內(nèi)部類型。例如,這允許你擁有一個可以接受名稱或數(shù)字的 JSON 字段。
-
-
revisionHistoryLimit (int32)
用來允許回滾而保留的舊歷史記錄的數(shù)量。此字段是個指針,用來區(qū)分明確的零值和未指定的指針。默認(rèn)值是 10。
- 下面的 YAML 包含一個 DaemonSet,其更新策略為 ‘RollingUpdate’:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
annotations:
kubernetes.io/change-cause: "fluentd version is latest"
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# 這些容忍度設(shè)置是為了讓該守護進程集在控制平面節(jié)點上運行
# 如果你不希望自己的控制平面節(jié)點運行 Pod,可以刪除它們
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
## 用于指定 Pod 被刪除后等待多長時間再強制終止。
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- 創(chuàng)建DaemonSet的Pod
[root@master daemonset]# kubectl apply -f fluentd-daemonset.yaml
daemonset.apps/fluentd-elasticsearch configured
[root@master daemonset]#
- 查看daemonset和pod
[root@master daemonset]# kubectl get daemonset -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd-elasticsearch 3 3 3 3 3 <none> 14m
[root@master daemonset]#
[root@master daemonset]# kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fluentd-elasticsearch-bjh69 1/1 Running 0 2m35s 10.244.0.51 192.168.194.128 <none> <none>
fluentd-elasticsearch-j59h8 1/1 Running 0 2m33s 10.244.1.112 192.168.194.130 <none> <none>
fluentd-elasticsearch-jnvfk 1/1 Running 0 2m26s 10.244.2.162 192.168.194.131 <none> <none>
[root@master daemonset]#
- 檢查 DaemonSet 的滾動更新策略
[root@master daemonset]# kubectl get ds/fluentd-elasticsearch -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' -n kube-system
RollingUpdate
[root@master daemonset]#
- 更新DaemonSet
[root@master daemonset]# kubectl edit -n kube-system ds fluentd-elasticsearch
daemonset.apps/fluentd-elasticsearch edited
[root@master daemonset]#
對DaemonSet執(zhí)行回滾
在創(chuàng)建Daploymen,DaemonSet等等可以回滾的資源類型的時候,一定要添加
annotations
信息,該信息是你定義資源簡介的,便于你分辨該資源是做什么的,用的鏡像版本,等等。metadata: name: fluentd-elasticsearch annotations: kubernetes.io/change-cause: "fluentd version is latest"
- 查看DaemonSet使用的鏡像版本
[root@master daemonset]# kubectl -n kube-system get ds fluentd-elasticsearch -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
fluentd-elasticsearch 3 3 2 1 2 <none> 2m23s fluentd-elasticsearch quay.io/fluentd_elasticsearch/fluentd:v2.5.2 name=fluentd-elasticsearch
[root@master daemonset]#
- 查看DaemonSet的歷史版本
[root@master daemonset]# kubectl -n kube-system rollout history ds fluentd-elasticsearch
daemonset.apps/fluentd-elasticsearch
REVISION CHANGE-CAUSE
1 fluentd version is latest
2 fluentd version is 2.6.0
3 fluentd version is 2.5.2
[root@master daemonset]#
說明: 注意 DaemonSet 修訂版本只會正向變化。也就是說,回滾完成后,所回滾到的
ControllerRevision
版本號 (.revision
字段) 會增加。 例如,如果用戶在系統(tǒng)中有版本 1 和版本 2,并從版本 2 回滾到版本 1, 帶有.revision: 1
的ControllerRevision
將變?yōu)?.revision: 3
。文章來源:http://www.zghlxwxcb.cn/news/detail-643604.html
- –to-revision指導(dǎo)回滾到指定版本
說明: 如果
--to-revision
參數(shù)未指定,將選中最近的版本。文章來源地址http://www.zghlxwxcb.cn/news/detail-643604.html
[root@master daemonset]# kubectl -n kube-system rollout undo --to-revision=1 ds fluentd-elasticsearch
daemonset.apps/fluentd-elasticsearch rolled back
[root@master daemonset]#
- 再次確認(rèn)版本(回滾正常)
[root@master daemonset]# kubectl -n kube-system get ds fluentd-elasticsearch -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
fluentd-elasticsearch 3 3 3 3 3 <none> 5m31s fluentd-elasticsearch quay.io/fluentd_elasticsearch/fluentd name=fluentd-elasticsearch
[root@master daemonset]#
到了這里,關(guān)于【云原生|Kubernetes】14-DaemonSet資源控制器詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!