Kubernetes核心概念介紹
Kubernetes是一個可輕便的,可拓展的開源平臺,為管理容器與服務提供便利的配置以及自動化.現已有著很龐大以及快速增長的生態系統.
Kubernetes還有一個重要的思想就是一切皆容器.
k8s是kubernetes的簡稱,8代指是ubernete.
關鍵概念
node
一個節點可以是VM虛擬機器或者物理機,部署service執行pod.由Master元件管理.
pod
在K8s當中能夠被建立以及排程的最小單元,並不是單個容器,一個Pod是由若干個容器組成.Pod容器內共享Network space.
- IP等網路資源分配的單位的基本單位.
- 共享Volume
- 同一個pod內的容器可以功能性IPC(訊息佇列等),共享主機名.
service
service其實就是一組pods的集合抽象定義.
service可以由Label Selector選出pods.
pod的IP地址會隨著pod生命週期消亡而變更,但service的IP不會產生變更,這樣可以很好的標識一個服務.
其實通過概念可以看出Service其實不是真正提供服務的因此,他需要將TCP/UDP的流量轉發到實際的Endpoints(實際是由Service的selector選擇出的Pod).
還有一點是Service可以直接通過設定ExternalIP(公網IP)訪問到內部應用服務.
網路
Docker Mode
Docker中同一主機內容器通過虛擬橋接進行通訊,預設情況下這個網路是host-private(私有網路).因此Docker容器在各個節點互不相同.
如果需要進行跨節點進行通訊,需要在每臺主機上開啟埠,Docker代理並轉發這個埠的流量到容器中,從而實現跨節點通訊.
Kubernetes實現
Kubernetes網路實現概念:
1.所有的容器可以不基於NAT互相通訊
2.所有的節點可以和容器進行不基於NAT通訊
3.IP地址對容器內外都是一致
NAT:網路地址轉換.
pod當中的容器位於同一個NetworkNamespace,因此它們是共享IP的,同一個pod可以通過localhost進行訪問.這個是通過Docker的--net=--net=container:<id>
KubeProxy
用於流量轉發每個節點都會存在KubeProxy.為每個服務生成一個虛擬的IP,並由三種(IPVS,iptables,usersapce)方式轉發到Pods中.
IPVS還是beta版,這裡先只介紹一下兩種方式:
- iptables:預設模式,kubeproxy不參與真正的流量轉發,實時監聽endpoints與service的變化控制iptables的轉發規則.實際流量的轉發是由iptables進行.因此相比與userspace模式速度更快,流量的轉發只是在核心.
- userspace:將實際service中cluster的IP通過iptables轉發到kube-proxy代理的埠中然後kube-proxy在轉到對應的pod當中.
MASTER元件
MASTER元件可以執行到任叢集的何節點,也可以實現高可用.執行這些元件的節點成為主節點.
這些元件為叢集提供控制層.這些主要元件做一些主要的決策例如排程,發現和響應叢集事件.
- kube-apiserver
位於MASTER節點,暴露K8s的介面 - etcd
提供一致性和高可用的持久化的鍵值儲存服務. - kube-scheduler
觀察是否有新的pod建立,如果有新的pod建立並且沒有分配節點,為pod分配節點並執行. - kube-controller-manager
- Node Controller:當節點停止時傳送通知和進行響應.
- Replication Controller:維護pod在節點設定的正確執行的副本數量.可以用於灰度釋出,滾動更新,多版本追蹤等
- Endpoints Controller:用於維護Services與endpoint的關係.
- Service Account & Token Controllers:為新的名稱空間建立下預設的賬戶與API的access token.
Node Component
Node Component執行在每一個節點之上,維護執行的pods,以及k8s的環境.
- Kubelet
叢集當中每個節點的代理,確保在一個pod中的容器處於執行狀態. - kube-proxy
能夠讓k8s通過維護在主機的網路規則以及連線代理進行服務抽象. - Container Runtime
是承擔容器執行的軟體
Addons
附加元件都屬於kube-system名稱空間,不是必須元件,但是這裡只介紹一個DNS元件.
DNS
Cluster DNS是一個叢集的DNS服務.容器啟動時在DNS查詢之時會使用DNS服務.
Namespaces
使用不同的名稱空間是為了分割資源,使用標籤來區分資源在同一名稱空間下.
可以在多個名稱空間存在相同的名字,但是在單個名稱空間下只能存在一個.
Label 與 Selector
Label使用鍵值儲存,關鍵做用是用於區分不同的物件.可以用來選擇區分不同的物件.
命名規則
Label的key分為字首以及名字.
Key 規則如下:
1.名字必須不超過63個字元,且以字母開頭,可由[\.-_a-zA-Z0-9]
構成.
2.字首必須是域名加/
,不超過253個字元.
3.如果字首不存在那麼k8s會假設這個Key是這個使用者私有.
Value規則:
不超過63個字元且以字母開頭可由[\.-_a-zA-Z0-9]
構成.
進行選擇
目前只支援基於集合和基於相等,並列條件可以在每個選擇條件之間加入,
表示邏輯&&
.
基於集合
支援的字元:in not in exists not exists
exists
的語法是直接寫Key的名稱,下述例子是查詢env為qa,dev,prod,且包含partition的key,且不包含notincluded的key.
env in (qa, dev, prod),partition,!notincluded
基於相等
支援的字元:= != ==
.
=
與==
是等價的都表示相等條件.
使用示例:
選出pods當中label中的key為env,value為prod
kubectl get pods -l 'env=prod,partition in (1)'
deployment
主要為了操作部署replicaset與pod.
功能:可以進行橫向擴充套件,藍綠髮布,金絲雀釋出,灰度釋出,多版本釋出等.
除此之外可已根據對應的釋出版本的歷史記錄進行回滾.
當然我們也可以設定自己的策略,當我們部署的pods或者需要更新pods沒有正常執行而異常退出,deployment controller會根據設定的策略對部署的pods進行重新部署.
配置示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
#指定副本數量
replicas: 3
selector:
matchLabels:
app: nginx
#pod的模板資訊
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
replicaset
主要作用:確保當前執行數量的pods.
官方不推薦直接使用replicaset進行操作,而推薦使用deployment.
其與replication controller最主要的區別是replicaset中selector支援集合操作.
Jobs
一個Job建立一個或者多個pods確保明確的執行數量成功執行.
主要存在下述三種類型:
1.非平行工作:通常啟動一個pod,當pod成功退出,任務就被完成.
2.固定執行任務數的平行工作:指定了.spec.completions
非0正數值,當執行成功的pod滿足了.spec.completions
的值時,那麼任務就會被完成
3.平行工作:每個pod都在執行job,只要有任一一個job中的工作完成,那麼其他的pod也會終止job.
CronJob
CronJob是類似於Crond服務的計劃工作模式.
配置要求:
1.Kubernetes版本大於1.8
2.對於小於1.8版本的需要在啟動時增加--runtime-config=batch/v2alpha1=true
配置項
簡單的配置要求
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
Volume
k8s支援很多種型別的Volume.這裡簡單介紹幾種Volume.
Volume宣告是在pod當中,因此pod的內的容器共享Volume.
pod中程序看到容器的內的檔案系統由兩部分組成:
1.Docker映象檔案系統
2.若干個Volume
ConfigMap
ConfigMap可以用於儲存一些配置資料,變數等.不適合儲存大型檔案.
示例:
apiVersion: v1
data:
allowed: '"true"'
enemies: aliens
lives: "3"
kind: ConfigMap
metadata:
creationTimestamp: 2017-12-27T18:36:28Z
name: game-config-env-file
namespace: default
resourceVersion: "809965"
selfLink: /api/v1/namespaces/default/configmaps/game-config-env-file
uid: d9d1ca5b-eb34-11e7-887b-42010a8002b8
secret
secret 可用於儲存一些加密的資訊以檔案的形式傳給pod.
persistentVolume
持久化volume,獨立於pod的生命週期.指定資源型別,大小,儲存型別等等.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
persistentVolumeClaim
對於PersistentVolume的資源請求(分配),被用於掛載persistentVolume到pod上,不需要關心底層的儲存環境無論是GCE或者是ISCSI.
通過多個pod使用供用的PVC我們可以實現,不同的之間共享資料.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
pod使用emptDir型別Volume使用示例
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}