歡迎光臨
每天分享高質量文章

一分鐘教你快速部署Kubernetes應用

Kubernetes是最近DevOps世界裡最讓人激動的技術了。在過去的幾年裡它吸引了很多人。它瞬間成名的原因是強大的容器技術。
Docker公司推出了偉大的容器產品,讓容器成為了技術領域獨一無二的焦點。Docker成功推動了容器的廣泛使用,然而容器技術的迅猛發展反過來卻讓其變得有點過時了。不過正是因為Docker,Linux容器的使用才會如此流行,這推動了容器編排引擎的發展。
進入Kubernetes時代——Kubernetes由Google開發,Google的基礎架構世界領先,執行多年,支撐著其數十億的容器的執行,Kubernetes則是凝聚了Google這些年實際經驗的結晶。Kubernetes轟動一時,從今年開始,Docker公司支援Kubernetes作為額外的編排引擎選項,和Docker Swarm併列。
從今以後,Kubernetes也將是Docker社群和Docker企業版的一部分。聽上去很不錯吧?各自領域的最佳方案終歸打包在了一起。
概述

Kubernetes,k8s,或稱為kube,是一個開源平臺,可以將容器的運維操作自動化。它消除了絕大部分已有的手工流程,包括部署,擴充套件以及容器化應用程式的管理。
使用Kubernetes,使用者可以將執行容器的主機組放到集群裡。Kubernetes幫助使用者管理這些叢集。這些叢集可以跨越公有雲,私有雲和混合雲——誰知道呢,說不定某一天跨越星球大戰的宇宙。
Kubernetes由Google的工程師團隊開發以及設計。Google很久以來一直就是容器技術的貢獻者。Kubernetes不僅是Google容器技術的活招牌,而且也在背後支撐著Google的雲服務產品。
Google每週部署超過20億個容器。這些都是由稱為Borg的內部平臺支撐的。Borg是Kubernetes的先驅。Google使用Borg多年積累下來的經驗教訓成為了Kubernetes的理念來源。
Kubernetes簡化了部署以及管理容器化應用程式相關的所有事情。Kubernetes將升級,回滾以及已部署服務的健康監控等等工作都自動化了。這讓使用者可以在事情真的變得很糟糕之前避免有問題版本的升級。
另外,Kubernetes可以基於使用情況動態地對服務進行擴容縮容,確保使用者只會在需要的時候執行所需要的實體。和容器一樣,Kubernetes允許使用者管理叢集,做版本控制和複製。
這僅僅是很簡要的概覽,還有更多關於Kubernetes的知識。
Kubernetes是如何工作的?

和Docker的編排方案Docker Swarm相比,Kubernetes是很複雜的系統。要理解Kubernetes是如何工作的,我們需要先理解其底層的理念和原則。
預期狀態(Desired State)

預期狀態是Kubernetes的核心理念之一。使用者可以自由定義Pod內的容器執行狀態。如果因為某種故障該容器停止了執行,Kubernetes會基於預期狀態重新建立Pod。
Kubernetes嚴格確保集群裡執行的所有容器總是在預期狀態下。這是由Kubernetes Master實現的,它是Kubernetes控制平面(Control Plane)的一部分。使用者可以使用kubectl直接和叢集互動,透過Kubernetes API設定或者修改預期狀態。
Kubernetes物件

根據Kubernetes檔案裡所述:
Kubernetes物件是“意圖記錄”——一旦使用者建立了物件,Kubernetes系統會持續工作保證這個物件的存在。使用者透過建立物件來告訴Kubernetes系統自己希望集群裡的工作負載是什麼樣子;這就是叢集的預期狀態。
任意時刻系統裡的物體狀態是由Kubernetes物件來表示的。Kubernetes物件也是容器介面之上的另一層抽象層。使用者可以直接和Kubernetes物件互動,而不用和容器直接互動。基本的Kubernetes物件如下:
  • Pod是節點上的最小的部署單元。它是一組必須一起執行的容器。一般來說,但不是必須的,Pod通常包含一個容器。

  • Service用來定義一組邏輯上存在關係的Pod以及訪問它們的相關策略。

  • Volume是Pod裡所有容器都能訪問的目錄。

  • Namespace是由物理叢集支撐的虛擬叢集。

Kubernetes提供了一些控制器(Controller)。這些控制器基於Kubernetes的基礎物件構建並提供額外的特性。Kubernetes控制器包括:
  • ReplicaSet確保在給定時間執行著特定數量的Pod副本

  • Deployment用來將當前狀態變更到預期狀態

  • StatefulSet用來控制部署順序以及捲的訪問等等。

  • DaemonSet用來在叢集的所有節點或者特定節點執行Pod的複製。

  • Job用來執行一些任務並且在成功完成工作之後或者在給定時間之後退出。

Kubernetes控制平面

