【Kubernetes系列】第2篇 基礎概念介紹

HankerCloud發表於2019-09-06

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 滾動升級,可以保證應用在升級期間,對外正常提供服務。
  • Recreate 重建策略,在建立出新的Pod之前會先殺掉所有已存在的Pod。

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:當 .spec.template更新時,並不立即刪除舊的Pod,而是等待使用者手動刪除這些舊Pod後自動建立新Pod。這是預設的更新策略,相容v1.6版本的行為
  • RollingUpdate:當  .spec.template 更新時,自動刪除舊的Pod並建立新Pod替換。在更新時這些Pod是按逆序的方式進行,依次刪除、建立並等待Pod變成Ready狀態才進行下一個Pod的更新。

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型別

    • 預定義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

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

    • 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設定預設值)
  • 使用者超額後禁止建立新的資源



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69947382/viewspace-2656273/,如需轉載,請註明出處,否則將追究法律責任。

相關文章