Published on

Cài đặt wordpress trên Kubernetes

Bài viết này sẽ giới thiệu cách cài đặt 1 website dùng Wordpress trên Kubernetes cluster.

Cài đặt MySQL trên Kubernetes

MySQL Deployment

mysql-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: website-mysql
  namespace: website
  labels:
    app: website-mysql
spec:
  selector:
    matchLabels:
      app: website-mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: website-mysql
    spec:
      containers:
        - image: mysql:5.6
          name: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql
                  key: password
            - name: MYSQL_DATABASE
              valueFrom:
                secretKeyRef:
                  name: mysql
                  key: db_name
            - name: MYSQL_USER
              valueFrom:
                secretKeyRef:
                  name: mysql
                  key: db_user
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql
                  key: db_pass
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql
          persistentVolumeClaim:
            claimName: website-mysql-pvc

Sau khi deploy file yaml này thì 1 MySQL server được tạo trong namespace wordpress đồng thời 1 database với tên, user, password truy cập được khởi tạo thông qua việc truyền các giá trị vào 3 env MYSQL_DATABASE, MYSQL_USERMYSQL_PASSWORD, đây là thông tin nhạy cảm nên sẽ được lưu trong 1 secretKey tên là mysql sẽ được nói đến ở phần secrets.yaml

MySQL Service

mysql-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: website-mysql
  namespace: website
  labels:
    app: website-mysql
spec:
  ports:
    - port: 3306
  selector:
    app: website-mysql

MySQL Volume

Trong ví dụ của mình dùng Persistent Volume NFS, các bạn có thể dùng loại PV khác cũng được. Trong đó:

  • 10.110.0.101: là IP của NFS server
  • /mnt/nfsdata/website/mysql: là folder lưu data của MySQL trên NFS server

mysql-volume.yaml:

kind: PersistentVolume
apiVersion: v1
metadata:
  name: website-mysql-pv
  namespace: website
  labels:
    app: website-mysql
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Recycle
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    server: 10.110.0.101
    path: '/mnt/nfsdata/website/mysql'
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: website-mysql-pvc
  namespace: website
  labels:
    app: website-mysql
spec:
  selector:
    matchLabels:
      app: website-mysql
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  volumeMode: Filesystem
  volumeName: website-mysql-pv

Cài đặt Wordpress trên Kubernetes

Wordpress Deployment

Các thông số cần quan tâm:

  • WORDPRESS_DB_HOST: đây là địa chỉ của MySQL server chưa database của wordpress và cũng chính là service name của MySQL đã deploy ở trên.
  • WORDPRESS_DB_NAME: Tên của database
  • WORDPRESS_DB_USER: Tên của user có quyền access vào database ở trên
  • WORDPRESS_DB_PASSWORD: Mật khẩu của user đó
  • WORDPRESS_TABLE_PREFIX: tùy chọn giúp thay đổi prefix của wordpress database, mặc định là wp

wordpress-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: website-wp
  namespace: website
  labels:
    app: website-wp
spec:
  selector:
    matchLabels:
      app: website-wp
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: website-wp
    spec:
      containers:
        - image: wordpress:5.8-apache
          imagePullPolicy: IfNotPresent
          name: wordpress
          env:
            - name: WORDPRESS_DB_HOST
              value: website-mysql
            - name: WORDPRESS_DB_NAME
              valueFrom:
                secretKeyRef:
                  name: mysql
                  key: db_name
            - name: WORDPRESS_DB_USER
              valueFrom:
                secretKeyRef:
                  name: mysql
                  key: db_user
            - name: WORDPRESS_TABLE_PREFIX
              valueFrom:
                secretKeyRef:
                  name: mysql
                  key: db_prefix
            - name: WORDPRESS_DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql
                  key: db_pass
          ports:
            - containerPort: 80
              name: wordpress
          volumeMounts:
            - name: wordpress-files
              mountPath: /var/www/html
      volumes:
        - name: wordpress-files
          persistentVolumeClaim:
            claimName: website-wp-pvc

Wordpress service

wordpress-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: website-wp
  namespace: website
  labels:
    app: website-wp
spec:
  ports:
    - port: 80
  selector:
    app: website-wp
  type: LoadBalancer

Wordpress Volumme

wordpress-volume.yaml

kind: PersistentVolume
apiVersion: v1
metadata:
  name: website-wp-pv
  namespace: website
  labels:
    app: website-wp
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 10.110.0.101
    path: '/mnt/nfs/website/www'
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: website-wp-pvc
  namespace: website
  labels:
    app: website-wp
spec:
  selector:
    matchLabels:
      app: website-wp
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  volumeName: website-wp-pv

Xem thêm bài viết Thiết lập và dụng NFS Persistent Volume trên Kubernetes để hiểu rõ hơn về NFS PVC.

Secrets chưa thông tin nhạy cảm

Như đã nói ở trên, 1 số thông tin nhạy cảm như Mật khấu, user của database không nên được thể hiện trong file yaml. Chúng ta nên tạo 1 file secrets để chứa các thông tin đó.

secrets.yaml

Các giá trị db_prefix, db_name, ... là các chuỗi ký tự được encode bằng base64

apiVersion: v1
kind: Secret
metadata:
  name: mysql
  namespace: website
  labels:
    app: website-wp
type: Opaque
data:
  db_prefix: d3Bf
  db_name: ZGVtbw==
  db_user: ZGVtby11c2Vy
  db_pass: ZGVtby1wYXNz
  username: bXlzcWwtYWRtaW4=
  password: bXlwYXNz

Ingress

Thiết lập Ingress resouce, bây giờ bạn có thể truy cập vào wordpress thông qua địa chỉ https://website.com

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: website
  namespace: website
  labels:
    app: website-wp
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/add-base-url: 'true'
    nginx.ingress.kubernetes.io/proxy-body-size: '0'
spec:
  tls:
    - hosts:
        - website.com
      secretName: ssl-website.com
  rules:
    - host: website.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: website-wp
                port:
                  number: 80

Sau khi đã tạo hết các file đó, chúng ta chạy kubectl để cài đặt và thiết lập trang web wordpress lên Kubernetes cluster

kubectl create namespace website
kubectl apply -f .\secrets.yaml
kubectl apply -f .\mysql-volume.yaml
kubectl apply -f .\wordpress-volume.yaml
kubectl apply -f .\mysql-deployment.yaml
kubectl apply -f .\wordpress-deployment.yaml
kubectl apply -f .\mysql-service.yaml
kubectl apply -f .\wordpress-service.yaml
kubectl apply -f .\ingress.yaml