Kubernetes控制平面的工作就是確保叢集的當前狀態和使用者的預期狀態一致。要實現這一標的,Kubernetes會自動執行一系列任務——比如,啟動或者重啟容器,擴充套件某個給定應用的副本數量,等等。
Kubernetes檔案定義如下:
Kubernetes控制平面的各個部分,比如Kubernetes Master以及kubelet行程,管控Kubernetes和使用者叢集的通訊。控制平面維護系統裡所有Kubernetes物件的記錄,並且持續執行控制迴路來管理物件的狀態。在任意時間,控制平面的控制迴路會響應叢集的變化,並且讓系統裡所有物件的實際狀態匹配上使用者定義的預期狀態。
Kubernetes控制平面負責維護叢集內的預期狀態。它記錄物件狀態並且持續執行控制迴路去檢查物件的當前狀態是否和預期狀態匹配。你可以把它看作是管理國家的政府。
Kubernetes Master

作為Kubernetes控制平面的一部分,Kubernetes master的工作是持續維護叢集的預期狀態。kubectl命令是透過Kubernetes API和叢集的Kubernetes master通訊的介面。可以看作負責維護法律和秩序的警察機構。
Kubernetes檔案定義:
“master”指的是管理叢集狀態的一組行程。通常這些行程都執行在集群裡的單個節點上,並且該節點也稱為master節點。master也可以被覆制用於實現高可用和冗餘。
Kubernetes Master控制並且協調集群裡的所有節點,包括執行在集群裡一個或者多個master節點上的三個行程:
  1. kube-apiserver:整個叢集的單點管理點。API server實現了RESTful的介面,用於和工具以及庫函式的通訊。kubectl命令直接和API server互動。

  2. kube-controller-manager:透過管理不同型別的控制器來規範叢集的狀態。

  3. kube-scheduler:在集群裡的可用節點上排程工作負載。

Kubernetes節點

Kubernetes節點是集群裡執行工作負載的工作機器(物理的VM或者物理伺服器等)。這些節點由Kubernetes master控制,並且透過持續監控來維護應用程式的預期狀態。之前它們被稱為minion。和master類似,集群裡的每個Kubernetes節點執行兩個行程:
  • kubelet是節點和Kubernetes Master之間的通訊介面。

  • kube-proxy是網路路由,它將每個節點上透過Kubernetes API定義的服務暴露出去。它還能夠執行簡單的TCP和UDP的流轉發。

投票應用

這裡開始嘗試在Kubernetes上實際執行一個應用程式。不過首先需要在本地安裝並執行Kubernetes。
安裝Kubernetes
現在,Kubernetes在Docker社群版17.12+裡開箱即用。如果你沒有安裝社群版,可以在https://www.docker.com/community-edition下載。
安裝MiniKube
在本地執行Kubernetes,需要安裝MiniKube。它會建立一個本地的VM並且執行一個單節點叢集。不要在這上面執行生產叢集。它最好僅用來做開發和測試。
單節點叢集
要執行一個單節點叢集,我們僅僅需要執行minikube start命令。然後,一個VM,一個叢集和Kubernetes就執行起來了。
$ minikube start

Starting local Kubernetes v1.10.0 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 version來驗證環境搭建成功,同時檢查Kubernetes的版本。
$ kubectl version

Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.1", GitCommit:"3a1c9449a956b6026f075fa3134ff92f7d55f812", GitTreeState:"clean", BuildDate:"2018-01-04T20:00:41Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.0", GitCommit:"fc32d2f3698e36b93322a3465f63a14e9f0eaead", GitTreeState:"clean", BuildDate:"2018-03-26T16:44:10Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}

投票應用
這是一個基於微服務架構的簡單應用,包括5個簡單的服務。
  1. Voting-App:應用前端,用Python編寫,使用者使用它來投票

  2. Redis:記憶體內資料庫,作為實時儲存使用

  3. Worker:.Net服務,從Redis裡獲得投票並儲存到Postgres資料庫裡

  4. DB:PostgreSql資料庫,用作資料庫。

  5. Result-App:應用前端,用Node.js編寫,展示投票結果。


Git clone並且cd到投票應用程式的程式碼庫裡。

“k8s-specifications”檔案夾裡包含該投票應用服務的Kubernetes yaml定義。每個服務有兩個yaml檔案:一個服務檔案和一個部署檔案。服務檔案定義pod的邏輯組及其策略。下麵是投票程式裡結果服務的服務檔案:
apiVersion: v1
kind: Service
metadata:
  name: result
spec:
  type: NodePort
  ports:
  - name: "result-service"
    port: 5001
    targetPort: 80
    nodePort: 31001
  selector:
    app: result

部署檔案用來定義應用程式的預期狀態,比如任意時間點應該執行著的副本數量。如下是投票應用的結果部署檔案。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: result
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: result
    spec:
      containers:
      - image: dockersamples/examplevotingapp_result:before
        name: result

建立服務和部署物件:
$ kubectl create -f k8s-specifications/

