Kubernetes是容器集羣管理系統,是一個開源的平臺,能夠實現容器集羣的自動化部署、自動擴縮容、維護等功能。能夠在物理或虛擬機的Kubernetes集羣上運行容器化應用,Kubernetes能提供一個以「容器爲中心的基礎架構」。若是你曾經用過Docker容器技術部署容器,那麼能夠將Docker當作Kubernetes內部使用的低級別組件。Kubernetes不只僅支持Docker,還支持Rocket,這是另外一種容器技術。前端
經過Kubernetes你能夠:node
想理解Kubernetes集羣,須要先搞明白其中的幾個重要概念。docker
Deployment負責建立和更新應用,當建立Deployment後,Kubernetes master 會將Deployment建立好的應用實例調度到集羣中的各個節點。
應用實例建立完成後,Kubernetes Deployment Controller會持續監視這些實例。若是管理實例的節點被關閉或刪除,那麼 Deployment Controller將會替換它們,實現自我修復能力。api
建立Deployment時,Kubernetes會建立了一個Pod來託管應用。Pod是Kubernetes中一個抽象化概念,由一個或多個容器組合在一塊兒得共享資源。Pod是獨立運行的基本單位,包含一組容器和卷。同一個Pod裏的容器共享同一個網絡命名空間,可使用localhost互相通訊。Pod是短暫的,不是持續性實體。
當在Kubernetes上建立Deployment時,該Deployment將會建立具備容器的Pods(而不會直接建立容器),每一個Pod將被綁定調度到Node節點上,並一直保持在那裏直到被終止(根據配置策略)或刪除。在節點出現故障的狀況下,羣集中的其餘可用節點上將會調度以前相同的Pod。瀏覽器
一個Pod老是在一個(Node)節點上運行,Node是Kubernetes中的工做節點,能夠是虛擬機或物理機。每一個Node由 Master管理,Node上能夠有多個pod,Kubernetes Master會自動處理羣集中Node的pod調度,同時Master的自動調度會考慮每一個Node上的可用資源。服務器
Replication Controller確保任意時間都有指定數量的Pod「副本」在運行。若是爲某個Pod建立了Replication Controller而且指定3個副本,它會建立3個Pod,而且持續監控它們。若是某個Pod不響應,那麼Replication Controller會替換它。若是在運行中將副本總數改成5,Replication Controller會馬上啓動2個新Pod,保證總數爲5。網絡
事實上,Pod是有生命週期的。當一個工做節點(Node)銷燬時,節點上運行的Pod也會銷燬,而後經過ReplicationController動態建立新的Pods來保持應用的運行。
舉個例子,考慮一個圖片處理 backend,它運行了3個副本,這些副本是可互換的 —— 前端不須要關心它們調用了哪一個 backend 副本。也就是說,Kubernetes集羣中的每一個Pod都有一個獨立的IP地址,所以須要有一種方式來自動協調各個Pod之間的變化,以便應用可以持續運行。
Kubernetes中的Service 是一個抽象的概念,它定義了Pod的邏輯分組和一種能夠訪問它們的策略,讓你的這組Pods能被Service訪問。藉助Service,能夠方便的實現服務發現與負載均衡。
Service能夠被指定四種類型:架構
你能夠賦予標籤(鍵值對)來標識你的Pod、Deployment、Service。以後就能夠經過選擇標籤來作具體的指令。負載均衡
本文以 MAC OS X 爲例進行。目標是將簡單的Hello World Node.js應用部署在Kubernetes上運行。所以你可能須要Node.js環境。
Minikube 是一個使咱們很容易在本地運行 kubernetes 的工具,由Kubernetes社區開發。curl
對於Node.js、Docker、VirtualBox的安裝,在這裏不作詳細介紹。能夠直接到官網下載安裝最新穩定版本。
使用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
編寫應用程序。將這段代碼保存在一個名爲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服務器。
在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 .
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
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.
完畢