摘要:本文屬於原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/bloghtml
文章一:帶着問題學 Kubernetes 架構nginx
Mac OS 10.11.xgit
kubectl == v1.6.4github
minikube == v0.19.1web
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 進行綁定。
好了,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)。
先以命令式的方式進行啓動,這也是最簡單的啓動方式,但不建議用於生產環境。(後面會涉及以配置文件進行部署。)
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>
從圖5中能夠看出,Pod 當前的狀態是 Running,若是本身嘗試的話,可能會遇到其餘狀態。由於 Pod 所處的生命週期的階段可能不同。
下面常見的有這幾種:
Pending:Pod 定義正確,提交到 Master,但其包含的容器鏡像還未徹底建立。一般處在 Master 對 Pod 的調度過程當中。
ContainerCreating:Pod 的調度完成,被分配到指定 Node 上。處於容器建立的過程當中。一般是在拉取鏡像的過程當中。
Running:Pod 包含的全部容器都已經成功建立,而且成功運行起來。
Successed:Pod 中全部容器都成功結束,且不會被重啓。這是 Pod 的一種最終狀態。
Failed:Pod 中全部容器都結束,但至少一個容器以失敗狀態結束。這也是 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 版。*
經過上述驗證,咱們直接刪除 Pod後,依然會建立新的 Pod,這是它的保障機制。咱們只有刪除它的上層管理者,即 deployment,那麼由它產生的 replicaset 和 Pod 會自動刪除。
kubectl delete deploy $DEPLOY_NAME
<center>圖9</center>
爲了後面演示的方便,舉一個服務自動構建的例子。(實用否,你們能夠自行判斷)
假設有兩個容器,一個是 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: {}
配置文件有必要的註釋,應該比較容易理解,這裏簡單講下兩點:
GIT 倉庫地址下只有一個 index.html 文件,內容爲:hello world 1!
。
關於共享數據 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。
查看 Pod 對應的 IP (也可在 Pod 詳細描述中得到)
kubectl get -o template pod/$POD_NAME --template={{.status.podIP}}
<center>圖11</center>
進入 K8S 集羣,訪問 Pod 中 nginx 服務
由於得到 Pod IP 是 K8S 集羣內部建立的,外面是沒法與其通訊的。因此咱們須要經過命令 minikube ssh
進入集羣,纔可進行 Pod 訪問。
<center>圖12</center>
再把 git 倉庫上的 index.html 內容改成 hello world 2!
,再訪問一下 Pod 觀察結果(需等待幾秒)。
<center>圖13</center>
最後,咱們來看下 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 相關的一些內容,但願對您有幫助~