deployment "db" created
service "db" created
deployment "redis" created
service "redis" created
deployment "result" created
service "result" created
deployment "vote" created
service "vote" created
deployment "worker" created

已經好了!你的應用已經被成功部署到這個單節點集群裡,可以檢視執行著的Pod和服務的串列。
$ kubectl get pods

NAME                      READY     STATUS    RESTARTS   AGE
db-86b99d968f-s5pv7       1/1       Running   0          1m
redis-659469b86b-hrxqs    1/1       Running   0          1m
result-59f4f867b8-cthvc   1/1       Running   0          1m
vote-54f5f76b95-zgwrm     1/1       Running   0          1m
worker-56578c48f8-h7zvs   1/1       Running   0          1m

$ kubectl get svc

NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
db           ClusterIP   10.109.241.59    <none>        5432/TCP         2m
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          23m
redis        ClusterIP   10.102.242.148   <none>        6379/TCP         2m
result       NodePort    10.106.7.255     <none>        5001:31001/TCP   2m
vote         NodePort    10.103.28.96     <none>        5000:31000/TCP   2m

投票應用暴露在30001埠,結果應用暴露在31001埠。你可以使用localhost:port來訪問應用。還可以使用IP訪問,IP可以透過minikube ip命令得到。
Kubernetes命令備忘錄

Minikube命令:
# 啟動Minikube伺服器
$ minikube start

# 得到Minikube IP
$ minikube ip

版本資訊:
$ kubectl version             #得到kubectl版本
$ kubectl cluster-info        #得到叢集資訊

建立物件:
$ kubectl create -f ./file.yml
$ kubectl create -f ./file1.yml -f ./file2.yaml
$ kubectl create -f ./dir
$ kubectl create -f http://www.fpaste.org/279276/48569091/raw/

檢視並且找到資源:

# 列出名稱空間裡的所有服務
$ kubectl get services

# 列出所有名稱空間裡的所有Pod
$ kubectl get pods --all-namespaces

# 列出名稱空間裡的所有Pod,並提供詳細資訊
$ kubectl get pods -o wide

# 列出特定的複製控制器
$ kubectl get rc 

# 列出帶有標簽env=production的所有pod
$ kubectl get pods -l env=production

列出服務,透過名稱排序:
$ kubectl get services --sort-by=.metadata.name

修改以及刪除資源:
$ kubectl label pods  new-label=awesome
$ kubectl annotate pods  icon-url=http://goo.gl/XXBTWq
$ kubectl delete pod pingredis-XXXXX

擴容縮容:
$ kubectl scale --replicas=3 deployment nginx

和執行著的Pod互動:
$ kubectl logs 

#
 執行tail -f 得到日誌輸出
$ kubectl logs -f 

#
 以互動shell執行pod
$ kubectl run -i --tty busybox --image=busybox -- sh

#
 連線到執行著的容器裡
$ kubectl attach  -i

#
 將Pod的埠轉發到本地機器
$ kubectl port-forward  <local-and-remote-port>

#
 將埠轉發到服務
$ kubectl port-forward                 

#
 在已有pod裡執行命令(僅有1個容器的情況下)
$ kubectl exec  -- ls /

#
 在已有pod裡執行命令(多個容器的情況下)
$ kubectl exec  -c  -- ls /

DNS查詢:
$ kubectl exec busybox -- nslookup kubernetes
$ kubectl exec busybox -- nslookup kubernetes.default
$ kubectl exec busybox -- nslookup kubernetes.default.svc.cluster.local

建立並暴露部署:
$ kubectl run nginx --image=nginx:1.9.12
$ kubectl expose deployment nginx --port=80 --type=LoadBalancer

總結

Kubernetes很酷,很可能就是容器編排的未來。這個技術很贊,值得對容器感興趣的人花時間學習。Kubernetes是非常強大的容器編排引擎,它設計用於自動化部署,擴充套件和操作容器,可以用來增強雲容器化戰略。
好的一面是Kubernetes可以和任何雲產品整合,可以是公有雲,私有雲,混合雲或者多雲。雲供應商,比如AWS和Google,提供了Kubernetes服務,比如Elastic Container Service for Kubernetes(EKS)和Google Kubernetes Engine(GKE)。不好的一面是Kubernetes比Docker自己的容器編排引擎Docker Swarm要複雜的多。
如果你想系統學習Kubernetes,可以參加我們的培訓,3天時間,幫你迅速上手Kubernetes。
Kubernetes專案實戰訓練將於2018年8月17日在深圳開課,3天時間帶你係統掌握Kubernetes本次培訓包括:Docker介紹、Docker映象、網路、儲存、容器安全;Kubernetes架構、設計理念、常用物件、網路、儲存、網路隔離、服務發現與負載均衡;Kubernetes核心元件、Pod、外掛、微服務、雲原生、Kubernetes Operator、叢集災備、Helm等,點選下方圖片檢視詳情。

贊(0)

分享創造快樂