書名: Kubernetes權威指南:從Docker到Kubernetes實踐全接觸(第4版)作者名: 龔正等編著本章字數: 1088字更新時間: 2019-09-23 11:04:37
3.2 Pod的基本用法
在對Pod的用法進行說明之前,有必要先對Docker容器中應用的運行要求進行說明。
在使用Docker時,可以使用docker run命令創建并啟動一個容器。而在Kubernetes系統中對長時間運行容器的要求是:其主程序需要一直在前臺執行。如果我們創建的Docker鏡像的啟動命令是后臺執行程序,例如Linux腳本:
nohup ./start.sh &
則在kubelet創建包含這個容器的Pod之后運行完該命令,即認為Pod執行結束,將立刻銷毀該Pod。如果為該Pod定義了ReplicationController,則系統會監控到該Pod已經終止,之后根據RC定義中Pod的replicas副本數量生成一個新的Pod。一旦創建新的Pod,就在執行完啟動命令后陷入無限循環的過程中。這就是Kubernetes需要我們自己創建的Docker鏡像并以一個前臺命令作為啟動命令的原因。
對于無法改造為前臺執行的應用,也可以使用開源工具Supervisor輔助進行前臺運行的功能。Supervisor提供了一種可以同時啟動多個后臺應用,并保持Supervisor自身在前臺執行的機制,可以滿足Kubernetes對容器的啟動要求。關于Supervisor的安裝和使用,請參考官網http://supervisord.org的文檔說明。
接下來對Pod對容器的封裝和應用進行說明。
Pod可以由1個或多個容器組合而成。在上一節Guestbook的例子中,名為frontend的Pod只由一個容器組成:
apiVersion: v1 kind: Pod metadata: name: frontend labels: name: frontend spec: containers: - name: frontend image: kubeguide/guestbook-php-frontend env: - name: GET_HOSTS_FROM value: env ports: - containerPort: 80
這個frontend Pod在成功啟動之后,將啟動1個Docker容器。
另一種場景是,當frontend和redis兩個容器應用為緊耦合的關系,并組合成一個整體對外提供服務時,應將這兩個容器打包為一個Pod,如圖3.1所示。

圖3.1 包含兩個容器的Pod
配置文件frontend-localredis-pod.yaml的內容如下:
apiVersion: v1 kind: Pod metadata: name: redis-php labels: name: redis-php spec: containers: - name: frontend image: kubeguide/guestbook-php-frontend:localredis ports: - containerPort: 80 - name: redis image: kubeguide/redis-master ports: - containerPort: 6379
屬于同一個Pod的多個容器應用之間相互訪問時僅需要通過localhost就可以通信,使得這一組容器被“綁定”在了一個環境中。
在Docker容器kubeguide/guestbook-php-frontend:localredis的PHP網頁中,直接通過URL地址“localhost:6379”對同屬于一個Pod的redis-master進行訪問。guestbook.php的內容如下:
<? set_include_path('.:/usr/local/lib/php'); error_reporting(E_ALL); ini_set('display_errors', 1); require 'Predis/Autoloader.php'; Predis\Autoloader::register(); if (isset($_GET['cmd']) === true) { $host = 'localhost'; if (getenv('REDIS_HOST') && strlen(getenv('REDIS_HOST')) > 0 ) { $host = getenv('REDIS_HOST'); } header('Content-Type: application/json'); if ($_GET['cmd'] == 'set') { $client = new Predis\Client([ 'scheme' => 'tcp', 'host' => $host, 'port' => 6379, ]); $client->set($_GET['key'], $_GET['value']); print('{"message": "Updated"}'); } else { $host = 'localhost'; if (getenv('REDIS_HOST') && strlen(getenv('REDIS_HOST')) > 0 ) { $host = getenv('REDIS_HOST'); } $client = new Predis\Client([ 'scheme' => 'tcp', 'host' => $host, 'port' => 6379, ]); $value = $client->get($_GET['key']); print('{"data": "' . $value . '"}'); } } else { phpinfo(); } ?>
運行kubectl create命令創建該Pod:
$ kubectl create -f frontend-localredis-pod.yaml pod "redis-php" created
查看已經創建的Pod:
# kubectl get pods NAME READY STATUS RESTARTS AGE redis-php 2/2 Running 0 10m
可以看到READY信息為2/2,表示Pod中的兩個容器都成功運行了。
查看這個Pod的詳細信息,可以看到兩個容器的定義及創建的過程(Event事件信息):
# kubectl describe pod redis-php Name: redis-php Namespace: default Node: k8s/192.168.18.3 Start Time: Thu, 28 Jul 2016 12:28:21 +0800 Labels: name=redis-php Status: Running IP: 172.17.1.4 Controllers: <none> Containers: frontend: Container ID: docker://ccc8616f8df1fb19abbd0ab189a36e6f6628b78ba7b97b1077d86e7fc224ee08 Image: kubeguide/guestbook-php-frontend:localredis Image ID: docker://sha256:d014f67384a11186e135b95a7ed0d794674f7ce258f0dce47267c3052a0d0fa9 Port: 80/TCP State: Running Started: Thu, 28 Jul 2016 12:28:22 +0800 Ready: True Restart Count: 0 Environment Variables: <none> redis: Container ID: docker://c0b19362097cda6dd5b8ed7d8eaaaf43aeeb969ee023ef255604bde089808075 Image: kubeguide/redis-master Image ID: docker://sha256:405a0b586f7ebeb545ec65be0e914311159d1baedccd3a93e9d3e3b249ec5cbd Port: 6379/TCP State: Running Started: Thu, 28 Jul 2016 12:28:23 +0800 Ready: True Restart Count: 0 Environment Variables: <none> Conditions: Type Status Initialized True Ready True PodScheduled True Volumes: default-token-97j21: Type: Secret (a volume populated by a Secret) SecretName: default-token-97j21 QoS Tier: BestEffort Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- ----- ------ ------- 18m 18m 1 {default-scheduler } Normal Scheduled Successfully assigned redis-php to k8s-node-1 18m 18m 1 {kubelet k8s-node-1} spec.containers{frontend} Normal Pulled Container image "kubeguide/guestbook-php-frontend:localredis" already present on machine 18m 18m 1 {kubelet k8s-node-1} spec.containers{frontend} Normal Created Created container with docker id ccc8616f8df1 18m 18m 1 {kubelet k8s-node-1} spec.containers{frontend} Normal Started Started container with docker id ccc8616f8df1 18m 18m 1 {kubelet k8s-node-1} spec.containers{redis} Normal Pulled Container image "kubeguide/redis-master" already present on machine 18m 18m 1 {kubelet k8s-node-1} spec.containers{redis} Normal Created Created container with docker id c0b19362097c 18m 18m 1 {kubelet k8s-node-1} spec.containers{redis} Normal Started Started container with docker id c0b19362097c