K8存储之ConfigMap、Secret

ConfigMap

ConfigMap是一种API对象,用来将非加密数据保存到键值对中。可以用作环境变量、命令行参数或者存储卷中的配置文件。

ConfigMap供容器使用的典型用法如下:

  • 生成为容器内的环境变量
  • 设置容器启动命令的启动参数(需设置为环境变量)
  • 以volume的形式挂载为容器内部的文件或者目录

configmap创建:

基于字面值用命令行创建:

# 命令格式
kubectl create configmap <映射名称> <数据源>
​
# <映射名称> 是为指定的ConfigMap 名称,<数据源> 是要从中提取数据的目录、 文件或者字面值。

比如我们创建一个configmap,里面有两个变量值,一个是nginx_port=80,一个是nginx_server_ip=192.168.248.130

[root@master ~]# kubectl create configmap nginx-env --from-literal=nginx_port=80 --from-literal=nginx_server=192.168.248.130
configmap/nginx-env created

查看configmap

[root@master ~]# kubectl get configmap 
NAME               DATA   AGE
kube-root-ca.crt   1      81d
nginx-env          2      82s
[root@master ~]# kubectl describe configmap nginx-env  
Name:         nginx-env
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx_port:
----
80
nginx_server:
----
192.168.248.130
Events:  <none>

此时名为nginx-env的configmap已经被创建,查看详细信息发现定义的变量值已经被写入。

同时也可以通过yaml文件被创建

#vim  configmap_nginx.yaml
piVersion: v1
kind: ConfigMap
metadata:
  name: nginx-env2
  namespace: default
data:
  nginx_port: "80"
  nginx_server: 192.168.248.130                               
[root@master ~]# kubectl apply -f configmap_nginx.yaml 
configmap/nginx-env2 created
[root@master ~]# kubectl get configmap
NAME               DATA   AGE
kube-root-ca.crt   1      81d
nginx-env          2      16m
nginx-env2         2      16s
[root@master ~]# kubectl describe configmap nginx-env2
Name:         nginx-env2
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx_port:
----
80
nginx_server:
----
192.168.248.130
Events:  <none>

基于文件创建ConfigMap

当configmap中需要被定义多个变量时,我们可以将变量写入到文件中,然后基于文件来创建configmap。用--from-file=<文件路径> 来指定,可以使用多次来指定不同的配置文件。文件在configmap中以键值对的形式被创建,键的名字就是文件名,值就是文件内容。

[root@master env]# cat /root/env/nginx-env     #查看变量文件
nginx_port=80
nginx_server=192.168.248.130

[root@master env]# kubectl create configmap nginx-config --from-file=/root/env/nginx-env 
configmap/nginx-config created
[root@master env]# kubectl get configmap nginx-config
NAME           DATA   AGE
nginx-config   1      58s
[root@master env]# kubectl describe configmap nginx-config   
Name:         nginx-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx-env:       #文件名
----
nginx_port=80     #文件中内容
nginx_server=192.168.248.130  #文件内容

Events:  <none>

基于目录创建ConfigMap

跟基于文件创建ConfigMap一样,只是把文件路径换为目录路径

[root@master env]# ll /root/env/
总用量 12
-rw-r--r--. 1 root root 158 7月  30 14:48 game.properties
-rw-r--r--. 1 root root  46 7月  30 14:50 nginx-env
-rw-r--r--. 1 root root 317 7月  30 14:44 ui.properties
[root@master env]# kubectl create configmap config-env --from-file=/root/env/                
configmap/config-env created
[root@master env]# kubectl describe configmap config-env
Name:         config-env
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

nginx-env:
----
nginx_port=80
nginx_server=192.168.248.130

ui.properties:
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice                                                                                                                                                                                                                                     
Events:  <none>

使用ConfigMap

环境变量方式

ConfigMap一定要先于pod创建,再创建一个pod,并挂载ConfigMap。

我们就用上面创建的名为nginx-env的ConfigMap来实验。先创建一个pod

[root@master ~]# cat test.yaml 
apiVersion: v1
kind: Service
metadata:
  name: service-nginx
  namespace: default
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - name: nginx
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydeploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: web
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.4
        ports:
        - name: nginx
          containerPort: 80
        volumeMounts:
          - name: html
            mountPath: /user/share/nginx/html/
        env:
        - name: TEST_PORT
          valueFrom:
            configMapKeyRef:
              name: nginx-env
              key: nginx_port
        - name: TEST_HOST
          valueFrom:
            configMapKeyRef:
              name: nginx-env
              key: nginx_server
      volumes:
      - name: html
        emptyDir: {}

创建pod并查看

