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

一分鐘教你快速部署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)

分享創造快樂