Kubernetes之十五----configMap和secre特色存储卷详解

2022/6/15 23:21:11

本文主要是介绍Kubernetes之十五----configMap和secre特色存储卷详解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1、本章简介

ConfigMap 和 Secret 是 Kubernetes 系统上两种特殊类型的存储卷, ConfigMap 对象用 于为容器中的应用提供配置数据以定制程序的行为,不过敏感的配置信息,例如密钥、证书 等通常由 Secret 对象来进行配置。 它们将相应的配置信息保存于对象中,而后在 Pod 资源 上以存储卷的形式将其挂载并获取相关的配置,以实现配置与镜像文件的解捐。 本章将主要讲解 ConfigMap与Secret 存储卷的用法。

 

2、configMap介绍

        ConfigMap用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件。ConfigMap跟secret很类似,但它可以更方便地处理不包含敏感信息的字符串。

       作为分布式系统的 Kubernetes 也提供了统一配置管理方案一一ConfigMap。 Kubemetes 基于 ConfigMap 对象实现了将配置文件从容器镜像中解祠,从而增强了容器应用的可移植 性。 简单来说,一个 ConfigMap 对象就是一系列配置数据的集合,这些数据可“注入”到 Pod 对象中,并为容器应用所使用;注入方式有挂载为存储卷和传递为环境变量两种。

        ConfigMap 对象将配置数据以键值对的形式进行存储,这些数据可以在 Pod 对象中使 用或者为系统组件提供配置,例如控制器对象等。 不过,无论应用程序如何使用 ConfigMap 对象中的数据,用户都完全可以通过在不同的环境中创建名称相同但内容不同的 ConfigMap 对象,从而为不同环境中同一功能的 Pod 资源提供不同的配置信息,实现应用与配置的灵活句兑。

 

3、创建ConfigMap对象和Pod环境变量并传递键值数据

3.1 通过命令进行创建configMap对象

        Kubernetes 的不少资源既可以使用 kubectl create命令创建, 也可以使用清单创建, 例如 前面讲到的 namespaceo ConfigMap 是另-个两种创建方式都比较常用的资源。 而且,通过 使用“ kubectl create configmap”命令,用户可以根据目录、文件或直接值创建 ConfigMap 对象。 命令的语法格式如下所示 :

kubectl create conf igrnap <map-name> <data-source> 

        其中,<map-name>即为 ConfigMap 对象的名称,而 <data-source>是数据源,它可以 通过直接值、文件或目录来获取。 无论是哪一种数据源供给方式,它都要转换为 ConfigMap 对象中的 Key-Value 数据,其中 Key 由用户在命令行给出或是文件数据源的文件名 ,它仅能 由字母、数字、连接号和点号组成,而 Value 则是直接值或文件数据源的内容。

为“ kubectl create  configmap,命令使用"--from-literal" 选项可在命令行直接给出键值对来创建 ConfigMap 对象,重复使用此选项则可以传递多个键值对。 命令格式如下:

创建一个名称空间为config以示区别和configmap

  • --from-literal=redis_host="redis.default.svc.cluster.local" 创建一个redis_hsot的名称为redis.default.svc.cluster.local

  • --from-literal=log_level="Info"                                       创建日志级别

[root@master ~]# kubectl create ns config        # 创建一个名称空间为config,以示区别
namespace/config created
[root@master ~]# kubectl create configmap filebeat-cfg -n config --from-literal=redis_host="redis.default.svc.cluster.local" --from-literal=log_level="Info" # 创建configmap,指定redis_host名称和日志级别
configmap/filebeat-cfg created


[root@master ~]# kubectl get cm -n config        # 查看创建的configmap信息,在config名称空间下
NAME           DATA   AGE
filebeat-cfg   2      51s

[root@master ~]# kubectl get cm -n config  -o yaml   # 查看configmap详细信息
apiVersion: v1
items:
- apiVersion: v1
  data:
    log_level: Info                             # 日志级别
    redis_host: redis.default.svc.cluster.local  # redis_host名称
  kind: ConfigMap
  metadata:
    creationTimestamp: "2020-08-04T01:40:14Z"
    name: filebeat-cfg
    namespace: config
    resourceVersion: "168207"
    selfLink: /api/v1/namespaces/config/configmaps/filebeat-cfg
    uid: 2d4517ac-6442-483d-a8d6-60d797fd2a1b
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