[root@master ~]# kubectl apply -f test.yaml       
service/service-nginx created
deployment.apps/mydeploy created
[root@master ~]# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
mydeploy-7bfd9b98c7-jwlcs   1/1     Running   0          5s
[root@master ~]# kubectl exec mydeploy-7bfd9b98c7-jwlcs -it -- /bin/bash
root@mydeploy-7bfd9b98c7-jwlcs:/# printenv
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=mydeploy-7bfd9b98c7-jwlcs
SERVICE_NGINX_SERVICE_PORT_NGINX=80
PWD=/
SERVICE_NGINX_SERVICE_HOST=10.110.104.68
SERVICE_NGINX_PORT=tcp://10.110.104.68:80
SERVICE_NGINX_PORT_80_TCP_PORT=80
SERVICE_NGINX_PORT_80_TCP_PROTO=tcp
TEST_PORT=80
PKG_RELEASE=1~bullseye
HOME=/root
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
TEST_HOST=192.168.248.130
SERVICE_NGINX_PORT_80_TCP=tcp://10.110.104.68:80
NJS_VERSION=0.7.0
TERM=xterm
SHLVL=1
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PORT=443
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_VERSION=1.21.4
SERVICE_NGINX_SERVICE_PORT=80
SERVICE_NGINX_PORT_80_TCP_ADDR=10.110.104.68
_=/usr/bin/printenv
root@mydeploy-7bfd9b98c7-jwlcs:/# 

可以发现configMap当中的环境变量已经注入到了pod容器当中

注意:用这种环境变量的注入方式,pod启动后,如果在去修改configMap当中的变量,对于pod是无效的,如果是以卷的方式挂载,是可的实时更新的。

以存储卷的形式挂载到pod中

[root@master ~]# cat test1.yaml 
apiVersion: v1
kind: Service
metadata:
  name: service-nginx
  namespace: default
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - name: nginx
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydeploy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: web
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.4
        ports:
        - name: nginx
          containerPort: 80
        volumeMounts:
          - name: nginx-config
            mountPath: /nginx/vars/
            readOnly: true
      volumes:
      - name: nginx-config
        configMap:
          name: nginx-env    

创建pod并进入查看/nginx/vars/下的变量文件

[root@master ~]# kubectl apply -f test1.yaml  
service/service-nginx created
deployment.apps/mydeploy created
[root@master ~]# kubectl get pod             
NAME                       READY   STATUS    RESTARTS   AGE
mydeploy-6dc957dc5-9lj4j   1/1     Running   0          2s
[root@master ~]# kubectl exec mydeploy-6dc957dc5-9lj4j -it -- /bin/bash
root@mydeploy-6dc957dc5-9lj4j:/# ls
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64  media  mnt  nginx  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@mydeploy-6dc957dc5-9lj4j:/# cd nginx/vars/
root@mydeploy-6dc957dc5-9lj4j:/nginx/vars# ls
nginx_port  nginx_server
root@mydeploy-6dc957dc5-9lj4j:/nginx/vars# cat nginx_port 
80     
root@mydeploy-6dc957dc5-9lj4j:/nginx/vars# 

我们查看到 nginx/vars/nginx_port中内容为80 ,修改nginx-env中的nginx_port值为8080

[root@master ~]# kubectl edit configmap nginx-env
"/tmp/kubectl-edit-vz3zm.yaml" 15L, 463C written
deployment.apps/mydeploy configured
[root@master ~]# kubectl get pod
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  nginx_port: "8080"
  nginx_server: 192.168.248.130
kind: ConfigMap
metadata:
  creationTimestamp: "2022-07-30T08:20:11Z"
  name: nginx-env
  namespace: default
  resourceVersion: "411597"
  uid: 0b42384e-03d5-499d-9527-e546e3477d2e

我们再进入容器查看nginx/vars/nginx_port的值,此时已经变成8080

[root@master ~]# kubectl exec mydeploy-6dc957dc5-9lj4j -it -- /bin/bash
root@mydeploy-6dc957dc5-9lj4j:/# cat nginx/vars/nginx_port 
8080
root@mydeploy-6dc957dc5-9lj4j:/# 

 Secret

Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 

 secret有三种类型:
  • Service Account:用来访问Kubernetes API,有Kubernetes自动创建并且会自动挂载到Pod的 /run/secrets/kubernetes.io/serviceaccount 目录中。
  • Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据也可以通过base64 –decode解码得到原始数据,所有加密性很弱。
  • kubernetes.io/dockerconfigjson : 用来存储私有docker registry的认证信息。

 

Secret的创建方式跟ConfigMap相似,只不过时把变量通过base64进行了转码

