Kubernetes 快速指南



Kubernetes - 概述

Kubernetes 是一個由雲原生計算基金會 (CNCF) 託管的開源容器管理工具。它也被稱為 Borg 的增強版,Borg 是谷歌開發的用於管理長期執行程序和批處理作業的工具,以前這些由獨立的系統處理。

Kubernetes 能夠自動化應用程式的部署、擴充套件和跨叢集的容器操作。它能夠建立以容器為中心的架構。

Kubernetes 的特性

以下是 Kubernetes 的一些重要特性。

  • 持續開發、整合和部署

  • 容器化基礎設施

  • 以應用為中心的管理

  • 自動可伸縮的基礎設施

  • 跨開發、測試和生產環境的一致性

  • 鬆散耦合的基礎設施,其中每個元件都可以作為一個獨立單元執行

  • 更高的資源利用率密度

  • 可預測的基礎設施

Kubernetes 的一個關鍵元件是,它可以在物理和虛擬機器基礎設施叢集上執行應用程式。它還能夠在雲上執行應用程式。**它有助於從以主機為中心的基礎設施遷移到以容器為中心的基礎設施。**

Kubernetes - 架構

在本章中,我們將討論 Kubernetes 的基本架構。

Kubernetes - 叢集架構

如下圖所示,Kubernetes 遵循客戶端-伺服器架構。其中,主節點安裝在一臺機器上,而節點安裝在單獨的 Linux 機器上。

Cluster Architecture

主節點和節點的關鍵元件在下一節中定義。

Kubernetes - 主節點元件

以下是 Kubernetes 主節點的元件。

etcd

它儲存叢集中每個節點都可以使用的配置資訊。它是一個高可用性的鍵值儲存,可以在多個節點之間分佈。由於它可能包含一些敏感資訊,因此只能由 Kubernetes API 伺服器訪問。它是一個所有節點都可以訪問的分散式鍵值儲存。

API 伺服器

Kubernetes 的 API 伺服器透過 API 提供所有叢集操作。API 伺服器實現了一個介面,這意味著不同的工具和庫可以輕鬆地與之通訊。**Kubeconfig** 是一個與伺服器端工具一起使用的軟體包,可用於通訊。它暴露了 Kubernetes API。

控制器管理器

此元件負責大多數調節叢集狀態並執行任務的控制器。一般來說,它可以被認為是一個在非終止迴圈中執行的守護程序,負責收集資訊並將其傳送到 API 伺服器。它努力獲得叢集的共享狀態,然後進行更改以將伺服器的當前狀態更改為所需狀態。關鍵控制器包括複製控制器、端點控制器、名稱空間控制器和服務帳戶控制器。控制器管理器執行不同型別的控制器來處理節點、端點等。

排程器

這是 Kubernetes 主節點的關鍵元件之一。它是主節點中負責分配工作負載的服務。它負責跟蹤叢集節點上工作負載的利用率,然後將工作負載放置在具有可用資源並接受工作負載的節點上。換句話說,這是負責將 Pod 分配給可用節點的機制。排程器負責工作負載利用率並將 Pod 分配給新節點。

Kubernetes - 節點元件

以下是節點伺服器的關鍵元件,這些元件對於與 Kubernetes 主節點通訊是必要的。

Docker

每個節點的第一個要求是 Docker,它有助於在一個相對隔離但輕量級的作業系統環境中執行封裝的應用程式容器。

Kubelet 服務

這是每個節點中一個小服務,負責在控制平面服務之間來回傳遞資訊。它與 **etcd** 儲存互動以讀取配置詳細資訊和寫入值。它與主節點元件通訊以接收命令和工作。然後 **kubelet** 程序承擔維護工作狀態和節點伺服器狀態的責任。它管理網路規則、埠轉發等。

Kubernetes 代理服務

這是一個在每個節點上執行的代理服務,有助於使服務可用於外部主機。它有助於將請求轉發到正確的容器,並且能夠執行基本的負載均衡。它確保網路環境是可預測且可訪問的,同時也是隔離的。它管理節點上的 Pod、卷、金鑰、建立新的容器健康檢查等。

Kubernetes - 主節點和節點結構

下圖顯示了 Kubernetes 主節點和節點的結構。

Master and Node Structure

Kubernetes - 設定

在設定 Kubernetes 之前,必須先設定虛擬資料中心 (vDC)。這可以被認為是一組機器,它們可以透過網路相互通訊。對於實踐操作,如果您沒有物理或雲基礎設施,可以在 **PROFITBRICKS** 上設定 vDC。

在任何雲上的 IaaS 設定完成後,您需要配置 **主節點** 和 **節點**。

**注意** - 此設定適用於 Ubuntu 機器。同樣也可以在其他 Linux 機器上設定。

先決條件

**安裝 Docker** - Kubernetes 的所有例項都需要 Docker。以下是安裝 Docker 的步驟。

**步驟 1** - 以 root 使用者帳戶登入到機器。

**步驟 2** - 更新軟體包資訊。確保 apt 軟體包正在執行。

**步驟 3** - 執行以下命令。

$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates

**步驟 4** - 新增新的 GPG 金鑰。

$ sudo apt-key adv \
   --keyserver hkp://ha.pool.sks-keyservers.net:80 \
   --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
$ echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee
/etc/apt/sources.list.d/docker.list

**步驟 5** - 更新 API 軟體包映象。

$ sudo apt-get update

完成上述所有任務後,您可以開始實際安裝 Docker 引擎。但是,在此之前,您需要驗證您使用的核心版本是否正確。

安裝 Docker 引擎

執行以下命令以安裝 Docker 引擎。

**步驟 1** - 登入到機器。

**步驟 2** - 更新軟體包索引。

$ sudo apt-get update

**步驟 3** - 使用以下命令安裝 Docker 引擎。

$ sudo apt-get install docker-engine

**步驟 4** - 啟動 Docker 守護程式。

$ sudo apt-get install docker-engine

**步驟 5** - 要驗證是否已安裝 Docker,請使用以下命令。

$ sudo docker run hello-world

安裝 etcd 2.0

這需要安裝在 Kubernetes 主節點上。要安裝它,請執行以下命令。

$ curl -L https://github.com/coreos/etcd/releases/download/v2.0.0/etcd
-v2.0.0-linux-amd64.tar.gz -o etcd-v2.0.0-linux-amd64.tar.gz ->1
$ tar xzvf etcd-v2.0.0-linux-amd64.tar.gz ------>2
$ cd etcd-v2.0.0-linux-amd64 ------------>3
$ mkdir /opt/bin ------------->4
$ cp etcd* /opt/bin ----------->5

在上述命令集中 -

  • 首先,我們下載 **etcd**。使用指定名稱儲存。
  • 然後,我們必須解壓 tar 包。
  • 我們在 /opt 中建立一個名為 bin 的目錄。
  • 將解壓後的檔案複製到目標位置。

現在我們準備構建 Kubernetes。我們需要在叢集上的所有機器上安裝 Kubernetes。

$ git clone https://github.com/GoogleCloudPlatform/kubernetes.git
$ cd kubernetes
$ make release

上述命令將在 kubernetes 資料夾的根目錄中建立一個 **_output** 目錄。接下來,我們可以將目錄解壓到我們選擇的任何目錄 /opt/bin 等。

接下來是網路部分,我們需要實際開始設定 Kubernetes 主節點和節點。為此,我們將為主機檔案新增一個條目,這可以在節點機器上完成。

$ echo "<IP address of master machine> kube-master
< IP address of Node Machine>" >> /etc/hosts

以下是上述命令的輸出。

Output

現在,我們將開始在 Kubernetes 主節點上進行實際配置。

首先,我們將開始將所有配置檔案複製到它們正確的位置。

$ cp <Current dir. location>/kube-apiserver /opt/bin/
$ cp <Current dir. location>/kube-controller-manager /opt/bin/
$ cp <Current dir. location>/kube-kube-scheduler /opt/bin/
$ cp <Current dir. location>/kubecfg /opt/bin/
$ cp <Current dir. location>/kubectl /opt/bin/
$ cp <Current dir. location>/kubernetes /opt/bin/

上述命令會將所有配置檔案複製到所需的位置。現在我們將回到我們構建 Kubernetes 資料夾的同一個目錄。

$ cp kubernetes/cluster/ubuntu/init_conf/kube-apiserver.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/init_conf/kube-controller-manager.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/init_conf/kube-kube-scheduler.conf /etc/init/

$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-apiserver /etc/init.d/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-controller-manager /etc/init.d/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-kube-scheduler /etc/init.d/

$ cp kubernetes/cluster/ubuntu/default_scripts/kubelet /etc/default/
$ cp kubernetes/cluster/ubuntu/default_scripts/kube-proxy /etc/default/
$ cp kubernetes/cluster/ubuntu/default_scripts/kubelet /etc/default/

下一步是更新 /etc 目錄下的已複製配置檔案。

使用以下命令配置主節點上的 etcd。

$ ETCD_OPTS = "-listen-client-urls = http://kube-master:4001"

配置 kube-apiserver

為此,在主節點上,我們需要編輯我們之前複製的 ** /etc/default/kube-apiserver ** 檔案。

$ KUBE_APISERVER_OPTS = "--address = 0.0.0.0 \
--port = 8080 \
--etcd_servers = <The path that is configured in ETCD_OPTS> \
--portal_net = 11.1.1.0/24 \
--allow_privileged = false \
--kubelet_port = < Port you want to configure> \
--v = 0"

配置 kube 控制器管理器

我們需要在 ** /etc/default/kube-controller-manager ** 中新增以下內容。

$ KUBE_CONTROLLER_MANAGER_OPTS = "--address = 0.0.0.0 \
--master = 127.0.0.1:8080 \
--machines = kube-minion \ -----> #this is the kubernatics node
--v = 0

