zoukankan      html  css  js  c++  java
  • K8S之secret

    K8S之secret

    官方文档

    secret是k8s中用来存储敏感认证信息的一种重要资源,大致可以分为三种类型:docker-registrygenerictls,从名称上就可以看出来,分别用于存储镜像仓库认证信息,一般信息和证书信息。其中generic类型的最常用,比较典型的就是用来存放数据库的认证信息。

    创建secret

    使用kubectl create命令创建

    使用 kubectl 管理 Secret

    我们先来查看一下命令帮助:

    [root@center-188 pod]# kubectl create secret --help
    Create a secret using specified subcommand.
    
    Available Commands:
      docker-registry Create a secret for use with a Docker registry
      generic         Create a secret from a local file, directory or literal value
      tls             Create a 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@center-188 pod]# kubectl create secret generic --help
    Create a secret based on a file, directory, or specified literal value.
    
     A single secret may package one or more key/value pairs.
    
     When creating a secret based on a file, the key will default to the basename of
    the file, and the value will default to the file content. If the basename is an
    invalid key or you wish to chose your own, you may specify an alternate key.
    
     When creating a secret based on a directory, each file whose basename is a
    valid key in the directory will be packaged into the secret. Any directory
    entries except regular files are ignored (e.g. subdirectories, symlinks,
    devices, pipes, etc).
    
    Examples:
      # Create a new secret named my-secret with keys for each file in folder bar
      kubectl create secret generic my-secret --from-file=path/to/bar
    
      # Create a new secret named my-secret with specified keys instead of names on
    disk
      kubectl create secret generic my-secret
    --from-file=ssh-privatekey=path/to/id_rsa
    --from-file=ssh-publickey=path/to/id_rsa.pub
    
      # Create a new secret named my-secret with key1=supersecret and key2=topsecret
      kubectl create secret generic my-secret --from-literal=key1=supersecret
    --from-literal=key2=topsecret
    
      # Create a new secret named my-secret using a combination of a file and a
    literal
      kubectl create secret generic my-secret
    --from-file=ssh-privatekey=path/to/id_rsa --from-literal=passphrase=topsecret
    
      # Create a new secret named my-secret from an env file
      kubectl create secret generic my-secret --from-env-file=path/to/bar.env
    
    Options:
          --allow-missing-template-keys=true: If true, ignore any errors in
    templates when a field or map key is missing in the template. Only applies to
    golang and jsonpath output formats.
          --append-hash=false: Append a hash of the secret to its name.
          --dry-run=false: If true, only print the object that would be sent,
    without sending it.
          --from-env-file='': Specify the path to a file to read lines of key=val
    pairs to create a secret (i.e. a Docker .env file).
          --from-file=[]: Key files can be specified using their file path, in which
    case a default name will be given to them, or optionally with a name and file
    path, in which case the given name will be used.  Specifying a directory will
    iterate each named file in the directory that is a valid secret key.
          --from-literal=[]: Specify a key and literal value to insert in secret
    (i.e. mykey=somevalue)
          --generator='secret/v1': The name of the API generator to use.
      -o, --output='': Output format. One of:
    json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
          --save-config=false: If true, the configuration of current object will be
    saved in its annotation. Otherwise, the annotation will be unchanged. This flag
    is useful when you want to perform kubectl apply on this object in the future.
          --template='': Template string or path to template file to use when
    -o=go-template, -o=go-template-file. The template format is golang templates
    [http://golang.org/pkg/text/template/#pkg-overview].
          --type='': The type of secret to create
          --validate=true: If true, use a schema to validate the input before
    sending it
    
    Usage:
      kubectl create secret generic NAME [--type=string] [--from-file=[key=]source]
    [--from-literal=key1=value1] [--dry-run] [options]
    
    Use "kubectl options" for a list of global command-line options (applies to all
    commands).
    

    这里已经说明的非常详细了,我再举几个例子说明一下:

    # 例一:
    # --from-literal:从命令行直接指定键值对信息
    [root@center-188 pod]# kubectl create secret generic ssh-user --from-literal=user=root -n wuvikr
    secret/ssh-user created
    
    
    # 可以看到我们在wuvikr名称空间下创建了一个名为ssh-user的secret
    [root@center-188 pod]# kubectl get secret -n wuvikr
    NAME                  TYPE                                  DATA   AGE
    ssh-user              Opaque                                1      28s
    
    
    # 查看详细信息
    # 其中data字段中,保存的就是我们指定的信息
    # 需要注意的是这里的cm9vdA==并不是加密信息,仅仅是root的base64转码后的信息
    # 生产中如果安全要求很高,可以使用secret加密插件
    [root@center-188 pod]# kubectl get secret ssh-user -n wuvikr -o yaml
    apiVersion: v1
    data:
      user: cm9vdA==
    kind: Secret
    metadata:
      creationTimestamp: "2021-02-26T01:38:27Z"
      name: ssh-user
      namespace: wuvikr
      resourceVersion: "46489313"
      selfLink: /api/v1/namespaces/wuvikr/secrets/ssh-user
      uid: 5d16c41f-1b70-4d3c-934e-ecfa7b29ab5e
    type: Opaque
    
    
    
    # 例二:
    # --from-file:从文件中读取键值对信息
    [root@center-188 pod]# cat passwd.txt
    123456
    
    # 这里--from-file后也可以跟上键名,如果不指定,默认键名为文件名
    [root@center-188 pod]# kubectl create secret generic ssh-pass --from-file=./passwd.txt -n wuvikr
    secret/ssh-pass created
    [root@center-188 pod]# kubectl get secret -n wuvikr
    NAME                  TYPE                                  DATA   AGE
    ssh-pass              Opaque                                1      8s
    ssh-user              Opaque                                1      9m21s
    
    
    # 查看详细信息
    [root@center-188 pod]# kubectl get secret ssh-pass -n wuvikr -o yaml
    apiVersion: v1
    data:
      passwd.txt: MTIzNDU2Cg==    #由于没有指定键名,键名默认为文件名了
    kind: Secret
    metadata:
      creationTimestamp: "2021-02-26T01:47:40Z"
      name: ssh-pass
      namespace: wuvikr
      resourceVersion: "46491627"
      selfLink: /api/v1/namespaces/wuvikr/secrets/ssh-pass
      uid: 1bd4650a-b58c-4e4a-9f15-cf0234bb10b6
    type: Opaque
    
    
    # 这次我们指定下键名
    [root@center-188 pod]# kubectl create secret generic ssh-pass1 --from-file=pass=./passwd.txt -n wuvikr
    [root@center-188 pod]# kubectl get secret ssh-pass1 -n wuvikr -o yaml
    apiVersion: v1
    data:
      pass: MTIzNDU2Cg==   # 指定了键名为pass
    kind: Secret
    metadata:
      creationTimestamp: "2021-02-26T01:54:26Z"
      name: ssh-pass1
      namespace: wuvikr
      resourceVersion: "46493370"
      selfLink: /api/v1/namespaces/wuvikr/secrets/ssh-pass1
      uid: dddb33d7-af66-44c0-b2f4-15d96ec64ef2
    type: Opaque
    
    
    # 当然也可以一次性将多个文件加入到一个secret中,具体怎么使用怎么方便就怎么来
    [root@center-188 pod]# kubectl create secret generic ssh-account -n wuvikr --from-file=username=./username.txt --from-file=password=./passwd.txt
    [root@center-188 pod]# kubectl get secret ssh-account -n wuvikr -o yaml
    apiVersion: v1
    data:
      password: MTIzNDU2Cg==
      username: YWRtaW4K
    kind: Secret
    metadata:
      creationTimestamp: "2021-02-26T05:09:37Z"
      name: ssh-account
      namespace: wuvikr
      resourceVersion: "46541985"
      selfLink: /api/v1/namespaces/wuvikr/secrets/ssh-account
      uid: 13a19839-ae6b-4b6b-bfe1-b2026dfeb668
    type: Opaque
    
    
    # 你可能会想,要是我们需要用到的secret值很多,一个个添加实在太麻烦了
    # 不用担心,--from-file还可以直接指定一个目录
    # 其目录中所有的文件都会被加载到secret中去
    # 但是这种情况下,就不能在命令行中直接指定键名了,因为目录下有多个文件。
    [root@center-188 pod]# ll files
    total 8
    -rw-r--r-- 1 root root 4 Feb 26 09:49 01.txt
    -rw-r--r-- 1 root root 4 Feb 26 09:49 02.txt
    [root@center-188 pod]# cat files/01.txt files/02.txt
    aaa
    bbb
    
    [root@center-188 pod]# kubectl create secret generic test01 --from-file=./files/ -n wuvikr
    [root@center-188 pod]# kubectl get secret test01 -n wuvikr -o yaml
    apiVersion: v1
    data:
      01.txt: YWFhCg==
      02.txt: YmJiCg==
    kind: Secret
    metadata:
      creationTimestamp: "2021-02-26T01:50:59Z"
      name: test01
      namespace: wuvikr
      resourceVersion: "46492414"
      selfLink: /api/v1/namespaces/wuvikr/secrets/test01
      uid: 65a61fa1-c9f0-4a9c-bf84-a1bf7e97fdcb
      
    # 是不是很方便,files目录下的每个文件都被添加到这个secret中来了,并且键名都为文件名。
    
    
    # 例三:
    # --from-env-file:环境变量键值对文件
    # 有时候我们在写yaml的时候,可能要为某个pod指定多个ENV
    # 一个一个添加真是太麻烦了,我们可以直接将这些ENV都写入一个文件中
    # 然后创建一个ENV的secret,再直接挂载到容器中使用。
    [root@center-188 pod]# cat env-mysql.txt
    MYSQL_ROOT_PASSWORD=744123
    MYSQL_DATABASE=testdb
    MYSQL_USER=test
    MYSQL_PASSWORD=123456
    
    [root@center-188 pod]# kubectl create secret generic env-mysql --from-env-file=./env-mysql.txt -n wuvikr
    secret/env-mysql created
    [root@center-188 pod]# kubectl get secret env-mysql -n wuvikr -o yaml
    apiVersion: v1
    data:
      MYSQL_DATABASE: dGVzdGRi
      MYSQL_PASSWORD: MTIzNDU2
      MYSQL_ROOT_PASSWORD: NzQ0MTIz
      MYSQL_USER: dGVzdA==
    kind: Secret
    metadata:
      creationTimestamp: "2021-02-26T02:09:58Z"
      name: env-mysql
      namespace: wuvikr
      resourceVersion: "46497156"
      selfLink: /api/v1/namespaces/wuvikr/secrets/env-mysql
      uid: 3e706ce9-c260-495f-ba98-9cca55de8f12
    type: Opaque
    

    直接写yaml文件创建

    使用配置文件管理 Secret

    如果我们很熟悉secret的格式的话,完全可以自己手写一份yaml文件来创建新的secret。从已有的secret导出一个当做模板,再按需修改就行了。

    # 导出已有模板
    [root@center-188 secret]# kubectl get secret ssh-user -n wuvikr -o yaml > my-secret.yaml
    
    # 按需修改,保留以下基础部分即可
    [root@center-188 secret]# cat my-secret.yaml
    apiVersion: v1
    data:
      user: cm9vdA==
    kind: Secret
    metadata:
      name: ssh-user
      namespace: wuvikr
      
    # 创建Secret
    [root@center-188 secret]# kubectl apply -f ./my-secret.yaml
    

    编辑修改secret

    可以kubectl edit命令来编辑修改已有的 Secret:

    [root@center-188 secret]# kubectl edit secrets ssh-user -n wuvikr
    
    # 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:
      user: cm9vdA==
    kind: Secret
    metadata:
      creationTimestamp: "2021-02-26T01:38:27Z"
      name: ssh-user
      namespace: wuvikr
      resourceVersion: "46489313"
      selfLink: /api/v1/namespaces/wuvikr/secrets/ssh-user
      uid: 5d16c41f-1b70-4d3c-934e-ecfa7b29ab5e
    type: Opaque
    

    需要注意的是:data字段中保存的是base64 编码的 Secret 值。

    # 先将要编辑的内容转换为base64编码,再编辑修改secret文件。
    [root@center-188 secret]# echo 'passwd' | base64
    cGFzc3dkCg==
    

    secret的使用

    以volume挂载的方式使用secret

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-volume-test
      namespace: wuvikr
    spec:
      containers:
      - name: secret-volume-test
        image: busybox
        args:
        - sleep
        - "86400"
        volumeMounts:
        - name: ssh-cred
          mountPath: "/tmp"
          readOnly: true
      volumes:
      - name: ssh-cred
        secret:
          secretName: ssh-account
    

    执行上面的yaml,并进入到容器中:

    [root@center-188 pod]# kubectl apply -f secret-volume-test.yaml
    pod/secret-volume-test created
    
    [root@center-188 pod]# kubectl exec -it secret-volume-test -n wuvikr -- sh
    / # cd /tmp
    /tmp # ls -al
    total 0
    drwxrwxrwt    3 root     root           120 Feb 26 05:29 .
    drwxr-xr-x    1 root     root            29 Feb 26 05:29 ..
    drwxr-xr-x    2 root     root            80 Feb 26 05:29 ..2021_02_26_05_29_13.312279811
    lrwxrwxrwx    1 root     root            31 Feb 26 05:29 ..data -> ..2021_02_26_05_29_13.312279811
    lrwxrwxrwx    1 root     root            15 Feb 26 05:29 password -> ..data/password
    lrwxrwxrwx    1 root     root            15 Feb 26 05:29 username -> ..data/username
    /tmp # cat username password
    admin
    123456
    

    这里的password 和username 文件其实只是一个软连接,这是k8s为了保持安全更新的一个机制,kubelet 会周期性检查被挂载的Secret是不是最新的,当etcd中的secret被更新后,pod中挂载的secret也会得到更新,但并不是立即更新,中间会有一个延迟。

    上面的挂载方式默认会将secret中的所有键全部挂载进容器中去,有时候我们或许只是想挂载secret中的某几个键,这种情况下可以使用spec.volumes[].secret.items字段来实现:

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-volume-item-test
      namespace: wuvikr
    spec:
      containers:
      - name: secret-volume-item-test
        image: busybox
        args:
        - sleep
        - "86400"
        volumeMounts:
        - name: ssh-cred
          mountPath: "/tmp"
          readOnly: true
      volumes:
      - name: ssh-cred
        secret:
          secretName: ssh-account
          items:
          - key: username
            path: my-path/username
    

    和之前的yaml文件几乎一样,唯一不同的就是在spec.volumes[].secret下使用了items 字段,只有在 items 中指定的键会加载。

    运行一下上面的yaml,并进入到容器中:

    [root@center-188 pod]# kubectl apply -f secret-volume-item-test.yaml
    pod/secret-volume-test created
    
    [root@center-188 pod]# kubectl exec -it secret-volume-item-test -n wuvikr -- sh
    / # cd /tmp
    /tmp # ls -al
    total 0
    drwxrwxrwt    3 root     root           100 Feb 26 05:46 .
    drwxr-xr-x    1 root     root            29 Feb 26 05:46 ..
    drwxr-xr-x    3 root     root            60 Feb 26 05:46 ..2021_02_26_05_46_42.795865831
    lrwxrwxrwx    1 root     root            31 Feb 26 05:46 ..data -> ..2021_02_26_05_46_42.795865831
    lrwxrwxrwx    1 root     root            14 Feb 26 05:46 my-path -> ..data/my-path
    /tmp # cd my-path/
    /tmp/..2021_02_26_05_46_42.795865831/my-path # ls
    username
    

    除了只加载了username之外,还可以发现username Secret 这次存储在了 /tmp/my-path/username 文件中而不是 /tmp/username 中了,这是spec.volumes[].secret.items[].path字段所实现的,而且这还是一个必须字段

    以环境变量的形式使用 Secrets

    环境变量引用有两种方式,下面示例中的第一种写法是从secret中引用某个环境变量,而第二种写法会直接加载secret中全部的环境变量。

    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-env-pod
      namespace: wuvikr
    spec:
      containers:
      - name: mycontainer
        image: mysql:latest
        env:
          - name: MYSQL_ROOT_PASSWORD
            valueFrom:
              secretKeyRef:
                name: env-mysql
                key: MYSQL_ROOT_PASSWORD
    #########################################
    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-env-pod
      namespace: wuvikr
    spec:
      containers:
      - name: mycontainer
        image: mysql:latest
        envFrom:
          - secretRef:
              name: env-mysql
    

    执行上面的yaml,并进入到容器中:

    [root@center-188 secret]# kubectl apply -f secret-env-pod.yaml
    pod/secret-env-pod created
    
    # 打印一下环境变量
    [root@center-188 secret]# kubectl exec -it secret-env-pod -n wuvikr -- bash
    root@secret-env-pod:/# printenv
    KUBERNETES_SERVICE_PORT_HTTPS=443
    KUBERNETES_SERVICE_PORT=443
    MYSQL_MAJOR=8.0
    HOSTNAME=secret-env-pod
    PWD=/
    MYSQL_ROOT_PASSWORD=744123
    MYSQL_PASSWORD=123456
    MYSQL_USER=test
    HOME=/root
    KUBERNETES_PORT_443_TCP=tcp://10.68.0.1:443
    MYSQL_VERSION=8.0.23-1debian10
    GOSU_VERSION=1.12
    TERM=xterm
    SHLVL=1
    KUBERNETES_PORT_443_TCP_PROTO=tcp
    MYSQL_DATABASE=testdb
    KUBERNETES_PORT_443_TCP_ADDR=10.68.0.1
    KUBERNETES_SERVICE_HOST=10.68.0.1
    KUBERNETES_PORT=tcp://10.68.0.1:443
    KUBERNETES_PORT_443_TCP_PORT=443
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    _=/usr/bin/printenv
    

    这里需要注意的是:Secret 更新之后对应的环境变量并不会被更新

    如果某个secret已经被更新,对于已经引用过该secret的容器来说,并不会主动更新ENV,除非该pod被重启。

    以上

  • 相关阅读:
    swagger-ui 系统配置过程(基于spring+springmvc+swagger+springfox配置 web-api 管理系统)
    如何简单扫描整理
    C#双面打印解决方法(打印wordexcel图片)
    MODI出现ORC RUNNING ERROR的解决方法
    EMGU 2.9.X在VS2010下调试真正靠谱的配置
    如何解决The underlying provider failed on Open问题
    shell编程之——cat /dev/null作用
    docker 容器的设置2
    docker 容器的设置1
    ssl证书生成与转换(pfx, pem, key, crt)
  • 原文地址:https://www.cnblogs.com/wuvikr/p/14452054.html
Copyright © 2011-2022 走看看