寫在前面
- 學習
遇到整理筆記k8s
- 感覺不管是
還是dev
,離不開生命周期,鈎子,守護程序這些,還是要看看底層的東西.ops
-
可以了解為特殊的DeamonSet
,即確定每個節點隻運作一個ReplicaSet
的pod副本
pod Set
-
與叢集中nodes節點的周期相同生命周期
- 類似 系統中的守護程序
等systemd
人生真難,但不配讓我認輸 ---沃金(知乎)
*
daemonset
DaemonSet
確定全部節點上運作一個 Pod 的副本。 當有節點加入叢集時, 也會為他們新增一個
Pod
。 當有節點從叢集移除時,這些
Pod
也會被回收。删除
DaemonSet
将會删除它建立的所有
Pod
。即單執行個體,每個節點隻跑一個
pod
DaemonSet
應用場景
DaemonSet
DaemonSet 的一些典型用法:
- 在每個Node上運作一個
或者GlusterFS存儲
Ceph存儲
Daemon程序
-
,例如日志采集程式
Fluentd
.Logstach
-
,采集該性能監控程式
Node
運作性能資料
,PrometheusNode Exporter
, New Relic agent或者Ganglia gmond等。collectd
一種簡單的用法是為每種類型的守護程序在所有的節點上都啟動一個 DaemonSet。 一個稍微複雜的用法是為同一種守護程序部署多個 DaemonSet;每個具有不同的标志, 并且對不同硬體類型具有不同的記憶體、CPU 要求。這句話不太懂,以後再研究下
DaemonSet
Pod排程政策
與
RC類似
,除了使用系統内置的算法在每台Node上進行排程,也可以在
Pod
的定義中使用
NodeSelector
或
NodeAffinity
來指定滿足條件的
Node
範圍進行排程。
學習環境準備
┌──[[email protected]]-[~/ansible]
└─$dir=k8s-daemonset-create;mkdir $dir;cd $dir
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl config current-context
kubernetes-admin@kubernetes
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl create ns liruilong-dameonset-create
namespace/liruilong-dameonset-create created
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl config set-context $(kubectl config current-context) --namespace=liruilong-daemonset-create
Context "kubernetes-admin@kubernetes" modified.
kubeadm中的deamonset
使用kubeadm安裝的k8s環境中是使用的DaemonSet,calico是網路相關,所有節點都需要有,kube-proxy是代理相關,用于負載均衡等操作
┌──[[email protected]]-[~/ansible/k8s-ReplicationController]
└─$kubectl get ds -A
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system calico-node 3 3 3 3 3 kubernetes.io/os=linux 4d23h
kube-system kube-proxy 3 3 3 3 3 kubernetes.io/os=linux 4d23h
┌──[[email protected]]-[~/ansible/k8s-ReplicationController]
└─$
Demonset的建立
這裡要說明的是
deamonset
和
deployment
隻有在
kind
的位置不同,可以拷貝
deployment
的模闆進行修改
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
labels:
app: myds1
name: myds1
spec:
#replicas: 1
selector:
matchLabels:
app: myds1
#strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: myds1
spec:
containers:
- image: nginx
name: nginx
resources: {}
#status: {}
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl create deployment myds1 --image=nginx --dry-run=client -o yaml > deamonset.yaml
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$vim deamonset.yaml
我們建立一個deamonset,目前隻有master節點和一個node節點正常工作
因為master節點有污點,是以會發現這裡隻允許一個deamonset
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl apply -f deamonset.yaml
daemonset.apps/myds1 created
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl get nodes
NAME STATUS ROLES AGE VERSION
vms81.liruilongs.github.io Ready control-plane,master 4d22h v1.22.2
vms82.liruilongs.github.io Ready <none> 4d22h v1.22.2
vms83.liruilongs.github.io NotReady <none> 4d22h v1.22.2
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl get pods
NAME READY STATUS RESTARTS AGE
myds1-fbmhp 1/1 Running 0 35s
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$
節點加入叢集自動新增節點pod
我們在啟動一台機器,會發現,新加入的
vms83.liruilongs.github.io
節點自動運作一個deamonset
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl get nodes
NAME STATUS ROLES AGE VERSION
vms81.liruilongs.github.io Ready control-plane,master 4d22h v1.22.2
vms82.liruilongs.github.io Ready <none> 4d22h v1.22.2
vms83.liruilongs.github.io Ready <none> 4d22h v1.22.2
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl get pods
NAME READY STATUS RESTARTS AGE
myds1-prldj 1/1 Running 0 6m13s
myds1-pvwm4 1/1 Running 0 10m
Deamonset污點節點加入pod
下面我們從新修改deamonset資源檔案,容忍有污點的節點
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
labels:
app: myds1
name: myds1
spec:
#replicas: 1
selector:
matchLabels:
app: myds1
#strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: myds1
spec:
terminationGracePeriodSeconds: 0
tolerations:
- operator: Exists
containers:
- image: nginx
name: nginx
resources: {}
#status: {}
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl apply -f deamonsettaint.yaml
daemonset.apps/myds1 created
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl get pods
NAME READY STATUS RESTARTS AGE
myds1-8tsnz 0/1 ContainerCreating 0 3s
myds1-9l6d9 0/1 ContainerCreating 0 3s
myds1-wz44b 0/1 ContainerCreating 0 3s
會發現每個節點都運作一個deamontset相關的pod
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl describe nodes vms81.liruilongs.github.io | grep Taint
Taints: node-role.kubernetes.io/master:NoSchedule
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl run pod1 --image=nginx --dry-run=server -o yaml | grep -A 6 terminationGracePeriodSeconds
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
當然,如果我們不想是以有污點的節點都運作deamonset相關pod,那麼我們可以使用另一種指定kye的方式
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
labels:
app: myds1
name: myds1
spec:
selector:
matchLabels:
app: myds1
template:
metadata:
creationTimestamp: null
labels:
app: myds1
spec:
terminationGracePeriodSeconds: 0
tolerations:
- operator: Exists
key: node-role.kubernetes.io/master
effect: "NoSchedule"
containers:
- image: nginx
name: nginx
resources: {}
會發現deamonset可以運作在master和node節點
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl apply -f deamonsetaint.yaml
daemonset.apps/myds1 created
┌──[[email protected]]-[~/ansible/k8s-daemonset-create]
└─$kubectl get pods
NAME READY STATUS RESTARTS AGE
myds1-f7hbb 0/1 ContainerCreating 0 4s
myds1-hksp9 0/1 ContainerCreating 0 4s
myds1-nnmzp 0/1 ContainerCreating 0 4s
Daemon Pods 是如何被排程的
DaemonSet
確定所有符合條件的節點都運作該 Pod 的一個副本。 通常,運作
Pod
的節點由
Kubernetes
排程器選擇。 不過,
DaemonSet Pods
由
DaemonSet
控制器建立和排程。這就帶來了以下問題:
Pod 行為的不一緻性:正常 Pod 在被建立後等待排程時處于 Pending 狀态, DaemonSet Pods 建立後不會處于 Pending 狀态下。
Pod 搶占 由預設排程器處理。啟用搶占後,DaemonSet 控制器将在不考慮 Pod 優先級和搶占 的情況下制定排程決策。這裡的預設排程器即k8s中排程器。
允許您使用預設排程器而不是
ScheduleDaemonSetPods
控制器來排程
DaemonSet
方法是将
DaemonSets,
條件而不是
NodeAffinity
條件添加到
.spec.nodeName
。 預設排程器接下來将
DaemonSet Pods
Pod
綁定到目标主機。
如果
的節點親和性配置已存在,則被替換 (原始的節點親和性配置在選擇目标主機之前被考慮)。
DaemonSet Pod
控制器僅在建立或修改
DaemonSet
時執行這些操作, 并且不會更改
DaemonSet Pod
DaemonSet
。
spec.template
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchFields:
- key: metadata.name
operator: In
values:
- target-host-name
與 Daemon Pods 通信
DaemonSet 中的 Pod 進行通信的幾種可能模式如下: |
---|
:配置 DaemonSet 中的 Pod,将更新發送到另一個服務,例如統計資料庫。 這些服務沒有用戶端。 |
:DaemonSet 中的 Pod 可以使用 hostPort,進而可以通過節點 IP 通路到 Pod。用戶端能通過某種方法擷取節點 IP 清單,并且基于此也可以擷取到相應的端口。 |
Pod 選擇算符的 無頭服務, 通過使用 endpoints 資源或從 DNS 中檢索到多個 A 記錄來發現 DaemonSet。 |
:建立具有相同 Pod 選擇算符的服務,并使用該服務随機通路到某個節點上的 守護程序(沒有辦法通路到特定節點)。 |
更新 DaemonSet
如果節點的标簽被修改,DaemonSet 将立刻向新比對上的節點添加 Pod, 同時删除不比對的節點上的 Pod。你可以修改 DaemonSet 建立的 Pod。不過并非 Pod 的所有字段都可更新。 下次當某節點(即使具有相同的名稱)被建立時,DaemonSet 控制器還會使用最初的模闆。
你可以修改
DaemonSet
建立的 Pod。不過并非
Pod
的所有字段都可更新。 下次當某節點(即使具有相同的名稱)被建立時,DaemonSet 控制器還會使用最初的模闆。
您可以删除一個 DaemonSet。如果使用 kubectl 并指定 --cascade=orphan 選項, 則 Pod 将被保留在節點上。接下來如果建立使用相同選擇算符的新 DaemonSet, 新的 DaemonSet 會收養已有的 Pod。 如果有 Pod 需要被替換,DaemonSet 會根據其 updateStrategy 來替換。
DaemonSet 的替代方案
init 腳本
直接在節點上啟動守護程序(例如使用
init、upstartd
systemd
)的做法當然是可行的。 不過,基于
DaemonSet
來運作這些程序有如下一些好處:
- 像所運作的其他應用一樣,
具備為守護程序提供監控和日志管理的能力。DaemonSet
- 為守護程序和應用所使用的配置語言和工具(如 Pod 模闆、kubectl)是相同的。
- 在資源受限的容器中運作守護程序能夠增加守護程序和應用容器的隔離性。 然而,這一點也可以通過在容器中運作守護程序但卻不在 Pod 中運作之來實作。 例如,直接基于 Docker 啟動。
裸 Pod
直接建立
Pod
并指定其運作在特定的節點上也是可以的。 然而,DaemonSet 能夠替換由于任何原因(例如節點失敗、例行節點維護、核心更新) 而被删除或終止的
Pod
。 由于這個原因,你應該使用 DaemonSet 而不是單獨建立 Pod。
靜态 Pod
通過在一個指定的、受
kubelet
監視的目錄下編寫檔案來建立
Pod
也是可行的。 這類
Pod
被稱為靜态 Pod。 不像
DaemonSet
,靜态 Pod 不受
kubectl
和其它
Kubernetes API
用戶端管理。 靜态 Pod 不依賴于 API 伺服器,這使得它們在啟動引導新叢集的情況下非常有用。 此外,靜态 Pod 在将來可能會被廢棄。
Deployments
DaemonSet
Deployments
非常類似, 它們都能建立 Pod,并且
Pod
中的程序都不希望被終止(例如,Web 伺服器、存儲伺服器)。建議為無狀态的服務使用
Deployments
,比如前端服務。 對這些服務而言,對副本的數量進行擴縮容、平滑更新,比精确控制 Pod 運作在某個主機上要重要得多。 當需要
Pod
副本總是運作在全部或特定主機上,并且當該
DaemonSet
提供了節點級别的功能(允許其他 Pod 在該特定節點上正确運作)時, 應該使用
DaemonSet。
例如,網絡插件通常包含一個以
DaemonSet
運作的元件。 這個
DaemonSet
元件確定它所在的節點的叢集網絡正常工作
┌──[[email protected]]-[~/ansible/k8s-ReplicationController]
└─$kubectl get ds -A
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system calico-node 3 3 3 3 3 kubernetes.io/os=linux 4d23h
kube-system kube-proxy 3 3 3 3 3 kubernetes.io/os=linux 4d23h
┌──[[email protected]]-[~/ansible/k8s-ReplicationController]
└─$