High Available Wordpress with Kubernetes <2>
在上篇中學到了 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 唷!
請繼續看下去
查看原文 >>