9. kubernetes 存儲卷

9. kubernetes 存儲卷

[TOC]

本文基于馬哥的docker和k8s視頻總結(jié), 在此致謝馬哥.

k8s上可以用的三種存儲卷類型

emptyDir

  • (1) emptyDir 只在節(jié)點本地使用, 且pod刪除時存儲卷會隨之被刪除, 用于當臨時目錄或緩存, 此存儲卷可使用節(jié)點的內(nèi)存

    一個存儲卷可以在同一個pod內(nèi)的多個容器間共享:

apiVersion: v1
kind: Pod
metadata:
    name: pod-demo
    namespace: default
    labels:
        app: myapp
        tier: frontend
    annotations:
        magedu.com/create-by: "cluster admin"
spec:
    containers:
    - name: myapp
        image: nginx
        ports:
        - name: http
            containerPort: 80
        volumeMounts:
        - name: html # 掛載名為html的存儲卷 (需要使用下面存在的volumes)
            mountPath: /usr/share/nginx/html/ # 掛載點路徑
            # 其他參數(shù): readOnly, subPath, mountPropagation
    - name: busybox
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        volumeMounts: # 掛載是容器級別的, 哪個容器使用, 哪個容器就要掛載, 不掛載時訪問不到數(shù)據(jù)
        - name: html
            mountPath: /data/ # 注意兩個容器的掛載路徑可以不同
        command:
        - "/bin/sh"
        - "-c"
        - "while true; done echo $(date) >> /data/index.html; sleep 10; done"
    volumes:
    - name: html
        emptyDir: {} # 可以指定為空, 表示使用默認值(使用硬盤空間, 不限制使用大小)
            # medium 指定使用的存儲卷設(shè)備, 空字符串代表使用硬盤, Memory代表使用內(nèi)存
            # sizeLimit 指定使用的存儲卷大小
kubectl apply -f vol-demo1.yml
kubectl exec -it pod-demo -c busybox -- /bin/sh
/ # echo $(date) >> /data/index.html
kubectl exec -it pod-demo -c myapp -- /bin/sh
/ # cat /data/web/html/index.html # 可以在另一個容器中看到共享的數(shù)據(jù)

kubect get pods -o wide # 查看pod的IP
curl pod_IP

hostPath

  • (2) hostPath 宿主機路徑, 將pod上的存儲卷與宿主機的目錄做映射
hostPath支持的type類型.png
apiVersion: v1
kind: Pod
metadata:
    name: pod-hostpath-vol
    namespace: default
spec:
    containers:
    - name: myapp
        image: nginx:1.14:alpine
        volumeMounts:
        - name: html
            mountPath: /usr/share/nginx/html/  
        volumes:
        - name: html
            hostPath:
                path: /data/pod/volume1/
                type: DirectoryOrCreate # 目錄不存在時自動創(chuàng)建
mkdir -p /data/pod/volume1/
echo "test hostPath" >> /data/pod/volume1/index.html # 只要節(jié)點上有相同內(nèi)容, 則pod宕了也沒關(guān)系
kubectl apply -f pod-hostpath-vol.yml

nfs為例

  • (3) 共享存儲, 支持awsElasticBlockStore, azureDisk, cephfs, glusterfs, gitRepo, nfs, iscsi, rbd
# node1(ip為192.168.200.200)作為nfs服務(wù)的提供者
yum -y install nfs-utils # 作為nfs共享存儲的節(jié)點需要安裝此包
mkdir /data/volumes -pv
vi /etc/exports
/data/volumes  192.168.0.0/16(rw,no_root_squash)
systemctl start nfs

# node2(ip為192.168.200.201)作為nfs服務(wù)的使用者
yum -y install nfs-utils
mount -t nfs 192.168.200.200:/data/volumes /mnt # 一定要進行掛載測試
umount /mnt
vi pod-nfs-vol.yml
apiVersion: v1
kind: Pod
metadata:
    name: pod-nfs-vol
    namespace: default
spec:
    containers:
    - name: myapp
        image: nginx:1.14:alpine
        volumeMounts:
        - name: html
            mountPath: /usr/share/nginx/html/  
        volumes:
        - name: html
            nfs:
                path: /data/pod/volumes
                server:
                    192.168.200.201
                readOnly: false # 默認就是false, 即rw
kubectl apply -f pod-nfs-vol.yml

注: nfs支持多客戶端同時掛載, 支持多客戶端的多路讀寫訪問

pvc和pv

pvcpv也是標準的k8s資源

定義存儲模型.png
kubectl explain pods.spec.volumes.persistentVolumeClaim
    claimName # 必要選項, 指明已創(chuàng)建好的pvc名稱
    readOnly # default false

