# 介绍一个小工具：Kubeseal

今天更新 Homebrew 的时候，眼角余光撇到一个 kube 开头的 Formula：kubeseal，名字还挺酷的，`brew home` 看了一下[项目主页](https://github.com/bitnami-labs/sealed-secrets)，还是 [bitnami](https://bitnami.com/) 的作品，就多看了下，发现是一个不明觉厉的工具，本着“来都来了”的乐观精神，写了这一篇不知所云的东西（还发现了个 Issue）。

（可能也许大概差不多）有一种情况，我们需要用 YAML 的形式生成一个 Secret，但是我们希望 YAML 自身的内容是加密的，以保证传输过程中，Secret 自身的内容不会被截获，但是同时这个 YAML 还能用于生成我们需要的 Secret。

Kubeseal 就可以解决这个问题，它在安装时，生成一个 TLS Secret，可以用来对 Secret 进行加密，用 CRD 的方式来进行 Secret 保存，把加密的 CRD YAML 提交到集群，Kubeseal 的服务端控制器会根据 CRD 内容进行解密，生成真正的 Secret。

## 安装

目前 Kubeseal 版本为 v0.8，安装很方便：

~~~shell
# 服务端
$ kubectl apply -f kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.8.0/controller.yaml
# 客户端（Homebrew）
$ brew install kubeseal
...
~~~

安装结束后，在 `kube-system` 命名空间中，生成了 Kubeseal 的控制器，以及用于加解密的 Secret：

~~~shell
$ kubectl get secret,deploy -n kube-system | grep seal
secret/sealed-secrets-controller-token-v4gbx   kubernetes.io/service-account-token   3      6h26m
secret/sealed-secrets-keyb2tvx                 kubernetes.io/tls                     2      6h26m
secret/sealed-secrets-keyhjmbs                 kubernetes.io/tls                     2      21m
deployment.extensions/sealed-secrets-controller   1/1     1            1           6h26m
$ kubectl api-resources| grep seal
sealedsecrets                                    bitnami.com                    true         SealedSecret
~~~

## 创建一个“加密”的 Secret

~~~shell
# 生成 Secret 的 YAML
$ kubectl create secret generic top-secret \
> --dry-run --from-literal=cloud=grass -o json  > mario.json
# 加密
$ cat mario.json | kubeseal > mario-secret.json
~~~

查看新生成的 `mario-secret.json`：

~~~json
{
  "kind": "SealedSecret",
  "apiVersion": "bitnami.com/v1alpha1",
  "metadata": {
    "name": "top-secret",
    "namespace": "default",
    "creationTimestamp": null
  },
  "spec": {
    "template": {
      "metadata": {
        "name": "top-secret",
        "namespace": "default",
        "creationTimestamp": null
      }
    },
    "encryptedData": {
      "cloud": "AgA89tN49OyoDn/19+QF4Qi7w5aq5v71Xvkzu9cA6mzF/QoDInq3xWnPHl6tt93yurZC0WY+XhlLYVHss3nfrkNtdR8+GSQioTiCRiy1oXnWW3ku37eJGbe7sbd3qIm/uoR/Q3Bvg138zhYfApdeI2T1ePfjDGOsqRRhwhYY5RHAJUsbCC1H0+EO/j/Cg/DmAheFbJHgHtVnHz0eEC6JOrFtLr5YpKXEgEnDIyULoj+TtGL5VXpDzDXwf5OZNvKLgOHl80WwmJWDeyjbbE0RGoPW7rcCyOwlMe/ywRaKgJqpgEm0n/v+3Wb87kd5du8cRsFWKc1ObK4UL0Gq4FMDNXI3m1rBFkeq7AEFiyKSkqlMnPQSOslMcq10hfEmUeOqiJE/GejUlvnhyix9zit83LNlzYxgWMRav+b5CI3PbxpFxAN6r+p+wfKmAMLMh7sfGsYbj5i1vvFbztCrFlGy5UzDBV4tz58mAjDUduyHAzSHkSXHTtMo5YFMk/awonpuUIbQVtGdfyLLqQlyvkcOIdCPVFiMSbRkr0ySPFXDilQp61VtY1002bu5kM6y30fKMSBhjY3ZCes6cz8RpytVszCF8fWDcJSDfI6eGBbgKkRNtm4CPRn6QZA5etgPJxry0PyCZCAmnhfcDodeZgy+bPbR4+G1YoxGq3UaTUhsf6R/nT/rvccphnIr/VrSd+/P9XgY4kZPnw=="
    }
  },
  "status": {

  }
}
~~~

把这个文件提交到集群，并查看生成的 Secret：

~~~shell
# 看看是否生成了 secret
$ kubectl get secrets
NAME                  TYPE                                  DATA   AGE
...
top-secret            Opaque                                1      6s
# 查看 top-secret 内容
$ kubectl view-secret top-secret cloud
grass
~~~

## 备份、恢复和轮转

前面提到，Kubeseal 安装过程中除了生成 Deployment 之外，还生成了一个 Secret，仔细观察会看到这个 Secret 带有一个标签：`sealedsecrets.bitnami.com/sealed-secrets-key=active`，代表这个 Secret 是正用于加密的。只要把这个 Secret 进行备份，或者复制到其它集群上，就可以用同样的密钥进行加密了。
如果把这个标签值修改为 `compromised`，就代表这一密钥已经过期。

对 Secret 进行上述的修改之后，可以删除控制器 Pod，以便生成并启用新的密钥，当然，过去生成的加密内容也不再有效，需要重新进行加密。

## 结论

看都看了，万一有人有用呢。。。。
