帶着問題學 Kubernetes 基本單元 Pod

帶着問題學 Kubernetes 基本單元 Pod

摘要:本文屬於原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/bloghtml

當前環境

  1. Mac OS 10.11.xgit

  2. kubectl == v1.6.4github

  3. minikube == v0.19.1web

  4. docker == 1.11.1docker

要點

  • 使用 minikube 本地搭建 K8Sapi

  • 證實每一個 Pod 都有一個 Pause服務器

  • Pod 的基本使用網絡

  • Pod 生命週期的各類狀態架構

  • Pod 的管理問題

  • Pod 的多容器場景

  • Pod 的數據共享問題

  • Pod 的網絡共享的實現原理

準備工做

關於 minikue 的安裝,官方文檔已經和詳盡了,這裏就不講了。

  • 啓動 minikube(minikube 是一個能讓 K8S 本地運行的工具

minikube start \
--vm-driver=xhyve \
--docker-env HTTP_PROXY=http://your-http-proxy-host:your-http-proxy-port  \
--docker-env HTTPS_PROXY=http(s)://your-https-proxy-host:your-https-proxy-port

稍微解釋下 --vm-driver=xhyve,若是早期有在 Mac 上安裝 docker 的同窗,應該知道 docker 會在你的電腦上安裝一個 VirtualBox 的虛擬驅動。由於 docker 支持的只有 Linux 系統,爲了讓它能在 Mac 上運行,其實是運行由 VirtualBox 運行的虛擬環境下的。--vm-driver 默認的參數也是 VirtualBox。再來看 xhyve,它實際和 VirtualBox 相似,簡單理解,它是一個更輕量的虛擬技術。

若是 docker 下載 gcr.io 鏡像有困難的話,建議配置 docker 代理(這裏推薦一個 多態代理)。另外一種取巧的方式是,先將所需的鏡像經過 docker hub 下載下來,再經過 docker tag 的方式來進行重命名。

  • 配置本機的 docker 環境

上面也說了,K8S 是運行在 xhyve 創建的虛擬環境下。因此本地的 docker 命令是沒法鏈接到 K8S 所依賴的 docker-daemon 的。固然,你能夠經過 minikube ssh 進入虛擬環境,再使用 docker 命令進行觀察。

更直觀的是,經過 eval $(minikube docker-env) 將本地 docker 與 K8S 依賴的 docker 進行綁定。這樣在本地就能夠經過 docker 命令觀察 K8S 中的容器變化了。

eval $(minikube docker-env -u) 取消與 minikube 中的 docker 進行綁定。

minikube 初始狀態

好了,K8S 已經成功運行起來了。咱們下面來初步觀察一下當前 Pod 的運行狀況,同時也驗證一下上一篇所說的「一個 Pod 一個 Pause」的真僞了。

  • 查看 K8S 上全部命名空間下的 Pod(剛啓動的話,可能須要必定時間來拉取相應的鏡像。

kubectl get pods --all-namespaces


<center>圖1</center>

能夠看到 K8S 一共啓動了3個 Pod,而且都是在 kube-system 命名空間下的。具體這3 個 Pod 的做用,你們唉看名字應該能猜到一點,不在本文介紹範圍內。

  • 驗證每一個 Pod 內都會運行一個 Pause 容器

docker ps


<center>圖2</center>

從圖中能夠看出,確實運行着3個 pause 容器。同時運行着5個容器,數字也與圖1中 READY 的總數一致(1+3+1)。

Pod

Q1:如何運行和查看 Pod 信息?

先以命令式的方式進行啓動,這也是最簡單的啓動方式,但不建議用於生產環境。(後面會涉及以配置文件進行部署。

kubectl run nginx --image=nginx

注意:在不指定命名空間時,默認爲 default,其餘指令基本都是如此。

是否是和docker run的命令很像,輕鬆上手。咱們看一下運行狀況。


<center>圖3</center>

圖中顯示,deployment 已經被建立。能夠把它看做是 Pod 的管理者,是 controller-manager 中的一員(後面還會講到)。

kubectl get deploy


<center>圖4</center>

查看 Pod 列表

kubectl get pods


<center>圖5</center>

查看指定 Pod 的詳細描述

kubectl describe pod $POD_NAME


<center>圖6</center>

Q2:Pod 的生命週期中所經歷的狀態有哪些?

從圖5中能夠看出,Pod 當前的狀態是 Running,若是本身嘗試的話,可能會遇到其餘狀態。由於 Pod 所處的生命週期的階段可能不同。

下面常見的有這幾種:

  • Pending:Pod 定義正確,提交到 Master,但其包含的容器鏡像還未徹底建立。一般處在 Master 對 Pod 的調度過程當中。

  • ContainerCreating:Pod 的調度完成,被分配到指定 Node 上。處於容器建立的過程當中。一般是在拉取鏡像的過程當中。

  • Running:Pod 包含的全部容器都已經成功建立,而且成功運行起來。

  • Successed:Pod 中全部容器都成功結束,且不會被重啓。這是 Pod 的一種最終狀態。

  • Failed:Pod 中全部容器都結束,但至少一個容器以失敗狀態結束。這也是 Pod 的一種最終狀態。

Q3:如何保證 Pod 正常運行?

從上面的各類狀態可知,因爲種種緣由,Pod 可能處於上述狀態的任何一種。對於異常的狀態,K8S 是經過一種指望值與當前值的比對機制,來保證 Pod 的正常運行。其內部是經過 replicaset(下一代 ReplicationController) 作到的。

kubectl get rs


<center>圖7</center>

觀察 replicaset 發現,存在一個 nginx-xxx 的 replicaset,它的指望值與當前值都爲1,表示須要一個 Pod,而且已經處於 READY 狀態。

但是咱們並無直接的建立過它。並且通常也不會直接去使用它。咱們一般會使用上層的 Deployment 來進行調用,由於它還提供了一些其餘的特性,如更新與回滾。

驗證:當手動刪除 Pod 時,Deployment 會自動建立一個新的 Pod,來確保與指望值的匹配。

kubectl delete pod $POD_NAME


<center>圖8</center>

*Deployment 相較 ReplicationController 而言,除了提供 ReplicationController 的基本功能,還支持聲明式的更新和回滾。
不過目前仍是 beta 版。*

Q4:如何正確刪除 Pod ?

經過上述驗證,咱們直接刪除 Pod後,依然會建立新的 Pod,這是它的保障機制。咱們只有刪除它的上層管理者,即 deployment,那麼由它產生的 replicaset 和 Pod 會自動刪除。

kubectl delete deploy $DEPLOY_NAME


<center>圖9</center>

Q5:什麼場景下 Pod 會運行多個容器?

爲了後面演示的方便,舉一個服務自動構建的例子。(實用否,你們能夠自行判斷

假設有兩個容器,一個是 nginx 容器,作靜態服務器,一個是 git-sync 容器,用於定時監測 git 倉庫上代碼的變化,拉取最新代碼到本地。這是兩個獨立的容器,若是把它們放在一個 Pod 裏面,Pod 的特色是內部網絡共享、數據空間共享。這樣就大大減小了原先跨容器訪問的複雜度。

這裏的例子舉得可能不是特別好,若是涉及跨容器的網絡通訊,那麼 Pod 的優點會獲得更好的體現。

這裏經過配置文件來啓動包含 nginx、git-sync 容器的 Pod,

配置文件 nginx-git.yml 具體內容以下:(官方參考文檔):

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-git
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx # 啓動 nginx 容器
        image: nginx
        volumeMounts: # 掛載數據卷
        - mountPath: /usr/share/nginx/html
          name: git-volume
      - name: git-sync # 啓動 git-sync 容器
        image: openweb/git-sync
        env:
        - name: GIT_SYNC_REPO
          value: "https://github.com/jasonGeng88/test.git"
        - name: GIT_SYNC_DEST
          value: "/git"
        - name: GIT_SYNC_BRANCH
          value: "master"
        - name: GIT_SYNC_REV
          value: "FETCH_HEAD"
        - name: GIT_SYNC_WAIT
          value: "10"
        volumeMounts: # 掛載數據卷
        - mountPath: /git
          name: git-volume
      volumes: # 共享數據卷
      - name: git-volume
        emptyDir: {}

配置文件有必要的註釋,應該比較容易理解,這裏簡單講下兩點:

  1. GIT 倉庫地址下只有一個 index.html 文件,內容爲:hello world 1!

  2. 關於共享數據 volumes 的配置問題。共享數據存儲的問題主要分爲:數據臨時存儲與持久性存儲。

    • 臨時存儲:

    volumes:
    - name: volume-name
      emptyDir: {}
* 掛載宿主機存儲:
volumes:
- name: volume-name
  hostPth: 
      path: "/data"
* 固然還有網絡磁盤存儲等(如谷歌公有云)

注意:即便是臨時存儲,由於數據是 Pod 下全部容器共享的,任何一個容器重啓,數據都不會丟失。當 Pod 結束時,臨時性數據纔會丟失。

演示:

  • 以配置文件運行 deployment:

kubectl create -f nginx-git.yml


<center>圖10</center>

  • 訪問 Pod 查看效果:

更實用的場景是將 Pod 做爲 Service 暴露,經過 Service 來進行訪問,由於本文主要講 Pod,不想引入 Service 的概念。因此咱們直接來訪問 Pod。

    1. 查看 Pod 對應的 IP (也可在 Pod 詳細描述中得到

kubectl get -o template pod/$POD_NAME --template={{.status.podIP}}


<center>圖11</center>

    1. 進入 K8S 集羣,訪問 Pod 中 nginx 服務

由於得到 Pod IP 是 K8S 集羣內部建立的,外面是沒法與其通訊的。因此咱們須要經過命令 minikube ssh 進入集羣,纔可進行 Pod 訪問。


<center>圖12</center>

再把 git 倉庫上的 index.html 內容改成 hello world 2!,再訪問一下 Pod 觀察結果(需等待幾秒)。


<center>圖13</center>

Q6:Pod 內部是如何實現網絡共享的?

最後,咱們來看下 Pod 的 IP 是如何生成的,以及內部容器是如何關聯的。

經過 docker ps 咱們發現,nginx-git 最終會生成三個容器,分別是 git-sync, nginx, pause。


<center>圖14</center>

經過 docker inspect $CONTAINER_ID 咱們發現,git-sync 與 nginx 的網絡模型都是使用了同一個容器ID的網絡,而該容器ID 正好對應了 pause 這個容器。


<center>圖15</center>

咱們再看 pause 容器的網絡模型,發現它使用的是 bridge 模式,而分配的 IP 正是對應了 Pod 的 IP。由此可知,Pod 內全部容器都是經過 pause 的網絡進行通訊的。


<center>圖16</center>

docker 中默認的網絡模式就是 Bridge 模式。

證實:

上面演示已經證實了集羣間經過 Pod IP 是能夠訪問到容器內的服務的。咱們下面證實,Pod 內容器之間經過 localhost 進行互相訪問。

咱們進入 git-sync 容器,經過訪問 localhost 的 80 端口,看是否能訪問到 nginx 容器。


<center>圖17</center>

答案很明顯了!

總結

本文沒有循序漸進的去一一介紹 Pod 的相關功能點,而是經過 K8S 的本地搭建,從 Pod 的基本使用開始,經過幾個問題穿插着介紹了 Pod 的一些主要的概念與使用。

本文知識點總結:

  • minikube 的啓動與鏈接

  • kubectl 的使用

  • Pod 的命令式與配置文件的啓動

  • Pod 的查看方式(概況與詳情)

  • Pod 生命週期中的各個狀態

  • deployment 對 Pod 的管理

  • deployment, replicaset, pod 三者的關係

  • Pod 內多容器的場景

  • Pod 的共享數據的臨時存儲與文件掛載的持久存儲

  • Pod 中 pause 的做用及網絡通訊的原理

可能關於 Pod 的有些知識點沒有講到,或者有講的不對的地方,也歡迎提出和指正!

後面,也會去講關於 service,configMap,update,rollout 相關的一些內容,但願對您有幫助~

相關文章
相關標籤/搜索