Docker玩了一陣子,總覺得沒有玩一些container management的service好像少了點什麼,
剛好team裡用到Kubernetes,所以這裡就記錄一下怎麼使用Kubernetes。
然後這篇會把Kubernetes架在Google Cloud Platform上面,所以還得去安裝Google Cloud SDK。
1. Downloading Kubernetes
第一步驟要先安裝Kubernetes,安裝方式有好幾種,
- tarball解開
- Build from source
- Homebrew
- Remote shell script
- 用Google Cloud SDK安裝
各個的詳細步驟可以去Kubernetes安裝頁面看,我自己是選擇透過Google Cloud SDK來安裝,所以首先要先安裝Google Cloud SDK。
安裝Google Cloud SDK
Google Cloud SDK這個tool讓你可以對Google Cloud Platform進行操作。安裝指令如下,Default installation path會在你的home目錄底下,
$ curl https://sdk.cloud.google.com | bash
接著要restart shell和設定gcloud environment,gcloud init
這個指令會彈出browser要你login,以及要你輸入default zone,我是選asia-east1-a。
$ exec -l $SHELL
$ gcloud init
安裝kubectl
$ gcloud components install kubectl
2. Setup Google Cloud
在這步驟要做幾件事情,
- 註冊Google Cloud
- Create project
- 打開billing
- 開啟Container Engine API.
Step 1. 註冊Google Cloud
點了上面的連結至console以後,就發現其實是以前的Google App Engine+Google APIs的後台,
只不過好久沒用了,發現改版改好多..
然後又發現新註冊的user有免費300美金的quota可以使用,
舊有的用戶還沒有這300美金可以用,所以建議可以乾脆註冊新帳號使用比較好。
Step 2: Create project
有了帳號以後,就去Create project,Create時的project名稱,
如果project名稱沒有重複的話,應該就會是你的PROJECT_ID
。
Step 3: 打開billing
這一步驟就是點這個連結去打開Billing,進去以後要填寫信用卡資料,目的是將來要收費,
不過如果你是新註冊的話,一開始先不用擔心這個問題,因為有300美金可以使用。
Step 4: 開啟Container Engine API
接著要去Enable Container Engine API,點這個連結去enable,進去以後就選取剛剛create的project,然後按下Continue。(如下圖)
3. Create your Node.js application
接著來寫一個簡單的Node.js application,等等會把這application包成docker image,
先create一個folder,然後建立一個server.js,
$ mkdir hellonode-app
$ cd hellonode-app
$ vim server.js
再把下面的內容貼入到server.js當中,下面的內容就是建立一個http server,且listen在8080 port上,
var http = require('http');
var handleRequest = function(request, response) {
response.writeHead(200);
response.end("Hello World!");
}
var www = http.createServer(handleRequest);
www.listen(8080);
4. Create and Push a Docker container image
接著要把上面的application變成一個docker image以及把image push上去,所以首先要先建立一個Dockerfile
,Dockerfile作用在之前的文章就有解釋過了,
簡單說就是用來定義這個image的資訊。
FROM node:0.12
EXPOSE 8080
COPY server.js .
CMD node server.js
有了Dockerfile
以後,就可以來build image了,記得把下面的ken-kubernetes-lab
換成你們自己的project id,
$ docker build -t gcr.io/ken-kubernetes-lab/hello-node:v1 .
build完以後,可以在自己local測試看看,
$ docker run -d -p 8080:8080 gcr.io/ken-kubernetes-lab/hello-node:v1
$ curl http://localhost:8080
接著就可以把image push上去Google Container Registry,
$ gcloud docker push gcr.io/ken-kubernetes-lab/hello-node:v1
5. Create a cluster
接著去console,建立一個cluster,如下圖。
建完以後,就把cluster的info餵給kubectl,記得把cluster-1
改成你的cluster名稱。
$ gcloud container clusters get-credentials cluster-1
6. Create a pod
pod
在kubernetes的定義是pods are the smallest deployable units of computing that can be created and managed in Kubernetes.
,
簡單說,如果你要在kubernetes的cluster裡面run起來一組
container,就得有一個pod,
一組
container的意思是,這個pod裡面由一個以上的container所組成。
用kubectl run來建立一個pod:
$ kubectl run hello-node --image=gcr.io/ken-kubernetes-lab/hello-node:v1 --port=8080
deployment "hello-node" created
如上面的output所示,kubectl run
建立了一個deployment
,deployment
主要是用來建立或者scale一個pod的一種方式,以這個例子來說,deployment管理了1個pod replica,想看deployment的資訊,就打:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-node 1 1 1 1 3d
7. Allow external traffic
pod預設只能被內部access,如果想要讓外部存取,必須把pod
expose成一個service
:
$ kubectl expose deployment hello-node --type="LoadBalancer"
你會發現上面的指令,我們是expose deployment這個object出來,而不是pod,
如上面所說,deployment可能會管理多個pods,所以可以透過deployment來當作load balancer。
取得service ip的指令,請打:
$ kubectl get services hello-node
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node 10.123.244.242 130.211.247.198 8080/TCP 3d
EXTERNAL_IP
可能需要一點點時間才會顯示出來,所以如果EXTERNAL_IP
一開始是空白的,請等一下再試一次。
8. Scale up your website
Kubernetes其中最強大的一點就是可以很輕鬆的scale你的application,
假設你的application突然需要更多的capacity,你可以簡單地叫deployment
去建立新的replica:
$ kubectl scale deployment hello-node --replicas=4
現在你的application就有4個replicas,每一個獨立地在cluster中運作,且load balancer去serve traffic。
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-node 4 4 4 4 3d
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-node-3344141985-j2zun 1/1 Running 0 2m
hello-node-3344141985-j70fh 1/1 Running 0 2m
hello-node-3344141985-lzynx 1/1 Running 0 3d
hello-node-3344141985-x3ycw 1/1 Running 0 2m
9. Roll out an upgrade to your website
假設你的application有bug fixes,Kubernetes也可以輕易地幫助你deploy新版本上去。
首先,先來改剛剛的server.js
,修改response message:
response.end("Hello Kubernetes World!");
接著可以build及publish新版本至registry:
$ docker build -t gcr.io/ken-kubernetes-lab/hello-node:v2 .
$ gcloud docker push gcr.io/ken-kubernetes-lab/hello-node:v2
push完成以後,我們就有一個v2版本的image可以使用,接下來只要透過kubectl edit
指令就可以進行update,
這個指令會打開一個text editor,內容是一個deployment的yaml config,
我們只需要把gcr.io/ken-kubernetes-lab/hello-node:v1
改成gcr.io/ken-kubernetes-lab/hello-node:v2
就好。
$ kubectl edit deployment hello-node
編輯完成以後,可以去看看pods有什麼變化:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-node-3344141985-j2zun 1/1 Terminating 0 19m
hello-node-3344141985-j70fh 1/1 Terminating 0 19m
hello-node-3344141985-lzynx 1/1 Terminating 0 3d
hello-node-3344141985-x3ycw 1/1 Terminating 0 19m
hello-node-3422850722-b0niu 1/1 Running 0 13s
hello-node-3422850722-gu7c3 1/1 Running 0 19s
hello-node-3422850722-oaqw7 1/1 Running 0 19s
hello-node-3422850722-ria1t 1/1 Running 0 13s
從output中會發現,deployment建立新的pod,把舊版的pod關掉了。
10. Delete
由於只有300美金啊,雖然我開了三天也才花費五塊美金,不過沒在用還是關掉吧!
刪除Deployment時,也會一併刪除pod;刪除service會刪除load balancer。
$ kubectl delete service,deployment hello-node
最後記得cluster也要刪除:
$ gcloud container clusters delete cluster-1