# Community UK8s

该 K8s 为 UCloud 托管集群, 我们在这个目录下存储了服务的配置文件.

- `manual` 目录下以每个 namespace 为子目录, 每项服务都采取 all-in-one 的方式储存配置，即在一个 yaml 里包含单个应用的所有相关信息(Ingress 配置除外). 这里的配置需要管理员手动部署.
- `fluxcd` 目录为 [fluxcd](https://fluxcd.io) 的配置文件, fluxcd 会将 git 仓库中最新的配置自动部署到 K8s 中.
- `image-updater` 是 fluxcd 的辅助服务, 它允许服务开发者通过 HTTP 请求来更新 github 仓库中的镜像版本, [文档](image-updater/README.md).

## Fluxcd 介绍

[Flux](https://fluxcd.io) 是一套使用 Git 来管理 K8s 服务配置的 CD(持续部署) 工具 (GitOps), 我们将服务配置存储在 `pingcap-inc/sre` 仓库中, flux 会通过定时拉取或者 github webhook 的方式来获取仓库中的最新配置, 然后更新 K8s 中的服务.

所以当开发者要更新服务配置或者版本的时候, 只需要提交 Pull Request 来更新 `fluxcd` 目录下的配置即可, 为了方便大家在 CI/CD 脚本中更新镜像版本, 我们提供了 [`image-updater`](image-updater/README.md) 服务, 它允许服务开发者通过 HTTP 请求来更新 github 仓库中的镜像版本.

### 不太优雅的地方

- configmap 和 secret 更改后无法自动应用到服务中, 需要手动重启 pod, 但你可以通过给 configmap 添加版本号后缀的方式或者给 deployment 添加注释的方式来绕过.

## 秘钥的存储和使用方式

为了保护秘钥安全, 我们在 Git 仓库中对秘钥进行了加密存储, 使用了 [sealed-secrets](https://github.com/bitnami-labs/sealed-secrets) 的解决方案, 它的中文介绍可以参考该文档: [《使用 Sealed Secrets 在 Kubernetes 中管理密钥部署》](https://aws.amazon.com/cn/blogs/china/managing-secrets-deployment-in-kubernetes-using-sealed-secrets/).

### 1. 下载 sealed 客户端

[下载地址](https://github.com/bitnami-labs/sealed-secrets/releases/tag/v0.18.0), 在 Assets 中根据你的电脑架构选择合适的下载包, 我们在这里以 Mac M1 为例选择 [`kubeseal-0.18.0-darwin-arm64.tar.gz`](https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.18.0/kubeseal-0.18.0-darwin-arm64.tar.gz).

```shell
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.18.0/kubeseal-0.18.0-darwin-arm64.tar.gz
tar -zxf kubeseal-0.18.0-darwin-arm64.tar.gz kubeseal
```

### 2. 加密

首先我们准备一个原始的 `demo-secret.yaml`

```shell
cat << EOF > demo-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  namespace: frontend
  name: database-credentials
type: Opaque
stringData:
  username: admin
  password: admin
EOF
```

请注意 namespace 也会在加密的时候用到, 所以必须在 `demo-secret.yaml` 中声明.

接下来进行加密, 在这个 README 同级的目录下已经有用来加密的公钥了 `sealed-secrets-public.crt`.

```shell
./kubeseal --cert sealed-secrets-public.crt -o yaml < demo-secret.yaml > demo-sealed-secret.yaml
```

之后我们只需要把加密后的 `demo-sealed-secret.yaml` 拷贝到配置文件中就好了.

### 3. 原理

我们在 Uk8s 中已经部署好了 `sealed-secrets` 的服务端, 它拥有可以用于解密的私钥, 当我们将 `demo-secret.yaml` 中的内容部署到 Uk8s 后, 它会自动将 `SealedSecret` 对象转化为 `Secret` 对象.

```shell
kubectl get secrets database-credentials -o yaml

apiVersion: v1
data:
  password: YWRtaW4=
  username: YWRtaW4=
kind: Secret
metadata:
  name: database-credentials
  namespace: frontend
  ownerReferences:
  - apiVersion: bitnami.com/v1alpha1
    controller: true
    kind: SealedSecret
    name: database-credentials
type: Opaque
```

请不要直接在 UK8s 直接修改由 `sealed-secrets` 生成的 `Secret` 实例.
