14.实践篇:Secret资源深度剖析

14.实践篇:Secret资源深度剖析

2020-02-07 14:17:01

Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。

1.What is Secret?

        kubernetes的secret对象可以让你存储和管理敏感信息,如密码、oauth token和ssh keys。把这些信息配置到secret里面会比在pod spec中定义更安全和灵活。
如果有兴趣,你还可以参考阅读secret的设计目的(https://git.k8s.io/community/contributors/design-proposals/auth/secrets.md)。

2.如何创建一个Secret

你同样可以采用命令行和yaml配置文件的方式,来创建一个secret。

2.1.命令行方式

kubectl create secret [TYPE] [NAME] [DATA]

你需要注意secret资源有以下三种[TYPE]类型:

1>docker-registry:创建一个给Docker registry容器镜像仓库使用的secret
2>generic: 从本地file, directory或者literal value创建一个 secret(这是大多数情况使用的)
3>tls: 创建一个TLS secret

[DATA]和我们上一节将configmap一样,也可以细分为--from-literal和--from-file

2.2.yaml配置文件方式

apiVersion: v1
kind: Secret
type: Opaque
data:
  username: YWRtaW4=
stringData:
  username: administrator

以上就是secret定义的核心配置,你需要额外注意的是type字段,其值为Opaque,对应我们上面提及的generic类型

Opaque:base64编码格式的Secret,用来存储密码、密钥等;

你可以通过以下命令进行secret配置字段的查看

kubectl explain secret

3.通过生成器创建一个Secret

除了命令行和yaml方式创建之外,从v1.14版本开始,kubectl支持通过使用Kustomize来管理对象,你同样可以使用他的generators来创建一个secret,并且在apiserver上将其运行起来。

1)首先,generators需要配置一个kustomization.yaml文件,对于上面的例子,我们可以这样来申明:

# Create a kustomization.yaml file with SecretGenerator
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: db-user-pass
  files:
  - username.txt
  - password.txt
EOF

2)如果你没有相关的txt文件,别忘了生成一份

[root@centos-1 tmp]# kubectl apply -k .
secret/db-user-pass-96mffmfh4k created

3)接着,我们使用-k参数来申明

[root@centos-1 tmp]# kubectl apply -k .secret/db-user-pass-96mffmfh4k created

4)此时你可以看到如下信息的secret:

[root@centos-1 tmp]# kubectl get secrets
NAME                      TYPE                                  DATA   AGE
db-user-pass-96mffmfh4k   Opaque                                2      47s
default-token-4fl6p       kubernetes.io/service-account-token   3      39d
[root@centos-1 tmp]# kubectl describe secrets/db-user-pass-96mffmfh4k
Name:         db-user-pass-96mffmfh4k
Namespace:    default
Labels:       <none>
Annotations:  
Type:         Opaque

Data
====
password.txt:  12 bytes
username.txt:  5 bytes

5)你也可以通过kustomize来申明一个literals的类型:

 cat <<EOF >./kustomization.yaml
secretGenerator:
- name: db-user-pass
  literals:
  - username=admin
  - password=secret
EOF

[root@centos-1 tmp]# kubectl apply -k .
secret/db-user-pass-4mf9kckdb5 created

注意:secret名是根据文本内容hash计算出来的,这得以保证每次可以得到一个修改后的文本内容

4.编辑一个Secret

你同样可以使用edit命令编辑一个secret,里面的信息修改后保存即可:

kubectl edit secrets mysecret

5.申明对照表

虽然我们上面提到,secret也可以通过--from-literal和--from-file来申明,但是对于三种不同类型[TYPE]的secret,还是有一些区分的,具体参见下面的表格:

TYPE类型 申明方式
docker-registry --docker-username,--docker-password,--docker-email
generic --from-literal和--from-file
tls --cert--key

6.如何使用一个Secret

secret的使用也是会因为使用类型不同而不同的,下面我会有一个详细的explain API的表格,可以帮助你更好地学习:

