一、背景介绍

前面介绍的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