上篇中學到了 pv、pvc、secret、deployment、replica set、pod ...

這些 kubernetes 潮潮的元件

但距離我們的目標還不到一半

再複習一下,我們的目標是

1.  建一個 kubernetes cluster in GKE

2. 在 kubernetes cluster 中做一個高可用性的 wordpress 服務

3. 演練如何做到 0 downtime 升級 wordpress 

4. 萬一內容一夕爆紅也可以輕易的調整 scale

 

目前我們已經建好 MYSQL 的 pod

接下來我們要做的事纔是重頭戲

首先,我們在上集學過 pv & pvc 

今天 wordpress 一樣需要一個空間來存放我們的內容

如法炮製一個 wp-pv-claim

wordpress-pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

 

別忘了 apply 

▶ kubectl apply -f wordpress-pvc.yaml
persistentvolumeclaim "wp-pv-claim" created

 

再來我們要做最重要的前端部分

新增一個 wordpress 的 deployment

wordpress-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  replicas: 3
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:4.8-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-passwd
              key: password
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: wordpress-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pv-claim

 

這邊一樣可以參考 wordpress docker image

一樣需要定義環境變數

WORDPRESS_DB_PASSWORD 可以共用上篇建立的 secret

但 WORDPRESS_DB_HOST 要指定什麼呢?

因為在 k8s 環境中 pod 是隨時會消失 & 產生

所以我們需要 service 的元件來 mapping 到目前的 pod

所以我們來新增一個 service 

mysql-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None

 

我們透過 selector 選擇 musql deployment 所貼上的 label 來 mapping 到我們指定的 3306 port

在 service 中有三中 type 可以使用

ClusterIP、NodePort、LoadBalancer

ClusterIP 是 k8s 內部所使用的,會對應到指定的內部 port

NodePort 是給 node 層級用的,會在每個 node 開 port 對應到指定的 pod

LoadBalancer 則是給對外連線使用

我們要用的整體架構大概會像這樣

 

到這一步我們的 wordpress & mysql 看似都好了

但!!!你可能會遇到些問題

"我的 pod 怎麼有些不 work ?"

這是因為我們稍早所用的 pvc 的 accessMode: ReadWriteOnce

"是不是改到 ReadWriteMany 就好了啊?"

答案是不行的!!

原因在這個表

這裡明確告訴我們 GCEPersistentDisk 是不支援 ReadWriteMany 的

所以我們要另外想辦法做一個支援 ReadWriteMany 的 Disk 出來

我們來做一個 nfs 的服務讓 wordpress 可以支援 ReadWriteMany

nfs-pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
  labels:
    app: nfs-pvc
spec:
  accessModes: [ "ReadWriteOnce" ]
  resources:
    requests:
      storage: 10Gi

 

然後做一個 pod 來掛載這個 pvc 

nfs-server-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-server
  template:
    metadata:
      labels:
        app: nfs-server
    spec:
      containers:
      - name: nfs-server
        image: k8s.gcr.io/volume-nfs:0.8
        ports:
          - name: nfs
            containerPort: 2049
          - name: mountd
            containerPort: 20048
          - name: rpcbind
            containerPort: 111
        securityContext:
          privileged: true
        volumeMounts:
          - mountPath: /exports
            name: nfs-pvc
      volumes:
        - name: nfs-pvc
          persistentVolumeClaim:
            claimName: nfs-pvc

 

最後要讓這個 pod 可以被內部存取

我們用 ClusterIP type 的 service 來做

預設的 service 就是 ClusterIP

nfs-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nfs-server
  labels:
    app: nfs-server
spec:
  ports:
    - name: nfs
      port: 2049
    - name: mountd
      port: 20048
    - name: rpcbind
      port: 111
  selector:
    app: nfs-server

 

我們可以看到這個 service 拿了一個 ClusterIP

▶ kubectl get svc nfs-server
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
nfs-server   ClusterIP   10.15.252.238   <none>        2049/TCP,20048/TCP,111/TCP   5m

 

接下來我們就可以做 ReadWriteMany 的 pv & pvc 摟!

wordpress-pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: wp-pv
spec:
  storageClassName: "nfs-pv"
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.15.252.238
    path: "/exports"

 

再來把 pvc 加上 storageClassName

wordpress-pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  storageClassName: "nfs-pv"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi

 

移除舊的 pvc + 新增新設定

▶ kubectl delete pvc wp-pv-claim; kubectl apply -f wordpress-pvc.yaml
persistentvolumeclaim "wp-pv-claim" deleted
persistentvolumeclaim "wp-pv-claim" created

▶ kubectl get pvc wp-pv-claim
NAME          STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
wp-pv-claim   Bound     wp-pv     10Gi       RWX            nfs-pv         1m

 

到這邊已經可以看到新的 pvc 是 ReadWriteMany 了

然後 pod 就算再不同 node 也可以 mount 相同的 persistent volume 了!!

▶ kubectl get pod  -o wide
NAME                               READY     STATUS    RESTARTS   AGE       IP           NODE
nfs-server-65d5686f55-frzhj        1/1       Running   0          29m       10.12.0.28   gke-wp-cluster-default-pool-5ef00653-1wwr
wordpress-7bbd67559b-279x5         1/1       Running   0          1h        10.12.1.9    gke-wp-cluster-default-pool-5ef00653-pbzp
wordpress-7bbd67559b-p8drd         1/1       Running   0          1h        10.12.0.26   gke-wp-cluster-default-pool-5ef00653-1wwr
wordpress-7bbd67559b-rvml6         1/1       Running   0          1h        10.12.0.27   gke-wp-cluster-default-pool-5ef00653-1wwr
wordpress-mysql-6dd894df8b-m9fxb   1/1       Running   0          2d        10.12.0.8    gke-wp-cluster-default-pool-5ef00653-1wwr

 

最後我們只需要將 wordpress 依剛剛的架構圖新增一個 LoadBalancer 的 service 就好了!!

wordpress-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer

 

一開始的狀態會是 pending 

那是因為 GKE 正在開一個 Load Balancer

▶ kubectl get service wordpress
NAME        TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
wordpress         LoadBalancer   10.15.244.169   <pending>     80:31446/TCP                 26s

▶ kubectl get service wordpress
NAME        TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
wordpress   LoadBalancer   10.15.244.169   35.221.238.197   80:31446/TCP   5m

 

這麼一來就可以看到 wordpress 已經完成了!

 

再來還有 part3 唷!

請繼續看下去

查看原文 >>
相關文章