Kubernetes 創(chuàng)建靜態(tài)Pod

2022-06-11 10:02 更新

創(chuàng)建靜態(tài) Pod

靜態(tài) Pod 在指定的節(jié)點(diǎn)上由 kubelet 守護(hù)進(jìn)程直接管理,不需要 API 服務(wù)器 監(jiān)管。 與由控制面管理的 Pod(例如,Deployment) 不同;kubelet 監(jiān)視每個(gè)靜態(tài) Pod(在它崩潰之后重新啟動(dòng))。

靜態(tài) Pod 永遠(yuǎn)都會(huì)綁定到一個(gè)指定節(jié)點(diǎn)上的 Kubelet。

kubelet 會(huì)嘗試通過(guò) Kubernetes API 服務(wù)器為每個(gè)靜態(tài) Pod 自動(dòng)創(chuàng)建一個(gè) 鏡像 Pod。 這意味著節(jié)點(diǎn)上運(yùn)行的靜態(tài) Pod 對(duì) API 服務(wù)來(lái)說(shuō)是可見(jiàn)的,但是不能通過(guò) API 服務(wù)器來(lái)控制。 Pod 名稱(chēng)將把以連字符開(kāi)頭的節(jié)點(diǎn)主機(jī)名作為后綴。

Note: 如果你在運(yùn)行一個(gè) Kubernetes 集群,并且在每個(gè)節(jié)點(diǎn)上都運(yùn)行一個(gè)靜態(tài) Pod, 就可能需要考慮使用 DaemonSet 替代這種方式。

Note: 靜態(tài) Pod 的 ?spec ?不能引用其他 API 對(duì)象 (如:ServiceAccount、 ConfigMap、 Secret 等)。

在開(kāi)始之前

你必須擁有一個(gè) Kubernetes 的集群,同時(shí)你的 Kubernetes 集群必須帶有 kubectl 命令行工具。 建議在至少有兩個(gè)節(jié)點(diǎn)的集群上運(yùn)行本教程,且這些節(jié)點(diǎn)不作為控制平面主機(jī)。 如果你還沒(méi)有集群,你可以通過(guò) Minikube 構(gòu)建一個(gè)你自己的集群,或者你可以使用下面任意一個(gè) Kubernetes 工具構(gòu)建:

要檢查版本,請(qǐng)輸入 ?kubectl version?。

本文假定你在使用 Docker 來(lái)運(yùn)行 Pod, 并且你的節(jié)點(diǎn)是運(yùn)行著 Fedora 操作系統(tǒng)。 其它發(fā)行版或者 Kubernetes 部署版本上操作方式可能不一樣。

創(chuàng)建靜態(tài) Pod 

可以通過(guò)文件系統(tǒng)上的配置文件 或者 web 網(wǎng)絡(luò)上的配置文件 來(lái)配置靜態(tài) Pod。

文件系統(tǒng)上的靜態(tài) Pod 聲明文件

聲明文件是標(biāo)準(zhǔn)的 Pod 定義文件,以 JSON 或者 YAML 格式存儲(chǔ)在指定目錄。路徑設(shè)置在 Kubelet 配置文件 的 ?staticPodPath: <目錄>? 字段,kubelet 會(huì)定期的掃描這個(gè)文件夾下的 YAML/JSON 文件來(lái)創(chuàng)建/刪除靜態(tài) Pod。 注意 kubelet 掃描目錄的時(shí)候會(huì)忽略以點(diǎn)開(kāi)頭的文件。

例如:下面是如何以靜態(tài) Pod 的方式啟動(dòng)一個(gè)簡(jiǎn)單 web 服務(wù):

  1. 選擇一個(gè)要運(yùn)行靜態(tài) Pod 的節(jié)點(diǎn)。在這個(gè)例子中選擇 ?my-node1?。
  2. ssh my-node1
    
  3. 選擇一個(gè)目錄,比如在 ?/etc/kubelet.d? 目錄來(lái)保存 web 服務(wù) Pod 的定義文件, ?/etc/kubelet.d/static-web.yaml?:
  4. # 在 kubelet 運(yùn)行的節(jié)點(diǎn)上執(zhí)行以下命令
    mkdir /etc/kubelet.d/
    cat <<EOF >/etc/kubelet.d/static-web.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: static-web
      labels:
        role: myrole
    spec:
      containers:
        - name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
    EOF
  5. 配置這個(gè)節(jié)點(diǎn)上的 kubelet,使用這個(gè)參數(shù)執(zhí)行 ?--pod-manifest-path=/etc/kubelet.d/?。 在 Fedora 上編輯 ?/etc/kubernetes/kubelet? 以包含下行:
  6. KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/"
    

    或者在 Kubelet 配置文件 中添加 ?staticPodPath: <目錄>?字段。

  7. 重啟 kubelet。Fedora 上使用下面的命令:
  8. # 在 kubelet 運(yùn)行的節(jié)點(diǎn)上執(zhí)行以下命令
    systemctl restart kubelet