注意:此类方式提供的数据量有限, 一般是在仅通过有限的几个数据项即可为Pod资源提供足够的配置信息时使用。

  

3.2 定义Pod 环境变量并传递ConfigMap对象键值数据

3.2.1 查看yaml文件帮助

查看kuberbetes帮助文档,然后再创建yaml配置文件

[root@master configmap]# kubectl explain pods.spec.containers               # 可以查看帮助里边的env变量信息
   env	<[]Object>
     List of environment variables to set in the container. Cannot be updated.
     
[root@master configmap]# kubectl explain pods.spec.containers.env.valueFrom  # 然后再env环境变量下也可以引用
KIND:     Pod
VERSION:  v1

RESOURCE: valueFrom <Object>

DESCRIPTION:
     Source for the environment variable's value. Cannot be used if value is not
     empty.

     EnvVarSource represents a source for the value of an EnvVar.

FIELDS:
   configMapKeyRef	<Object>                              # 引用此变量
     Selects a key of a ConfigMap.

   fieldRef	<Object>
     Selects a field of the pod: supports metadata.name, metadata.namespace,
     metadata.labels, metadata.annotations, spec.nodeName,
     spec.serviceAccountName, status.hostIP, status.podIP.

   resourceFieldRef	<Object>
     Selects a resource of the container: only resources limits and requests
     (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu,
     requests.memory and requests.ephemeral-storage) are currently supported.

   secretKeyRef	<Object>                                    # 引用此变量
     Selects a key of a secret in the pod's namespace
[root@master configmap]# kubectl explain pods.spec.containers.env.valueFrom.configMapKeyRef # 下面更详细的引用
KIND:     Pod
VERSION:  v1

RESOURCE: configMapKeyRef <Object>

DESCRIPTION:
     Selects a key of a ConfigMap.

     Selects a key from a ConfigMap.

FIELDS:
   key	<string> -required-                                    # 引用文件的键
     The key to select.

   name	<string>                                               # 应用文件的名称
     Name of the referent. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

   optional	<boolean>
     Specify whether the ConfigMap or its key must be defined

 

3.2.2 向Pod 环境变量传递ConfigMap对象键值数据

        Pod 资源的环境变量值的获得方式之一包括引用 ConfigMap 对 象中的数据,这一点通过在 env 字段中为 valueFrom 内configMapKeyRef对象即可实现, 其使用格式如下 :

        其中, 字段 name 的值为要引用的 ConfigMap 对象的名称字段 key 可用于指定要引用 ConfigMap 对象中某键的键名。 此类环境变量的使用方式与直接定义的环境变量并无区别,它们可被用于容器的启动脚本或直接传递给容器应用等。 

1、创建yaml文件

[root@master ~]# mkdir configmap
[root@master ~]# cd configmap/
[root@master configmap]# cat pod-cfg.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-cfg-demo
  namespace: config
spec:
  containers:
  - name: filebeat
    image: ikubernetes/filebeat:5.6.5-alpine
    env:
    - name: REDIS_HOST        # 定义镜像中redis_host的环境变量名称要大写
      valueFrom:              # 用来给REDIS_HOST来传值的
        configMapKeyRef:
          name: filebeat-cfg  # 引用上面创建好的configMap的值
          key: redis_host     # 引用上面创建到redis_host的键(创建configMap时的值)
    - name: LOG_LEVEL         # 定义log_level日志级别的环境变量时要大写
      valueFrom:
        configMapKeyRef:
          name: filebeat-cfg  # 也是引用上面的值,与REDIS_HOST值类似
          key: log_level      # configMap资源中的键

注意:创建引用了 ConfigMap 资源的 Pod 对象时 , 被引用的资源必须事先存在, 否则将无 法启动相应的容器,直到被依赖的资源创建完成为止。不过, 那些未引 用不存在的 ConfigMap 资源的容器将不受 此 影 响 。另外 , ConfigMap 是名称空 间 级别的资源, 它必须与引用它的 Pod 资源在同 一 空间 中 。

 

2、执行yaml文件并创建pod,查看验证结果

[root@master configmap]# kubectl apply -f pod-cfg.yaml   # 创建变量名并引用
pod/pod-cfg-demo created 
[root@master configmap]# kubectl get pods -n config  # 查看此时的pod已经运行
NAME           READY   STATUS    RESTARTS   AGE
pod-cfg-demo   1/1     Running   0          40s

 

