成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Kubernetes中的Pause容器到底是干嘛的

云計算 云原生
那為啥使用 kubectl create 或 kubectl apply 等命令創建Pod時,通常不會顯式地看到Pause容器。這是因為Pause容器是由Kubernetes自動創建和管理的,通常不需要用戶手動操作或關注。它是Pod的一個隱式組成部分,用于維護Pod的基礎設施和容器之間的網絡隔離。

引言

Kubernetes出現的報錯如下:

Failed to create pod sandbox: rpc error: code = Unknown desc = failed to get sandbox image "k8s.gcr.io/pause:3.5": failed to pull image "k8s.gcr.io/pause:3.5": failed to pull and unpack image "k8s.gcr.io/pause:3.5": failed to resolve reference "k8s.gcr.io/pause:3.5": failed to do request: Head "https://k8s.gcr.io/v2/pause/manifests/3.5": x509: certificate signed by unknown authority

k8s.gcr.io 這個地址是需要連外網才可以拉取到,導致 pause 鏡像拉不下來,Pod無法啟動。以前都沒關注過 pause 這個容器,它是啥,做什么用的,怎么在 Pod 里沒看到過他,本文將帶你了解 pause 容器。

Pause容器是個啥

在Kubernetes中,Pod是最小的調度單元,但它的內部結構卻充滿了許多復雜的機制,其中之一就是Pause容器。盡管Pause容器看似不起眼,但它在整個Kubernetes集群中發揮了至關重要的作用。我們在 kubernetes 的 node 節點,執行 docker ps,可以發現每個 node 上都運行了一個 pause進程的容器,具體如下:

[root@localhost ~]# docker ps |grep traefik
66032431a20e   2ae1addee1b2                                                     "/entrypoint.sh --gl…"   30 hours ago     Up 30 hours               k8s_traefik_traefik-68b9ccfc77-x8sqg_traefik_aa5b97bf-3db8-4b92-89a7-1fe551645e6a_0
10d393461904   registry.aliyuncs.com/google_containers/pause:3.5                "/pause"                 30 hours ago     Up 30 hours               k8s_POD_traefik-68b9ccfc77-x8sqg_traefik_aa5b97bf-3db8-4b92-89a7-1fe551645e6a_0

會發現有很多 pause 容器運行于服務器上面,容器命名也很規范,然后每次啟動一個容器,都會伴隨一個pause這樣的容器啟動。那它究竟是干啥子的?它就是 Pause 容器,又叫 Infra 容器。我們在部署完 kubernetes 集群后,查看 kubelet 進程,可以看到配置中有這樣一個參數:

[root@localhost ~]# ps -ef|grep kubelet
root      8675     1 10 Sep18 ?        03:15:07 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.5

pause 容器使用的鏡像為 registry.aliyuncs.com/google_containers/pause:3.5  該鏡像非常小,只有 683kB,由于它總是處于 Pause (暫時)狀態,所以取名叫 pause

[root@localhost ~]# docker images|grep pause
registry.aliyuncs.com/google_containers/pause                     3.5        ed210e3e4a5b   2 years ago     683kB

想了解該 pause 容器的構成(代碼是用 C 語言寫的)的可以去官方倉庫上一看究竟:https://github.com/kubernetes/kubernetes/tree/master/build/pause

Pause容器的作用

  1. 網絡命名空間隔離:Pod是Kubernetes中最小的調度單元,可以包含一個或多個容器。為了實現容器之間的網絡隔離,每個Pod都有自己獨立的網絡命名空間。Pause容器負責創建并維護這個網絡命名空間,其他容器共享這個網絡命名空間,使它們能夠相互通信,而不會與其他Pod中的容器發生沖突。
  2. 進程隔離:Pause容器保持一個輕量級的進程運行,即使Pod中的其他容器都停止了。這個進程實際上不執行任何有用的工作,但它的存在確保了Pod不會在沒有容器運行的情況下被刪除。當其他容器停止時,Pause容器仍在運行,以維持Pod的生命周期。
  3. 資源隔離:盡管Pause容器通常不分配大量的CPU和內存資源,但它可以配置以使用一些資源。這有助于確保即使Pod中沒有其他容器運行時,Kubernetes仍然可以監控和管理Pod的資源使用情況。這也有助于防止Pod被其他具有相同資源要求的Pod占用。
  4. IP地址維護:Pause容器負責維護Pod的IP地址。Pod的IP地址通常是動態分配的,但由于Pause容器一直在運行,它可以維護Pod的IP地址,以便其他容器可以通過該地址進行通信。這有助于確保Pod的IP地址在整個Pod的生命周期內保持一致。
  5. 生命周期管理:Pause容器的生命周期與Pod的生命周期相同。當Pod創建時,Pause容器被創建;當Pod刪除時,Pause容器也會被刪除。這確保了Pod的整個生命周期都由Kubernetes進行管理,包括創建、擴展、縮放和刪除。

