Kubernetes——Secret资源

Secret资源

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

一、Secret概述

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

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

  secret 字段定义如下:

[root@mh-k8s-master-247-10 ~]# kubectl explain secret
KIND:     Secret
VERSION:  v1

DESCRIPTION:
     Secret holds secret data of a certain type. The total bytes of the values
     in the Data field must be less than MaxSecretSize bytes.

FIELDS:
   apiVersion	<string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

   data	<map[string]string>
     Data contains the secret data. Each key must consist of alphanumeric
     characters, '-', '_' or '.'. The serialized form of the secret data is a
     base64 encoded string, representing the arbitrary (possibly non-string)
     data value here. Described in https://tools.ietf.org/html/rfc4648#section-4

   immutable	<boolean>
     Immutable, if set to true, ensures that data stored in the Secret cannot be
     updated (only object metadata can be modified). If not set to true, the
     field can be modified at any time. Defaulted to nil. This is an alpha field
     enabled by ImmutableEphemeralVolumes feature gate.

   kind	<string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

   metadata	<Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   stringData	<map[string]string>
     stringData allows specifying non-binary secret data in string form. It is
     provided as a write-only convenience method. All keys and values are merged
     into the data field on write, overwriting any existing values. It is never
     output when reading from the API.

   type	<string>
     Used to facilitate programmatic handling of secret data.

[root@mh-k8s-master-247-10 ~]# 

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

    • Opaque: 自定义数据内容:base64编码,用来存储密码、密钥、信息、证书等数据。
    • kubernetes.io/tls: 用于为 SSL 通信模式存储证书和私钥文件,命令式创建时类型表示为 tls。
    • kubernetes.io/dockerconfigjson: 用来存储 Docker 镜像仓库的认证信息,类型标识为 docker-registry。
    • kubernetes.io/servcie-account-token: Servcie Account 的认证信息,可在创建 Service Account 时由 Kubernetes 自动创建。
base64 编码并非加密机制,其编码的数据可使用  "base64 --decode" 一类的命令进行解码。

二、创建 Secret 资源

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

1)命令式创建

[root@mh-k8s-master-247-10 ~]# 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@mh-k8s-master-247-10 ~]# 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='none': Must be "none", "server", or "client". If client strategy, only print the object that would be
sent, without sending it. If server strategy, submit server-side request without persisting the resource.
      --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)
  -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=server|client|none] [options]

Use "kubectl options" for a list of global command-line options (applies to all commands).
[root@mh-k8s-master-247-10 ~]# 

  例如:以 "root/ikubernetes" 分别为用户名和密码创建了一个名为 mysql-auth 的 Secret 对象:

kubectl create secret generic mysql-auth --from-literal=username=root --from-literal=password=ikubernetes

  查看 Secret 资源的属性信息命令如下:

[root@mh-k8s-master-247-10 ~]# kubectl create secret generic mysql-auth --from-literal=username=root --from-literal=password=ikubernetes
secret/mysql-auth created
[root@mh-k8s-master-247-10 ~]# kubectl get secrets mysql-auth -o yaml
apiVersion: v1
data:
  password: aWt1YmVybmV0ZXM=
  username: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2022-06-25T12:44:53Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:password: {}
        f:username: {}
      f:type: {}
    manager: kubectl
    operation: Update
    time: "2022-06-25T12:44:53Z"
  name: mysql-auth
  namespace: default
  resourceVersion: "84718210"
  selfLink: /api/v1/namespaces/default/secrets/mysql-auth
  uid: e44ffdda-953f-4c40-96e4-a0e5d5ca2779
type: Opaque
[root@mh-k8s-master-247-10 ~]# 

  Kubernets 系统的 Secret 对象的 Base64 编码的数据并非加密格式,许多相关的工具均可轻松解码,如下所示的 Base64 命令:

[root@mh-k8s-master-247-10 ~]# echo aWt1YmVybmV0ZXM= | base64 -d
ikubernetes[root@mh-k8s-master-247-10 ~]# 

  对于文件中的数据,也可以在创建 generic 格式 Secret 对象时使用  "--from-file" 选项从文中直接进行加载,命令如下所示:

[root@mh-k8s-master-247-10 ~]# kubectl create secret generic ssh-key-secret --from-file=ssh-private-key=/root/.ssh/id_rsa --from-file=ssh-public-key=/root/.ssh/id_rsa.pub 
secret/ssh-key-secret created
[root@mh-k8s-master-247-10 ~]# 

  如果要基于私钥和数字证书文件创建用于 SSL/TLS 通信的 Secret 对象,则需要使用如下命令格式:

[root@mh-k8s-master-247-10 ~]# kubectl create tls --help
Create a resource from a file or from stdin.

 JSON and YAML formats are accepted.

Examples:
  # Create a pod using the data in pod.json.
  kubectl create -f ./pod.json
  
  # Create a pod based on the JSON passed into stdin.
  cat pod.json | kubectl create -f -
  
  # Edit the data in docker-registry.yaml in JSON then create the resource using the edited data.
  kubectl create -f docker-registry.yaml --edit -o json

Available Commands:
  clusterrole         Create a ClusterRole.
  clusterrolebinding  Create a ClusterRoleBinding for a particular ClusterRole
  configmap           Create a configmap from a local file, directory or literal value
  cronjob             Create a cronjob with the specified name.
  deployment          Create a deployment with the specified name.
  job                 Create a job with the specified name.
  namespace           Create a namespace with the specified name
  poddisruptionbudget Create a pod disruption budget with the specified name.
  priorityclass       Create a priorityclass with the specified name.
  quota               Create a quota with the specified name.
  role                Create a role with single rule.
  rolebinding         Create a RoleBinding for a particular Role or ClusterRole
  secret              Create a secret using specified subcommand
  service             Create a service using specified subcommand.
  serviceaccount      Create a service account with the specified name

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.
      --dry-run='none': Must be "none", "server", or "client". If client strategy, only print the object that would be
sent, without sending it. If server strategy, submit server-side request without persisting the resource.
      --edit=false: Edit the API resource before creating
  -f, --filename=[]: Filename, directory, or URL to files to use to create the resource
  -k, --kustomize='': Process the kustomization directory. This flag can't be used together with -f or -R.
  -o, --output='': Output format. One of:
json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
      --raw='': Raw URI to POST to the server.  Uses the transport specified by the kubeconfig file.
      --record=false: Record current kubectl command in the resource annotation. If set to false, do not record the
command. If set to true, record the command. If not set, default to updating the existing annotation value only if one
already exists.
  -R, --recursive=false: Process the directory used in -f, --filename recursively. Useful when you want to manage
related manifests organized within the same directory.
      --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.
  -l, --selector='': Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
      --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].
      --validate=true: If true, use a schema to validate the input before sending it
      --windows-line-endings=false: Only relevant if --edit=true. Defaults to the line ending native to your platform.

Usage:
  kubectl create -f FILENAME [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@mh-k8s-master-247-10 ~]# 

  例子:假如需要为 Nginx 测试创建 SSL 虚拟主机,用户首先使用了类似如下的命令生成了私钥和自签证书,使用如下命令将要两个文件(私钥和证书两个文件)创建为 Secret对象。注意无论用户提供的证书和私钥文件使用什么名称,它们一律会被转换为分别以 tls.key(私钥) 和 tls.crt(证书)为其键名:

[root@mh-k8s-master-247-10 ~]# openssl req -new -x509 -key nginx.key -out nginx.crt -subj /C=CN/ST=Shanghai/L=Shanghai/O=DevOps/CN=www.zuoyang.com
[root@mh-k8s-master-247-10 ~]# ls
nginx.crt  nginx.key
[root@mh-k8s-master-247-10 ~]# kubectl create secret tls nginx-ssl --key=./nginx.key --cert=./nginx.crt 
secret/nginx-ssl created
[root@mh-k8s-master-247-10 ~]# kubectl get secrets nginx-ssl
NAME        TYPE                DATA   AGE
nginx-ssl   kubernetes.io/tls   2      48s
[root@mh-k8s-master-247-10 ~]# 

2、清单式创建

  Secret 资源是标准的 Kubernetes API 对象,除了标准的 apiVersion、kind 和 metadata 字段,它可用的其他字段具体如下:

    • data <map[string]string>: "key:value" 格式的数据,通常是敏感信息,数据格式需是以 Base64 格式编码的字符串,因此需要用户事先先完成编码。
    • stringData <map[string]string>: 以明文格式(非 Base64 编码)定义的 "key:value" 数据;无须用户事先对数据进行 Base64 编码,而是在创建为 Secret 对象时自动进行编码并保存于 data 字段中,stringData 字段中明文不会被 API Server 输出,不过若是使用 "kubectl apply" 命令进行的创建,那么注解信息中还是可能会直接输出这些信息的。
    • type <string>: 仅是为了便于编程方式处理 Secret 数据而提供的类型标识。

  下面是保存于配置文件 secret-demo.yaml 中的 Secret 资源定义示例,其使用 stringData 提供了明文格式的键值数据,从而免去了事先进行手动编码的麻烦:

apiVersion: v1
kind: Secret
metadata:
  name: secret-demo
stringData:
  username: redis
  password: redis@123
type: Opaque

三、Secret 存储卷

  类似于 Pod 使用 ConfigMap 对象的方式,Secret 对象可以注入为环境变量,也可以存储为卷形式挂载使用。

  一个简单的 demo 示例,示例文件名: secret-volume-pod.yaml 中的 Secret 资源使用示例,它将 nginx-ssl 关联为 Pod 资源的名为 nginxcert 的 Secret 存储卷,而后由容器 web-server 挂载至 /etc/nginx/ssl 目录下:

apiVersion: v1
kind: Pod
metadata:
  name: secret-volume-demo
  namespace: default
spec:
  containers:
  - image: nginx:alpine
    name: nginx-server
    volumeMounts:
	- name: nginxcert
	  mountPath: /etc/nginx/ssl
	  readOnly: true
  volumes:
  - name: nginxcert
    secret:
	  secretName: nginx-ssl

  将上面资源清单文件中定义的资源创建于 Kubernetes 系统上,然后再查看容器挂载点目录中的文件,以确认其挂载是否成功完成。

[root@mh-k8s-master-247-10 ~]# kubectl apply -f secret-volume-pod.yaml 
pod/secret-volume-demo created
[root@mh-k8s-master-247-10 ~]# kubectl exec secret-volume-demo ls /etc/nginx/ssl/
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
tls.crt
tls.key
[root@mh-k8s-master-247-10 ~]# 

  此时,通过 ConfigMap 对象为容器应用 Nginx 提供 HTTPS 虚拟主机配置,它只要使用由 Secret 对象生成的私钥和证书文件,即可定义出容器化运行的 Nginx 服务。

 四、imagePullSecret 资源对象

  imagePullSecret 资源可用于辅助 kubelet 从需要认证的私有镜像仓库获取镜像,它通过将 Secret 提供的密码传递给 kubelet 从而在拉取镜像前完成必要的认证过程。

  使用 imagePullSecret 的方式有两种:

1、创建 docker-registry 类型的 Secret 对象,并在定义 Pod 资源时明确通过 "imagePullSecret" 字段给出。

2、创建 docker-registry 类型的 Secret 对象,将其添加到某特定的 ServiceAccount 对象中,那些使用该 ServiceAccount 资源创建的 Pod 对象,以及默认使用该 ServiceAccount 的 Pod 对象都将会直接使用 imagePullSecrets 中的认证信息。

kubectl create secret docker-registry  local-registry --docker-username=admin --docker-password=admin@123 --docker-email=admin@123.com

  例如:创建一个 secret 对象,名为 harbor,用于 k8s 登录 harbor 拉取镜像的例子:

  Secret 对象资源清单如下:

kind: Secret
apiVersion: v1
metadata:
  name: harbor
  namespace: mh-oms-parent
  annotations:
    kubesphere.io/creator: '81000900'
data:
  .dockerconfigjson: >-
    eyJhdXRocyI6eyJodHRwczovL2hhcmJvci……后面省略
type: kubernetes.io/dockerconfigjson

  在 Kubernetes 系统上创建好后,我们看看:

[root@mh-k8s-master-247-10 ~]# kubectl get secret --all-namespaces|grep harbor
dev-devops7zccn                   harbor                                                credential.devops.kubesphere.io/basic-auth   2      68d
es                                harbor                                                kubernetes.io/dockerconfigjson               1      29d
exxk-lab                          harbor                                                kubernetes.io/dockerconfigjson               1      58d
exxk-labnh7gc                     harbor                                                credential.devops.kubesphere.io/basic-auth   2      58d
mh-oms-parent                     harbor                                                kubernetes.io/dockerconfigjson               1      68d
mh-pdm-parent                     harbor                                                kubernetes.io/dockerconfigjson               1      65d
mh-smc-parent                     harbor                                                kubernetes.io/dockerconfigjson               1      67d
[root@mh-k8s-master-247-10 ~]# kubectl describe secrets harbor -n mh-oms-parent
Name:         harbor
Namespace:    mh-oms-parent
Labels:       <none>
Annotations:  kubesphere.io/creator: 81000900

Type:  kubernetes.io/dockerconfigjson

Data
====
.dockerconfigjson:  141 bytes
[root@mh-k8s-master-247-10 ~]# 

  此类 Secret 对象打印的类型信息为 "kubernetes.io/dockerconfigjson"。上面的配置清单仅是一个示例,大家按照自己实际的情况修改。

-完-

posted @ 2022-06-25 20:24  左扬  阅读(407)  评论(0编辑  收藏  举报
levels of contents