一、背景介绍
前面介绍的k8s中的pv存储卷与cm存储卷,k8s中还有2中特殊的存储卷:secret和downwardAPI。其作用分别是用来存放敏感信息和将pod中的信息暴漏给pod中运行的代码,这也是k8s中经常会用到的两个存储卷,下面就这两个存储卷展开详细说明。
二、Secret存储卷
尽管configMap资源也可以存放类似密码等敏感信息,但是它是将其存放在etcd中,这种持久化存储存在一定的安全隐患。所以在生还环境中,使用secret 卷用来给 Pod 传递例如密码等敏感信息。可以将 Secret 存储在 Kubernetes API 服务器上,然后以文件的形式挂载到 Pod 中,无需直接与 Kubernetes 耦合。 secret 卷由 tmpfs(基于 RAM 的文件系统)提供存储,因此它们永远不会被写入非易失性(持久化的)存储器。使用时需要注意以下几点:
- 使用前你必须在 Kubernetes API 中创建 Secret。
- Secret 总是以 readOnly 的模式挂载。
- 容器以 subPath 卷挂载方式使用 Secret 时,将无法接收 Secret 的更新。
1.Secret的类型
创建 Secret 时,你可以使用 Secret 资源的 type 字段,或者与其等价的 kubectl 命令行参数(如果有的话)为其设置类型。如果 type 值为空字符串,则被视为 Opaque 类型。
内置类型 | 用法 |
Opaque | 用户定义的任意数据 |
kubernetes.io/service-account-token | 服务账号令牌 |
kubernetes.io/dockercfg | ~/.dockercfg文件的序列化形式 |
kubernetes.io/dockerconfigjson | ~/.docker/config.json文件的序列化形式 |
kubernetes.io/basic-auth | 用于基本身份认证的凭据 |
kubernetes.io/ssh-auth | 用于 SSH 身份认证的凭据 |
kubernetes.io/tls | 用于 TLS 客户端或者服务器端的数据 |
bootstrap.kubernetes.io/token | 启动引导令牌数据 |
2.从私有仓库拉取镜像
假设从私有仓库上拉取arkling/nginx:test镜像,并将它创建为一个pod,由于没有提供私有仓库的凭证信息,所以pod无法正常创建
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: arkling/nginx:test
imagePullPolicy: Always
root@master1:~/yaml/chapter4# kubectl apply -f 12.yaml
pod/private-reg created
root@master1:~/yaml/chapter4# kubectl get pod
NAME READY STATUS RESTARTS AGE
private-reg 0/1 ImagePullBackOff 0 89s
root@master1:~/yaml/chapter4# kubectl describe pod private-reg
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 44s default-scheduler Successfully assigned default/private-reg to node2
Warning Failed 22s kubelet Failed to pull image "arkling/nginx:test": rpc error: code = Unknown desc = Error response from daemon: pull access denied for arkling/nginx, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
Warning Failed 22s kubelet Error: ErrImagePull
Normal BackOff 22s kubelet Back-off pulling image "arkling/nginx:test"
Warning Failed 22s kubelet Error: ImagePullBackOff
Normal Pulling 9s (x2 over 43s) kubelet Pulling image "arkling/nginx:test"
此时,先创建出secret资源,将私有仓库的认证信息写入该资源后,再在创建pod时引用
root@master1:~/yaml/chapter4# kubectl create secret docker-registry regcred \
> --docker-server=https://index.docker.io/v1/ \
> --docker-username=arkling \
> --docker-password=****** #私有仓库密码
secret/regcred created
root@master1:~/yaml/chapter4# kubectl get secrets
NAME TYPE DATA AGE
regcred kubernetes.io/dockerconfigjson 1 51s
root@master1:~/yaml/chapter4# kubectl describe secrets regcred
Name: regcred
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 122 bytes
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: arkling/nginx:test
imagePullPolicy: Always
imagePullSecrets:
- name: regcred
root@master1:~/yaml/chapter4# kubectl apply -f 13.yaml
pod/private-reg created
root@master1:~/yaml/chapter4# kubectl get pod
NAME READY STATUS RESTARTS AGE
private-reg 1/1 Running 0 41s
三、downwardAPI
downwardAPI 卷用于为应用提供 downward API 数据。 在这类卷中,所公开的数据以纯文本格式的只读文件形式存在。Downward API 允许容器在不使用 Kubernetes 客户端或 API 服务器的情况下获得自己或集群的信息。在 Kubernetes 中,有两种方式可以将 Pod 和容器字段呈现给运行中的容器:
- 环境变量
- 存储卷文件
这两种呈现 Pod 和容器字段的方式都称为 downward API。严格的说downward API并不算一种存储卷,他只是对pod中运行的容器或者应用提供了一种当前pod环境的反向引用。
当前物理节点配置为4c8g,通过命令可以看到
root@master1:~/yaml/chapter4# cat /proc/cpuinfo | grep processor
processor : 0
processor : 1
processor : 2
processor : 3
root@master1:~/yaml/chapter4# free -m
total used free shared buff/cache available
Mem: 7937 928 2853 2 4155 6699
Swap: 0 0 0
当我们对pod做了资源限制后,进入容器查看,发现容器只能看到物理节点的信息,并无法获取到pod中的信息,这就需要我们使用downwardAPI将pod中的信息暴漏给容器
apiVersion: v1
kind: Pod
metadata:
name: downloadapi-pod
spec:
containers:
- name: downloadapi-container
image: nginx:alpine
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "2Gi"
cpu: "1"
requests:
memory: "1000Mi"
cpu: "500m"
root@master1:~/yaml/chapter4# kubectl apply -f 14.yaml
pod/downloadapi-pod created
root@master1:~/yaml/chapter4# kubectl get pod
NAME READY STATUS RESTARTS AGE
downloadapi-pod 1/1 Running 0 8s
root@master1:~/yaml/chapter4# kubectl exec -it downloadapi-pod -- cat /proc/cpuinfo | grep processor
processor : 0
processor : 1
processor : 2
processor : 3
root@master1:~/yaml/chapter4# kubectl exec -it downloadapi-pod -- free -m
total used free shared buff/cache available
Mem: 7938 555 3724 2 3659 7073
Swap: 0 0 0
1.通过环境变量将 Pod 信息呈现给容器
示例中分别同时演示了用 Pod 字段(fieldRef)作为环境变量的值,和用容器字段(resourceFieldRef)作为环境变量的值,另外需要注意的是:通过这种方式呈现出来的值没有小数形式,如果将requests.cpu的500m值通过该方式展示,得到的结果为1(1000m等于1cpu)
apiVersion: v1
kind: Pod
metadata:
name: downloadapi-pod
spec:
containers:
- name: downloadapi-container
image: nginx:alpine
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "2Gi"
cpu: "1"
requests:
memory: "1000Mi"
cpu: "500m"
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: downloadapi-container
resource: limits.cpu
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: downloadapi-container
resource: limits.memory
divisor: 1Mi
root@master1:~/yaml/chapter4# kubectl apply -f 14.yaml
pod/downloadapi-pod created
root@master1:~/yaml/chapter4# kubectl get pod
NAME READY STATUS RESTARTS AGE
downloadapi-pod 1/1 Running 0 108s
root@master1:~/yaml/chapter4# kubectl exec -it downloadapi-pod -- printenv | grep MY_
MY_POD_IP=10.244.2.93
MY_CPU_LIMIT=1
MY_MEM_LIMIT=2048
MY_POD_NAME=downloadapi-pod
2.通过存储卷将 Pod 信息呈现给容器
通过该方式的呈现方法结合了环境变量呈现和存储卷挂载,并无其他额外说明,在此不做赘述
apiVersion: v1
kind: Pod
metadata:
name: downloadapi-pod
spec:
containers:
- name: downloadapi-container
image: nginx:alpine
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "2Gi"
cpu: "1"
requests:
memory: "1000Mi"
cpu: "500m"
volumeMounts:
- name: procinfo
mountPath: /etc/procinfo
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: procinfo
downwardAPI:
items:
- path: "cpuinfo"
resourceFieldRef:
containerName: downloadapi-container
resource: limits.cpu
- path: "meninfo"
resourceFieldRef:
containerName: downloadapi-container
resource: limits.memory
- name: podinfo
downwardAPI:
items:
- path: "MY_POD_NAME"
fieldRef:
fieldPath: metadata.name
root@master1:~/yaml/chapter4# kubectl apply -f 14.yaml
pod/downloadapi-pod created
root@master1:~/yaml/chapter4# kubectl get pod
NAME READY STATUS RESTARTS AGE
downloadapi-pod 1/1 Running 0 5s
root@master1:~/yaml/chapter4# kubectl exec -it downloadapi-pod -- ls /etc/podinfo
MY_POD_NAME
root@master1:~/yaml/chapter4# kubectl exec -it downloadapi-pod -- cat /etc/podinfo/MY_POD_NAME
downloadapi-podroot
root@master1:~/yaml/chapter4# kubectl exec -it downloadapi-pod -- ls -la /etc/procinfo
total 0
drwxrwxrwt 3 root root 120 Sep 17 02:24 .
drwxr-xr-x 1 root root 50 Sep 17 02:24 ..
drwxr-xr-x 2 root root 80 Sep 17 02:24 ..2023_09_17_02_24_16.3243841005
lrwxrwxrwx 1 root root 32 Sep 17 02:24 ..data -> ..2023_09_17_02_24_16.3243841005
lrwxrwxrwx 1 root root 14 Sep 17 02:24 cpuinfo -> ..data/cpuinfo
lrwxrwxrwx 1 root root 14 Sep 17 02:24 meninfo -> ..data/meninfo
root@master1:~/yaml/chapter4# kubectl exec -it downloadapi-pod -- cat /etc/procinfo/cpuinfo
1
root@master1:~/yaml/chapter4# kubectl exec -it downloadapi-pod -- cat /etc/procinfo/meninfo
2147483648