什麼是 Kubernetes? 容器化和部署指南

已發表: 2022-03-11

不久前,我們使用了單體式 Web 應用程序:龐大的代碼庫隨著新功能和特性的增長而發展,直到它們變成巨大的、移動緩慢、難以管理的巨人。 現在,越來越多的開發人員、架構師和 DevOps 專家開始認為,使用微服務比使用巨型單體更好。 通常,使用基於微服務的架構意味著將您的單體應用程序拆分為至少兩個應用程序:前端應用程序和後端應用程序(API)。 在決定使用微服務之後,就會出現一個問題:在什麼環境下運行微服務比較好? 我應該選擇什麼來使我的服務穩定且易於管理和部署? 簡短的回答是:使用 Docker!

在本文中,我將向您介紹容器,解釋 Kubernetes,並教您如何使用 CircleCI 將應用程序容器化並部署到 Kubernetes 集群。

碼頭工人? 什麼是 Docker?

Docker 是一個旨在讓 DevOps(和您的生活)更輕鬆的工具。 使用 Docker,開發人員可以在容器中創建、部署和運行應用程序。 容器允許開發人員將應用程序與它需要的所有部分(例如庫和其他依賴項)打包在一起,並將它們作為一個包全部發送出去。

將部署到主機的應用與打包在容器中的應用進行比較

將部署到主機的應用與打包在容器中的應用進行比較

使用容器,開發人員可以輕鬆(重新)將映像部署到任何操作系統。 只需安裝 Docker,執行一個命令,您的應用程序就會啟動並運行。 哦,不用擔心與主機操作系統中的新版本庫有任何不一致。 此外,您可以在同一主機上啟動更多容器——它是同一個應用程序還是另一個? 沒關係。

似乎 Docker 是一個很棒的工具。 但是我應該如何以及在哪裡啟動容器?

關於容器的運行方式和位置有很多選擇:AWS Elastic Container Service(AWS Fargate 或具有水平和垂直自動縮放功能的預留實例); 在 Azure 或 Google Cloud 中具有預定義 Docker 映像的雲實例(帶有模板、實例組和自動縮放); 使用 Docker 在您自己的服務器上; 或者,當然,Kubernetes! Kubernetes 是 Google 的工程師在 2014 年專門為虛擬化和容器創建的。

Kubernetes? 那是什麼?

Kubernetes 是一個開源系統,它允許您運行容器、管理容器、自動化部署、擴展部署、創建和配置入口、部署無狀態或有狀態應用程序以及許多其他事情。 基本上,您可以啟動一個或多個實例並安裝 Kubernetes 以將它們作為 Kubernetes 集群運行。 然後獲取 Kubernetes 集群的 API 端點,配置kubectl (管理 Kubernetes 集群的工具),Kubernetes 就可以服務了。

那麼我為什麼要使用它呢?

使用 Kubernetes,您可以最大限度地利用計算資源。 使用 Kubernetes,您將成為您的船(基礎設施)的船長,Kubernetes 將助您一臂之力。 使用 Kubernetes,您的服務將是 HA。 最重要的是,使用 Kubernetes,您將節省大量資金。

看起來很有希望! 特別是如果它會省錢! 讓我們多談談吧!

Kubernetes 日復一日地越來越受歡迎。 讓我們更深入地研究引擎蓋下的內容。

引擎蓋下:什麼是 Kubernetes?

什麼是 Kubernetes?構成 Kubernetes 底層的組件

組成 Kubernetes 的組件

Kubernetes 是整個系統的名稱,但就像您的汽車一樣,有許多小部件完美協調地協同工作以使 Kubernetes 發揮作用。 讓我們了解它們是什麼。

主節點——整個 Kubernetes 集群的控制面板。 master 的組件可以在集群中的任何節點上運行。 關鍵組件是:

  • API 服務器:所有 REST 命令的入口點,是用戶可訪問的主節點的唯一組件。
  • 數據存儲: Kubernetes 集群使用的強大、一致且高可用的鍵值存儲。
  • 調度程序:監視新創建的 pod 並將它們分配給節點。 由於調度程序,將 Pod 和服務部署到節點上。
  • 控制器管理器:運行集群中處理日常任務​​的所有控制器。
  • Worker 節點:主節點代理,也稱為 Minion 節點。 豆莢在這裡運行。 工作節點包含所有必要的服務來管理容器之間的網絡、與主節點通信以及為調度的容器分配資源。
  • Docker:在每個工作節點上運行並下載圖像和啟動容器。
  • Kubelet:監控 pod 的狀態並確保容器啟動並運行。 它還與數據存儲進行通信,獲取有關服務的信息並寫入有關新創建的服務的詳細信息。
  • Kube-proxy:單個工作節點上服務的網絡代理和負載均衡器。 它負責流量路由。
  • Kubectl:用戶與 Kubernetes API 服務器通信的 CLI 工具。

什麼是 Pod 和服務?

