k8s往secret里导入证书_K8s 安全抽象:Secret

本文详细介绍了Kubernetes(K8s)中的Secret,包括Secret的作用、分类及创建方法,如通过字面量、文件和YAML创建generic secret,并展示了如何在Pod中应用Secret作为环境变量、挂载卷和映射目录。此外,还涵盖了如何创建docker-registry secret以拉取私有镜像,以及创建TLS secret以实现SSL通信。
摘要由CSDN通过智能技术生成

# K8s 安全抽象:Secret

> [K8s Secret](https://kubernetes.io/zh/docs/concepts/configuration/secret/)

> [为 Pod 配置服务账户](https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/)

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,包含账户密码两个字段。

```bash

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:

Annotations:

Type: Opaque

Data

====

password: 6 bytes

username: 5 bytes

```

再看看其yaml形态:

```bash

kubectl get secret db-order-secret -o yaml

```

其中字段是base64编码后的值。

```yaml

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`。

```bash

$ echo MTIzNDU2 | base64 --decode

123456

```

### 通过文件创建

在当前目录创建一个RSA 公私钥对作为例子。

```bash

$ 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,公钥可分发给另一方。

```bash

kubectl create secret generic rsa-key-secret --from-file=./id_rsa

```

### 通过yaml创建

通过yaml提供元数据以创建secret,字段需用base64先编码,如: `echo -n admin | base64`。

```yaml

apiVersion: v1

kind: Secret

metadata:

name: db-user-secret

type: Opaque

data:

username: YWRtaW4=

password: MTIzNDU2

```

然后创建Secret即可。

```bash

kubectl apply -f ./secret.yaml

```

### Pod 中应用Secret

下面的例子演示了Secret 的三种应用方式。

* 作为volume直接挂载,在容器中可直接使用

* 在环境变量中使用secret

* 向特定目录映射secret

下面是Pod yaml。

```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验证效果。

* 做环境变量

```yaml

- name: SECRET_USERNAME

valueFrom:

secretKeyRef:

name: db-user-secret

key: username

```

结果如下:

```bash

$ env | grep SECRET_USERNAME

SECRET_USERNAME=admin

```

* 挂载到容器

```yaml

volumeMounts:

- name: volume1

mountPath: "/etc/foo1"

readOnly: true

```

效果如下:

```bash

$ 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

```yaml

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` 中

```bash

$ cat /etc/foo2/usernameFile

admin

```

## 创建 docker-registry secret 拉取镜像

构建、部署时需要拉取镜像,可以向Pod提供一个secret专门用于拉取镜像。

以腾讯云镜像仓库为例,`ccr.ccs.tencentyun.com/easyk8s/nginx` 是一个私有的demo镜像。

利用下面yaml跑一个简单Pod:

```yaml

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` 。

![](https://imgcdn.chenyongjun.vip/2020/03/14/2.png)

接下来创建一个secret专门用于拉取镜像。

```bash

kubectl create secret docker-registry registry-tecent-secret \

--docker-server=ccr.ccs.tencentyun.com \

--docker-username=name \

--docker-password=password

```

在 Pod 中使用 secret。

```yaml

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成功创建。

![](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文件.

```bash

kubectl create secret tls nginx-ssl-secret \

--key=nginx.key \

--cert=nginx.crt

```

下面是 secret 的数据,其类型为:`kubernetes.io/tls`

```bash

$ kubectl describe secret/nginx-ssl-secret

Name: nginx-ssl-secret

Namespace: default

Labels:

Annotations:

Type: kubernetes.io/tls

Data

====

tls.crt: 4241 bytes

tls.key: 1679 bytes

```

在nginx pod 中应用该secret,作为volume映射到容器中。

```yaml

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`。

```bash

$ 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 示意图

![](https://imgcdn.chenyongjun.vip/2020/03/14/5.png)

扫码或搜索 codercyj 关注微信公众号, 结伴学习, 一起努力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值