內容摘要
創建第一個Pod
查詢Pod信息
Pod是K8S集群的核心概念,核心資源,其他資源都以它為中心。
Pod的本質就是1個或者多個容器的集合,大家先這樣理解,隨著課程的深入,大家對它會越來越熟悉。
測試環境
請參考前一章,在阿里雲準備單節點測試環境,將該節點主機名設為master。
構建測試鏡像
在根目錄下創建test文件夾,在該文件夾下,創建Dockerfile文件以及app.js文件。
Dockerfile內容如下:
FROM node:7
ADD app.js /app.js
ENTRYPOINT ["node", "app.js"]
上面用到的app.js文件內容如下:
const http = require('http');
const os = require('os');
console.log("server starting...");
var handler = function(request, response) {
console.log("Received request from " + request.connection.remoteAddress);
response.writeHead(200);
response.end("You've hit " + os.hostname() + "\n");
};
var www = http.createServer(handler);
www.listen(8080);
使用如下命令構建容器鏡像:
docker build -t first_pod .
如下圖:

由於node:7基礎鏡像有點大,構建可能會持續幾分鐘,這個具體要看你的網速。
構建完成後,將鏡像push到自己在hub.docker.com中的容器倉庫,步驟如下:
1、給新構建的鏡像打tag
docker tag first_pod huqianakls/first_pod:latest
注意:huqianakls 是dockers上的賬號或者id號,使用/隔開,/後面就是鏡像名和tag;
2、登錄自己的賬號
docker login -u huqianakls
3、推送鏡像
docker push huqianakls/first_pod:latest
之後,在自己的docker倉庫查看是否成功。
創建第1個Pod
在根目錄下創建Pod的yaml文件,名為first_pod.yaml,內容如下:
apiVersion: v1
kind: Pod
metadata:
name: firstpod
spec:
containers:
- image: huqianakls/first_pod:latest
name: firstcontainer
ports:
- containerPort: 8080
protocol: TCP
上述Pod的yaml描述文件很簡單,下面簡單解釋下:
apiVersion:資源的版本,這裡不用糾結,後面會講解;
kind:資源類型,這裡就是Pod,Pod是K8S的一種資源類型;
metadata:元數據;
metadata.name:Pod的名字
spec:容器信息;
spec.containers:描述容器信息的集合,這裡只提供了一個容器;
image:鏡像名和tag;
name:容器名稱;
ports:容器端口信息;
ports.containerPort:容器的端口;
ports.protocol:端口協議,這裡是TCP協議;
創建Pod,使用命令:
kubectl create -f first_pod.yaml

