kubernetes快速入门9-存储卷volumes

kubernetes快速入门9-存储volumes

volumes的出现主要解决以下两个问题:

  1. 容器中数据的持久化,因容器中的文件是临时存放的,一旦容器崩溃后kubelet将重建容器,容器将以一个干净的状态被重建
  2. 一个Pod中多个容器间数据共享

存储大体上可以分为本地类型存储网络连接类型存储,而网络连接型的存储又可以分为传统意义上的NAS和SAN存储分布O O a式类型网络连接存储第三方云端存储

在k8s中pod是调度的最小单位,volu- N ; p u s I ~mes也是挂载在po I m l sod上的。Kubernetes 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷。使用卷时, Pod 声明中需要提供卷的类型 (.spec.volumes 字段)和卷挂载的位置 (.spec.cok f nntainers.vr 2 X { P )olumeMd S b # Iounts 字段).

Volume的类型

emptyDir

pods.spec.volumes
emptyDir    <Object>  空目录
medium  <string>  卷的介质,默认值为"",表示使用节点的磁盘介质,也可以设置为Memory,表示使用内存
sizeLimit   &l% V f I x t y Bt;string> 大小上限制,使用磁盘为存储介质时,大小限制取绝于磁盘大小
最佳实践:实际使用中,使用“emptyDir {}”,表示使用磁盘介质,大小也受限于磁盘

emptyDir类型的卷的生生命周期和pod相同,pod一旦被删除,那卷里的数据也被删除。

以一个pod运行两个container,共享emptDir存储卷举一个事例。

k8s@node01:~/my_manifests/volumes$} ! U Y - cx . n F ; A { + Gat emptydir-pods.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp
namespace: defau` d 2 o 4 3lt
labels:
app: myapp
spec:
cont $ i } ~ Q Bainers:
- name: mZ U , Q 3 8yapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http! y @ : ]
containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
- name: busybox
image: busybox:latest
volumeMounts:
- name:8 G Z ^ H f html
mountPath: /data/
command: ["/bin/sh", "-c", "while true; do echo $(date) >> /data/index.html; sleep 2; done"]
volumes:
-s - u c } name: html
emptyDir: i  o u G J x R: {}
# 资源配置清单说明:
# pod中d V ` z Y , A两个容器运行后都会先挂载指定类型为emptyDir的存储卷,容器myapp挂载到/usr/so g n 9hare/nginx/html/,覆盖原有的nginx的root目录,g T / H n此时该目录为空目录;容器busybox启动后也把emptyDir这个存储卷挂载到/data/目录,并每隔2秒种向该目录的index.html文件写数据,而myqpp容器提供的http服务就有了主页文件。
k8s@node01:~/m% d zy_manifests/volumes$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
myapp   2/2     Running   0          19s   10.244.2.93   node03   <none>           <none>
# 访o ; ~ H问测试
k8s@node01:~/my_manifests/volumes$ curl 10.244.2.93
Tue Jul 28 08:15:12 UTC 2020
Tue Jul 28 08:15:14 UTC 2020
Tue Jul 28 08:15:16 UTC 2020
Tue Jul 28 08:15:18 UTC 2020
Tue Jul 28 08:15:20 U[ $ I WTC 2020
Tues & C g Y P R . d JulL ` { $ 6 28 08:15:22 UTC 2020
Tue Jul 28 08:15:24 UTC 2020
Tue Jul 28 08:15:26 UTC 2020
Tue Jul 28 08:15:28 UTu , * ^C 2020

hostPath

pods.spec.volumes
hostPath    &lc  Q L lt;Object&1 M {gt;  在工作节点上挂载一个已存在的文件或目录
path    <string> -required-  工作节点上的文件路径
type    <string>   hostPath的类型,有许多,参考:https://kubernetes.io/zh/docs/concepts/storage/volumes/#hostpath

hostPath类型的存储卷不会因pod被删除而删除,它能把数据持久化在工作节点上,但pod被删除重建后被调度到其他工作上运行,那之前持久化的数据在该工作节点上是没有的,所以在k8s中此种类型的存x } t 0 C b v储卷很少用。

k8s@node01:~/my_N f k ! Q D B  cmanT H R ? 3 N ) 8ifests/volumes$ cat hostpath M + Z F 1 Xh-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-hostpath
namespace: default
labels:
ap[ + u K I I xp: myapp
spec:
containers:
-W 2 p X U Y y name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:R M z
- name: http
containerPort& 3 5 @ } . g i: 80
volumeMounts:
- nameh L ` @ 3 R ] Z: html
mountPath: /usB s Zr/share/nginx/html/
volumeA i # h ) 1 Ds:
- name: html
hostPath:
path: /data/pub/html/
type: DirectoryOrCreate  # 目录不存在自动创建
k8s@node01:~/my_manifests/volumes$ kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODw  lE     NOMINATED NODE   READINESS GATES
myapp-hostpath   1/1     Running   0          8s    10.244.2.95   node03   <none>           <none>
# pod运行在了node03上,所以在node03上创建一个主页文件
root@node03:~# echo "hello." >&x 7 Ugt; /data/pub/html/index.html
# 访问测试
root@node03:~# curl 10.244.2.95
hw 1 x Yello.

nf[ } i Hs

在pod启动时将挂载nfs存储卷,pod被删除时只是卸载已挂载的存储卷,而存储卷中的内容被存储所保q M d & ^ k留。

podsX x f.spec.volumeH 2 D L bs
nfs <Obi _ } n , ! J / Vject>
path    <string> -required-    nfs的挂载路径
server  <string> -required-  nfs地址

