应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥。将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 Secret。
Secret 会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息。Secret 会以 Volume 的形式被 mount 到 Pod,容器可通过文件的方式使用 Secret 中的敏感数据;此外,容器也可以环境变量的方式使用这些数据。
Secret 可通过命令行或 YAML 创建。比如希望 Secret 中包含如下信息:
-
用户名
admin
-
密码
123456
1.创建 Secret方式
有四种方法创建 Secret:
1.1 通过 --from-literal
:
kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
每个 --from-literal
对应一个信息条目。
1.2 通过 --from-file
:
echo -n admin > ./username echo -n 123456 > ./password kubectl create secret generic mysecret --from-file=./username --from-file=./password
每个文件内容对应一个信息条目。
1.3通过 --from-env-file
:
cat << EOF > env.txt username=admin password=123456 EOF kubectl create secret generic mysecret --from-env-file=env.txt
文件 env.txt
中每行 Key=Value 对应一个信息条目。
1.4通过 YAML 配置文件:
文件中的敏感数据必须是通过 base64 编码后的结果。
执行 kubectl apply
创建 Secret:
2.查看secret
2.1通过 kubectl get secret
查看存在的 secret
显示有两个数据条目
2.2通过kubectl describe secret
查看条目的 Key
2.3通过kubectl edit secret mysecret 查看vlaue
2.4通过base64将value反解码
3.vloume方式secret的使用
Pod 可以通过 Volume 或者环境变量的方式使用 Secret,先学习 Volume 方式。
Pod 的配置文件如下所示:
① 定义 volume foo
,来源为 secret mysecret
。
② 将 foo
mount 到容器路径 /etc/foo
,可指定读写权限为 readOnly
。
创建 Pod 并在容器中读取 Secret:
可以看到,Kubernetes 会在指定的路径 /etc/foo
下为每条敏感数据创建一个文件,文件名就是数据条目的 Key,这里是 /etc/foo/username
和 /etc/foo/password
,Value 则以明文存放在文件中。
我们也可以自定义存放数据的文件名,比如将配置文件改为:
这时数据将分别存放在 /etc/foo/my-group/my-username
和 /etc/foo/my-group/my-password
中。
以 Volume 方式使用的 Secret 支持动态更新:Secret 更新后,容器中的数据也会更新。
将 password 更新为 abcdef
,base64 编码为 YWJjZGVm
4.环境变量中使用secret
通过 Volume 使用 Secret,容器必须从文件读取数据,会稍显麻烦,Kubernetes 还支持通过环境变量使用 Secre
创建 Pod 并读取 Secret。
通过环境变量 SECRET_USERNAME
和 SECRET_PASSWORD
成功读取到 Secret 的数据。
需要注意的是,环境变量读取 Secret 很方便,但无法支撑 Secret 动态更新。
Secret 可以为 Pod 提供密码、Token、私钥等敏感数据;对于一些非敏感数据,比如应用的配置信息,则可以用 ConfigMap
一、启动应用安全信息的保护:
Secret介绍:
- 用户名
admin
- 密码
123456
创建 Secret
1. 通过 --from-literal
:
[root@cicd ~]# kubectl get secret
NAME TYPE DATA AGE
default-token-g44kp kubernetes.io/service-account-token 3 3d
mysecret Opaque 2 9s
--from-literal
对应一个信息条目。2. 通过 --from-file
:
[root@cicd yml]# cat username
admin[root@cicd yml]# cat password
123[root@cicd yml]#
3. 通过 --from-env-file
:
env.txt
中每行 Key=Value 对应一个信息条目。4. 通过 YAML 配置文件:
echo -n admin | base64
YWRtaW4=
echo -n 123 | base64
YWJj
然后编写以下文件,添加关键参数。
[root@cicd yml]# cat secret.yml
apiVersion: v1
kind: Secret
metadata:
name: yoursecret
data:
username: YWRtaW4=
password: YWJj
data的数据以key:value的形式写入。
kubectl apply
创建 Secret[root@cicd yml]# echo -n YWRtaW4=| base64 --decode #-n 不换行
admin[root@cicd yml]# echo -n YWJj | base64 --decode
abc[root@cicd yml]#
二、secret在pod中的应用:
volume 方式使用 Secret
创建 Pod 并在容器中读取 Secret:
[root@cicd yml]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mypod-c3 1/1 Running 3 2h
mypod-c4 1/1 Running 2 1h
mypod3 0/1 ContainerCreating 0 42s
可以看到mypod3正在创建,这一状态的原因有2;
一是因为延迟,等会就行
二是因为报错,执行
[root@cicd yml]# kubectl describe pod mypod3
进入mypod3查看详细状态信息,如果报错根据报错做出反应。
创建完后,我们进入mypod3验证:
[root@cicd yml]# kubectl exec -it mypod3 sh
error: unable to upgrade connection: container not found ("mypod")
如果报此错,则是因为创建的pod不成功,即error或者正在创建中。
[root@cicd yml]# echo -n mdzz | base64
bWR6eg==
重新执行secret.yml文件
sh: getcwd: No such file or directory
这是因为改变的密码正在生效,重新进入/etc/foo发现新的 password 已经同步好了。
/etc/foo/..2019_06_24_09_42_04.419998613/my-group # cat my-password mdzz/etc/foo/..2019_06_24_09_42_04.419998613/my-group #
环境变量方式使用 Secret
注意上图里的key:username和key:password是对应secret.yml文件里的
所以一定要注意书写,不然是无法通过环境变量方式使用secret的。
pod "mypod5" created
[root@cicd yml]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mypod5 1/1 Running 0 56s
[root@cicd yml]# kubectl exec-it mypod5 sh
/ # echo $SECRET_USERNAME
admin
/ # echo $SECRET_PASSWORD
mdzz