kubectl explain pvc.spec
    accessModes <[]string># 訪問模型, 這里不可隨便定義, 有些設(shè)備可能不支持某種模型
        ReadWriteOnce # 單路讀寫, 可簡寫為RWO
        ReadOnlyMany # 多路只讀, 可簡寫為ROM
        ReadWriteMany # 多路讀寫, 可簡寫為RWM
    resources # 資源限制, 對應(yīng)的存儲空間至少需要的大小
    selecotr # pv可以有標簽, pvc上使用selector時表示必須使用哪個pv建立關(guān)聯(lián)關(guān)系, 不加selector時自動選擇最佳匹配
    volumeMode # 后端存儲卷的模式, 可以不指定
    volumeName # 卷名稱, 綁定某個pv, 可以不指定

kubectl explain pv.spec
    accessModes <[]string># 訪問模型, 這里不可隨便定義, 有些設(shè)備可能不支持某種模型
        ReadWriteOnce # 單路讀寫, 可簡寫為RWO
        ReadOnlyMany # 多路只讀, 可簡寫為ROM
        ReadWriteMany # 多路讀寫, 可簡寫為RWM
    capacity <map[string]string> # 定義存儲空間大小, 支持E, P, T, G, M, K, m和Ei, Pi, Ti, Gi, Mi, Ki, mi
        stroage
  • 創(chuàng)建pvc后會去找系統(tǒng)上合適的pv進行綁定, 如果沒有則掛起(pending), 例如pvc需要使用30G, 而pv現(xiàn)在最大創(chuàng)建的容量只有20G, 不滿足條件, 操作被掛起, 直到滿足條件

  • pvpvc是一一對應(yīng)的關(guān)系, 如果某個pvpvc占用了, 則這個pv不能再被其他pvc占用, 但一個pvc可以被多個pod訪問

# node1(ip為192.168.200.200)作為nfs服務(wù)的提供者
yum -y install nfs-utils # 作為nfs共享存儲的節(jié)點需要安裝此包
mkdir /data/volumes -pv
vi /etc/exports
/data/volumes/v1  192.168.0.0/16(rw,no_root_squash)
/data/volumes/v2  192.168.0.0/16(rw,no_root_squash)
/data/volumes/v3  192.168.0.0/16(rw,no_root_squash)
/data/volumes/v4  192.168.0.0/16(rw,no_root_squash)
/data/volumes/v5  192.168.0.0/16(rw,no_root_squash)
exportfs -arv
showmount -e

# node2(ip為192.168.200.201)作為nfs服務(wù)的使用者
yum -y install nfs-utils
mount -t nfs 192.168.200.200:/data/volumes /mnt # 一定要進行掛載測試
umount /mnt
vi pod-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv001 # 定義pv時千萬不要定義namespace, 因為pv是集群級別的, 不屬于namespace
    labels:
        name: pv001
spec:
    nfs:
        path: /data/volumes/v1
        server: 192.168.200.200
    accessModes: ["ReadWriteMany", "ReadWriteOnce"]
    capacity:
        storage: 2Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv002
    labels:
        name: pv002
spec:
    nfs:
        path: /data/volumes/v2
        server: 192.168.200.200
    accessModes: ["ReadWriteMany"]
    capacity:
        storage: 5Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv003
    labels:
        name: pv003
spec:
    nfs:
        path: /data/volumes/v3
        server: 192.168.200.200
    accessModes: ["ReadWriteMany", "ReadWriteOnce"]
    capacity:
        storage: 20Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv004
    labels:
        name: pv004
spec:
    nfs:
        path: /data/volumes/v4
        server: 192.168.200.200
    accessModes: ["ReadWriteMany", "ReadWriteOnce"]
    capacity:
        storage: 10Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv005
    labels:
        name: pv005
spec:
    nfs:
        path: /data/volumes/v5
        server: 192.168.200.200
    accessModes: ["ReadWriteMany", "ReadWriteOnce"]
    capacity:
        storage: 10Gi

---
kubectl apply -f pod-pv.yml
kubectl get pv
    # RECLAIM POLICY 回收策略, 某個pvc綁定了pv, 當pvc被刪除后pv內(nèi)還有數(shù)據(jù), 該如何處理?
        # Retain 保留數(shù)據(jù)
        # Recycle 回收
        # Delete 刪除

vi pod-pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: mypvc
    namespace: default
spec:
    accessModes: ["ReadWriteMany"] # pvc的accessModes必須是pv的子集
    resources:
        requests: # 要求有多大的存儲空間
            storage: 6Gi

