Kubernetes部署Discuz

Kubernetes部署Discuz

Administrator 1739 2021-12-09

部署准备

  1. 下载MySQL,PHP及nginx镜像

    docker pull mysql:5.7
    docker pull richarvey/nginx-php-fpm
    
  2. 创建k8s_discuz/dz_web_dockerfile目录,新建Dockerfile文件,内容如下:

    FROM richarvey/nginx-php-fpm
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    RUN echo 'Asia/Shanghai' > /etc/timezone
    RUN rm -rf /etc/nginx/nginx.conf /usr/local/etc/php-fpm.d/www.conf
    COPY nginx.conf /etc/nginx/nginx.conf
    COPY www.conf /usr/local/etc/php-fpm.d/www.conf
    ENTRYPOINT /usr/sbin/nginx -c /etc/nginx/nginx.conf && /usr/local/sbin/php-fpm -c /usr/local/etc/php-fpm.conf
    
  3. 创建nginx.conf和www.conf

    nginx.conf

    user nobody;
    worker_processes 1;
    error_log /var/log/nginx_error.log crit;
    worker_rlimit_nofile 51200;
    
    events
    {
        use epoll;
        worker_connections 6000;
    }
    
    http
    {
        include mime.types;
        default_type application/octet-stream;
        log_format main '$remote_addr $http_x_forwarded_for [$time_local]'
        '$host "$request_uri" $status'
        '"$http_referer" "$http_user_agent"';
        sendfile on;
        tcp_nopush on;
        keepalive_timeout 30;
        client_header_timeout 3m;
        client_body_timeout 3m;
        send_timeout 3m;
        connection_pool_size 256;
        client_header_buffer_size 1k;
        large_client_header_buffers 8 4k;
        request_pool_size 4k;
        output_buffers 4 32k;
        postpone_output 1460;
        client_max_body_size 10m;
        client_body_buffer_size 256k;
        fastcgi_intercept_errors on;
        tcp_nodelay on;
        gzip on;
        gzip_min_length 1k;
        gzip_buffers 4 8k;
        gzip_comp_level 5;
        gzip_http_version 1.1;
        gzip_types text/plain application/x-javascript text/css text/htm application/xml;
    
    server
    {
        listen 80;
        server_name localhost;
        index index.html index.htm index.php;
        root /var/www/html;
    
        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            }
        rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last;
        rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last;
        rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last;
        rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last;
        rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last;
        rewrite ^([^\.]*)/(fid|tid)-([0-9]+)\.html$ $1/index.php?action=$2&value=$3 last;
      }
    }
    

    www.conf

    [www]
    listen = 127.0.0.1:9000
    user = nginx
    group = nginx
    pm = dynamic
    pm.max_children = 50
    pm.start_servers = 20
    pm.min_spare_servers = 20
    pm.max_spare_servers = 30
    pm.max_requests = 500
    rlimit_files = 1024
    
  4. NFS配置

    首先搭建NFS服务,在nfs共享目录下创建目录mkdir -p /data/shared/discuz/{web,db}

部署步骤

镜像处理

使用Dockerfile重建nginx-php-fpm镜像:

docker build -t nginx-php .

将镜像push到harbor仓库:

docker tag nginx-php harbor.mez100.com.cn/tnt/nginx-php
docker tag mysql:5.7 harbor.mez100.com.cn/tnt/mysql:5.7

docker push harbor.mez100.com.cn/tnt/nginx-php
docker push harbor.mez100.com.cn/tnt/mysql:5.7

