在 K8s 中启动 MariaDB

这是系列博客的第一篇,解释了如何在 Kubernetes (K8s) 中使用 MariaDB,并解释了 K8s 和 MariaDB 的一些重要概念。

本博客解释了如何使用 CLI 在 K8s 中将 MariaDB 作为无状态应用启动,并探索了可以在 CLI 上运行的不同命令。

前提条件是您已经安装了 kubectl (这也会安装 Docker 运行时) 和 minikube (本地 K8s)。

首先启动 minikube

$ minikube start && kubectl get nodes
NAME       STATUS   ROLES                  AGE    VERSION
minikube   Ready    control-plane,master   104d   v1.22.2

Pod 是一个 K8s 资源,也是 K8s 中最小的单元。它是 K8s 层对容器的顶级抽象。Pod 是短暂的,很容易消亡,当再次启动时,新的 Pod 将获得新的 IP。这就是无状态应用的意思;当 Pod 被重启或删除时,数据没有一致性。通常一个 Pod 用于运行 1 个应用容器。

Deployment 是一个 K8s 资源,它是对 Pod 之上的抽象,为 Pod 提供蓝图,并帮助与 Pod 交互、复制 Pod 等。

K8s API 包含其他类型的资源,可以使用 kubectl api-resources 列出。在那里可以找到 Deployments、ReplicaSetSecretsConfigMapsServices 等。

从 CLI 启动 MariaDB

要从 CLI 创建任何资源,需要运行命令 kubectl create <资源> <名称> --image=<镜像名称>。例如,如果是部署 nginx,最后的命令将是 kubectl create deployment nginx --image=nginx

要创建并运行容器,MariaDB 需要至少设置一个预期的环境变量(参见 MariaDB Docker Library)。我们需要传递环境变量,但我找不到通过 kubectl create deployment 命令从 CLI 传递环境变量的方法。本博客稍后将介绍如何正确创建和启动 MariaDB 部署。

可以使用 kubectl run 命令启动 Pod(尽管不推荐)并传递环境变量。我们使用该命令通过 MARIADB_ROOT_PASSWORD 环境变量设置 root 密码。

$ kubectl run mariadb-test-pod --image=mariadb --env="MARIADB_ROOT_PASSWORD=secret"
pod/mariadb-test-pod created

要显示 Pod(或任何其他资源)的信息(状态/重启次数/时长),运行

$ kubectl get pods
NAME               READY   STATUS    RESTARTS   AGE
mariadb-test-pod   1/1     Running   0          2m37s

要登录容器,可以使用 kubectl exec 命令。我们使用该命令在容器内启动 mariadb 客户端并执行查询。

$ kubectl exec -it mariadb-test-pod -- mariadb -uroot -psecret -e "select current_user()"
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+

另一个有用的命令是 kubectl logs,它打印 Pod 中容器的日志。

要查看我们创建的 mariadb-test-pod 的日志,运行

$ kubectl logs mariadb-test-pod
...
2022-03-16  7:54:43 0 [Note] mariadbd: ready for connections.
Version: '10.7.3-MariaDB-1:10.7.3+maria~focal'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution

要调试 Pod 并获取更多关于 Pod 的信息,运行 kubectl describe 命令

$ kubectl describe pod mariadb-test-pod
...
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  27m   default-scheduler  Successfully assigned default/mariadb-test-pod to minikube
  Normal  Pulling    27m   kubelet            Pulling image "mariadb"
  Normal  Pulled     27m   kubelet            Successfully pulled image "mariadb" in 19.675118703s
  Normal  Created    27m   kubelet            Created container mariadb-test-pod
  Normal  Started    27m   kubelet            Started container mariadb-test-pod

最后,要删除 Pod,运行 kubectl delete 命令

$ kubectl delete pod mariadb-test-pod
pod "mariadb-test-pod" deleted

使用配置文件启动 MariaDB

相较于使用 CLI 在 K8s 中启动资源,推荐的方式是创建配置 YAML 文件。

创建 YAML 文件 mariadb-deployment.yaml。该文件可在 GitHub mariadb.org-tools 上找到。

apiVersion: apps/v1
kind: Deployment # what to create?
metadata:
  name: mariadb-deployment
spec: # specification for deployment resource
  replicas: 2 # how many replicas of pods we want to create
  selector:
    matchLabels:
      app: mariadb
  template: # blueprint for pods
    metadata:
      labels:
        app: mariadb # service will look for this label
    spec: # specification for pods
      containers: # we can have one or more containers
      - name: mariadb
        image: mariadb
        ports:
        - containerPort: 3306 
        env:
        #- name: MARIADB_RANDOM_ROOT_PASSWORD
        - name: MARIADB_ALLOW_EMPTY_ROOT_PASSWORD
          value: "0" # if it is 1 and root_password is set, root_password takes precedance
        - name: MARIADB_ROOT_PASSWORD
          value: secret

注意,我们指定了要创建的内容(Deployment)。

Deployment 是 Pod 的一个超集资源,可以通过配置文件的副本数(replicas)进行扩缩容。

每个 Pod 都有其标签,标签是键值对,可用于使用 kubectl 命令过滤 Pod,也是与 K8s 集群中的服务交互的接口(稍后我们将解释服务资源)。

Pod 可以包含容器数组,但我们创建的是一个名为 mariadb 的单个容器(注意此名称由 Deployment 选择器用于创建容器),使用 mariadb(最新)镜像,并设置端口和环境变量。

要创建并启动 Deployment,需要使用 kubectl apply 命令并指定 YAML 文件

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

要显示 Deployment,运行

$ kubectl get deploy
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
mariadb-deployment   2/2     2            2           48s

它显示 Deployment 的全部 2 个副本已就绪并启动。

要获取副本信息,显示 ReplicaSet 资源

$ kubectl get replicasets
NAME                           DESIRED   CURRENT   READY   AGE
mariadb-deployment-9fd9fbbfd   2         2         2       3m26s

要获取 Pod 信息,显示 Pod 资源

$ kubectl get pods
NAME                                 READY   STATUS    RESTARTS   AGE
mariadb-deployment-9fd9fbbfd-5rkzp   1/1     Running   0          106s
mariadb-deployment-9fd9fbbfd-jtbk2   1/1     Running   0          106s

注意,ReplicaSet 和 Pod 的末尾都有 K8s 创建的哈希前缀,作为唯一标识符。K8s 集群中的每个 Pod 都有其唯一的 IP,因此当它被删除时,会创建一个带有新 IP 的新 Pod,从而导致数据丢失。Pod 的 IP 可以通过以下命令找到。

$ kubectl get pods -o wide
NAME                                 READY   STATUS    RESTARTS   AGE     IP            NODE       NOMINATED NODE   READINESS GATES
mariadb-deployment-9fd9fbbfd-5rkzp   1/1     Running   0          5m22s   172.17.0.12   minikube   <none>           <none>
mariadb-deployment-9fd9fbbfd-jtbk2   1/1     Running   0          5m22s   172.17.0.8    minikube   <none>           <none>

要获取容器日志,运行 kubectl logs deploy/mariadb-deployment

要启动 mariadb 客户端,我们需要在一个带有哈希名称的 Pod 上运行 kubectl exec。在这种情况下,有两个带有不同哈希名称的 Pod,所以我们将对两者进行测试。

$ kubectl exec -it mariadb-deployment-9fd9fbbfd-5rkzp -- mariadb -uroot -psecret -e "select current_user()"
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+
$ kubectl exec -it mariadb-deployment-9fd9fbbfd-jtbk2 -- mariadb -uroot -psecret -e "select current_user()"
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+

如果需求增加,需要对应用进行扩缩容。这通过更改 Deployment 中的副本数来实现。这将确保创建新的 Pod 并调度到具有可用资源的节点。要将 Deployment 从 2 个副本扩容到 4 个,运行以下命令。

$ kubectl get deploy
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
mariadb-deployment   2/2     2            2           17m
$ kubectl scale deploy/mariadb-deployment --replicas=4
deployment.apps/mariadb-deployment scaled
$ kubectl get deploy
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
mariadb-deployment   4/4     4            4           22m

自己尝试缩容吧 :)。

要删除 Deployment(这将删除 Deployment 创建的一切,例如 Pod 和 ReplicaSets),运行

$ kubectl delete deploy mariadb-deployment
deployment.apps "mariadb-deployment" deleted

结论和未来工作

本博客展示了如何在 K8s 集群中创建 MariaDB Pod,并演示了使用基本 kubectl 命令与 K8s 进行交互。此外,还从 YAML 文件创建了 Deployment,并了解了如何对 Deployment 进行扩缩容。

在下一篇博客中,我们将创建一个前端 Deployment,以便与本博客中的 Deployment(我们称之为后端)进行交互,并探索其他 K8s 概念,如 Services、Secrets 和 ConfigMaps,了解它们是什么、如何创建以及如何使用它们。

欢迎在 Zulip 上与我们交流。

阅读更多