pod定義詳解
下面是一個完整的yaml格式定義的文件,注意格式,子集包含關系,不要有tab,要用空格。不是所有的元素都要寫,按照實際應用場景配置即可。
定義一個簡單pod(最好把docker源改成國內的)
apiVersion: v1
kind: Pod
metadata:
name: hello-world
namespace: default
spec:
restartPolicy: OnFailure
containers:
- name: hello
image: "ubuntu:14.04"
command: ["/bin/echo","hello","world"]
pod文件解釋:
apiVersion: v1//k8s版本
kind: pod//聲明API對象類型這里是pod
metadata:
name:hello-word //pod名字必須在namespace中是唯一
spec://配置pod具體配置
restartPolicy: OnFailure // pod重啟策略 [Always默認策略,當容器退出時總是重啟容器|Never當容器退出時,從不重啟|OnFailure容器正常退出不會再重新啟動,退出碼非0時才重啟容器]
containers: //pod中的容器列表,可以有多個容器
- name: hello //容器名字,在一個pod中唯一
image: "ubuntu:14.04" //鏡像名字
command: ["/bin/echo","hello","word"]//設置容器的啟動命令
創建pod
[root@kubernetes-master pods]# kubectl create -f helloworld.yml
pod "hello-word" created
查看pod狀態,狀態不是runing而是完成,說明容器運行完成已經退出了
查看容器log輸出
[root@kubernetes-master pods]# kubectl logs hello-world
hello world
這里要說一下command和args2個參數:
pod中定義env
容器獲取pod信息

1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: print-pod-info 5 namespace: default 6 spec: 7 containers: 8 - name: my-pod 9 image: busybox 10 resources: 11 requests: 12 memory: "32Mi" 13 cpu: "125m" 14 limits: 15 memory: "64Mi" 16 cpu: "250m" 17 env: 18 - name: MY_POD 19 valueFrom: 20 fieldRef: 21 fieldPath: metadata.name 22 - name: MY_POD_NAMESPACE 23 valueFrom: 24 fieldRef: 25 fieldPath: metadata.namespace 26 - name: MY_POD_IP 27 valueFrom: 28 fieldRef: 29 fieldPath: status.podIP 30 - name: MY_POD_SERVICE_ACCOUNT 31 valueFrom: 32 fieldRef: 33 fieldPath: spec.serviceAccountName 34 - name: MY_CPU_REQUEST 35 valueFrom: 36 resourceFieldRef: 37 containerName: my-pod 38 resource: requests.cpu 39 - name: MY_CPU_LIMIT 40 valueFrom: 41 resourceFieldRef: 42 containerName: my-pod 43 resource: limits.cpu 44 - name: MY_MEM_REQUEST 45 valueFrom: 46 resourceFieldRef: 47 containerName: my-pod 48 resource: requests.memory 49 - name: MY_MEM_LIMIT 50 valueFrom: 51 resourceFieldRef: 52 containerName: my-pod 53 resource: limits.memory 54 command: ["/bin/sh","-c","while true;do sleep 5;done"]
解釋:
env:
- name: MY_POD 定義的變量名字最好是大寫
valueFrom: 獲取pod中的信息這個是固定的
fieldRef: 獲取pod中的信息這個是固定的
fieldPath: metadata.name 獲取pod中的信息這個是固定的
定義普通變量:
env:
- name: MY_POD 定義的變量名字最好是大寫
value: "massage......" 變量的值
端口:
配置nginx

1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: my-nginx 5 namespace: default 6 spec: 7 containers: 8 - image: nginx 9 imagePullPolicy: IfNotPresent 10 name: nginx 11 ports: 12 - name: web 13 containerPort: 80 //容器內部端口 14 protocol: TCP //協議可選 15 hostIP: 0.0.0.0 //worknodeIP可選,0.0.0.0就是任意選擇 16 hostPort: 8000 //worknode(宿主機)上的端口
提示:
ports.name 這個值在pod中也是唯一的,當配置一個端口的時候是可選的,多個端口是必選。
如果同時2個pod的的宿主機端口都是80那么k8s會將容器分別調度到沒有占用80端口機器上啟動
數據持久化和共享