先准备nfs环境,就在s J j node01主节点上安装nfs服务

# 安装nfs服务
k8s@node01:~$ sudo apt install nfs-kernez J Xls . N-server
k8s@node01:* G G 5 K : O~$ ss -tanl | grep 2049
LISTEN   0         64                   0.0.0.0:2049             0.0.0.0:*
LISTEN   0         64                      [::]:2049                [::]:*
# 准备nfs 2 s K h _ A P cs共享目{ } { y } ,录及文件
k_ W W u U h8s@node01:~$ cat /data/nfs/volume/indeK  g J j Ox.html
this is a test page.
k8s@node01:~$ cat /etc/eQ | + 2 W wxports
/data/nfs/voluU H 6me  192T d n.168.101.0/24(rw,sync,no_subtree_check,root_squash)
k8s@^ . 8 = C pnode01:~$ sudo eg X a = { = .xportfs -ra

在各工作节点上安装nfs] F ^-common客户端工具,让mount支持nfs类型的挂载

root@node03:~# apt-get install nfs-common
# 测试
root@node03:~X R A V ( b e ` g# mouf W T ~ ? F Mnt -t nfs node01:/data/nfZ ` J s g }s/volume /mn% r ] E j f ot
root@node03:~# cat /mnt/index.6 A 1 W T [ ^htd C | S 0 M 5 2ml
this is a test page.

编写D 1 C H ) a J ^清单文件并运用