Pod 是Kubernetes集群的最小單元,它就像一棟巨大建築的牆上的一塊磚。 Pod 是一組需要一起運行並且可以共享資源(Linux 命名空間、cgroup、IP 地址)的容器。 豆莢的壽命不長。

服務是許多 pod 之上的抽象,通常需要一個代理,其他服務才能通過虛擬 IP 地址與其通信。

簡單部署示例

不同的利益相關者如何與 Kubernetes 驅動的應用程序交互

不同的利益相關者如何與 Kubernetes 驅動的應用程序交互

我將使用一個簡單的 Ruby on Rails 應用程序和 GKE 作為運行 Kubernetes 的平台。 實際上,您可以在 AWS 或 Azure 中使用 Kubernetes,甚至可以在自己的硬件中創建集群,或者使用minikube在本地運行 Kubernetes——您可以在此頁面上找到所有選項。

此應用程序的源文件可在此 GitHub 存儲庫中找到。

要創建一個新的 Rails 應用程序,請執行:

 rails new blog

config/database.yml file中為生產配置 MySQL 連接:

 production: adapter: mysql2 encoding: utf8 pool: 5 port: 3306 database: <%= ENV['DATABASE_NAME'] %> host: 127.0.0.1 username: <%= ENV['DATABASE_USERNAME'] %> password: <%= ENV['DATABASE_PASSWORD'] %>

要創建 Article 模型、控制器、視圖和遷移,請執行:

 rails g scaffold Article title:string description:text

要將 gem 添加到 Gemfile:

 gem 'mysql2', '< 0.6.0', '>= 0.4.4' gem 'health_check'

要創建 Docker 映像,請獲取我的 Dockerfile 並執行:

 docker build -t REPO_NAME/IMAGE_NAME:TAG . && docker push REPO_NAME/IMAGE_NAME:TAG

是時候創建一個 Kubernetes 集群了。 打開 GKE 頁面並創建 Kubernetes 集群。 創建集群後,單擊“連接按鈕”並複制命令——確保您已安裝並配置 gCloud CLI 工具(操作方法)和 kubectl。 在您的 PC 上執行複制的命令並檢查與 Kubernetes 集群的連接; 執行kubectl cluster-info

該應用程序已準備好部署到 k8s 集群。 讓我們創建一個 MySQL 數據庫。 在 gCloud 控制台中打開 SQL 頁面並為應用程序創建一個 MySQL 數據庫實例。 實例準備就緒後,創建用戶和數據庫並複制實例連接名稱

此外,我們需要在API & Services頁面中創建一個服務帳戶密鑰,以便從 sidecar 容器訪問 MySQL 數據庫。 您可以在此處找到有關該過程的更多信息。 將下載的文件重命名為service-account.json 。 我們稍後會回到那個文件。

我們已經準備好將我們的應用程序部署到 Kubernetes,但首先,我們應該為我們的應用程序創建秘密——Kubernetes 中為存儲敏感數據而創建的秘密對象。 上傳之前下載的service-account.json文件:

 kubectl create secret generic mysql-instance-credentials \ --from-file=credentials.json=service-account.json

為應用程序創建秘密:

 kubectl create secret generic simple-app-secrets \ --from-literal=username=$MYSQL_PASSWORD \ --from-literal=password=$MYSQL_PASSWORD \ --from-literal=database-name=$MYSQL_DB_NAME \ --from-literal=secretkey=$SECRET_RAILS_KEY

不要忘記用您的值替換值或設置環境變量。

在創建部署之前,讓我們看一下部署文件。 我將三個文件合併為一個; 第一部分是一個服務,它將公開端口 80 並將所有來自端口 80 的連接轉發到 3000。該服務有一個選擇器,服務通過該選擇器知道它應該向哪些 pod 轉發連接。

文件的下一部分是部署,它描述了部署策略——將在 pod 內啟動的容器、環境變量、資源、探測器、每個容器的掛載以及其他信息。

最後一部分是 Horizo​​ntal Pod Autoscaler。 HPA有一個非常簡單的配置。 請記住,如果您沒有在部署部分為容器設置資源, HPA將無法工作。

您可以在 GKE 編輯頁面中為您的 Kubernetes 集群配置 Vertical Autoscaler。 它也有一個非常簡單的配置。

是時候將它發送到 GKE 集群了! 首先,我們應該通過 job 運行遷移。 執行:

kubectl apply -f rake-tasks-job.yaml - 此作業對 CI/CD 流程很有用。

kubectl apply -f deployment.yaml – 創建服務、部署和 HPA。

然後通過執行以下命令檢查您的 pod: kubectl get pods -w

 NAME READY STATUS RESTARTS AGE sample-799bf9fd9c-86cqf 2/2 Running 0 1m sample-799bf9fd9c-887vv 2/2 Running 0 1m sample-799bf9fd9c-pkscp 2/2 Running 0 1m

現在讓我們為應用程序創建一個入口:

  1. 創建靜態 IP: gcloud compute addresses create sample-ip --global
  2. 創建入口(文件): kubectl apply -f ingress.yaml
  3. 檢查入口是否已經創建並獲取IP: kubectl get ingress -w
  4. 為您的應用程序創建域/子域。

CI/CD

讓我們使用 CircleCI 創建一個 CI/CD 管道。 實際上,使用 CircleCI 創建 CI/CD 管道很容易,但請記住,沒有像這樣的測試的快速而骯髒的全自動部署過程將適用於小型項目,但請不要為任何嚴重的事情這樣做,因為,如果任何新代碼在生產中出現問題,你就會賠錢。 這就是為什麼你應該考慮設計一個健壯的部署過程,在完全推出之前啟動金絲雀任務,在金絲雀啟動後檢查日誌中的錯誤等等。

目前,我們有一個小而簡單的項目,所以讓我們創建一個完全自動化的、無需測試的 CI/CD 部署過程。 首先,您應該將 CircleCI 與您的存儲庫集成——您可以在此處找到所有說明。 然後我們應該創建一個配置文件,其中包含 CircleCI 系統的說明。 配置看起來很簡單。 要點是 GitHub repo 中有兩個分支: masterproduction

  1. master 分支用於開發,用於新代碼。 當有人將新代碼推送到主分支時,CircleCI 會啟動主分支的工作流程——構建和測試代碼。
  2. 生產分支用於將新版本部署到生產環境。 生產分支的工作流程如下:推送新代碼(或者更好的是,從主分支打開 PR 到生產)以觸發新的構建和部署過程; 在構建過程中,CircleCI 創建新的 Docker 鏡像,將其推送到 GCR 並為部署創建新的 rollout; 如果推出失敗,CircleCI 會觸發回滾過程。

在運行任何構建之前,您應該在 CircleCI 中配置一個項目。 在 API 中創建一個新的服務帳戶,並在 GCloud 中創建一個具有以下角色的服務頁面:完全訪問 GCR 和 GKE,打開下載的 JSON 文件並複制內容,然後在 CircleCI 的項目設置中創建一個新的環境變量,名稱為GCLOUD_SERVICE_KEY並將服務帳戶文件的內容粘貼為值。 此外,您需要創建下一個環境變量: GOOGLE_PROJECT_ID (您可以在 GCloud 控制台主頁上找到它)、 GOOGLE_COMPUTE_ZONE (您的 GKE 集群的區域)和GOOGLE_CLUSTER_NAME (GKE 集群名稱)。

CircleCI 的最後一步(部署)如下所示:

 kubectl patch deployment sample -p '{"spec":{"template":{"spec":{"containers":[{"name":"sample","image":"gcr.io/test-d6bf8/simple:'"$CIRCLE_SHA1"'"}]}}}}' if ! kubectl rollout status deploy/sample; then echo "DEPLOY FAILED, ROLLING BACK TO PREVIOUS" kubectl rollout undo deploy/sample # Deploy failed -> notify slack else echo "Deploy succeeded, current version: ${CIRCLE_SHA1}" # Deploy succeeded -> notify slack fi deployment.extensions/sample patched Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available... Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available... deployment "sample" successfully rolled out Deploy succeeded, current version: 512eabb11c463c5431a1af4ed0b9ebd23597edd9

結論

看起來創建新的 Kubernetes 集群的過程並不難! CI/CD 過程真的很棒!

是的! Kubernetes 太棒了! 使用 Kubernetes,您的系統將更加穩定、易於管理,並使您成為系統的負責人。 更不用說,Kubernetes 對系統進行了一點遊戲化,將為您的營銷提供 +100 分!

現在您已經掌握了基礎知識,您可以更進一步,將其轉變為更高級的配置。 我計劃在以後的文章中介紹更多內容,但與此同時,這裡有一個挑戰:為您的應用程序創建一個健壯的 Kubernetes 集群,其中有一個位於集群內部的有狀態數據庫(包括用於進行備份的 sidecar Pod),將 Jenkins 安裝在相同的 Kubernetes 集群用於 CI/CD 管道,並讓 Jenkins 使用 pod 作為構建的從屬。 使用 certmanager 為您的入口添加/獲取 SSL 證書。 使用 Stackdriver 為您的應用創建監控和警報系統。

Kubernetes 很棒,因為它易於擴展,沒有供應商鎖定,而且由於您為實例付費,因此可以節省資金。 然而,並不是每個人都是 Kubernetes 專家或有時間建立一個新的集群——對於另一種觀點,Toptaler Amin Shah Gilani 提出了使用 Heroku、GitLab CI 和他已經想出的大量自動化的案例為了在How to Build an Effective Initial Deployment Pipeline中編寫更多的代碼,做更少的操作任務。

有關的:
  • 做數學:使用 Orchestrator 自動擴展微服務應用程序
  • K8s/Kubernetes:AWS 與 GCP 與 Azure
  • Kubernetes 服務網格比較