MySQL服务搭建

  1. 创建secret(mysql的root密码)

    kubectl create secret generic mysql-pass --from-literal=password=DzPasswd1

  2. 创建k8s_discuz/mysql目录,编辑mysql-pv.yaml文件用于创建PV

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: mysql-pv
    spec:
      capacity:
        storage: 10Gi
      accessModes:
        - ReadWriteMany
      nfs:
        path: /data/shared/discuz/db
        server: 192.168.8.33
    
    [root@master1 mysql]# kubectl create -f mysql-pv.yaml
    persistentvolume/mysql-pv created
    
    [root@master1 mysql]# kubectl get pv
    NAME       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
    mysql-pv   10Gi       RWX            Retain           Bound    default/mysql-claim                           11s
    pv01       10Gi       RWX            Retain           Bound    default/myclaim                               24h
    
  3. 创建mysql-pvc.yaml文件用于创建pvc:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mysql-claim
      labels:
        app: discuz
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 10Gi
    
    [root@master1 mysql]# kubectl create -f mysql-pvc.yaml
    persistentvolumeclaim/mysql-claim created
    
    [root@master1 mysql]# kubectl get pvc
    NAME          STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    myclaim       Bound    pv01       10Gi       RWX                           24h
    mysql-claim   Bound    mysql-pv   10Gi       RWX                           20s
    
  4. 创建MySQL的deployment文件mysql-dp.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dz-mysql
      labels:
        app: discuz
    spec:
      selector:
        matchLabels:
          app: discuz
          tier: mysql
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            app: discuz
            tier: mysql
        spec:
          imagePullSecrets:
            - name: hill-secret
          containers:
          - image: harbor.mez100.com.cn/tnt/mysql:5.7
            name: dz-mysql
            env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-pass
                  key: password
            ports:
            - containerPort: 3306
              name: dz-mysql
            volumeMounts:
            - name: mysql-persistent-storage
              mountPath: /var/lib/mysql
          volumes:
          - name: mysql-persistent-storage
            persistentVolumeClaim:
              claimName: mysql-claim		  
    
    
    [root@master1 mysql]# kubectl create -f mysql-dp.yaml
    deployment.apps/dz-mysql created
    [root@master1 mysql]# kubectl get pod -o wide
    NAME                        READY   STATUS    RESTARTS       AGE     IP            NODE              NOMINATED NODE   READINESS GATES
    dz-mysql-5c4fc65868-5tjsl   1/1     Running   0              3s      172.20.2.21   192.168.139.131   <none>           <none>
    
    
  5. 创建MySQL的service文件mysql-svc.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: dz-mysql
      labels:
        app: discuz
    spec:
      ports:
        - port: 3306
      selector:
        app: discuz
        tier: mysql
    

    创建service并测试mysql能否登录:

    [root@master1 mysql]# kubectl create -f mysql-svc.yaml
    service/dz-mysql created
    
    [root@master1 mysql]# kubectl get svc
    NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    dz-mysql     ClusterIP   10.68.244.100   <none>        3306/TCP       23s
    
    [root@master1 mysql]# mysql -uroot -pDzPasswd1 -h10.68.244.100
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.36 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MySQL [(none)]> 
    

Nginx和PHP服务搭建

  1. 创建k8s_discuz/nginx_php目录,编辑web-pv.yaml文件创建PV:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: web-pv
    spec:
      capacity:
        storage: 10Gi
      accessModes:
        - ReadWriteMany
      nfs:
        path: /data/shared/discuz/web
        server: 192.168.8.33
    
    [root@master1 nginx_php]# kubectl create -f web-pv.yaml
    persistentvolume/web-pv created
    [root@master1 nginx_php]# kubectl get pv
    NAME       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                 STORAGECLASS   REASON   AGE
    mysql-pv   10Gi       RWX            Retain           Bound       default/mysql-claim                           5h26m
    pv01       10Gi       RWX            Retain           Bound       default/myclaim                               25h
    web-pv     10Gi       RWX            Retain           Available                                                 6s
    
  2. 创建web-pvc.yaml文件用于创建web的PVC:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: web-claim
      labels:
        app: discuz
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 10Gi
    
    [root@master1 nginx_php]# kubectl get pvc
    NAME          STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    myclaim       Bound    pv01       10Gi       RWX                           25h
    mysql-claim   Bound    mysql-pv   10Gi       RWX                           4h59m
    web-claim     Bound    web-pv     10Gi       RWX                           5s
    
  3. 接着为web服务创建deployment文件web-dp.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dz-web
      labels:
        app: discuz
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: discuz
          tier: nginx-php
      template:
        metadata:
          labels:
            app: discuz
            tier: nginx-php
        spec:
          imagePullSecrets:
          - name: hill-secret
          containers:
          - image: harbor.mez100.com.cn/tnt/nginx-php
            name: dz-web
            ports:
            - containerPort: 9000
            - containerPort: 80
              name: dz-web
            volumeMounts:
            - name: web-persistent-storage
              mountPath: /var/www/html
          volumes:
          - name: web-persistent-storage
            persistentVolumeClaim:
              claimName: web-claim
    
    [root@master1 nginx_php]# kubectl create -f web-dp.yaml
    deployment.apps/dz-web created
    
    [root@master1 nginx_php]# kubectl get pod
    NAME                        READY   STATUS              RESTARTS       AGE
    dz-mysql-5c4fc65868-hrvvh   1/1     Running             0              39m
    dz-web-8594b474f9-w52nw     0/1     ContainerCreating   0              40s
    
    [root@master1 nginx_php]# kubectl get pod
    NAME                        READY   STATUS    RESTARTS   AGE
    dz-mysql-5c4fc65868-hrvvh   1/1     Running   0          91m
    dz-web-8594b474f9-qd6cv     1/1     Running   0          6m33s
    
    
  4. 为web服务创建service文件web-svc.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: dz-web
      labels:
        app: discuz
    spec:
      ports:
        - port: 80
      selector:
        app: discuz
        tier: nginx-php
    
    [root@master1 nginx_php]# kubectl create -f web-svc.yaml
    service/dz-web created
    
    [root@master1 nginx_php]# kubectl get svc
    NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    dz-mysql     ClusterIP   10.68.244.100   <none>        3306/TCP   90m
    dz-web       ClusterIP   10.68.36.245    <none>        80/TCP     5s
    kubernetes   ClusterIP   10.68.0.1       <none>        443/TCP    8d
    
    [root@master1 nginx_php]# curl 10.68.36.245
    <html>
    <head><title>403 Forbidden</title></head>
    <body>
    <center><h1>403 Forbidden</h1></center>
    <hr><center>nginx/1.18.0</center>
    </body>
    </html>
    

