【容器应用系列教程】Kubernetes部署WordPress博客

一、准备阶段

主机名 IP 安装的软件
k8s-master.linux.com 192.168.140.10 kubernetes、NFS
k8s-node01.linux.com 192.168.140.11 kubernetes、NFS
k8s-node02.linux.com 192.168.140.12 kubernetes、NFS
k8s-nfs.linux.com 192.168.140.13 NFS

关于Kubernetes集群部署教程:https://www.wsjj.top/archives/138

二、配置NFS服务器

搭建过程省略
关于NFS搭建教程:https://www.wsjj.top/archives/62

[root@k8s-nfs ~]# exportfs -arv
exporting *:/slave_db
exporting *:/master_db

所有k8s节点安装NFS依赖

后面需要挂载NFS远程存储,需要用到依赖

[root@k8s-master ~]# yum install -y nfs-utils
[root@k8s-node01 ~]# yum install -y nfs-utils
[root@k8s-node02 ~]# yum install -y nfs-utils

三、创建命名空间

[root@k8s-master ~]# mkdir wordpress
[root@k8s-master ~]# cd wordpress/
[root@k8s-master wordpress]# vim wp-ns.yml

apiVersion: v1
kind: Namespace
metadata:
    name: wordpress
[root@k8s-master wordpress]# kubectl create -f wp-ns.yml

[root@k8s-master wordpress]# kubectl get ns
NAME              STATUS   AGE
default           Active   6d4h
kube-node-lease   Active   6d4h
kube-public       Active   6d4h
kube-system       Active   6d4h
wordpress         Active   4h39m

四、创建PVPVC

关于Kubernetes创建PVPVC的教程:https://www.wsjj.top/archives/144

1.创建Master库用到的PVPVC

[root@k8s-master wordpress]# vim master-pv-pvc.yml

apiVersion: v1
kind: PersistentVolume
metadata:
   name: master-db-pv
   namespace: wordpress
spec:
  capacity:
      storage: 9G
  accessModes:
       - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
      server: 192.168.140.13	#NFS服务器地址
      path: /master_db	#NFS共享的目录
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
     name: master-db-pvc
     namespace: wordpress
spec:
     accessModes:
        - ReadWriteMany
     resources:
        requests:
            storage: 9G
[root@k8s-master wordpress]# kubectl create -f master-pv-pvc.yml 
persistentvolume/master-db-pv created
persistentvolumeclaim/master-db-pvc created

[root@k8s-master wordpress]# kubectl get pvc -n wordpress
NAME            STATUS   VOLUME         CAPACITY   ACCESS MODES   STORAGECLASS   AGE
master-db-pvc   Bound    master-db-pv   9G         RWX                           10s

[root@k8s-master wordpress]# kubectl get pv -n wordpress
NAME           CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE
master-db-pv   9G         RWX            Recycle          Bound    wordpress/master-db-pvc                           75s

2.创建Slave库用到的PVPVC

[root@k8s-master wordpress]# vim slave-pv-pvc.yml

apiVersion: v1
kind: PersistentVolume
metadata:
   name: slave-db-pv
   namespace: wordpress
spec:
  capacity:
      storage: 10G
  accessModes:
       - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
      server: 192.168.140.13
      path: /slave_db
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
     name: slave-db-pvc
     namespace: wordpress
spec:
     accessModes:
        - ReadWriteMany
     resources:
        requests:
            storage: 10G
[root@k8s-master wordpress]# kubectl create -f slave-pv-pvc.yml 
persistentvolume/slave-db-pv created
persistentvolumeclaim/slave-db-pvc created

[root@k8s-master wordpress]# kubectl get pv -n wordpress
NAME           CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE
master-db-pv   9G         RWX            Recycle          Bound    wordpress/master-db-pvc                           5m37s
slave-db-pv    10G        RWX            Recycle          Bound    wordpress/slave-db-pvc                            9s

[root@k8s-master wordpress]# kubectl get pvc -n wordpress
NAME            STATUS   VOLUME         CAPACITY   ACCESS MODES   STORAGECLASS   AGE
master-db-pvc   Bound    master-db-pv   9G         RWX                           5m40s
slave-db-pvc    Bound    salve-db-pv    10G        RWX                           12s

