昨天還沒把整個服務架起來,缺少資料庫的部分。Kubernetes 還有另一種 Object 是 StatefulSet,可以應用在需要保持狀態的服務上。這邊為了簡便先使用 Deployment 來架資料庫。
搭配昨天文章一起服用 → https://ithelp.ithome.com.tw/articles/10322186
跟昨天一樣,建立 deployment、secret、service。MySQL 版本使用 8.1.0
。
Deployment & Secret
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ironman
name: db-deploy
labels:
name: db-deploy
app: prac-node-login
spec:
replicas: 1
selector:
matchLabels:
name: db-pod
app: prac-node-login
template:
metadata:
name: db-pod
labels:
name: db-pod
app: prac-node-login
spec:
containers:
- name: db
image: mysql:8.1.0
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: db-secrets
key: MYSQL_INIT_DATABASE
nodeSelector:
role: "agent"
---
# using --- to separate different spec, then they can be in the same yaml file
apiVersion: v1
kind: Secret
metadata:
namespace: ironman
name: db-secrets
labels:
name: db-secrets
app: prac-node-login
type: Opaque
data:
MYSQL_ROOT_PASSWORD: cm9vdHB3ZDEyMzQ=
MYSQL_INIT_DATABASE: dGVzdA==
port 的部分 MySQL 預設會使用 3306,可以從 docker hub 上的 image tag 點進去看 dockerfile,就能知道當初 build image 時開哪個 port。
環境變數的部分這邊用另一種方式去 refrence secret,可以定義 env name,然後引用 Secret 裡面的 key-value pair。因 MySQL 啟動一定要給 root password,不然會失敗。這邊還定義了 MYSQL_DATABASE 這個環境變數,在啟動 MySQL 的時候就建這個 DB。
這些資訊都可以從 docker hub 上得到 → https://hub.docker.com/_/mysql
Service
apiVersion: v1
kind: Service
metadata:
namespace: ironman
name: db-service
labels:
name: db-service
app: prac-node-login
spec:
# type: ClusterIP
selector: # map the pod label
name: db-pod
app: prac-node-login
ports:
- protocol: TCP
port: 3306
targetPort: 3306
MySQL 接的 Service 就不是 Node Port 這種類型了。如果沒有寫 Type 預設會是 ClusterIP。這個 Service 在 Cluster 中會被分配一個 IP,可以被 Cluster 中的其他 Service / Pod 訪問,但沒有開放給集群外部。
前面提過,Pod 的 IP 會變,所以 Cluster 中 Pod 跟 Pod 的溝通還是要透過 Service。而 Cluster IP 就能在這時候派上用場。以資料庫的應用場景來看,我們不會希望外界的人能夠訪問資料庫,所以 DB 不會開 Node Port ,而是讓其他應用在使用 DB 時透過 Cluster IP Service 連接。
KEY POINT!
那昨天我們建的 web server 是透過什麼資訊才能知道要去哪邊連 MySQL 的呢?
web server 使用的 secret ,裡面設的 MYSQL_HOST
要跟 DB pod 掛的 service name 一樣喔!用 base64 decode 會發現這兩邊是對應的,並且要在相同的 namespace 中。
YAML 檔都寫好後就來跑跑看吧!執行 kubectl apply -f <filename / directory name>
再使用 kubectl get all -n ironman
觀察。
看起來都運作正常。 service
可以看到兩種類型的 service 的不同。
接下來進到 container 中測試一下密碼、database 設置對不對。
# -- 後面接的是操作 mysql 的指令
kubectl exec -it -n ironman <pod_name> -- mysql -uroot -p
預設 superuser 是 root,密碼就是前面 secret 中定義的密碼。利用 show databases;
檢查我們想要建的資料庫有沒有成功建立。
補充一下關於權限的部分,這邊偷懶直接使用 root user,但比較好的做法還是另外建立 user & password 給 app 使用,權限也要限縮哦。
再來就是些手動的部分啦。App 使用的 Table 還是要透過手動的方式進去 Container 中建立。執行下面的 code:
CREATE TABLE user (
id INT AUTO_INCREMENT,
name VARCHAR(70) NOT NULL CHECK (name <> ''),
email VARCHAR(200) NOT NULL CHECK (email <> ''),
password VARCHAR(100) NOT NULL CHECK (password <> ''),
created TIMESTAMP DEFAULT NOW(),
PRIMARY KEY(id)
);
再來就可以測試有沒有辦法註冊以及登入。因昨天我們將 Host port 8081 mapping 到 node 30001 port。這邊要使用 localhost:8081
進入網站。點 SignUp button 註冊一組帳號。
如果註冊成功會有 alert 跳出,並跳轉到 member page。
再測試看看資料庫是否已經存有我們註冊的資料。登出後再 Sign In 一次。
成功的話一樣會看到 alert 並跳轉到 member page。
畫個簡陋的架構圖 -
Day 3 有裝了一個 dashboard,這邊也開一下看看介面。Service Account token 的部分如果不是 long-term token 要記得重新產生。
Day 3 文章連結 → https://ithelp.ithome.com.tw/articles/10320337
Dashboard URL: http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
Dashboard Namespace 選擇 ironman,就可以看到正在跑的 Deployments、Pods、Replica Sets。
左邊也可以選 Services、Secrets 就能看到前面部署的 Services & Secrets。