---
apiVersion: v1
kind: Pod
metadata:
    name: pod-vol-pvc
    namespace: default
spec:
    containers:
    - name: myapp
        image: nginx:1.14:alpine
        volumeMounts:
        - name: html
            mountPath: /usr/share/nginx/html/  
        volumes:
        - name: html
            persistentVolumeClaim:
                claimName: mypvc
kubeclt apply -f pod-pvc.yml
kubectl get pv # 可查看STATUS, 是否被Bound
kubectl get pvc

特殊類型的存儲卷: 用于制作數(shù)據(jù)中心

配置容器化應(yīng)用的方式有以下幾種:

  • (1) 自定義命令行參數(shù)
    • command
    • args: []
  • (2) 把配置文件直接放入基本鏡像并重構(gòu)
  • (3) 環(huán)境變量
    • (3.1) Could Native的應(yīng)用程序一般可直接通過環(huán)境變量加載配置
    • 通過entrypoint腳本來預(yù)處理變量為配置文件中配置信息
  • (4) 存儲卷
    • (4.1) configmap: 明文
    • (4.2) secret: 密文

configmap

# 創(chuàng)建configmap的方式:
# 第一種: 直接直接用命令行的方式給定
kubectl create configmap nginx-config --from-literal=nginx_port=80 --from-ilteral=server_name=myapp.magedu.com
    # --from-literal=key=value 直接用命令行的方式給定
kubectl get cm
kubectl describe cm nginx-config
    # 可在顯示信息中看到Data (定義的key和value)

# 第二種: 配置文件給定
mkdir configmap
vi www.conf
server {
    server_name myapp.magedu.com;
    listen 80;
    root /data/web/html/;
}

kubectl create configmap nginx-www --from-file=www=./www.conf
    # 按這種方式指定, key=www, value=www.conf的文件內(nèi)容
kubectl create configmap nginx-www --from-file=./www.conf
    # 按照這種方式指定, key=文件名(此例中為www.conf), value=www.conf的文件內(nèi)容
kubectl descirbe cm nginx-www

vi pod-configmap.yml
  • 通過環(huán)境變量的方式向pod傳數(shù)據(jù):
apiVersion: v1
kind: Pod
metadata:
    name: pod-demo-1
    namespace: default
    labels:
        app: myapp
        tier: frontend 
    annotations:
        alexti/created-by: "cluster admin"
spec:
    containers: 
    - name: myapp 
        image: nginx:1.14-alpine 
        ports: 
        - name: http
            containerPort: 80
        env:
        - name: NGINX_SERVER_PORT # 變量最好使用下劃線
            valueFrom: 
                configMapKeyRef: # 引用configmap獲取數(shù)據(jù)
                    name: nginx-config
                    key: nginx_port # nginx_port的值會傳遞給變量NGINX_SERVER_PORT
                    optional: true # 如果configmap不存在或者configmap中定義的變量沒有你需要使用的key, pod將無法被啟動, 可以將這一項的值設(shè)置為true, 表示此configmap可以在定義完之后再創(chuàng)建
        - name: NGINX_SERVER_NAME
            valueFrom:
                configMapKeyRef:
                    name: nginx-conf
                    key: server_name
                    optional: true
kubectl apply -f pod-configmap.yml
kubectl exec -it pod pod-demo-1 -- /bin/sh
/ # printenv # 可查看到自定義的變量: NGINX_SERVER_PORT和NGINX_SERVER_NAME

kubectl edit cm nginx-config # 支持編輯
  • 通過存儲卷的方式向pod傳數(shù)據(jù):

方法一, 使用命令行創(chuàng)建的configmap:

vi pod-configmap2.yml
apiVersion: v1
kind: Pod
metadata:
    name: pod-demo-2
    namespace: default
    labels:
        app: myapp
        tier: frontend 
    annotations:
        alexti/created-by: "cluster admin"
spec:
    containers: 
    - name: myapp 
        image: nginx:1.14-alpine 
        ports: 
        - name: http
            containerPort: 80
        volumeMounts:
        - name: nginxconf
            mountPath: /etc/nginx/config.d/
            readOnly: true # 不允許容器修改配置文件
        volumes:
        - name: nginxconf
            configMap: # 存儲卷類型為configMap
                name: nginx-config
kubectl apply -f pod-configmap2.yml
kubectl exec -it pod pod-demo-2 -- /bin/sh
/ # cd /etc/nginx/config.d/
/ # ls # 可以查看到兩個文件, 文件名為nginx_port和server_name

kubectl edit cm nginx-config
    # 將nginx_port從80改為8080