接下來,在相應的檔案中配置 kube 排程器。

$ KUBE_SCHEDULER_OPTS = "--address = 0.0.0.0 \
--master = 127.0.0.1:8080 \
--v = 0"

完成上述所有任務後,我們就可以啟動 Kubernetes 主節點了。為此,我們將重新啟動 Docker。

$ service docker restart

Kubernetes 節點配置

Kubernetes 節點將執行兩個服務 **kubelet 和 kube-proxy**。在繼續之前,我們需要將下載的二進位制檔案複製到我們想要配置 kubernetes 節點的所需資料夾。

使用與 kubernetes 主節點相同的複製檔案方法。因為它只執行 kubelet 和 kube-proxy,我們將配置它們。

$ cp <Path of the extracted file>/kubelet /opt/bin/
$ cp <Path of the extracted file>/kube-proxy /opt/bin/
$ cp <Path of the extracted file>/kubecfg /opt/bin/
$ cp <Path of the extracted file>/kubectl /opt/bin/
$ cp <Path of the extracted file>/kubernetes /opt/bin/

現在,我們將內容複製到相應的目錄。

$ cp kubernetes/cluster/ubuntu/init_conf/kubelet.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/init_conf/kube-proxy.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kubelet /etc/init.d/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-proxy /etc/init.d/
$ cp kubernetes/cluster/ubuntu/default_scripts/kubelet /etc/default/
$ cp kubernetes/cluster/ubuntu/default_scripts/kube-proxy /etc/default/

我們將配置 **kubelet** 和 **kube-proxy conf** 檔案。

我們將配置 ** /etc/init/kubelet.conf **。

$ KUBELET_OPTS = "--address = 0.0.0.0 \
--port = 10250 \
--hostname_override = kube-minion \
--etcd_servers = http://kube-master:4001 \
--enable_server = true
--v = 0"
/

對於 kube-proxy,我們將使用以下命令進行配置。

$ KUBE_PROXY_OPTS = "--etcd_servers = http://kube-master:4001 \
--v = 0"
/etc/init/kube-proxy.conf

最後,我們將重新啟動 Docker 服務。

$ service docker restart

現在我們完成了配置。您可以透過執行以下命令進行檢查。

$ /opt/bin/kubectl get minions

Kubernetes - 映象

Kubernetes (Docker) 映象是容器化基礎設施的關鍵構建塊。目前,我們只支援 Kubernetes 支援 Docker 映象。Pod 中的每個容器在其內部執行著它的 Docker 映象。

當我們配置 Pod 時,配置檔案中的 image 屬性與 Docker 命令的語法相同。配置檔案有一個欄位用於定義映象名稱,我們計劃從登錄檔中提取該名稱。

以下是將從 Docker 登錄檔中提取映象並部署到 Kubernetes 容器中的常見配置結構。

apiVersion: v1
kind: pod
metadata:
   name: Tesing_for_Image_pull -----------> 1
   spec:
      containers:
         - name: neo4j-server ------------------------> 2
         image: <Name of the Docker image>----------> 3
         imagePullPolicy: Always ------------->4
         command: ["echo", "SUCCESS"] ------------------->

在上面的程式碼中,我們定義了 -

  • **name: Tesing_for_Image_pull** - 此名稱用於標識和檢查從 Docker 登錄檔中提取映象後將建立的容器的名稱。

  • **name: neo4j-server** - 這是我們嘗試建立的容器的名稱。例如,我們給它命名為 neo4j-server。

  • **image: ** - 這是我們嘗試從 Docker 或內部映象登錄檔中提取的映象的名稱。我們需要定義完整的登錄檔路徑以及我們嘗試提取的映象名稱。

  • **imagePullPolicy** - Always - 此映象拉取策略定義了無論何時我們執行此檔案來建立容器,它都將再次拉取同名映象。

  • **command: [“echo”, “SUCCESS”]** - 透過此設定,當我們建立容器並且一切順利時,當我們訪問容器時,它將顯示一條訊息。

為了提取映象並建立容器,我們將執行以下命令。

$ kubectl create –f Tesing_for_Image_pull

獲取日誌後,我們將獲得成功的輸出。

$ kubectl log Tesing_for_Image_pull

上述命令將產生成功輸出或失敗輸出。

**注意** - 建議您自己嘗試所有命令。

Kubernetes - 作業

作業的主要功能是建立一個或多個 Pod 並跟蹤 Pod 的成功情況。它們確保指定數量的 Pod 成功完成。當完成指定數量的 Pod 成功執行後,則認為作業已完成。

建立作業

使用以下命令建立作業:

apiVersion: v1
kind: Job ------------------------> 1
metadata:
   name: py
   spec:
   template:
      metadata
      name: py -------> 2
      spec:
         containers:
            - name: py ------------------------> 3
            image: python----------> 4
            command: ["python", "SUCCESS"]
            restartPocliy: Never --------> 5

在上面的程式碼中,我們定義了 -

  • kind: Job → 我們已將 kind 定義為 Job,這將告訴 kubectl 使用的 yaml 檔案用於建立作業型別的 Pod。

  • Name: py → 這是我們使用的模板的名稱,spec 定義了模板。

  • name: py → 我們在容器規範下指定了一個名為 py 的名稱,這有助於識別將由此建立的 Pod。

  • Image: python → 我們將拉取以建立將在 Pod 內執行的容器的映象。

  • restartPolicy: Never →映象重啟條件設定為 Never,這意味著如果容器被終止或出現故障,它將不會自行重啟。

我們將使用以下命令和名為 py.yaml 儲存的 yaml 檔案來建立作業。

$ kubectl create –f py.yaml

上述命令將建立一個作業。如果要檢查作業的狀態,請使用以下命令。

$ kubectl describe jobs/py

上述命令將建立一個作業。如果要檢查作業的狀態,請使用以下命令。

定時作業

Kubernetes 中的定時作業使用 Cronetes,它接收 Kubernetes 作業並在 Kubernetes 叢集中啟動它們。

  • 排程作業將在指定時間點執行 Pod。
  • 為此建立一個週期性作業,該作業會自動呼叫自身。

注意 - 定時作業功能由 1.4 版支援,透過在啟動 API 伺服器時傳遞 –runtime-config=batch/v2alpha1 來啟用 betch/v2alpha 1 API。

我們將使用與建立作業相同的 yaml 檔案,並將其設定為定時作業。

apiVersion: v1
kind: Job
metadata:
   name: py
spec:
   schedule: h/30 * * * * ? -------------------> 1
   template:
      metadata
         name: py
      spec:
         containers:
         - name: py
         image: python
         args:
/bin/sh -------> 2
-c
ps –eaf ------------> 3
restartPocliy: OnFailure

在上面的程式碼中,我們定義了 -

  • schedule: h/30 * * * * ? → 將作業排程為每 30 分鐘執行一次。

  • /bin/sh: 這將使用 /bin/sh 進入容器。

  • ps –eaf → 將在機器上執行 ps -eaf 命令,並列出容器內所有正在執行的程序。

當我們嘗試在指定時間點構建和執行一組任務然後完成流程時,此定時作業概念非常有用。

Kubernetes - 標籤 & 選擇器

標籤

標籤是附加到 Pod、副本控制器和服務的鍵值對。它們用作物件的標識屬性,例如 Pod 和副本控制器。它們可以在建立時新增到物件,也可以在執行時新增或修改。

選擇器

標籤不提供唯一性。一般來說,許多物件可以攜帶相同的標籤。標籤選擇器是 Kubernetes 中的核心分組原語。使用者可以使用它們來選擇一組物件。

Kubernetes API 目前支援兩種型別的選擇器:

  • 基於等式的選擇器
  • 基於集合的選擇器

基於等式的選擇器

它們允許按鍵和值進行篩選。匹配的物件應滿足所有指定的標籤。

基於集合的選擇器

基於集合的選擇器允許根據一組值篩選鍵。

apiVersion: v1
kind: Service
metadata:
   name: sp-neo4j-standalone
spec:
   ports:
      - port: 7474
      name: neo4j
   type: NodePort
   selector:
      app: salesplatform ---------> 1
      component: neo4j -----------> 2

在上面的程式碼中,我們使用標籤選擇器 app: salesplatform 和元件 component: neo4j

使用 kubectl 命令執行該檔案後,它將建立一個名為 sp-neo4j-standalone 的服務,該服務將在 7474 埠上進行通訊。型別為 NodePort,新的標籤選擇器為 app: salesplatformcomponent: neo4j

Kubernetes - 名稱空間

名稱空間為資源名稱提供了額外的限定。當多個團隊使用相同的叢集並且存在名稱衝突的可能性時,這很有用。它可以作為多個叢集之間的虛擬牆。

名稱空間的功能

以下是 Kubernetes 中名稱空間的一些重要功能:

  • 名稱空間有助於使用相同名稱空間的 Pod 之間的通訊。

  • 名稱空間是可以在同一物理叢集之上存在的虛擬叢集。

  • 它們在團隊及其環境之間提供邏輯隔離。

建立名稱空間

以下命令用於建立名稱空間。

apiVersion: v1
kind: Namespce
metadata
   name: elk

控制名稱空間

以下命令用於控制名稱空間。

$ kubectl create –f namespace.yml ---------> 1
$ kubectl get namespace -----------------> 2
$ kubectl get namespace <Namespace name> ------->3
$ kubectl describe namespace <Namespace name> ---->4
$ kubectl delete namespace <Namespace name>

在上面的程式碼中,

  • 我們使用命令建立名稱空間。
  • 這將列出所有可用的名稱空間。
  • 這將獲取命令中指定的特定名稱空間。
  • 這將描述有關服務的完整詳細資訊。
  • 這將刪除叢集中存在的特定名稱空間。

