在Kubernetes上部署PhpMyAdmin来管理MySQL Pod
说明
在本教程中,我们将学习如何将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