什么是volume?
volume
是pod中容器访问的数据目录。
如果我们仅在运行的Pod中修改数据内容,当Pod发生意外Down掉,控制器会重新启动一个新的Pod,那么文件将会被重载。如果是多副本Pod需要修改文件,我们也不可能花费大量时间一个一个去修改,这时衍生出
Volume
的概念
我们今天就先从一种特殊的Volume开始,这种特殊的 Volume,叫作 Projected Volume(投射数据卷),在阅读本篇之前建议先学习一下【 云原生 | kubernetes 】资源对象 - Pod的深度解析
Projected Volume
为什么是特殊的Volume呢,它们和普通的存储卷不一样,它们不是用来存储容器的数据,也不是用来进行容器和宿主机之间的数据交换(Docker Volume的作用)。这些特殊的Volume是为容器提供预先定义好的数据。
Projected Volume 是 Kubernetes v1.11 之后的新特性
目前,有以下四种类型的Projected Volume:
secret
configMap
downwardAPI
serviceAccountToken
secret
这种Volume主要是用来给Pod传递一些敏感信息,比如密码。把想要的数据加密存放,需要使用时挂在到Pod的容器下,来访问到Secret
保存的数据
示例
例子中定义了一个很简单的Pod,它挂在了一个特殊的Volume,这个Volume的数据来源是名为mysecret的secret对象。
1.创建Volume-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: nginx
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
2.创建Secret对象
1>通过kubectl create
[root@ycloud ~]# echo "ycloud" >> mysecret.txt
[root@ycloud ~]# kubectl create secret generic mysecret --from-file=./mysecret.txt
secret/mysecret created
2>yaml清单
---
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: eWNsb3VkCg==
可以看到,yaml清单中Secret对象只有一个,但data字段可以以Key-Value的格式白村对各数据。需要注意的是,Secret对象要求这些数据必须经过Base64转码,以免发生安全隐患。
[root@ycloud ~]# kubectl get secrets
NAME TYPE DATA AGE
mysecret Opaque 2 5m21s
[root@ycloud ~]# echo eWNsb3VkCg== | base64 -d ## -d base64解码
ycloud
转码不是被加密,如果要对数据进行加密操作,可以了解下secret的加密插件。
3.验证
现在我们创建刚才的Pod yaml文件
[root@ycloud ~]# kubectl apply -f Volume-test.yaml
pod/volume-test created
当Pod运行成功之后,我们验证下创建的Secret对象在不在容器里
[root@sztcyl-177-9-244 script]# kubectl get po
NAME READY STATUS RESTARTS AGE
volume-test 1/1 Running 0 5m21s
[root@sztcyl-177-9-244 script]# kubectl exec -it volume-test -- /bin/bash
root@volume-test:/# ls projected-volume/
username
root@volume-test:/# cat projected-volume/username
ycloud
configMap
这个Volume的作用和Secret类似,只不过Config不用对数据进行加密,一般用来存储一些配置文件。 引用 configMap 对象时,你可以在卷中通过它的名称来引用。可以自定义 ConfigMap 要使用的路径。
这里展示一个简单的案例,nginx通过配置test.conf文件,代理访问百度网址。
apiVersion: v1
kind: Pod
metadata:
name: configmap-test
spec:
containers:
- name: container-test
image: nginx
volumeMounts:
- name: all-in-one
mountPath: "/etc/nginx/conf.d"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- configMap:
name: myconfigmap
---
apiVersion: v1
kind: Config
metedata:
name: myconfigmap
data:
test.conf |
server {
listen 8080;
server_name ycloud;
location / {
proxy_pass http://112.80.248.76; ##baidu 地址
}
}
直接验证结果
[root@ycloud ~]# kubectl apply -f configmap-test.yaml
pod/configmap-test created
configmap/myconfigmap created
[root@ycloud ~]# kubectl get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
configmap-test 1/1 Running 0 2m14s 100.111.212.1 ycloud <none> <none>
[root@ycloud ~]# curl 100.111.212.1:8080 ##配置转发的8080端口
<!DOCTYPE html>
·······
<title>百度一下,你就知道</title>
·······
注意:
- 在使用
ConfigMap
之前你首先要创建它。- 容器以
subPath
卷挂载方式使用 ConfigMap 时,将无法接收 ConfigMap 的更新。- 文本数据挂载成文件时采用 UTF-8 字符编码。如果使用其他字符编码形式,可使用
binaryData
字段。- 修改好
ConfigMap
数据之后,Pod里的数据会热加载,无需重新启动,这点secret类似
kubelet有一个启动参数–sync-frequency,控制同步配置的时间间隔,默认值是1min,所以当更新configmap的内容后,真正容器中的挂载内容变化可能在0~1min之后。如果这个值修改的过少,可能会导致kubelet的资源消耗会上升。
downwardAPI
它的作用能直接获取Pod和容器的字段信息
简答案例
apiVersion: v1
kind: Pod
metadata:
name: downwardapi-test
spec:
containers:
- name: container-test
image: nginx
volumeMounts:
- name: all-in-one
mountPath: "/usr/share/nginx/html/"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- downwardAPI:
items:
- path: "aa.html"
fieldRef:
fieldPath: metadata.name
- path: "bb.html"
resourceFieldRef:
containerName: container-test
resource: limits.cpu
通过downwardapi对象获取Pod的.metadata.name
和.limits.cpu
信息
[root@ycloud ~]# kubectl apply -f bb.yaml
pod/downwardapi-test created
[root@ycloud ~]# kubectl get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
downwardapi-test 1/1 Running 0 2m7s 100.111.212.28 ycloud <none> <none>
[root@ycloud ~]# curl 100.111.212.28/aa.html
downwardapi-test
[root@ycloud ~]# curl 100.111.212.28/bb.html
4
验证查看返回的信息。
目前支持的字段
可通过 fieldRef
获得的信息
- spec.nodeName - 宿主机名字
- status.hostIP - 宿主机IP
- IPmetadata.name - Pod的名字
- metadata.namespace - Pod的
- Namespacestatus.podIP - Pod的IP
- spec.serviceAccountName - Pod的Service Account的名字
- metadata.uid - Pod的UIDmetadata.labels[‘’] - 指定的Label值
- metadata.annotations[‘’] - 指定的Annotation值
- metadata.labels - Pod的所有Label
- metadata.annotations - Pod的所有Annotation
可通过 resourceFieldRef
获得的信息
-
resource: limits.cpu - 容器的 CPU 限制值
-
resource: requests.cpu - 容器的 CPU 请求值
-
resource: limits.memory - 容器的内存限制值
-
resource: requests.memory - 容器的内存请求值
-
resource: limits.hugepages-* - 容器的巨页限制值
-
resource: requests.hugepages-* - 容器的巨页请求值
-
resource: limits.ephemeral-storage - 容器的临时存储的限制值
-
resource: requests.ephemeral-storage - 容器的临时存储的请求值
serviceAccountToken
我们后面讲解基于角色的权限控制RBAC时在详细讲解
参考文献
https://kubernetes.io/zh-cn/docs/concepts/storage/projected-volumes/
https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#secret