先來一起回憶一下上節(jié)課內(nèi)容箩退,k8s的幾個組成部分:
研發(fā)采用聲明式定義自己的應(yīng)用:
應(yīng)用運(yùn)行在k8s集群上的全景圖:
什么是pod
Pod,是 Kubernetes 項(xiàng)目中最小的 API 對象。如果換一個更專業(yè)的說法,我們可以這樣描述:Pod,是 Kubernetes 項(xiàng)目的原子調(diào)度單位舀锨。
Kubernetes 項(xiàng)目中的最小編排單位是Pod彪腔,而不是容器番挺。
Pod 扮演的是傳統(tǒng)部署環(huán)境里“虛擬機(jī)”的角色贴铜。
而如果你能把 Pod 看成傳統(tǒng)環(huán)境里的“機(jī)器”轩褐、把容器看作是運(yùn)行在這個“機(jī)器”里的“用戶程序”,那么很多關(guān)于 Pod 對象的設(shè)計(jì)就非常容易理解了莫矗。
比如妹懒,凡是調(diào)度、網(wǎng)絡(luò)、存儲,以及安全相關(guān)的屬性蜻韭,基本上是 Pod 級別的俯画。
這些屬性的共同特征是,它們描述的是“機(jī)器”這個整體,而不是里面運(yùn)行的“程序”。比如辩越,配置這個“機(jī)器”的網(wǎng)卡(即:Pod 的網(wǎng)絡(luò)定義)亏钩。
配置這個“機(jī)器”的磁盤(即:Pod 的存儲定義),以及這臺“機(jī)器”運(yùn)行在哪個服務(wù)器之上(即:Pod 的調(diào)度)豪嚎。
當(dāng)容器間存在超緊密協(xié)作時篷角,我們可以稱為“超親密關(guān)系”俩滥。這些具有“超親密關(guān)系”容器的典型特征包括但不限于:互相之間會發(fā)生直接的文件交換掷倔、使用 localhost 或者 Socket 文件進(jìn)行本地通信勒葱、會發(fā)生非常頻繁的遠(yuǎn)程調(diào)用等等殃姓。
這也就意味著枷颊,并不是所有有“關(guān)系”的容器都屬于同一個 Pod。比如,Backend 后端容器和 Fronted 前端容器 雖然會發(fā)生訪問關(guān)系鲤屡,但并沒有必要儡湾、也不應(yīng)該部署在同一臺機(jī)器上,它們更適合做成兩個 Pod分開部署执俩。
那什么時候定義這種“超親密關(guān)系“呢徐钠?
比較典型的例子——容器的日志收集,役首。
比如尝丐,我現(xiàn)在有一個應(yīng)用,需要不斷地把日志文件輸出到容器的 /var/log 目錄中衡奥。
這時爹袁,我就可以把一個 Pod 里的 Volume 掛載到應(yīng)用容器的 /var/log 目錄上。
實(shí)際上矮固,這個所謂的“組合”操作失息,正是容器設(shè)計(jì)模式里最常用的一種模式,它叫:邊車模式(sidecar)档址。
我們在這個 Pod 里同時運(yùn)行一個 sidecar 容器盹兢,它也聲明掛載同一個 Volume 到自己的 /var/log 目錄上。這樣守伸,接下來 sidecar 容器就只需要做一件事兒绎秒,那就是不斷地從自己的 /var/log 目錄里讀取日志文件,轉(zhuǎn)發(fā)到 MongoDB 或者 Elasticsearch 中存儲起來尼摹。這樣见芹,一個最基本的日志收集工作就完成了。
Infra容器
Pod 里的所有容器蠢涝,共享的是同一個 Network Namespace玄呛,并且可以聲明共享同一個 Volume。
在 Kubernetes 項(xiàng)目里和二,Pod 的實(shí)現(xiàn)需要使用一個中間容器徘铝,這個容器叫作 Infra 容器。在這個 Pod 中儿咱,Infra 容器永遠(yuǎn)都是第一個被創(chuàng)建的容器庭砍,而其他用戶定義的容器,則通過 Join Network Namespace 的方式混埠,與 Infra 容器關(guān)聯(lián)在一起怠缸。這樣的組織關(guān)系,可以用下面這樣一個示意圖來表達(dá):
創(chuàng)建一個Pod
配置kube_config
聯(lián)系tower配置測試環(huán)境kube_config
通過kubectl創(chuàng)建一個namespace
kubectl create ns testops
通過kubectl創(chuàng)建一個pod
apiVersion: v1
kind: Pod
metadata:
name: kubia-manual
namespace: testops
spec:
containers:
- image: luksa/kubia
name: kubia
ports:
- containerPort: 8080
protocol: TCP
kubectl create -f kubia-manual.yaml
Pod的關(guān)鍵字段
Kubernetes 項(xiàng)目中對 Container 的定義钳宪,和 Docker 相比并沒有什么太大區(qū)別揭北。Image(鏡像)扳炬、Command(啟動命令)、workingDir(容器的工作目錄)搔体、Ports(容器要開發(fā)的端口)恨樟,以及 volumeMounts(容器要掛載的 Volume)都是構(gòu)成 Kubernetes 項(xiàng)目中 Container 的主要字段。
看個例子:
1疚俱、這個YAML描述符中使用的Kubernetes API版本劝术。
2、Kubernetes對象/資源的類型呆奕。
3养晋、Pod元數(shù)據(jù)(名稱、標(biāo)簽梁钾、注釋等)绳泉。
4、Pod規(guī)格/內(nèi)容(Pod容器姆泻、卷等列表)零酪。
5、Pod和其容器的詳細(xì)情況拇勃。
接下來四苇,介紹 Pod 中幾個重要字段的含義和用法。
Label
是一個供用戶將 Pod 與 Node 進(jìn)行綁定的字段
通常潜秋,我們微服務(wù)架構(gòu)下中會有許多個pod蛔琅,那么如何給這些pod分類呢,這里就要用到 Label 這個概念峻呛。
kubectl get pods -n {namespaces} -a --show-labels=true
NodeSelector
NodeSelector:是一個供用戶將 Pod 與 Node 進(jìn)行綁定的字段,用法如下所示:
apiVersion: v1
kind: Pod
...
spec:
nodeSelector:
disktype: ssd
這樣的一個配置辜窑,意味著這個 Pod 永遠(yuǎn)只能運(yùn)行在攜帶了“disktype: ssd”標(biāo)簽(Label)的節(jié)點(diǎn)上钩述;否則,它將調(diào)度失敗穆碎。
HostAliases
定義了 Pod 的 hosts 文件(比如 /etc/hosts)里的內(nèi)容牙勘,用法如下:
apiVersion: v1
kind: Pod
...
spec:
hostAliases:
- ip: "10.1.2.3"
hostnames:
- "foo.remote"
- "bar.remote"
...
在這個 Pod 的 YAML 文件中,我設(shè)置了一組 IP 和 hostname 的數(shù)據(jù)所禀。這樣方面,這個 Pod 啟動后,/etc/hosts 文件的內(nèi)容將如下所示:
cat /etc/hosts
#Kubernetes-managed hosts file.
127.0.0.1 localhost
...
10.244.135.10 hostaliases-pod
10.1.2.3 foo.remote
10.1.2.3 bar.remote
ImagePullPolicy
它定義了鏡像拉取的策略色徘。而它之所以是一個 Container 級別的屬性恭金,是因?yàn)槿萜麋R像本來就是 Container 定義中的一部分。
ImagePullPolicy 的值默認(rèn)是 Always褂策,即每次創(chuàng)建 Pod 都重新拉取一次鏡像横腿。另外颓屑,當(dāng)容器的鏡像是類似于 nginx 或者 nginx:latest 這樣的名字時,ImagePullPolicy 也會被認(rèn)為 Always耿焊。
Lifecycle
它定義的是 Container Lifecycle Hooks揪惦。顧名思義,Container Lifecycle Hooks 的作用罗侯,是在容器狀態(tài)發(fā)生變化時觸發(fā)一系列“鉤子”器腋。我們來看這樣一個例子:
Pending 這個狀態(tài)意味著,Pod 的 YAML 文件已經(jīng)提交給了 Kubernetes钩杰,API 對象已經(jīng)被創(chuàng)建并保存在 Etcd 當(dāng)中纫塌。但是,這個 Pod 里有些容器因?yàn)槟撤N原因而不能被順利創(chuàng)建榜苫。比如护戳,調(diào)度不成功。
Running 這個狀態(tài)下垂睬,Pod 已經(jīng)調(diào)度成功媳荒,跟一個具體的節(jié)點(diǎn)綁定。它包含的容器都已經(jīng)創(chuàng)建成功驹饺,并且至少有一個正在運(yùn)行中钳枕。
Succeeded 這個狀態(tài)意味著,Pod 里的所有容器都正常運(yùn)行完畢赏壹,并且已經(jīng)退出了鱼炒。這種情況在運(yùn)行一次性任務(wù)時最為常見。
Failed 這個狀態(tài)下蝌借,Pod 里至少有一個容器以不正常的狀態(tài)(非 0 的返回碼)退出昔瞧。這個狀態(tài)的出現(xiàn),意味著你得想辦法 Debug 這個容器的應(yīng)用菩佑,比如查看 Pod 的 Events 和日志自晰。
Unknown 這是一個異常狀態(tài),意味著 Pod 的狀態(tài)不能持續(xù)地被 kubelet 匯報(bào)給 kube-apiserver稍坯,這很有可能是主從節(jié)點(diǎn)(Master 和 Kubelet)間的通信出現(xiàn)了問題酬荞。
除了上面的字段,Pod還有一組Condition瞧哟,它們主要用于描述造成當(dāng)前 Status 的具體原因是什么混巧。
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
作業(yè)
查看Pods其他字段
1、下載k8s源碼
mkdir -p $GOPATH/src/k8s.io
2勤揩、進(jìn)入目錄$GOPATH/src/k8s.io咧党,執(zhí)行以下命令即可開始下載:
git clone https://github.com/kubernetes/kubernetes -b release-1.13
3、下載完畢后雄可,k8s.io目錄下出現(xiàn)一個名為kubernetes的文件夾凿傅。
cat $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/api/core/v1/types.go
觀察pod
使用kubectl命令缠犀,觀察你目前用的測試環(huán)境某個服務(wù)的pod信息
kubectl命令表
http://docs.kubernetes.org.cn/683.html
Pod其他屬性
# yaml格式的pod定義文件完整內(nèi)容:
apiVersion: v1 #必選,版本號聪舒,例如v1
kind: Pod #必選辨液,Pod
metadata: #必選,元數(shù)據(jù)
name: string #必選箱残,Pod名稱
namespace: string #必選滔迈,Pod所屬的命名空間
labels: #自定義標(biāo)簽
- name: string #自定義標(biāo)簽名字
annotations: #自定義注釋列表
- name: string
spec: #必選,Pod中容器的詳細(xì)定義
containers: #必選被辑,Pod中容器列表
- name: string #必選燎悍,容器名稱
image: string #必選,容器的鏡像名稱
imagePullPolicy: [Always | Never | IfNotPresent] #獲取鏡像的策略 Alawys表示下載鏡像 IfnotPresent表示優(yōu)先使用本地鏡像盼理,否則下載鏡像谈山,Nerver表示僅使用本地鏡像
command: [string] #容器的啟動命令列表,如不指定宏怔,使用打包時使用的啟動命令
args: [string] #容器的啟動命令參數(shù)列表
workingDir: string #容器的工作目錄
volumeMounts: #掛載到容器內(nèi)部的存儲卷配置
- name: string #引用pod定義的共享存儲卷的名稱奏路,需用volumes[]部分定義的的卷名
mountPath: string #存儲卷在容器內(nèi)mount的絕對路徑,應(yīng)少于512字符
readOnly: boolean #是否為只讀模式
ports: #需要暴露的端口庫號列表
- name: string #端口號名稱
containerPort: int #容器需要監(jiān)聽的端口號
hostPort: int #容器所在主機(jī)需要監(jiān)聽的端口號臊诊,默認(rèn)與Container相同
protocol: string #端口協(xié)議鸽粉,支持TCP和UDP,默認(rèn)TCP
env: #容器運(yùn)行前需設(shè)置的環(huán)境變量列表
- name: string #環(huán)境變量名稱
value: string #環(huán)境變量的值
resources: #資源限制和請求的設(shè)置
limits: #資源限制的設(shè)置
cpu: string #Cpu的限制抓艳,單位為core數(shù)触机,將用于docker run --cpu-shares參數(shù)
memory: string #內(nèi)存限制,單位可以為Mib/Gib玷或,將用于docker run --memory參數(shù)
requests: #資源請求的設(shè)置
cpu: string #Cpu請求儡首,容器啟動的初始可用數(shù)量
memory: string #內(nèi)存清楚,容器啟動的初始可用數(shù)量
livenessProbe: #對Pod內(nèi)個容器健康檢查的設(shè)置偏友,當(dāng)探測無響應(yīng)幾次后將自動重啟該容器椒舵,檢查方法有exec、httpGet和tcpSocket约谈,對一個容器只需設(shè)置其中一種方法即可
exec: #對Pod容器內(nèi)檢查方式設(shè)置為exec方式
command: [string] #exec方式需要制定的命令或腳本
httpGet: #對Pod內(nèi)個容器健康檢查方法設(shè)置為HttpGet,需要制定Path犁钟、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #對Pod內(nèi)個容器健康檢查方式設(shè)置為tcpSocket方式
port: number
initialDelaySeconds: 0 #容器啟動完成后首次探測的時間棱诱,單位為秒
timeoutSeconds: 0 #對容器健康檢查探測等待響應(yīng)的超時時間,單位秒涝动,默認(rèn)1秒
periodSeconds: 0 #對容器監(jiān)控檢查的定期探測時間設(shè)置迈勋,單位秒,默認(rèn)10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure] #Pod的重啟策略醋粟,Always表示一旦不管以何種方式終止運(yùn)行靡菇,kubelet都將重啟重归,OnFailure表示只有Pod以非0退出碼退出才重啟,Nerver表示不再重啟該P(yáng)od
nodeSelector: obeject #設(shè)置NodeSelector表示將該P(yáng)od調(diào)度到包含這個label的node上厦凤,以key:value的格式指定
imagePullSecrets: #Pull鏡像時使用的secret名稱鼻吮,以key:secretkey格式指定
- name: string
hostNetwork: false #是否使用主機(jī)網(wǎng)絡(luò)模式,默認(rèn)為false较鼓,如果設(shè)置為true椎木,表示使用宿主機(jī)網(wǎng)絡(luò)
volumes: #在該pod上定義共享存儲卷列表
- name: string #共享存儲卷名稱 (volumes類型有很多種)
emptyDir: {} #類型為emtyDir的存儲卷,與Pod同生命周期的一個臨時目錄博烂。為空值
hostPath: string #類型為hostPath的存儲卷香椎,表示掛載Pod所在宿主機(jī)的目錄
path: string #Pod所在宿主機(jī)的目錄,將被用于同期中mount的目錄
secret: #類型為secret的存儲卷禽篱,掛載集群與定義的secre對象到容器內(nèi)部
scretname: string
items:
- key: string
path: string
configMap: #類型為configMap的存儲卷畜伐,掛載預(yù)定義的configMap對象到容器內(nèi)部
name: string
items:
- key: string
path: string