第十八章 kubernetes 核心技术-Secret


一、Secret概述

Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 Pod 规约中或者镜像中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。

由于创建 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防措施, 例如避免将机密数据写入非易失性存储。

Secret 类似于 ConfigMap 但专门用于保存机密数据。

二、Secret作用

Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用.

默认情况下,Kubernetes Secret 未加密地存储在 API 服务器的底层数据存储(etcd)中。 任何拥有 API 访问权限的人都可以检索或修改 Secret,任何有权访问 etcd 的人也可以。 此外,任何有权限在命名空间中创建 Pod 的人都可以使用该访问权限读取该命名空间中的任何 Secret; 这包括间接访问,例如创建 Deployment 的能力。

为了安全地使用 Secret,请至少执行以下步骤:
1)为 Secret 启用静态加密;
2)启用或配置 RBAC 规则来限制读取 Secret 的数据(包括通过间接方式)。
3)在适当的情况下,还可以使用 RBAC 等机制来限制允许哪些主体创建新 Secret 或替换现有 Secret。

三、Secret概览

要使用 Secret,Pod 需要引用 Secret。 Pod 可以用三种方式之一来使用 Secret:

1)作为挂载到一个或多个容器上的 卷 中的文件。
2)作为容器的环境变量
3)由 kubelet 在为 Pod 拉取镜像时使用

Kubernetes 控制平面也使用 Secret; 例如,引导令牌 Secret 是一种帮助自动化节点注册的机制。

Secret 对象的名称必须是合法的 DNS 子域名。 在为创建 Secret 编写配置文件时,你可以设置 data 与/或 stringData 字段。 data 和 stringData 字段都是可选的。data 字段中所有键值都必须是 base64 编码的字符串。如果不希望执行这种 base64 字符串的转换操作,你可以选择设置 stringData 字段,其中可以使用任何字符串作为其取值。

四、Secret 的类型

创建 Secret 时,你可以使用 Secret 资源的 type 字段, 或者与其等价的 kubectl 命令行参数(如果有的话)为其设置类型。 Secret 的 type 有助于对不同类型机密数据的编程处理。

Kubernetes 提供若干种内置的类型,用于一些常见的使用场景。 针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。
?Service Account :用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的/run/secrets/kubernetes.io/serviceaccount 目录中
?Opaque : base64 编码格式的 Secret,用来存储密码、密钥等
?kubernetes.io/dockerconfigjson :用来存储私有 docker registry 的认证信息
内置类型 用法
Opaque 用户定义的任意数据
kubernetes.io/service-account-token 服务账号令牌
kubernetes.io/dockercfg ~/.dockercfg 文件的序列化形式
kubernetes.io/dockerconfigjson ~/.docker/config.json 文件的序列化形式
kubernetes.io/basic-auth 用于基本身份认证的凭据
kubernetes.io/ssh-auth 用于 SSH 身份认证的凭据
kubernetes.io/tls 用于 TLS 客户端或者服务器端的数据
bootstrap.kubernetes.io/token 启动引导令牌数据
通过为 Secret 对象的 type 字段设置一个非空的字符串值,你也可以定义并使用自己 Secret 类型。如果 type 值为空字符串,则被视为 Opaque 类型。 Kubernetes 并不对类型的名称作任何限制。不过,如果你要使用内置类型之一, 则你必须满足为该类型所定义的所有要求。、

五、Service Account示例

Service Account 用来访问 Kubernetes API,甶 Kubernetes 自动创建,并且会自动挂载到Pod 的/run/secrets/kubernetes.io/serviceaccount 目录中

[root@kubernetes-master-001 ~]# kubectl  run nginx --image nginx
pod/nginx created

[root@kubernetes-master-001 ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
nginx                  1/1     Running   0          25s

[root@kubernetes-master-001 ~]# kubectl exec nginx  ls /run/secrets/kubernetes.io/serviceaccount 
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
ca.crt
namespace
token

六、Opaque Secret示例

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

1.Secret 变量形式挂载Pod示例

1)创建Secret加密数据

[root@kubernetes-master-001 ~]# echo -n 'admin' |base64
YWRtaW4=
[root@kubernetes-master-001 ~]# echo -n 'Jinhuino1' |base64
SmluaHVpbm8x
[root@kubernetes-master-001 ~]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: SmluaHVpbm8x

2)部署Secret

#1.部署Secret
[root@kubernetes-master-001 ~]# kubectl create -f secret.yaml 
secret/mysecret created

#2.查看Secret
[root@kubernetes-master-001 ~]# kubectl  get secret
NAME                  TYPE                                  DATA   AGE
default-token-668jw   kubernetes.io/service-account-token   3      4d3h
mysecret              Opaque                                2      14s

3)编写Pod文件

#1.编写Pod文件
[root@kubernetes-master-001 ~]# vim secret-val.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password

4)部署Pod

[root@kubernetes-master-001 ~]# kubectl  apply  -f secret-val.yaml 
pod/mypod created

[root@kubernetes-master-001 ~]# kubectl  get pods
NAME                   READY   STATUS    RESTARTS   AGE
ds-test-7krrv          1/1     Running   0          24h
ds-test-jnxzm          1/1     Running   0          24h
mypod                  1/1     Running   0          44s
web-5bb6fd4c98-54ll2   1/1     Running   0          3d1h
web-5bb6fd4c98-585rn   1/1     Running   0          3d1h

5)验证Secret

[root@kubernetes-master-001 ~]# kubectl  exec -it mypod bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mypod:/# echo $SECRET_USERNAME
admin
root@mypod:/# echo $SECRET_PASSWORD
Jinhuino1

2.Secret 以卷挂载pod容器示例

1)删除原有的pod

[root@kubernetes-master-001 ~]# kubectl delete -f secret-val.yaml 
pod "mypod" deleted

2)编写Pod文件

#1.编写Pod文件
[root@kubernetes-master-001 ~]# vim secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

3)部署Pod

[root@kubernetes-master-001 ~]# kubectl  apply -f  secret-volume.yaml 
pod/mypod created

[root@kubernetes-master-001 ~]# kubectl  get pods
NAME    READY   STATUS    RESTARTS   AGE
mypod   1/1     Running   0          54s

4)验证Secret

[root@kubernetes-master-001 ~]# kubectl  exec -it mypod bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mypod:/# cd /etc/foo
root@mypod:/etc/foo# ls
password  username

root@mypod:/etc/foo# cat password 
Jinhuino1root@mypod:/etc/foo# cat username 
adminroot@mypod:/etc/foo#

七、dockerconfigjson示例

用来存储私有docker registry的认证信息。

1.创建secret

[root@kubernetes-master-001 ~]# export DOCKER_REGISTRY_SERVER=10.0.0.100
[root@kubernetes-master-001 ~]# export DOCKER_USER=root
[root@kubernetes-master-001 ~]# export DOCKER_PASSWORD=root@123
[root@kubernetes-master-001 ~]# export DOCKER_EMAIL=root@123.com
[root@kubernetes-master-001 ~]# kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret/myregistrykey created

2.查看secret

[root@kubernetes-master-001 ~]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-668jw   kubernetes.io/service-account-token   3      7d21h
myregistrykey         kubernetes.io/dockerconfigjson        1      52s
mysecret              Opaque                                2      3d17h

[root@kubernetes-master-001 ~]# kubectl  describe secrets  myregistrykey
Name:         myregistrykey
Namespace:    default
Labels:       
Annotations:  

Type:  kubernetes.io/dockerconfigjson

Data
====
.dockerconfigjson:  161 bytes

3.创建测试secret

[root@kubernetes-master-001 ~]# vim secret-docker.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: mysecret
spec:
  selector:
    matchLabels:
      app: mysecret
  template:
    metadata:
      labels:
        app: mysecret
    spec:
      containers:
        - name: nginx
      imagePullSecrets:
        - name: myregistrykey

相关