1. 數據存儲
-
容器的生命周期可能很短,會被頻繁地創建和銷毀。那么容器在銷毀時,保存在容器中的數據也會被清除。這種結果對用戶來說,在某些情況下是不樂意看到的。為了持久化保存容器的數據,kubernetes引入了Volume的概念。
-
Volume是Pod中能夠被多個容器訪問的共享目錄,它被定義在Pod上,然后被一個Pod里的多個容器掛載到具體的文件目錄下,kubernetes通過Volume實現同一個Pod中不同容器之間的數據共享以及數據的持久化存儲。Volume的生命容器不與Pod中單個容器的生命周期相關,當容器終止或者重啟時,Volume中的數據也不會丟失。
-
kubernetes的Volume支持多種類型,比較常見的有下面幾個:
-
簡單存儲:EmptyDir、HostPath、NFS
-
高級存儲:PV、PVC
-
配置存儲:ConfigMap、Secret
-
1.1 基本存儲
1.1.1 EmptyDir
EmptyDir 是一種輕量級的存儲選項,用于 Pod 內部容器之間的數據共享或臨時存儲。下面是一些關于 EmptyDir 的補充信息:
-
生命周期:EmptyDir 的生命周期與 Pod 綁定。當 Pod 被創建時,EmptyDir 被創建并掛載到 Pod 中所有需要它的容器上。當 Pod 被刪除時,EmptyDir 及其內容也會被刪除。
-
使用場景:
-
臨時存儲:對于需要臨時寫入和讀取數據,但不要求數據持久化的場景,如緩存或會話數據。
-
容器間數據共享:當 Pod 中運行多個容器需要共享文件時,EmptyDir 可以作為一個共享存儲空間。
-
數據處理:在數據被處理并存儲到更持久的存儲解決方案之前,可以臨時存儲在 EmptyDir 中。
-
-
性能:EmptyDir 存儲的性能通常與宿主機的磁盤性能相當,因為它直接存儲在宿主機上。
-
限制:由于 EmptyDir 與 Pod 的生命周期綁定,因此它不適合存儲需要跨 Pod 持久化的數據。此外,EmptyDir 不保證數據的備份或復制,所以在 Pod 重啟或重建時數據可能會丟失。
-
配置:EmptyDir 可以通過 Pod 定義中的
spec.volumes
字段來配置,無需指定宿主機上的路徑。 -
安全性:EmptyDir 默認只對 Pod 內部的容器可見,提供了一定程度的隔離。
在一個Pod中準備兩個容器nginx和busybox,然后聲明一個Volume分別掛在到兩個容器的目錄中,然后nginx容器負責向Volume中寫日志,busybox中通過命令將日志內容讀到控制臺。
-
示例
[root@k8s-master-01 ~]# vim volume-emptydir.yaml --- apiVersion: v1 kind: Pod metadata:name: volume-emptydirnamespace: test spec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 80volumeMounts: # 將logs-volume掛在到nginx容器中,對應的目錄為 /var/log/nginx- name: logs-volumemountPath: /var/log/nginx- name: busyboximage: busybox:1.30command: ["/bin/sh","-c","tail -f /logs/access.log"] # 初始命令,動態讀取指定文件中內容volumeMounts: # 將logs-volume 掛在到busybox容器中,對應的目錄為 /logs- name: logs-volumemountPath: /logsvolumes: # 聲明volume, name為logs-volume,類型為emptyDir- name: logs-volumeemptyDir: {}[root@k8s-master-01 ~]# kubectl apply -f volume-emptydir.yaml pod/volume-emptydir created [root@k8s-master-01 ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES volume-emptydir 2/2 Running 0 62s 1.244.44.201 k8s-node-02 <none> <none>
-
訪問
[root@k8s-master-01 ~]# kubectl exec -it volume-emptydir -n test /bin/bash root@volume-emptydir:/# echo 'This is EmptyDir test' > /usr/share/nginx/html/index.html root@volume-emptydir:/# exit [root@k8s-master-01 ~]# curl 1.244.44.201 This is EmptyDir test
-
通過kubectl logs命令查看指定容器的標準輸出
[root@k8s-master-01 ~]# kubectl logs -f volume-emptydir -n test -c busybox # 可以看到訪問日志 1.244.151.128 - - [22/May/2024:07:15:58 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-" 1.244.151.128 - - [22/May/2024:07:17:04 +0000] "GET / HTTP/1.1" 200 22 "-" "curl/7.29.0" "-"
1.1.2 HostPath
-
EmptyDir中數據不會被持久化,它會隨著Pod的結束而銷毀,如果想簡單的將數據持久化到主機中,可以選擇HostPath。
-
HostPath就是將Node主機中一個實際目錄掛在到Pod中,以供容器使用,這樣的設計就可以保證Pod銷毀了,但是數據依據可以存在于Node主機上。
-
數據持久性:與
EmptyDir
不同,HostPath
卷將 Node 主機上的一個目錄掛載到 Pod 中,使得 Pod 內的容器可以訪問和修改該目錄上的文件。由于這些文件存儲在 Node 主機上,因此即使 Pod 被刪除,數據仍然可以在 Node 主機上保持。 -
用途:
HostPath
適用于需要持久化數據的場景,例如數據庫文件、配置文件等。然而,由于HostPath
直接使用了 Node 主機的文件系統,可能會帶來一些安全和管理上的挑戰,例如權限管理、數據一致性等問題。
-
-
示例
[root@k8s-master-01 ~]# vim volume-hostpath.yaml --- apiVersion: v1 kind: Pod metadata:name: volume-hostpathnamespace: test spec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 80volumeMounts:- name: logs-volumemountPath: /var/log/nginx- name: busyboximage: busybox:1.30command: ["/bin/sh","-c","tail -f /logs/access.log"]volumeMounts:- name: logs-volumemountPath: /logsvolumes:- name: logs-volumehostPath:path: /root/logstype: DirectoryOrCreate[root@k8s-master-01 ~]# kubectl apply -f volume-hostpath.yaml pod/volume-hostpath created [root@k8s-master-01 ~]# kubectl get pod -n test -o wide # 調度到了node2 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES volume-hostpath 2/2 Running 0 23s 1.244.44.202 k8s-node-02 <none> <none>
各個 type
值的詳細說明:
type 值 | 描述 |
---|---|
DirectoryOrCreate | 如果指定的目錄存在,則使用該目錄;如果不存在,則先創建目錄后使用。 |
Directory | 目錄必須存在,否則掛載操作會失敗。 |
FileOrCreate | 如果指定的文件存在,則使用該文件;如果不存在,則先創建文件后使用。 |
File | 文件必須存在,否則掛載操作會失敗。 |
Socket | Unix 套接字必須存在,否則掛載操作會失敗。 |
CharDevice | 字符設備必須存在,否則掛載操作會失敗。 |
BlockDevice | 塊設備必須存在,否則掛載操作會失敗。 |
-
測試
[root@k8s-master-01 ~]# curl 1.244.44.202# 下來就可以去host的/root/logs目錄下查看存儲的文件了 注意: 下面的操作需要到Pod所在的節點運行,這里是調度到了node2 [root@k8s-node-02 ~]# ll /root/logs/ total 4 -rw-r--r-- 1 root root 95 May 22 15:44 access.log -rw-r--r-- 1 root root 0 May 22 15:39 error.log [root@k8s-node-02 ~]# cat /root/logs/access.log 1.244.151.128 - - [22/May/2024:07:44:59 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"# 同樣的道理,如果在此目錄下創建一個文件,到容器中也是可以看到的
1.1.3 NFS
-
雖然
HostPath
可以用于解決數據持久化的問題,但它并不適用于跨節點的數據共享和高可用性場景。一旦 Pod 從一個節點遷移到另一個節點,HostPath
卷中的數據就無法訪問。這是因為HostPath
卷依賴于特定節點上的文件系統,而不是一個獨立的網絡存儲系統。 -
為了解決這個問題,確保數據在節點遷移時仍然可用,通常推薦使用網絡文件存儲系統,如 NFS (Network File System) 或 CIFS (Common Internet File System)。這兩種協議允許 Pod 訪問遠程存儲系統上的數據,就好像它們是本地文件一樣。
-
NFS 是一種網絡文件系統協議,它允許客戶端計算機訪問服務器上的文件和目錄,就像它們是本地文件一樣。通過設置 NFS 服務器,您可以將 Pod 中的存儲直接連接到 NFS 系統上。這樣,即使 Pod 從一個節點遷移到另一個節點,只要網絡連接正常,Pod 就可以繼續訪問數據。
-
首先要準備NFS的服務器,這里為了簡單,直接是master節點做NFS服務器
# 在master上安裝nfs服務 [root@k8s-master-01 ~]# yum install nfs-utils -y ? # 準備一個共享目錄 [root@k8s-master-01 ~]# mkdir /nfstest ? # 將共享目錄以讀寫權限暴露給192.168.110.0/24網段中的所有主機 [root@k8s-master-01 ~]# vim /etc/exports /nfstest 192.168.110.0/24(rw,no_root_squash) ? [root@k8s-master-01 ~]# systemctl restart rpcbind.service nfs-server.service
-
在的每個node節點上都安裝下NFS,這樣的目的是為了node節點可以驅動NFS設備
[root@k8s-node-01 ~]# yum install nfs-utils -y [root@k8s-node-01 ~]# showmount -e 192.168.110.21 Export list for 192.168.110.21: /nfstest 192.168.110.0/24 ? [root@k8s-node-02 ~]# yum install nfs-utils -y [root@k8s-node-02 ~]# showmount -e 192.168.110.21 Export list for 192.168.110.21: /nfstest 192.168.110.0/24
-
編寫Pod的配置文件
[root@k8s-master-01 ~]# vim volume-nfs.yaml --- apiVersion: v1 kind: Pod metadata:name: volume-nfsnamespace: test spec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 80volumeMounts:- name: logs-volumemountPath: /var/log/nginx- name: busyboximage: busybox:1.30command: ["/bin/sh","-c","tail -f /logs/access.log"]volumeMounts:- name: logs-volumemountPath: /logsvolumes:- name: logs-volumenfs:server: k8s-master-01path: /nfstest[root@k8s-master-01 ~]# kubectl apply -f volume-nfs.yaml pod/volume-nfs created [root@k8s-master-01 ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES volume-nfs 2/2 Running 0 118s 1.244.44.204 k8s-node-02 <none>
-
查看
[root@k8s-master-01 ~]# ll /nfstest/ total 0 -rw-r--r-- 1 root root 0 May 22 17:23 access.log -rw-r--r-- 1 root root 0 May 22 17:23 error.log [root@k8s-master-01 ~]# curl 1.244.44.204 [root@k8s-master-01 ~]# cat /nfstest/access.log 1.244.151.128 - - [22/May/2024:09:26:39 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
1.2 高級存儲
1.2.1 PV和PVC
由于kubernetes支持的存儲系統有很多,要求客戶全都掌握,顯然不現實。為了能夠屏蔽底層存儲實現的細節,方便用戶使用, kubernetes引入PV和PVC兩種資源對象。
-
PV(Persistent Volume)
-
PV是Kubernetes中的一個API對象,它代表集群中的一塊存儲,這塊存儲已經預先按照某種方式設置好了,并且可以被多個用戶使用。PV是集群資源,由Kubernetes管理員預先配置,它們不會因Pod的終止而消失,因此被稱為“持久化”。PV可以采用多種形式,例如本地存儲、網絡附加存儲(NAS)、云存儲服務等。
-
-
PVC(Persistent Volume Claim)
-
PVC是用戶對存儲的請求,它允許用戶以聲明式的方式請求存儲資源,而無需關心存儲的具體實現細節。用戶定義所需的存儲容量、訪問模式和存儲類別(如果需要),然后提交PVC請求。
-
在Kubernetes中使用PV(Persistent Volume)和PVC(Persistent Volume Claim)確實可以帶來工作流的細分和專業化,這樣的分工可以提高效率并減少錯誤。以下是各個角色的主要職責:
-
存儲工程師,存儲工程師負責維護和操作底層的存儲系統。他們的工作包括:
-
選擇合適的存儲解決方案,包括本地存儲、網絡附加存儲(NAS)、存儲區域網絡(SAN)或云存儲服務。
-
配置和管理存儲硬件或服務,確保其性能、可靠性和安全性。
-
監控存儲系統的性能,確保它滿足Kubernetes集群的需求。
-
管理數據備份、恢復和災難恢復計劃。
-
-
Kubernetes管理員,Kubernetes管理員負責維護Kubernetes集群和PV資源。他們的工作職責包括:
-
創建和管理PV資源,將底層存儲系統抽象化,使其可以在Kubernetes集群中使用。
-
配置PV的訪問模式和存儲容量,確保它們符合集群的使用需求。
-
監控PV的使用情況,確保存儲資源得到合理分配和優化。
-
管理PV的生命周期,包括創建、修改和刪除操作。
-
-
Kubernetes用戶,Kubernetes用戶負責維護PVC資源,他們通常是開發人員或應用運維團隊。他們的工作職責包括:
-
創建和管理PVC,根據應用的需求聲明所需的存儲資源。
-
定義PVC的存儲容量、訪問模式和選擇器,以便與合適的PV進行綁定。
-
將PVC掛載到Pod中,以便應用可以持久化存儲數據。
-
監控PVC的狀態和使用情況,確保應用的存儲需求得到滿足。
-
1.2.2 PV(Persistent Volume)
-
PV(Persistent Volume)在Kubernetes中指的是持久化卷,它是一種存儲抽象的概念,代表了集群中的一塊存儲,這可以是本地磁盤、網絡附加存儲(NAS)、或者云存儲等。PV與底層存儲的具體實現細節相解耦,使得Kubernetes管理員可以靈活地管理存儲資源。
1.2.2.1 PV的主要特點包括
-
獨立性:PV獨立于Pod存在,即使使用PV的Pod被刪除,PV中的數據也不會丟失。
-
持久性:PV在設計上用于數據的持久化存儲,它們在Kubernetes集群中是長壽命的。
-
可配置性:Kubernetes管理員可以配置PV的大小、訪問模式(如ReadWriteOnce、ReadOnlyMany、ReadWriteMany)以及存儲類別(StorageClass)。
-
可重用性:PV一旦被創建,可以被多個Pod重用,只要它們的訪問模式和存儲需求相匹配。
-
動態供應:通過StorageClass資源,Kubernetes可以自動創建PV以滿足PVC的請求,這個過程稱為動態存儲供應。
1.2.2.2 PV的生命周期
-
創建:Kubernetes管理員根據集群的存儲需求預先創建PV資源。
-
綁定:當用戶提交PVC(Persistent Volume Claim)請求時,Kubernetes會嘗試找到一個匹配的PV進行綁定。
-
使用:綁定成功后,PV可以被Pod通過PVC訪問和使用。
-
回收:當PVC被刪除時,PV可以被釋放并根據回收策略進行清理,以便再次使用或保持其數據。
1.2.2.3 資源清單文件
apiVersion: v1 kind: PersistentVolume metadata:name: pv2 spec:nfs: # 存儲類型,與底層真正存儲對應path: /path/to/nfs/share # NFS共享路徑server: nfs-server.example.com # NFS服務器地址capacity: # 存儲能力,目前只支持存儲空間的設置storage: 2GiaccessModes: # 訪問模式- ReadWriteOnce # 可以被一個節點掛載為讀寫模式persistentVolumeReclaimPolicy: Retain # 回收策略# Retain:刪除PersistentVolumeClaim后,不會刪除PersistentVolume,只是標記為不可用# Delete:刪除PersistentVolumeClaim后,會刪除PersistentVolume# Recycle:刪除PersistentVolumeClaim后,將PersistentVolume清理并重新可用,但數據將丟失
1.2.2.4 PV關鍵配置參數
-
存儲類型
-
定義:底層實際存儲的類型,Kubernetes 支持多種存儲類型,如 NFS、iSCSI、glusterFS 等,每種類型的配置都會有所不同。
-
影響因素:不同存儲類型可能支持的訪問模式和回收策略不同。
-
-
存儲能力(capacity)
-
定義:當前主要支持存儲空間的設置(如
storage=1Gi
),但未來可能會增加 IOPS、吞吐量等其他性能指標的配置。 -
注意事項:存儲能力的設置直接影響到 PV 能夠提供給 Pod 的存儲空間大小。
-
訪問模式(accessModes)
-
定義:描述用戶應用對存儲資源的訪問權限,包括:
-
ReadWriteOnce(RWO):讀寫權限,但只能被單個節點掛載。
-
ReadOnlyMany(ROX):只讀權限,可被多個節點掛載。
-
ReadWriteMany(RWX):讀寫權限,可被多個節點掛載。
-
-
注意事項:底層不同的存儲類型可能支持的訪問模式不同。
-
-
回收策略(persistentVolumeReclaimPolicy)
-
定義:當 PV 不再被使用時,對其的處理方式,包括:
-
Retain(保留):保留數據,需管理員手動清理。
-
Recycle(回收):清除 PV 中的數據。
-
Delete(刪除):與 PV 相關聯的后端存儲完成 volume 刪除操作。
-
-
注意事項:底層不同的存儲類型可能支持的回收策略不同。
-
-
存儲類別(storageClassName)
-
定義:通過
storageClassName
參數指定一個存儲類別,有助于管理和組織不同類型的存儲資源。 -
綁定規則:具有特定類別的 PV 只能與請求了該類別的 Persistent Volume Claim (PVC) 進行綁定;未設定類別的 PV 則只能與不請求任何類別的 PVC 進行綁定。
-
-
狀態(status)
-
定義:PV 在生命周期中的狀態,包括:
-
Available(可用):表示可用狀態,尚未被任何 PVC 綁定。
-
Bound(已綁定):表示 PV 已經被 PVC 綁定。
-
Released(已釋放):表示 PVC 被刪除,但資源還未被集群重新聲明。
-
Failed(失敗):表示該 PV 的自動回收失敗。
-
-
1.2.2.5 示例
-
使用NFS作為存儲,來演示PV的使用,創建3個PV,對應NFS中的3個暴露的路徑
[root@k8s-master-01 ~]# mkdir /data/pv{1..3} -p [root@k8s-master-01 ~]# vim /etc/exports /data/pv1 192.168.110.0/24(rw,no_root_squash) /data/pv2 192.168.110.0/24(rw,no_root_squash) /data/pv3 192.168.110.0/24(rw,no_root_squash) ? ? [root@k8s-master-01 ~]# exportfs -arv exporting 192.168.110.0/24:/data/pv3 exporting 192.168.110.0/24:/data/pv2 exporting 192.168.110.0/24:/data/pv1
-
創建pv配置文件
[root@k8s-master-01 ~]# vim pv.yaml --- apiVersion: v1 kind: PersistentVolume metadata:name: pv1 spec:capacity:storage: 1GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retainnfs:path: /data/pv1server: k8s-master-01--- apiVersion: v1 kind: PersistentVolume metadata:name: pv2 spec:capacity:storage: 2GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retainnfs:path: /data/pv2server: k8s-master-01--- apiVersion: v1 kind: PersistentVolume metadata:name: pv3 spec:capacity:storage: 3GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retainnfs:path: /data/pv3server: k8s-master-01[root@k8s-master-01 ~]# kubectl apply -f pv.yaml persistentvolume/pv1 created persistentvolume/pv2 created persistentvolume/pv3 created[root@k8s-master-01 ~]# kubectl get pv -o wide NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE pv1 1Gi RWX Retain Available 119s Filesystem pv2 2Gi RWX Retain Available 119s Filesystem pv3 3Gi RWX Retain Available 119s Filesystem
1.2.3 PVC(Persistent Volume Claim)
1.2.3.1 資源清單
-
PVC是資源的申請,用來聲明對存儲空間、訪問模式、存儲類別需求信息。
apiVersion: v1 kind: PersistentVolumeClaim metadata:name: pvcnamespace: dev spec:accessModes: # 訪問模式- ReadWriteOnce # 或者 ReadOnlyMany、ReadWriteMany,取決于你的需求selector: # 采用標簽對PV選擇matchLabels:app: myapp # 這里的值應該匹配你想要綁定的PV的標簽storageClassName: # 存儲類別- standard # 如果沒有指定存儲類別,則默認使用defaultresources: # 請求空間requests:storage: 5Gi # 請求的存儲空間大小
1.2.3.2 PVC 的關鍵配置參數
-
訪問模式(accessModes)
-
定義:描述用戶應用對存儲資源的訪問權限。
-
可選值
-
ReadWriteOnce
:表示該卷可以被集群中的一個節點掛載為讀寫模式。 -
ReadOnlyMany
:表示該卷可以被集群中的多個節點掛載為只讀模式。 -
ReadWriteMany
:表示該卷可以被集群中的多個節點同時掛載為讀寫模式。
-
-
注意事項:不同的存儲類型可能支持的訪問模式不同。
-
-
選擇條件(selector)
-
定義:通過 Label Selector 的設置,使 PVC 對系統中已存在的 PV 進行篩選。
-
作用:允許 PVC 根據標簽選擇特定的 PV,從而實現更靈活的存儲資源管理。
-
示例:
matchLabels: { app: myapp }
表示 PVC 會嘗試綁定標簽為{ app: myapp }
的 PV。
-
-
存儲類別(storageClassName)
-
定義:PVC 在定義時可以設定需要的后端存儲的類別。
-
作用:只有設置了相同
storageClassName
的 PV 才能被系統選出作為 PVC 的目標。 -
示例:
storageClassName: standard
表示 PVC 要求使用名為standard
的存儲類別。
-
-
資源請求(Resources)
-
定義:PVC 中的資源請求字段用于指定 PVC 需要的最小存儲空間大小。
-
示例:
resources.requests.storage: 5Gi
表示 PVC 請求至少需要 5GB 的存儲空間。 -
注意事項:PVC 的資源請求必須小于或等于 PV 提供的最大存儲空間,否則 PVC 無法成功綁定到 PV 上。
-
1.2.3.3 配置示例
[root@k8s-master-01 ~]# vim pvc.yaml --- apiVersion: v1 kind: PersistentVolumeClaim metadata:name: pvc1namespace: test spec:accessModes:- ReadWriteManyresources:requests:storage: 10Mi--- apiVersion: v1 kind: PersistentVolumeClaim metadata:name: pvc2namespace: test spec:accessModes:- ReadWriteManyresources:requests:storage: 10Mi--- apiVersion: v1 kind: PersistentVolumeClaim metadata:name: pvc3namespace: test spec:accessModes:- ReadWriteManyresources:requests:storage: 10Mi[root@k8s-master-01 ~]# kubectl apply -f pvc.yaml persistentvolumeclaim/pvc1 created persistentvolumeclaim/pvc2 created persistentvolumeclaim/pvc3 created[root@k8s-master-01 ~]# kubectl get pvc -n test -o wide NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE pvc1 Bound pv1 1Gi RWX 6s Filesystem pvc2 Bound pv2 2Gi RWX 6s Filesystem pvc3 Bound pv3 3Gi RWX 6s Filesystem[root@k8s-master-01 ~]# kubectl get pv -o wide # PV狀態變為綁定 NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE pv1 1Gi RWX Retain Bound test/pvc1 2m26s Filesystem pv2 2Gi RWX Retain Bound test/pvc2 2m26s Filesystem pv3 3Gi RWX Retain Bound test/pvc3 2m26s Filesystem
-
創建pods.yaml, 使用pv
[root@k8s-master-01 ~]# vim pods.yaml --- apiVersion: v1 kind: Pod metadata:name: pod1namespace: test spec:containers:- name: busyboximage: busybox:1.30command: ["/bin/sh", "-c", "while true; do echo pod1 >> /root/out.txt; sleep 10; done;"]volumeMounts:- name: volumemountPath: /root/volumes:- name: volumepersistentVolumeClaim:claimName: pvc1readOnly: false--- apiVersion: v1 kind: Pod metadata:name: pod2namespace: test spec:containers:- name: busyboximage: busybox:1.30command: ["/bin/sh", "-c", "while true; do echo pod2 >> /root/out.txt; sleep 10; done;"]volumeMounts:- name: volumemountPath: /root/volumes:- name: volumepersistentVolumeClaim:claimName: pvc2readOnly: false[root@k8s-master-01 ~]# kubectl apply -f pods.yaml pod/pod1 created pod/pod2 created[root@k8s-master-01 ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod1 1/1 Running 0 17s 1.244.154.197 k8s-node-01 <none> <none> pod2 1/1 Running 0 17s 1.244.44.194 k8s-node-02 <none> <none># 查看nfs中的文件存儲 [root@k8s-master-01 ~]# cat /data/pv1/out.txt pod1 pod1 pod1 [root@k8s-master-01 ~]# cat /data/pv2/out.txt pod2 pod2 pod2
1.2.4 PVC和PV在Kubernetes中的生命周期
1.2.4.1 資源供應
-
管理員首先需要創建底層存儲(如NFS、AWS EBS等),然后創建一個PV來代表這個存儲。PV定義了存儲的類型、大小、訪問模式等信息。
1.2.4.2 資源綁定
-
用戶創建PVC來請求存儲資源。PVC定義了存儲需求,比如大小和訪問模式。
-
Kubernetes 集群會根據PVC的聲明去尋找一個或多個PV來滿足這些需求。如果找到匹配的PV,Kubernetes 會自動將PVC和PV進行綁定。
-
如果沒有找到匹配的PV,PVC將進入Pending狀態,直到管理員創建了一個符合要求的PV。
1.2.4.3 資源使用
-
一旦PVC和PV綁定,用戶可以在Pod中使用PVC,就像使用普通的Volume一樣,將PVC掛載到容器內部的路徑上。
-
Pod使用Volume的方式將PVC掛載到容器內的某個路徑進行使用。
1.2.4.4 資源釋放
-
當用戶不再需要PVC時,可以刪除PVC來釋放與之綁定的PV。刪除PVC后,與該PVC綁定的PV會被標記為“已釋放”,但PV上的數據可能仍然存在,直到管理員清理這些數據。
-
PV的存儲空間在被釋放后,根據PV的回收策略,Kubernetes 會決定如何處理剩余的數據。例如,如果設置為
Retain
,數據將保持原地;如果設置為Delete
,數據將被刪除。
1.2.4.5 資源回收
-
對于PV,管理員可以設定回收策略,用于設置與之綁定的PVC釋放資源之后如何處理遺留數據的問題。只有PV的存儲空間完成回收,才能供新的PVC綁定和使用
-
Kubernetes 根據PV的設置的回收策略(reclaim policy)來決定如何回收PV上的數據。常見的回收策略有Retain和Delete。
-
Retain
: 數據將保留在PV上,直到管理員手動清理。 -
Delete
: 數據將被刪除,PV可以被重新綁定。
-
-
示例
[root@k8s-master-01 ~]# kubectl delete -f pvc.yaml # 刪除PV persistentvolumeclaim "pvc1" deleted persistentvolumeclaim "pvc2" deleted persistentvolumeclaim "pvc3" deleted [root@k8s-master-01 ~]# kubectl get pv -o wide # 狀態變為Retain NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE pv1 1Gi RWX Retain Released test/pvc1 10m Filesystem pv2 2Gi RWX Retain Released test/pvc2 10m Filesystem pv3 3Gi RWX Retain Released test/pvc3
1.3 配置存儲
-
在Kubernetes中,
ConfigMap
和Secret
是兩種核心資源,用于存儲和管理應用程序的配置數據和敏感信息。理解它們的功能和最佳實踐對于提高Kubernetes應用程序的安全性和配置管理的效率至關重要。
1.3.1 ConfigMap
-
ConfigMap
是一種API對象,允許你存儲非敏感配置數據,如環境變量、數據庫URL等。它以鍵值對的形式存儲數據,便于應用程序訪問必要的配置。ConfigMap
可以直接掛載到容器中或作為環境變量注入到容器中,從而使得應用程序能夠訪問存儲的配置數據,而無需修改應用程序代碼。
1.3.1.1 基本配置
-
配置
[root@k8s-master-01 ~]# vim configmap.yaml --- apiVersion: v1 kind: ConfigMap metadata:name: configmapnamespace: test data:msg: |username: kxyage: 22address: beijing[root@k8s-master-01 ~]# kubectl apply -f configmap.yaml configmap/configmap created [root@k8s-master-01 ~]# kubectl get configmaps configmap -n test NAME DATA AGE configmap 1 65s
-
創建一個pod-configmap.yaml,將上面創建的configmap掛載進去
[root@k8s-master-01 ~]# vim pod-configmap.yaml --- apiVersion: v1 kind: Pod metadata:name: pod-configmapnamespace: test spec:containers:- name: nginximage: nginx:1.17.1volumeMounts:- name: configmountPath: /configmap/configvolumes:- name: configconfigMap:name: configmap[root@k8s-master-01 ~]# kubectl apply -f pod-configmap.yaml pod/pod-configmap created [root@k8s-master-01 ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-configmap 1/1 Running 0 2m49s 1.244.154.198 k8s-node-01 <none> <none>[root@k8s-master-01 ~]# kubectl exec -it pod-configmap -n test /bin/bash root@pod-configmap:/# cd /configmap/config/ root@pod-configmap:/configmap/config# ls msg root@pod-configmap:/configmap/config# cat msg username: kxy age: 22 address: beijing# 可以看到映射已經成功,每個configmap都映射成了一個目錄 # key--->文件 value---->文件中的內容 # 此時如果更新configmap的內容, 容器中的值也會動態更新# 動態驗證 [root@k8s-master-01 ~]# kubectl edit cm configmap -n test 將22改為100000000 [root@k8s-master-01 ~]# kubectl exec -it pod-configmap -n test /bin/bash root@pod-configmap:/# cd /configmap/config/ root@pod-configmap:/configmap/config# cat msg username: kxy age: 100000000 address: beijing
-
使用字面值創建
# 使用文字值創建,利用 --from-literal 參數傳遞配置信息,該參數可以使用多次 # 創建名稱為special-config的ConfigMap配置 [root@k8s-master-01 ~]# kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm [root@k8s-master-01 ~]# kubectl get cm special-config NAME DATA AGE special-config 2 50s [root@k8s-master-01 ~]# kubectl describe cm special-config Name: special-config Namespace: default Labels: <none> Annotations: <none>Data ==== special.how: ---- very special.type: ---- charmBinaryData ====Events: <none>[root@k8s-master-01 ~]# kubectl delete cm special-config
-
使用文件創建
# 只要指定為一個文件就可以從單個文件中創建 ConfigMap 。 --from-file 這個參數可以使用多次,你可以使用兩次分別指定上個實 例中的那兩個配置文件,效果就跟指定整個目錄是一樣的。 [root@k8s-master-01 ~]# kubectl create configmap game-config-2 --from-file=/etc/hosts [root@k8s-master-01 ~]# kubectl describe cm game-config-2 Name: ? ? ? ? game-config-2 Namespace: ? default Labels: ? ? ? <none> Annotations: <none> ? Data ==== hosts: ---- 127.0.0.1 ? localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 ? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.110.21 k8s-master-01 192.168.110.24 K8s-node-01 192.168.110.25 K8s-node-02 ? ? BinaryData ==== ? Events: <none> ? [root@k8s-master-01 ~]# kubectl delete cm game-config-2
-
使用目錄創建
# --from-file 指定在目錄下的所有文件都會被用在 ConfigMap 里面創建一個鍵值對,鍵的名字就是文件名,值就是文件的內容。 [root@k8s-master-01 ~]# mkdir test [root@k8s-master-01 ~]# cp /etc/hosts /root/test/ [root@k8s-master-01 ~]# cp /etc/resolv.conf /root/test/ [root@k8s-master-01 ~]# kubectl create configmap my-config --from-file=/root/test/ configmap/my-config created [root@k8s-master-01 ~]# kubectl describe cm my-config Name: ? ? ? ? my-config Namespace: ? default Labels: ? ? ? <none> Annotations: <none> ? Data ==== hosts: ---- 127.0.0.1 ? localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 ? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.110.21 k8s-master-01 192.168.110.24 K8s-node-01 192.168.110.25 K8s-node-02 ? resolv.conf: ---- # Generated by NetworkManager nameserver 192.168.110.2 ? ? BinaryData ==== ? Events: <none>
1.3.1.2 ConfigMap的使用
-
通過環境變量方式傳遞給Pod
[root@k8s-master-01 ~]# vim pod-configmap.yaml apiVersion: v1 kind: Pod metadata:name: pod1 spec:containers:- name: pod1image: busybox:1.30command: ["/bin/sh", "-c", "env"]env:- name: key1valueFrom:configMapKeyRef:name: cm1-configkey: db_hostrestartPolicy: Never[root@k8s-master-01 ~]# kubectl apply -f pod-configmap.yaml pod/pod1 created [root@k8s-master-01 ~]# kubectl get pod NAME READY STATUS RESTARTS AGE pod1 0/1 Comp 0 74s
1.3.1.3 ConfigMap熱更新
-
正常情況下,我們可以通過如下配置,在啟動的 Pod 容器里面獲取到 ConfigMap 中配置的信息。
[root@k8s-master-01 ~]# vim hotipdate.yaml --- apiVersion: v1 kind: ConfigMap metadata:name: log-confignamespace: default data:log_level: INFO---apiVersion: apps/v1 kind: Deployment metadata:name: my-nginx spec:replicas: 1selector:matchLabels:run: my-nginx # 確保selector與template的labels匹配template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginx:1.17.1ports:- containerPort: 80volumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: log-config[root@k8s-master-01 ~]# kubectl apply -f hotipdate.yaml configmap/log-config unchanged deployment.apps/my-nginx created[root@k8s-master-01 ~]# kubectl get cm,pod -o wide NAME DATA AGE configmap/cm1-config 0 152m configmap/kube-root-ca.crt 1 3d3h configmap/log-config 1 10mNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/my-nginx-77cdddc657-6kbsz 1/1 Running 0 7m26s 1.244.154.200 k8s-node-01 <none> <none># 查找對應信息 [root@k8s-master-01 ~]# kubectl exec -it my-nginx-77cdddc657-6kbsz /bin/bash -- cat /etc/config/log_level INFO
-
修改 ConfigMap 配置,修改 log_level 的值為 DEBUG 等待大概 30 秒鐘時間,再次查看環境變量的值。
# 修改ConfigMap配置 [root@k8s-master-01 ~]# kubectl edit configmap log-config :%s/INFO/DEBUG/g[root@k8s-master-01 ~]# kubectl exec -it my-nginx-77cdddc657-6kbsz /bin/bash -- cat /etc/config/log_level DEBUG
1.3.1.4 ConfigMap 更新后滾動更新 Pod
更新ConfigMap
目前并不會觸發相關 Pod 的滾動更新,可以通過修改 pod annotations 的方式強制觸發滾動更新。這個例子里我們在 .spec.template.metadata.annotations
中添加 version/config,每次通過修改 version/config 來觸發滾動更新。
[root@k8s-master-01 ~]# kubectl patch deployment my-nginx --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20240525" }}}}}'
1.3.1.5 解決deployment 擴容引發服務配置不一致
-
運維層面
-
重啟 Deployment: 使用
kubectl rollout restart deployment
命令可以觸發 Deployment 控制器去滾動更新 Pods。這將導致舊的 Pods 被逐漸替換為新的 Pods,新的 Pods 將掛載最新的 ConfigMap。kubectl rollout restart deployment <deployment-name>
-
重建 Pods: 通過刪除現有的 Pods,可以觸發 Deployment 控制器根據最新的配置重新創建 Pods。這可以通過
kubectl delete pod
命令實現。kubectl delete pod <pod-name>
或者,您可以使用標簽選擇器來刪除所有匹配的 Pods:
kubectl delete pods -l app=my-nginx
-
應用程序層面
-
配置熱加載: 應用程序需要能夠檢測到配置文件的變化,并在不重啟服務的情況下重新加載配置。這通常涉及到在應用程序中實現一個監聽器,當檢測到 ConfigMap 中的文件發生變化時,觸發配置的重新加載。
-
使用環境變量: 另一種方法是將 ConfigMap 中的值作為環境變量掛載到 Pod 中。這樣,應用程序可以在啟動時讀取這些環境變量,而不需要關心文件系統的變化。
-
使用 Init 容器: 在 Pod 中使用 Init 容器來處理配置文件。Init 容器在應用程序容器啟動之前運行,可以用來下載或生成配置文件,然后將它們存儲在 Pod 的共享卷中。
-
使用 ConfigMap 觸發器: 某些應用程序或平臺可能支持 ConfigMap 觸發器,當 ConfigMap 更新時,這些觸發器可以通知應用程序進行相應的操作。
-
使用自定義的 Operator: 開發一個自定義的 Operator 來管理應用程序的配置。Operator 可以監控 ConfigMap 的變化,并根據這些變化自動更新應用程序的配置。
-
1.3.1.6 ConfigMap 錯誤排查和故障處理方法
-
檢查 ConfigMap 是否存在: 使用
kubectl get configmap <configmap-name> -n <namespace>
命令來確認 ConfigMap 是否已經創建。 -
檢查 Pod 是否正確引用 ConfigMap:
-
檢查 Pod 的 YAML 文件,確保
spec.volumes
中包含了對 ConfigMap 的引用。 -
使用
kubectl describe pod <pod-name> -n <namespace>
命令查看 Pod 的詳細信息,以確定是否正確引用了 ConfigMap。
-
-
檢查 ConfigMap 的數據是否正確:
-
確保 ConfigMap 中的數據是正確的。
-
使用
kubectl get configmap <configmap-name> -n <namespace> -o yaml
命令查看 ConfigMap 的詳細信息。
-
-
檢查容器中的環境變量和配置文件:
-
使用
kubectl exec -it <pod-name> -n <namespace> -- /bin/sh
命令進入容器。 -
在容器內部,使用
env
命令查看環境變量,或者直接查看配置文件的內容。
-
-
檢查 ConfigMap 的權限和安全性:
-
如果 ConfigMap 包含敏感信息,確保使用 Kubernetes 的 RBAC 功能來限制訪問權限。
-
使用
kubectl get rolebindings -n <namespace>
和kubectl get roles -n <namespace>
命令來檢查權限設置。
-
-
使用 Kubernetes 的日志記錄和監控功能:
-
使用
kubectl logs <pod-name> -n <namespace>
命令查看容器的日志信息。 -
使用 Kubernetes 的監控工具來監控 ConfigMap 和相關資源的狀態。
-
1.3.2 Secret
-
在 Kubernetes 中,
Secret
對象確實是用來存儲敏感信息的一種資源例如密碼、秘鑰、證書等等。它與ConfigMap
類似,但設計目的不同。
1.3.2.1 Secret有三種類型
-
Opaque:
-
這種類型的
Secret
用于存儲少量的敏感數據,如密碼、令牌或密鑰。 -
數據以 Base64 編碼格式存儲,這意味著雖然數據在存儲時被編碼,但仍然可以通過 Base64 解碼來查看原始數據,因此安全性相對較低。
-
-
Service Account:
-
這種類型的
Secret
通常用于服務賬戶(ServiceAccount),它們由 Kubernetes 自動創建和管理。 -
服務賬戶的
Secret
包含訪問 Kubernetes API 所需的認證信息,如 API 令牌。 -
這些
Secret
會自動掛載到 Pod 的/run/secrets/kubernetes.io/serviceaccount
目錄中,供 Pod 內的應用程序使用。
-
-
kubernetes.io/dockerconfigjson:
-
這種類型的
Secret
用于存儲私有 Docker 注冊表(registry)的認證信息。 -
當需要從私有 registry 拉取鏡像時,可以使用這種
Secret
來提供認證信息。 -
可以通過在 Pod 的
spec
中指定imagePullSecrets
來引用這些Secret
,以便 Kubernetes 能夠訪問私有 registry。
-
1.3.2.2 Service Account類型
-
Service Account 是 Kubernetes 中的一個對象,它為運行在集群中的 Pod 提供了一種安全的方式來訪問 Kubernetes API。Service Account 與普通用戶賬戶類似,但它是自動管理的,并且通常與特定的服務或應用程序相關聯,而不是與個人用戶相關聯。
# serviceaccout創建時Kubernetes會雙認創建對M的secret,對應的secret會自動掛載到Pod [root@k8s-master-01 ~]# kubectl exec -it my-nginx-55b7dc67f-6tzzd -- ls /var/run/secrets/kubernetes.io/serviceaccount ca.crt namespace token# 每個namespace下有一個名為defau1t的默認的ServiceAccount對象 [root@k8s-master-01 ~]# kubectl get sa NAME SECRETS AGE default 0 3d3h [root@k8s-master-01 ~]# kubectl get sa -n test NAME SECRETS AGE default 0 3h21m# serviceAccount里有一個名為Tokens的可以作為Volume一樣被Mount到Pod里的secret,當Pod啟動時這個secret會被自動Mount到Pod的指定目錄下,用來協助完成Pod中的進程訪問API server時的身份鑒權過程 [root@k8s-master-01 ~]# kubectl get pod my-nginx-55b7dc67f-6tzzd -o yaml spec:containers:- image: nginx:1.17.1imagePullPolicy: IfNotPresentname: my-nginxports:- containerPort: 80protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilevolumeMounts:- mountPath: /etc/configname: config-volume- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: kube-api-access-mvpssreadOnly: true
1.3.2.3 Opaque類型
-
Opaque 類型的數據是一個 map 類型,要求value是base64編碼。
-
手動創建base64加密
[root@k8s-master-01 ~]# echo -n 'admin' | base64 YWRtaW4= [root@k8s-master-01 ~]# echo -n 'kxy20021003' | base64 a3h5MjAwMjEwMDM=
-
解密
[root@k8s-master-01 ~]# echo 'a3h5MjAwMjEwMDM=' | base64 --decode kxy20021003
這里需要注意的是,像這樣創建的 Secret 對象,它里面的內容僅僅是經過了轉碼,而并沒有被加密。在真正的生產環境中,你需要在 Kubernetes 中開啟 Secret 的加密插件,增強數據的安全性。
1.3.2.4 kubernetes.io/dockerconfigjson類型
-
用來創建用戶docker registry認證的Secret,直接使用kubectl create命令創建即可
[root@k8s-master-01 ~]# kubectl create secret docker-registry myregistry \ --docker-server=DOCKER_SERVER \ --docker-username=DOCKER_USER \ --docker-password=DOCKER_PASSWORD \ --docker-email=DOCKER_EMAIL[root@k8s-master-01 ~]# kubectl get secret NAME TYPE DATA AGE myregistry kubernetes.io/dockerconfigjson 1 37s
-
kubectl create secret
是創建新 Secret 的命令。 -
docker-registry
是 Secret 的類型,指定了這是一個用于 Docker registry 的認證信息。 -
myregistry
是要創建的 Secret 的名稱。 -
--docker-server
后面應跟 Docker registry 的服務器地址,例如https://index.docker.io/v1/
。 -
--docker-username
后面應跟 Docker registry 的用戶名。 -
--docker-password
后面應跟 Docker registry 的密碼。 -
--docker-email
后面應跟 Docker registry 的用戶郵箱。
1.3.2.5 Secret創建及使用方法
-
方式一: kubectl create secret 命令
[root@k8s-master-01 ~]# kubectl create secret --help Create a secret with specified type.A docker-registry type secret is for accessing a container registry.A generic type secret indicate an Opaque secret type.A tls type secret holds TLS certificate and its associated key.Available Commands:docker-registry Create a secret for use with a Docker registrygeneric Create a secret from a local file, directory, or literal valuetls Create a TLS secretUsage:kubectl create secret (docker-registry | generic | tls) [options]Use "kubectl create secret <command> --help" for more information about a given command. Use "kubectl options" for a list of global command-line options (applies to all commands).
-
kubectl create secret
:這是創建 Secret 的基本命令。 -
(docker-registry | generic | tls)
:這表示創建 Secret 時需要指定一個類型。Kubernetes 支持三種類型的 Secret:-
docker-registry
:用于訪問 Docker 容器注冊表的認證信息。 -
generic
:通用類型的 Secret,用于存儲少量的敏感數據,如密碼或密鑰。 -
tls
:用于存儲 TLS 證書及其關聯的私鑰。
-
-
[options]
:創建不同類型的 Secret 時,可能需要提供一些選項或參數,比如認證信息、文件路徑、證書詳情等。 -
Available Commands
:列出了與kubectl create secret
相關的可用子命令。 -
Usage
:顯示了如何使用kubectl create secret
命令的示例格式。 -
Use "kubectl create secret <command> --help"
:提示用戶如果想要獲取某個特定子命令的更多信息,可以使用<command> --help
來查看幫助信息。 -
Use "kubectl options"
:提示用戶如果想要查看所有kubectl
命令的全局選項,可以使用kubectl options
命令。
# generic子命令可以通過本地文件、目錄或者literal(鍵值對) [root@k8s-master-01 ~]# echo admin > username.txt [root@k8s-master-01 ~]# echo 1f2d1e2e67df > passwd.txt [root@k8s-master-01 ~]# kubectl create secret generic user --from-file=./username.txt secret/user created [root@k8s-master-01 ~]# kubectl create secret generic pass --from-file=./passwd.txt secret/pass created [root@k8s-master-01 ~]# kubectl get secrets | grep Opaque pass Opaque 1 16s user Opaque 1 30s# 默認情況下key為文件名或者直接通過鍵值對創建 [root@k8s-master-01 ~]# kubectl delete secrets pass secret "pass" deleted [root@k8s-master-01 ~]# kubectl delete secrets user secret "user" deleted [root@k8s-master-01 ~]# kubectl create secret generic user --from-literal=username=admin secret/user created [root@k8s-master-01 ~]# kubectl create secret generic pass --from-literal=password=1f2d1e2e67df secret/pass created [root@k8s-master-01 ~]# kubectl get secrets | grep Opaque pass Opaque 1 3s user Opaque 1 7s
-
通過yaml文件創建
[root@k8s-master-01 ~]# vim secret.yaml apiVersion: v1 kind: Secret metadata:name: mysecret type: Opaque data:user: YWRtaW4= ?# base64編碼的"user"pass: MWYyZDFlMmU2N2Rm ?# base64編碼的"pass123" ? [root@k8s-master-01 ~]# kubectl apply -f secret.yaml secret/mysecret created ? [root@k8s-master-01 ~]# kubectl get secret | grep Opaque mysecret ? ? Opaque ? ? ? ? ? ? ? ? ? ? ? ? ? 2 ? ? 41s
1.3.2.6 Secret的使用
-
方式一:通過Volume掛載的方式
[root@k8s-master-01 ~]# vim test-projected-volume.yaml apiVersion: v1 kind: Pod metadata:name: test-projected-volume spec:containers:- name: test-secret-volumeimage: busybox:1.30args:- sleep- "86400"volumeMounts:- name: mysql-credmountPath: "/projected-volume"readOnly: truevolumes:- name: mysql-credprojected:sources:- secret:name: mysql-useritems:- key: userpath: user- secret:name: mysql-passitems:- key: passpath: pass[root@k8s-master-01 ~]# kubectl apply -f test-projected-volume.yaml ? # 當 Pod 變成 Running 狀態之后,我們再驗證一下這些 Secret 對象是不是已經在容器里了 [root@k8s-master-01 ~]# kubectl exec -it test-projected-volume -- /bin/sh # ls /projected-volume/ user pass # cat /projected-volume/user admin # cat /projected-volume/pass 1f2d1e2e67df
-
方法二:通過環境變量
[root@k8s-master-01 ~]# kubectl create secret generic mysecret --from-file=user=./username.txt --from-file=pass=passwd.txt [root@k8s-master-01 ~]# vim pod-secret-env.yaml apiVersion: v1 kind: Pod metadata:name: pod-secret-env spec:containers:- name: myappimage: busyboxargs:- sleep- "86400"env:- name: SECRET_USERNAMEvalueFrom:secretKeyRef:name: mysecretkey: user- name: SECRET_PASSWORDvalueFrom:secretKeyRef:name: mysecretkey: passrestartPolicy: Never[root@k8s-master-01 ~]# kubectl get pod NAME ? ? ? ? ? ? READY ? STATUS ? RESTARTS ? AGE pod-secret-env ? 1/1 ? ? Running ? 0 ? ? ? ? 40s
1.3.2.7 docker config json
-
使用 Kuberctl 創建 docker registry 認證的 secret
# 創建格式 $ kubectl create secret docker-registry myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-password=DOCKER_PASSWORD \ --docker-email=DOCKER_EMAIL ? ?
-
在創建 Pod 的時候,通過 imagePullSecrets 來引用剛創建的 myregistrykey
[root@k8s-master-01 ~]# kubectl create secret docker-registry myregistrykey \ --docker-server=hub.escape.com \ --docker-username=admin \ --docker-password=harbor123456 \ --docker-email=harbor@escape.com ? [root@k8s-master-01 ~]# kubectl get secret NAME ? ? ? ? ? TYPE ? ? ? ? ? ? ? ? ? ? ? ? ? ? DATA ? AGE myregistrykey ? kubernetes.io/dockerconfigjson ? 1 ? ? 3m25s