1. 集羣架構php
1.1. Nodes(節點)node
一個節點就是Kubernetes中的一個工做機器,一個節點多是一臺虛擬機,也多是一臺物理機。linux
每一個節點都包含運行pods所需的服務,並由master組件管理。nginx
節點上的服務包括container runtime、kubelet和kube-proxy。web
1.1.1. 節點狀態redis
節點的狀態包含如下信息:docker
# 查看節點列表
kubectl get nodes
# 查看節點狀態
kubectl describe node <insert-node-name-here>
示例:api
localhost-2:~ chengjiansheng$ kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready master 3d2h v1.16.2 localhost-2:~ chengjiansheng$ kubectl describe node minikube Name: minikube Roles: master Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux kubernetes.io/arch=amd64 kubernetes.io/hostname=minikube kubernetes.io/os=linux node-role.kubernetes.io/master= Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock node.alpha.kubernetes.io/ttl: 0 volumes.kubernetes.io/controller-managed-attach-detach: true CreationTimestamp: Sat, 16 Nov 2019 18:58:34 +0800 Taints: <none> Unschedulable: false Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- MemoryPressure False Tue, 19 Nov 2019 21:21:27 +0800 Sat, 16 Nov 2019 18:58:30 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure False Tue, 19 Nov 2019 21:21:27 +0800 Sat, 16 Nov 2019 18:58:30 +0800 KubeletHasNoDiskPressure kubelet has no disk pressure PIDPressure False Tue, 19 Nov 2019 21:21:27 +0800 Sat, 16 Nov 2019 18:58:30 +0800 KubeletHasSufficientPID kubelet has sufficient PID available Ready True Tue, 19 Nov 2019 21:21:27 +0800 Sat, 16 Nov 2019 18:58:30 +0800 KubeletReady kubelet is posting ready status Addresses: InternalIP: 192.168.99.111 Hostname: minikube Capacity: cpu: 2 ephemeral-storage: 17784772Ki hugepages-2Mi: 0 memory: 1985612Ki pods: 110 Allocatable: cpu: 2 ephemeral-storage: 17784772Ki hugepages-2Mi: 0 memory: 1985612Ki pods: 110 System Info: Machine ID: 0ea5d1f0d9bc427f83fd59da99157a63 System UUID: f2aed72a-64ac-4016-8cb4-eaa2ce6afea5 Boot ID: 8c476881-65ed-419a-aee5-ccc4adaa7527 Kernel Version: 4.19.76 OS Image: Buildroot 2019.02.6 Operating System: linux Architecture: amd64 Container Runtime Version: docker://18.9.9 Kubelet Version: v1.16.2 Kube-Proxy Version: v1.16.2 Non-terminated Pods: (12 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE --------- ---- ------------ ---------- --------------- ------------- --- default hello-minikube-6cf65d8776-7lkkt 0 (0%) 0 (0%) 0 (0%) 0 (0%) 6d14h kube-system coredns-67c766df46-hhxh8 100m (5%) 0 (0%) 70Mi (3%) 170Mi (8%) 6d17h kube-system coredns-67c766df46-p2hh9 100m (5%) 0 (0%) 70Mi (3%) 170Mi (8%) 6d17h kube-system etcd-minikube 0 (0%) 0 (0%) 0 (0%) 0 (0%) 6d17h kube-system kube-addon-manager-minikube 5m (0%) 0 (0%) 50Mi (2%) 0 (0%) 6d17h kube-system kube-apiserver-minikube 250m (12%) 0 (0%) 0 (0%) 0 (0%) 6d17h kube-system kube-controller-manager-minikube 200m (10%) 0 (0%) 0 (0%) 0 (0%) 6d17h kube-system kube-proxy-8zzlz 0 (0%) 0 (0%) 0 (0%) 0 (0%) 6d17h kube-system kube-scheduler-minikube 100m (5%) 0 (0%) 0 (0%) 0 (0%) 6d17h kube-system storage-provisioner 0 (0%) 0 (0%) 0 (0%) 0 (0%) 6d17h kubernetes-dashboard dashboard-metrics-scraper-76585494d8-2w8md 0 (0%) 0 (0%) 0 (0%) 0 (0%) 6d11h kubernetes-dashboard kubernetes-dashboard-57f4cb4545-mqxxn 0 (0%) 0 (0%) 0 (0%) 0 (0%) 6d11h Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 755m (37%) 0 (0%) memory 190Mi (9%) 340Mi (17%) ephemeral-storage 0 (0%) 0 (0%) Events: <none>
conditions字段描述全部Running節點的狀態。 安全
若是Ready條件的狀態在長時間內保持Unknown或爲False,而且持續時間超過pod-eviction-timeout所指定的時間的話,那麼會向kube-controller-manager傳遞一個參數,節點控制器將調度節點上的全部pod進行刪除。默認的清除超時時間是5分鐘。在某些狀況下,當節點不可用時,apiserver沒法與節點上的kubelet通訊。在與apiserver從新創建通訊以前,不能將刪除沒法與kubelet通訊pods的決定傳達給kubelet。與此同時,計劃刪除的pods能夠繼續在分區節點上運行。服務器
在1.5及更高版本中,節點控制器不會強制刪除pod,直到確認它們已中止在集羣中運行。你能夠看到在一個不可到達的節點上運行的pod一直處於Terminating或Unknown狀態。在Kubernetes沒法從底層基礎設施推斷出某個節點是否永久離開了集羣的狀況下,集羣管理員可能須要手工刪除節點對象。從Kubernetes中刪除節點對象將致使在該節點上運行的全部Pod對象從apiserver中刪除,並釋放它們的名稱。
Capacity 和 Allocatable 字段,描述節點上可用的資源:CPU、內存和能夠在節點上調度的最大pods數。
Capacity塊中的字段表示節點擁有的資源總量。
Allocatable塊表示一個節點上可供普通Pods使用的資源數量。
1.1.1. 節點管理
與pods和services不一樣,node不是由Kubernetes建立的:它是由諸如谷歌計算引擎之類的雲提供商在外部建立的,或者它存在於一組物理或虛擬機中。所以,當Kubernetes建立一個節點時,它建立一個表示該節點的對象。建立以後,Kubernetes檢查節點是否有效。
Kubernetes在內部建立一個節點對象來表示,並經過基於metada.name字段的健康檢查來驗證節點。若是節點是有效的,也就是說,若是全部必需的服務都在運行,那麼它就有資格運行pod。不然,對於任何集羣活動都將忽略它,直到它變得有效爲止。
目前,有三個組件與Kubernetes節點接口交互:node controller、kubelet和kubectl。
Node Controller
節點控制器是管理節點各個方面的Kubernetes master組件。
第一個是在節點註冊時爲其分配CIDR塊(若是打開了CIDR分配)。
第二個是使節點控制器的內部節點列表與雲提供商的可用機器列表保持最新。在雲環境中運行時,每當某個節點不健康時,節點控制器就會詢問雲提供商該節點的VM是否仍然可用。不然,節點控制器將從節點列表中刪除節點。
第三是監控節點的健康情況。節點控制器每隔--node-monitor-period秒檢查每一個節點的狀態。
1.2. Master-Node Communication(主節點通訊)
1.2.1. Cluster to Master
從集羣到主服務器的全部通訊路徑都終止於apiserver(其餘的主組件都不是爲了公開遠程服務而設計的)。在典型的部署中,apiserver被配置爲偵聽安全HTTPS端口(443)上的遠程鏈接,而且啓用了一種或多種形式的客戶端身份驗證。
但願鏈接到apiserver的pod能夠經過利用服務賬戶來實現安全鏈接,以便Kubernetes在pod實例化時自動將公共根證書和有效的承載令牌注入到pod中。kubernetes服務(在全部名稱空間中)配置了一個虛擬IP地址,該地址(經過kube-proxy)重定向到apiserver上的HTTPS端點。
所以,默認狀況下,從集羣(節點和在節點上運行的pod)到主服務器的鏈接的默認操做模式是安全的,能夠在不可信的和/或公共網絡上運行。
1.2.2. Master to Cluster
從master(apiserver)到cluster有兩條主要通訊路徑。第一個是從apiserver到kubelet進程,它在集羣中的每一個節點上運行。第二種是經過apiserver的代理功能從apiserver到任何節點、pod或服務。
apiserver to kubelet
從apiserver到kubelet的鏈接用於:
默認狀況下,apiserver不驗證kubelet的服務證書,這使得鏈接容易受到中間人攻擊,在不可信的和/或公共網絡上運行不安全。爲了校驗此鏈接,請使用--kubelet-certificate-authority標誌爲apiserver提供一個根證書包,用於驗證kubelet的服務證書。
apiserver to nodes, pods, and services
從apiserver到節點、pod或服務的鏈接默認爲純HTTP鏈接,所以既不進行身份驗證,也不進行加密。他們能夠運行在一個安全的HTTPS鏈接經過加前綴HTTPS,但他們不會驗證證書提供的HTTPS端點也提供客戶端憑證因此當鏈接將被加密,它不會提供任何擔保的完整性。這些鏈接目前在不可信和/或公共網絡上運行是不安全的。
1.3. Controllers
在Kubernetes中,控制器是監視集羣狀態的控制迴路,而後根據須要進行或請求更改。每一個控制器都試圖將當前集羣狀態移動到更接近指望的狀態。
2. Containers(容器)
2.1. Images(鏡像)
爲了在Kubernetes pod中引用鏡像,你必須首先建立Docker鏡像,並推送至鏡像倉庫。容器的image屬性支持與docker命令相同的語法 。
2.1.1. 更新鏡像
默認的拉取策略是IfNotPresent,它會致使Kubelet跳過拉取一個已經存在的鏡像。
若是你但願老是強制拉取,能夠採用如下任意一種方式:
2.1.2. 使用私有倉庫
https://cr.console.aliyun.com/cn-hangzhou/new
3. Workloads
3.1. Pods
Pod是Kubernetes應用程序的基本執行單元,建立或部署的Kubernetes對象模型中最小、最簡單的單元。Pod表明在集羣上運行的進程。
一個Pod封裝了一個應用程序的容器(在某些狀況下是多個容器)、存儲資源、一個惟一的網絡IP和控制容器如何運行的選項。
一個Pod表明一個部署單元:Kubernetes中的應用程序的一個單個實例,它可能由單個容器或少許緊密耦合且共享資源的容器組成。
Docker是Kubernetes Pod中最經常使用的容器運行時,可是Pods也支持其餘容器運行時。
Pods在Kubernetes集羣中主要有兩種使用方式:
Each Pod is meant to run a single instance of a given application. If you want to scale your application horizontally (e.g., run multiple instances), you should use multiple Pods, one for each instance. In Kubernetes, this is generally referred to as replication. Replicated Pods are usually created and managed as a group by an abstraction called a Controller.
每一個Pod表明運行一個給定應用的一個單個實例。若是你想要水平擴展你的應用(例如,運行多個實例),你應該用多個Pods,每一個實例一個Pod。在Kubernetes中,一般稱之爲副本。副本Pods一般做爲一個組被一個控制器建立和管理。
Pods如何管理多個容器
Pods被設計成支持多個協做流程(做爲容器),造成一個內聚的服務單元。Pod中的容器會自動在集羣中的同一物理或虛擬機上同時定位和調度。容器能夠共享資源和依賴項,彼此通訊,以及協調什麼時候以及如何終止它們。
請注意,在單個Pod中分組多個共存和共同管理的容器是一個相對高級的用例。你應該僅在容器緊密耦合的特定實例中使用此模式。例如,可能有一個容器充當共享卷中的文件的web服務器,還有一個單獨的「sidecar」容器,用於從遠程源更新這些文件,以下圖所示:
有些pod有init容器和app容器。Init容器在應用程序容器啓動以前運行並完成。
Pods爲組成它的容器們提供兩種共享資源:網絡和存儲。
網絡
每一個Pod被分配一個惟一的IP地址。Pod中的每一個容器共享網絡命名空間,包括IP地址和網絡端口。Pod中的容器可使用localhost彼此通訊。當Pod中的容器與Pod外的實體通訊時,它們必須協調如何使用共享的網絡資源(如端口)。
存儲
一個Pod能夠指定一組共享存儲卷。Pod中的全部容器均可以訪問共享卷,從而容許這些容器共享數據。卷還容許在Pod中保存持久數據,以防須要從新啓動其中一個容器。
3.1.1. Pods and Controllers
一般,不多直接在kubernetes中建立單獨的Pods,這是由於Pod被設計成相對短暫的一次性實體。當Pod被建立時(直接建立,或間接由控制器建立)),它將被調度到在集羣中的節點上運行。Pod將一直在該節點上,直到進程終止、刪除Pod對象、因爲缺少資源而驅逐Pod或節點失敗。
Pods沒法自愈(自動恢復)。若是將Pod調度到失敗的節點,或者調度操做自己失敗,則Pod將被刪除。一樣,若是因爲缺少資源或節點維護,Pod也將被刪除。Kubernetes使用一個更高層次的抽象,稱爲控制器,它處理管理相對可丟棄的Pod實例的工做。所以,雖然能夠直接操做Pod,但在Kubernetes中使用控制器來管理Pod要常見得多。
一個Controller能夠爲你建立和管理多個Pods,並處理副本和rollout,以及集羣範圍內提供自修復功能。例如,若是一個節點失敗,控制器可能經過在不一樣的節點上調度相同的副原本自動替換Pod。
控制器使用Pod模板來製做實際的Pod。下面是一個例子:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
3.2. Pod是什麼
一個Pod(就像一個豌豆莢)是一個組,這個組中包含一個或多個容器(好比,Docker容器),具備共享存儲/網絡,以及如何運行容器的規範。Pod的內容老是同時定位和同時調度,並在共享上下文中運行。Pod爲特定於應用程序的「邏輯主機」創建模型,它包含一個或多個相對緊密耦合的應用程序容器,在容器以前的世界中,在相同的物理或虛擬機上執行意味着在相同的邏輯主機上執行。
Docker是最多見的容器運行時。
Pod中的容器共享一個IP地址和端口空間,而且能夠經過localhost相互查找。它們還可使用SystemV信號量或POSIX共享內存等標準進程間通訊進行通訊。不一樣Pods中的容器有不一樣的IP地址,沒有特殊配置的狀況下是不能經過IPC進行通訊的。這些容器一般經過Pod IP地址彼此通訊。
Pod中的應用程序也能夠訪問共享volumes,這些共享volumes被定義爲Pod的一部分,能夠安裝到每一個應用程序的文件系統中。
在Docker構造方面,Pod被建模爲一組Docker容器,它們具備共享的名稱空間和共享的文件系統volumes。
與單個應用程序容器同樣,Pods被認爲是相對短暫的(而不是持久的)實體。正如在pod生命週期中所討論的,建立pod,分配唯一ID (UID),並將其調度到節點,直到終止(根據重啓策略)或刪除。若是一個節點死亡,那麼在超時以後,該節點的Pods將被刪除。給定的Pod(由UID定義)不會「從新調度」到一個新節點;相反,它能夠被一個相同的Pod替換,若是須要,甚至可使用相同的名稱,可是要使用一個新的UID。
若是Pod被刪除,那麼與之相關聯的資源都會被銷燬,並在必要的時候從新建立。
3.2.1. Pods的動機
Pods是一個模型,這種模型就是將多個協做流程內聚成一個服務。它們經過提供比其組成應用程序集更高級別的抽象來簡化應用程序部署和管理。Pods能夠做爲部署、水平擴展和副本的單元。在Pods中,託管(協同調度)、共享命運(例如終止)、協調副本、資源共享和依賴項管理都是自動處理的。
Pods使得數據共享和成員之間的通訊成爲可能。
在一個Pod中的全部應用程序都使用相同的網絡名稱空間(即,相同的IP和端口),所以應用之間能夠「找到」彼此並使用localhost進行通訊。所以,Pod中的應用程序必須協調它們對端口的使用。每一個Pod在平面共享網絡空間中都有一個IP地址,能夠經過網絡與其它物理計算機和Pod進行徹底通訊。
除了定義在Pod中運行的應用程序容器外,Pod還指定一組共享存儲volumes。Volumes使數據可以在容器重啓後繼續存在,並在Pod內的應用程序之間共享。
爲何不在一個(Docke)容器中運行多個應用程序呢?
一、透明度。使Pod中的容器對基礎設施可見使基礎設施可以向這些容器提供服務,例如流程管理和資源監控。這爲用戶提供了許多便利。
二、解耦軟件依賴關係。能夠獨立地對各個容器進行版本控制、從新構建和從新部署。
三、易用性。用戶不須要運行本身的進程管理器,不須要擔憂信號和輸出代碼傳播等問題
四、效率。由於基礎設施承擔了更多的責任,容器能夠更輕量級。
3.2.2. Pods的持久性
Pods不打算被視爲持久的實體。它們沒法在調度失敗、節點失敗或其餘驅逐(如因爲缺少資源或在節點維護的狀況下)中倖存下來。
通常來講,用戶不須要直接建立Pods。他們幾乎老是應該使用控制器,即便對於單例也是如此,例如部署。控制器提供集羣範圍的自修復,以及副本和滾動管理。
3.2.3. Pods終止
由於Pods表示集羣中節點上正在運行的進程,因此容許這些進程在再也不須要它們時優雅地終止是很重要的(PS:優雅指的是與使用終止信號被暴力殺死而沒有機會清理的狀況相比)。用戶應該可以請求刪除並知道進程什麼時候終止,但也可以確保刪除最終完成。當用戶請求刪除一個Pod時,系統記錄容許強制殺死Pod以前的寬限期(默認30秒),並向每一個容器中的主進程發送TERM信號。寬限期一過,KILL信號就發送給這些進程,而後從API服務器刪除Pod。若是在等待進程終止時從新啓動了Kubelet或容器管理器,則將在完整的寬限期內重試終止。
3.3. Controllers
3.3.1. ReplicaSet
ReplicaSet(副本集)的目的是維護一組穩定的副本Pods,以保證在任何給定時間都有可用的Pods。所以,它一般用於保證指定數量的相同Pods的可用性。
一個ReplicaSet是由一些字段定義的,包括一個選擇器,它指定如何識別它能夠得到的pod,一個副本的數量指示它應該維護多少個pod,一個pod模板指定它應該建立的新pod的數據,以知足replicas的數量標準。而後,一個複製集經過建立和刪除Pods來實現它的目的,以達到所需的數量。當一個複製集須要建立新的Pod時,它使用它的Pod模板。
示例:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# modify replicas according to your case
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
保存這個manifest文件爲frontend.yaml,並提交到Kubernetes集羣,這樣就建立了一個副本集定義。
# 提交副本集定義
kubectl apply -f frontend.yaml
# 獲取當前副本集
kubectl get rs
# 查看副本集狀態
kubectl describe rs/frontend
3.3.2. ReplicationController
ReplicationController確保在任什麼時候候都運行指定數量的pod副本。換句話說,一個ReplicationController確保一個pod或一組同類的pod老是處於可用狀態。
若是有太多的pods,ReplicationController會終止額外的pods。若是數量太少,ReplicationController就會啓動更多的pods。與手動建立的pods不一樣,ReplicationController維護的pods在失敗、刪除或終止時將自動替換。例如,在內核升級等破壞性維護以後,將在節點上從新建立pods。所以,即便應用程序只須要一個pod,也應該使用ReplicationController。ReplicationController相似於進程管理器,可是它不是管理單個節點上的單個進程,而是管理跨多個節點的多個pod。
下面這個示例ReplicationController配置運行三個nginx web服務器副本:
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
另存爲replication.yaml
# 提交副本定義
kubectl apply -f replication.yaml
# 查看副本狀態
kubectl describe replicationcontrollers/nginx
3.3.3. Deployments
一個Deployment(部署)爲 Pods 和 ReplicaSets 提供聲明式更新。
你在部署中描述一個指望的狀態,而Deployment Controller以受控的速率將實際狀態更改成指望狀態。你能夠定義部署來建立新的副本集,或者刪除現有的部署。
例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
3.3.4. DaemonSet
DaemonSet確保全部(或部分)節點都運行一個Pod的副本。隨着節點被添加到集羣中,pod也被添加到該節點上。當節點從集羣中移除時,這些pods將被垃圾收集。刪除DaemonSet將清理它建立的pods。
4. Services
一種將運行在一組pod上的應用程序公開爲網絡服務的抽象方法。
使用Kubernetes,你不須要修改應用程序來使用不熟悉的服務發現機制。Kubernetes爲Pods提供它們本身的IP地址和單個DNS名稱,而且能夠在它們之間實現負載均衡。
每一個Pod都有本身的IP地址,可是在部署中,某個時刻運行的Pod集可能與稍後運行該應用程序的Pod集稍微有些不一樣。
在Kubernetes中,服務是一種抽象,它定義了一組邏輯Pods和訪問它們的策略(有時這種模式被稱爲微服務)。服務最終部署到哪一個pods一般由選擇器決定
若是你在應用程序中使用Kubernetes API進行服務發現,則能夠查詢API服務器的端點,而且在服務更新的時候這些端點也會獲得更新。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
4.1. 服務發現
Kubernetes支持兩種主要的模式:服務環境變量和DNS
當在節點上運行Pod時,kubelet爲每一個激活的服務添加一組環境變量。它既支持Docker links compatible 的變量,也支持更簡單的{SVCNAME}_SERVICE_HOST和{SVCNAME}_SERVICE_PORT變量,其中服務名採用大寫形式,破折號轉換爲下劃線。
例如,有一個服務名字叫「redis-master」,IP和端口分別是10.0.0.11和6379,那麼將會生成如下環境變量:
REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
4.2. 發佈服務
Kubernetes ServiceTypes 容許你指定想要的服務類型。默認是ClusterIP。
Type可選值有:
4.3. Volumes
容器中的磁盤上的文件是短暫的,這給在容器中運行的重要應用程序帶來了一些問題。首先,當容器崩潰時,kubelet將從新啓動它,可是文件將丟失—容器將以一個乾淨的狀態開始。其次,在一個Pod中一塊兒運行容器時,經常須要在這些容器之間共享文件。Kubernetes Volume抽象解決了這兩個問題。
Docker也有一個volumes(卷)的概念,在Docker中,卷就是磁盤上或另外一個容器中的目錄,其生存期沒有管理。
Kubernetes volume有一個明確的生命週期,它與包裹它的Pod同樣。所以,卷的生命週期比在Pod中運行的任何容器都長,而且跨容器從新啓動時保留數據。固然,當一個pod被刪除的時候,volum也會被刪除。更重要的是,Kubernetes支持多種類型的卷,一個Pod能夠同時使用任意數量的卷。