3、查看此时的环境变量信息

[root@master configmap]# kubectl exec -it pod-cfg-demo  -n config  -- /bin/sh  # 进入pod中查看此时的环境变量
/ # printenv 
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
LOG_LEVEL=Info                                          # 日志级别是Info
HOSTNAME=pod-cfg-demo
SHLVL=1
HOME=/root
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
REDIS_HOST=redis.default.svc.cluster.local               # 引用的环境变量
FILEBEAT_VERSION=5.6.5

  

4、此时修改configmap里边的环境变量值,虽然用命令查看此时的环境变量被修改了,实际在pod环境变量并没有被修改。

[root@master ~]# kubectl edit cm filebeat-cfg  -n config 
apiVersion: v1
data:
  log_level: Notice                                               # 将Info改为Notice
  redis_host: redis.default.svc.cluster.local

[root@master ~]# kubectl get cm filebeat-cfg  -n config -o yaml  # 用命令查看此时的环境变量已经被修改
apiVersion: v1
data:
  log_level: Notice                                             # 此时修改完环境变量,并查看此时的环境变量已经被修改
  redis_host: redis.default.svc.cluster.local

  

5、查看pod的环境变量信息未被修改

[root@master configmap]# kubectl exec -it pod-cfg-demo  -n config  -- /bin/sh
/ # printenv                             # 再次查看环境变量
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
LOG_LEVEL=Info              # 但是在pod中查看此时的日志级别还是未修改的

 

4、ConfigMap 存储卷

 存储卷原理:若ConfigMap 对象中的键值来源于较长的文件内容,那么使用环境变量将其导人会使 得变量值占据过多的内存空间而且不易处理。 此类数据通常用于为容器应用提供配置文件, 因此将其内容直接作为文件进行引用方为较好的选择。 其实现方式是,在定义 Pod 资源时, 将此类 ConfigMap 对象配置为 ConfigMap 类型的存储卷,而后由容器将其挂载至特定的挂 载点后直接进行访问。

 

1、定义两个configMap文件

为“ kubectl create configmap ,命令使用“--from-file” 选项即可基于文件内容来创建ConfigMap对象, 它的命令格式如下。 可以重复多次使用"--from-file"选项传递多个文件内容:

kubectl create configmap <co口figmap_name> --from-file工<path-to-file>

  

1、创建访问页面路径

[root@master configmap]# cat server.conf                   # 定义访问页面路径
server {
    	server_name www.peng.com;
    	listen 80;
    	location / {
           root "/usr/share/nginx/html";
    	}
}

[root@master configmap]# cp server.conf server1.conf
[root@master configmap]# cat server1.conf 
server {
    	server_name www.ilinux.io;
    	listen 80;
    	location / {
    	    root "/html/ilinux";
    	}
}

 

2、通过访问页面文件创建configMap,并验证信息

  •  --from-file=./server.conf          指定的是相对路径的文件名称
  • --from-file=server-second.conf=./server1.conf     定义第二个文件的名称信息为server-second.conf
[root@master configmap]# kubectl create configmap nginx-cfg --from-file=./server.conf  --from-file=server-second.conf=./server1.conf  -n config    # 其中server-second.conf是自定义创建的文件名 
configmap/nginx-cfg created    