在服務中使用名稱空間 - 示例

以下是使用名稱空間服務的示例檔案的示例。

apiVersion: v1
kind: Service
metadata:
   name: elasticsearch
   namespace: elk
   labels:
      component: elasticsearch
spec:
   type: LoadBalancer
   selector:
      component: elasticsearch
   ports:
   - name: http
      port: 9200
      protocol: TCP
   - name: transport
      port: 9300
      protocol: TCP

在上面的程式碼中,我們在服務元資料下使用相同的名稱空間,名稱為 elk

Kubernetes - 節點

節點是 Kubernetes 叢集中的工作機器,也稱為 minion。它們是工作單元,可以是物理機、虛擬機器或雲實例。

每個節點都具有在其上執行 Pod 所需的所有配置,例如代理服務和 kubelet 服務以及 Docker,後者用於在節點上建立的 Pod 上執行 Docker 容器。

它們不是由 Kubernetes 建立的,而是由雲服務提供商或 Kubernetes 叢集管理器在物理機或虛擬機器上外部建立的。

Kubernetes 用於處理多個節點的關鍵元件是控制器管理器,它執行多種型別的控制器來管理節點。為了管理節點,Kubernetes 建立一個 kind 為 node 的物件,該物件將驗證建立的物件是否為有效節點。

帶選擇器的服務

apiVersion: v1
kind: node
metadata:
   name: < ip address of the node>
   labels:
      name: <lable name>

在 JSON 格式中,建立的實際物件如下所示:

{
   Kind: node
   apiVersion: v1
   "metadata": 
   {
      "name": "10.01.1.10",
      "labels"
      {
         "name": "cluster 1 node"
      }
   }
}

節點控制器

它們是在 Kubernetes 主伺服器上執行的服務集合,並根據 metadata.name 持續監控叢集中的節點。如果所有必需的服務都正在執行,則驗證節點,並且控制器將向該節點分配新建立的 Pod。如果無效,則主伺服器將不會向其分配任何 Pod,並將等待其變為有效。

如果 –register-node 標誌為 true,則 Kubernetes 主伺服器會自動註冊節點。

–register-node = true

但是,如果叢集管理員想要手動管理它,則可以透過關閉以下標誌來完成:

–register-node = false

Kubernetes - 服務

服務可以定義為 Pod 的邏輯集合。它可以定義為 Pod 之上的抽象,它提供單個 IP 地址和 DNS 名稱,Pod 可以透過該名稱進行訪問。使用服務,可以輕鬆管理負載均衡配置。它有助於 Pod 輕鬆擴充套件。

服務是 Kubernetes 中的 REST 物件,其定義可以釋出到 Kubernetes apiServer(在 Kubernetes 主伺服器上)以建立新例項。

無選擇器的服務

apiVersion: v1
kind: Service
metadata:
   name: Tutorial_point_service
spec:
   ports:
   - port: 8080
   targetPort: 31999

上述配置將建立一個名為 Tutorial_point_service 的服務。

帶選擇器的服務配置檔案

apiVersion: v1
kind: Service
metadata:
   name: Tutorial_point_service
spec:
   selector:
      application: "My Application" -------------------> (Selector)
   ports:
   - port: 8080
   targetPort: 31999

在此示例中,我們有一個選擇器;因此,為了傳輸流量,我們需要手動建立一個端點。

apiVersion: v1
kind: Endpoints
metadata:
   name: Tutorial_point_service
subnets:
   address:
      "ip": "192.168.168.40" -------------------> (Selector)
   ports:
      - port: 8080

在上面的程式碼中,我們建立了一個端點,該端點將流量路由到定義為“192.168.168.40:8080”的端點。

多埠服務建立

apiVersion: v1
kind: Service
metadata:
   name: Tutorial_point_service
spec:
   selector:
      application: “My Application” -------------------> (Selector)
   ClusterIP: 10.3.0.12
   ports:
      -name: http
      protocol: TCP
      port: 80
      targetPort: 31999
   -name:https
      Protocol: TCP
      Port: 443
      targetPort: 31998

服務的型別

ClusterIP - 這有助於限制叢集內的服務。它在定義的 Kubernetes 叢集內公開服務。

spec:
   type: NodePort
   ports:
   - port: 8080
      nodePort: 31999
      name: NodeportService

NodePort - 它將在已部署節點的靜態埠上公開服務。將自動建立一個 ClusterIP 服務,NodePort 服務將路由到該服務。可以使用 NodeIP:nodePort 從叢集外部訪問該服務。

spec:
   ports:
   - port: 8080
      nodePort: 31999
      name: NodeportService
      clusterIP: 10.20.30.40

Load Balancer - 它使用雲提供商的負載均衡器。將自動建立 NodePortClusterIP 服務,外部負載均衡器將路由到這些服務。

一個完整的服務 yaml 檔案,服務型別為 Node Port。嘗試自己建立一個。

apiVersion: v1
kind: Service
metadata:
   name: appname
   labels:
      k8s-app: appname
spec:
   type: NodePort
   ports:
   - port: 8080
      nodePort: 31999
      name: omninginx
   selector:
      k8s-app: appname
      component: nginx
      env: env_name

Kubernetes - Pod

Pod 是 Kubernetes 叢集節點內容器及其儲存的集合。可以在其中建立包含多個容器的 Pod。例如,在同一個 Pod 中保留資料庫容器和資料容器。

Pod 的型別

有兩種型別的 Pod:

  • 單容器 Pod
  • 多容器 Pod

單容器 Pod

它們可以使用 kubctl run 命令輕鬆建立,在該命令中,您在 Docker 登錄檔中有一個已定義的映象,我們將在建立 Pod 時拉取該映象。

$ kubectl run <name of pod> --image=<name of the image from registry>

示例 - 我們將建立一個使用 Docker hub 上可用的 tomcat 映象的 Pod。

$ kubectl run tomcat --image = tomcat:8.0

這也可以透過建立 yaml 檔案然後執行 kubectl create 命令來完成。

apiVersion: v1
kind: Pod
metadata:
   name: Tomcat
spec:
   containers:
   - name: Tomcat
    image: tomcat: 8.0
    ports:
containerPort: 7500
   imagePullPolicy: Always

建立上述 yaml 檔案後,我們將使用 tomcat.yml 的名稱儲存檔案,並執行 create 命令來執行該文件。

$ kubectl create –f tomcat.yml

它將建立一個名為 tomcat 的 Pod。我們可以使用 describe 命令和 kubectl 來描述 Pod。

多容器 Pod

多容器 Pod 是使用帶有容器定義的 yaml mail 建立的。

apiVersion: v1
kind: Pod
metadata:
   name: Tomcat
spec:
   containers:
   - name: Tomcat
    image: tomcat: 8.0
    ports:
containerPort: 7500
   imagePullPolicy: Always
   -name: Database
   Image: mongoDB
   Ports:
containerPort: 7501
   imagePullPolicy: Always

在上面的程式碼中,我們建立了一個包含兩個容器的 Pod,一個用於 tomcat,另一個用於 MongoDB。

Kubernetes - 複製控制器

副本控制器是 Kubernetes 的關鍵功能之一,負責管理 Pod 生命週期。它負責確保在任何時間點都執行指定數量的 Pod 副本。當想要確保執行指定數量的 Pod 或至少一個 Pod 時,它會用到。它能夠啟動或關閉指定的 Pod 數量。

最佳實踐是使用副本控制器來管理 Pod 生命週期,而不是反覆建立 Pod。

apiVersion: v1
kind: ReplicationController --------------------------> 1
metadata:
   name: Tomcat-ReplicationController --------------------------> 2
spec:
   replicas: 3 ------------------------> 3
   template:
      metadata:
         name: Tomcat-ReplicationController
      labels:
         app: App
         component: neo4j
      spec:
         containers:
         - name: Tomcat- -----------------------> 4
         image: tomcat: 8.0
         ports:
            - containerPort: 7474 ------------------------> 5

設定詳情

  • Kind: ReplicationController → 在上面的程式碼中,我們將 kind 定義為副本控制器,這將告訴 kubectl 將使用 yaml 檔案來建立副本控制器。

  • name: Tomcat-ReplicationController → 這有助於識別將建立副本控制器的名稱。如果我們執行 kubctl,get rc ,它將顯示副本控制器的詳細資訊。

  • replicas: 3 → 這有助於副本控制器瞭解它需要在 Pod 生命週期中的任何時間點維護三個 Pod 副本。

  • name: Tomcat → 在 spec 部分中,我們將名稱定義為 tomcat,這將告訴副本控制器 Pod 內的容器是 tomcat。

  • containerPort: 7474 → 它有助於確保叢集中執行 Pod 內容器的所有節點都在相同的 7474 埠上公開。

Kube Service for Replicas

在這裡,Kubernetes 服務充當三個 tomcat 副本的負載均衡器。

Kubernetes - 副本集

副本集(Replica Set)確保應該執行多少個 Pod 副本。它可以被認為是複製控制器的替代品。副本集和複製控制器之間的關鍵區別在於,複製控制器只支援基於等式的選擇器,而副本集支援基於集合的選擇器。

apiVersion: extensions/v1beta1 --------------------->1
kind: ReplicaSet --------------------------> 2
metadata:
   name: Tomcat-ReplicaSet
spec:
   replicas: 3
   selector:
      matchLables:
         tier: Backend ------------------> 3
      matchExpression:
{ key: tier, operation: In, values: [Backend]} --------------> 4
template:
   metadata:
      lables:
         app: Tomcat-ReplicaSet
         tier: Backend
      labels:
         app: App
         component: neo4j
   spec:
      containers:
      - name: Tomcat
      image: tomcat: 8.0
      ports:
      - containerPort: 7474

設定詳情

  • apiVersion: extensions/v1beta1 → 在上面的程式碼中,API 版本是 Kubernetes 的高階 Beta 版本,它支援副本集的概念。

  • kind: ReplicaSet → 我們已將 kind 定義為副本集,這有助於 kubectl 理解該檔案用於建立副本集。

  • tier: Backend → 我們已將標籤 tier 定義為 backend,這將建立一個匹配的選擇器。

  • {key: tier, operation: In, values: [Backend]} → 這將幫助matchExpression理解我們定義的匹配條件以及matchLabel用於查詢詳細資訊的操作。

使用kubectl執行以上檔案,並使用yaml檔案中的定義建立後端副本集。

Kube Service Backend Replicaset

Kubernetes - 部署

Deployment(部署)是複製控制器的升級和更高版本。它們管理副本集的部署,副本集也是複製控制器的升級版本。它們具有更新副本集的能力,並且還能夠回滾到以前的版本。

它們提供了許多matchLabelsselectors的更新功能。我們在 Kubernetes master 中獲得了一個新的控制器,稱為部署控制器,它使這一切成為可能。它具有中途更改部署的能力。

更改部署

更新 - 使用者可以在部署完成之前更新正在進行的部署。在此,現有部署將被終止,並將建立新的部署。

刪除 - 使用者可以在部署完成之前透過刪除來暫停/取消部署。重新建立相同的部署將恢復它。

回滾 - 我們可以回滾部署或正在進行的部署。使用者可以使用DeploymentSpec.PodTemplateSpec = oldRC.PodTemplateSpec來建立或更新部署。

部署策略

部署策略有助於定義新的 RC 如何替換現有的 RC。

重新建立 - 此功能將終止所有現有的 RC,然後啟動新的 RC。這導致快速部署,但是當舊 Pod 關閉而新 Pod 尚未啟動時,會導致停機時間。

滾動更新 - 此功能逐漸關閉舊 RC 並啟動新的 RC。這導致部署緩慢,但是沒有停機時間。在此過程中,始終有一些舊 Pod 和一些新 Pod 可用。

Deployment 的配置檔案如下所示。

apiVersion: extensions/v1beta1 --------------------->1
kind: Deployment --------------------------> 2
metadata:
   name: Tomcat-ReplicaSet
spec:
   replicas: 3
   template:
      metadata:
         lables:
            app: Tomcat-ReplicaSet
            tier: Backend
   spec:
      containers:
         - name: Tomcatimage:
            tomcat: 8.0
            ports:
               - containerPort: 7474

在上面的程式碼中,與副本集唯一不同的是我們將 kind 定義為 deployment。

建立部署

$ kubectl create –f Deployment.yaml -–record
deployment "Deployment" created Successfully.

獲取部署

$ kubectl get deployments
NAME           DESIRED     CURRENT     UP-TO-DATE     AVILABLE    AGE
Deployment        3           3           3              3        20s

檢查部署狀態

$ kubectl rollout status deployment/Deployment

更新部署

$ kubectl set image deployment/Deployment tomcat=tomcat:6.0

回滾到之前的部署

$ kubectl rollout undo deployment/Deployment –to-revision=2

Kubernetes - 卷

在 Kubernetes 中,卷可以被認為是 Pod 中容器可以訪問的目錄。Kubernetes 中有不同型別的卷,型別定義了卷的建立方式及其內容。

卷的概念在 Docker 中就已經存在,但是唯一的問題是卷非常侷限於特定的 Pod。一旦 Pod 的生命週期結束,卷也會丟失。

另一方面,透過 Kubernetes 建立的卷不受任何容器的限制。它支援部署在 Kubernetes Pod 內的任何或所有容器。Kubernetes 卷的一個關鍵優勢是,它支援不同型別的儲存,其中 Pod 可以同時使用多個儲存。

Kubernetes 卷的型別

這是一些常用的 Kubernetes 卷的列表:

  • emptyDir - 這是一種在首次將 Pod 分配給節點時建立的卷。只要 Pod 在該節點上執行,它就會保持活動狀態。該卷最初為空,Pod 中的容器可以讀取和寫入 emptyDir 卷中的檔案。一旦 Pod 從節點中移除,emptyDir 中的資料就會被擦除。

  • hostPath - 此型別的卷將主機節點檔案系統中的檔案或目錄掛載到您的 Pod 中。

  • gcePersistentDisk - 此型別的卷將 Google Compute Engine (GCE) 永續性磁碟掛載到您的 Pod 中。當 Pod 從節點中移除時,gcePersistentDisk中的資料將保持不變。

  • awsElasticBlockStore - 此型別的卷將 Amazon Web Services (AWS) Elastic Block Store 掛載到您的 Pod 中。與gcePersistentDisk一樣,當 Pod 從節點中移除時,awsElasticBlockStore中的資料將保持不變。

  • nfs - nfs卷允許將現有的 NFS(網路檔案系統)掛載到您的 Pod 中。當 Pod 從節點中移除時,nfs卷中的資料不會被擦除。該卷僅被解除安裝。

  • iscsi - iscsi卷允許將現有的 iSCSI(IP 上的 SCSI)卷掛載到您的 Pod 中。

  • flocker - 它是一個開源的叢集式容器資料卷管理器。它用於管理資料卷。flocker卷允許將 Flocker 資料集掛載到 Pod 中。如果 Flocker 中不存在資料集,則首先需要使用 Flocker API 建立它。

  • glusterfs - Glusterfs 是一個開源的網路檔案系統。glusterfs卷允許將 glusterfs 卷掛載到您的 Pod 中。

  • rbd - RBD 代表 Rados Block Device。rbd卷允許將 Rados Block Device 卷掛載到您的 Pod 中。Pod 從節點中移除後,資料仍然保留。

  • cephfs - cephfs卷允許將現有的 CephFS 卷掛載到您的 Pod 中。Pod 從節點中移除後,資料將保持不變。

  • gitRepo - gitRepo卷掛載一個空目錄,並將git儲存庫克隆到其中供您的 Pod 使用。

  • secret - secret卷用於將敏感資訊(如密碼)傳遞給 Pod。

  • persistentVolumeClaim - persistentVolumeClaim卷用於將 PersistentVolume 掛載到 Pod 中。PersistentVolume 是一種允許使用者“宣告”永續性儲存(如 GCE PersistentDisk 或 iSCSI 卷)而不必瞭解特定雲環境的詳細資訊的方法。

  • downwardAPI - downwardAPI卷用於使向下 API 資料可供應用程式使用。它掛載一個目錄並將請求的資料寫入純文字檔案。

  • azureDiskVolume - AzureDiskVolume用於將 Microsoft Azure 資料磁碟掛載到 Pod 中。

持久卷和持久卷宣告

持久卷 (PV) - 這是管理員已配置的一塊網路儲存。它是叢集中的資源,獨立於使用 PV 的任何單個 Pod。

持久卷宣告 (PVC) - Kubernetes 為其 Pod 請求的儲存稱為 PVC。使用者無需瞭解底層配置。宣告必須在建立 Pod 的相同名稱空間中建立。

建立持久卷

kind: PersistentVolume ---------> 1
apiVersion: v1
metadata:
   name: pv0001 ------------------> 2
   labels:
      type: local
spec:
   capacity: -----------------------> 3
      storage: 10Gi ----------------------> 4
   accessModes:
      - ReadWriteOnce -------------------> 5
      hostPath:
         path: "/tmp/data01" --------------------------> 6

在上面的程式碼中,我們定義了 -

  • kind: PersistentVolume → 我們已將 kind 定義為 PersistentVolume,這告訴 Kubernetes 正在使用的 yaml 檔案用於建立持久卷。

  • name: pv0001 → 我們正在建立的持久卷的名稱。

  • capacity: → 此規範將定義我們嘗試建立的 PV 的容量。

  • storage: 10Gi → 這告訴底層基礎設施我們正在嘗試在定義的路徑上宣告 10Gi 空間。

  • ReadWriteOnce → 這告訴我們正在建立的卷的訪問許可權。

  • path: "/tmp/data01" → 此定義告訴機器我們正在嘗試在底層基礎設施上的此路徑下建立卷。

建立 PV

$ kubectl create –f local-01.yaml
persistentvolume "pv0001" created

檢查 PV

$ kubectl get pv
NAME        CAPACITY      ACCESSMODES       STATUS       CLAIM      REASON     AGE
pv0001        10Gi            RWO         Available                            14s

描述 PV

$ kubectl describe pv pv0001

建立持久卷宣告

kind: PersistentVolumeClaim --------------> 1
apiVersion: v1
metadata:
   name: myclaim-1 --------------------> 2
spec:
   accessModes:
      - ReadWriteOnce ------------------------> 3
   resources:
      requests:
         storage: 3Gi ---------------------> 4

在上面的程式碼中,我們定義了 -

  • kind: PersistentVolumeClaim → 它指示底層基礎設施我們正在嘗試宣告指定數量的空間。

  • name: myclaim-1 → 我們嘗試建立的宣告的名稱。

  • ReadWriteOnce → 這指定了我們嘗試建立的宣告的模式。

  • storage: 3Gi → 這將告訴 Kubernetes 我們嘗試宣告的空間量。

建立 PVC

$ kubectl create –f myclaim-1
persistentvolumeclaim "myclaim-1" created

獲取有關 PVC 的詳細資訊

$ kubectl get pvc
NAME        STATUS   VOLUME   CAPACITY   ACCESSMODES   AGE
myclaim-1   Bound    pv0001     10Gi         RWO       7s

描述 PVC

$ kubectl describe pv pv0001

在 POD 中使用 PV 和 PVC

kind: Pod
apiVersion: v1
metadata:
   name: mypod
   labels:
      name: frontendhttp
