帶你理解Kubernetes,部署一個Node應用

Kubernetes是什麼?

Kubernetes是容器集羣管理系統,是一個開源的平臺,能夠實現容器集羣的自動化部署、自動擴縮容、維護等功能。能夠在物理或虛擬機的Kubernetes集羣上運行容器化應用,Kubernetes能提供一個以「容器爲中心的基礎架構」。若是你曾經用過Docker容器技術部署容器,那麼能夠將Docker當作Kubernetes內部使用的低級別組件。Kubernetes不只僅支持Docker,還支持Rocket,這是另外一種容器技術。前端

經過Kubernetes你能夠:node

  • 自動化容器的部署和複製
  • 快速擴展應用
  • 將容器組織成組,而且提供容器間的負載均衡
  • 無縫對接新的應用功能

想理解Kubernetes集羣,須要先搞明白其中的幾個重要概念。docker

Deployment

Deployment負責建立和更新應用,當建立Deployment後,Kubernetes master 會將Deployment建立好的應用實例調度到集羣中的各個節點。
應用實例建立完成後,Kubernetes Deployment Controller會持續監視這些實例。若是管理實例的節點被關閉或刪除,那麼 Deployment Controller將會替換它們,實現自我修復能力。api

Pod

建立Deployment時,Kubernetes會建立了一個Pod來託管應用。Pod是Kubernetes中一個抽象化概念,由一個或多個容器組合在一塊兒得共享資源。Pod是獨立運行的基本單位,包含一組容器和卷。同一個Pod裏的容器共享同一個網絡命名空間,可使用localhost互相通訊。Pod是短暫的,不是持續性實體。
當在Kubernetes上建立Deployment時,該Deployment將會建立具備容器的Pods(而不會直接建立容器),每一個Pod將被綁定調度到Node節點上,並一直保持在那裏直到被終止(根據配置策略)或刪除。在節點出現故障的狀況下,羣集中的其餘可用節點上將會調度以前相同的Pod。瀏覽器

Node

一個Pod老是在一個(Node)節點上運行,Node是Kubernetes中的工做節點,能夠是虛擬機或物理機。每一個Node由 Master管理,Node上能夠有多個pod,Kubernetes Master會自動處理羣集中Node的pod調度,同時Master的自動調度會考慮每一個Node上的可用資源。服務器

Replication Controller

Replication Controller確保任意時間都有指定數量的Pod「副本」在運行。若是爲某個Pod建立了Replication Controller而且指定3個副本,它會建立3個Pod,而且持續監控它們。若是某個Pod不響應,那麼Replication Controller會替換它。若是在運行中將副本總數改成5,Replication Controller會馬上啓動2個新Pod,保證總數爲5。網絡

Service

事實上,Pod是有生命週期的。當一個工做節點(Node)銷燬時,節點上運行的Pod也會銷燬,而後經過ReplicationController動態建立新的Pods來保持應用的運行。
舉個例子,考慮一個圖片處理 backend,它運行了3個副本,這些副本是可互換的 —— 前端不須要關心它們調用了哪一個 backend 副本。也就是說,Kubernetes集羣中的每一個Pod都有一個獨立的IP地址,所以須要有一種方式來自動協調各個Pod之間的變化,以便應用可以持續運行。
Kubernetes中的Service 是一個抽象的概念,它定義了Pod的邏輯分組和一種能夠訪問它們的策略,讓你的這組Pods能被Service訪問。藉助Service,能夠方便的實現服務發現與負載均衡。
Service能夠被指定四種類型:架構

  • ClusterIP - 在集羣中內部IP上暴露服務。此類型使Service只能從羣集中訪問。
  • NodePort - 經過每一個 Node 上的 IP 和靜態端口(NodePort)暴露服務。NodePort 服務會路由到 ClusterIP 服務,這個 ClusterIP 服務會自動建立。經過請求 <NodeIP>:<NodePort>,能夠從集羣的外部訪問一個 NodePort 服務。
  • LoadBalancer - 使用雲提供商的負載均衡器(若是支持),能夠向外部暴露服務。外部的負載均衡器能夠路由到 NodePort 服務和 ClusterIP 服務。(通常經常使用此類型向外暴露端口,並作負載均衡)
  • ExternalName - 經過返回 CNAME 和它的值,能夠將服務映射到 externalName 字段的內容,沒有任何類型代理被建立。

Label

你能夠賦予標籤(鍵值對)來標識你的Pod、Deployment、Service。以後就能夠經過選擇標籤來作具體的指令。負載均衡

使用Minikube在kubernetes中部署第一個應用

本文以 MAC OS X 爲例進行。目標是將簡單的Hello World Node.js應用部署在Kubernetes上運行。所以你可能須要Node.js環境。
Minikube 是一個使咱們很容易在本地運行 kubernetes 的工具,由Kubernetes社區開發。curl

準備工做

  1. Node.js
  2. Docker
  3. VM - VirtualBox
  4. Minikube
  5. Kubectl

對於Node.js、Docker、VirtualBox的安裝,在這裏不作詳細介紹。能夠直接到官網下載安裝最新穩定版本。

建立Minikube集羣

使用curl下載並安裝最新版本Minikube:

$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 && \
  chmod +x minikube && \
  sudo mv minikube /usr/local/bin/

使用Homebrew下載kubectl命令管理工具:

$ brew install kubectl

默認的VM驅動程序VirtualBox,所以可直接啓動Minikube:

$ minikube start

接下來會打印出相似信息...

