一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
一、前言
ConfigMap
传递敏感数据,就需要Secret
。
Secret
对象可以存储和管理敏感信息,比如passwords
、OAuth tokens
、以及ssh keys
等。把敏感信息存储到Secret
对象中会比放到Pod
的定义文件或是容器镜像中更加安全、灵活,使用Secret
对象可以更好的控制数据的使用方式,并且减少意外泄露的风险。
不仅用户可以创建 Secret
对象,kubernetes
系统也会创建一些 Secret
对象。
二、使用
在 Pod
的容器中,Secrets
可以被挂载成为数据卷或是引用为环境变量来使用。 另外还可以在私有仓库 Docker
镜像拉取时配置进行使用。
Secrets
作为数据卷Secrets
作为环境变量- 镜像拉取时配置
(1)Secrets
作为数据卷
通常将 Secret
作为挂载卷在 Pod
中使用的步骤如下:
- 创建一个
Secret
或是使用已经存在的Secret
。通常多个 Pods 会使用同一个 Secret。 - 修改
Pod YAML
文件定义,使用字段.spec.volumes[]
挂载卷,卷的名称可以任意命名,在字段.spec.volumes[].secret.secretName
中填写需要挂载的 Secret 对象的名称。 - 在每个需要 Secret 的容器中添加字段
.spec.containers[].volumeMounts[]
。规定.spec.containers[].volumeMounts[].readOnly = true
以及字段.spec.containers[].volumeMounts[].mountPath
表示将 Secret 挂载到某个未使用过的目录下。 - 修改镜像或是命令行以便程序可以在对应的目录下找到需要的文件。Secret
data
字段下的每个 key 都会被用作挂载目录下的文件名。
新建文件 mysecret-pod.yaml
,这个 YAML 文件定义了将 mysecret 挂载到容器中的 /etc/foo
目录下:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
执行创建并进入到容器中查看:
$ kubectl exec -it mypod -- bash
root@mypod:/data# cd /etc/foo
root@mypod:/etc/foo# ls
password username
root@mypod:/etc/foo# cat username
admin
root@mypod:/etc/foo# cat password
1f2d1e2e67dfroot
如果想要指定挂载的文件名可以使用 items
和 path
字段,将上面的定义修改为:
# 将 username secret 的值存储到 /etc/foo/my-group/my-username 文件中,同时 username secret 不会被使用到
......
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
(2)Secrets
作为环境变量
在 Pod 中使用 Secret 作为环境变量的步骤如下:
- 创建一个 Secret 或是使用已经存在的 Secret。通常多个 Pods 会使用同一个 Secret。
- 修改 Pod YAML 文件,在每个容器中添加环境变量引用需要的 Secret 的值,使用字段
env[].valueFrom.secretKeyRef
。 - 修改镜像或是命令行以便程序可以通过环境变量找到需要的值。
创建 YAML 文件 secret-env-pod.yaml
,从环境变量中使用 Secret:
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
执行创建并进入容器检查环境变量:
$ kubectl exec -it secret-env-pod -- bash
root@secret-env-pod:/data# echo $SECRET_USERNAME
admin
root@secret-env-pod:/data# echo $SECRET_PASSWORD
1f2d1e2e67df
(3)镜像拉取时配置
当我们需要从某个私有仓库拉取镜像时,可以使用 Secret 存储私有仓库的密码并借助 kubelet 传递密码,具体定义时通过指定 Pod 的字段 spc.ImagePullSecrets
来引用它。
这里有两个步骤:
- 创建包含 Docker 镜像仓库证书的 Secret
- 在 Pod 定义中使用字段 ImagePullSecrets 引用该 Secret
需要在 Docker Hub 上创建一个账号,使用该账号创建一个私有仓库。
使用如下命令创建用于 Docker 镜像仓库鉴权的 Secret:
# 这里的 xxxx 替换为你们自己的账号信息
kubectl create secret docker-registry mydockerhubsecret --docker-username=xxxx --docker-password=xxxx --docker-email=xxxx
查看详细信息:
$ kubectl get secret mydockerhubsecret -o yaml
可以看到 mydockerhubsecret Secret 有一个隐藏的 .dockerconfigjson 文件,这个文件就是用于帮助验证的。
然后在创建 Pod 的时候引用这个 mydockerhubsecret:
apiVersion: v1
kind: Pod
metadata:
name: private-pod
spec:
imagePullSecrets:
- name: mydockerhubsecret
containers:
- image: username/private:tag # 这里根据你的实际情况添加私有仓库的镜像名
name: main
restartPolicy: Never