zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    “神一般存在”的印度理工学院到底有多牛?
    MobaXterm
    VC Debug和Release区别
    Mock 模拟测试简介及 Mockito 使用入门
    JUnit单元测试教程(翻译自Java Code Geeks)
    JUnit4单元测试入门教程
    单元测试利器 JUnit 4
    深入探索 JUnit 4
    JUnit
    Java泛型之类型擦除
  • 原文地址:https://www.cnblogs.com/xulan0922/p/14710131.html
Copyright © 2011-2022 走看看