spec:
   containers:
   - name: myfrontend
      image: nginx
      ports:
      - containerPort: 80
         name: "http-server"
      volumeMounts: ----------------------------> 1
      - mountPath: "/usr/share/tomcat/html"
         name: mypd
   volumes: -----------------------> 2
      - name: mypd
         persistentVolumeClaim: ------------------------->3
         claimName: myclaim-1

在上面的程式碼中,我們定義了 -

  • volumeMounts: → 這是將進行掛載的容器中的路徑。

  • Volume: → 此定義定義了我們將宣告的卷定義。

  • persistentVolumeClaim: → 在此之下,我們定義了將在定義的 Pod 中使用的卷名稱。

Kubernetes - 金鑰

Secrets 可以定義為 Kubernetes 物件,用於儲存敏感資料,例如使用者名稱和密碼,並進行加密。

在 Kubernetes 中建立 Secrets 的方法有很多。

  • 從文字檔案建立。
  • 從 yaml 檔案建立。

從文字檔案建立

為了從文字檔案(例如使用者名稱和密碼)建立 Secrets,我們首先需要將它們儲存在 txt 檔案中,然後使用以下命令。

$ kubectl create secret generic tomcat-passwd –-from-file = ./username.txt –fromfile = ./.
password.txt

從 Yaml 檔案建立

apiVersion: v1
kind: Secret
metadata:
name: tomcat-pass
type: Opaque
data:
   password: <User Password>
   username: <User Name>

建立 Secret

$ kubectl create –f Secret.yaml
secrets/tomcat-pass

使用 Secrets

建立 Secrets 後,它可以在 Pod 或複製控制器中使用,如下所示:

  • 環境變數

作為環境變數

為了將 Secret 用作環境變數,我們將在 Pod yaml 檔案的 spec 部分下使用env

env:
- name: SECRET_USERNAME
   valueFrom:
      secretKeyRef:
         name: mysecret
         key: tomcat-pass

作為卷

spec:
   volumes:
      - name: "secretstest"
         secret:
            secretName: tomcat-pass
   containers:
      - image: tomcat:7.0
         name: awebserver
         volumeMounts:
            - mountPath: "/tmp/mysec"
            name: "secretstest"

Secret 配置作為環境變數

apiVersion: v1
kind: ReplicationController
metadata:
   name: appname
spec:
replicas: replica_count
template:
   metadata:
      name: appname
   spec:
      nodeSelector:
         resource-group:
      containers:
         - name: appname
            image:
            imagePullPolicy: Always
            ports:
            - containerPort: 3000
            env: -----------------------------> 1
               - name: ENV
                  valueFrom:
                     configMapKeyRef:
                        name: appname
                        key: tomcat-secrets

在上面的程式碼中,在env定義下,我們正在複製控制器中使用 Secret 作為環境變數。

Secret 作為卷掛載

apiVersion: v1
kind: pod
metadata:
   name: appname
spec:
   metadata:
      name: appname
   spec:
   volumes:
      - name: "secretstest"
         secret:
            secretName: tomcat-pass
   containers:
      - image: tomcat: 8.0
         name: awebserver
         volumeMounts:
            - mountPath: "/tmp/mysec"
            name: "secretstest"

Kubernetes - 網路策略

網路策略定義了同一名稱空間中的 Pod 如何相互通訊以及網路端點。它需要在 API 伺服器的執行時配置中啟用extensions/v1beta1/networkpolicies。其資源使用標籤來選擇 Pod 並定義規則以允許流量到名稱空間中定義的特定 Pod。

首先,我們需要配置名稱空間隔離策略。基本上,這種網路策略在負載均衡器上是必需的。

kind: Namespace
apiVersion: v1
metadata:
   annotations:
      net.beta.kubernetes.io/network-policy: |
      {
         "ingress": 
         {
            "isolation": "DefaultDeny"
         }
      }

$ kubectl annotate ns <namespace> "net.beta.kubernetes.io/network-policy = 
{\"ingress\": {\"isolation\": \"DefaultDeny\"}}"

建立名稱空間後,我們需要建立網路策略。

網路策略 Yaml

kind: NetworkPolicy
apiVersion: extensions/v1beta1
metadata:
   name: allow-frontend
   namespace: myns
spec:
   podSelector:
      matchLabels:
         role: backend
   ingress:
   - from:
      - podSelector:
         matchLabels:
            role: frontend
   ports:
      - protocol: TCP
         port: 6379

Kubernetes - API

Kubernetes API 作為系統宣告式配置模式的基礎。Kubectl 命令列工具可用於建立、更新、刪除和獲取 API 物件。Kubernetes API 充當 Kubernetes 不同元件之間的通訊器。

向 Kubernetes 新增 API

向 Kubernetes 新增新的 API 將為 Kubernetes 新增新功能,從而增強 Kubernetes 的功能。但是,與此同時,它也會增加系統的成本和可維護性。為了在成本和複雜性之間取得平衡,為此定義了一些集合。

要新增的 API 應該對超過 50% 的使用者有用。Kubernetes 中沒有其他方法可以實現該功能。例外情況將在 Kubernetes 社群會議中討論,然後新增 API。

API 變更

為了增強 Kubernetes 的能力,系統會不斷引入變更。Kubernetes 團隊這樣做是為了向 Kubernetes 新增功能,而不會刪除或影響系統的現有功能。

為了演示一般流程,這裡有一個(假設的)示例:

  • 使用者將 Pod 物件 POST 到 /api/v7beta1/...

  • JSON 被反序列化為 v7beta1.Pod 結構

  • 將預設值應用於 v7beta1.Pod

  • v7beta1.Pod 轉換為 api.Pod 結構

  • 驗證 api.Pod,並將任何錯誤返回給使用者

  • api.Pod 轉換為 v6.Pod(因為 v6 是最新的穩定版本)

  • v6.Pod 序列化為 JSON 並寫入 etcd

現在我們已經儲存了 Pod 物件,使用者可以在任何受支援的 API 版本中獲取該物件。例如:

  • 使用者從 /api/v5/... 獲取 Pod

  • etcd 讀取 JSON 並將其反序列化v6.Pod 結構

  • 將預設值應用於 v6.Pod

  • v6.Pod 轉換為 api.Pod 結構

  • api.Pod 轉換為 v5.Pod 結構

  • v5.Pod 序列化為 JSON 併發送給使用者

此過程的含義是必須謹慎且向後相容地進行 API 變更。

API 版本控制

為了更輕鬆地支援多個結構,Kubernetes 支援多個 API 版本,每個版本位於不同的 API 路徑,例如 /api/v1/apsi/extensions/v1beta1

Kubernetes 的版本控制標準在多個標準中定義。

Alpha 版本

  • 此版本包含 alpha 版本(例如 v1alpha1)

  • 此版本可能存在錯誤;啟用的版本可能存在錯誤

  • 隨時可能取消對錯誤的支援。

  • 建議僅在短期測試中使用,因為可能並非一直都提供支援。

Beta 版本

  • 版本名稱包含 beta(例如 v2beta3)

  • 程式碼已完全測試,並且啟用的版本應該穩定。

  • 不會取消對該功能的支援;可能會有一些小的更改。

  • 由於後續版本中可能存在不相容的更改,因此建議僅用於非關鍵業務用途。

穩定版本

  • 版本名稱為 vX,其中 X 為整數。

  • 功能的穩定版本將在許多後續版本中出現在釋出的軟體中。

Kubernetes - Kubectl

Kubectl 是與 Kubernetes API 互動的命令列實用程式。它是一個用於在 Kubernetes 叢集中通訊和管理 Pod 的介面。

需要在本地設定 kubectl 才能與 Kubernetes 叢集互動。

設定 Kubectl

使用 curl 命令將可執行檔案下載到本地工作站。

在 Linux 上

$ curl -O https://storage.googleapis.com/kubernetesrelease/
release/v1.5.2/bin/linux/amd64/kubectl

在 OS X 工作站上

$ curl -O https://storage.googleapis.com/kubernetesrelease/
release/v1.5.2/bin/darwin/amd64/kubectl

下載完成後,將二進位制檔案移動到系統的路徑中。

$ chmod +x kubectl
$ mv kubectl /usr/local/bin/kubectl

配置 Kubectl

以下是執行配置操作的步驟。

$ kubectl config set-cluster default-cluster --server = https://${MASTER_HOST} --
certificate-authority = ${CA_CERT}

$ kubectl config set-credentials default-admin --certificateauthority = ${
CA_CERT} --client-key = ${ADMIN_KEY} --clientcertificate = ${
ADMIN_CERT}

$ kubectl config set-context default-system --cluster = default-cluster --
user = default-admin
$ kubectl config use-context default-system
  • ${MASTER_HOST} 替換為前面步驟中使用的主節點地址或名稱。

  • ${CA_CERT} 替換為前面步驟中建立的 ca.pem 的絕對路徑。

  • ${ADMIN_KEY} 替換為前面步驟中建立的 admin-key.pem 的絕對路徑。

  • ${ADMIN_CERT} 替換為前面步驟中建立的 admin.pem 的絕對路徑。

驗證設定

要驗證 kubectl 是否正常工作,請檢查 Kubernetes 客戶端是否已正確設定。

$ kubectl get nodes

NAME       LABELS                                     STATUS
Vipin.com  Kubernetes.io/hostname = vipin.mishra.com    Ready

Kubernetes - Kubectl 命令

Kubectl 控制 Kubernetes 叢集。它是 Kubernetes 的關鍵元件之一,在設定完成後,它可以在任何機器上的工作站上執行。它能夠管理叢集中的節點。

Kubectl 命令用於互動和管理 Kubernetes 物件和叢集。在本章中,我們將討論透過 kubectl 在 Kubernetes 中使用的一些命令。

kubectl annotate - 它更新資源上的註釋。

$kubectl annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ...
KEY_N = VAL_N [--resource-version = version]

例如:

kubectl annotate pods tomcat description = 'my frontend'

kubectl api-versions - 它列印叢集上受支援的 API 版本。

$ kubectl api-version;

kubectl apply - 它能夠透過檔案或 stdin 配置資源。

$ kubectl apply –f <filename>

kubectl attach - 這將事物附加到正在執行的容器。

$ kubectl attach <pod> –c <container>
$ kubectl attach 123456-7890 -c tomcat-conatiner

kubectl autoscale - 這用於自動縮放已定義的 Pod,例如 Deployment、ReplicaSet、Replication Controller。

$ kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min = MINPODS] --
max = MAXPODS [--cpu-percent = CPU] [flags]
$ kubectl autoscale deployment foo --min = 2 --max = 10

kubectl cluster-info - 它顯示叢集資訊。

$ kubectl cluster-info

kubectl cluster-info dump - 它轉儲有關叢集的相關資訊,用於除錯和診斷。

$ kubectl cluster-info dump
$ kubectl cluster-info dump --output-directory = /path/to/cluster-state

kubectl config - 修改 kubeconfig 檔案。

$ kubectl config <SUBCOMMAD>
$ kubectl config –-kubeconfig <String of File name>

kubectl config current-context - 它顯示當前上下文。

$ kubectl config current-context
#deploys the current context

kubectl config delete-cluster - 從 kubeconfig 中刪除指定的叢集。

$ kubectl config delete-cluster <Cluster Name>

kubectl config delete-context - 從 kubeconfig 中刪除指定的上下文。

$ kubectl config delete-context <Context Name>

kubectl config get-clusters - 顯示 kubeconfig 中定義的叢集。

$ kubectl config get-cluster
$ kubectl config get-cluster <Cluser Name>

kubectl config get-contexts - 描述一個或多個上下文。

$ kubectl config get-context <Context Name>

kubectl config set-cluster - 設定 Kubernetes 中的叢集條目。

$ kubectl config set-cluster NAME [--server = server] [--certificateauthority =
path/to/certificate/authority] [--insecure-skip-tls-verify = true]

kubectl config set-context - 設定 kubernetes 入口點中的上下文條目。

$ kubectl config set-context NAME [--cluster = cluster_nickname] [--
user = user_nickname] [--namespace = namespace]
$ kubectl config set-context prod –user = vipin-mishra

kubectl config set-credentials - 在 kubeconfig 中設定使用者條目。

$ kubectl config set-credentials cluster-admin --username = vipin --
password = uXFGweU9l35qcif

kubectl config set - 設定 kubeconfig 檔案中的單個值。

$ kubectl config set PROPERTY_NAME PROPERTY_VALUE

kubectl config unset - 它取消設定 kubectl 中的特定元件。

$ kubectl config unset PROPERTY_NAME PROPERTY_VALUE

kubectl config use-context - 設定 kubectl 檔案中的當前上下文。

$ kubectl config use-context <Context Name>

kubectl config view

$ kubectl config view
$ kubectl config view –o jsonpath='{.users[?(@.name == "e2e")].user.password}'

kubectl cp - 將檔案和目錄複製到容器和從容器複製。

$ kubectl cp <Files from source> <Files to Destinatiion>
$ kubectl cp /tmp/foo <some-pod>:/tmp/bar -c <specific-container>

kubectl create - 透過檔名或 stdin 建立資源。為此,接受 JSON 或 YAML 格式。

$ kubectl create –f <File Name>
$ cat <file name> | kubectl create –f -

同樣,我們可以使用 create 命令以及 kubectl 建立多個列出的內容。

  • deployment
  • namespace
  • quota
  • secret docker-registry
  • secret
  • secret generic
  • secret tls
  • serviceaccount
  • service clusterip
  • service loadbalancer
  • service nodeport

kubectl delete - 透過檔名、stdin、資源和名稱刪除資源。

$ kubectl delete –f ([-f FILENAME] | TYPE [(NAME | -l label | --all)])

kubectl describe - 描述 Kubernetes 中的任何特定資源。顯示資源或一組資源的詳細資訊。

$ kubectl describe <type> <type name>
$ kubectl describe pod tomcat

kubectl drain - 這用於出於維護目的而排空節點。它為維護準備節點。這將使節點標記為不可用,因此不應為將要建立的新容器分配它。

$ kubectl drain tomcat –force

kubectl edit - 它用於結束伺服器上的資源。這允許直接編輯可以透過命令列工具接收的資源。

$ kubectl edit <Resource/Name | File Name)
Ex.
$ kubectl edit rc/tomcat

kubectl exec - 這有助於在容器中執行命令。

$ kubectl exec POD <-c CONTAINER > -- COMMAND < args...>
$ kubectl exec tomcat 123-5-456 date

kubectl expose - 這用於將 Kubernetes 物件(例如 Pod、Replication Controller 和 Service)公開為新的 Kubernetes 服務。它能夠透過正在執行的容器或 yaml 檔案公開它。

$ kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol = TCP|UDP]
[--target-port = number-or-name] [--name = name] [--external-ip = external-ip-ofservice]
[--type = type]
$ kubectl expose rc tomcat –-port=80 –target-port = 30000
$ kubectl expose –f tomcat.yaml –port = 80 –target-port =

kubectl get - 此命令能夠獲取有關 Kubernetes 資源的叢集資料。

$ kubectl get [(-o|--output=)json|yaml|wide|custom-columns=...|custom-columnsfile=...|
go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...]
(TYPE [NAME | -l label] | TYPE/NAME ...) [flags]

例如:

$ kubectl get pod <pod name>
$ kubectl get service <Service name>

kubectl logs - 用於獲取 Pod 中容器的日誌。列印日誌可以定義 Pod 中的容器名稱。如果 POD 只有一個容器,則無需定義其名稱。

$ kubectl logs [-f] [-p] POD [-c CONTAINER]
Example
$ kubectl logs tomcat.
$ kubectl logs –p –c tomcat.8

kubectl port-forward - 用於將一個或多個本地埠轉發到 Pod。

$ kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT
[...[LOCAL_PORT_N:]REMOTE_PORT_N]
$ kubectl port-forward tomcat 3000 4000
$ kubectl port-forward tomcat 3000:5000

kubectl replace - 能夠透過檔名或 stdin 替換資源。

$ kubectl replace -f FILENAME
$ kubectl replace –f tomcat.yml
$ cat tomcat.yml | kubectl replace –f -

kubectl rolling-update - 對 Replication Controller 執行滾動更新。透過一次更新一個 Pod 來將指定的 Replication Controller 替換為新的 Replication Controller。

$ kubectl rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] --
image = NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC)
$ kubectl rolling-update frontend-v1 –f freontend-v2.yaml

kubectl rollout - 它能夠管理部署的推出。

$ Kubectl rollout <Sub Command>
$ kubectl rollout undo deployment/tomcat

除此之外,我們可以使用 rollout 執行多項任務,例如:

  • rollout history
  • rollout pause
  • rollout resume
  • rollout status
  • rollout undo

kubectl run - run 命令能夠在 Kubernetes 叢集上執行映像。

$ kubectl run NAME --image = image [--env = "key = value"] [--port = port] [--
replicas = replicas] [--dry-run = bool] [--overrides = inline-json] [--command] --
[COMMAND] [args...]
$ kubectl run tomcat --image = tomcat:7.0
$ kubectl run tomcat –-image = tomcat:7.0 –port = 5000

kubectl scale - 它將縮放 Kubernetes Deployment、ReplicaSet、Replication Controller 或 Job 的大小。

$ kubectl scale [--resource-version = version] [--current-replicas = count] --
replicas = COUNT (-f FILENAME | TYPE NAME )
$ kubectl scale –-replica = 3 rs/tomcat
$ kubectl scale –replica = 3 tomcat.yaml

kubectl set image - 它更新 Pod 模板的映像。

$ kubectl set image (-f FILENAME | TYPE NAME)
CONTAINER_NAME_1 = CONTAINER_IMAGE_1 ... CONTAINER_NAME_N = CONTAINER_IMAGE_N
$ kubectl set image deployment/tomcat busybox = busybox ngnix = ngnix:1.9.1
$ kubectl set image deployments, rc tomcat = tomcat6.0 --all

kubectl set resources - 用於設定資源的內容。它使用 Pod 模板更新物件的資源/限制。