安装Discuz

  1. 下载discuz安装包到nfs的web目录下,将解压缩的upload目录下的所有文件放到nfs的web目录下:

    root@localhost:/data/shared/discuz/# mv upload/* web/
    root@localhost:/data/shared/discuz/web# ls
    admin.php  archiver     crossdomain.xml  forum.php  index.php  member.php  portal.php  source    uc_client
    api        config       data             group.php  install    misc.php    robots.txt  static    uc_server
    api.php    connect.php  favicon.ico      home.php   m          plugin.php  search.php  template
    
    
  2. 根据php的www.conf文件内定义的user和group用户,修改discuz代码文件的用户组和属组:

    chown -R 100 data/ uc_server/data/ uc_client/data/ config/

  3. 登录mysql,创建MySQL 数据库和普通用户:

    MySQL [(none)]> create database discuz;
    Query OK, 1 row affected (0.08 sec)
    
    MySQL [(none)]> grant all on discuz.* to 'dz'@'%' identified by '123456';
    Query OK, 0 rows affected, 1 warning (0.05 sec)
    
  4. 由于前面的web-svc.yaml文件内没有定义NodePort,所以只能用集群内的ClusterIP访问,修改web-svc.yaml为pod增加NodePort,方便访问:

    apiVersion: v1
    kind: Service
    metadata:
      name: dz-web
      labels:
        app: discuz
    spec:
      type: NodePort
      ports:
      - name: dz-http
        port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: discuz
        tier: nginx-php
    

    这里没有定义具体的NodePort端口号,是为了让k8s集群为我们自动分配,如果想要自定义,则可以在targetPort下增加nodePort: 30080配置,端口号必须在30000以上。

    删除原有的service,重新创建service:

    [root@master1 nginx_php]# kubectl delete -f web-svc.yaml
    [root@master1 nginx_php]# kubectl create -f web-svc.yaml
    
    [root@master1 nginx_php]# kubectl get svc
    NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    dz-mysql     ClusterIP   10.68.244.100   <none>        3306/TCP       18h
    dz-web       NodePort    10.68.90.27     <none>        80:30803/TCP   16h
    kubernetes   ClusterIP   10.68.0.1       <none>        443/TCP        9d
    
    

    然后就可以使用master或node的IP加上NodePort端口号访问到discuz安装页面。

  5. 在不配置NodePort的情况下,也可以配置一个k8s集群外面的nginx反向代理,代理Cluster-IP来实现外部访问,nginx配置文件如下:

    server {
                listen 80;
                server_name dz.evobot.cn;
    
                location / {
                    proxy_pass      http://10.68.90.27:80;
                    proxy_set_header Host   $host;
                    proxy_set_header X-Real-IP      $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
    }
    
    [root@master1 conf.d]# kubectl get svc
    NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    dz-mysql     ClusterIP   10.68.244.100   <none>        3306/TCP       19h
    dz-web       NodePort    10.68.90.27     <none>        80:30803/TCP   16h
    kubernetes   ClusterIP   10.68.0.1       <none>        443/TCP        9d
    

    启动nginx并配置本地host后,就可以在浏览器内访问discuz安装页面,在安装时,数据库服务器的地址可以直接填写MySQL的service name,不需要填写IP,即填写dz-mysql: