1. 程式人生 > >Kubernetes入門--搭建Kubernetes叢集,並啟動容器服務

Kubernetes入門--搭建Kubernetes叢集,並啟動容器服務

英文原作者:Ben Cane  翻譯作者:Miazzy 翻譯&轉載:https://blog.codeship.com/getting-started-with-kubernetes/

 

Kubernetes入門

 

Kubernetes是一個非常受歡迎的開源容器管理系統。Kubernetes專案的目標是跨多個節點管理容器,就像管理單個系統上的容器一樣簡單。為此,它提供了許多獨特的功能,例如流量負載平衡,自我修復(自動重啟),排程,擴充套件和滾動更新。

在今天的文章中,我們將通過在多節點Kubernetes叢集中部署簡單的Web應用程式來了解Kubernetes。然而,在我們開始部署容器之前,我們首先需要設定一個叢集。

 

搭建Kubernetes叢集

官方入門指南將指導您在Google的Container Engine平臺上部署Kubernetes叢集。雖然這是一種快速簡便的啟動和執行方法,但對於本文,我們將使用替代提供程式部署Kubernetes,特別是通過Vagrant。我們使用Vagrant有幾個原因,但主要是因為它顯示瞭如何在通用平臺而不是GCE上部署Kubernetes。

Kubernetes附帶了幾個適用於各種平臺的安裝指令碼。這些指令碼中的大多數使用Bash環境變數來更改Kubernetes的安裝方式和方式。

對於此安裝,我們將定義兩個變數:

  • NUM_NODES
     - 控制要部署的節點數
  • KUBERNETES_PROVIDER - 指定安裝Kubernetes的平臺

讓我們定義安裝指令碼應該使用vagrant平臺並配置2節點叢集。

$ export NUM_NODES=2
$ export KUBERNETES_PROVIDER=vagrant

例如,如果我們想在AWS上部署Kubernetes,我們可以通過將KUBERNETES_PROVIDER環境變數更改為aws

 

使用Kubernetes安裝指令碼

雖然有很多關於如何安裝Kubernetes的演練,但我發現最簡單的方法是使用(https://get.k8s.io)上提供的Kubernetes安裝指令碼。

該指令碼本質上是與Kubernetes一起分發的安裝指令碼的包裝器,這使得該過程變得更加容易。關於這個指令碼我最喜歡的一件事是它也會為你下載Kubernetes。

要開始使用此指令碼,我們需要下載它; 我們可以通過快速curl命令完成此操作。一旦我們下載了指令碼,我們就可以通過執行bash命令後跟指令碼名來執行它。

$ curl https://get.k8s.io > kubernetes_install.sh
$ bash kubernetes_install.sh
Downloading kubernetes release v1.2.2 to /var/tmp/kubernetes.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  426M  100  426M    0     0  12.2M      0  0:00:34  0:00:34 --:--:-- 6007k
Unpacking kubernetes release v1.2.2
Creating a kubernetes on vagrant...
<output truncated>
Kubernetes master is running at https://10.245.1.2
Heapster is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/heapster
KubeDNS is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kube-dns
kubernetes-dashboard is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard
Grafana is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
InfluxDB is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb
Installation successful!

指令碼完成執行後,我們有一個正在執行的Kubernetes叢集。但是,在我們開始與這個Kubernetes叢集互動之前,我們還有一個步驟; 我們需要kubectl安裝命令。

 

設定kubectl

kubectl命令存在兩個的LinuxMac OS X的。由於我從MacBook執行此安裝,我將安裝Mac OS X版本kubectl。這意味著我將通過Vagrant執行叢集,但是從我的MacBook與該叢集進行互動。

要下載kubectl命令,我們將再次使用curl

$ curl https://storage.googleapis.com/kubernetes-release/release/v1.2.0/bin/darwin/amd64/kubectl > kubectl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 38.7M  100 38.7M    0     0  10.4M      0  0:00:03  0:00:03 --:--:-- 10.4M
$ chmod 750 kubectl

在之後kubectl的二進位制檔案下載和許可權更改為允許執行的kubectl命令幾乎準備就緒。在我們開始與Kubernetes叢集進行互動之前,還需要一步。該步驟是配置kubectl命令。

$ export KUBECONFIG=~/.kube/config

與大多數Kubernetes指令碼一樣,kubectl命令的配置由環境變數驅動。當我們執行上面的叢集安裝指令碼時,該指令碼.kube在我的使用者主目錄中建立了一個配置目錄。在該目錄中,它還建立了一個名為的檔案config。此檔案用於儲存有關已建立的Kubernetes群集的資訊。

通過將KUBECONFIG環境變數設定為~/.kube/config,我們定義該kubectl命令應該引用此配置檔案。讓我們快速瀏覽一下該檔案,以便更好地瞭解正在設定的內容。

$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <SSLKEYDATA>
    server: https://10.245.1.2
  name: vagrant
contexts:
- context:
    cluster: vagrant
    user: vagrant
  name: vagrant
current-context: vagrant
kind: Config
preferences: {}
users:
- name: vagrant
  user:
    client-certificate-data: <SSLKEYDATA>
    client-key-data: <SSLKEYDATA>
    token: sometoken
- name: vagrant-basic-auth
  user:
    password: somepassword
    username: admin

.kube/config檔案設定了兩個主要資訊:

  • 叢集的位置
  • 用於與該群集通訊的身份驗證資料

.kube/config定義檔案後,讓我們嘗試kubectl對我們的Kubernetes叢集執行命令以驗證一切正常。

$ ./kubectl get nodes
NAME                STATUS    AGE
kubernetes-node-1   Ready     31m
kubernetes-node-2   Ready     24m

在輸出./kubectl get nodes命令向我們表明,我們能夠連線到我們的Kubernetes叢集,並顯示我們的兩個節點的狀態kubernetes-node-1kubernetes-node-2。有了這個,我們可以繼續安裝完成。

 

關於Kubernetes節點的更多資訊

在上面的命令中,我們用於kubectl顯示此群集上可用的Kubernetes節點的狀態。但是,我們確實沒有探究節點是什麼或它在群集中扮演什麼角色。

Kubernetes 節點是用於託管應用程式容器的物理或虛擬(在我們的示例中為虛擬)機器。在傳統的基於容器的環境中,您通常會定義在指定的物理或虛擬主機上執行的特定容器。但是,在Kubernetes叢集中,您只需定義要執行的應用程式容器。Kubernetes主伺服器確定應用程式容器將在哪個節點上執行。

此方法還使Kubernetes叢集能夠執行諸如容器或節點死亡時自動重啟等任務。

 

 

部署我們的應用程式

隨著我們的Kubernetes叢集準備就緒,我們現在可以開始部署應用程式容器。我們今天要部署的應用程式容器將是Ghost的一個例項。Ghost是一個流行的基於JavaScript的部落格平臺,憑藉其官方Docker映象,它的部署非常簡單。

由於我們將使用預構建的Docker容器,因此我們不需要首先構建Docker映象。但是,重要的是要說明為了在Kubernetes叢集上使用自定義構建的容器。您必須首先構建容器並將其推送到Docker Hub等Docker儲存庫。

要啟動我們的Ghost容器,我們將使用./kubectl帶有該run選項的命令。

$ ./kubectl run ghost --image=ghost --port=2368
deployment "ghost" created

在上面的命令中,我們ghost使用映像建立了一個名為的部署,ghost並指定ghost容器需要埠2368。在走得太遠之前,讓我們首先驗證容器是否正在執行。我們可以通過kubectl使用get pods選項執行命令來驗證這一點。

$ ./kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
ghost-3550706830-4c2n5   1/1       Running   0          20m

get pods選項將告訴kubectl命令列出當前部署到群集的所有Kubernetes Pod。

 

什麼是Pod和部署?

波德是一組可以如同它們是在同一系統內執行相互通訊容器。對於那些熟悉Docker的人來說,這可能聽起來像連結容器,但實際上還有更多的東西。Pod中的容器不僅能夠通過連線相互localhost連線,容器內執行的程序還能夠與其他容器共享記憶體段。

Pod的目標是允許在Pod中執行的應用程式以與它們不在容器中執行但只是在同一物理主機上執行相同的方式進行互動。此功能可以輕鬆部署非專門設計為在容器內執行的應用程式。

一個部署或部署物件,類似於期望狀態的概念。本質上,部署是圍繞所需功能的高階配置。例如,在我們啟動Ghost容器之前,我們不只是啟動Ghost容器。我們實際上配置了Kubernetes以確保至少有一個Ghost容器副本正在執行。

 

為Ghost建立服務

雖然Pod中的容器可以連線到群集外部的系統,但外部系統甚至其他Pod都無法與它們通訊。這是因為,預設情況下,為Ghost服務定義的埠不會在此群集之外公開。這是服務發揮作用的地方。

為了使我們的Ghost應用程式可以在叢集外部訪問,我們剛剛建立的部署需要作為Kubernetes 服務公開。要將Ghost部署設定為服務,我們將kubectl再次使用該命令,這次使用該expose選項。

$ ./kubectl expose deployment ghost --type="NodePort"
service "ghost" exposed

在上面的命令中,我們使用--type帶有引數的標誌NodePort。此標誌定義要為此服務公開的服務型別,在本例中為NodePort服務型別。該NodePort服務型別將設定所有節點監聽指定的埠上。如果我們kubectl再次使用該命令,我們可以看到我們的更改生效,但這次使用該get services選項。

$ ./kubectl get services
NAME         CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
ghost        10.247.63.140   nodes         2368/TCP   55s
kubernetes   10.247.0.1      <none>        443/TCP    19m

 

服務型別

目前,Kubernetes支援三種服務型別:

  • ClusterIP
  • NodePort
  • LoadBalancer

如果我們只希望將此服務公開給此叢集中的其他Pod,我們可以使用ClusterIP預設的服務型別。這將開啟每個節點上用於Pod to Pod通訊的埠。

LoadBalancer服務型別旨在提供一個外部IP作為該服務的負載均衡。由於我們的部署是在本地膝上型電腦上利用Vagrant,因此該選項在我們的環境中不起作用。它適用於部署在GCE或AWS等雲環境中的Kubernetes叢集。

 

測試我們的Ghost例項

由於我們在定義NodePort服務時未指定要使用的埠,因此Kubernetes隨機分配了一個埠。要檢視它分配的埠,我們可以使用kubectl帶有該describe service選項的命令。

$ ./kubectl describe service ghost
Name:           ghost
Namespace:      default
Labels:         run=ghost
Selector:       run=ghost
Type:           NodePort
IP:         10.247.63.140
Port:           <unset> 2368/TCP
NodePort:       <unset> 32738/TCP
Endpoints:      10.246.3.3:2368
Session Affinity:   None
No events.

我們可以看到分配的埠是32738。使用此埠,我們可以使用該curl命令對任何Kubernetes節點進行HTTP呼叫,並重定向到2368應用程式容器中的埠。

$ curl -vk http://10.245.1.3:32738
* Rebuilt URL to: http://10.245.1.3:32738/
*   Trying 10.245.1.3...
* Connected to 10.245.1.3 (10.245.1.3) port 32738 (#0)
> GET / HTTP/1.1
> Host: 10.245.1.3:32738
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express

curl命令的輸出中,我們可以看到連線200 OK響應成功。有趣的是,請求是指未執行Ghost容器的節點。我們可以看到這一點,如果我們使用kubectldescribe的群。

$ ./kubectl describe pod ghost-3550706830-ss4se
Name:       ghost-3550706830-ss4se
Namespace:  default
Node:       kubernetes-node-2/10.245.1.4
Start Time: Sat, 16 Apr 2016 21:13:20 -0700
Labels:     pod-template-hash=3550706830,run=ghost
Status:     Running
IP:     10.246.3.3
Controllers:    ReplicaSet/ghost-3550706830
Containers:
  ghost:
    Container ID:   docker://55ea497a166ff13a733d4ad3be3abe42a6d7f3d2c259f2653102fedda485e25d
    Image:      ghost
    Image ID:       docker://09849b7a78d3882afcd46f2310c8b972352bc36aaec9f7fe7771bbc86e5222b9
    Port:       2368/TCP
    QoS Tier:
      memory:   BestEffort
      cpu:  Burstable
    Requests:
      cpu:      100m
    State:      Running
      Started:      Sat, 16 Apr 2016 21:14:33 -0700
    Ready:      True
    Restart Count:  0
    Environment Variables:
Conditions:
  Type      Status
  Ready     True
Volumes:
  default-token-imnyi:
    Type:   Secret (a volume populated by a Secret)
    SecretName: default-token-imnyi
No events.

在上面的描述中,我們可以看到Ghost Pod正在執行kubernetes-node-2。但是,我們剛剛提出的HTTP請求是kubernetes-node-1。這可以通過名為的Kubernetes服務實現kube-proxy。使用kube-proxy,每當流量到達服務埠時,Kubernetes節點將檢查該服務是否在該節點本地執行。如果沒有,它會將流量重定向到執行該服務的節點。

在上面的例子中,這意味著即使發出了HTTP請求kubernetes-node-1kube-proxy服務也會將該流量重定向到kubernetes-node-2容器執行的位置。

此功能允許使用者執行服務,而無需擔心服務的位置以及服務是否已從一個節點移動到另一個節點。一個非常有用的功能,可以減少相當多的維護和頭痛。

 

擴充套件部署

既然我們的Ghost服務正在執行並且可以被外部訪問,我們需要執行上一個任務,在多個例項中擴充套件我們的Ghost應用程式。要做到這一點,我們可以簡單地kubectl再次呼叫該命令,但這次使用該scale選項。

  • $ ./kubectl scale deployment ghost --replicas=4
  • deployment "ghost" scaled

我們已經指定應該有4 replicasghost部署。如果我們kubectl get pods再次執行,我們應該看到3個額外的pod用於ghost部署。

./kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
ghost-3550706830-49r81   1/1       Running   0          7h
ghost-3550706830-4c2n5   1/1       Running   0          8h
ghost-3550706830-7o2fs   1/1       Running   0          7h
ghost-3550706830-f3dae   1/1       Running   0          7h

通過最後一步,我們現在讓我們的Ghost服務跨多個節點和多個pod執行。在請求我們的Ghost服務時,這些請求將被負載平衡到我們的各種Ghost例項。

 

摘要

在本文中,我們學習瞭如何跨多個Vagrant管理的虛擬機器部署多節點Kubernetes叢集。我們還學習瞭如何將應用程式部署到叢集,使該應用程式可以被外部系統訪問,最後將應用程式擴充套件到四個例項。儘管我們完成了所有這些任務,但我們只是觸及了Kubernetes的表面。