五、准备ConfigMap

关于Kubernetes配置映射ConfigMap教程:https://www.wsjj.top/archives/146

1.准备主库配置文件

[root@k8s-master wordpress]# vim master-db-config.yml

apiVersion: v1
kind: ConfigMap
metadata:
    name: master-db-config
    namespace: wordpress
data:
    my.cnf: |
        [mysqld]
        server_id=10
        log_bin=master
        gtid_mode=on
        enforce_gtid_consistency=true
        collation-server = utf8_general_ci
        character-set-server = utf8
[root@k8s-master wordpress]# kubectl create -f master-db-config.yml 
configmap/master-db-config created

[root@k8s-master wordpress]# kubectl get cm -n wordpress
NAME               DATA   AGE
kube-root-ca.crt   1      5h4m
master-db-config   1      15s

2.准备从库配置文件

[root@k8s-master wordpress]# vim slave-db-config.yml

apiVersion: v1
kind: ConfigMap
metadata:
    name: slave-db-config
    namespace: wordpress
data:
    my.cnf: |
        [mysqld]
        server_id=11
        log_bin=slave
        gtid_mode=on
        enforce_gtid_consistency=true
        collation-server = utf8_general_ci
        character-set-server = utf8
[root@k8s-master wordpress]# kubectl create -f slave-db-config.yml 
configmap/slave-db-config created
[root@k8s-master wordpress]# kubectl get cm -n wordpress
NAME               DATA   AGE
kube-root-ca.crt   1      5h6m
master-db-config   1      2m28s
slave-db-config    1      9s

六、配置主从复制数据库

关于Kubernetes有状态负载StatefulSet教程:https://www.wsjj.top/archives/145

1.创建主库PodService

[root@k8s-master wordpress]# vim wp-master-mysql.yml

apiVersion: apps/v1
kind: StatefulSet	#类型有状态负载
metadata:
    name: wp-master-mysql
    namespace: wordpress
spec:	#控制副本集
    replicas: 1
    selector:
        matchLabels:
            app: wp-master-mysql	#对应下面的自定义标签
    serviceName: "wp-master-mysql"	#此处名字应该对应下面的service名字
    template:
        metadata:
            labels:
                app: wp-master-mysql	#我们自定义个标签(重要)
        spec:	#控制Pod
            containers:
            - name: wp-master-mysql
              image: mysql:5.7
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 3306
              env:
              - name: MYSQL_ROOT_PASSWORD
                value: "WWW.1.com"
              - name: MYSQL_DATABASE
                value: "wordpress"
              - name: MYSQL_USER
                value: "wpuser"
              - name: MYSQL_PASSWORD
                value: "redhat"
              resources:	#配置资源限制
                requests:
                  memory: "1G"
                  cpu: "1"
                limits:
                  memory: "2G"
                  cpu: "2"
              volumeMounts:
                  - name: mysql-data-volume
                    mountPath: /var/lib/mysql
                  - name: mysql-config-volume
                    mountPath: /etc/mysql/conf.d
                    readOnly: true
            volumes:	#配置挂载
                - name: mysql-data-volume
                  persistentVolumeClaim:
                    claimName: master-db-pvc	#指定数据目录持久挂载
                - name: mysql-config-volume
                  projected:
                    sources:
                    - configMap:
                        name: master-db-config	#挂载自定义master配置文件
---
apiVersion: v1
kind: Service
metadata:
    name: wp-master-mysql
    namespace: wordpress
spec:
    ports:
    - port: 3306
    selector:
      app: wp-master-mysql	#此处的标签应该对应上面创建的
[root@k8s-master wordpress]# kubectl create -f wp-master-mysql.yml 
statefulset.apps/wp-master-mysql created
service/wp-master-mysql created

查看Pod

[root@k8s-master wordpress]# kubectl get pods -n wordpress
NAME                READY   STATUS    RESTARTS   AGE
wp-master-mysql-0   1/1     Running   0          3m47s

创建主从复制用到的用户

