1 Pod - 執行個體
Pod是一組緊密關聯的容器集合,支援多個容器在一個Pod中共享網絡和檔案系統,可以通過程序間通信和檔案共享這種簡單高效的方式完成服務,是Kubernetes排程的基本機關。Pod的設計理念是 每個Pod都有一個唯一的IP
Pod具有如下特征:
- 包含多個共享IPC、Network和UTC namespace的容器,可直接通過localhost通信
- 所有Pod内容器都可以通路共享的Volume,可以通路共享資料
- 優雅終止:Pod删除的時候先給其内的程序發送SIGTERM,等待一段時間(grace period)後才強制停止依然還在運作的程序
- 特權容器(通過SecurityContext配置)具有改變系統配置的權限(在網絡插件中大量應用)
- 支援三種重新開機政策(restartPolicy),分别是:Always、OnFailure、Never
- 支援三種鏡像拉取政策(imagePullPolicy),分别是:Always、Never、IfNotPresent
- 資源限制,Kubernetes通過CGroup限制容器的CPU以及記憶體等資源,可以設定request以及limit值
- 健康檢查,提供兩種健康檢查探針,分别是livenessProbe和redinessProbe,前者用于探測容器是否存活,如果探測失敗,則根據重新開機政策進行重新開機操作,後者用于檢查容器狀态是否正常,如果檢查容器狀态不正常,則請求不會到達該Pod
- Init container在所有容器運作之前執行,常用來初始化配置
- 容器生命周期鈎子函數,用于監聽容器生命周期的特定事件,并在事件發生時執行已注冊的回調函數,支援兩種鈎子函數:postStart和preStop,前者是在容器啟動後執行,後者是在容器停止前執行
2 Namespace - 命名空間
Namespace(命名空間)是對一組資源和對象的抽象集合,比如可以用來将系統内部的對象劃分為不同的項目組或者使用者組。常見的pod、service、replicaSet和deployment等都是屬于某一個namespace的(預設是default),而node, persistentVolumes等則不屬于任何namespace。
常用namespace操作:
# 查詢所有namespaces
kubectl get namespace
# 建立namespace
kubectl create namespace ns-name
# 删除namespace
kubectl delete namespace ns-name
删除命名空間時,需注意以下幾點:
- 删除一個namespace會自動删除所有屬于該namespace的資源。
- default 和 kube-system 命名空間不可删除。
- PersistentVolumes是不屬于任何namespace的,但PersistentVolumeClaim是屬于某個特定namespace的。
- Events是否屬于namespace取決于産生events的對象。
3 Node 節點
Node是Pod真正運作的主機,可以是實體機也可以是虛拟機。Node本質上不是Kubernetes來建立的, Kubernetes隻是管理Node上的資源。為了管理Pod,每個Node節點上至少需要運作container runtime(Docker)、kubelet和kube-proxy服務。
常用node操作:
# 查詢所有node
kubectl get nodes
# 将node标志為不可排程
kubectl cordon $nodename
# 将node标志為可排程
kubectl uncordon $nodename
taint(污點)
使用kubectl taint指令可以給某個Node節點設定污點,Node被設定上污點之後就和Pod之間存在了一種相斥的關系,可以讓Node拒絕Pod的排程執行,甚至将Node已經存在的Pod驅逐出去。每個污點的組成:
key=value:effect
,目前taint effect支援如下三個選項:
- NoSchedule:表示k8s将不會将Pod排程到具有該污點的Node上
- PreferNoSchedule:表示k8s将盡量避免将Pod排程到具有該污點的Node上
- NoExecute:表示k8s将不會将Pod排程到具有該污點的Node上,同時會将Node上已經存在的Pod驅逐出去
常用指令如下:
# 為節點node0設定不可排程污點
kubectl taint node node0 key1=value1:NoShedule
# 将node0上key值為key1的污點移除
kubectl taint node node0 key-
# 為kube-master節點設定不可排程污點
kubectl taint node node1 node-role.kubernetes.io/master=:NoSchedule
# 為kube-master節點設定盡量不可排程污點
kubectl taint node node1 node-role.kubernetes.io/master=PreferNoSchedule
容忍(Tolerations)
設定了污點的Node将根據taint的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之間産生互斥的關系,Pod将在一定程度上不會被排程到Node上。 但我們可以在Pod上設定容忍(Toleration),意思是設定了容忍的Pod将可以容忍污點的存在,可以被排程到存在污點的Node上。
4 Service 服務
Service是對一組提供相同功能的Pods的抽象,并為他們提供一個統一的入口,借助 Service 應用可以友善的實作服務發現與負載均衡,并實作應用的零當機更新。 Service通過标簽(label)來選取後端Pod,一般配合ReplicaSet或者Deployment來保證後端容器的正常運作。
service 有如下四種類型,預設是ClusterIP:
- ClusterIP: 預設類型,自動配置設定一個僅叢集内部可以通路的虛拟IP
- NodePort: 在ClusterIP基礎上為Service在每台機器上綁定一個端口,這樣就可以通過
來通路該服務NodeIP:NodePort
- LoadBalancer: 在NodePort的基礎上,借助cloud provider建立一個外部的負載均衡器,并将請求轉發到 NodeIP:NodePort
- ExternalName: 将服務通過DNS CNAME記錄方式轉發到指定的域名
另外,也可以将已有的服務以Service的形式加入到Kubernetes叢集中來,隻需要在建立 Service 的時候不指定Label selector,而是在Service建立好後手動為其添加endpoint。
5 Volume 存儲卷
預設情況下容器的資料是非持久化的,容器消亡以後資料也會跟着丢失,是以Docker提供了Volume機制以便将資料持久化存儲。Kubernetes提供了更強大的Volume機制和插件,解決了容器資料持久化以及容器間共享資料的問題。
Kubernetes存儲卷的生命周期與Pod綁定
- 容器挂掉後Kubelet再次重新開機容器時,Volume的資料依然還在
- Pod删除時,Volume才會清理。資料是否丢失取決于具體的Volume類型,比如emptyDir的資料會丢失,而PV的資料則不會丢
目前Kubernetes主要支援以下Volume類型:
- emptyDir:Pod存在,emptyDir就會存在,容器挂掉不會引起emptyDir目錄下的資料丢失,但是pod被删除或者遷移,emptyDir也會被删除
- hostPath:hostPath允許挂載Node上的檔案系統到Pod裡面去
- NFS(Network File System):網絡檔案系統,Kubernetes中通過簡單地配置就可以挂載NFS到Pod中,而NFS中的資料是可以永久儲存的,同時NFS支援同時寫操作。
- glusterfs:同NFS一樣是一種網絡檔案系統,Kubernetes可以将glusterfs挂載到Pod中,并進行永久儲存
- cephfs:一種分布式網絡檔案系統,可以挂載到Pod中,并進行永久儲存
- subpath:Pod的多個容器使用同一個Volume時,會經常用到
- secret:密鑰管理,可以将敏感資訊進行加密之後儲存并挂載到Pod中
- persistentVolumeClaim:用于将持久化存儲(PersistentVolume)挂載到Pod中
...
6 PersistentVolume(PV) 持久化存儲卷
PersistentVolume(PV)是叢集之中的一塊網絡存儲。跟 Node 一樣,也是叢集的資源。PersistentVolume (PV)和PersistentVolumeClaim (PVC)提供了友善的持久化卷: PV提供網絡存儲資源,而PVC請求存儲資源并将其挂載到Pod中。
PV的通路模式(accessModes)有三種:
- ReadWriteOnce(RWO):是最基本的方式,可讀可寫,但隻支援被單個Pod挂載。
- ReadOnlyMany(ROX):可以以隻讀的方式被多個Pod挂載。
- ReadWriteMany(RWX):這種存儲可以以讀寫的方式被多個Pod共享。
不是每一種存儲都支援這三種方式,像共享方式,目前支援的還比較少,比較常用的是 NFS。在PVC綁定PV時通常根據兩個條件來綁定,一個是存儲的大小,另一個就是 通路模式。
PV的回收政策(persistentVolumeReclaimPolicy)也有三種
- Retain,不清理保留Volume(需要手動清理)
- Recycle,删除資料,即 rm -rf /thevolume/* (隻有NFS和HostPath支援)
- Delete,删除存儲資源
7 Deployment 無狀态應用
一般情況下我們不需要手動建立Pod執行個體,而是采用更高一層的抽象或定義來管理Pod,針對無狀态類型的應用,Kubernetes使用Deloyment的Controller對象與之對應。其典型的應用場景包括:
- 定義Deployment來建立Pod和ReplicaSet
- 滾動更新和復原應用
- 擴容和縮容
- 暫停和繼續Deployment
常用的操作指令如下:
# 生成一個Deployment對象
kubectl run www --image=10.0.0.183:5000/hanker/www:0.0.1 --port=8080
# 查找Deployment
kubectl get deployment --all-namespaces
# 檢視某個Deployment
kubectl describe deployment www
# 編輯Deployment定義
kubectl edit deployment www
# 删除某Deployment
kubectl delete deployment www
# 擴縮容操作,即修改Deployment下的Pod執行個體個數
kubectl scale deployment/www --replicas=2
# 更新鏡像
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
# 復原操作
kubectl rollout undo deployment/nginx-deployment
# 檢視復原進度
kubectl rollout status deployment/nginx-deployment
# 啟用水準伸縮(HPA - horizontal pod autoscaling),設定最小、最大執行個體數量以及目标cpu使用率
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
# 暫停更新Deployment
kubectl rollout pause deployment/nginx-deployment
# 恢複更新Deployment
kubectl rollout resume deploy nginx
更新政策
.spec.strategy
指新的Pod替換舊的Pod的政策,有以下兩種類型
-
滾動更新,可以保證應用在更新期間,對外正常提供服務。RollingUpdate
-
重建政策,在建立出新的Pod之前會先殺掉所有已存在的Pod。Recreate
Deployment和ReplicaSet兩者之間的關系
- 使用Deployment來建立ReplicaSet。ReplicaSet在背景建立pod,檢查啟動狀态,看它是成功還是失敗。
- 當執行更新操作時,會建立一個新的ReplicaSet,Deployment會按照控制的速率将pod從舊的ReplicaSet移 動到新的ReplicaSet中
8 StatefulSet 有狀态應用
Deployments和ReplicaSets是為無狀态服務設計的,那麼StatefulSet則是為了有狀态服務而設計,其應用場景包括:
- 穩定的持久化存儲,即Pod重新排程後還是能通路到相同的持久化資料,基于PVC來實作
- 穩定的網絡标志,即Pod重新排程後其PodName和HostName不變,基于Headless Service(即沒有Cluster IP的Service)來實作
- 有序部署,有序擴充,即Pod是有順序的,在部署或者擴充的時候要依據定義的順序依次進行操作(即從0到N-1,在下一個Pod運作之前所有之前的Pod必須都是Running和Ready狀态),基于init containers來實作
- 有序收縮,有序删除(即從N-1到0)
支援兩種更新政策:
- OnDelete:當
更新時,并不立即删除舊的Pod,而是等待使用者手動删除這些舊Pod後自動建立新Pod。這是預設的更新政策,相容v1.6版本的行為.spec.template
- RollingUpdate:當
更新時,自動删除舊的Pod并建立新Pod替換。在更新時這些Pod是按逆序的方式進行,依次删除、建立并等待Pod變成Ready狀态才進行下一個Pod的更新。.spec.template
9 DaemonSet 守護程序集
DaemonSet保證在特定或所有Node節點上都運作一個Pod執行個體,常用來部署一些叢集的日志采集、監控或者其他系統管理應用。典型的應用包括:
- 日志收集,比如fluentd,logstash等
- 系統監控,比如Prometheus Node Exporter,collectd等
- 系統程式,比如kube-proxy, kube-dns, glusterd, ceph,ingress-controller等
指定Node節點
DaemonSet會忽略Node的unschedulable狀态,有兩種方式來指定Pod隻運作在指定的Node節點上:
- nodeSelector:隻排程到比對指定label的Node上
- nodeAffinity:功能更豐富的Node選擇器,比如支援集合操作
- podAffinity:排程到滿足條件的Pod所在的Node上
目前支援兩種政策
- OnDelete: 預設政策,更新模闆後,隻有手動删除了舊的Pod後才會建立新的Pod
- RollingUpdate: 更新DaemonSet模版後,自動删除舊的Pod并建立新的Pod
10 Ingress 負載均衡
Kubernetes中的負載均衡我們主要用到了以下兩種機制:
- Service:使用Service提供叢集内部的負載均衡,Kube-proxy負責将service請求負載均衡到後端的Pod中
- Ingress Controller:使用Ingress提供叢集外部的負載均衡
Service和Pod的IP僅可在叢集内部通路。叢集外部的請求需要通過負載均衡轉發到service所在節點暴露的端口上,然後再由kube-proxy通過邊緣路由器将其轉發到相關的Pod,Ingress可以給service提供叢集外部通路的URL、負載均衡、HTTP路由等,為了配置這些Ingress規則,叢集管理者需要部署一個Ingress Controller,它監聽Ingress和service的變化,并根據規則配置負載均衡并提供通路入口。
常用的ingress controller:
- nginx
- traefik
- Kong
- Openresty
11 Job & CronJob 任務和定時任務
Job負責批量處理短暫的一次性任務 (short lived one-off tasks),即僅執行一次的任務,它保證批處理任務的一個或多個Pod成功結束。
CronJob即定時任務,就類似于Linux系統的crontab,在指定的時間周期運作指定的任務。
12 HPA(Horizontal Pod Autoscaling) 水準伸縮
Horizontal Pod Autoscaling可以根據CPU、記憶體使用率或應用自定義metrics自動擴充Pod數量 (支援replication controller、deployment和replica set)。
- 控制管理器預設每隔30s查詢metrics的資源使用情況(可以通過 --horizontal-pod-autoscaler-sync-period 修改)
- 支援三種metrics類型
1)預定義metrics(比如Pod的CPU)以使用率的方式計算
2)自定義的Pod metrics,以原始值(raw value)的方式計算
3)自定義的object metrics
- 支援兩種metrics查詢方式:Heapster和自定義的REST API
- 支援多metrics
可以通過如下指令建立HPA:
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
13 Service Account
Service account是為了友善Pod裡面的程序調用Kubernetes API或其他外部服務而設計的
授權
Service Account為服務提供了一種友善的認證機制,但它不關心授權的問題。可以配合RBAC(Role Based Access Control)來為Service Account鑒權,通過定義Role、RoleBinding、ClusterRole、ClusterRoleBinding來對sa進行授權。
14 Secret 密鑰
Sercert-密鑰解決了密碼、token、密鑰等敏感資料的配置問題,而不需要把這些敏感資料暴露到鏡像或者Pod Spec中。Secret可以以Volume或者環境變量的方式使用。有如下三種類型:
- Service Account:用來通路Kubernetes API,由Kubernetes自動建立,并且會自動挂載到Pod的 /run/secrets/kubernetes.io/serviceaccount 目錄中;
- Opaque:base64編碼格式的Secret,用來存儲密碼、密鑰等;
- kubernetes.io/dockerconfigjson: 用來存儲私有docker registry的認證資訊。
15 ConfigMap 配置中心
ConfigMap用于儲存配置資料的鍵值對,可以用來儲存單個屬性,也可以用來儲存配置檔案。ConfigMap跟secret很類似,但它可以更友善地處理不包含敏感資訊的字元串。ConfigMap可以通過三種方式在Pod中使用,三種分别方式為:設定環境變量、設定容器指令行參數以及在Volume中直接挂載檔案或目錄。
可以使用 kubectl create configmap從檔案、目錄或者key-value字元串建立等建立 ConfigMap。也可以通過 kubectl create -f value.yaml 建立。
16 Resource Quotas 資源配額
資源配額(Resource Quotas)是用來限制使用者資源用量的一種機制。
資源配額有如下類型:
- 計算資源,包括cpu和memory
1)cpu, limits.cpu, requests.cpu
2)memory, limits.memory, requests.memory
- 存儲資源,包括存儲資源的總量以及指定storage class的總量
1)requests.storage:存儲資源總量,如500Gi
2)persistentvolumeclaims:pvc的個數
3).storageclass.storage.k8s.io/requests.storage
4).storageclass.storage.k8s.io/persistentvolumeclaims
- 對象數,即可建立的對象的個數
1)pods, replicationcontrollers, configmaps, secrets
2)resourcequotas, persistentvolumeclaims
3)services, services.loadbalancers, services.nodeports
它的工作原理為:
資源配額應用在Namespace上,并且每個Namespace最多隻能有一個 ResourceQuota 對象
開啟計算資源配額後,建立容器時必須配置計算資源請求或限制(也可以 用LimitRange設定預設值)
使用者超額後禁止建立新的資源