在kubernetes上部署和运行wordpress

既然docker容器能够部署wordpress和mysql,那么在kubernetes(简称k8s)上就能部署和运行wordpress。官方有一个配置案例,如何在k8s上运行wordpress,详见如下链接。

Deploying WordPress and MySQL with Persistent Volumes

这个案例里的配置文件很简单,就三个YAML文件,下载来放到本地,然后运行kubectl命令就可以成功部署。当然,本地要有k8s cluster环境,我是在一台vps上安装了minikube来运行k8s的。

VPS满足2核4G内存40G磁盘的基本要求即可,安装ubuntu系统。如何安装minikube,请见官方文档:

minikube start

下载上述3个YAML文件放到同一目录,运行如下命令及其输出:

$ k apply -k ./
secret/mysql-pass-h96tb29c44 created
service/wordpress created
service/wordpress-mysql created
persistentvolumeclaim/mysql-pv-claim created
persistentvolumeclaim/wp-pv-claim created
deployment.apps/wordpress created
deployment.apps/wordpress-mysql created

上述配置和命令在k8s里创建了如下资源:

  • 一个secret用来保存mysql密码
  • 两个service分别是wordpress和mysql
  • 两个pvc分配给mysql和wordpress作为持久化存储
  • 两个deployment分别是wordpress和mysql

也就是说,mysql和wordpress分别部署在两个pod里,它们各使用一个service来暴露服务接口。

查看已经部署的service:

$ k get service
NAME              TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP      10.96.0.1        <none>        443/TCP        13d
wordpress         LoadBalancer   10.108.253.187   <pending>     80:32241/TCP   3s
wordpress-mysql   ClusterIP      None             <none>        3306/TCP       3s

这其中第二个service至关重要,它是wordpress的对外服务接口。因为官网的配置文件,将这个service定义成loadbalancer,它就多了一个外部ip。实际上,如果不配置成loadbalancer,而是用默认的ClusterIP,在这里反而更简单些。因为我们可以再配置一个Ingress,来实现外网域名对内网ip的映射。

在上述命令的输出里,我们看到wordpress service外部ip处于挂起状态(pending),这是因为minikube的运行态势导致的。运行如下命令获取外部url:

$ minikube service wordpress
|-----------|-----------|-------------|---------------------------|
| NAMESPACE |   NAME    | TARGET PORT |            URL            |
|-----------|-----------|-------------|---------------------------|
| default   | wordpress |          80 | http://192.168.49.2:32241 |
|-----------|-----------|-------------|---------------------------|
🎉  Opening service default/wordpress in default browser...
👉  http://192.168.49.2:32241

这里的意思是,wordpress服务的外部ip是192.168.49.2,这个外部ip是k8s集群分配的,跟vps自身的外网ip无关。我的vps实际上就一个公网ip,要访问wordpress的话,只能访问这个公网ip,然后使用nginx将请求proxy到wordpress的服务ip(192.168.49.2)。

再强调下,这里标准的配置应该是对wordpress service使用ClusterIP,然后配置一个独立的Ingress规则,将外网的域名映射到k8s的ClusterIP。这是更为标准的实现,否则就要按如下的步骤,手工配置nginx。

在vps里安装nginx,对nginx的配置很简单,创建如下配置文件:

server {
  listen 80;
  listen [::]:80;

  server_name kube.xxx.com;

  location / {
      proxy_pass http://192.168.49.2:32241;
      proxy_set_header	Host	$host;
  }
}

这里的意思是,对于域名kube.xxx.com的HTTP请求,反向代理到192.168.49.2这个ip的32241端口,这是wordpress service的服务端口。同时,在向后段的请求里,加上Host头部。配置完后,重启下nginx。

当然,kube.xxx.com是一个有效的公网域名,它需要解析到vps的公网ip。

运行如下命令,登陆wordpress所部署的pod,在apache2的站点配置里,加上ServerName。否则,apache2默认使用192.168.49.2作为主机名,前端页面里很多资源文件(比如css)会加载这个主机名,就导致打不开(公网当然无法访问service ip)。

# 查看运行的pod
$ k get pod
NAME                               READY   STATUS    RESTARTS        AGE
wordpress-6c44b8fd79-6wlx6         1/1     Running   1 (7h41m ago)   8h
wordpress-mysql-696ccc4dfc-9pn97   1/1     Running   0               8h

# 使用kubectl exec打开wordpress pod的bash shell
$ k exec -it wordpress-6c44b8fd79-6wlx6 /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

# 进去wordpress pod后,编辑apache2的站点配置文件
# vi /etc/apache2/sites-enabled/000-default.conf 

在上述apache2的配置文件里,只需加一行,设置hostname即可:

ServerName kube.xxx.com

当然,理想的方式不是直接修改pod里的配置,而是创建全局的ConfigMap,将hostname放在ConfigMap里,pod启动后就会自动加载。

在pod里设置完apache2的hostname后,运行如下命令reload一下:

# service apache2 reload
[ ok ] Reloading web server: apache2.

到此为止基本就可以了。在浏览器打开kube.xxx.com这个域名,会出来wordpress的安装页面。正常安装wordpress即可,与平时用的wordpress没什么区别。安装完后,就可以测试它的配置,以及写文章和浏览了,如下图所示。

还可以用如下命令来查看pod的输出日志:

$ k logs --tail=10 --follow wordpress-6c44b8fd79-6wlx6

显然,k logs和k exec对于故障诊断是非常有用的,这也是k8s的强大之处。

当然,这种方式安装wordpress是不够安全的,因为只使用了一个pod,没有高可用。官方文档也提到这点,请参考如下。

Warning: This deployment is not suitable for production use cases, as it uses single instance WordPress and MySQL Pods. Consider using WordPress Helm Chart to deploy WordPress in production.

Print Friendly, PDF & Email

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注