[root@k8s-master wordpress]# kubectl exec -it wp-master-mysql-0 -n wordpress -- bash
bash-4.2# mysql -uroot -pWWW.1.com
mysql> grant replication slave on *.* to 'repluser'@'%' identified by 'WWW.1.com';
Query OK, 0 rows affected, 1 warning (0.00 sec)

2.创建从库PodService

[root@k8s-master wordpress]# vim wp-slave-mysql.yml

apiVersion: apps/v1
kind: StatefulSet
metadata:
    name: wp-slave-mysql
    namespace: wordpress
spec:
    replicas: 1
    selector:
        matchLabels:
            app: wp-slave-mysql
    serviceName: "wp-slave-mysql"
    template:
        metadata:
            labels:
                app: wp-slave-mysql
        spec:
            containers:
            - name: wp-slave-mysql
              image: mysql:5.7
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 3306
              env:
              - name: MYSQL_ROOT_PASSWORD
                value: "WWW.1.com"
              resources:
                requests:
                  memory: "1G"
                  cpu: "1"
                limits:
                  memory: "2G"
                  cpu: "2"
              volumeMounts:
                  - name: mysql-data-volume
                    mountPath: /var/lib/mysql
                  - name: mysql-config-volume
                    mountPath: /etc/mysql/conf.d
                    readOnly: true
            volumes:
                - name: mysql-data-volume
                  persistentVolumeClaim:
                    claimName: slave-db-pvc	#挂载从库持久数据
                - name: mysql-config-volume
                  projected:
                    sources:
                    - configMap:
                        name: slave-db-config	#挂载从库配置文件
---
apiVersion: v1
kind: Service
metadata:
    name: wp-slave-mysql
    namespace: wordpress
spec:
    ports:
    - port: 3306
    selector:
      app: wp-slave-mysql
[root@k8s-master wordpress]# kubectl create -f wp-slave-mysql.yml 
statefulset.apps/wp-slave-mysql created
service/wp-slave-mysql created
[root@k8s-master wordpress]# kubectl get pods -n wordpress
NAME                READY   STATUS    RESTARTS   AGE
wp-master-mysql-0   1/1     Running   0          38m
wp-slave-mysql-0    1/1     Running   0          2m19s

3.配置主从复制

因为从库和主库都在同一个wordpress命名空间内,又因为k8scronDNSservice解析,所以填写服务名即可,如果不在同一个命名空间,可能需要填写全名。
更多关于Service服务名的详情,请查看这期教程:【容器应用系列教程】Kubernetes服务管理Service

[root@k8s-master wordpress]# kubectl exec -it wp-slave-mysql-0 -n wordpress -- bash
bash-4.2# mysql -uroot -pWWW.1.com

mysql> change master to
    -> master_host="wp-master-mysql",	#数据库地址为master容器的服务名
    -> master_user="repluser",
    -> master_password="WWW.1.com",
    -> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.04 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: wp-master-mysql
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master.000003
          Read_Master_Log_Pos: 481
               Relay_Log_File: wp-slave-mysql-0-relay-bin.000003
                Relay_Log_Pos: 688
        Relay_Master_Log_File: master.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

七、部署WordPress

1.安装Ingress-nginx插件

Ingress-nginx负责基于服务名发布服务
关于Ingress-nginx部署文件下载地址:https://pan.baidu.com/s/1l9cF-AShYicLk1arwVboEw?pwd=jge3

[root@k8s-master wordpress]# kubectl create -f ingress-nginx-deploy_v1.3.1.yaml

namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
[root@k8s-master wordpress]# kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-ct2hs        0/1     Completed   0          68s
ingress-nginx-admission-patch-dshpv         0/1     Completed   0          68s
ingress-nginx-controller-64ff7cd7cf-sm4sx   1/1     Running     0          68s	#controller插件正常运行

2.配置NFS

[root@k8s-nfs ~]# exportfs -arv
exporting *:/wordpress
exporting *:/slave_db
exporting *:/master_db

3.创建WordPressPodService

关于Kubernetes无状态负载Deployment教程:https://www.wsjj.top/archives/141