注意:在運行前,請登錄自己的容器,上面構建鏡像的時候我們已經登錄,這裡就不用登錄了。
創建成功後,使用如下命令查詢Pod:
kubectl get pod
上面查詢了兩次,第1次查詢到的狀態為ContainerCreating,表示容器在創建中;第2次查詢狀態為Running,表示運行中,即創建成功。
分析Pod
在第一個Pod創建成功後,我們使用Docker動手教程中講解的知識來分析下集群中的容器。
查詢容器,命令為:
docker ps | grep first
從查詢結果可以看到,出現了兩個容器,名稱分別為: k8s_firstcontainer_firstpod_default_aca9e662-d945-11e9-a667-00163e16cfe5_0和k8s_POD_firstpod_default_aca9e662-d945-11e9-a667-00163e16cfe5_0。
這說明該Pod運行後,啟動了兩個容器:
第一個容器是Pod資源中設置的;
另一個容器是K8S系統指定的,它的啟動命令為/pause,因此該容器一般叫pause容器。
分別查詢容器的詳情,命令為:
docker inspect k8s_firstcontainer_firstpod_default_aca9e662-d945-11e9-a667-00163e16cfe5_0
其結果如下,這裡只查看器網路配置:
"NetworkSettings": {
"Bridge": "",
"SandboxID": "",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {}
}
可以看出,網絡配置沒有數據。
查詢Pause容器,命令為:
docker inspect k8s_POD_firstpod_default_aca9e662-d945-11e9-a667-00163e16cfe5_0
返回的網絡配置數據為:
"NetworkSettings": {
"Bridge": "",
"SandboxID": "0e5f3b325c0e3cf5964f343bad00073c8021f2134492f18cac7c5f54cfab2054",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/0e5f3b325c0e",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"none": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "c7ec2bd11b8fe1836f683c99ee743bf57e4a9d395b7d9bb3fb0d22242a637272",
"EndpointID": "3009dcda6e8ac13c6032b61fdb380eb2ba8bfc4d840478e9d9423c7f69c0bf39",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}}}
可以看到,網絡數據是有的。請大家尤其注意NetworkID和EndpointID兩個屬性,這是容器網絡的信息。
請大家注意下配置信息,如下:
"Config": {
"Hostname": "firstpod",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": null,
"Image": "k8s.gcr.io/pause-amd64:3.1",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/pause"
],
"OnBuild": null,
"Labels": {
"annotation.kubernetes.io/config.seen": "2019-09-17T20:21:28.438086866+08:00",
"annotation.kubernetes.io/config.source": "api",
"io.kubernetes.container.name": "POD",
"io.kubernetes.docker.type": "podsandbox",
"io.kubernetes.pod.name": "firstpod",
"io.kubernetes.pod.namespace": "default",
"io.kubernetes.pod.uid": "aca9e662-d945-11e9-a667-00163e16cfe5"
}},
注意上面的Image字段,標識了該容器的鏡像為: k8s.gcr.io/pause-amd64:3.1,Entrypoint字段標識了容器的啟動命令。這就是pause容器的大概信息。
查詢Pod詳情
前面查詢Pod是全集查詢,可以單獨查詢Pod的詳情,分為兩種方式:kubectl get / kubectl describe。
kubectl get
命令為:
kubectl get pod firstpod -o yaml
命令格式:kubectl get pod Pod名稱 -o yaml。
按照Pod名稱查詢,這裡名稱為firstpod;
-o yaml表示返回數據的格式,這裡以yaml格式,還可以指定以json格式返回,參數為:-o json;
結果為:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: 2019-09-17T12:21:28Z
name: firstpod
namespace: default
resourceVersion: "3858"
selfLink: /api/v1/namespaces/default/pods/firstpod
uid: aca9e662-d945-11e9-a667-00163e16cfe5
spec:
containers:
- image: huqianakls/first_pod:latest
imagePullPolicy: Always
name: firstcontainer
ports:
- containerPort: 8080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-975gj
readOnly: true
dnsPolicy: ClusterFirst
nodeName: master
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: default-token-975gj
secret:
defaultMode: 420
secretName: default-token-975gj
status:
conditions:
- lastProbeTime: null
lastTransitionTime: 2019-09-17T12:21:28Z
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: 2019-09-17T12:21:37Z
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: 2019-09-17T12:21:28Z
status: "True"
type: PodScheduled
containerStatuses:
- containerID: docker://0c4b85187057c218a6eb7ece85973ab7762e690ebebe53a7b48e3260e1b617a0
image: huqianakls/first_pod:latest
imageID: docker-pullable://huqianakls/first_pod@sha256:7a10ed22576c47122b97c7011e0e6d85bd915540b06f4aa23eb9f75f7313342c
lastState: {}
name: firstcontainer
ready: true
restartCount: 0
state: running
startedAt: 2019-09-17T12:21:36Z
hostIP: 172.18.152.3
phase: Running
podIP: 192.168.219.72
qosClass: BestEffort
startTime: 2019-09-17T12:21:28Z
大家可以看到返回的結果非常多,實際上我們在創建Pod的yaml文件中只提供了很少的參數。
首先解釋下metadata下面的參數,我們只在yaml資源文件中指定了name屬性,其他屬性都是K8S自己加上的。
creationTimestamp:表示創建時間;
namespace:表示命名空間,這裡先不細講,大致只要知道這是資源劃分的一種方式;
resourceVersion:資源的版本,該數據是K8S集群自動設置的,大家不用設置;
selfLink:這是資源在集群中的位置,不過一般都不會使用,訪問容器我們還是使用端口或者集群提供的更高級方式。
uid:資源在集群中的唯一身份ID,由集群自動生成;
spec下的資源這裡不講解,後續會慢慢讓大家知道。
請大家注意到下面的status信息,表示Pod的狀態,下面對某些屬性做下說明:
containerStatuses:下面的數據是Pod中容器狀態數據;
containerStatuses.name:容器名稱,這和Pod的名稱是有區別的;
containerStatuses.image:容器鏡像名稱;
containerStatuses.ready:表示容器是否準備好,即是否可以使用;
hostIP:容器所在主機IP地址,這裡顯示的是阿里雲內網IP地址;
phase:階段,也可以叫狀態,Running表示運行中;
podIP:Pod IP地址
qosClass: 服務等級,這個概念這裡先不細講,後面會詳細說明;
startTime:啟動時間,這裡和creationTimestamp時間一樣;
kubectl describe
這個命令比kubectl get獲取的信息更多,非常實用。
kubectl describe pod firstpod
結果為:
Name: firstpod
Namespace: default
Node: master/172.18.152.3
Start Time: Tue, 17 Sep 2019 20:21:28 +0800
Labels:
Annotations:
Status: Running
IP: 192.168.219.72
Containers:
firstcontainer:
Container ID: docker://0c4b85187057c218a6eb7ece85973ab7762e690ebebe53a7b48e3260e1b617a0
Image: huqianakls/first_pod:latest
Image ID: docker-pullable://huqianakls/first_pod@sha256:7a10ed22576c47122b97c7011e0e6d85bd915540b06f4aa23eb9f75f7313342c
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 17 Sep 2019 20:21:36 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-975gj (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-975gj:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-975gj
Optional: false
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Event會顯示出Pod運行的大致過程,便於我們瞭解Pod的執行細節。後面大家會經常使用它去查詢Pod的詳細信息。
關於獲取Pod詳情的方式就介紹到這裡。這裡有很多參數,有我們設置的也有K8S默認設置的,有些參數的意義我沒有細講,後面會給大家一一講解。
到此為止,Pod的第一節將講到這裡,本節主要是帶大家初步體驗下K8S核心資源Pod大概是什麼。請大家一定要完成課後的實驗。
實驗
運行自己的第一個Pod