k8s@node01:~/my_manifests/volumes$ ca0 : k et nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-nfs
namesp6 y s 0 ; Zace: default
labels:
app: myapp
spec:
containers:
- name: myapp-nfs
image: ikubernetes/myapp:v1
imagePullPolb ~ Q | V O b ficy: IfNotPresent
ports:
- name: http
contM j 1 R [ ] mainerPort: 8f m i ?0
volumeMounts:
- name: html
mountPath: /u? ^ 1 O `sr/sX 0 K ^ 8 m X + jhare/nginx/html/
volumes:
- namf ( F B Ie: html
nfs:  # nfs类型只需要提供挂载目录及服务器地址
path: /data/nfs/volume/
server: node01.k8s] _ 5 E $.com
k8s@node01:~/my_manifests/volZ | ,  T ; 7umes$ kubectl apz T N qply -f nfs-pod.yaml
k8s@node01:~/my_manifests/volumes$ kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
myapp-nfs   1/1     Running   0          6sN d ^ } ( 1 v ,    10.244.2.96   node03   <none>           <* U 2  O % 8 Nnone>
k8s@node01:~/my_manifests/volumes$ curl 10.244.2.96, 3 ~ r 5
this is a tN $ gest page.M Y B K z f E ?

PV及PVC

Persistent Volumes简写为PV,译为持久卷;Persistent Volumes Clain简写为PVC,译为持久卷认领。

在k8s集群中,pod中的数据想持久化,一般是需要外部的存储集群来9 b Q 6 i ] L p提供该能力,而存储集群可以多种,可以是NFS,Ceph RBD,GlsterFS, az= I [ % mureDisk等,要想接入这些存储,需要熟悉使用这些u r ~ = x C k W存储的接口API,各种参数,而对于k8s用户来说这十分困难,所K ^ 7 a X X {以引入了PV和PVC这两个概念。

PV和PVC都是k8s中的资源,PV没有名称空间的概念,它是针对k8s整个集群而言,它运行在各种存储集2 1 l r ( g f 2 群之上的一种抽象,对于不同的存储,会具有不同的特性,比如存储的速度,大小等,针对这些特性,管理员需要创建H O A S P不同特性的PV,PV不直接对用户开放,用户想要使用存储只需要向PVC申请即可,用户在申请存储使用时只需要表明使用存储的一些基本特性,比如要多大的存储设备,要速度快的等,PVC就可以在创建好的PV中寻找一个适合要求的与之建立绑定关系并分配相应的存储空间给用h M J ,户使用,用户就不需要关心到底使用的何种存储,细节被PVC抹平。PV与PVC是一一对应的关系,PV一旦被一个PVC绑定就不能被其他的PVC绑定。

使用ku( P I R /bectl explain pv查看帮助信息

KIND:     Py 3 | | f X bersistentVolume
VERSION:  v1    属于核心群组中的v1
spec <Object>
accessModes <[]string&s } 1 k u * .gt;   访问模型,参考:https://kubernetes.io/o - $ T T ` # bdocs/concepts/storage/persistent-volumes#access-modes
nfs <Object>  nfs类型的n . ^pv
capacity    <map[string]string>  定义pv的容量
storage <string>  大小,单位以1000进制时使用(E, P, T, G, M, K, m),以1024进制时使用(Ei, Pi, Ti, Gi, Mi, Ki)

以前边的NFS存储事例来实现使用PVC来请求存储卷功能。

# 修改nfs的导出目录,导出3| V 5 # ^ 1 ~ K P个目录,相应的目录需要创建
k8s@node01:~$ cat /etc/expo- 2 4 G 0 ~ ! frts
/data/nfsV L * s H I ! # E/volume/v1  192.164 . -8.1~ K . 3 A 001.0/24(rw,sync,no_subtree_check,root_squash)
/data/nfs/volume/v2  192.168.101.0/G 8 % 1 124(rw,sync,no_subtree_check,root_squash)
/data/nfs/volume/v3H h u . u J m + &  192.168.101.0/24(rw,w & Y G t R 0 8sync,no_subtree_check,root_squash)
# 给予写权R G F ) v 5 2限
k8s@node01:~$ sudo chmod o+w -R /data/nfs/volume/
k8s@node01! h : ; J N k d:I R * t~$ sudo exportfs -_ f u | r P | Rrav
exporting 192.168.101.0/24:/dataD l 1 8 w } p #/nfs/volume/v3
exporting 192.168.101.0/24:/data/nfs/G P : C Q l ivolume/v2
exporting 192.168.101.0/24:/data/nfs/volume/v1
# 创建Ph ! B d Y 0 yV资源
k8s@node01:~/my_mK H ~ S #anifests/volumes$ cat pv-nfe B B | A g } :s.yaml
apiVersion:H L M Z H [ 0 v1
kinda 3 S k I u h: PersistentVolume
metadata:  # PV资源不设置namespaK c T I ce
nu x j l % 6 zame: pv001
labels:
name: pv001
speed: slow
spec:
nfs:
path: /db F { & * k Hata/nfs/volume/v1
server: node01.k8s.com# :  N H
accesN 8 ^ j SsModes: ["ReadWriteMany","ReadWc 7 mriteOnce"]
capacity:
storage: 1GiO | ) h c B 7
---
apiVersion: v1
kind: PersistentVolume
metadata:  # PV资源不设置namespace
name: pv002
labels:
name: pv002
speed: medium
spec:
n, J v jfs:
path: /data/nfs/volume/v2
server: n0 : ! W Aode01.k8s.com
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacityl R ? K K & V 6:
storage: 2Gi
---
apiVersioU f w . l cn: v1
kind: Persistent7 r ? O 2 L ?Volume
metadata:  # PV资源不设置namespace
name: pv003
labels:
name: pv003
speed: medium
spec:
nfs:
path: /data/nfs/volume/v3
server: node01.k8s.com
as 9 { w : O Q w /ccessModes: ["ReadWriteOnce"]
capacity:
storage: 3Gi
k8s@node01:~/my_mS o ` X tanifests/volumes$/ s l B * M Q s j kubectl apply -f pv-nfs.yaml
persistentvolume/pv001 created
persistentvolume/pv002 cH a J ` r &reated
persistentvolL E s ;ume/pv003 created
k8s@node01:~/, t x a ,my_manifests/volumes$ kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   10 # 1Gi        RWO,RWX        Retain           Available                                   4s
pv002   2Gi        RWO,RWX        R . t #etain           AvaY ~ e r 3 !ilable                                   4s
pv003   3Gi        RWO            Retain           Available                                   4s

创建一个pod,使用pvc来使用pv提供的存储卷,使用kubect9 z s y x / E # Sl explain pvc查看帮助信息

KIND:     PersistentVolumeCl  E / claim
VERSION:  v1
sr z : apec <Object>
accessModes <[]string>   是pv中定义的访[ , ~ ? $问模型的子集
resourcB 4 @ y Yes   <Object>  资源要求
requests    <map[string]string>  请求资源的大小要求
storge <string>! W # 5 / , m N  大小

编写配置清单,应用并测试

k8s@node01:~/my_manifests/vol2 [ o * G ] Qumes$ cat pvc-pod.yaml
apiVeL n G @ n ?rsion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-html
namespace: default
spec:
accessModes: ["ReadWriteMany"]
selector:
matchLabels:
speed: medium
resourceo Z Z R A Ps:
requests:
storage: 2Gi
---
apiVersion: v1
kind: Pod
met/ n ? |adata:
name: pod` ; =-volx z g 9-pvc
namespace: default
spec:
contb 2 ? p x - gaiy 9 i s Z Nners:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNot7 q m  : Q PPresent
volumeMounts:
- name: nginx-root
mountPath7 2 D , 6: /usr/share/nginx/html/
volumes:
- name: nginx-y - L I ` ; W Sroot
persistentVolumeClaim:
claimName: pvc-html
# 配置清单中的pvc资源中使用了标签选择器,pi ~ bv002和pv003满足条件,又使用了resout  p 6 r d J mrces来定义空间大小为2Gi,2 x z { j q [ - G最后挑选出的pv只有pv002
k8s@q 8 A ) Q $ G ] *node01:~/my_manifests/volumes$ kubectl apply -f pvc-pod.yaml
persistentvolumeclaim/pvc-html created
pod/pod-vol-pvc confl { o H rigured
k8s@nz ^ W B b c y x 1ode01:~/my_manifests/volumes$ kubectl get pvc
NA` 2 t M n SME       STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-C s _ g Q dhtml} 9 [ N V n J ` e   Bound    pv002    2Gi        RWO,RWX                       5s
# 连接到pod的容器中创建一个主页文件
k8s@node01:~/my_manifests/volumes$ kubectl get pods -o wide
NAME          REA- & IDY   STATUS    RESTAR2 T wTS   AGE   IP            NODE     NOMINATED NO{ & P 8 ~ N oDE   READINESS GATES
pod-vol-pvc   1/1     Running   0          10m   10.244.2.98   node03   <none>           <Y ! u q;b w 0 R J EnoF K . C * $ z vnS i * O 6e>
k8s@node01:~/my_U ~ * B ` Smanifests/volumes$ kubectl exec -it pod-vol-pvc -- /bin/sh
/ # echo ok > /usr/sharc s Ne/nginx/html/index.html
# 访问测试
k8s@node01:~/! ) p r J P @ ]my_manifests/volumes$ curl 10.244.2.98
ok
# 查看nfs服务器上的相应共享目录是否有文件
k8s@o G L B r 9 ! |node01:~$ cat /data/nfs/volume/v2/index.html
ok

当pvc删除后,之前分配给该pvc的pv就处于Released状态,该pv就不能分配给pvc了,此时需要C q _手动处理该pv,

k8s@node? ] u N R W01:~/myh Q ? c c M y $ ]_manifests/volx P fumes$ kubectl delete -Y l m z 4 V i w tf pvc-pod.yaml
persisu f U 8 1 [tentvolumeclaim "pL T ; 9 ) N I 6vc-html" deleted
pod "pod-vol-pvc" deleted
k8s@nor 8 fde01:~/my_manifest~ n 9s/volumes$ kubectl get pv
NAME    CAs # ` w M  L Q #PACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM              STORAGECLASS   REASON   AGE
pv001   1Gi        RWO,RWX        Retain           Available                                              152m
pv002Y J P ( 4   2Gi        RWO,RWX        Retain           ReleasedJ C n a V * ? 3    default/pvc-html                           152m
pv- { m | C E n003   3Gy x e J u z C r )i        RW K v : * % u BWO            Retain           Available                                              152m
k8s@node01:~/my_manifests/volumes$ kubectl edit pv pv| o ) Y u . D0020 9 .
# 删除spec.claimRef字段的所有键值
spec:
claimRef:
apiVersion: v1
kind: PersistentVolumeClaim
name: pvc-html
namespace: defaulT X s ( ?t
resourceVersion:+ K j + ^ "649874"
uid: 945c88fe o J h z :-9513-4b15-85 s 03bc-0edebc9) 4 7 *5ab53
# 保存退出后相应的pv状态即可恢复
k8s@node01:~/my_manifests/volumes$ kul O / 7 9 3 { u 5bectl get pv
NAME    CB I . o Y 1 R K ?APACITY   ACCESS MODES   RECLAIM POLICY   STATUSe J O z d M      CLAIM   STORAGEL I e F z ~ K YCLASS   REASON   AGE
pv001   1Gi        RWO,RWX        Retain           Available                                   155m
pv002   2Gi        RWO,RWX        Retain           Available                                   155m
pv003   3Gi        RWO            Retain           Available                                   155m

而在实际生产环境中,pvc申请的存储卷时并不会刚好有符合条件的pv存在,此pvc将不能够有相应的pv与之匹配。k8s在此种情况下引入了StorageClass抽象资源,把后端存储进行分类,pvc在申请存储卷时可以动态创建pv。

Secret和Cony 6 * x a l | JfigMap特殊存储卷

配置容器化应用的方式:

  1. 直接把配置文件打包到镜像

  2. { e B ) A 5 ; | &定义pod资源清单时传递args,以参数形式传递给程序

  3. 使用环境变量

    3.1 Cloud Native的应用程序可直接使用环境变量加载配` + A 1置
    3.2 通过entrypoint脚本预处理环境变量为配置文件的配置信息

    4. 存储卷

ConfigMap和Secret对象也是k8s中一种特殊的存储卷对象。

ConfigMap

ConfigMap是k8s中的] v J一等公民,它存放一个个“kev/v4 k g h y V ? K walue”形式的数据。

configmap可简写为cm,使用kubectl explain cm查看资源清单配置时的帮助信息。

命令创建ConfigMap对象
## 命令行直接Q S f 8 [ Y传递key和value值
k8s@node01:~$ kubectl create configmap nginx-port --from-literal=nginx_porn w ! 1 E ?t=8; - L ~ ^ % g0 --from-literal=server_name=test.k8s.com
configmap/nginx-port created
k8s@node01:~$ kubectl get ck 8 M E  @ U V tm
NAME         DATA   AGE
nginx-porp M b 3 T : w Rt   2      4s
# 查看详细信息的两种方式
k8sa y k@node01:~$ kubectl get cm nginx-port] ) g X h -o yaml
k8s@node01:~$ kubP r o [ S zectl describe cm nginx-port
## 使用本地文件当作数? C 7 R据创建configmap资源
k8sr F 0 . $ i@node01:~/cm$ cat www.conf
server {
server_name test.k8s.com;
listen 8/ U Q @ $ G0;
root /data/web/html/;
}
k8s@node01:0 D F~/cm$ kubectl create configmap nginx-www-conf --from-file=./R U q 1www.conf
configmap: a c/nginx-www-conf created
k8s@node01:~/cm$ kubectl get cm
NAME             DATA   AGE
nginx-port       2      5m8s
nginx-www-conf   1      5s
# 使用文件创建时,如果不给key的名称,那文件名当作key,文件内容当作value
Pod中使用env引用ConfigMap对象

ConfigMap对象创建好后,可以在pod中进行引用,kubectl explain pods.spec.containers.env查看 3 P ( P $ U相应的帮助信

KIND:     Pod
VERSION:  v1
FIELDS:
spec <Object>
containers <* - 2 m K _ B +;[]Object>
env < Y V a V * p;[]Object>
name@ { c Y b p    <string> -required-
valueFrO # } q y . com   <} Z z  b V | { {;Object>
configMapKeyRef <Object&P R - ugt;
name# 5 B S T X p . v    <string>  表示引用哪个config~ S x T |map资源
key <string> -requirh N f  H ed-  表示引用configt G M P A 0 =map资源中的key名称
optional    <boolean>  该key是否是可u r Z H选,true表示key必须定义
k8s@node01:~/cm$ kubectl get cm
NAME             DATA   AGE
nginx-port       2      62m
nginx-www-conf   1      57m
k8s@node01:~/cm$ kubectl describe cm nginx-port
Name:         nginx-port
Namespace:    defaulF Q U W 2 6 e ht
Labels:       <none>
AnnotR F D L N 7 sations:  <nonek b 6 k = n&gs 3 ]  Kt;
Data
====
nginx_port:
----
80
server_name:
----
test.k8s.c9 ( v dom
Events:  <none, V ; i o>
k8s@node01:~/my_manifests/volumes$ cat configmap-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-vw / A @ - a I p @ol-configmap
namespace:@ ? $ default
spec:
containers:
- name: myapp
image: ikubernete( G / ) = 0 zs/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
e` q g z R O / V xnv:
- name: NGINX_SERVER_POR[ | ` R C % ET
valueFrom:
configMapKe^ = Z , P n A +yRef:
name: nginx-port
key: nginx_port
- name: NGINX_SERVER_NAME
valueFrom:
configMapL s M ; | =KeyRef:
name: nginx-port
key: server_name
k8b L p Zs@node01:~/my_manife~ # 4 0sts/volumes$ kubects & B [ .l apply -f configmap-pod.yaml
pod/pod-vol-configmap created
k8s@node01:~/my_manifests/volumes$ kubectl get pods
NAME                READY   STATUS    RESTARTS   AGE
pod-vol-configm^ D Vap   1/1     Running   0          4s
k8s@nod! J j m I {e01:~/my_manifestQ / X 4 F w fse ^ / s N/volumes$ kubectl exec -it pod-! o B ^ w Nvol-configmap -- printenv
PG & W X P |ATH=/usr; = 6 e o/local/sbin:/usr/local/bin:b h s ) ) + u h/I I  T _ Rusr/sbin:/usr/biP j % En:/sbin:/bin
HOSTNAMt | ( !E=pod-vol& ) p-configmap
TERM- v s=xterm
NG_ I 6 | ,INX_SERVER_PORT=80   # 从configmap中获取的变量
NGINX_SERVER_NAME=test.k8s.com  # 从configmap中获取的变量
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNM y T e j | . @ ;ETES_PORT_443_TCP_PROTO=tc. o * ] K ^ t A Up
KUBERNETES_PORT_443_TCP_PORT=443
...

h 4 Z x意:以env方式引用ConfigMap对象中的变量只在pod启动时获取,如果pod运行后再edit ConfigMap资源,那pod的变量是不能进行更新的。

pod中以存储卷形式挂载ConfigMap对象
k8s@node01:~/my_manifests/volumes$ cat configmap-pod-2.yaml
apil j p ( = 0 + QVersion: v1
kind: Pod
metadata:
name: pod-vol-configmap-2
namespaY : m )ce: default
speE - - 7c:
containers:
- name: myapp
image: ikub^ 0 O I ? . - N /ernetes/myapp:v1
imagePullPolicy: IfNotPrec N 9 P f Usent
ports:
- name: http
containerPort: 80
vf # % q K c 3 JolumeMounts:
- name: ngiT $ F A } D ; ^nxconf
mouP L E V @ 1ntPath: /etc/nginx/conf.d/
rea; g 3 t % ZdOnly: true
volumes:
- name: nginxconf
configMap:
name: nginx-ww/ d S t C 5 S u Rw-conf
k8s@node01:~/my_manifests/volumes$ kubectl apply -f configmap-pod-2.yaml
pod/pod-vol-u 6 9 S 1 / @configmap-2 created
k8s@2 G H l node01:~/my_manifests/volumes$ kubectl get pods
NAME                  READY   STATUS    RESTARTS   AGE
pod-vol-configmap     1H % a ] J y 0 U/1     Running   0          17m
pod-vol-configmap-2   1/1     Running   0          6s
# configMap对象以存储卷的形式挂载在容器中
k8 #  s i 7 1 X8s@node01:~/my_manifests/volumes$ kubectl exec -X  1 V I = Nit pod-vol-c# J onfigmap-2 -- cat /etc/nginx/conf.d/www.conf
server {
server_name test.k8s.com;
listen 80;
rP + % . m |oot /data/web/html/;
}
# 修改configmap资源中的r F + 5数据
k8s@node01:~/my[ 2 u X v { s X g_manifests/volumes$ kubectl edit cm nginx-www- | C V B 4-conf
# 把
listen 80;
# 修改为
listen 8080;
# 保存退出
# 需要等一会,容器中挂载的卷内容也会被改变
k8s@node01:~/my_manifests/volumes$ kubectx s 4 { 7 L H * sl execk j p # H 9 -it pod-vol-configmap-2 -- cat /etc/nginx/conf.d/www.conf
server {
server_name test.k8s.com;
listen 8080;
root /data/weL ` i Vb/html/;
}

Secret

和ConfK S O l %igMap类似,N ? z但只是用于保存敏感数据。7 9 f k D

命令创6 g W a t h j建Secret资源
$ kubectl create secret --help
Available CommandU / b vs:
docker-registry Create a secret for use with a Docker registry 当使用私有仓库拉取镜像时保存认证| ) + n信息
gener$ ] & ; t R I 5ic         Create a secret from a local file, directory or literal value 其他类型的敏感数据都可以使用此类型
tls             Create a TLK A c F 4 U Y dS secret  服务需要使用证书认证时用于保存证书及key的信息
# 创建一个通用类型的secret对象
k8s@node01:~/my_manifests/volumes$ kubectl crea2 ~ d N x + ; E (te secret generic my` - 1 [ z z 0 8sql-password --from-literal=password=passwf J | Wd@123!
secret/mysql-paS A ; Yssword created
k8s@node01:~/my_manif) o ?ests/volumes$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-w Q a %token-ndclg   kubernetes.io/servic1 S ? . $e-account-token   3      7d
inB j u 8 ) Ogress-https         kubernetes.io/tls                     2      31h
mY # K  }ysql-password        Opaque                                1      11s
k8s@node01:~/my_manifests/volum; N z y b res$ kubectl get_ j H % s A K secret mysql-password -o yaml
apiVersion: v1
data:
password: c2 A 3 :GFzc3dkQDEyMyE=   # 通l v . G i 8过base64编码
kind: Secret
metadata:
creat% 3 iionTimestamp: "2020-07-29T09:31W t q E:59Z"
...
# 通过base64可解码,也只是在一定程序上i [ k :  R x B对敏感数据进行保护
k8s@node01:~/my_% N ` p M 8 2manifests/volumes$ echo cGFzc3dkQDEyMyE= | base64 -d
passwd@123!
pod中使用secret资源

secre ( w ; Ct资源同样9 $ Y % p可以使用env的% D Z i ; F方式注入到pod中

k8s@node01:~/my_manifests/volumes$ cat secret-pod.yaml
apiQ b K  `Version: v1
kind: Pod
metadata:
name: pod# - N O v y-vol-secret
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfN- N [ f !otPresenL e 3 ^ W K F [ zt
ports:
- name: http
containerPort: 80
env:
- name: MYSQL_ROOT_PASSWD
valueFrom:
secretKeyRef:
name: mysx O { {ql-password
key: password
k8s@node01:~/my_manifes[ ^  c 9ts/volumes$ kubectl apply -f secret-po^ t @ C }  )d.yaml
pod/pod` U N u Y-vol-secret created
k8s@node01:~/my_manifests/volumes$ kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
pod-vol-secret   1/1     Running   0          3s 5 n q * e 9 .
k8s@node01:~/my_manifes+ 3 1ts/volumes$ kubectl exec pod-v^ x q Lol-secret -- printenv) z d s 5 | ,
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bB ) , 1 A J d Tin:/a * ysbin:/bin
HOSTNAME=pod-v; / /ol-secret
MYSQL_ROOT_PASSWD=passwd@12X 2 Z . H B /3!  # 解码后的密码

同样也可以向ConfigMap一样使用卷的方式挂载在Pod中,这里就不举例了。