K8s 安全抽象:Secret
欢迎访问博客原文Secret 是对敏感信息的抽象,例如:密码、token、SSH key,其他对象可引用Secret。Pod 使用 Secret 有两种场景:作为 volume 中的文件被挂载到 Pod 中一个或多个容器中拉取镜像时需要使用 secret 作为安全凭证Secret 分类Secret 可分为三类:docker-registry:创建一个给 Docker R...
欢迎访问博客原文
Secret 是对敏感信息的抽象,例如:密码、token、SSH key,其他对象可引用Secret。
Pod 使用 Secret 有两种场景:
- 作为 volume 中的文件被挂载到 Pod 中一个或多个容器中
- 拉取镜像时需要使用 secret 作为安全凭证
Secret 分类
Secret 可分为三类:
- docker-registry: 创建一个给 Docker Registry 使用的 secret,实际是保存了账户密码。
- generic:从本地 file, directory 或者 literal value 创建一个 secret。
- tls:创建一个 TLS secret。
创建 generic secret
通过 literal(字面量)创建
创建一个order数据库的secret,包含账户密码两个字段。
kubectl create secret generic db-order-secret --from-literal=username=admin --from-literal=password=123456
literal 中若包含特殊字符则需要进行转义,如"123456!" 需设置为 “123456\!”
查看secret,describe secret db-order-secret
,查看时隐藏了字段值,仅展示了字节数。
对应的API对象为 Opaque([oʊˈpeɪk]),译为"不透明物",等同于"敏感数据"。
Name: db-order-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 6 bytes
username: 5 bytes
再看看其yaml形态:
kubectl get secret db-order-secret -o yaml
其中字段是base64编码后的值。
apiVersion: v1
data:
password: MTIzNDU2
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2020-03-14T04:21:29Z"
name: db-order-secret
namespace: default
resourceVersion: "28023453"
selfLink: /api/v1/namespaces/default/secrets/db-order-secret
uid: 5c60f906-ec8e-4277-8b96-caa75ef6589a
type: Opaque
解码password字段,值为123456
。
$ echo MTIzNDU2 | base64 --decode
123456
通过文件创建
在当前目录创建一个RSA 公私钥对作为例子。
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): ./id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./id_rsa.
Your public key has been saved in ./id_rsa.pub.
将私钥创建为secret,公钥可分发给另一方。
kubectl create secret generic rsa-key-secret --from-file=./id_rsa
通过yaml创建
通过yaml提供元数据以创建secret,字段需用base64先编码,如: echo -n admin | base64
。
apiVersion: v1
kind: Secret
metadata:
name: db-user-secret
type: Opaque
data:
username: YWRtaW4=
password: MTIzNDU2
然后创建Secret即可。
kubectl apply -f ./secret.yaml
Pod 中应用Secret
下面的例子演示了Secret 的三种应用方式。
- 作为volume直接挂载,在容器中可直接使用
- 在环境变量中使用secret
- 向特定目录映射secret
下面是Pod yaml。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: nginx
env:
- name: SECRET_USERNAME
# 使用secret 做环境变量
valueFrom:
secretKeyRef:
name: db-user-secret
key: username
volumeMounts:
# 将secret作为volume挂载
- name: volume1
mountPath: "/etc/foo1"
readOnly: true
# 向特定目录映射secret
- name: volume2
mountPath: "/etc/foo2"
readOnly: true
volumes:
- name: volume1
secret:
secretName: db-user-secret
- name: volume2
secret:
secretName: db-user-secret
items:
- key: username
path: usernameFile
创建Pod,然后进入Pod验证效果。
- 做环境变量
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: db-user-secret
key: username
结果如下:
$ env | grep SECRET_USERNAME
SECRET_USERNAME=admin
- 挂载到容器
volumeMounts:
- name: volume1
mountPath: "/etc/foo1"
readOnly: true
效果如下:
$ ls -l /etc/foo1
total 0
lrwxrwxrwx 1 root root 15 Mar 14 07:49 password -> ..data/password
lrwxrwxrwx 1 root root 15 Mar 14 07:49 username -> ..data/username
- 向特定目录映射secret
spec:
volumeMounts:
- name: volume2
mountPath: "/etc/foo2"
readOnly: true
volumes:
- name: volume2
secret:
secretName: db-user-secret
items:
- key: username
path: usernameFile
将 username 字段映射到了 /etc/foo2/usernameFile
中
$ cat /etc/foo2/usernameFile
admin
创建 docker-registry secret 拉取镜像
构建、部署时需要拉取镜像,可以向Pod提供一个secret专门用于拉取镜像。
以腾讯云镜像仓库为例,ccr.ccs.tencentyun.com/easyk8s/nginx
是一个私有的demo镜像。
利用下面yaml跑一个简单Pod:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: ccr.ccs.tencentyun.com/easyk8s/nginx:1.17
运行后Pod Event如下,出现 Error: ErrImagePull
。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aCIiPd6t-1584194450616)(https://imgcdn.chenyongjun.vip/2020/03/14/2.png)]
接下来创建一个secret专门用于拉取镜像。
kubectl create secret docker-registry registry-tecent-secret \
--docker-server=ccr.ccs.tencentyun.com \
--docker-username=name \
--docker-password=password
在 Pod 中使用 secret。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: ccr.ccs.tencentyun.com/easyk8s/nginx:1.17
imagePullSecrets:
- name: registry-tecent-secret
应用yaml后Pod成功创建。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F28N8FX3-1584194450617)(https://imgcdn.chenyongjun.vip/2020/03/14/3.png)]
通过kubectl get secret registry-tecent-secret -o yaml
拿到的 registry-tecent-secret
的yaml结构如下:
apiVersion: v1
data:
.dockerconfigjson: eyJhdXR...
kind: Secret
metadata:
creationTimestamp: "2020-03-14T05:01:04Z"
name: registry-tecent-secret
namespace: default
resourceVersion: "28027921"
selfLink: /api/v1/namespaces/default/secrets/registry-tecent-secret
uid: a05ae3c0-b504-448b-bc78-8c540b2dda6c
type: kubernetes.io/dockerconfigjson
其中 .dockerconfigjson 通过base64解码后可以拿到docker-registry的账户密码。
创建tls secret
存储用于SSL通讯的私钥文件和证书文件,下面以nginx为例子。
预先准备好nginx ssl 通讯所需的key和crt文件.
kubectl create secret tls nginx-ssl-secret \
--key=nginx.key \
--cert=nginx.crt
下面是 secret 的数据,其类型为:kubernetes.io/tls
$ kubectl describe secret/nginx-ssl-secret
Name: nginx-ssl-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.crt: 4241 bytes
tls.key: 1679 bytes
在nginx pod 中应用该secret,作为volume映射到容器中。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: nginx-crt
mountPath: /etc/nginx/ssl
readOnly: true
volumes:
- name: nginx-crt
secret:
secretName: nginx-ssl-secret
运行Pod后进入Pod查看 /etc/nginx/ssl
目录,可看到映射的证书、私钥文件,不过名字从 nginx.crt, nginx.key
变为了 tls.crt, tls.key
。
$ ls -l /etc/nginx/ssl/
total 0
lrwxrwxrwx 1 root root 14 Mar 14 08:42 tls.crt -> ..data/tls.crt
lrwxrwxrwx 1 root root 14 Mar 14 08:42 tls.key -> ..data/tls.key
接着可以在nginx配置中使用这两个文件完成ssl通讯配置。
常用 Secret 示意图
欢迎关注公众号 [陈一乐],一起学习,一起成长
更多推荐
所有评论(0)