在Kubernetes上部署PhpMyAdmin来管理MySQL Pod

时间:2020-01-09 10:34:18  来源:igfitidea点击:

说明

在本教程中,我们将学习如何将PhpMyAdmin部署到Kubernetes,以管理MySQL服务器Pod。

MySQL服务器很可能仅在Kubernetes群集中可用,因为这样的服务不应暴露于公共Internet。但是,我们将需要一种解决方案来管理数据库,并且该解决方案不包括运行exec来直接访问一个或者多个pod的权限。

PhpMyAdmin是用于管理MySQL服务器的非常流行的Web前端。它是能够管理Kubernetes中托管的MySQL服务器的理想人选,因为它使我们能够轻松,有效地管理所有数据库。

入门

本教程使用的资源可从Github获得。我们可以免费下载它们以遵循或者作为我们自己环境的模板。

  • Kubernetes模板

部署PhpMyAdmin Pod

机密

我们的PhpMyAdmin部署将链接到现有的MySQL服务,而不是允许用户指定该服务的地址。 PhpMyAdmin将需要知道所连接的MySQL服务器的根密码。

已经创建了一个秘密来存储MySQL的根密码。我们将把这个PhpMyAdmin作为目标,与MySQL pod共享。下面显示了机密数据的示例,以供参考。

---
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secrets
type: Opaque
data:
  root-password: c3VwZXItc2VjcmV0LXBhc3N3b3Jk

root-password值是创建的任意键名称,用于存储MySQL服务器的root密码的base64编码的字符串。机密资源文件中的所有机密值必须使用base64编码。

当pod的容器启动时,PhpMyAdmin Kubernetes部署将引用root-password键来设置MYSQL_ROOT_PASSWORD环境变量。

创建部署资源

创建一个名为deployment.yml的新文件。

touch deployment.yml

将以下内容添加到deployment.yml文件。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: phpmyadmin-deployment
  labels:
    app: phpmyadmin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: phpmyadmin
  template:
    metadata:
      labels:
        app: phpmyadmin
    spec:
      containers:
        - name: phpmyadmin
          image: phpmyadmin/phpmyadmin
          ports:
            - containerPort: 80
          env:
            - name: PMA_HOST
              value: mysql-service
            - name: PMA_PORT
              value: "3306"
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secrets
                  key: root-password

使用kubectl apply命令创建部署

kubectl apply -f deployment.yml

创建服务资源

Kubernetes Pod是短暂的,其IP地址仅与Pod一样有效。这对于长期访问PhpMyAdmin来说是个问题,这就是为什么我们为吊舱创建服务资源。

服务资源将被分配一个静态IP地址,并且对该IP地址的所有请求都将转发到后端PhpMyAdmin容器。服务资源通过标签耦合到吊舱。

创建一个名为service.yml的新文件

touch service.yml

向其中添加以下内容。由于我们为PhpMyAdmin容器分配了phpmyadmin标签,因此我们将其用作服务中的选择器。

---
apiVersion: v1
kind: Service
metadata:
  name: phpmyadmin-service
spec:
  type: NodePort
  selector:
    app: phpmyadmin
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

要创建服务资源,我们使用kubectl apply命令。

kubectl apply -f service.yml

入口控制器

为了简化将PhpMyAdmin公开到公共Internet,将创建一个入口资源。入口资源将指向PhpMyAdmin服务资源。

创建一个基本的HTTP入口

创建一个名为ingress.yml的新文件

touch ingress.yml

向其中添加以下内容。

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: phpmyadmin-http-ingress
spec:
  backend:
    serviceName: phpmyadmin-service
    servicePort: 80

使用kubectl apply命令创建入口资源。

kubectl apply -f ingress.yml

使用TLS保护入口

上面的入口示例通过HTTP公开了PhpMyAdmin,这意味着我们的流量所经过的任何网络都可以访问所有敏感信息。对于生产环境来说,这显然是一个不好的做法。

要保护Ingress端点,我们需要执行以下操作:

  • 证书颁发机构证书
  • TLS证书
  • TLS密钥

这三个文件都需要作为Kubernetes秘密存储。使用以下命令创建新的机密,将文件名替换为与环境匹配的文件名。

kubectl create secret generic ingress-tls-secret --from-file=tls.crt=server.crt --from-file=tls.key=server.key --from-file=ca.crt=ca.crt

或者,我们可以创建另一个秘密资源文件,并存储每个文件的base64编码的字符串。要对文件进行base64编码,请对每个文件使用以下命令。

base64 -i <文件名>

使用base64编码的文件值,以下是存储所需证书和密钥的机密文件的示例。

---
apiVersion: v1
kind: Secret
metadata:
  name: ingess-tls-secret
type: Opaque
data:

通过将以下注释添加到ingress.yml文件的元数据部分,我们为入口控制器启用TLS加密。

  • nginx.ingress.kubernetes.io/auth-tls-verify-client
  • nginx.ingress.kubernetes.io/auth-tls-secret
  • nginx.ingress.kubernetes.io/auth-tls-verify-depth

更新ingress.yml资源文件以包含注释。完成后,更新文件应类似于以下示例。

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: phpmyadmin-http-ingress
  annotations:
    # Enable client certificate authentication
    nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
    # Create the secret containing the trusted ca certificates
    nginx.ingress.kubernetes.io/auth-tls-secret: "default/ingress-tls-secret"
    # Specify the verification depth in the client certificates chain
    nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
spec:
  backend:
    serviceName: phpmyadmin-service
    servicePort: 80