TYPE类型 使用方式
docker-registry spec.imagePullSecrets <[]Object>
docker-registry ServiceAccount
generic和tls spec.containers.env.valueFrom.secretKeyRef
generic和tls spec.containers.envFrom.secretRef
generic和tls spec.volumes.secret.secretName/items

注意:通过使用 kubectl explain <使用方式>就可以查到对应的配置字段的要求了。

理论部分已经讲完,接下来我们将以generic类型进行实战讲解

secret资源同样提供了以env和volume的两种方式进行载入,我们来看一下吧

7.实战:以环境变量方式载入Secret

1) 首先,创建所需的文本文件username.txt和password.txt

echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt

2) 创建generic类型的secret,名字为db-user-pass,并从刚才的两个文件中载入

kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt

3) 观察secret情况,观察相关信息是否被成功载入

[root@centos-1 mainfasts]# kubectl get secrets/db-user-pass -o yaml
apiVersion: v1
data:
  password.txt: MWYyZDFlMmU2N2Rm
  username.txt: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: "2019-12-05T07:39:02Z"
  name: db-user-pass
  namespace: default
  resourceVersion: "10014"
  selfLink: /api/v1/namespaces/default/secrets/db-user-pass
  uid: 6b15c821-5975-405f-9144-0c1fbaa1e341
type: Opaque

注意:secret中的信息是通过base64进行编码的

4) 我们可以尝试使用base64解码配置文件中的对应信息,来验证上面的说法是否正确

[root@centos-1 mainfasts]# echo YWRtaW4=|base64 -d
admin
[root@centos-1 mainfasts]# echo MWYyZDFlMmU2N2Rm|base64 -d
1f2d1e2e67df

5) 接着,编辑redis-secretenv-demo.yaml,让他读取我们创建的名为db-user-pass的secret,并且将变量名username.txt的值赋值给SECRET_USERNAME的环境变量,以及password.txt赋值给SECRET_PASSWORD。别忘了使用apply -f生效这个配置文件。

apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: mycontainer
    image: redis
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: db-user-pass
            key: username.txt
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: db-user-pass
            key: password.txt
  restartPolicy: Never

6) 随后,进入Pod的交互式接口模式,观察secret变量载入情况。
你可以发现我们传递的变量已经成功读取到了。

[root@centos-1 secret]# kubectl exec -it secret-env-pod -- /bin/sh
# printenv
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=secret-env-pod
REDIS_DOWNLOAD_SHA=61db74eabf6801f057fd24b590232f2f337d422280fd19486eca03be87d3a82b
HOME=/root
SECRET_PASSWORD=1f2d1e2e67df
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
SECRET_USERNAME=admin
REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-5.0.7.tar.gz
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
REDIS_VERSION=5.0.7
GOSU_VERSION=1.11
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/data

8.实战:以存储卷方式载入Secret

1) 我们重新编辑redis-secretfiles-volumes,新增一个secret类型的volumes叫做secret-volume,我们把他挂载到pod容器的"/etc/secret-volume"目录,并且期望变量名改为username,而不是username.txt。

apiVersion: v1
kind: Pod
metadata:
  name: secret-dotfiles-pod
spec:
  volumes:
  - name: secret-volume
    secret:
      secretName: db-user-pass
      items:
      - key: username.txt                  #secrets中key的名字
        path: username                     #希望映射在Pod中的名字
      - key: password.txt
        path: password
  containers:
  - name: dotfile-test-container
    image: redis
    volumeMounts:
    - name: secret-volume
      readOnly: true
      mountPath: "/etc/secret-volume"

2) apply -f之后,我们还是进入pod的交互式接口模式,发现/etc/secret-volume中已经生成对应的配置文件。并且文件名也已经成功替换映射过来了,是username而不是username.txt。

[root@centos-1 secret]# kubectl exec -it secret-dotfiles-pod -- /bin/sh
# cd /etc/secret-volume
# ls
password  username
# cat password
1f2d1e2e67df
# cat username
admin#

@版权声明:51CTO独家出品,未经允许不能转载,否则追究法律责任


版权声明:
作者:WaterBear
链接:https://l-t.top/2050.html
来源:雷霆运维
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录