1.案例準備
儲存卷以MariaDb來演示,其中每個節點需要準備如下映象
docker pull mariadb:10.5.2
編寫部署mariadb的資原始檔:
apiVersion: apps/v1kind: Deploymentmetadata: name: mariadb-demo labels: app: mariadb-demospec: replicas: 1 template: metadata: name: mariadb-demo labels: app: mariadb-demo spec: containers: - name: mariadb-demo image: mariadb:10.5.2 imagePullPolicy: IfNotPresent env: - name: MYSQL_ROOT_PASSWORD value: root #mysql root賬戶的密碼 - name: TZ value: Asia/Shanghai args: - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" ports: - containerPort: 3306 restartPolicy: Always selector: matchLabels: app: mariadb-demo---apiVersion: v1kind: Servicemetadata: name: mariadb-svcspec: selector: app: mariadb-demo ports: - port: 3306 targetPort: 3306 nodePort: 13306 type: NodePort
部署執行:
[root@k8s-master01 mariadb]# kubectl apply -f mariadb-demo.yml deployment.apps/mariadb-demo createdservice/mariadb-svc created#檢視pod[root@k8s-master01 mariadb]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESmariadb-demo-68f748c9cc-6k6mh 1/1 Running 0 14s 10.81.85.243 k8s-node01 <none> <none>#檢視服務[root@k8s-master01 mariadb]# kubectl get serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.1.0.1 <none> 443/TCP 6d10hmariadb-svc NodePort 10.1.163.25 <none> 3306:30036/TCP 8m57s
使用資料庫連線工具測試效果:
2.secretSecret 解決了密碼、token、金鑰等敏感資料的配置問題,而不需要把這些敏感資料暴露到映象或者 Pod Spec中。Secret 可以以 Volume 或者環境變數的方式使用。(案例中mariadb的密碼就是配置在spec中)
secret有三種類型:
Service Account :用來訪問 Kubernetes API,由 Kubernetes 自動建立,並且會自動掛載到 Pod的/run/secrets/kubernetes.io/serviceaccount 目錄中。Opaque :base64編碼格式的Secret,用來儲存密碼、金鑰等kubernetes.io/dockerconfigjson :用來儲存私有 docker registry 的認證資訊2.1 Service Account#檢視系統pods[root@k8s-master01 mariadb]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGEcalico-kube-controllers-6b94766748-95bch 1/1 Running 6 6d10hcalico-node-mt6ch 1/1 Running 6 6d10hcalico-node-wxthh 1/1 Running 1 6d10hcalico-node-zf9sl 1/1 Running 6 6d10hcoredns-6955765f44-77tcj 1/1 Running 6 6d10hcoredns-6955765f44-kf6jf 1/1 Running 6 6d10hetcd-k8s-master01 1/1 Running 6 6d10hkube-apiserver-k8s-master01 1/1 Running 8 6d10hkube-controller-manager-k8s-master01 1/1 Running 53 6d10hkube-proxy-7kcln 1/1 Running 6 6d10hkube-proxy-gjlsk 1/1 Running 1 6d10hkube-proxy-hftxh 1/1 Running 6 6d10hkube-scheduler-k8s-master01 1/1 Running 50 6d10h#隨機選擇一個pod進入,檢視sa[root@k8s-master01 mariadb]# kubectl exec -it kube-proxy-7kcln -n kube-system sh# cd /run/secrets/kubernetes.io/serviceaccount# lsca.crt namespace token# cat ca.crt-----BEGIN CERTIFICATE-----MIICyDCCAbCgAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJlcm5ldGVzMB4XDTIwMTIxOTIzMTM1NFoXDTMwMTIxNzIzMTM1NFowFTETMBEGA1UEAxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPE1Z05pJYCZ9tpyEQ4fBarjGxRui909iSnF+hncsLLTHrws07SVRk3U5mo/uHLcJ8l9C1fcv0S5sCSIqgAvh7chDGAdq4K6wOQIcYDiMbGI/Sw0hFDfMYDlO6Bd0OUrprZLy8Fz0m3+IewAfnVAfAIKwoAb7Ya74jTsFaG4vCVX9iu/nVCZsdNKYSjk6X6U5RnZChAtd/D1EWzOYY94qPsFkbeRENTc1hiqRckqvPJDV1pMUf8JGMIMkwDfWzrvFHLqmljqt7ybCH5RspYy+pOAjz4DC97H2A/EjQgmuELHPdgHqLM5RSsnsMvybbaaFSEI2pFFVRZyF6BZanFBomMCAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFcwGgUVKNyYn7YzIxCpkZJdUag6GI/Wna1/WowyklppONFae+ZVo08GuHO/nq9+pzj+tPaqrIWTbtFNRivn7b8DZUj6gFxedO0U+Flt5grsdXjV3nc5J1feY3hRyq/jl8UBE4IAgZ1PVeOlbxXdplkNisdQ+/05sshsj7SF1pf2fpGQQoJ0u0E2ZptEwuhKB4Xu7uP10cxAVq9ye3VuXdsvnziNQDa4eW3hoit0xkjFJ8YQ4QmL/UAUQ+Avy3/M26ZHnpcmqwTbLLvGRrI3iCo3y/JsDaM3ydPk/Jo5dDDfVRAo5My7YeEYOd9H7M/4BXHMxhRnrydEj/kfQbo1g5c=-----END CERTIFICATE-----# exit
2.2 Opaquebase64加密解密
[root@k8s-master01 mariadb]# echo -n "root" | base64cm9vdA==[root@k8s-master01 mariadb]# echo -n "cm9vdA==" |base64 -droot
演示如何使用Opaque 來給mariadb設定root密碼,Opaque只支援base64的方式加密。
secret資源配置檔案:
apiVersion: v1kind: Secretmetadata: name: secret-demotype: Opaquedata:# k-v形式,這個password可以隨便定義,密碼採用base64加密 password: cm9vdA==
mariadb的部署配置檔案:
apiVersion: apps/v1kind: Deploymentmetadata: name: mariadb-secret labels: app: mariadb-secretspec: replicas: 1 template: metadata: name: mariadb-secret labels: app: mariadb-secret spec: containers: - name: mariadb-secret image: mariadb:10.5.2 imagePullPolicy: IfNotPresent ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD #mysql root賬戶的密碼 valueFrom: secretKeyRef: key: password #secret資源的data.key,這個key可以自定義 name: secret-demo #定義secret資源的名稱 - name: TZ value: Asia/Shanghai args: - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" restartPolicy: Always selector: matchLabels: app: mariadb-secret---apiVersion: v1kind: Servicemetadata: name: mariadb-secret-svcspec: selector: app: mariadb-secret ports: - port: 3306 targetPort: 3306 nodePort: 30036 type: NodePort
注意關鍵點在:
- name: MYSQL_ROOT_PASSWORD #mysql root賬戶的密碼 valueFrom: secretKeyRef: key: password #secret資源的data.key,這個key可以自定義 name: secret-demo #定義secret資源的名稱
key就是secret資源中定義的key,name就是secret的資源name
部署:
#部署,可以使用 .來批次部署當前資料夾下所有的資原始檔[root@k8s-master01 secrets]# kubectl apply -f .secret/secret-demo createddeployment.apps/mariadb-secret createdservice/mariadb-secret-svc created#檢視secrets[root@k8s-master01 secrets]# kubectl get secrets NAME TYPE DATA AGEdefault-token-r4r5v kubernetes.io/service-account-token 3 6d11hsecret-demo Opaque 1 19s#檢視pod[root@k8s-master01 secrets]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESmariadb-secret-79f78c64db-h8skx 1/1 Running 0 27s 10.81.85.245 k8s-node01 <none> <none>#檢視service[root@k8s-master01 secrets]# kubectl get serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.1.0.1 <none> 443/TCP 6d11hmariadb-secret-svc NodePort 10.1.94.137 <none> 3306:30036/TCP 35s
使用資料庫工具連線:
3. ConfigMapConfigMap是用於儲存配置資料的鍵值對,可以用來儲存單個屬性,也可以儲存配置檔案。configmap 可以從檔案、目錄或者 key-value 字串建立等建立 ConfigMap。也可以透過 kubectl create -f從描述檔案建立
建立ConfigMap的方式有4種:
直接在命令列中指定configmap引數建立,即--from-literal指定檔案建立,即將一個配置檔案建立為一個ConfigMap--from-file=<檔案>指定目錄建立,即將一個目錄下的所有配置檔案建立為一個ConfigMap,--from-file=<目錄>先寫好標準的configmap的yaml檔案,然後kubectl create -f 建立3.1 命令列建立語法規則:kubectl create configmap map的名字 --from-literal=key=value,如果有可以繼續在後邊寫 --from-literal=key=value,演示案例:
#使用命令列建立configmap[root@k8s-master01 secrets]# kubectl create configmap davidconfigmap --from-literal=david-key=david-valueconfigmap/davidconfigmap created#檢視configmap[root@k8s-master01 secrets]# kubectl get configmaps NAME DATA AGEdavidconfigmap 1 13s#檢視資料[root@k8s-master01 secrets]# kubectl get configmap davidconfigmap -o go-template='{{.data}}'map[david-key:david-value]#刪除[root@k8s-master01 secrets]# kubectl delete configmaps davidconfigmap configmap "davidconfigmap" deleted
3.2 配置檔案的形式語法規則:kubectl create configmap cumulx-test --from-file=xxxx key的名稱是檔名稱,value的值是這個檔案的內容,案例如下:
準備一個jdbc.properties的配置檔案
vim jdbc.properties
jdbc.driverclass=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/testjdbc.username=rootjdbc.password=admin
#指定檔案的方式建立configmap[root@k8s-master01 data]# kubectl create configmap myjdbcconfigmap --from-file=jdbc.properties configmap/myjdbcconfigmap created#檢視資訊[root@k8s-master01 data]# kubectl describe configmaps myjdbcconfigmap Name: myjdbcconfigmapNamespace: defaultLabels: <none>Annotations: <none>Data====jdbc.properties:----jdbc.driverclass=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/testjdbc.username=rootjdbc.password=adminEvents: <none>#刪除[root@k8s-master01 data]# kubectl delete configmaps myjdbcconfigmap configmap "myjdbcconfigmap" deleted
3.3 目錄的方式語法:kubectl create configmap cumulx-test --from-file=/data/
#指定配置檔案的目錄[root@k8s-master01 data]# kubectl create configmap myconfig --from-file=/data/configmaps/configmap/myconfig created#檢視詳情[root@k8s-master01 data]# kubectl describe configmaps myconfig Name: myconfigNamespace: defaultLabels: <none>Annotations: <none>Data====jdbc.properties:----jdbc.driverclass=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/testjdbc.username=rootjdbc.password=adminEvents: <none>[root@k8s-master01 data]# kubectl delete configmaps myconfig configmap "myconfig" deleted
3.4 資原始檔的形式jdbc.yml資原始檔
apiVersion: v1kind: ConfigMapmetadata: name: myjdbc-configdata: jdbc-driverclass: com.mysql.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/test jdbc-username: root jdbc-password: admin
執行部署:
[root@k8s-master01 configmaps]# kubectl apply -f jdbc.yml configmap/myjdbc-config created[root@k8s-master01 configmaps]# kubectl describe configmaps myjdbc-config Name: myjdbc-configNamespace: defaultLabels: <none>Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","data":{"jdbc-driverclass":"com.mysql.jdbc.Driver","jdbc-password":"admin","jdbc-url":"jdbc:mysql://localhost:3306/test...Data====jdbc-driverclass:----com.mysql.jdbc.Driverjdbc-password:----adminjdbc-url:----jdbc:mysql://localhost:3306/testjdbc-username:----rootEvents: <none>
4.label某些特殊情況下,需要將某些服務固定在一臺宿主機上, k8s可以使用label給node節點打上標籤來滿足這種需求 .
#新增標籤[root@k8s-master01 data]# kubectl label nodes kus-node01 mariadb=mariadbError from server (NotFound): nodes "kus-node01" not found[root@k8s-master01 data]# kubectl label nodes k8s-node01 mariadb=mariadbnode/k8s-node01 labeled#檢視叢集節點 node01節點最後有一個mariadb=mariadb的標籤[root@k8s-master01 data]# kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELSk8s-master01 Ready master 6d16h v1.17.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master01,kubernetes.io/os=linux,node-role.kubernetes.io/master=k8s-node01 Ready <none> 6d16h v1.17.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01,kubernetes.io/os=linux,mariadb=mariadb#修改[root@k8s-master01 data]# kubectl label nodes k8s-node01 mariadb=mariadb-update --overwrite node/k8s-node01 labeled[root@k8s-master01 data]# kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELSk8s-master01 Ready master 6d16h v1.17.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master01,kubernetes.io/os=linux,node-role.kubernetes.io/master=k8s-node01 Ready <none> 6d16h v1.17.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01,kubernetes.io/os=linux,mariadb=mariadb-update#刪除標籤[root@k8s-master01 data]# kubectl label nodes k8s-node01 mariadb-node/k8s-node01 labeled[root@k8s-master01 data]# kubectl get nodes --show-labelsNAME STATUS ROLES AGE VERSION LABELSk8s-master01 Ready master 6d16h v1.17.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master01,kubernetes.io/os=linux,node-role.kubernetes.io/master=k8s-node01 Ready <none> 6d16h v1.17.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01,kubernetes.io/os=linux
案例 將某個pod固定部署到指定的節點
在前面mariadb案例中pod配置新增節點選擇器的配置nodeSelector:mariadb: mariadb,這樣能確定的mariadb給部署在k8s-node01這個節點了。
spec: replicas: 1 template: metadata: name: mariadb-secret labels: app: mariadb-secret spec: nodeSelector: mariadb: mariadb #節點標籤選擇器 containers: - name: mariadb-secret image: mariadb:10.5.2 imagePullPolicy: IfNotPresent ports: - containerPort: 3306
部署詳情:
[root@k8s-master01 labels]# kubectl apply -f .secret/secret-demo unchangeddeployment.apps/mariadb-secret createdservice/mariadb-secret-svc created[root@k8s-master01 labels]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESmariadb-secret-5cd9dd86ff-r7x7p 1/1 Running 0 22s 10.81.85.246 k8s-node01 <none> <none>
5. hostpathhostPath型別的儲存卷是指將工作節點上某檔案系統的目錄或檔案掛載於Pod中的一種儲存卷。把宿主機上的目錄掛載到容器,但是在每個節點上都要有,因為不確定容器會分配到哪個節點。也是把儲存從宿主機掛載到k8s叢集上,但它有許多限制,例如只支援單節點(Node),而且只支援“ReadWriteOnce”模式。
案例:集合前面加密Opaque的案例,同時結合label案例,將mariadb的資料目錄給掛載到k8s-node01節點的/data/mariadb目錄下。完整的資源清單如下:
mariadb-secret-demo.yml
apiVersion: v1kind: Secretmetadata: name: secret-demotype: Opaquedata: password: cm9vdA==
mariadb.yml
apiVersion: apps/v1kind: Deploymentmetadata: name: mariadb-secret labels: app: mariadb-secretspec: replicas: 1 template: metadata: name: mariadb-secret labels: app: mariadb-secret spec: nodeSelector: mariadb: mariadb #節點標籤選擇器 containers: - name: mariadb-secret image: mariadb:10.5.2 imagePullPolicy: IfNotPresent ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD #mysql root賬戶的密碼 valueFrom: secretKeyRef: key: password #secret資源的data.key,這個key可以自定義 name: secret-demo #定義secret資源的名稱 - name: TZ value: Asia/Shanghai args: - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" volumeMounts: - mountPath: /var/lib/mysql #容器內的掛載目錄 name: volume-mariadb restartPolicy: Always volumes: - name: volume-mariadb hostPath: path: /data/mariadb type: Directory selector: matchLabels: app: mariadb-secret---apiVersion: v1kind: Servicemetadata: name: mariadb-secret-svcspec: selector: app: mariadb-secret ports: - port: 3306 targetPort: 3306 nodePort: 30036 type: NodePort
注意關鍵配置關鍵點:
容器內部掛載目錄:
volumeMounts: - mountPath: /var/lib/mysql #容器內的掛載目錄 name: volume-mariadb
容器外部掛載目錄:
volumes: - name: volume-mariadb hostPath: path: /data/mariadb type: Directory
部署:
在k8s-node01節點新建/data/mariadb目錄。
[root@k8s-master01 hostpath]# kubectl apply -f .secret/secret-demo createddeployment.apps/mariadb-secret createdservice/mariadb-secret-svc created[root@k8s-master01 hostpath]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESmariadb-secret-647f866cd9-98hvp 1/1 Running 0 6m43s 10.81.85.247 k8s-node01 <none> <none>[root@k8s-master01 hostpath]# kubectl get serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.1.0.1 <none> 443/TCP 6d17hmariadb-secret-svc NodePort 10.1.252.169 <none> 3306:30036/TCP 6m53s
k8s-node01節點檢視掛載目錄:
[root@k8s-node01 mariadb]# pwd/data/mariadb[root@k8s-node01 mariadb]# lltotal 141076-rw-rw---- 1 polkitd input 18620416 Dec 27 00:35 aria_log.00000001-rw-rw---- 1 polkitd input 52 Dec 27 00:35 aria_log_control-rw-rw---- 1 polkitd input 976 Dec 27 00:35 ib_buffer_pool-rw-rw---- 1 polkitd input 12582912 Dec 27 00:35 ibdata1-rw-rw---- 1 polkitd input 100663296 Dec 27 00:35 ib_logfile0-rw-rw---- 1 polkitd input 12582912 Dec 27 00:35 ibtmp1-rw-rw---- 1 polkitd input 0 Dec 27 00:35 multi-master.infodrwx------ 2 polkitd input 4096 Dec 27 00:35 mysqldrwx------ 2 polkitd input 20 Dec 27 00:35 performance_schema
新建資料庫david:
再次檢視掛載目錄:掛載目錄多了david資料夾
[root@k8s-node01 mariadb]# lltotal 141076-rw-rw---- 1 polkitd input 18620416 Dec 27 00:35 aria_log.00000001-rw-rw---- 1 polkitd input 52 Dec 27 00:35 aria_log_controldrwx------ 2 polkitd input 20 Dec 27 00:44 david-rw-rw---- 1 polkitd input 976 Dec 27 00:35 ib_buffer_pool-rw-rw---- 1 polkitd input 12582912 Dec 27 00:35 ibdata1-rw-rw---- 1 polkitd input 100663296 Dec 27 00:35 ib_logfile0-rw-rw---- 1 polkitd input 12582912 Dec 27 00:35 ibtmp1-rw-rw---- 1 polkitd input 0 Dec 27 00:35 multi-master.infodrwx------ 2 polkitd input 4096 Dec 27 00:35 mysqldrwx------ 2 polkitd input 20 Dec 27 00:35 performance_schema
注意:hostpath的限制只支援單節點(Node),而且只支援“ReadWriteOnce”模式
6. PV&PVCpersistentVolume (PV):是由管理員設定的儲存,它是叢集的一部分。就像節點是叢集中的資源一樣,PV也是叢集中的資源。PV是Volumes之類的卷外掛,但具有獨立於使用PV的pod的生命週期.
peresistentVolumeClaim(PVC):是使用者儲存的請求。它與pod相似,pod消耗節點資源,PVC消耗PV資源。pod可以請求特定級別的資源(CPU和記憶體)。甚至可以請求特定的大小和訪問模式。例如:可以以讀/寫一次或者 只讀多次模式掛載。
PV就好比是一個倉庫,我們需要先購買一個倉庫,即定義一個PV儲存服務,例如CEPH,NFS,LocalHostpath等等 。PVC就好比租戶,pv和pvc是一對一繫結的,掛載到POD中,一個pvc可以被多個pod掛載 。
6.1基於hostpath的pv&pvc案例pv資原始檔:注意storageClassName: standard是pv和pvc關聯點。掛載磁碟目錄為/data/pv/mariadb
apiVersion: v1kind: PersistentVolumemetadata: name: data-mariadb-pv labels: app: mariadb-pvspec: accessModes: - ReadWriteOnce #hostpath只支援ReadWriteOnce capacity: storage: 10Gi hostPath: path: /data/pv/mariadb type: DirectoryOrCreate #目錄,不存在就建立 persistentVolumeReclaimPolicy: Retain #回收策略 storageClassName: standard #pv和pvc關聯點 volumeMode: Filesystem
pvc資原始檔:
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: mariadb-pvc labels: app: mariadb-pvcspec: accessModes: - ReadWriteOnce storageClassName: standard #pv和pvc關聯 resources: requests: storage: 5Gi
pod資原始檔:
加密配置
apiVersion: v1kind: Secretmetadata: name: secret-demotype: Opaquedata: password: cm9vdA==
apiVersion: apps/v1kind: Deploymentmetadata: name: mariadb-secret labels: app: mariadb-secretspec: replicas: 1 template: metadata: name: mariadb-secret labels: app: mariadb-secret spec: nodeSelector: mariadb: mariadb #節點標籤選擇器 containers: - name: mariadb-secret image: mariadb:10.5.2 imagePullPolicy: IfNotPresent ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD #mysql root賬戶的密碼 valueFrom: secretKeyRef: key: password #secret資源的data.key,這個key可以自定義 name: secret-demo #定義secret資源的名稱 - name: TZ value: Asia/Shanghai args: - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" volumeMounts: - mountPath: /var/lib/mysql #容器內的掛載目錄 name: volume-mariadb restartPolicy: Always volumes: - name: volume-mariadb persistentVolumeClaim: claimName: mariadb-pvc #消耗的pvc name selector: matchLabels: app: mariadb-secret---apiVersion: v1kind: Servicemetadata: name: mariadb-secret-svcspec: selector: app: mariadb-secret ports: - port: 3306 targetPort: 3306 nodePort: 30036 type: NodePort
注意關鍵配置點:
volumes: - name: volume-mariadb persistentVolumeClaim: claimName: mariadb-pvc #消耗的pvc name
由配置看出pod->pvc->pv的消耗關係。
部署:
[root@k8s-master01 pv&pvchostpath]# kubectl apply -f .persistentvolume/data-mariadb-pv createdpersistentvolumeclaim/mariadb-pvc createdsecret/secret-demo createddeployment.apps/mariadb-secret createdservice/mariadb-secret-svc created#檢視pv RWO即ReadWriteOnce[root@k8s-master01 pv&pvchostpath]# kubectl get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEdata-mariadb-pv 10Gi RWO Retain Bound default/mariadb-pvc standard 88s#檢視pvc[root@k8s-master01 pv&pvchostpath]# kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEmariadb-pvc Bound data-mariadb-pv 10Gi RWO standard 2m6s#檢視pod[root@k8s-master01 pv&pvchostpath]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESmariadb-secret-54bbbdd557-ptts8 1/1 Running 0 2m23s 10.81.85.248 k8s-node01 <none> <none>
檢視掛載宿主機的目錄:
[root@k8s-node01 mariadb]# pwd/data/pv/mariadb[root@k8s-node01 mariadb]# lltotal 141076-rw-rw---- 1 polkitd input 18620416 Dec 27 01:13 aria_log.00000001-rw-rw---- 1 polkitd input 52 Dec 27 01:13 aria_log_control-rw-rw---- 1 polkitd input 976 Dec 27 01:13 ib_buffer_pool-rw-rw---- 1 polkitd input 12582912 Dec 27 01:13 ibdata1-rw-rw---- 1 polkitd input 100663296 Dec 27 01:13 ib_logfile0-rw-rw---- 1 polkitd input 12582912 Dec 27 01:14 ibtmp1-rw-rw---- 1 polkitd input 0 Dec 27 01:13 multi-master.infodrwx------ 2 polkitd input 4096 Dec 27 01:13 mysqldrwx------ 2 polkitd input 20 Dec 27 01:13 performance_schema
新建一個數據庫:
再次檢視掛載目錄:生成對應的資料夾。
[root@k8s-node01 mariadb]# lltotal 141076-rw-rw---- 1 polkitd input 18620416 Dec 27 01:13 aria_log.00000001-rw-rw---- 1 polkitd input 52 Dec 27 01:13 aria_log_control-rw-rw---- 1 polkitd input 976 Dec 27 01:13 ib_buffer_pool-rw-rw---- 1 polkitd input 12582912 Dec 27 01:13 ibdata1-rw-rw---- 1 polkitd input 100663296 Dec 27 01:13 ib_logfile0-rw-rw---- 1 polkitd input 12582912 Dec 27 01:14 ibtmp1-rw-rw---- 1 polkitd input 0 Dec 27 01:13 multi-master.infodrwx------ 2 polkitd input 4096 Dec 27 01:13 mysqldrwx------ 2 polkitd input 20 Dec 27 01:13 performance_schemadrwx------ 2 polkitd input 20 Dec 27 01:25 pv@002dpvc@002dhostpath
6.2 pv和pvc相關引數解析儲存機制:Kubernetes 為了能讓管理員方便管理叢集中的儲存資源,同時也為了讓使用者使用儲存更加方便,所以遮蔽了底層儲存的實現細節,將儲存抽象出兩個 API 資源 PersistentVolume 和 PersistentVolumeClaim 物件來對儲存進行管理。
PersistentVolume(持久化卷):是對底層共享儲存的一種抽象,將共享儲存定義為一種資源,它屬於叢集級別資源,不屬於任何 Namespace ,使用者使用 PV需要透過 PVC 申請。PV 是由管理員進行建立和配置,它和具體的底層的共享儲存技術的實現方式有關,比如說 Ceph、GlusterFS、NFS 等,都是透過外掛機制完成與共享儲存的對接,且根據不同的儲存 PV 可配置引數也是不相同。
PersistentVolumeClaim(持久化卷宣告): 是使用者儲存的一種宣告,類似於對儲存資源的申請,它屬於一個 Namespace 中的資源,可用於向 PV 申請儲存資源。 PVC 和 Pod 比較類似, Pod 消耗的是 Node 節點資源,而 PVC 消耗的是 PV 儲存資源, Pod 可以請求 CPU 和 Memory,而 PVC 可以請求特定的儲存空間和訪問模式。
PV支援儲存的型別:
RBD:Ceph 塊儲存。FC:光纖儲存裝置。NFS:網路問卷儲存卷。iSCSI:iSCSI 儲存裝置。CephFS:開源共享儲存系統。Flocker:一種開源共享儲存系統。Glusterfs:一種開源共享儲存系統。Flexvolume:一種外掛式的儲存機制。HostPath:宿主機目錄,僅能用於單機。AzureFile:Azure 公有云提供的 File。AzureDisk:Azure 公有云提供的 Disk。ScaleIO Volumes:DellEMC 的儲存裝置。StorageOS:StorageOS 提供的儲存服務。VsphereVolume:VMWare 提供的儲存系統。Quobyte Volumes:Quobyte 提供的儲存服務。Portworx Volumes:Portworx 提供的儲存服務。GCEPersistentDisk:GCE 公有云提供的 PersistentDisk。AWSElasticBlockStore:AWS 公有云提供的 ElasticBlockStore。
PV的生命週期:
Available(可用)—— 可用狀態,尚未被 PVC 繫結。Bound(已繫結)—— 繫結狀態,已經與某個 PVC 繫結。Released(已釋放)—— 與之繫結的 PVC 已經被刪除,但資源尚未被叢集回收。Failed(失敗)—— 當刪除 PVC 清理資源,自動回收卷時失敗,所以處於故障狀態PV資原始檔相關引數:
capacity .storage: PV 掛多大儲存空間進行設定
volumeMode:儲存卷模式指定,可選項包括
Filesystem: 檔案系統,預設是此選項。Block: 塊裝置accessModes :訪問模式,包含三種
ReadWriteOnce——該卷可以被單個節點以讀/寫模式掛載ReadOnlyMany——該卷可以被多個節點以只讀模式掛載ReadWriteMany——該卷可以被多個節點以讀/寫模式掛載不過不同的儲存所支援的訪問模式也不相同。
mountOptions:掛載引數 ,PV 可以根據不同的儲存卷型別,設定不同的掛載引數,每種型別的儲存卷可配置引數都不相同。
storageClassName: PV 可以透過配置 storageClassName 引數指定一個儲存類 StorageClass 資源,具有特定StorageClass 的 PV 只能與指定相同 StorageClass 的 PVC 進行繫結 。
persistentVolumeReclaimPolicy:回收策略 ,包含如下三種選項
Retain(保留): 保留資料,需要由管理員手動清理。Recycle(回收): 刪除資料,即刪除目錄下的所有檔案,比如說執行 rm -rf /thevolume/* 命令,目前只有 NFS 和 HostPath 支援。Delete(刪除): 刪除儲存資源,僅僅部分雲端儲存系統支援,比如刪除 AWS EBS 卷,目前只有AWS EBS,GCE PD,Azure 磁碟和 Cinder 卷支援刪除。PVC資原始檔相關引數:
selector:篩選器,PVC 可以透過在 Selecter 中設定 Laberl 標籤,篩選出帶有指定 Label 的 PV 進行繫結。
resources :PVC 設定目前只有 requests.storage 一個引數,用於指定申請儲存空間的大小。
storageClass :PVC 要想繫結帶有特定 StorageClass 的 PV 時,也必須設定 storageClassName 引數,且名也必須要和 PV 中的 storageClassName 保持一致。
accessModes:PVC 中可設定的訪問模式與 PV 種一樣,用於限制應用對資源的訪問許可權。
7.NFS7.1相關概念NFS 是 Network FileSystem 的縮寫,顧名思義就是網路檔案儲存系統, 分為服務端(Server)和客戶端(Client).允許網路中的計算機之間透過 TCP/IP 網路共享資源.透過 NFS,我們本地 NFS 的客戶端應用可以透明地讀寫位於服務端 NFS 伺服器上的檔案,就像訪問本地檔案一樣方便。簡單的理解,NFS 就是可以透過網路,讓不同的主機、不同的作業系統可以共享儲存的服務.
NFS 在檔案傳送或資訊傳送過程中依賴於 RPC(Remote Procedure Call) 協議,即遠端過程呼叫, 簡單的理解二者關係:NFS是 一個檔案儲存系統,而 RPC是負責資訊的傳輸 .
NFS共享儲存方式
手動方式靜態建立所需要的PV和PVC。透過建立PVC動態地建立對應PV,無需手動建立PV7.2 NFS安裝NFS安裝:k8s叢集所有節點都需要安裝NFS服務,選用k8s的master節點作為NFS服務的server端(因本地磁碟和記憶體限制) 。
yum install -y nfs-utils rpcbind
在master上建立共享目錄:
[root@k8s-master01 ~]# useradd nfsnobody[root@k8s-master01 ~]# password nfsnobody[root@k8s-master01 ~]# mkdir -p /nfs/mariadb[root@k8s-master01 ~]# chmod 777 /nfs/mariadb[root@k8s-master01 ~]# chown nfsnobody /nfs/mariadb#新增配置檔案vi /etc/exports#新增配置內容/nfs/mariadb *(rw,no_root_squash,no_all_squash,sync)#啟動nfs服務systemctl start rpcbindsystemctl start nfs#設定開啟啟動systemctl enable rpcbindsystemctl enable nfs
掛載測試
#在node01 檢視共享目錄[root@k8s-node01 mariadb]# showmount -e 192.168.223.131Export list for 192.168.223.131:/nfs/mariadb *#在客戶端建立掛在目錄[root@k8s-node01 mariadb]# mkdir -p /data/mariadb#掛載遠端目錄到本地 /data/mariadb 目錄[root@k8s-node01 mariadb]# mount 192.168.198.156:/nfs/mariadb /data/mariadb#在服務端編寫一個txt檔案[root@k8s-master01 mariadb]# vim test.txt#在node01檢視掛載的共享目錄[root@k8s-node01 mariadb]# lstest.txt#解除安裝,有可能無法解除安裝[root@k8s-node01 mariadb]# umount /data/mariadb umount.nfs4: /data/mariadb: device is busy#強制解除安裝[root@k8s-node01 mariadb]# umount -l /data/mariadb/
7.3 NFS結合k8s案例7.3.1修改nfs配置
使用NFS4協議方式進行多共享目錄配置。所有共享目錄的根目錄為/nfs/data。伺服器端的/etc/exports檔案中的配置為 :
/nfs/data *(rw,fsid=0,sync,no_wdelay,insecure_locks,no_root_squash)#重啟NFS服務systemctl restart rpcbindsystemctl restart nfs
7.3.2 資源清單以及部署驗證
在6.1案例的基礎之上修改:
pv:
apiVersion: v1kind: PersistentVolumemetadata: name: data-mariadb-pv labels: app: mariadb-pvspec: accessModes: - ReadWriteOnce capacity: storage: 10Gi mountOptions: - hard - nfsvers=4.1 nfs: path: /mariadb # server: 192.168.223.131 persistentVolumeReclaimPolicy: Retain storageClassName: standard volumeMode: Filesystem
關鍵點:K8S的靜態NFS服務PV的nfs:path 的值不用寫共享根目錄,直接寫/mariadb即可。K8S會幫我們配置成/nfs/data/mariadb目錄
mountOptions: - hard - nfsvers=4.1 nfs: path: /mariadb server: 192.168.223.131
pvc:
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: mariadb-pvc labels: app: mariadb-pvcspec: accessModes: - ReadWriteOnce storageClassName: standard #pv和pvc關聯 resources: requests: storage: 5Gi
secrets:
apiVersion: v1kind: Secretmetadata: name: secret-demotype: Opaquedata: password: cm9vdA==
pod:
apiVersion: apps/v1kind: Deploymentmetadata: name: mariadb-secret labels: app: mariadb-secretspec: replicas: 1 template: metadata: name: mariadb-secret labels: app: mariadb-secret spec: containers: - name: mariadb-secret image: mariadb:10.5.2 imagePullPolicy: IfNotPresent ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD #mysql root賬戶的密碼 valueFrom: secretKeyRef: key: password #secret資源的data.key,這個key可以自定義 name: secret-demo #定義secret資源的名稱 - name: TZ value: Asia/Shanghai args: - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" volumeMounts: - mountPath: /var/lib/mysql #容器內的掛載目錄 name: volume-mariadb restartPolicy: Always volumes: - name: volume-mariadb persistentVolumeClaim: claimName: mariadb-pvc #消耗的pvc name selector: matchLabels: app: mariadb-secret---apiVersion: v1kind: Servicemetadata: name: mariadb-secret-svcspec: selector: app: mariadb-secret ports: - port: 3306 targetPort: 3306 nodePort: 30036 type: NodePort
部署:
[root@k8s-master01 nfs]# kubectl apply -f .persistentvolume/data-mariadb-pv createdpersistentvolumeclaim/mariadb-pvc createdsecret/secret-demo createddeployment.apps/mariadb-secret createdservice/mariadb-secret-svc created[root@k8s-master01 nfs]# kubectl get podNAME READY STATUS RESTARTS AGEmariadb-secret-5997bb67cb-cj748 1/1 Running 0 11s#檢視pv[root@k8s-master01 nfs]# kubectl get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEdata-mariadb-pv 10Gi RWO Retain Bound default/mariadb-pvc standard 10m#檢視pvc[root@k8s-master01 nfs]# kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEmariadb-pvc Bound data-mariadb-pv 10Gi RWO standard 10m#檢視nfs共享目錄[root@k8s-master01 mariadb]# cd /nfs/data/mariadb/[root@k8s-master01 mariadb]# lltotal 141092-rw-rw---- 1 polkitd input 18636800 Dec 27 06:17 aria_log.00000001-rw-rw---- 1 polkitd input 52 Dec 27 06:17 aria_log_control-rw-rw---- 1 polkitd input 976 Dec 27 06:17 ib_buffer_pool-rw-rw---- 1 polkitd input 12582912 Dec 27 06:17 ibdata1-rw-rw---- 1 polkitd input 100663296 Dec 27 06:17 ib_logfile0-rw-rw---- 1 polkitd input 12582912 Dec 27 06:17 ibtmp1-rw-rw---- 1 polkitd input 0 Dec 27 06:16 multi-master.infodrwx------ 2 polkitd input 4096 Dec 27 06:17 mysqldrwx------ 2 polkitd input 20 Dec 27 06:16 performance_schema
使用資料庫工具驗證連結: