無狀態服務:
1、沒有實時的資料需要儲存 (即使有,也是靜態資料)
2、服務叢集網路中,拿掉一個服務後,一段時間後,加入這個服務,對服務叢集沒有任何影響。
比如:
目前開發應用程式(Java程式碼)
有狀態服務:
1、有實時的資料需要儲存
2、服務叢集網路中,拿掉一個服務後,一段時間後,加入這個服務,對服務叢集有一定的影響(資料完整性,一致性)
比如:
關係型資料庫(mysql、sqlserver)
kubernetes部署無狀態服務,部署架構,形態:對於無狀態服務部署的幾個關鍵物件:Deployment、ReplicaSet、Pod.
在kubernetes中,服務部署的最小單元都是POD;對於部署有狀態服務,必須對POD容器的資料儲存做持久化處理。需要引入PV(persistent volume)PVC(persistent volume claim)、磁碟等記憶體。
https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume/
Volume資料卷生命週期:(volume資料卷是kubernetes資源物件,本身並不儲存資料,而僅僅是提供把資料掛載到容器中的能力)
1、pod內部容器宕機,volume資料卷及資料不會丟失;
2、pod宕機,此時volume資料卷消失了,資料也丟失了,重建的pod無法找回資料了。
Volume 資料卷是Kubernetes抽象出來的一個資源物件,它本身不儲存資料,它主要實現資料掛載(把不同儲存媒介中的資料給掛載到pod內部容器中)
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# 宿主上目錄位置
path: /data
# 此欄位為可選
type: Directory
1)首先自行安裝一臺nfs伺服器。
2)yaml檔案
apiVersion: v1
kind: Pod
metadata:
name: nfs
spec:
containers:
- image: harbor.hyz.com/library/mynginx:v1
name: test-vo
volumeMounts:
- mountPath: /cache
name: test-nfs
volumes:
- name: test-nfs
nfs:
server: 192.168.211.13
path: /data/harbor
ConfigMap是k8s提供的一個設定中心,類似於微服務架構中(nacos,zookeeper)設定中心服務,用來儲存一些組態檔。
例如:
1、部署Redis服務,可以把redis.conf組態檔儲存在configmap資源物件中;
2、部署mysql服務,可以把my.cnf組態檔儲存在configmap資源物件中。
ConfigMap資源物件儲存結構:key-value模式,key是關鍵字元,value可以是字串,也可以是一個檔案內容。
Examples:
# Create a new configmap named my-config based on folder bar
kubectl create configmap my-config --from-file=path/to/bar
# Create a new configmap named my-config with specified keys instead of file basenames on disk
kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
# Create a new configmap named my-config with key1=config1 and key2=config2
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
# Create a new configmap named my-config from the key=value pairs in the file
kubectl create configmap my-config --from-file=path/to/bar
# Create a new configmap named my-config from an env file
kubectl create configmap my-config --from-env-file=path/to/bar.env
1、根據目錄建立
kubect create cm my-config-1 --from-file=/data/config
2、根據檔案建立
kubectl create cm my-config-2 --from-file=/data/config/application.yml
3、根據字面量(key-value)建立
kubectl create cm my-config-3 --from-literal=key=value1 --from-literal=key2=value2
1)使用單個 ConfigMap 中的資料定義容器環境變數
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: harbor.hyz.com/library/mynginx:v1
command: [ "/bin/sh", "-c", "env" ]
env:
# 定義環境變數
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
# ConfigMap 包含你要賦給 SPECIAL_LEVEL_KEY 的值
name: special-config
# 指定與取值相關的鍵名
key: special.how
restartPolicy: Never
經過測試:發現成功的把configmap中資料引入到環境變數中;
2)volume方式掛載:
apiVersion: v1
kind: Pod
metadata:
name: cm-volume
spec:
containers:
- image: harbor.hyz.com/library/mynginx:v1
name: test-container
command: [ "/bin/sh", "-c", "sleep 600s" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-config-2
檢視容器內部是否掛載成功:
my-config-2中的4個檔案都掛載成功。
修改ConfigMap中的資料,pod服務能夠馬上察覺到。
Secret是kubernetes本地資料卷的一種,secret提供儲存敏感資料的一種服務,用來把敏感儲存secret物件中,保證服務的安全性。
具體作用:防止一些敏感資料直接保證服務映象中;例如:token, 祕鑰,密碼等等。當pod需要這些資料的時候,動態的從secret資源物件中載入即可。
Secret有4種型別:
Service Account :用來存取Kubernetes API,由Kubernetes自動建立,並且會自動掛載到Pod的/run/secrets/kubernetes.io/serviceaccount目錄中;
Opaque :base64編碼格式的Secret,用來儲存密碼、金鑰、資訊、證書等,型別識別符號為generic;
kubernetes.io/dockerconfigjson :用來儲存私有docker registry的認證資訊,型別標識為docker-registry。
kubernetes.io/tls:用於為SSL通訊模式儲存證書和私鑰檔案,命令式建立型別標識為tls。
當我們採用rest風格存取k8s api時,需要攜帶一些鑑權資訊,比如token\ca證書\賬號密碼等,之後每臺Node節點會根據鑑權資訊去master鑑權。
[root@k8s-master01 stateful]# echo -n "admin" | base64
YWRtaW4=
[root@k8s-master01 stateful]# echo -n "abcdefgh" | base64
YWJjZGVmZ2g=
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: YWJjZGVmZ2g=
username: YWRtaW4=
apiVersion: v1
kind: Pod
metadata:
name: secret-test
labels:
name: secret-test
spec:
volumes:
- name: secrets
secret:
secretName: mysecret
containers:
- image: harbor.hyz.com/library/mynginx:v1
name: test-container
volumeMounts:
- name: secrets
mountPath: "/etc/secrets"
readOnly: true
驗證:進入容器/etc/secrets目錄下,列印username, password屬性
確實是我們進行加密後的2個源字串。
Pv持久化資料卷,是用來讓服務和儲存媒介解耦(讓volume資料卷和底層的儲存媒介進行解耦,volume資料卷消失了,但是pv不會消失,pv和pod沒有強關聯,當pod被重構後,根據hostname不變性,從而可以再次找回資料,保證資料的不丟失),因此為了部署有狀態服務,kubernetes抽象出來了一個PV持久化資料資源物件,k8s可以自由的控制這個資源物件,其作用就是遮蔽掉底層複雜的儲存媒介的操作,使得kubernetes管理持久化的資料卷更加高效,簡單。
企業中服務部署需要儲存資料:前期規劃資料大小,需要多少儲存空間?? 然後由運維幫助建立持久化資料卷,根據需求大小進行建立.
可以把pv物件看做一個一個虛擬儲存塊,是一種虛擬化的概念,在邏輯上實現對物理資源隔離,同時實現對底層物理儲存媒介的抽象,使得k8s更加方便的管理儲存空間,想使用哪個儲存塊,由k8s實現自由的排程。
Pv是k8s抽象出來的資源物件,k8s自由控制自己的資源物件
Pv儲存塊是根據業務需求,事先由運維先規劃,建立好儲存塊,專案需要,從儲存塊中獲取資料即可。
問題: 建立pod服務時候,需要儲存資料,但是pv儲存物件有上萬個,pod應該是哪個pv儲存塊?
Pvc(persistent volume claim) 持久化的資料卷宣告卷,代理pod傳送請求,幫助pod匹配一個合適的pv物件;
疑問:pvc是如何找到合適的pv資源物件?
建立pod服務的時候,儲存資料,繫結一合適的pv物件:
1、向pvc發出請求,讓pvc幫助我們選擇一個合適的pv儲存塊
2、pvc傳送申請請求,請求匹配一個合適的pv儲存物件,匹配方式如下:
1)、存取大小
2)、存取方式
1)建立Pv1
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv1
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /opt/hyz
server: 192.168.66.13
2)建立pv2
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv2
spec:
capacity:
storage: 7Gi
accessModes:
- ReadWriteMany
nfs:
path: /opt/hyz
server: 192.168.66.13
apiVersion: v1
kind: Pod
metadata:
name: pv-pod
spec:
containers:
- image: harbor.hyz.com/library/mynginx:v1
name: test-container
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumes:
- name: www
persistentVolumeClaim:
claimName: my-pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany
resources:
request:
storage: 5Gi
HeadlessService : 字面意思: 無頭服務,內涵含義:沒有ip地址的Service; 也就是說對於有狀態服務部署來說,使用的是headlessService, 不會給service分配ip地址;
HeadlessService作用就是把後端服務的ip地址暴露給前端,便於使用者端使用。
根據需求: 建立pv儲存塊物件,可以想象:在開發中,需要大量的儲存塊,如果使用人工建立,非常低效,且沒有含金量。
因此根據解放生產力指標:讓pv按需動態建立,再也不需要人為的方式建立。使用storageclass實現pv物件動態建立。
Storageclass 動態建立pv儲存塊實現的部署方案:
要想實現pv按需動態建立,那必須先完成環境設定:
1、安裝storageclass
2、安裝persistent volume provisioner