kubectl exec -it pod pod-demo-2 -- /bin/sh
/ # cat /etc/nginx/config/nginx_port # 此時可以查看到結(jié)果為修改后的8080

方法二, 使用創(chuàng)建的配置文件:

vi pod-configmap3.yml
apiVersion: v1
kind: Pod
metadata:
    name: pod-demo-3
    namespace: default
    labels:
        app: myapp
        tier: frontend 
    annotations:
        alexti/created-by: "cluster admin"
spec:
    containers: 
    - name: myapp 
        image: nginx:1.14-alpine 
        ports: 
        - name: http
            containerPort: 80
        volumeMounts:
        - name: nginxconf
            mountPath: /etc/nginx/conf.d/
            readOnly: true # 不允許容器修改配置文件
        volumes:
        - name: nginxconf
            configMap: # 存儲卷類型為configMap
                name: nginx-www
                # 指定items可以只掛載部分鍵值而不是全部
kubecgtl apply -f pod-configmap3.yml
kubectl get pods
kuebctl exec -it pod-demo-3 -- /bin/sh
/ # cat /etc/nginx/conf.d/www.conf # 可看到使用配置文件定義的配置
/ # nginx -T # 查看nginx加載的配置

kubectl edit cm nginx-www
    # 將某個參數(shù)修改, 例如listen的值改為8080, 等待一段時間后會發(fā)現(xiàn)pod內(nèi)的配置會隨之修改為8080, 但此時配置還未生效, 需要重載配置文件
/ # nginx -s reload

secret

kubectl create secret --help
    # 有三種類型
    generic # 通用的secret, 一般用于保存密碼
    tls # 保存私鑰和證書
    docker-registry # 保存docker-registry認證信息, 連接私有倉庫時拉取鏡像時使用

kubectl create secret generic mysql-root-password --form-literal=password=MyP@ss123
kubectl get secret
kubectl descirbe secret mysql-root-password # 會發(fā)現(xiàn)值不顯示
kubectl get secret mysql-root-password -o yaml
echo "經(jīng)base加密后的密碼" | base64 -d # 解碼, 可看到密碼源碼, 說明密碼安全性不佳

vi pod-secret-1.yml
apiVersion: v1
kind: Pod
metadata:
    name: pod-demo-4
    namespace: default
    labels:
        app: myapp
        tier: frontend 
    annotations:
        alexti/created-by: "cluster admin"
spec:
    containers: 
    - name: myapp 
        image: nginx:1.14-alpine 
        ports: 
        - name: http
            containerPort: 80
        env:
        - name: MYSQL_ROOT_PASSWORD
            valueFrom: 
                secretKeyRef:
                    name: mysql-root-password
                    key: password
                    optional: true
kubectl apply -f pod-secret-1.yml
kubectl exec -it pod-demo-4 -- printenv # 會發(fā)現(xiàn)傳入的MYSQL_ROOT_PASSWORD在會解密后通過環(huán)境變量的方式注入pod
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末叔遂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子争剿,更是在濱河造成了極大的恐慌已艰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚕苇,死亡現(xiàn)場離奇詭異哩掺,居然都是意外死亡,警方通過查閱死者的電腦和手機涩笤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門嚼吞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蹬碧,你說我怎么就攤上這事舱禽。” “怎么了锰茉?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵呢蔫,是天一觀的道長。 經(jīng)常有香客問我,道長片吊,這世上最難降的妖魔是什么绽昏? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮俏脊,結(jié)果婚禮上全谤,老公的妹妹穿的比我還像新娘。我一直安慰自己爷贫,他們只是感情好认然,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著漫萄,像睡著了一般卷员。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腾务,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天毕骡,我揣著相機與錄音,去河邊找鬼岩瘦。 笑死未巫,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的启昧。 我是一名探鬼主播叙凡,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼密末!你這毒婦竟也來了握爷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤严里,失蹤者是張志新(化名)和其女友劉穎饼拍,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體田炭,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年漓柑,在試婚紗的時候發(fā)現(xiàn)自己被綠了教硫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡辆布,死狀恐怖瞬矩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锋玲,我是刑警寧澤景用,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響伞插,放射性物質(zhì)發(fā)生泄漏割粮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一媚污、第九天 我趴在偏房一處隱蔽的房頂上張望舀瓢。 院中可真熱鬧,春花似錦耗美、人聲如沸京髓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽堰怨。三九已至,卻和暖如春蛇摸,著一層夾襖步出監(jiān)牢的瞬間备图,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工皇型, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诬烹,地道東北人。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓弃鸦,卻偏偏與公主長得像绞吁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子唬格,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容