自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Kubernetes中的多容器Pod和Pod內(nèi)容器間通信

云計算
容器(Container)常被用來解決比如微服務(wù)的單個問題,但在實際場景中,問題的解決往往需要多容器方案。本文會討論將多個容器整合進單個Kubernetes Pod 中,以及Pod中的容器之間是如何通信的。

 容器(Container)常被用來解決比如微服務(wù)的單個問題,但在實際場景中,問題的解決往往需要多容器方案。本文會討論將多個容器整合進單個Kubernetes Pod 中,以及Pod中的容器之間是如何通信的。

[[282920]]

1. 關(guān)于Kubernetes Pod

1.1 Kubernetes Pod 是什么?

首先我們來探討下什么是Pod。Pod是Kubernetes中最小的可部署和管理單元。換句話講,如果需要在Kubernetes中運行單個容器,那么你就得為這個容器創(chuàng)建一個Pod。同時,一個Pod可以包含多個容器,這些容器往往是緊耦合的。怎么樣個緊耦合法呢?試著想象這么一個場景,一個Pod中的多個容器代表需要運行在同一個服務(wù)器上的多個進程。這種類比是合理的,因為在許多方面,Pod就類似于一臺服務(wù)器。比如,通過localhost每個容器可以訪問它所在Pod中的其它容器。

1.2 為什么Kubernetes將Pod而不是單個容器作為最小可部署單元呢?

盡管直接部署單個容器也許會更容易,但增加Pod這個新的抽象層會帶來新的好處。容器是一個真實存在的實體,它代表一個具體的東西。這個“東西”可以是一個Docker容器,也可以是一個rkt容器。每種“東西”都有不同的用途。為了管理容器,Kubernetes需要更多的信息,比如重啟策略(restart policy),它定義了當(dāng)容器終止了時怎樣重啟容器;還有活性檢測(liveness probe),它定義了如何從應(yīng)用視角去檢測容器中的進程是否活著,比如Web服務(wù)器進程是否能響應(yīng)HTTP請求。

為了避免在容器這個已有的實體上增加這些新的屬性,Kubernetes架構(gòu)師們決定使用一個新的實體,那就是Pod。它邏輯地包含一個或多個容器。

1.3 為什么Kubernetes允許Pod中存在一個或多個容器?

Pod中的容器們運行在一個邏輯“主機”上。他們使用同一個網(wǎng)絡(luò)命名空間(network namespace,換句話講,就是同樣的IP地址和端口空間),以及同樣的IPC(inter-process communication,進程間通信)命名空間,他們還使用共享卷(shared volume)。這些特征使得Pod內(nèi)的容器能互相高效地通信。同時,Pod使得你可以將多個緊耦合的應(yīng)用容器當(dāng)做一個實體來管理。

那么,如果一個應(yīng)用需要在同一臺服務(wù)器上運行多個容器,為什么不把所有東西放在一個容器里面呢?好吧,首先,這會違反“一個容器一個進程”規(guī)范。這個規(guī)范很重要,因為當(dāng)一個容器中有多個進程時,調(diào)試會變得非常困難,因為不同進程的日志會混在一起,而且很難去管理這些進程的生命周期。其次,為一個應(yīng)用使用多個容器會更簡單、更直接、能解耦軟件依賴。而且,更細粒度的容器可以在團隊間復(fù)用。

1.4 多容器Pod的用例

多容器Pod的主要目的是為了支持同時存在的(co-located)及同時被管理的(co-managed)幫助進程(helper process)。幫助進程有幾種通用場景:

邊車容器(sidecarcontainer):比如日志或數(shù)據(jù)變化監(jiān)視器等。一個團隊創(chuàng)建日志監(jiān)視器(log watcher)后,它可以被各種應(yīng)用使用。另一個邊車容器的例子是文件或數(shù)據(jù)加載器,它負責(zé)為主容器產(chǎn)生數(shù)據(jù)。

代理(Proxy)、橋(bridge)和適配器(adapter):它們將主容器連接到外部世界。比如,Apache HTTP 服務(wù)器或nginx 會讀取靜態(tài)文件。它們還能被用作主容器中的web應(yīng)用的反向代理(reverseproxy)。

當(dāng)你在Pod中運行多層應(yīng)用(比如WordPress)時,推薦的方式是為每層使用單獨的Pod。最簡單的理由是這樣你就可以獨立地擴展每層,并將他們分布在不同節(jié)點上。

2. Pod 中容器間的通信

在Pod中運行多個容器,使得它們之間的通信非常直接。他們自己的通信有幾種方法。

2.1 通過共享卷通信

在Kubernetes中,Pod中的容器可以將共享卷當(dāng)做一種簡單和高效的共享數(shù)據(jù)方式。在大多數(shù)場景中,使用主機上的一個目錄,并在多個容器間共享,是一種高效的方式。

Kubernetes volume(卷)使得在容器重啟后數(shù)據(jù)能被保存下來。卷具有和Pod一樣的生命周期。這意味著,只要Pod存在,卷就存在。如果Pod被刪除了,即使一模一樣的Pod被創(chuàng)建出來,原來Pod的共享卷也會被銷毀,一個新的共享卷會被創(chuàng)建出來。

Pod中的多個容器使用共享卷的一個標(biāo)準(zhǔn)用例是,當(dāng)一個容器向共享目錄寫入日志或其它文件時,其它容器從共享目錄中讀取數(shù)據(jù)。比如我們創(chuàng)建一個下面的Pod:

  1. apiVersion: v1 
  2. kind: Pod 
  3. metadata: 
  4.  name: mc1 
  5. spec: 
  6.  volumes: 
  7.   -name: html 
  8.    emptyDir: {} 
  9.  containers: 
  10.   -name: 1st 
  11.    image: nginx 
  12.    volumeMounts: 
  13.     -name: html 
  14.      mountPath: /usr/share/nginx/html 
  15.   -name: 2nd 
  16.    image: debian 
  17.    volumeMounts: 
  18.     -name: html 
  19.      mountPath: /html 
  20.    command: ["/bin/sh""-c"
  21.    args: 
  22.      - while true; do 
  23.          date >> /html/index.html; 
  24.          sleep 1; 
  25.        done 

本例中,定義了一個名為html的卷。它的類型是 emptyDir,這意味著當(dāng)Pod被分配到一個節(jié)點上時,卷會被基于一個空目錄創(chuàng)建出來,只要該Pod一直運行著,這個卷就會一直存在。1st容器運行nginx服務(wù)器,它將共享卷掛載到/usr/share/nginx/html 目錄。2nd容器使用Debian鏡像,它將共享卷掛載到 /html目錄。每秒鐘,2nd容器會將當(dāng)前日期和時間寫入到共享卷之中的index.html文件。當(dāng)用戶向Pod發(fā)送HTTP請求時,Nginx讀取這個文件的內(nèi)容并返回給用戶。

 

你可以通過暴露nginx端口或使用瀏覽器訪問它來檢查該Pod,或者直接查看容器額共享目錄:

  1. $ kubectl exec mc1 -c 1st -- /bin/cat/usr/share/nginx/html/index.html 
  2.  ... 
  3.  FriAug 25 18:36:06 UTC 2019 
  4.   
  5.  $kubectl exec mc1 -c 2nd -- /bin/cat /html/index.html 
  6.  ... 
  7.  FriAug 25 18:36:06 UTC 2019 
  8.  FriAug 25 18:36:07 UTC 2019 

2.2 進程間通信(Inter-processCommunication,IPC)

Pod中的容器共享同一個IPC命名空間,這意味著它們可以使用標(biāo)準(zhǔn)的進程間通信方式來互相通信,比如SystemV信號量和POSIX共享內(nèi)存。

在下面的例子中,我們會定義一個包含兩個容器的Pod。它們使用同樣的鏡像。第一個容器是生產(chǎn)者(producer),它會創(chuàng)建一個標(biāo)準(zhǔn)的Linux消息隊列,并向該隊列中寫入一些隨機字符串,最后寫入一個特定的退出字符。第二個容器是消費者(consumer),它打開同一個隊列,讀取字符,直到讀到特殊的退出字符為止。我們將Pod的重啟策略設(shè)置為“Never”,因此在兩個容器都終止后Pod會停止。

  1. apiVersion: v1 
  2. kind: Pod 
  3. metadata: 
  4.  name: mc2 
  5. spec: 
  6.  containers: 
  7.   -name: producer 
  8.    image: allingeek/ch6_ipc 
  9.    command: ["./ipc""-producer"
  10.   -name: consumer 
  11.    image: allingeek/ch6_ipc 
  12.    command: ["./ipc""-consumer"
  13.  restartPolicy: Never 

Pod 運行后,查看每個容器的日志,確認2nd容器收到了1st容器的全部消息,包括特定的退出消息:

  1. $ kubectl logs mc2 -c producer 
  2. ... 
  3. Produced: f4 
  4. Produced: 1d 
  5. Produced: 9e 
  6. Produced: 27 
  7. $ kubectl logs mc2 -c consumer 
  8. ... 
  9. Consumed: f4 
  10. Consumed: 1d 
  11. Consumed: 9e 
  12. Consumed: 27 
  13. Consumed: done 

 

默認情況下,Pod中的所有容器都是并行啟動的,因為沒有辦法去指定一個容器在另一個容器啟動后才啟動。比如,在IPC例子中,有可能第二個容器在第一個容器啟動完成并創(chuàng)建消息隊列前就啟動完畢了。此時,第二個容器會失敗,因此它需要消息隊列在其啟動時就已經(jīng)存在了。

有一些方法去控制容器的啟動順序,比如 Kubernetes Init Containers(初始化容器),初始化容器會被首先啟動。但是在云原生環(huán)境中,最好能為所有不可控的失敗都做好準(zhǔn)備。比如,要修復(fù)上述問題,最好的辦法是修改應(yīng)用去等待,直到消息隊列被創(chuàng)建出來為止。

2.3 容器間的網(wǎng)絡(luò)通信

Pod中的容器可以通過“localhost”來互相通信,因為他們使用同一個網(wǎng)絡(luò)命名空間。而且,對容器來說,hostname就是Pod的名稱。因為Pod中的所有容器共享同一個IP地址和端口空間,你需要為每個需要接收連接的容器分配不同的端口。也就是說,Pod中的應(yīng)用需要自己協(xié)調(diào)端口的使用。

在下面的例子中,我們會創(chuàng)建一個多容器Pod,其中一個容器中運行Nginx,它作為另一個容器中運行的web應(yīng)用的反向代理。

(1)步驟1,為nginx配置文件創(chuàng)建一個ConfigMap。從80端口進來的HTTP請求會被轉(zhuǎn)發(fā)到localhost上的5000端口。

  1. apiVersion: v1 
  2. kind: ConfigMap 
  3. metadata: 
  4.  name: mc3-nginx-conf 
  5. data: 
  6.  nginx.conf: |- 
  7.    user  nginx; 
  8.    worker_processes  1; 
  9.   
  10.    error_log /var/log/nginx/error.log warn; 
  11.    pid        /var/run/nginx.pid; 
  12.   
  13.    events { 
  14.        worker_connections  1024; 
  15.     } 
  16.   
  17.    http { 
  18.        include      /etc/nginx/mime.types; 
  19.        default_type application/octet-stream; 
  20.   
  21.        sendfile        on
  22.        keepalive_timeout  65; 
  23.   
  24.        upstream webapp { 
  25.            server 127.0.0.1:5000; 
  26.        } 

(2)步驟2:創(chuàng)建一個兩容器Pod,一個容器運行nginx,另一個容器運行簡單的web應(yīng)用。注意我們只為Pod定義了80端口。端口5000不能被從Pod外部訪問到。

  1. apiVersion: v1 
  2. kind: Pod 
  3. metadata: 
  4.  name: mc3 
  5.  labels: 
  6.    app: mc3 
  7. spec: 
  8.  containers: 
  9.   -name: webapp 
  10.    image: training/webapp 
  11.   -name: nginx 
  12.    image: nginx:alpine 
  13.    ports: 
  14.     -containerPort: 80 
  15.    volumeMounts: 
  16.     -name: nginx-proxy-config 
  17.      mountPath: /etc/nginx/nginx.conf 
  18.      subPath: nginx.conf 
  19.  volumes: 
  20.   -name: nginx-proxy-config 
  21.    configMap: 
  22.      name: mc3-nginx-conf 

查看pod中的端口空間,能看到有80 和 5000端口。

  1. # netstat -lntp 
  2. Active Internet connections (only servers) 
  3. Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name 
  4. tcp       0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -               
  5. tcp       0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN      1/python 

(3)步驟3:將Pod暴露為一個 NodePort服務(wù)

  1. $ kubectl expose pod mc3 --type=NodePort--port=80 
  2. service "mc3" exposed 

(4)步驟4:確認服務(wù)

  1. [root@master1 ~]# kubectl describe svc mc3 
  2. Name:                    mc3 
  3. Namespace:               testproject 
  4. Labels:                   app=mc3 
  5. Annotations:              <none> 
  6. Selector:                  app=mc3 
  7. Type:                     NodePort 
  8. IP:                       172.30.34.232 
  9. Port:                     <unset>  80/TCP 
  10. TargetPort:                80/TCP 
  11. NodePort:                 <unset>  32728/TCP 
  12. Endpoints:                10.130.0.190:80 
  13. Session Affinity:           None 
  14. External Traffic Policy:      Cluster 
  15. Events:                   <none> 

現(xiàn)在,就可以使用瀏覽器或者curl工具來訪問這個web應(yīng)用了。

  1. [root@master1 ~]# curl 10.70.209.68:32728 
  2. Hello world! 

nginx容器的80端口上收到的HTTP請求會被轉(zhuǎn)發(fā)到web應(yīng)用容器的5000端口。

 

上面的例子只展示了在Pod中一個容器去訪問其它容器,實際上,更常見的是Pod中的多個容器會在不同的端口上監(jiān)聽,所有這些端口都會被暴露出去。要實現(xiàn)這種形式,要么你創(chuàng)建一個暴露多個端口的服務(wù),要么為每個要被暴露的端口創(chuàng)建一個服務(wù)。

3. 小結(jié)

通過創(chuàng)建Pod概念,Kubernetes為編排容器的行為以及容器間互相通信都提供了極大的便利。容器們可以共享存儲卷,以及可以通過網(wǎng)絡(luò)甚至IPC互相通信。

原文:https://www.mirantis.com/blog/multi-container-pods-and-container-communication-in-kubernetes/

 

原文作者:Pavel Chekin

責(zé)任編輯:武曉燕 來源: 大魏分享
相關(guān)推薦

2021-11-22 08:00:00

Kubernetes容器集群

2020-07-06 07:52:10

Kubernetes網(wǎng)絡(luò)通信

2021-09-14 13:25:23

容器pod僵尸進程

2022-06-01 09:38:36

KubernetesPod容器

2024-01-02 09:19:15

kubernetes集群HTTP

2023-07-04 07:30:03

容器Pod組件

2024-03-07 12:08:02

Podkubernetes容器

2022-05-26 07:33:48

Pod容器debug

2022-04-26 05:55:13

容器K8s管理debug問題

2023-02-09 16:47:34

KubernetesPod優(yōu)先級

2023-10-19 19:42:25

IstioPodkubernetes

2021-04-14 09:33:58

Kubernetes通信網(wǎng)絡(luò)模型

2020-04-10 08:00:08

Kubernetes補丁pod

2024-06-19 09:33:05

2022-09-22 12:11:38

PodKubernetes

2022-06-21 14:46:52

KubernetesPODMultus

2019-03-22 14:38:03

容器安全隔離

2022-04-09 15:26:46

Kubernetes刪除操作源碼解析

2020-11-30 12:15:26

KubernetesPodLinux

2024-04-26 06:43:19

KubernetesPod識別
點贊
收藏

51CTO技術(shù)棧公眾號