kubernetes 配置管理-secret&configmap

Secret

k8s secrets用于存储和管理一些敏感数据,比如密码,token,密钥等敏感信息。它把 Pod 想要访问的加密数据存放到 Etcd 中。然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了。

Secret三种类型:

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

1.Opaque类型

Opaque 类型的数据是一个 map 类型,要求必须value是base64编码。

所以要使用Opaque ,先手动创建base64加密,比如:

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

解密也很简单:

[root@master ~]# echo 'YWRtaW4=' | base64 --decode
admin

像这样创建的 Secret 对象,它里面的内容仅仅是经过了转码,而并没有真正被加密。在真正的生产环境中,需要在 Kubernetes 中开启 Secret 的加密插件,增强数据的安全性。

2. Service Account类型

      Service Account 对象的作用,就是 Kubernetes 系统内置的一种“服务账户”,它是 Kubernetes 进行权限分配的对象。比如,Service Account A,可以只被允许对 Kubernetes API 进行 GET 操作,而 Service Account B,则可以有 Kubernetes API 的所有操作权限。

3. kubernetes.io/dockerconfigjson类型

用来创建用户docker registry认证的Secret,直接使用kubectl create命令创建即可,如下:

kubectl create secret docker-registry myregistry --docker-server=DOCKER_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL

[root@master ~]# kubectl get secret |grep myregistry
myregistry            kubernetes.io/dockerconfigjson        1      41s

如果有pod需要拉取私有仓库中的docker镜像的话就需要使用到上面的myregistry这个Secret:

apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
  - name: foo
    image: 192.168.1.100:5000/test:v1
  imagePullSecrets:
  - name: myregistry

Secret创建方式

方式一:kubectl create secret 命令

generic子命令可以通过本地文件、目录或者literal(键值对),来创建secret

比如本地文件内容如下:

$ cat ./password.txt
1f2d1e2e67df

根据这个文件创建secret:

[root@master secret]# kubectl create secret generic pass --from-file=./password.txt
secret/pass created
[root@master secret]# kubectl get secret |grep pass
pass                  Opaque                                1      91s

默认情况下key为文件名。

也可以不通过文件,直接通过键值对创建:

$ kubectl create secret generic pass --from-literal=password=1f2d1e2e67df

方式二: 通过yaml文件创建

#secret.yaml
 
apiVersion: v1
kind: Secret
metadata: 
  name: mysecret
type: Opaque
data:  
  user: YWRtaW4=  
  pass: MWYyZDFlMmU2N2Rm

注:通过yaml创建Opaque类型的Secret值需要base64编码

创建secret:

[root@master secret]# kubectl create -f secret.yaml
secret/mysecret created
[root@master secret]# kubectl get secret |grep Opaque
mysecret              Opaque                                2      52s

mysecret中包括了两对key/value:

[root@master secret]# kubectl describe secret mysecret
Name:         mysecret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
pass:  12 bytes
user:  5 bytes

多数情况下,会使用yaml文件的方式来创建secret。

Secret使用方式

方式一:通过Volume挂载的方式

# secret-volume.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mypod1
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

在pod中,挂载卷name为foo,挂载位置为/etc/foo,只读,其挂载内容为之前创建的mysecret。

创建pod:

[root@master secret]# kubectl apply -f secret-volume.yaml 
pod/mypod1 created
[root@master secret]# kubectl get pods
NAME     READY   STATUS    RESTARTS   AGE
mypod1   1/1     Running   0          6m37s

验证一下这些 Secret 对象是不是已经在容器里了:

[root@master secret]# kubectl exec -it mypod1 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
root@mypod1:/# cd /etc/foo
root@mypod1:/etc/foo# ls
pass  user
root@mypod1:/etc/foo# cat pass 
1f2d1e2e67df
root@mypod1:/etc/foo# cat user 
admin

方式二:通过环境变量

# secret-var.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mypod2
spec:
  containers:
  - name: nginx
    image: nginx
    env:
      - name: SECRET_USER
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: user
      - name: SECRET_PASS
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: pass

在pod中,声明两个环境变量SECRET_USER与SECRET_PASS,分别对应之前创建的mysecret中的两个key。

创建pod:

[root@master secret]# kubectl apply -f secret-var.yaml 
pod/mypod2 created
[root@master secret]# kubectl get pods
NAME     READY   STATUS    RESTARTS   AGE
mypod2   1/1     Running   0          3m44s

验证下,进入容器中查看环境变量:

[root@master secret]# kubectl exec -it mypod2 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
root@mypod2:/# env|grep SECRET
SECRET_PASS=1f2d1e2e67df
SECRET_USER=admin