1 piVersion: v1 2 kind: Pod 3 metadata: 4 name: newhello 5 namespace: default 6 spec: 7 restartPolicy: Never 8 containers: 9 - name: write 10 image: "ubuntu:14.04" 11 command: ["/bin/sh","-c","echo \"hello word\" >> /data/hello"] 12 volumeMounts: 13 - name: data 掛在下面定義卷data 14 mountPath: /data 掛載到容器中的目錄 15 - name: read 16 image: "ubuntu:14.04" 17 command: ["bash","-c","sleep 10; cat /data/hello"] 18 volumeMounts: 19 - name: data 20 mountPath: /data 21 volumes: 定義卷 22 - name: data 卷名字 23 hostPath: 宿主機 24 path: /tmp 宿主機路徑
查看結果
[root@kubernetes-master pods]# kubectl logs newhello read
hello word
pod生命周期:
1、 Pending:kubernetes已經開始創建Pod,但是Pod中的一個或多個容器還沒有被啟動。比如Pod正處在應該被分配到哪個節點上這個調度過程中,或者kubernetes還在從鏡像倉庫中下載Pod中容器鏡像這個下載過程中。
2、 Running:kubernetes已經將Pod分配到節點上,並且Pod中的所有容器都啟動了。還包括Pod中至少有一個容器仍然在運行狀態,或者正在重新啟動狀態。
3、 Succeeded:Pod中的所有容器都處在終止狀態,並且這些容器是自主正常退出到終止狀態的,也就是退出代碼為0,而且kubernetes也沒有重啟任何容器。
4、 Failed:Pod中的所有容器都處在終止狀態,並且至少有一個容器不是正常終止的,也就是退出代碼不為0,或者是由於系統強行終止的。
5、 Unknown:由於一些特殊情況無法獲取Pod狀態,比如由於網絡原因無法同Pod所在的主機通訊。
變量Phase的取值還取決於結構體PodSpec中的RestartPolicy變量,這個RestartPolicy變量是用來設置Pod中容器重啟策略的,包括三個可選值,分別是Always、OnFailure和Never。
這三個值得含義分別是:
1、Always:表示對容器一直執行重啟策略。如果不設置RestartPolicy,那么Always是默認值。
2、OnFailure:表示在容器失敗的時候重啟容器。
3、 Never:表示在對容器不執行重啟策略。
總結一下pod重啟策略和容器退出后。pod狀態
pod生命周期回調
主要作用就是在容器開始的時候做一個動作,容器停止的時候做一個動作

1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: javaweb2 5 namespace: default 6 spec: 7 containers: 8 - image:ubuntu:14.04 9 name: war 10 lifecycle: 11 postStart: 12 exec: 13 command: 14 - "cp" 15 - "/sample.war" 16 - "/app" 17 preStop: 18 httpGet: 19 host: monitor.com 20 path: /warning 21 port: 8080 22 scheme: HTTP
PostStart:容器創建成功后回調
PreStop :容器終止前回調
自定義pod檢查
在很多實際場景下,僅僅使用進程級健康檢查還遠遠不夠。有時,從Docker的角度來看,容器進程依舊在運行;但是如果從應用程序的角度來看,代碼處於死鎖狀態,即容器永遠都無法正常響應用戶的業務
為了解決以上問題,Kubernetes引人了一個在容器內執行的活性探針(Liveness Probe)和(Readiness Probe)的概念,以支持用戶自己實現應用業務級的健康檢查。這些檢查項由Kubelet代為執行,以確保用戶的應用程序正確運轉,至於什么樣的狀態才算“正確”,則由用戶自己定義。
1Liveness Probe 容器自定義檢查,檢查失敗容器被殺死,然后根據pod重啟策略來做
2Readiness Probe 檢查失敗直接從代理后端移除,既不會分發請求給改pod。
Kubernetes支持3種類型的應用健康檢查動作,分別為HTTP Get、Container Exec和TCP Socket。個人感覺exec的方式還是最通用的,因為不是每個服務都有http服務,但每個服務都可以在自己內部定義健康檢查的job,定期執行,然后將檢查結果保存到一個特定的文件中,外部探針就不斷的查看這個健康文件就OK了。
HTTPget:
path URL路徑
port 端口
host 請求IP
scheme:求情協議默認HTTP
Kubelet將調用容器內Web應用的web hook,如果返回的HTTP狀態碼在200和399之間,則認為容器運轉正常,否則認為容器運轉不正常。每進行一次HTTP健康檢查都會訪問一次指定的URL。給出httpGet的簡單示例如下:

1 [root@k8s-master livenessProbe]# cat test-livenessprobe.yaml 2 apiVersion: v1 3 kind: Pod 4 metadata: 5 labels: 6 name: test-livenessprobe 7 name: test-livenessprobe 8 spec: 9 containers: 10 - name: test-livenessprobe 11 image: registry:5000/back_demon:1.0 12 livenessProbe: 13 httpGet: 14 path: /starott_cloud_client/test/overview-frontend 15 port: 8080 16 initialDelaySeconds: 15 17 periodSeconds: 5 18 timeoutSeconds: 1 19 command: 20 - /run.sh
TCP Socket:
tcpSocket:
port:8080
檢查tcp端口8080是否正常
Exec:
exec:
command:
這里拿exec做例子演示Liveness Probe和Readiness Probe區別:

1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: livemess-probe 5 labels: 6 test: liveness 7 spec: 8 containers: 9 - name: libeness 10 image: "ubuntu:14.04" 11 command: 12 - /bin/sh 13 - -c 14 - echo ok > /tmp/health; sleep 30;rm -rf /tmp/health;sleep 600 15 livenessProbe: 16 exec: 17 command: 18 - cat 19 - /tmp/health 20 initialDelaySeconds: 15 21 timeoutSeconds: 1
注意看restarts數值
30秒后容器重啟了
查看錯誤日志
kubectl describe pod livemess-probe |grep Unhealthy
Readiness Probe實驗
容器狀態還是running但是k8s不會往這個pod上轉發數據
日志查詢:
一個pod中2個容器,一個正常退出一個異常退出。重啟策略O:nFailure,異常退出時在重啟容器

1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: logs-pod 5 namespace: default 6 spec: 7 restartPolicy: OnFailure 8 containers: 9 - name: cont1 10 image: "ubuntu:14.04" 11 command: ["bash","-c","echo \"cont1:`date --rfc-3339 ns`\";exit 0"] 12 - name: cont2 13 image: "ubuntu:14.04" 14 command: ["bash","-c","echo \"cont2:`date --rfc-3339 ns`\";exit 1"]
查看容器1和容器2日志
[root@kubernetes-master pods]# kubectl logs logs-pod cont1
cont1:2017-07-11 13:15:41.122936441+00:00
[root@kubernetes-master pods]# kubectl logs logs-pod cont2
cont2:2017-07-11 13:21:40.452165906+00:00
查看日志歷史,有的時候會出現查詢不到當前日志,我們就 可意查詢上一次容器打的日志。加上這個--previous
[root@kubernetes-master pods]# kubectl logs logs-pod cont2 --previous
cont2:2017-07-11 13:21:40.452165906+00:00
定義持久化日志

1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: logs-pod 5 namespace: default 6 spec: 7 restartPolicy: OnFailure 8 containers: 9 - name: cont1 10 terminationMessagePath: /dev/termination-log 11 image: "ubuntu:14.04" 12 command: ["bash","-c","echo \"cont1:`date --rfc-3339 ns`\" >> /dev/termination-log;"]
用到的參數terminationMessagePath:
[root@kubernetes-master pods]# kubectl get pod logs-pod --template="{{range .status.containerStatuses}}{{.state.terminated.message}}{{end}}" --show-all
cont1:2017-07-11 13:28:03.421374195+00:00
遠程連接容器
1、exec(功能強大)
2、attach(這個比較麻煩)
遠程執行命令並返回
[root@kubernetes-master pods]# kubectl exec mysql -- date
Tue Jul 11 13:42:44 UTC 2017
進入pod容器
[root@kubernetes-master pods]# kubectl exec -ti mysql /bin/bash