以kubernates建立node.js services範例

shangrex
9 min readJul 12, 2021

--

環境

OS: Ubuntu 20.04
node.js: v10.19.0
Docker version 20.10.7, build f0df350
npm: 6.14.4

kubernates介紹(k8s)

在大型的公司中,多個Nodes與多個services可以形成high availbility、load balancing和no single point failure的系統,但是管理上會比較複雜。在k8s之前,多數人管理docker containers時,都會選擇使用docker compose管理或是有其他公司所開發的工具,但往往會發現更新版本時或是管理上非常麻煩。以google所開發的k8s可以輕鬆管理龐大的服務並且維護上面方便,在推出沒多久,便成為主流。

架構

picture reference

Pod: 一個docker-compose中的最小單位,可以共用IP address、file system和network namespace

Replica set: 控制Pod的數量,若是其中一個pod被刪掉它會自動新增一個以控制數量。

Deployment: 若是想要升級版本時,可以使用deployment做rolling update

DaemonSet: 確保所有Nodes中都有一個Pod。並且做log collection daemon、storage daemon和monitoring daemon。

實例

建立key_value的service

和之前一樣的key_value service,Dockerfile大概長這樣

#首先先load node的images,來當作web app
FROM node:14
#建立自己的work dir,改成自己的資料位置
WORKDIR /home/shangrex/program/k8s/
#把package.json複製進去
COPY package*.json ./
RUN npm install
#bundle app source
COPY . .
#打開5001 port
EXPOSE 3000
#執行command
CMD ["node", "key_value.js"]

建立好docker image,key_value:service可以替換成自己的image名稱

sudo docker build . -t key_value:service

觀察建立好的image

sudo docker image ls

若是要測試docker image,-d 後加上自己的id

sudo docker run  -p 3000:3000  -d 47335cf366a5

可以發現建立好docker container之後功能是正常的

Install kubernates

k8s使用官網的教學
minikube 官網安裝
利用snap快速安裝

snap install kubectl --classic
kubectl version --client

安裝minikube來做模擬k8s

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

啟用minikube

minikube start

正常情況下會會因為group&權限而出錯,參考官網解決辦法

再次啟用

minikube start --driver=docker

Deployment

先去dockerhub辦帳號,把建好的images上傳道dockerhub
create repo按下去後,選擇public,並按照他的要求上傳image

CLI大致上如下

:後面為tag,可以改成自己想要的tag
全部都做好後便可以準備撰寫yaml,要先使用指令docker login登入

建好basic_deploy.yaml檔案,replica set為3,image name為push上docker hub的名稱。service名稱為nodejs-deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nodejs
template:
metadata:
labels:
app: nodejs
spec:
containers:
- name: my-first-container
image: shangrex/key_value:new
ports:
- containerPort: 3000

正式deploy,若是要用簡單的image可以用kubectl run — image=<docker_image>
若是要用檔案的話,指令如下,建立自己的yaml file

kubectl create -f basic_deploy.yaml

觀察services

kubectl get  deployment.apps/nodejs-deployment

觀察pod

kubectl get services

Expose

暴露port(這邊還是在minikube裡)

kubectl expose deployment nodejs-deployment --type=NodePort --port=3000

使用port-fowarding讓外面可以連到裡面

kubectl port-forward service/nodejs-deployment 3000:3000

key_value基本測試

Cronjob

以官網的例子來練習minicube的cronjob
可以看到在spec.schedule底下的排程
由左到右分別是

  • 分鐘
  • 小時
  • 每月中第幾天
  • 星期幾
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure

建立cronjob

kubectl create -f cronjob.yaml

查看cronjob

kubectl get jobs --watch

Debug

Delete Deployment

若是create deployment之後,想要刪除pods時發現刪不掉,這是因為deployment還存在,它會繼續去create一個新的,所以要刪掉的是deployent

list all deployments

kubectl get deployments --all-namespaces

delete specify deployments

kubectl delete -n NAMESPACE deployment 
#或是
kubectl delete deployment nodejs-deployment

kubectl create problem

發現image似乎沒有抓到
可能原因

  1. image 名稱打錯
  2. yaml 格式錯誤
    可以用去看格式
  • kubectl apply -f basic_deploy.yaml

kubectl check

查看logs

kubectl describe pods $pods_name

查看component status

kubectl get deployment
kubectl get pods
kubectl get cronjob
kubectl get services

Reference

kubectl build
k8s nodejs yaml example
k8s daemonset example

Author: Shangrex

若有錯誤或是建議請多多指出,作者會改進!!

--

--

shangrex

CS student in UIUC from Taiwan, Love to read books , travel around the world and play LOL