[root@k8s-master wordpress]# vim wordpress.yml

apiVersion: apps/v1
kind: Deployment	#类型无状态负载
metadata:
    name: wordpress
    namespace: wordpress
spec:
    replicas: 1
    selector:
        matchLabels:
            app: wordpress
    strategy:	#滚动更新策略
        type: RollingUpdate
        rollingUpdate:
            maxSurge: 1
            maxUnavailable: 0
    template:
        metadata:
            labels:
                app: wordpress
        spec:
            containers:
            - name: wordpress
              image: wordpress
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 80
              env:
              - name: WORDPRESS_DB_HOST
                value: "wp-master-mysql"	#数据库连接地址同样是服务名
              - name: WORDPRESS_DB_USER
                value: "wpuser"
              - name: WORDPRESS_DB_PASSWORD
                value: "redhat"
              - name: WORDPRESS_DB_NAME
                value: "wordpress"
              - name: WORDPRESS_TABLE_PREFIX
                value: "wp_"
              resources:
                requests:
                  memory: "1G"
                  cpu: "1"
                limits:
                  memory: "2G"
                  cpu: "2"
              volumeMounts:
                - name: wordpress-data-volumes
                  mountPath: /var/www/html	#挂载到wordpress数据目录
            volumes:
              - name: wordpress-data-volumes
                nfs:
                  server: "192.168.140.13"	#挂载NFS共享目录
                  path: /wordpress
---
apiVersion: v1
kind: Service
metadata:
    name: wordpress
    namespace: wordpress
spec:	#服务类型是ClusterIP
    ports:
    - port: 80
    selector:
      app: wordpress
[root@k8s-master wordpress]# kubectl create -f wordpress.yml 
deployment.apps/wordpress created
service/wordpress created
[root@k8s-master wordpress]# kubectl get pods -n wordpress
NAME                         READY   STATUS    RESTARTS   AGE
wordpress-7c79b77f77-j26nk   1/1     Running   0          5m31s
wp-master-mysql-0            1/1     Running   0          64m
wp-slave-mysql-0             1/1     Running   0          28m

4.创建Ingress服务发布WordPress

[root@k8s-master wordpress]# vim wp-ingress.yml

apiVersion: extensions/v1beta1
kind: Ingress 
metadata:
  name: wp-ingress
  namespace: wordpress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules: 
  - host: wp.linux.com
    http:
      paths: 
      - path:  
        backend: 
          serviceName: wordpress
          servicePort: 80
[root@k8s-master wordpress]# kubectl create -f wp-ingress.yml

Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/wp-ingress created

5.修改Windows上的hosts文件

路径:C:\Windows\System32\drivers\etc\hosts
解析的IP地址,取决于您的ingresscontroller跑在哪个物理机上,我这里跑在node01

kubernetes12

6.测试访问

安装配置过程省略

kubernetes13

如果你跟到了这一步,那么恭喜你,最基本的wordpress已经部署好啦!

八、部署Redis

1.配置NFS共享

[root@k8s-nfs ~]# exportfs -arv
exporting *:/wp_redis
exporting *:/wordpress
exporting *:/slave_db
exporting *:/master_db

2.创建redis用到的PVPVC

[root@k8s-master wordpress]# vim redis-pv-pvc.yml

apiVersion: v1
kind: PersistentVolume
metadata:
   name: redis-db-pv
   namespace: wordpress
spec:
  capacity:
      storage: 10G
  accessModes:
       - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
      server: 192.168.140.13
      path: /wp_redis
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
     name: redis-db-pvc
     namespace: wordpress
spec:
     accessModes:
        - ReadWriteMany
     resources:
        requests:
            storage: 10G
[root@k8s-master wordpress]# kubectl create -f redis-pv-pvc.yml 
persistentvolume/redis-db-pv created
persistentvolumeclaim/redis-db-pvc created

[root@k8s-master wordpress]# kubectl get pvc -n wordpress
NAME            STATUS   VOLUME         CAPACITY   ACCESS MODES   STORAGECLASS   AGE
master-db-pvc   Bound    master-db-pv   9G         RWX                           165m
redis-db-pvc    Bound    redis-db-pv    10G        RWX                           10s
slave-db-pvc    Bound    slave-db-pv    10G        RWX                           86m