[root@master configmap]# kubectl get cm -n config  # 查看此时创建好的configmap信息
NAME           DATA   AGE
filebeat-cfg   2      72m
nginx-cfg      2      30s
[root@master configmap]# kubectl get cm  nginx-cfg -n config -o yaml
apiVersion: v1
data:
  server.conf: "server {\n    \tserver_name www.peng.com;\n   \tlisten 80; \tlocation 
  / {\n    \t\t  \  root \"/usr/share/nginx/html\";\n    \t}\n}\n"  # 查看此时创建的myserver.conf配置文件
  server-second.conf: "server {\n    \tserver_name www.ilinux.io;\n   \tlisten 80;  \tlocation 
  / {\n    \t\t   root \"/html/ilinux\";\n    \t}\n}\n"             # 查看此时创建的第二个配置文件
kind: ConfigMap
metadata:
  creationTimestamp: "2020-08-04T02:52:22Z"
  name: nginx-cfg           # configmap名称
  namespace: config
  resourceVersion: "175017"
  selfLink: /api/v1/namespaces/config/configmaps/nginx-cfg
  uid: c67ad90a-e873-477e-b76f-8b1e6dbe406b

  

2、挂载整个存储卷

       关联为 Pod 资源的存储卷时, ConfigMap 对象中的每个键都对应地表现为一个文件, 键名转为文件名而键值则为相应文件的内容即便是通过直接值创建的键值数据,也一样表现为文件视图。 挂载于容器上之后, 由键值数据表现出的文件位于挂载点目录中,容器中 的进程可直接读取这些文件的内容。 配置Pod 资源时, 基于存储卷的方式引用 ConfigMap 对象的方法非常简单,仅需要指 明存储卷名称及要引用的 ConfigMap 对象名称即可。 下面是于配置文件 myapp-pod.yaml 中定义的 Pod 资源,创建的 ConfigMap 对象 nginx-cfg,容器myapp将其挂载至应用程序 Nginx 加载配置文件模块的目录/etc/ nginx/conf.d 中, 具体如下 :

 

1、定义一个myapp-pod.yaml文件,将configmap中的nginx-cfg挂载只应用容器中

[root@master configmap]# cat myapp-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  namespace: config
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: config                # 指定挂载的存储卷的名称,与volumes上的名称一致
      mountPath: /etc/nginx/conf.d/
  volumes:
  - name: config                 # 存储卷名称
    configMap:
      name: nginx-cfg            # 与前面创建的configmap的nginx-cfg进行关联
      items:                     # 引用哪个键
      - key: server.conf         # 指定配置文件必须是相对路径才能被调用
        path: server-first.conf 
      - key: server-second.conf  # key值为上面创建的configmap对应的值
        path: server-second.conf  # path路径对应的是configmap对应的配置文件

configMap 存储卷的 items 字段的值是一个对象列表,可嵌套使用的字段有三个,具体 如下。

key <string>: 要引用的键名称,必选字段。 

path<string>: 对应的键于挂载点目录中生成的文件的相对路径,可以不同于键名称, 必选字段。

mode <integer> : 文件的权限模型,可用范围为 0 到 0777。

上面的配置示例中, server.-firstconf 映射成了server.conf 文件,而 server-second.conf则保持了与键名同名,并明确指定使用 0644 的权限,从而达成了仅装载部分 文件至容器之目的。

 

2、创建yaml文件,并查看效果

[root@master configmap]# kubectl apply -f myapp-pod.yaml 
pod/myapp-pod created

[root@master configmap]# kubectl get pods -n config
NAME           READY   STATUS    RESTARTS   AGE
nginx-pod      1/1     Running   0          12m                    # 此时查看到新的pod已经创建成功
pod-cfg-demo   1/1     Running   1          7h2m

[root@master configmap]# kubectl describe pods nginx-pod -n config  # 查看此时的pod运行状态信息,已经是运行状态
.............中间省略了
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned config/nginx-pod to node2
  Normal  Pulled     13m        kubelet, node2     Container image "nginx:1.14.1-alpine" already present on machine
  Normal  Created    13m        kubelet, node2     Created container myapp
  Normal  Started    13m        kubelet, node2     Started container myapp

 

3、进入到容器内部查看此时的配置文件是否存在,和监听的端口是否打开

[root@master configmap]# kubectl  exec -it nginx-pod  -n config  -- /bin/sh  # 连接到nginx-pod容器中,查看此时nginx的配置文件信息
/ # cd /etc/nginx/conf.d  # 切换到访问页面下
/etc/nginx/conf.d # ls    # 此时可以看到有两个配置文件信息
server-first.conf   server-second.conf
/etc/nginx/conf.d # cat server-first.conf   # 查看此时的配置文件信息
server {
    	server_name www.peng.com;
  	listen 80;
    	location / {
              root "/html/peng";
    	}
}
/etc/nginx/conf.d # cat server-second.conf   # 查看此时的配置文件信息
server {
    	server_name www.ilinux.io;
	listen 80;
    	location / {
    	      root "/html/ilinux";
    	}
}
/etc/nginx/conf.d # netstat -nl              # 查看此时的端口号80也已经被监听
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN  

  

4、如果想要修改监听的端口号怎么办?我们只需要修改nginx-cfg资源里的信息,而不能修改配置文件,因为你已经创建好了pod的容器

[root@master configmap]# kubectl edit cm nginx-cfg -n config   # 修改nginx-cfg的配置信息即可
.......此处省略无关信息
apiVersion: v1
data:
  server-second.conf: "server {\n    \tserver_name www.ilinux.io;\n\tlisten 80;\n
    \   \tlocation / {\n    \t      root \"/html/ilinux\";\n    \t}\n}\n"
  server.conf: "server {\n    \tserver_name www.peng.com;\n  \tlisten 8080;\n    \tlocation               # 将server.conf中80改为8080即可
    / {\n              root \"/html/peng\";\n    \t}\n}\n"

  

5、此时可以看到修改后的端口监听状态已经成为8080,并创建两个访问页面进行测试,如果端口没有监听,就需要手动重新加载

[root@master configmap]# kubectl edit cm nginx-cfg -n config   # 修改nginx-cfg的配置信息即可
}/etc/nginx/conf.d # cat server-first.conf 
server {
    	server_name www.peng.com;
  	listen 8080;
    	location / {
              root "/html/peng";
    	}
}
/etc/nginx/conf.d # netstat -nlt          # 查看此时的端口号是否正常
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      
/etc/nginx/conf.d # nginx -s reload       # 如果没监听成功,我们就需要手动重新进行加载
2020/08/04 09:30:35 [notice] 26#26: signal process started
/etc/nginx/conf.d # netstat -nlt          # 查看此时的端口号已经被重新加载成功为8080端口
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN 
/etc/nginx/conf.d # mkdir /html/peng -p                           # 创建访问页面目录
/etc/nginx/conf.d # mkdir /html/ilinux -p                        # 创建访问页面目录
/etc/nginx/conf.d # echo welcome to shanghai > /html/peng/index.html  # 创建访问页面
/etc/nginx/conf.d # echo welcome to shanghai-1 > /html/ilinux/index.html # 创建访问页面
/etc/nginx/conf.d # exit

  

6、查看pod的IP地址,并写入到hosts文件中,进行域名解析并访问

[root@master configmap]# kubectl get pods -o wide -n config  # 查看此时创建的pod  IP地址
NAME           READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
nginx-pod      1/1     Running   1          3h55m   10.244.2.70   node2   <none>           <none>
pod-cfg-demo   1/1     Running   2          10h     10.244.2.71   node2   <none>           <none>

[root@master configmap]# cat /etc/hosts   # 进行域名解析
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.7.101 master
192.168.7.102 node1
192.168.7.103 node2
192.168.7.104 nfs
10.244.2.70 www.peng.com                  # 在master节点上进行域名解析
10.244.2.70 www.ilinux.io                 # 在master节点上进行域名解析

[root@master configmap]# curl www.peng.com        # 访问网页
welcome to shanghai-1
[root@master configmap]# curl www.ilinux.io:8080  # 访问网页
welcome to shanghai

  

 5、Secret 资源

Secret资源的功能类似于ConfigMap,但它专用于存放敏感数据,例如密码、数字证书、私钥、令牌和SSH key 等。

 

1、Secret概述

        Secret 对象存储数据的方式及使用方式类似于 ConfigMap 对象,以键值方式存储数据, 在 Pod 资源中通过环境变量或存储卷进行数据访问。 不同的是, Secret 对象仅会被分发至调 用了此对象的 Pod 资源所在的工作节点,且只能由节点将其存储于内存中。 另外, Secret 对 象的数据的存储及打印格式为 Base64 编码的字符串,因此用户在创建 Secret 对象时也要提 供此种编码格式的数据。 不过,在容器中以环境变量或存储卷的方式访问时,它们会被自动 解码为明文格式。 

        需要注意的是,在 Master 节点上, S巳cret 对象以非加密的格式存储于 etcd中,因此 管理员必须加以精心管控以确保敏感数据的机密性,必须确保 etcd 集群节点间以及与 API Server 的安全通信,etcd 服务的访问授权,还包括用户访问 API Server 时的授权,因为拥有 创建 Pod 资源的用户都可以使用 Secret 资源并能够通过 Pod 中的容器访问其数据。 

        Secret 对象主要有两种用途, 一是作为存储卷注入到 Pod 上由容器应用程序所使用, 二是用于 kubelet 为 Pod 里的容器拉取镜像时向私有仓库提供认证信息。 不过,后面使用 ServiceAccount 资源自建的 Secret 对象是一种更具安全性的方式。

 Secret 资源主要由四种类型组成,具体如下。

  •  Opaque:自定义数据内容; base64 编码,用来存储密码、密钥、信息、证书等数据,类型标识符为 generic。 
  •  kubernetes.io/service-account-token : Service Account 的认证信息,可在创建 Service Accout 时由 Kubernetes 自动创建。 
  • kubernetes.io/dockerconfiεjson :用来存储 Docker 镜像仓库的认证信息,类型标识为docker-registry。
  •  kubernetes.io/tls : 用于为 SSL 通信模式存储证书和私钥文件,命令式创建时类型标 识为 tls。

       注意:base编码并非加密机制,其编码的数据可使用“ base64 …decode”一类的命令进 行解码。

 

2、创建Secret资源

   手动创建Secret对象的方式有两种:通过kubectl create命令和使用Secret配置文件。

2.1 命令式创建 

 1、创建secret

        不少场景中, Pod 中的应用需要通过用户名和密码访问其他服务,例如访问数据库系统等。 创建此类的 Secret 对象,可以使用“ kubectl create secret generic <SECRET_NAME> --from-literal=key=value'’命令直接进行创建,不过为用户认证之需进行创建时, 其使用的 键名通常是 username 和 password。

[root@master configmap]# kubectl create secret generic mysql-root-password -n config --from-literal=password=centos         # 创建secret,名称为mysql-root-password,--from-literal=password密码为centos
secret/mysql-root-password created

 

2、查看创建的secret资源信息,此时查看的密码是通过base64进行加密的,但是通过base64可以进行破解。

[root@master configmap]# kubectl get secret  mysql-root-password -n config -o yaml          # 查看secret的具体信息
apiVersion: v1
data:
  password: Y2VudG9z                                                                        # 创建的密码必须事base64编码密钥
kind: Secret
metadata:
  creationTimestamp: "2020-08-04T14:31:43Z"
  name: mysql-root-password
  namespace: config
  resourceVersion: "230246"
  selfLink: /api/v1/namespaces/config/secrets/mysql-root-password
  uid: 0a4a4a2e-9c2b-411c-85eb-fb89b23f6daa
type: Opaque 
[root@master configmap]# echo Y2VudG9z | base64 -d                                          # 将base64编码进行解密,可以查看到此时的密码就是centos
centos[root@master configmap]# 
[root@master configmap]# kubectl get secret -n config                                       # 查看创建的secret信息
NAME                  TYPE                                  DATA   AGE
default-token-qmgzk   kubernetes.io/service-account-token   3      13h
mysql-root-password   Opaque                                1      40m

 

2.2 通过secret向pod注入环境变量 

1、创建Pod,与前面创建的secret进行关联

[root@master configmap]# cat  mysql-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  namespace: config
spec:
  containers:
  - name: mysql
    image: mysql:5.6
    env:
    - name: MYSQL_ROOT_PASSWORD  # 镜像定义的环境变量名
      valueFrom:
        secretKeyRef:
          key: password             # 密码的键,对应的密码就是上面创建的centos
          name: mysql-root-password # 创建的secret名称

  

2、执行yaml文件,创建pod,并查看pod的详细信息

[root@master configmap]# kubectl apply -f mysql-pod.yaml   # 创建pod资源
pod/mysql-pod created
[root@master configmap]# kubectl get pods -n config     # 查看此时的pod运行状态
NAME           READY   STATUS    RESTARTS   AGE
mysql-pod      1/1     Running   0          17m
nginx-pod      1/1     Running   1          6h3m
pod-cfg-demo   1/1     Running   2          12h

 

3、进入到pod容器中,查看此时的信息,此方法不是保存密钥的妥当方法,里面可以看到登录数据库的密码

[root@master configmap]# kubectl exec -it mysql-pod -n config -- /bin/sh
# mysql -pcentos            # 登录到数据库中
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.49 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit
Bye
# printenv                 # 可以使用printenv进行查看环境变量值
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=mysql-pod
MYSQL_MAJOR=5.6
HOME=/root
MYSQL_ROOT_PASSWORD=centos
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MYSQL_VERSION=5.6.49-1debian9
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
GOSU_VERSION=1.12
KUBERNETES_SERVICE_HOST=10.96.0.1

  

3、Secret 存储卷

       类似于 Pod 消费 ConfigMap 对象的方式, Secret 对象可以注入为环境变量,也可以存储为卷形式挂载使用。 不过,容器应用通常会在发生错误时将所有环境变量保存于日志信息 中,甚至有些应用在启动时即会将运行环境打印到日志中;另外,容器应用调用第三方程序为子进程时,这些子进程能够继承并使用父进程的所有环境变量。 有鉴于此,使用环境变量引用 Secret 对象中的敏感信息实在算不上明智之举。

        在 Pod 中使用 Secret 存储卷的方式,除了其类型及引用标识要替换为 Secret 及 secretName 之外,几乎完全类似于 Config Map 存储卷,包括支持使用挂载整个存储卷、只挂载存储卷 中的指定键值以及独立挂载存储卷中的键等使用方式。 

 

3.1 基于存储卷创建Secret

 1、创建tls.key和tls.crt密钥文件

[root@master configmap]# openssl genrsa -out tls.key 2048
Generating RSA private key, 2048 bit long modulus
..............+++
.......+++
e is 65537 (0x10001)
[root@master configmap]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=myapp.peng.com
[root@master configmap]# ll
total 32
-rw-r--r-- 1 root root  413 Aug  4 17:02 myapp-pod.yaml
-rw-r--r-- 1 root root  652 Aug  4 22:31 my-pod.yaml
-rw-r--r-- 1 root root  276 Aug  4 22:49 mysql-pod.yaml
-rw-r--r-- 1 root root  407 Aug  4 10:12 pod-cfg.yaml
-rw-r--r-- 1 root root  112 Aug  4 16:07 server1.conf
-rw-r--r-- 1 root root  114 Aug  4 16:48 server.conf
-rw-r--r-- 1 root root 1285 Aug  5 21:37 tls.crt         # 查看生成的tls.crt文件
-rw-r--r-- 1 root root 1675 Aug  5 21:37 tls.key         # 查看此时生成的tls.key文件  


 

2、基于上面创建的tls.key和tls.crt文件创建 tls类型的secret文件

[root@master configmap]# kubectl  create  secret tls  mysql-cert  --cert=./tls.crt  --key=./tls.key  -n config
secret/mysql-cert created
[root@master configmap]# kubectl get secrets -n config        #   查看此时创建的secret状态
NAME                  TYPE                                  DATA   AGE
default-token-qmgzk   kubernetes.io/service-account-token   3      36h
mysql-cert            kubernetes.io/tls                     2      4m16s
mysql-root-password   Opaque                                1      23h

 

3、将上面资源清单文件中定义的资源创建于 Kubernetes 系统上,而后再查看容器挂载点 目录中的文件,以确认其挂载是否成功完成,将创建的secret的tls.crt和ltls.key映射为两个文件

[root@master configmap]# cat  my-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: config
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: config
      mountPath: /etc/nginx/conf.d/
    - name: tls                     # tls存储卷
      mountPath: /etc/nginx/certs/  # 存储卷挂载目录
  volumes:
  - name: config
    configMap:
      name: nginx-cfg
      items:
      - key: server.conf
        path: server-first.conf
      - key: server-second.conf
        path: server-second.conf
  - name: tls                  # 创建第二个volume
    secret:
      secretName: mysql-cert   # secret创建的名称
      items:
        - key: tls.crt         # 定义tls.crt名称
          path: myapp.crt      # 映射为此名称
        - key: tls.key         # 第二个tls.key的名称
          path: myapp.key      # 映射的名称
          mode: 0600           # 文件权限改为0600

 

4、创建pod,并查看容器内部的密钥文件

[root@master configmap]# kubectl apply -f my-pod.yaml   # 创建pod
pod/my-pod created
[root@master configmap]# kubectl exec -it my-pod -n config -- /bin/sh  # 到容器内部查看加密文件
/ # cd  /etc/nginx/certs
/etc/nginx/certs # ls
myapp.crt  myapp.key
/etc/nginx/certs # exit

  

 



这篇关于Kubernetes之十五----configMap和secre特色存储卷详解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程