$ kubectl set resources (-f FILENAME | TYPE NAME) ([--limits = LIMITS & --
requests = REQUESTS]
$ kubectl set resources deployment tomcat -c = tomcat --
limits = cpu = 200m,memory = 512Mi

kubectl top node - 它顯示 CPU/記憶體/儲存使用情況。top 命令允許您檢視節點的資源消耗。

$ kubectl top node [node Name]

此命令也可以與 Pod 一起使用。

Kubernetes - 建立應用

為了建立 Kubernetes 部署的應用程式,我們需要首先在 Docker 上建立應用程式。這可以透過兩種方式完成:

  • 透過下載
  • 從 Dockerfile

透過下載

可以從 Docker Hub 下載現有映像,並將其儲存在本地 Docker 登錄檔中。

為此,請執行 Docker pull 命令。

$ docker pull --help
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from the registry
   -a, --all-tags = false     Download all tagged images in the repository
   --help = false             Print usage

以下是上述程式碼的輸出。

App Output

上面的螢幕截圖顯示了一組儲存在本地 Docker 登錄檔中的映像。

如果我們想從包含要測試的應用程式的映像構建容器,我們可以使用 Docker run 命令來完成。

$ docker run –i –t unbunt /bin/bash

從 Dockerfile

為了從 Dockerfile 建立應用程式,我們需要首先建立一個 Dockerfile。

下面是一個 Jenkins Docker 檔案的示例。

FROM ubuntu:14.04
MAINTAINER vipinkumarmishra@virtusapolaris.com
ENV REFRESHED_AT 2017-01-15
RUN apt-get update -qq && apt-get install -qqy curl
RUN curl https://get.docker.io/gpg | apt-key add -
RUN echo deb http://get.docker.io/ubuntu docker main > /etc/apt/↩
sources.list.d/docker.list
RUN apt-get update -qq && apt-get install -qqy iptables ca-↩
certificates lxc openjdk-6-jdk git-core lxc-docker
ENV JENKINS_HOME /opt/jenkins/data
ENV JENKINS_MIRROR http://mirrors.jenkins-ci.org
RUN mkdir -p $JENKINS_HOME/plugins
RUN curl -sf -o /opt/jenkins/jenkins.war -L $JENKINS_MIRROR/war-↩
stable/latest/jenkins.war
RUN for plugin in chucknorris greenballs scm-api git-client git ↩
ws-cleanup ;\
do curl -sf -o $JENKINS_HOME/plugins/${plugin}.hpi \
-L $JENKINS_MIRROR/plugins/${plugin}/latest/${plugin}.hpi ↩
; done
ADD ./dockerjenkins.sh /usr/local/bin/dockerjenkins.sh
RUN chmod +x /usr/local/bin/dockerjenkins.sh
VOLUME /var/lib/docker
EXPOSE 8080
ENTRYPOINT [ "/usr/local/bin/dockerjenkins.sh" ]

建立上述檔案後,將其儲存為 Dockerfile,然後 `cd` 到檔案路徑。然後,執行以下命令。

Run Command
$ sudo docker build -t jamtur01/Jenkins .

構建映象後,我們可以測試映象是否正常工作並可以轉換為容器。

$ docker run –i –t jamtur01/Jenkins /bin/bash

Kubernetes - 應用部署

部署是將映象轉換為容器,然後將這些映象分配到 Kubernetes 叢集中的 Pod 的一種方法。這也有助於設定應用程式叢集,其中包括部署服務、Pod、副本控制器和副本集。可以這樣設定叢集:部署在 Pod 上的應用程式可以相互通訊。

在此設定中,我們可以在一個應用程式的頂部設定負載均衡器,將流量分流到一組 Pod,然後它們與後端 Pod 通訊。Pod 之間的通訊透過在 Kubernetes 中構建的服務物件進行。

Application Cluster View

Nginx 負載均衡器 Yaml 檔案

apiVersion: v1
kind: Service
metadata:
   name: oppv-dev-nginx
      labels:
         k8s-app: omni-ppv-api
spec:
   type: NodePort
   ports:
   - port: 8080
      nodePort: 31999
      name: omninginx
   selector:
      k8s-app: appname
      component: nginx
      env: dev

Nginx 副本控制器 Yaml 檔案

apiVersion: v1
kind: ReplicationController
metadata:
   name: appname
spec:
   replicas: replica_count
   template:
      metadata:
         name: appname
         labels:
            k8s-app: appname
            component: nginx
               env: env_name
spec:
   nodeSelector:
      resource-group: oppv
   containers:
      - name: appname
      image: IMAGE_TEMPLATE
      imagePullPolicy: Always
      ports:
         - containerPort: 8080
         resources:
            requests:
               memory: "request_mem"
               cpu: "request_cpu"
            limits:
               memory: "limit_mem"
               cpu: "limit_cpu"
            env:
            - name: BACKEND_HOST
               value: oppv-env_name-node:3000

前端服務 Yaml 檔案

apiVersion: v1
kind: Service
metadata:
   name: appname
   labels:
      k8s-app: appname
spec:
   type: NodePort
   ports:
   - name: http
      port: 3000
      protocol: TCP
      targetPort: 3000
   selector:
      k8s-app: appname
      component: nodejs
      env: dev

前端副本控制器 Yaml 檔案

apiVersion: v1
kind: ReplicationController
metadata:
   name: Frontend
spec:
   replicas: 3
   template:
      metadata:
         name: frontend
         labels:
            k8s-app: Frontend
            component: nodejs
            env: Dev
spec:
   nodeSelector:
      resource-group: oppv
   containers:
      - name: appname
         image: IMAGE_TEMPLATE
         imagePullPolicy: Always
         ports:
            - containerPort: 3000
            resources:
               requests:
                  memory: "request_mem"
                  cpu: "limit_cpu"
                  limits:
                  memory: "limit_mem"
                  cpu: "limit_cpu"
            env:
               - name: ENV
               valueFrom:
               configMapKeyRef:
               name: appname
               key: config-env

後端服務 Yaml 檔案

apiVersion: v1
kind: Service
metadata:
   name: backend
   labels:
      k8s-app: backend
spec:
   type: NodePort
   ports:
   - name: http
      port: 9010
      protocol: TCP
      targetPort: 9000
   selector:
      k8s-app: appname
      component: play
      env: dev

後端副本控制器 Yaml 檔案

apiVersion: v1
kind: ReplicationController
metadata:
   name: backend
spec:
   replicas: 3
   template:
      metadata:
         name: backend
      labels:
         k8s-app: beckend
         component: play
         env: dev
spec:
   nodeSelector:
      resource-group: oppv
      containers:
         - name: appname
            image: IMAGE_TEMPLATE
            imagePullPolicy: Always
            ports:
            - containerPort: 9000
            command: [ "./docker-entrypoint.sh" ]
            resources:
               requests:
                  memory: "request_mem"
                  cpu: "request_cpu"
               limits:
                  memory: "limit_mem"
                  cpu: "limit_cpu"
            volumeMounts:
               - name: config-volume
               mountPath: /app/vipin/play/conf
         volumes:
            - name: config-volume
            configMap:
            name: appname

Kubernetes - 自動伸縮

自動伸縮是 Kubernetes 叢集的關鍵特性之一。它是一個功能,叢集能夠隨著服務響應需求的增加而增加節點數量,隨著需求的減少而減少節點數量。此自動伸縮功能目前受 Google Cloud Engine (GCE) 和 Google Container Engine (GKE) 支援,很快就會在 AWS 上推出。

為了在 GCE 中設定可伸縮的基礎架構,我們需要首先擁有一個啟用了 Google Cloud Monitoring、Google Cloud Logging 和 Stackdriver 功能的活動 GCE 專案。

首先,我們將設定叢集,其中執行少量節點。完成後,我們需要設定以下環境變數。

環境變數

export NUM_NODES = 2
export KUBE_AUTOSCALER_MIN_NODES = 2
export KUBE_AUTOSCALER_MAX_NODES = 5
export KUBE_ENABLE_CLUSTER_AUTOSCALER = true

完成後,我們將透過執行kube-up.sh啟動叢集。這將建立一個叢集以及叢集自動伸縮器附加元件。

./cluster/kube-up.sh

建立集群后,我們可以使用以下 kubectl 命令檢查叢集。

$ kubectl get nodes
NAME                             STATUS                       AGE
kubernetes-master                Ready,SchedulingDisabled     10m
kubernetes-minion-group-de5q     Ready                        10m
kubernetes-minion-group-yhdx     Ready                        8m

現在,我們可以在叢集上部署應用程式,然後啟用水平 Pod 自動伸縮器。這可以使用以下命令完成。

$ kubectl autoscale deployment <Application Name> --cpu-percent = 50 --min = 1 --
max = 10

上述命令表明,隨著應用程式負載的增加,我們將至少維護一個,最多 10 個 Pod 副本。

我們可以透過執行$kubclt get hpa命令來檢查自動伸縮器的狀態。我們將使用以下命令增加 Pod 上的負載。

$ kubectl run -i --tty load-generator --image = busybox /bin/sh
$ while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done

我們可以透過執行$ kubectl get hpa命令來檢查hpa

$ kubectl get hpa
NAME         REFERENCE                     TARGET CURRENT
php-apache   Deployment/php-apache/scale    50%    310%

MINPODS  MAXPODS   AGE
  1        20      2m
  
$ kubectl get deployment php-apache
NAME         DESIRED    CURRENT    UP-TO-DATE    AVAILABLE   AGE
php-apache      7          7           7            3        4m

我們可以使用以下命令檢查正在執行的 Pod 數量。

jsz@jsz-desk2:~/k8s-src$ kubectl get pods
php-apache-2046965998-3ewo6 0/1        Pending 0         1m
php-apache-2046965998-8m03k 1/1        Running 0         1m
php-apache-2046965998-ddpgp 1/1        Running 0         5m
php-apache-2046965998-lrik6 1/1        Running 0         1m
php-apache-2046965998-nj465 0/1        Pending 0         1m
php-apache-2046965998-tmwg1 1/1        Running 0         1m
php-apache-2046965998-xkbw1 0/1        Pending 0         1m

最後,我們可以獲取節點狀態。

$ kubectl get nodes
NAME                             STATUS                        AGE
kubernetes-master                Ready,SchedulingDisabled      9m
kubernetes-minion-group-6z5i     Ready                         43s
kubernetes-minion-group-de5q     Ready                         9m
kubernetes-minion-group-yhdx     Ready                         9m

Kubernetes - 儀表盤設定

設定 Kubernetes 儀表板涉及多個步驟,需要一組工具作為先決條件才能進行設定。

  • Docker (1.3+)
  • go (1.5+)
  • nodejs (4.2.2+)
  • npm (1.3+)
  • java (7+)
  • gulp (3.9+)
  • Kubernetes (1.1.2+)

設定儀表板

$ sudo apt-get update && sudo apt-get upgrade

Installing Python
$ sudo apt-get install python
$ sudo apt-get install python3

Installing GCC
$ sudo apt-get install gcc-4.8 g++-4.8

Installing make
$ sudo apt-get install make

Installing Java
$ sudo apt-get install openjdk-7-jdk

Installing Node.js
$ wget https://nodejs.org/dist/v4.2.2/node-v4.2.2.tar.gz
$ tar -xzf node-v4.2.2.tar.gz
$ cd node-v4.2.2
$ ./configure
$ make
$ sudo make install

Installing gulp
$ npm install -g gulp
$ npm install gulp

驗證版本

Java Version
$ java –version
java version "1.7.0_91"
OpenJDK Runtime Environment (IcedTea 2.6.3) (7u91-2.6.3-1~deb8u1+rpi1)
OpenJDK Zero VM (build 24.91-b01, mixed mode)

$ node –v
V4.2.2

$ npn -v
2.14.7

$ gulp -v
[09:51:28] CLI version 3.9.0

$ sudo gcc --version
gcc (Raspbian 4.8.4-1) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc. This is free software; 
see the source for copying conditions. There is NO warranty; not even for 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

安裝 GO

$ git clone https://go.googlesource.com/go
$ cd go
$ git checkout go1.4.3
$ cd src

Building GO
$ ./all.bash
$ vi /root/.bashrc
In the .bashrc
   export GOROOT = $HOME/go
   export PATH = $PATH:$GOROOT/bin
   
$ go version
go version go1.4.3 linux/arm

安裝 Kubernetes 儀表板

$ git clone https://github.com/kubernetes/dashboard.git
$ cd dashboard
$ npm install -g bower

執行儀表板

$ git clone https://github.com/kubernetes/dashboard.git
$ cd dashboard
$ npm install -g bower
$ gulp serve
[11:19:12] Requiring external module babel-core/register
[11:20:50] Using gulpfile ~/dashboard/gulpfile.babel.js
[11:20:50] Starting 'package-backend-source'...
[11:20:50] Starting 'kill-backend'...
[11:20:50] Finished 'kill-backend' after 1.39 ms
[11:20:50] Starting 'scripts'...
[11:20:53] Starting 'styles'...
[11:21:41] Finished 'scripts' after 50 s
[11:21:42] Finished 'package-backend-source' after 52 s
[11:21:42] Starting 'backend'...
[11:21:43] Finished 'styles' after 49 s
[11:21:43] Starting 'index'...
[11:21:44] Finished 'index' after 1.43 s
[11:21:44] Starting 'watch'...
[11:21:45] Finished 'watch' after 1.41 s
[11:23:27] Finished 'backend' after 1.73 min
[11:23:27] Starting 'spawn-backend'...
[11:23:27] Finished 'spawn-backend' after 88 ms
[11:23:27] Starting 'serve'...
2016/02/01 11:23:27 Starting HTTP server on port 9091
2016/02/01 11:23:27 Creating API client for
2016/02/01 11:23:27 Creating Heapster REST client for https://:8082
[11:23:27] Finished 'serve' after 312 ms
[BS] [BrowserSync SPA] Running...
[BS] Access URLs:
--------------------------------------
Local: https://:9090/
External: http://192.168.1.21:9090/
--------------------------------------
UI: https://:3001
UI External: http://192.168.1.21:3001
--------------------------------------
[BS] Serving files from: /root/dashboard/.tmp/serve
[BS] Serving files from: /root/dashboard/src/app/frontend
[BS] Serving files from: /root/dashboard/src/app

Kubernetes 儀表板

Kubernetes Dashboard

Kubernetes - 監控

監控是管理大型叢集的關鍵元件之一。為此,我們有很多工具。

使用 Prometheus 進行監控

這是一個監控和警報系統。它是在 SoundCloud 構建的,並在 2012 年開源。它可以很好地處理多維資料。

Prometheus 有多個元件參與監控:

  • Prometheus - 它是抓取和儲存資料的核心元件。

  • Prometheus 節點瀏覽器 - 獲取主機級矩陣並將其公開給 Prometheus。

  • Ranch-eye - 是一個haproxy,並將cAdvisor統計資訊公開給 Prometheus。

  • Grafana - 資料視覺化。

  • InfluxDB - 特別用於儲存來自 Rancher 的資料的時序資料庫。

  • Prom-ranch-exporter - 它是一個簡單的 node.js 應用程式,有助於查詢 Rancher 伺服器以獲取服務堆疊的狀態。

Monitoring with Prometheus

Sematext Docker 代理

它是一個現代的、支援 Docker 的指標、事件和日誌收集代理。它作為一個小容器在每個 Docker 主機上執行,併為所有叢集節點和容器收集日誌、指標和事件。它會發現所有容器(一個 Pod 可能包含多個容器),包括 Kubernetes 核心服務的容器(如果核心服務部署在 Docker 容器中)。部署後,所有日誌和指標都會立即可用。

將代理部署到節點

Kubernetes 提供 DaemonSet,確保將 Pod 新增到叢集。

配置 SemaText Docker 代理

它透過環境變數進行配置。

  • 如果您還沒有帳戶,請在apps.sematext.com獲取免費帳戶。

  • 建立一個型別為“Docker”的 SPM 應用程式以獲取 SPM 應用程式令牌。SPM 應用程式將儲存您的 Kubernetes 效能指標和事件。

  • 建立一個 Logsene 應用程式以獲取 Logsene 應用程式令牌。Logsene 應用程式將儲存您的 Kubernetes 日誌。

  • 編輯 DaemonSet 定義中的 LOGSENE_TOKEN 和 SPM_TOKEN 值,如下所示。

    • 獲取最新的 sematext-agent-daemonset.yml(原始純文字)模板(如下所示)。

    • 將其儲存在磁碟上的某個位置。

    • 將 SPM_TOKEN 和 LOGSENE_TOKEN 佔位符替換為您的 SPM 和 Logsene 應用程式令牌。

建立 DaemonSet 物件

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
   name: sematext-agent
spec:
   template:
      metadata:
         labels:
            app: sematext-agent
      spec:
         selector: {}
         dnsPolicy: "ClusterFirst"
         restartPolicy: "Always"
         containers:
         - name: sematext-agent
            image: sematext/sematext-agent-docker:latest
            imagePullPolicy: "Always"
            env:
            - name: SPM_TOKEN
               value: "REPLACE THIS WITH YOUR SPM TOKEN"
            - name: LOGSENE_TOKEN
               value: "REPLACE THIS WITH YOUR LOGSENE TOKEN"
            - name: KUBERNETES
               value: "1"
            volumeMounts:
               - mountPath: /var/run/docker.sock
                  name: docker-sock
               - mountPath: /etc/localtime
                  name: localtime
            volumes:
               - name: docker-sock
                  hostPath:
                     path: /var/run/docker.sock
               - name: localtime
                  hostPath:
                     path: /etc/localtime

使用 kubectl 執行 Sematext Agent Docker

$ kubectl create -f sematext-agent-daemonset.yml
daemonset "sematext-agent-daemonset" created

Kubernetes 日誌

Kubernetes 容器的日誌與 Docker 容器日誌並沒有太大區別。但是,Kubernetes 使用者需要檢視已部署 Pod 的日誌。因此,擁有可用於日誌搜尋的 Kubernetes 特定資訊非常有用,例如:

  • Kubernetes 名稱空間
  • Kubernetes Pod 名稱
  • Kubernetes 容器名稱
  • Docker 映象名稱
  • Kubernetes UID

使用 ELK Stack 和 LogSpout

ELK 堆疊包括 Elasticsearch、Logstash 和 Kibana。為了將日誌收集並轉發到日誌記錄平臺,我們將使用 LogSpout(儘管還有其他選項,例如 FluentD)。

以下程式碼顯示如何在 Kubernetes 上設定 ELK 叢集併為 Elasticsearch 建立服務:

apiVersion: v1
kind: Service
metadata:
   name: elasticsearch
   namespace: elk
   labels:
      component: elasticsearch
spec:
   type: LoadBalancer
   selector:
      component: elasticsearch
   ports:
   - name: http
      port: 9200
      protocol: TCP
   - name: transport
      port: 9300
      protocol: TCP

建立副本控制器

apiVersion: v1
kind: ReplicationController
metadata:
   name: es
   namespace: elk
   labels:
      component: elasticsearch
spec:
   replicas: 1
   template:
      metadata:
         labels:
            component: elasticsearch
spec:
serviceAccount: elasticsearch
containers:
   - name: es
      securityContext:
      capabilities:
      add:
      - IPC_LOCK
   image: quay.io/pires/docker-elasticsearch-kubernetes:1.7.1-4
   env:
   - name: KUBERNETES_CA_CERTIFICATE_FILE
   value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
   - name: NAMESPACE
   valueFrom:
      fieldRef:
         fieldPath: metadata.namespace
   - name: "CLUSTER_NAME"
      value: "myesdb"
   - name: "DISCOVERY_SERVICE"
      value: "elasticsearch"
   - name: NODE_MASTER
      value: "true"
   - name: NODE_DATA
      value: "true"
   - name: HTTP_ENABLE
      value: "true"
ports:
- containerPort: 9200
   name: http
   protocol: TCP
- containerPort: 9300
volumeMounts:
- mountPath: /data
   name: storage
volumes:
   - name: storage
      emptyDir: {}

Kibana URL

對於 Kibana,我們將 Elasticsearch URL 作為環境變數提供。

- name: KIBANA_ES_URL
value: "http://elasticsearch.elk.svc.cluster.local:9200"
- name: KUBERNETES_TRUST_CERT
value: "true"

Kibana UI 將可在容器埠 5601 和相應的主機/節點埠組合處訪問。開始時,Kibana 中不會有任何資料(這是預期的,因為您沒有推送任何資料)。

廣告