通过volume挂载和环境变量的区别

通过Volume挂载到容器内部时,当该Secret的值发生变化时,容器内部具备自动更新的能力,但是通过环境变量设置到容器内部该值不具备自动更新的能力。

所以一般推荐使用Volume挂载的方式使用Secret。

ConfigMap

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

ConfigMap可以将环境变量配置信息和容器镜像解耦,便于应用配置的修改。如果需要存储加密信息时可以使用Secret对象。

ConfigMap创建方式

方式一:通过命令行创建configmap

可以使用 kubectl create configmap 从文件、目录或者 key-value 字符串创建等创建 ConfigMap

(1)通过文件创建configmap

# test.txt
ip=172.31.92.11
port=3306

kubectl create configmap my-config --from-file=./test.txt

查看configmap:

(2)通过文件夹创建configmap

$ mkdir config
$ echo hello > config/test1
$ echo world > config/test2

kubectl create configmap dir-config --from-file=config/

查看configmap:

configmap资源中有两个键值对,test1:hello和test2:world,key为文件名,value为文件内容。

(3)直接通过键值对创建configmap

kubectl create configmap literal-config --from-literal=key1=hello --from-literal=key2=world

查看configmap:

方式二:通过yaml文件创建

#config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
 name: my-config
data:
 key1: hello
 key2: world
[root@master configmap]# kubectl apply -f config.yaml 
configmap/my-config created
[root@master configmap]# kubectl get cm
NAME        DATA   AGE
my-config   2      10s
[root@master configmap]# kubectl describe cm my-config
Name:         my-config
Namespace:    default
Labels:       <none>
Annotations:  
Data
====
key1:
----
hello
key2:
----
world
Events:  <none>

ConfigMap使用方式

方式一:通过Volume挂载的方式

# configmap-volume.yaml

apiVersion: v1
kind: Pod
metadata:
 name: test-pod-configmap-volume
spec:
 containers:
 - name: test-pod-busybox
   image: busybox
   imagePullPolicy: IfNotPresent
   args:
   - sleep
   - "86400"
   volumeMounts:
   - name: config-volume
     mountPath: "/projected-volume"
     readOnly: true
 volumes:
 - name: config-volume
   projected:
    sources:
    - configMap:
       name: my-config

在pod中,挂载卷name为config-volume,挂载位置为/projected-volume,只读,其挂载内容为之前创建的my-config。

创建pod:

[root@master configmap]# kubectl apply -f configmap-volume.yaml 
pod/test-pod-configmap-volume created
[root@master configmap]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
test-pod-configmap-volume   1/1     Running   0          9s

进入容器验证configmap中的对象:

[root@master configmap]# kubectl exec -it test-pod-configmap-volume -- /bin/sh
/ # cd /projected-volume
/projected-volume # ls
key1  key2

方式二:通过环境变量

# configmap-cmd.yaml
apiVersion: v1 kind: Pod metadata: name: test
-pod-configmap-cmd spec: containers: - name: test-busybox image: busybox imagePullPolicy: IfNotPresent command: [ "/bin/sh","-c","echo $(KEY1) $(KEY2)"] env: - name: KEY1 valueFrom: configMapKeyRef: name: my-config key: key1 - name: KEY2 valueFrom: configMapKeyRef: name: my-config key: key2 restartPolicy: Never

在pod中,声明两个环境变量KEY1与KEY2,分别对应之前创建的my-config中的两个key。

创建pod:

[root@master configmap]# kubectl apply -f configmap-cmd.yaml 
pod/test-pod-configmap-cmd created
[root@master configmap]# kubectl get pods
NAME                        READY   STATUS      RESTARTS   AGE
test-pod-configmap-cmd      0/1     Completed   0          30s
test-pod-configmap-volume   1/1     Running     0          12m

该pod成功启动后状态为completed,日志中会输出环境变量KEY1和KEY2的值:

[root@master configmap]# kubectl logs test-pod-configmap-cmd
hello world

通过volume挂载和环境变量的区别

通过Volume挂载到容器内部时,当该configmap的值发生变化时,容器内部具备自动更新的能力,但是通过环境变量设置到容器内部该值不具备自动更新的能力。

 

Secret 与 ConfigMap 对比

最后对比下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 不区分类型

 

参考:

Secret:https://blog.csdn.net/skh2015java/article/details/109228364

ConfigMap:https://skaygo.blog.csdn.net/article/details/109228836

 

posted @ 2021-05-03 22:40  酒红色  阅读(266)  评论(0编辑  收藏  举报