Pause容器工作原理

一個 Pod 可以由一組容器組成的,這些容器之間共享存儲和網絡資源,那么網絡資源是如何共享的呢?下面是個例子:

圖片圖片

比如說現在有一個 Pod,其中包含了一個容器 A 和一個容器 B,它們兩個就要共享 Network Namespace。在 Kubernetes 里的解法是這樣的:它會在每個 Pod 里,額外起一個 Infra container 小容器來共享整個 Pod 的 Network Namespace。Infra container 是一個非常小的鏡像,大概 683kB,是一個C語言寫的、永遠處于“暫停”狀態的容器。由于有了這樣一個 Infra container 之后,其他所有容器都會通過 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。所以說一個 Pod 里面的所有容器,它們看到的網絡視圖可以說是完全一樣的。即:它們看到的網絡設備、IP地址、Mac地址等等,跟網絡相關的信息,其實全是一份,這一份都來自于 Pod 第一次創建的這個 Infra container。這就是 Pod 解決網絡共享的一個解法。在 Pod 里面,一定有一個 IP 地址,是這個 Pod 的 Network Namespace 對應的地址,也是這個 Infra container 的 IP 地址。所以大家看到的都是一份,而其他所有網絡資源,都是一個 Pod 一份,并且被 Pod 中的所有容器共享。這就是 Pod 的網絡實現方式。由于需要有一個相當于說中間的容器存在,所以整個 Pod 里面,必然是 Infra container 第一個啟動。并且整個 Pod 的生命周期是等同于 Infra container 的生命周期的,與容器 A 和 B 是無關的。這是非常重要的一個設計。kubernetes的pause容器主要為每個業務容器提供兩個核心功能:

  • 第一,它提供整個pod的Linux命名空間的基礎。
  • 第二,啟用PID命名空間,它在每個pod中都作為PID為1的進程,并回收僵尸進程。

手工模擬Pod

我們已經知道,一個 Pod 從表面上來看至少由一個容器組成,而實際上一個 Pod 至少要有包含兩個容器,一個是應用容器,一個是 pause 容器。運行一個pause容器:

[root@localhost ~]# docker run -d --name pause -p 8080:80 registry.aliyuncs.com/google_containers/pause:3.5
fd315974f5d1a5f52ca47c5dc31aea3774cebf90c88ce065cc9e9ea2f52c103c
  • --name:指定 pause 容器的名字,pause
  • -p 8080:80:將宿主機的 8080 端口映射到容器的 80 端口

運行一個nginx容器,代理 127.0.0.1:8888 springboot應用程序

# 準備nginx配置文件
[root@k8s001 ~]# cat <<EOF >> nginx.conf
error_log stderr;
events { worker_connections  1024; }
http {
    server {
        listen 80 default_server;
        server_name www.kubesre.com;
        location / {
            proxy_pass http://127.0.0.1:8888;
        }
    }
}
EOF
 
# 創建nginx容器
[root@localhost ~]# docker run -d --name nginx -v `pwd`/nginx.conf:/etc/nginx/nginx.conf --net=container:pause --ipc=container:pause --pid=container:pause --ipc=shareable nginx
fa9f858adae826ad536178747e00fffc829c7baf98c3bc29e945230abbf2a5cb
  • --net=container:pause:用于與另一個容器共享網絡命名空間。在這種情況下,容器 "nginx" 會與名為 "pause" 的容器共享網絡命名空間,它們可以使用相同的網絡配置和接口。
  • --ipc=container:pause:用于與另一個容器共享 IPC 命名空間。IPC 命名空間允許容器之間進行進程間通信(Inter-Process Communication),在這里,容器 "nginx" 與名為 "pause" 的容器共享 IPC 命名空間。
  • --pid=container:pause:用于與另一個容器共享 PID 命名空間。PID 命名空間允許容器查看和管理其他容器的進程。
  • --ipc=shareable:指示 IPC 命名空間是可共享的,以便其他容器也可以加入到這個共享命名空間中。