Web 網(wǎng)上的靜態(tài) Pod 聲明文件

Kubelet 根據(jù) ?--manifest-url=<URL>? 參數(shù)的配置定期的下載指定文件,并且轉(zhuǎn)換成 JSON/YAML 格式的 Pod 定義文件。 與文件系統(tǒng)上的清單文件使用方式類(lèi)似,kubelet 調(diào)度獲取清單文件。 如果靜態(tài) Pod 的清單文件有改變,kubelet 會(huì)應(yīng)用這些改變。

按照下面的方式來(lái):

  1. 創(chuàng)建一個(gè) YAML 文件,并保存在 web 服務(wù)上,為 kubelet 生成一個(gè) URL。
  2. apiVersion: v1
    kind: Pod
    metadata:
      name: static-web
      labels:
        role: myrole
    spec:
      containers:
        - name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
  3. 通過(guò)在選擇的節(jié)點(diǎn)上使用 ?--manifest-url=<manifest-url>? 配置運(yùn)行 kubelet。 在 Fedora 添加下面這行到 ?/etc/kubernetes/kubelet? :
  4. KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<manifest-url>"
    
  5. 重啟 kubelet。在 Fedora 上運(yùn)行如下命令:
  6. # 在 kubelet 運(yùn)行的節(jié)點(diǎn)上執(zhí)行以下命令
    systemctl restart kubelet

觀察靜態(tài) pod 的行為 

當(dāng) kubelet 啟動(dòng)時(shí),會(huì)自動(dòng)啟動(dòng)所有定義的靜態(tài) Pod。 當(dāng)定義了一個(gè)靜態(tài) Pod 并重新啟動(dòng) kubelet 時(shí),新的靜態(tài) Pod 就應(yīng)該已經(jīng)在運(yùn)行了。

可以在節(jié)點(diǎn)上運(yùn)行下面的命令來(lái)查看正在運(yùn)行的容器(包括靜態(tài) Pod):

# 在 kubelet 運(yùn)行的節(jié)點(diǎn)上執(zhí)行以下命令
crictl ps

輸出可能會(huì)像這樣:

CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
129fd7d382018   docker.io/library/nginx@sha256:...    11 minutes ago    Running    web     0          34533c6729106

Note: ?crictl ?會(huì)輸出鏡像 URI 和 SHA-256 校驗(yàn)和。 ?NAME ?看起來(lái)像: ?docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31?。

可以在 API 服務(wù)上看到鏡像 Pod:

kubectl get pods
NAME         READY   STATUS    RESTARTS        AGE
static-web   1/1     Running   0               2m

Note: 要確保 kubelet 在 API 服務(wù)上有創(chuàng)建鏡像 Pod 的權(quán)限。如果沒(méi)有,創(chuàng)建請(qǐng)求會(huì)被 API 服務(wù)拒絕。

靜態(tài) Pod 上的標(biāo)簽 被傳到鏡像 Pod。 你可以通過(guò) 選擇算符 使用這些標(biāo)簽。

如果你用 ?kubectl ?從 API 服務(wù)上刪除鏡像 Pod,kubelet 不會(huì) 移除靜態(tài) Pod:

kubectl delete pod static-web
pod "static-web" deleted

可以看到 Pod 還在運(yùn)行:

kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
static-web   1/1     Running   0          4s

回到 kubelet 運(yùn)行的節(jié)點(diǎn)上,你可以手動(dòng)停止容器。 可以看到過(guò)了一段時(shí)間后 kubelet 會(huì)發(fā)現(xiàn)容器停止了并且會(huì)自動(dòng)重啟 Pod:

# 在 kubelet 運(yùn)行的節(jié)點(diǎn)上執(zhí)行以下命令
# 把 ID 換為你的容器的 ID
crictl stop 129fd7d382018
sleep 20
crictl ps
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
89db4553e1eeb   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106

動(dòng)態(tài)增加和刪除靜態(tài) pod 

運(yùn)行中的 kubelet 會(huì)定期掃描配置的目錄(比如例子中的 ?/etc/kubelet.d? 目錄)中的變化, 并且根據(jù)文件中出現(xiàn)/消失的 Pod 來(lái)添加/刪除 Pod。

# 前提是你在用主機(jī)文件系統(tǒng)上的靜態(tài) Pod 配置文件
# 在 kubelet 運(yùn)行的節(jié)點(diǎn)上執(zhí)行以下命令
mv /etc/kubelet.d/static-web.yaml /tmp
sleep 20
crictl ps
# 可以看到?jīng)]有 nginx 容器在運(yùn)行
mv /tmp/static-web.yaml  /etc/kubelet.d/
sleep 20
crictl ps
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
f427638871c35   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)