Kubernetes部署實操教程
Kubernetes 部署實操教程
ofollow,noindex" target="_blank">原文
之前,我們基本都是單體 web 應用程式:大型的程式碼庫,隨著新的功能和特性不斷髮展,最後它們都會變成巨大的,緩慢移動的,難以管理的巨人。 現在,越來越多的開發人員,架構師和 DevOps 專家認為,使用微服務比使用大型單體應用更好。 通常,使用基於微服務的體系結構意味著將您的單體應用分成至少兩個應用程式:前端應用程式和後端應用程式(API)。 在決定使用微服務之後,出現了一個問題:在什麼環境下執行微服務更好? 我應該選擇什麼來使我的服務穩定,易於管理和部署? 簡短的回答是:使用 Docker!
在本文中,我將向您介紹容器,解釋 Kubernetes,並教您如何使用 CircleCI 將應用程式容器化和部署到 Kubernetes 叢集。
Docker?什麼是 Docker?
Docker 是一款旨在讓 DevOps(和您的生活)更輕鬆的工具。 使用 Docker,開發人員可以在容器中建立,部署和執行應用程式。 容器允許開發人員使用所需的所有部件(例如庫和其他依賴項)打包應用程式,並將其作為一個包釋出出去。
使用容器,開發人員可以輕鬆將映象(重新)部署到任何作業系統。 只需安裝 Docker,執行命令,您的應用程式即可啟動並執行。 哦,不要擔心主機作業系統中新版本庫的任何不一致。 此外,您可以在同一主機上啟動很多容器 - 不管是相同的應用程式還是其他應用程式,都沒關係。
看起來 Docker 是一個很棒的工具。 但是我應該如何以及在何處啟動容器?
執行容器的方式有很多選擇:
- AWS Elastic Container Service(AWS Fargate 或具有水平和垂直自動伸縮的預留例項);
- Azure 或 Google Cloud 中具有預定義 Docker 映象的雲實例(包含模板,例項組和自動縮放);
- 在您自己的伺服器上;
- 當然還有 Kubernetes! Kubernetes 是 2014 年由 Google 工程師專門為虛擬化和容器建立的。
Kubernetes? 那是什麼?
Kubernetes 是一個開源系統,允許您執行容器,管理容器,自動化部署,擴充套件部署,建立和配置 Ingress,部署無狀態或有狀態應用程式以及許多其他內容。 基本上,您可以啟動一個或多個例項來安裝 Kubernetes,將其作為 Kubernetes 叢集進行操作。 然後獲取 Kubernetes 叢集的 API 端點,配置 kubectl(管理 Kubernetes 叢集的工具),Kubernetes 即可投入使用。
那我為什麼要用 Kubernetes 呢?
使用 Kubernetes,您可以最大限度地利用計算資源。 通過 Kubernetes,您將成為您的船(基礎設施)的船長,Kubernetes 將為您揚帆。 使用 Kubernetes,您的服務將是高可用的。 最重要的是,通過 Kubernetes,您將節省大量資金。
看起來很有前途,特別是如果它會省錢! 讓我們來談談它!
Kubernetes 日復一日地更加受歡迎。 讓我們更深入地研究一下這幕後的內容。
(譯者注:上圖有個小錯誤,kubectl 寫成了 kubecti。)
Kubernetes 是整個系統的名稱,但與您的汽車一樣,有許多小部件可以完美地彼此協同工作以使 Kubernetes 發揮其各種作用。 讓我們來了解它們分別是什麼。
主節點(Master Node) - 整個 Kubernetes 叢集的控制面板。 主節點的元件可以在群集中的任何節點上執行。 關鍵組成部分是:
- API Server:所有 REST 命令的入口點,是可以讓使用者可以訪問的主節點的唯一元件。
- Datastore: Kubernetes 群集使用的強大,一致且高可用的鍵值儲存。
- Scheduler:監視新建立的 pod 並將它們分配給節點。 pod 和 services 部署到節點上主要由 scheduler 來控制。
- Controller manager: 管理著處理叢集中日常任務的所有控制器。
- Worker Node:主要的節點代理,也稱為 minion(舊版本 kubernetes 的叫法)。 Pod 在這裡執行。 工作節點包含所有必要的服務,這些服務包括管理容器之間的網路,與主節點通訊以及將資源分配給已排程容器等。
- Docker:執行在每個工作節點上,用來下載映象和啟動容器。
- Kubelet:監視 pod 的狀態並確保容器已啟動並執行。 它還與資料儲存通訊,獲取有關服務的資訊並記錄新建立的服務的詳細資訊。
- Kube-proxy:單個工作節點上的服務的網路代理和負載均衡。 它負責流量路由。
- Kubectl:一個 CLI 工具,供使用者與 Kubernetes API Server 進行通訊。
那什麼是 pods 和 services?
Pod 是 Kubernetes 叢集中最小的單元,就像一座巨大建築物牆上的一塊磚。 pod 是一組需要一起執行並且可以共享資源的容器(Linux 名稱空間,cgroups,IP 地址)。 Pod 的生命週期是非永久性的。
Service 是在多個 pod 之上的抽象,通常需要在它上面有層代理,以便其他服務通過虛擬 IP 地址與其通訊。
一個簡單部署例子
我將使用簡單的 Ruby on Rails 應用程式和 GKE 作為執行 Kubernetes 的平臺。 實際上,您可以在 AWS 或 Azure 中使用 Kubernetes,甚至可以在您自己的硬體中建立叢集,或使用您 minikube 在本地執行 Kubernetes,所有的選項你都可以在這個頁面 Setup - Kubernetes 上找到。
這個 app 的原始碼你可以在 GitHub - d-kononov/simple-rails-app-in-k8s 裡找到。
要建立新的 Rails 應用程式,請執行:
rails new blog
在 config/database.yml
檔案中配置生產 SQL/">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 model, controller, views, 和 migration, 請執行:
rails g scaffold Article title:string description:text
新增 Gems 到 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和服務
頁面中建立一個 service account
金鑰,以便從 sidecar 容器訪問 MySQL 資料庫。 您可以在 此處 找到有關該流程的更多資訊。 將下載的檔案重新命名為 service-account.json
。 我們稍後會用到這個檔案。
我們準備將我們的應用程式部署到 Kubernetes,但首先,我們應該為我們的應用程式建立 secret
- 在 Kubernetes 中建立用於儲存敏感資料的 secret 物件。 上傳之前下載的 service-account.json
檔案:
kubectl create secret generic mysql-instance-credentials \ --from-file=credentials.json=service-account.json
為應用程式建立 secrets:
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
請不要忘記替換必要的配置,或者記得正確地設定環境變數。
在建立 deployment 之前,讓我們看一下 deployment.yaml 。 我把三個檔案連成一個; 第一部分是一個 service,它將公開埠 80 並轉發到埠 80 和到 3000 的所有連線。該 service 有一個 selector,service 通過它知道應該哪個 pod 應該轉發連線。
該檔案的下一部分是 deployment,它描述了將在 pod 中啟動的部署策略容器,環境變數,資源,探針,每個容器的 mounts 以及其他資訊。
最後一部分是 Horizontal Pod Autoscaler。 HPA 有一個非常簡單的配置。 請記住,如果您未在部署部分中為容器設定資源,則 HPA 將無法執行。
您可以在 GKE 編輯頁面中為 Kubernetes 叢集配置 Vertical Autoscaler。 它也有一個非常簡單的配置。
是時候將它釋出到 GKE 叢集了! 首先,我們通過 rake-tasks-job.yaml 進行部署。 執行:
kubectl apply -f rake-tasks-job.yaml
這個 job 對於 CI/CD 很有用。
kubectl apply -f deployment.yaml
上面這條命令用來建立 service, deployment 和 HPA。
然後通過 kubectl get pods -w
命令來檢查你的 pods:
NAMEREADYSTATUSRESTARTSAGE sample-799bf9fd9c-86cqf2/2Running01m sample-799bf9fd9c-887vv2/2Running01m sample-799bf9fd9c-pkscp2/2Running01m
現在讓我們為應用建立一個 Ingress:
gcloud compute addresses create sample-ip --global kubectl apply -f ingress.yaml kubectl get ingress -w
CI/CD
讓我們使用 CircleCI 建立一個 CI/CD 管道。 實際上,使用 CircleCI 建立 CI/CD 管道很容易,但請記住,快而髒的未經過測試的全自動部署過程僅適用於小型專案,但請不要在嚴肅的專案上這樣做。如果任何新程式碼在生產中出現問題,那麼你將會損失巨大。 這就是為什麼你應該考慮設計一個強大的部署過程,在完全推出之前啟動 canary 任務,在 canary 啟動後檢查日誌中的錯誤,等等。
目前,我們有一個簡單的小專案,所以讓我們建立一個完全自動化,無測試的 CI / CD 部署過程。 首先,您應該將 CircleCI 與您的程式碼倉庫進行整合 - 您可以在此處 config.yml 找到具體內容。 然後我們應該建立一個包含 CircleCI 系統指令的配置檔案。 Config 看起來很簡單。 要點是 GitHub 倉庫中有兩個分支:master 和 production。
- 主分支用於開發,用於新程式碼。 當有人將新程式碼推送到主分支時,CircleCI 啟動主分支構建和測試程式碼的工作流。
- 生產分支用於將新版本部署到生產環境。 生產分支的工作流程如下:推送新程式碼(如果從主分支到生產開放 PR 則更好)以觸發新的構建和部署過程; 在構建過程中,CircleCI 建立新的 Docker 映象,將其推送到 GCR 並建立新的部署; 如果失敗,CircleCI 將觸發回滾過程。
在執行任何構建之前,您應該在 CircleCI 中配置專案。 在 API 和 GCloud 中的 service 頁面中建立一個新的 service account,具有以下角色:完全訪問 GCR 和 GKE,開啟下載的 JSON 檔案並複製內容,然後在 CircleCI 的專案設定中建立一個新的環境變數 GCLOUD_SERVICE_KEY 並將 service account 檔案的內容貼上為值。 此外,您需要建立下一個 env vars: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 分!
現在您已經掌握了基礎知識,您可以進一步將其轉換為更高階的配置。我計劃在以後的文章中介紹更多內容,但與此同時,有一個挑戰:使用位於叢集內的有狀態資料庫(包括用於備份的 sidecar Pod)為您的應用程式建立一個強大的 Kubernetes 叢集,在其中安裝 Jenkins 用於 CI/CD 管道,讓 Jenkins 使用 pod 作為構建的 slave。使用 certmanager 為您的 Ingress 新增/獲取 SSL 證書。使用 Stackdriver 為您的應用程式建立監控和報警系統。
Kubernetes 非常棒,因為它很容易擴充套件,沒有供應商鎖定,並且,因為您為例項付費,所以您可以省錢。然而,不是每個人都是 Kubernetes 專家或者有時間建立一個新的叢集。這裡有一個可選方案:關於如何構建有效的初始部署管道並執行更少的操作任務,我的同事 Toptaler Amin Shah Gilani 使用 Heroku,GitLab CI 以及他能想到的其他自動化部署工具做了一套教程 CI/CD:如何部署有效的初始化部署管道 。