Starting local Kubernetes v1.9.4 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.

驗證kubectl是否安裝成功:

$ kubectl cluster-info

會打印出相似的信息:

Kubernetes master is running at https://192.168.99.100:8443

建立Node.js應用

編寫應用程序。將這段代碼保存在一個名爲hellonode的文件夾中,文件名server.js:

var http = require('http');

var handleRequest = function(request, response) {
  console.log('Received request for URL: ' + request.url);
  response.writeHead(200);
  response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(3000);

啓動應用:

$ node server.js

如今能夠在 http://localhost:3000 中查看到「Hello World!」消息。
Ctrl-C中止正在運行的Node.js服務器。

建立Docker容器鏡像

在hellonode文件夾中建立一個Dockerfile命名的文件。

FROM node:8.10.0
EXPOSE 3000
COPY server.js .
CMD node server.js

咱們使用Minikube,而不是將Docker鏡像push到registry,可使用與Minikube VM相同的Docker主機構建鏡像,以使鏡像自動存在。爲此,請確保使用Minikube Docker守護進程:

$ eval $(minikube docker-env)

注意:若是不在使用Minikube主機時,能夠經過運行eval $(minikube docker-env -u)來撤消此更改。

使用Minikube Docker守護進程build Docker鏡像:

$ docker build -t hello-node:v1 .

建立Deployment

Kubernetes Deployment 是檢查Pod的健康情況,若是它終止,則從新啓動一個Pod的容器,Deployment管理Pod的建立和擴展。

使用kubectl run命令建立Deployment來管理Pod。

$ kubectl run hello-node --image=hello-node:v1 --port=3000

查看Deployment:

$ kubectl get deployments

輸出:

NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-node   1         1         1            1           5s

查看Pod:

$ kubectl get pods

輸出:

NAME                          READY     STATUS    RESTARTS   AGE
hello-node-6ddb5576c9-644xn   1/1       Running   0          1m

查看deployment的詳細信息:

$ kubectl describe deployment

建立Service

Pod只能經過Kubernetes羣集內部IP訪問。要使hello-node容器能從Kubernetes虛擬網絡外部訪問,需要使用Kubernetes Service暴露Pod。

咱們可使用kubectl expose命令將Pod暴露到外部環境:

$ kubectl expose deployment hello-node --type=LoadBalancer

查看Service:

$ kubectl get services

輸出:

NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
hello-node   LoadBalancer   10.110.94.17   <pending>     8080:32081/TCP   2m
kubernetes   ClusterIP      10.96.0.1      <none>        443/TCP          6d

查看詳細信息:

$ kubectl describe service hello-node

輸出:

Name:                     hello-node
Namespace:                default
Labels:                   run=hello-node
Annotations:              <none>
Selector:                 run=hello-node
Type:                     LoadBalancer
IP:                       10.110.94.17
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  32081/TCP
Endpoints:                172.17.0.5:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

經過--type=LoadBalancer 來在羣集外暴露Service,在支持負載均衡的雲提供商上,將配置外部IP(EXTERNAL-IP,在Minikube顯示爲:<pending>)地址來訪問Service。在Minikube上,該LoadBalancer type使服務能夠經過minikube Service 命令訪問。

$ minikube service hello-node

將打開瀏覽器,在本地IP地址爲應用提供服務,顯示「Hello World」的消息。

能夠查看到日誌:

$ kubectl logs <pod-name>  //exp: kubectl logs hello-node-6ddb5576c9-644xn
// 可經過 kubectl get pods 查看pod-name

擴展實例

根據線上需求,擴容和縮容是常會遇到的問題。Scaling 是經過更改 Deployment 中的副本數量實現的。一旦有多個實例,就能夠滾動更新,而不會中止服務。經過kubectl scale指令來擴容和縮容。

$ kubectl scale deployments/hello-node --replicas=4

在查看pods:

$ kubectl get pods

輸出:

NAME                         READY     STATUS    RESTARTS   AGE
hello-node-9f5f775d6-6qdmn   1/1       Running   0          3s
hello-node-9f5f775d6-9mrm6   1/1       Running   0          3s
hello-node-9f5f775d6-jxb8z   1/1       Running   0          3s
hello-node-9f5f775d6-tx8kg   1/1       Running   0          11m

總共有4個實例,那麼就可經過Service 的 --type=LoadBalancer 進行負載均衡。

更新應用程序

編輯server.js文件以返回新消息:

response.end('Hello World Again!');

docker build新版本鏡像:

$ docker build -t hello-node:v2 .

Deployment更新鏡像:

$ kubectl set image deployment/hello-node hello-node=hello-node:v2

再次在瀏覽器查看消息:

$ minikube service hello-node

清理刪除

刪除在羣集中建立的資源:

$ kubectl delete service hello-node
$ kubectl delete deployment hello-node

查看pods:

$ kubectl get pods

輸出:

NAME                         READY     STATUS        RESTARTS   AGE
hello-node-9f5f775d6-6qdmn   1/1       Terminating   0          6m
hello-node-9f5f775d6-9mrm6   1/1       Terminating   0          6m
hello-node-9f5f775d6-jxb8z   1/1       Terminating   0          6m
hello-node-9f5f775d6-tx8kg   1/1       Terminating   0          18m

所有在中止中... 稍等一分鐘,再查看,輸出 No resources found.

中止

$ minikube stop

輸出:

Stopping local Kubernetes cluster...
Machine stopped.

完畢

相關文章
相關標籤/搜索