Volume在集群中也是一种资源,Pod通过挂载(Mount)的方式来使用一个或多个Volume。某些类型的Volume具有与Pod相同的生命周期,被称为“临时卷”。
emptyDIr
该类型的Volume在Pod被调度到Node时由Kubelet进行创建,在初始状态下是个空目录,被命名为“空目录”(Empty DIrectory)。它与Pod具有相同的生命周期,当Pod被销毁时,emptyDir对应的目录也会被删除。同一个Pod中的多个容器都可以挂载这种类型的Volume。
使用场景
- 基于磁盘进行合并排序操作时需要的暂存空间;
- 长时间计算任务的中间检查点文件;
- 为某个Web服务提供的临时网站内容文件。
- 同一个Pod中容器共享数据
使用内存提供存储服务
emptyDir可以通过medium字段设置存储介质为“Memory”,表示使用基于内存的文件系统。需要注意的是,在主机重启后,内存中存储的信息会被清空。写入内存的数据将被计入容器的内存使用量,受到容器级别内存资源上限(Memory Resource Limit)的限制。
示例
---
apiVersion: v1
kind: pod
metadata:
name: pod1
spec:
containers:
- image: busybox
name: test1
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
{/tabs-pane}
{tabs-pane label="示例2"}
#设置emptyDir使用内存
apiVersion: v1
kind: pod
……
volumes:
- name: cache-volume
emptyDir:
medium: "Memory"
{/tabs-pane}
{tabs-pane label="示例3"}
#设置emptyDir使用内存,并设置可使用的内存上限
#需要开启SizeMemoryBackedVolumes
apiVersion: v1
kind: pod
……
volumes:
- name: cache-volume
emptyDir:
medium: "Memory"
sizeLimit: 500Mi
{/tabs-pane}
Generic Ephemeral
Generic Ephemeral类型的Volume(通用临时卷)与emptyDir的功能相似,但更加灵活,有以下特性:
- 后端的存储既可以是本地磁盘,也可以是网络存储;
- 可以为Generic Ephemeral设置容量上限;
- 在Generic Ephemeral内可以有一些初始数据。
- 在驱动支持的情况下,Generic Ephemeral支持快照、克隆、调整大小、容量跟踪等标准的卷操作。
示例
---
apiVersion: v1
kind: pod
metadata:
name: my-app
spec:
containers:
- name: my-frontend
image: busybox
command: [ "sleep", "1000" ]
volumeMounts:
- mountPath: "/scratch"
name: scratch-volume
volumes:
- name: scratch-volume
ephemeral:
volumeClaimTemplate:
matedata:
labels:
type: my-frontend-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "scratch-storage-class"
resources:
requests:
storage: 1Gi
说明:
上面的示例中,Generic Ephemeral类型的Volume的参数设置需要从storageClass"scratch-storage-class"中申请1GiB的存储空间。
根据volumeClaimTemplate的配置,系统将自动创建一个对应的PVC,并确保在删除Pod时自动删除这个PVC。这个PVC会以Pod的名称和Volume的名称的组合为其命名,中间以“-”连接,本例中PVC的名称是“my-app-scratch-volume”。某些情况下,这种命名机制可能会引起冲突,在部署Pod时需要注意。
在安全方面,当用户有权限创建Pod的时候,Generic Ephemeral会隐式地创建一个PVC(即使用户没有创建PVC的权限),这可能不符合安全要求。
Kubernetes的一些内部资源对象也可以通过Volume的形式挂载为容器的目录或文件,包括configMap、Secret、Downward API等,这些类型的Volume也是临时卷,会随着Pod的销毁而被系统删除。
ConfigMap
ConfigMap主要保存应用所需的配置文件,并且通过Valume的形式挂载到容器内的文件系统中,以供容器内的应用读取。这样就可以做到配置文件与镜像的分离,使容器具有可移植性。
ConfigMap在使用之前需要先创建它,ConfigMap不能用来保存大量的数据,其中保存的数据不可以超过1MIB。
ConfigMap主要用来生成容器内的环境变量,设置容器启动命令的命令行参数(需要设置为环境变量),以Volume的形式挂载为容器内的文件或目录等。
由于ConfigMap受限于命名空间,所以要引用ConfigMap的Pod必须与ConfigMap处于相同的命名空间中才能被成功引用。
静态Pod因为不受master管理,无法引用ConfigMap。
创建ConfigMap的方式
ConfigMap中不存在spec字段,它通过data或binaryData字段定义配置数据。data字段用于保存经过utf-8编码的字符串,binaryData字段用于保存经过Base64编码的二进制数据。
ConfigMap中有个immutable字段,用于设置配置数据不可更改。即ConfigMap一旦创建成功后就不可修改。
设置这个字段可以防止意外更新ConfigMap对应用带来的异常影响,减少API Server监控ConfigMap的变化带来的性能损耗。
1.基于本地配置文件
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-appvare
data:
apploglevel: info
appdatadir: /var/data
#通过kubectl创建这个ConfigMap
kubectl apply -f cm-appvare.yaml
2.基于kubectl命令行
可以直接通过kubectl create configmap 命令创建ConfigMap,支持通过下面三种参数来指定不同类型的数据源创建ConfigMap。
- --from-file:基于指定的文件或目录创建ConfigMap
- --from-env-file:基于指定的env文件创建ConfigMap
- --from-literal:基于指定的键值对创建ConfigMap
--from-file
如果基于指定文件创建ConfigMap,默认情况下key的值会被设置为文件名,value的值会被设置为问几点内容。也可以通过命令行参数指定key名,不将文件名作为key名。
如果基于指定的目录创建ConfigMap,则目录下的每个文件都会被创建为data中的一个key:value键值对。
参数--from-file可以多次出现,用于在一个kubectl create命令行中将多个文件或目录创建到一个ConfigMap中。
用文件名作为key值时需要注意文件名要符合key的命名规范,否则命令将运行失败。名称中只能使用这些字符:[a-z] [A-Z] [0-9] - _ .
#在当前目录下存在server.xml文件,创建一个只包含该文件内容的ConfigMap
kubectl create configmap server-config --from-file=server.xml
#在当前目录下有个configs子目录,里面有两个配置文件,创建一个包含这两个配置文件内容的ConfigMap
kubectl create configmap app-config --from-file=./configs
#创建ConfigMap时指定key的名字为mykey
kubectl create configmap server-config --from-file=mykey=server.xml
#多次使用--from-file参数,创建一个包含多个配置文件内容的ConfigMap
kubectl create configmap app-config --from-file=server.xml --from-file=logging.properties
--from-env-file
--from-env-file同样支持多次使用该参数创建一个包含多个源配置文件的ConfigMap。
env文件包含一组环境变量的配置数据,其内容遵循如下语法规则:
- 每行文本都为VAR=VALUE的格式,等号两边不能有空格
- 忽略以“#”开头的注释行
- 忽略空行
对文本中的引号不做转义处理,即保留原始文本并将其作为value的值
#环境变量文件示例 cat log.properties level=FINE directory="${catalina.base}/logs" prefix=catalina. #通过kubectl create命令进行创建 kubectl create configmap log-env-config --from-env-file=log.properties
--from-literal
--from-literal可以多次使用从而生成多个ConfigMap的数据内容。使用该参数时只能直接从命令行输入键值对,适用于简单的环境变量或少量键值对。该参数生成的ConfigMap无法动态更新。
kubectl create configmap appenv --from-literal=loglevel=info --from-literal=appdatadir=/var/data
在Pod中使用ConfigMap
容器应用通过以下两种方式使用ConfigMap
- 将ConfigMap中的内容设置为容器的环境变量
- 通过volume将ConfigMap中的内容挂载为容器内的文件或目录
cat cm-appvars
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-appvars
data:
apploglevel: info
appdatadir: /var/data
{/tabs-pane}
{tabs-pane label="挂载示例1"}
apiVersion: v1
kind: Pod
metadata:
name: cm-test-pod
spec:
containers:
- name: cm-test
image: busybox
command: [ "/bin/sh", "-c", "env | grep APP" ]
env:
- name: APPLOGLEVEL #定义环境变量的名称
valueFrom: #key"APPLOGLEVEL"对应的值
configMapKeyRef:
name: cm-appvars #环境变量的值取自cm-appvars
key: apploglevel #key为apploglevel
- name: APPDATADIR #定义环境变量的名称
valueFrom: #key"APPDATADIR"对应的值
configMapKeyRef:
name: cm-appvars #环境变量的值取自cm-appvars
key: appdatadir #key为appdatadir
restartPolicy: Never
kubectl create -f cm-test-pod.yaml
kubectl logs cm-test-pod
APPDATADIR=/var/data
APPLOGLEVEL=info
{/tabs-pane}
{tabs-pane label="挂载示例2"}
---
apiVersion: v1
kind: Pod
metadata:
name: cm-test-pod
spec:
containers:
- name: cm-test
image: busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: cm-appvars
restartPolicy: Never
kubectl apply -f cm-test-pod2.yaml
kubectl logs cm-test-pod2
apploglevel=info
appdatadir=/var/data
{/tabs-pane}
示例2中通过envFrom字段,实现了在Pod环境下将ConfigMap中的所有key:value键值对都自动生成环境变量。
环境变量的命名受POSIX命名规范约束(a-zA-Z_*),不能以数字开头。如果包含非法字符,则系统将挑过该环境变量的创建,并记录一个Event来提示环境变量无法生成,但并不阻止Pod的启动。
通过Volume将ConfigMap中的内容挂载为容器内的文件或目录
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-appconfigfiles
data:
key-serverxml: |
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
……
……
</Service>
</Server>
key-loggingproperties: "handlers
= 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler,
……
……
= 4host-manager.org.apache.juli.FileHandler\r\n\r\n"
{/tabs-pane}
{tabs-pane label="示例1"}
---
apiVersion: v1
kind: Pod
metadata:
name: cm-test-app
spec:
containers:
- name: cm-test-app
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
volumeMounts:
- name: serverxml #引用Volume的名称
mountPath: /configfiles #挂载到容器内该目录下
volumes:
- name: serverxml #定义Volume的名称
configMap:
name: cm-appconfigfiles #指定ConfigMap的名称
items:
- key: key-serverxml #ConfigMap中key的名称
path: server.xml #key对应的值(value)将以server.xml文件名挂载
- key: key-loggingproperties #ConfigMap中key的名称
path: logging.properties #key对应的值(value)将以logging.properties文件名挂载到容器内
kubectl exec -it cm-test-app --bash
ls /configfiles
sserver.xml logging.properties
{/tabs-pane}
{tabs-pane label="示例2"}
#如果在引用ConfigMap时不指定items,则通过volumeMount方式在容器内的目录下为每个item都生成一个名为“key”的文件,文件的内容为key的值。
---
apiVersion: v1
kind: Pod
metadata:
name: cm-test-app
spec:
containers:
- name: cm-test-app
image: kubeguide/tomcat-app:v1
imagePullPolicy: Never
ports:
- containerPort: 8080
volumeMounts:
- name: serverxml #引用Volume的名称
mountPath: /configfiles #挂载到容器的该目录下
volumes:
- name: serverxml #定义Volume的名称
configMap:
name: cm-appconfigfiles #使用ConfigMap“cm-appconfigfiles”
kubectl exec -it cm-test-app --bash
ls /configfiles
key-loggingproperties key-serverxml
{/tabs-pane}
ConfigMap可选设置
在Pod的定义中,可以将对ConfigMap的引用设置为是否可选(optional),若设置为可选(optional=true),则表示如果ConfigMap不存在,或者引用的数据项在ConfigMap中不存在,那么目标数据将被设置为空值。当ConfigMap被设置为Volume存储卷时,表示当ConfigMap不存在时,目标挂载的文件内容是空的。
---
apiVersion: v1
kind: Pod
metadata:
name: cm-test-pod-cm-env-optional
spec:
containers:
- name: cm-test
image: busybox
command: [ "/bin/sh", "-c", "env | grep APP" ]
env:
- name: APPLOGLEVEL
valueFrom:
configMapKeyRef:
name: cm-appvars
key: apploglevel
optional: true #设置为可选
- name: APPDATADIR
valueFrom:
configMapKeyRef:
name: cm-appvars
key: appdatadir
optional: true #设置为可选
restartPolicy: Never
kubec logs cm-test-pod-cm-env-optional
[结果为空]
{/tabs-pane}
{tabs-pane label="示例2"}
---
apiVersion: v1
kind: Pod
metadata:
name: cm-test-app-cm-volume-optional
spec:
containers:
- name: tomcat
image: busybox
command: [ "/bin/sh", "-c", "tail -f /dev/null" ]
volumeMounts:
- name: serverxml
mountPath: /configfiles
volumes:
- name: serverxml
configMap:
name: cm-appconfigfiles
optional: true
kubectl exec -it cm-test-app-cm-volume-optional --bash
ls /configfiles
[结果为空]
{/tabs-pane}
Secret
Secret专门用于保存机密数据。在设置Secret.data字段时,所有键值都必须是经过base64编码的字符串。
Secret主要用来为容器配置环境变量,挂载配置文件/目录到容器。此外,由Kubelet为Pod拉取镜像时,在需要登录仓库的时候使用。
Downward API
通过Downward API 可以将Pod或者Container的某些元数据信息(如Pod名称、Pod IP、Node Ip、Label、Annotation、容器资源限制等)以文件的形式挂载到容器内,以供容器内的应用使用。
Downward API可以通过两种方式将Pod和容器的元数据信息注入到容器内。
- 环境变量方式:将Pod或container的配置信息设置为容器内的环境变量
Volume挂载方式:将Pod或container的配置信息以文件的形式挂载到容器内
Downward API支持设置的Pod和Container信息
可以通过fieldRef设置的字段
字段名 | 说明 |
---|---|
metadata.name | Pod名称 |
metadata.namespace | Pod所在名称空间的名称 |
metadata.uid | Pod的UID |
metadata.labels[' | Pod的某个Label的值,通过 |
metadata.annotations[' | Pod某个Annotation的值,通过 |
Pod的以下元数据信息可以被设置为容器内的环境变量,但在设置downwardAPI为存储卷类型时不能再设置filedRef字段的内容
字段名 | 说明 |
---|---|
spec.serviceAccountName | Pod使用的ServiceAccount名称 |
spec.nodeName | Pod所在的Node的名称 |
status.hostIP | Pod所在Node的IP地址 |
status.hostIPs | Pod所在Node的IPv4和IPv5双栈地址 |
status.podIP | Pod的IP地址 |
status.podIPs | Pod的IPv4和IPv5双栈地址 |
在设置downwardAPI为存储卷类型时,可以在其fieldRef字段设置以下信息,但不能通过环境变量的方式设置。
- mmetadata.lables:Pod的Label列表,每个Lable都以key为文件名,value为文件的内容,每个Label各占一行
- metadata.annotation:Pod的Annotation列表,每个Annotation都以key为文件名,value为文件的内容,每个Annotation各占一行
可以通过resourceFieldRef设置的字段
字段名 | 说明 |
---|---|
limits.cpu | Container级别的CPU Limit |
requests.cpu | Container级别的CPU Request |
limits.memory | Container级别的Memory Limit |
requests.memory | Container级别的Memory Request |
limits.hugepages-* | Container级别的HugePage(巨页)Limit |
requests.hugepages-* | Container级别的HugePage(巨页)Request |
limits.ephemeral-storage | Container级别的临时存储空间Limit |
requests.ephemeral-storage | Container级别的临时存储空间Request |
Projected Volume
Projected Volume是一种特殊的Volume类型,用于将一个或多个资源对象(ConfigMap、Secret、Downward API)一次性挂载到容器内的同一个目录下。
常见应用场景
- 通过Pod的标签生成不同的配置文件,需要使用配置文件及用户名和密码时,需要使用3种资源:ConfigMap、Secret、Downward API。
- 在自动化运维应用中使用配置文件和帐号信息时,需要使用ConfigMap、Secret。
- 在配置文件中使用Pod名称(metadata.name)记录日志时,需要使用ConfigMap、Downward API。
- 使用某个Secret对Pod所在的命名空间(metadata.namespace)进行加密时,需要使用Secret、Downward API。
Project Volume在Pod的Volume定义中类型为projected,通过sources字段来设置一个或多个的ConfigMap、Secret、Downward API、Service Account Token等资源。各种类型的资源配置内容与单独设置为Volume时基本一致,需要注意以下两个不同点:
- 对于Secret类型的Volume,字段名“secretName”在projected.sources.secret中被改为“name”;
- Volume的挂载模式“defaultMode”只可以设置为projected级别。对于各子项,仍然可以设置各自的挂载模式,使用的字段名为“mode”。
评论 (0)