手动创建base64加密

[root@master ~]# echo -n 'admin' | base64
YWRtaW4=
[root@master ~]# echo -n 'qwe123QAZ' | base64      
cXdlMTIzUUFa

手动解密

[root@master ~]# echo -n 'YWRtaW4=' | base64 -d
admin
[root@master ~]# echo -n 'cXdlMTIzUUFa' | base64 -d
qwe123QAZ

创建Secret

一、通过命令行创建

[root@master ~]# kubectl create secret test-secret --help
Create a secret using specified subcommand.

Available Commands:
  docker-registry 创建一个给 Docker registry 使用的 secret
  generic         从本地 file, directory 或者 literal value 创建一个 secret
  tls             创建一个 TLS secret

Usage:
  kubectl create secret [flags] [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).
[root@master ~]# kubectl create secret generic test-user --from-literal=user=admin
secret/test-user created
[root@master ~]# kubectl create secret generic test-passwd --from-literal=passwd=qwe123QAZ
secret/test-passwd created
[root@master ~]# kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-mkcn2   kubernetes.io/service-account-token   3      82d
test-passwd           Opaque                                1      21s
test-user             Opaque                                1      46s
[root@master ~]# 

我们通过查看secret发现刚刚创建的类型为Opaque

二、通过yaml创建

[root@master ~]# cat secret.yaml 
apiVersion: v1
kind: Secret
metadata: 
  name: test-secret
type: Opaque   #注意类型为Opaque
data:  
  test-user: YWRtaW4=    #值为base64编码后的
  test-passwd: cXdlMTIzUUFa  #值为编码后的

 

secret使用

一、通过变量注入

[root@master ~]# cat secret-pod.yaml                
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.21.4
    imagePullPolicy: IfNotPresent
    env:
    - name: nginx-user
      valueFrom:
        secretKeyRef:
          name: test-secret
          key: test-user
    - name: nginx-passwd
      valueFrom:
        secretKeyRef:
          name: test-secret
          key: test-passwd

创建pod并查看

[root@master ~]# kubectl apply -f secret-pod.yaml
pod/mypod created
[root@master ~]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
mydeploy-6dc957dc5-9lj4j   1/1     Running   0          4h42m
mypod                      1/1     Running   0          18s

进入pod查看

[root@master ~]# kubectl exec mypod -it -- /bin/bash
root@mypod:/# printenv
nginx-user=admin
nginx-passwd=qwe123QAZ
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=mypod
SERVICE_NGINX_SERVICE_PORT_NGINX=80
PWD=/
SERVICE_NGINX_SERVICE_HOST=10.111.70.83
SERVICE_NGINX_PORT=tcp://10.111.70.83:80
SERVICE_NGINX_PORT_80_TCP_PORT=80
SERVICE_NGINX_PORT_80_TCP_PROTO=tcp
PKG_RELEASE=1~bullseye
HOME=/root
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
SERVICE_NGINX_PORT_80_TCP=tcp://10.111.70.83:80
NJS_VERSION=0.7.0
TERM=xterm
SHLVL=1
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PORT=443
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_VERSION=1.21.4
SERVICE_NGINX_SERVICE_PORT=80
SERVICE_NGINX_PORT_80_TCP_ADDR=10.111.70.83
_=/usr/bin/printenv
root@mypod:/# 

二、通过Volume挂载的方式

[root@master ~]# cat secret-pod2.yaml                 
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.21.4
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: test-secret
      mountPath: /nginx/
      readOnly: true
  volumes:
  - name: test-secret
    projected:
      sources:
      - secret:
          name: test-secret

创建pod,并进入容器查看

[root@master ~]# kubectl exec nginx -it -- /bin/bash
root@nginx:/# ls
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64  media  mnt  nginx  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@nginx:/# cd nginx
root@nginx:/nginx# ls
test-passwd  test-user
root@nginx:/nginx# cat test-passwd 
qwe123QAZ
root@nginx:/nginx# cat test-user   
admin
root@nginx:/nginx# 

最后我们来对比下Secret和ConfigMap这两种资源对象的异同点:

相同点:

key/value的形式

属于某个特定的namespace

可以导入到环境变量

可以通过目录/文件形式挂载

通过 volume 挂载的配置信息均可热更新 

不同点:

Secret 可以被 ServerAccount 关联

Secret 可以存储 docker register 的鉴权信息,用在 ImagePullSecret 参数中,用于拉取私有仓库的镜像

Secret 支持 Base64 加密

Secret 分为 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型,而 Configmap 不区分类型

 

posted @ 2022-07-30 22:19  李志锋  阅读(248)  评论(0编辑  收藏  举报