MariaDB 与 K8s:创建 Secret 并在 MariaDB 部署中使用

上一篇博客中,我们创建了一个无状态应用程序,使用 K8s 资源 Deployment 进行部署,并暴露了 root 密码,这在安全性方面当然是不推荐的。K8s 允许使用特定的 K8s 资源隐藏机密数据。

让我们看看如何在 K8s 中使用 Secrets

K8s 中的 Secrets

为了保存机密数据,可以使用名为 Secret 的 K8s 资源。

可以通过运行 kubectl create secret 从 CLI 创建 Secret。

这里我们将使用两种方法来创建 Secret。第一种方法将用户存储在一个文件中,密码存储在另一个文件中,然后通过读取文件来创建 Secret 对象。数据将使用 base64 加密。

$ echo -n 'root' >./username.txt
$ echo -n 'secret' >./password.txt 

# Create generic secret object with keys username and password from files
$ kubectl create secret generic mariadb-secret --from-file=username=./username.txt --from-file=password=./password.txt
secret/mariadb-secret created

要显示 Secret,可以使用以下命令

$ kubectl get secret mariadb-secret
NAME             TYPE     DATA   AGE
mariadb-secret   Opaque   2      61s

$ kubectl describe secret mariadb-secret
Name:         mariadb-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
username:  4 bytes
password:  6 bytes

请注意,即使意外显示 Secret,数据也已安全保护。

要解码 Secret,可以使用

# Decode data field from secret using json output
$ kubectl get secret mariadb-secret -o jsonpath='{.data}'
{"password":"c2VjcmV0","username":"cm9vdA=="}

# Get data using yaml output
$ kubectl get secret mariadb-secret -o yaml
apiVersion: v1
data:
  password: c2VjcmV0
  username: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2022-03-21T10:49:24Z"
  name: mariadb-secret
  namespace: default
  resourceVersion: "392508"
  uid: 25943f12-d47d-4042-b9c6-027646864d3b
type: Opaque

# Decode base64 encrypted data username
$ echo "cm9vdA=="|base64 -d # output 'root'

要删除 Secret,运行

$ kubectl delete secret mariadb-secret
secret "mariadb-secret" deleted

这里我们想指出的第二种方法是使用键/值字面量

$ kubectl create secret generic my-test-secret --from-literal=mariadb-root-password=secret

要再次获取数据,可以使用输出格式(此处我们使用 go-template

$ kubectl get secret my-test-secret -o go-template='{{.data}}'
[mariadb-root-password:c2VjcmV0]

或者,也可以使用配置文件。配置文件示例(GitHub 上的文件

apiVersion: v1
kind: Secret
metadata:
    name: mariadb-secret
type: Opaque
data:
  # Encoded value: echo -n 'secret'|base64
  mariadb-root-password: c2VjcmV0 

要创建资源,运行 kubectl apply

$ kubectl apply -f mariadb-secret.yaml 
secret/mariadb-secret created

要使用 Secrets,Secrets 必须先存在。

可以在容器中使用它来设置 root 密码,因此要这样做,更新 MARIADB_ROOT_PASSWORD 的值(GitHub 上的部署文件

        - name: MARIADB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mariadb-secret
              key: mariadb-root-password

让我们创建包含 Secret 信息的部署配置文件并显示结果。

$ kubectl  apply -f mariadb-deployment-from-secret.yaml 
deployment.apps/mariadb-deployment created

现在可以通过运行 kubectl exec 命令在 Pod 上进行测试。

# Get the Pods
$ kubectl get all 
NAME                                      READY   STATUS    RESTARTS   AGE
pod/mariadb-deployment-7bcbb796f5-cfh8b   1/1     Running   0          6s
pod/mariadb-deployment-7bcbb796f5-gjtlj   1/1     Running   0          6s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   143d

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mariadb-deployment   2/2     2            2           6s

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/mariadb-deployment-7bcbb796f5   2         2         2       6s

# Run mariadb client
$ kubectl exec mariadb-deployment-7bcbb796f5-cfh8b -- mariadb -uroot -psecret -e "select version()"
version()
10.7.3-MariaDB-1:10.7.3+maria~focal

从上面我们可以看到成功访问了 MariaDB 数据库。

结论和未来工作

这篇博客展示了如何在 K8s 集群中创建 Secret,并演示了使用基本的 kubectl 命令来操作 K8s 中的 Secrets。此外,还创建了一个 Deployment 并与 Secret 结合使用。Secret 可以用于使用 MariaDB 加密插件初始化静态数据加密(encryption-at-rest)。在接下来的博客中,我们可能也会介绍这一点。

在下一篇博客中,我们将创建带有 Persistent Volumes 的部署。

欢迎在 Zulip 上讨论。

阅读更多