Pod是一組緊密關聯的容器集合,支持多個容器在一個Pod中共享網絡和文件系統,能夠經過進程間通訊和文件共享這種簡單高效的方式完成服務,是Kubernetes調度的基本單位。Pod的設計理念是 每一個Pod都有一個惟一的IPphp
Pod具備以下特徵:node
包含多個共享IPC、Network和UTC namespace的容器,可直接經過localhost通訊 nginx
全部Pod內容器均可以訪問共享的Volume,能夠訪問共享數據 docker
優雅終止:Pod刪除的時候先給其內的進程發送SIGTERM,等待一段時間(grace period)後才強制中止依然還在運行的進程 apache
特權容器(經過SecurityContext配置)具備改變系統配置的權限(在網絡插件中大量應用)json
支持三種重啓策略(restartPolicy),分別是:Always、OnFailure、Never後端
支持三種鏡像拉取策略(imagePullPolicy),分別是:Always、Never、IfNotPresentbash
資源限制,Kubernetes經過CGroup限制容器的CPU以及內存等資源,能夠設置request以及limit值網絡
健康檢查,提供兩種健康檢查探針,分別是livenessProbe和redinessProbe,前者用於探測容器是否存活,若是探測失敗,則根據重啓策略進行重啓操做,後者用於檢查容器狀態是否正常,若是檢查容器狀態不正常,則請求不會到達該Pod負載均衡
Init container在全部容器運行以前執行,經常使用來初始化配置
容器生命週期鉤子函數,用於監聽容器生命週期的特定事件,並在事件發生時執行已註冊的回調函數,支持兩種鉤子函數:postStart和preStop,前者是在容器啓動後執行,後者是在容器中止前執行
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的對象。
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上。
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。
默認狀況下容器的數據是非持久化的,容器消亡之後數據也會跟着丟失,因此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中
...
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,刪除存儲資源
通常狀況下咱們不須要手動建立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` 滾動升級,能夠保證應用在升級期間,對外正常提供服務。
`Recreate` 重建策略,在建立出新的Pod以前會先殺掉全部已存在的Pod。
Deployment和ReplicaSet二者之間的關係
使用Deployment來建立ReplicaSet。ReplicaSet在後臺建立pod,檢查啓動狀態,看它是成功仍是失敗。
當執行更新操做時,會建立一個新的ReplicaSet,Deployment會按照控制的速率將pod從舊的ReplicaSet移 動到新的ReplicaSet中
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:當`.spec.template`更新時,並不當即刪除舊的Pod,而是等待用戶手動刪除這些舊Pod後自動建立新Pod。這是默認的更新策略,兼容v1.6版本的行爲
RollingUpdate:當 `.spec.template` 更新時,自動刪除舊的Pod並建立新Pod替換。在更新時這些Pod是按逆序的方式進行,依次刪除、建立並等待Pod變成Ready狀態才進行下一個Pod的更新。
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
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
Job負責批量處理短暫的一次性任務 (short lived one-off tasks),即僅執行一次的任務,它保證批處理任務的一個或多個Pod成功結束。
CronJob即定時任務,就相似於Linux系統的crontab,在指定的時間週期運行指定的任務。
Horizontal Pod Autoscaling能夠根據CPU、內存使用率或應用自定義metrics自動擴展Pod數量 (支持replication controller、deployment和replica set)。
控制管理器默認每隔30s查詢metrics的資源使用狀況(能夠經過 --horizontal-pod-autoscaler-sync-period 修改)
支持三種metrics類型
預約義metrics(好比Pod的CPU)以利用率的方式計算
自定義的Pod metrics,以原始值(raw value)的方式計算
自定義的object metrics
支持兩種metrics查詢方式:Heapster和自定義的REST API
支持多metrics
能夠經過以下命令建立HPA:
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10複製代碼
Service account是爲了方便Pod裏面的進程調用Kubernetes API或其餘外部服務而設計的
受權
Service Account爲服務提供了一種方便的認證機制,但它不關心受權的問題。能夠配合RBAC(Role Based Access Control)來爲Service Account鑑權,經過定義Role、RoleBinding、ClusterRole、ClusterRoleBinding來對sa進行受權。
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的認證信息。
ConfigMap用於保存配置數據的鍵值對,能夠用來保存單個屬性,也能夠用來保存配置文件。ConfigMap跟secret很相似,但它能夠更方便地處理不包含敏感信息的字符串。ConfigMap能夠經過三種方式在Pod中使用,三種分別方式爲:設置環境變量、設置容器命令行參數以及在Volume中直接掛載文件或目錄。
可使用 kubectl create configmap從文件、目錄或者key-value字符串建立等建立 ConfigMap。也能夠經過 kubectl create -f value.yaml 建立。
資源配額(Resource Quotas)是用來限制用戶資源用量的一種機制。
資源配額有以下類型:
計算資源,包括cpu和memory
cpu, limits.cpu, requests.cpu
memory, limits.memory, requests.memory
存儲資源,包括存儲資源的總量以及指定storage class的總量
requests.storage:存儲資源總量,如500Gi
persistentvolumeclaims:pvc的個數
.storageclass.storage.k8s.io/requests.storage
.storageclass.storage.k8s.io/persistentvolumeclaims
對象數,便可建立的對象的個數
pods, replicationcontrollers, configmaps, secrets
resourcequotas, persistentvolumeclaims
services, services.loadbalancers, services.nodeports
它的工做原理爲:
資源配額應用在Namespace上,而且每一個Namespace最多隻能有一個 ResourceQuota 對象
開啓計算資源配額後,建立容器時必須配置計算資源請求或限制(也能夠 用LimitRange設置默認值)
用戶超額後禁止建立新的資源