[root@k8s-master wordpress]# kubectl get pv -n wordpress
NAME           CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE
master-db-pv   9G         RWX            Recycle          Bound    wordpress/master-db-pvc                           166m
redis-db-pv    10G        RWX            Recycle          Bound    wordpress/redis-db-pvc                            46s
slave-db-pv    10G        RWX            Recycle          Bound    wordpress/slave-db-pvc                            87m

3.创建RedisConfigMap

[root@k8s-master wordpress]# vim redis-config.yml

apiVersion: v1
kind: ConfigMap
metadata:
    name: redis-config
    namespace: wordpress
data:
    redis.conf: |
        dir /srv
        port 6379
        bind 0.0.0.0
        appendonly yes	#开启数据持久化
        daemonize no
        # protected-mode no	#是否开启保护模式,此配置进针对redis6.x+版本生效
        pidfile /srv/redis-6379.pid
[root@k8s-master wordpress]# kubectl create -f redis-config.yml 
configmap/redis-config created

[root@k8s-master wordpress]# kubectl get cm -n wordpress
NAME               DATA   AGE
kube-root-ca.crt   1      7h43m
master-db-config   1      159m
redis-config       1      17s
slave-db-config    1      105m

4.创建Redis的PodService

[root@k8s-master wordpress]# vim wp-redis.yml

apiVersion: apps/v1
kind: StatefulSet	#有状态负载
metadata:
  name: redis
  namespace: wordpress
  labels:
    app: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  serviceName: "redis"
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:3.0.7
        command:
          - "sh"
          - "-c"
          - "redis-server /usr/local/redis/redis.conf"
        ports:
        - containerPort: 6379
        resources:
          limits:
            cpu: 1000m
            memory: 1024Mi
          requests:
            cpu: 1000m
            memory: 1024Mi
        livenessProbe:
          tcpSocket:
            port: 6379
          initialDelaySeconds: 300
          timeoutSeconds: 1
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          tcpSocket:
            port: 6379
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 3
        volumeMounts:
        - name: wp-redis-config
          mountPath:  /usr/local/redis/redis.conf	#配置文件挂载到容器内
          subPath: redis.conf
        - name: wp-redis-data-volume
          mountPath: /srv	#配置文件里指定的数据目录
      volumes:
      - name: wp-redis-config
        configMap:
          name: redis-config	#挂载配置文件
      - name: wp-redis-data-volume
        persistentVolumeClaim:
            claimName: redis-db-pvc	#挂载PVC
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: wordpress
  labels:
    app: redis
spec:
  ports:
    - name: tcp
      port: 6379
  selector:
    app: redis
[root@k8s-master wordpress]# kubectl create -f wp-redis.yml

5.在WordPress插件库安装Redis插件

下载完暂时不要启用插件!!!

kubernetes14

6.修改插件配置文件

A.编辑配置文件

前往NFS服务器修改配置文件

[root@k8s-nfs ~]# vim /wordpress/wp-config.php
#在配置文件底部增加以下内容
define('WP_REDIS_HOST', 'redis');	#这里的名字,对应redis中的service名字
define('WP_REDIS_PORT', '6379');
define('WP_REDIS_DATABASE', '0');

B.修改插件的配置文件

[root@k8s-nfs ~]# vim /wordpress/wp-content/plugins/redis-cache/includes/object-cache.php

protected function build_parameters() {
        $parameters = [
            'scheme' => 'tcp',
            'host' => 'redis',	#修改redis连接地址为服务名
            'port' => 6379,
            'database' => 0,
            'timeout' => 1,
            'read_timeout' => 1,
            'retry_interval' => null,
            'persistent' => false,
        ];

C.启动Reids插件测试

kubernetes15

如果您的Redis启动失败,请检查连接地址是否正确
优先检查rediswordpress服务是否在同一个命名空间内,如果不是,请把连接地址改成完整名字!
完整名字参考:redis.wordpress.svc.cluster.local 服务名.命名空间名.svc.集群域名