創建一個應用容器 springboot

[root@localhost ~]# docker run -d --name springboot --net=container:pause --ipc=container:pause --pid=container:pause --ipc=shareable registry.cn-shanghai.aliyuncs.com/kubesre02/springboot
e33cfa3cebd5aafa714ca6ef0f6a16be52a282c64b8d24b2d98890ccf02c436a

到這里,我們就純手工模擬出了一個符合 K8S Pod 模型的 “Pod” ,只是它并不由 K8S 進行管理。驗證,查看運行的容器

[root@localhost ]~# docker ps | grep -E "pause|nginx|springboot"
4f877cdcba5d   registry.cn-shanghai.aliyuncs.com/kubesre02/springboot   "java -jar /app.jar"     3 seconds ago   Up 2 seconds                                               springboot
e541dc010fb3   nginx                                                    "/docker-entrypoint.…"   19 hours ago    Up 19 hours                                                nginx
09f94a052d50   registry.aliyuncs.com/google_containers/pause:3.5        "/pause"                 19 hours ago    Up 19 hours    0.0.0.0:8080->80/tcp, :::8080->80/tcp       pause

通過瀏覽器訪問 http://ip:8080 端口

[root@localhost ~]# curl http://localhost:8080
Hello Docker World

從上面的步驟可見:

  • pause容器將內部80端口映射到宿主機8080端口。
  • pause容器在宿主機上設置好網絡namespace后,nginx容器加入到該網絡的namespace中。
  • nginx容器啟動的時候指定了-net=container:pause。
  • springboot 容器啟動時,同樣方式加入到該網絡的namespace中。
  • 這樣三個容器共享了網絡,互相之間就可以使用localhost直接通信。
  • --ipc=container:pause,--pid=container:pause就是三個容器的ipc和pid處于同一個namespace中,init進程為pause。

這里,我們進入springboot 容器內部查看:

[root@localhost ~]# /tmp/test# docker exec -it springboot sh
/ # ps aux
PID   USER     TIME   COMMAND
    1 65535      0:00 /pause
  205 root       0:22 java -jar /app.jar
  240 root       0:00 nginx: master process nginx -g daemon off;
  261 101        0:00 nginx: worker process
  263 root       0:00 sh
  269 root       0:00 ps aux

在springboot 容器中可以看到pause和nginx容器的進程,并且pause容器的PID為1,而在kubernetes中容器的PID=1的進程則為容器本身的業務進程。

如果沒有 K8S 的 Pod ,啟動一個 業務容器,你需要手動創建三個容器,當你想銷毀這個服務時,同樣需要刪除三個容器。而有了 K8S 的 Pod,這三個容器在邏輯上就是一個整體,創建 Pod 就會自動創建三個容器,刪除 Pod 就會刪除三個容器,從管理上來講,方便了不少。

這正是 Pod 存在的一個根本意義所在。

如何回收僵尸進程

在Linux中,PID命名空間中的進程是一個樹型結構,每個進程有一個父進程。在樹的根上只有一個進程沒有真正的父進程。這是init進程,其PID為1。

僵尸進程是指已經停止運行但它們的進程表條目仍然存在的進程,在UNIX系統中,一個子進程結束了,但是它的父進程沒有等待(調用wait/waitpid)它,那么它將變成一個僵尸進程。

僵尸進程是怎么產生的?

出現僵尸進程的一種情況是:父進程編寫得很糟糕,省略了wait調用,或者父進程意外崩潰在子進程之前死亡,而新的父進程沒有調用wait。當一個進程的父進程在子進程之前死亡時,操作系統將該子進程分配給init進程或PID 1的進程。即init進程接納子進程并成為其父進程。這意味著,現在當子進程退出時,新的父進程(init)必須調用wait來獲取它的退出碼,否則它的進程表條目將永遠保留下來,成為僵死進程。

在Kubernetes pod中,容器的運行方式與上述基本相同,但是為每個pod創建了一個特殊的pause容器。

這個pause容器運行了一個非常簡單的進程,它不執行任何函數,本質上永遠休眠,其源碼實現:

/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
 
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
 
static void sigdown(int signo) {
  psignal(signo, "Shutting down, got signal");
  exit(0);
}
 
static void sigreap(int signo) {
  while (waitpid(-1, NULL, WNOHANG) > 0);
}
 
int main() {
  if (getpid() != 1)
    /* Not an error because pause sees use outside of infra containers. */
    fprintf(stderr, "Warning: pause should be the first process\n");
 
  if (sigaction(SIGINT, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
    return 1;
  if (sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
    return 2;
  if (sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap,
                                             .sa_flags = SA_NOCLDSTOP},
                NULL) < 0)
    return 3;
 
  for (;;)
    pause();
  fprintf(stderr, "Error: infinite loop terminated\n");
  return 42;
}

從上述代碼種我們可以發現,pause容器不僅僅調用pause()使進程休眠,還擁有另外一個重要的功能:

它假定自己為PID 1的角色,當僵尸進程被其父進程孤立時,會被pause容器進行收養,通過調用wait來獲取僵尸進程。這樣一來就不會在Kubernetes pod的PID命名空間中堆積僵尸進程了。

那為啥使用 kubectl create 或 kubectl apply 等命令創建Pod時,通常不會顯式地看到Pause容器。這是因為Pause容器是由Kubernetes自動創建和管理的,通常不需要用戶手動操作或關注。它是Pod的一個隱式組成部分,用于維護Pod的基礎設施和容器之間的網絡隔離。

不難想到,這其中的過程是非常復雜的。而且我們還沒有深入探討如何去監控和管理這些容器的生命周期。但是不用擔心,我們不需要這么復雜的去管理我們的容器,因為kubernetes已經都為我們做好了。

責任編輯:武曉燕 來源: 云原生運維圈
相關推薦

2022-02-16 20:04:08

容器KubernetesShim

2022-04-10 19:26:07

TypeScript類型語法

2024-02-22 08:00:00

SoraOpenAI

2022-08-08 08:00:00

人工智能機器學習計算機應用

2020-10-25 20:05:29

Pythonyield開發

2024-07-12 15:08:23

Python@wraps函數

2024-08-26 14:23:56

2024-03-15 08:06:58

MySQLJOIN命令

2022-04-15 08:54:39

PythonAsync代碼

2022-05-24 17:00:41

區塊鏈IT比特幣

2018-07-30 11:27:12

云服務

2010-04-02 16:46:43

云計算

2019-05-28 13:50:27

MySQL幻讀數據庫

2020-08-19 07:48:11

云計算亞馬遜搜索

2013-04-24 09:08:17

Google眼鏡

2023-12-15 07:23:39

電子管半導體芯片集成電路

2018-05-03 15:03:09

內存虛擬化空間

2021-08-13 05:47:48

通信設計院通信行業設計院

2022-08-12 08:03:59

算力網絡算力網絡

2024-01-16 23:30:46

?fractionsPython分數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩视频在线播放 | 午夜成人免费视频 | 免费在线观看av网址 | 少妇精品亚洲一区二区成人 | 久久精品在线 | 久久69精品久久久久久国产越南 | 一区二区中文 | 国产一区二区三区在线 | 在线播放日韩 | 亚洲三级在线观看 | 免费国产视频在线观看 | 久久综合婷婷 | 日韩高清国产一区在线 | 国产精品96久久久久久 | 高清久久久 | 91麻豆产精品久久久久久夏晴子 | 三级黄色片在线观看 | 乳色吐息在线观看 | 免费黄色的视频 | 狠狠干天天干 | 欧美mv日韩mv国产网站91进入 | 亚洲精品久久久蜜桃 | 欧美极品在线 | 日韩成人在线看 | 欧美精品1区2区3区 免费黄篇 | 国产亚洲精品久久久久动 | 国产一区二 | 免费亚洲网站 | 日韩中文字幕在线视频 | 99在线免费视频 | 日本一级淫片免费啪啪3 | 亚洲欧美国产一区二区三区 | 久久久久精| 久久国产精品99久久久大便 | 亚洲国产黄 | 久久久久久亚洲国产精品 | 午夜精品一区二区三区在线 | 亚洲一二三在线观看 | 国精日本亚洲欧州国产中文久久 | 91亚洲精品久久久电影 | 在线观看成人精品 |