使用 AWS、k3s、Rancher、Vault 和 ArgoCD 在 Kubernetes 上集成 GitOps

翻譯: s1mp le_zj
編輯: LinuxSuRen

最近我寫了一篇關於 CI 和 CD 之間核心區別的文章,我覺得是時候把這些理論運用到實際當中了。


隨着 Kubernetes 將自己打造爲容器編排的工業標準以來,爲你的應用和工具尋找一條能夠高效使用聲明式模型的途徑是成功的關鍵因素。這篇文章中,我將帶領大家在 AWS 上設置一個 k3s Kubernetes 集羣,然後集成 ArgoCD 和 Vault 創建一個安全的 GitOps。可以從這裏檢出基礎設施代碼和 Kubernetes unbrella 應用代碼。

以下是我們將會使用的組件/工具:

  • AWS – 底層基礎設施雲服務方案提供商。它將管理讓 Kubernetes 正常運行的虛擬機和網絡。並允許通過外部世界進入集羣內部。

  • k3s – 由 rancher 開發的一套精簡版本的 Kubernetes 發行版。它清理了許多 alpha 和雲插件,它還允許使用關係型的數據庫(這裏使用的是 RDS)以替代 etcd 作爲後臺存儲。

  • Rancher – 一款以 API 驅動的可以輕鬆管理 Kubernetes 集羣的 UI 工具。

  • Vault – Hashicorp 的密鑰管理系統。我將會使用集成在 vault 的 Banzai Cloud 的 bank-vault,它會允許通過使用一個 Admission Webhook 的方式將密鑰直接注入到 pod 中。這將大大減少你將密鑰存儲到 Git 倉庫的需求。

  • ArgoCD – 一款 GitOps 工具允許你使用 Git 維護 Kubernetes 資源的狀態。ArgoCD 會自動同步 Kubernetes 資源到你的 Git 倉庫中,這樣同樣可以使集羣中的配置清單手動修改後能夠被自動恢復。這樣能夠確保你的聲明式部署模型。

  • Cert Manager/LetsEncrypt – 提供一種爲 Kubernetes 入口自動生成和更新證書的方法。

讓我們從 AWS 基礎設施開始吧。

前置條件 

你需要安裝以下 CLI 到你的系統裏:

  • Trerraform

  • Kubectl

  • AWS

你同樣需要 AWS 管理員權限和獲取密鑰/密碼的方法。如果沒有的話,使用信用卡創建一個賬號即可。

最後,你需要一個主機域名用來管理/升級指向基於 Kubernetes 的 ELB。如果沒有,建議你在 NameCheap 上創建一個賬號然後購買一個 .dev 域名。便宜也好用。

AWS 基礎設施 

對於 AWS 基礎設施,我們將會使用支持 S3 的 Terraform 來維持狀態。這也給我們提供了一種聲明式定義我們的基礎設施並在我們需要時進行迭代創建變更的方法。查看基礎設施倉庫你會看到一個 k3s/example.tfvars 文件。我們需要爲特定的環境/用例更新這個文件,設置如下值:

  • db_username – 管理員用戶名會被應用到 Kubernetes 後端存儲的 RDS 實例中。

  • db_password – RDS 用戶的管理員密碼。通常它會在 terraform apply 命令內聯過程中傳遞此參數,簡單起見,我們將它存儲到文件裏面。

  • piblic_ssh_key – 如果你需要 SSH 到 Kubernetes 的 EC2s,該值爲公共的 SSH 密鑰。

  • keypair_name – public_ssh_key 對應的密鑰對名稱。

  • key_s3_bucket_name – 當集羣創建成功時用於存儲 kubeconfig 文件的存儲區。它在 Amazon 中是全局唯一的。

如果你想修改集羣大小或者設置特定的 CIDRs,可以在下面設置一些可選字段,但是默認你會得到 6-節點(3 服務器,3終端)的 k3s 集羣。

你同樣需要創建一個 S3 存儲區用來存儲 Terraform 狀態然後在 k3s/backends/s3.tfcats 和 k3s/main.tf 中修改 bucket 字段以匹配它們。

當我們更新完所有的字段以及創建完 S3 狀態存儲區之後,接着進行下面的操作以及應用 Terraform。首先,確保在 AWS 賬戶中擁有一個管理者 IAM 用戶這樣你可以設置環境變量或者在系統中使用 AWS API 能夠訪問接口的 AWS 憑據文件,然後運行下面的命令:

cd k3s/  
terraform init -backend-config=backends/s3.tfvars
terraform apply -var-file=example.tfvars

上述命令執行完成後,應用成功後,Terraform 將會輸出預期的 AWS 狀態。你可以查看它們如果按照預期執行的請輸入 yes。AWS 資源配置完成大概需要 5-10 分鐘,時間大多用在了 RDS 集羣上。

確認你的 Kubernetes 集羣 

成功應用 Terraform 之後(多花幾分鐘時間確認 k3s 是否已經部署進去),你需要使用如下命令從 S3 存儲區中獲取 kebeconfig 文件(替換你在 example.tfvars 文件中輸入的存儲區名字):

aws s3 cp s3://YOUR_BUCKET_NAME/k3s.yaml ~/.kube/config

這樣就完成了讓你與你的集羣通信的所有步驟了。然後我們查看下節點的狀態。在繼續下面的事情之前,請確保它們都是 Ready 狀態:

$ kubectl get nodes  
NAME STATUS ROLES AGE VERSION
ip-10-0-1-208.ec2.internal Ready <none> 39m v1.18.9+k3s1
ip-10-0-1-12.ec2.internal Ready master 39m v1.18.9+k3s1
ip-10-0-1-191.ec2.internal Ready master 39m v1.18.9+k3s1
ip-10-0-2-12.ec2.internal Ready master 39m v1.18.9+k3s1
ip-10-0-2-204.ec2.internal Ready <none> 39m v1.18.9+k3s1
ip-10-0-1-169.ec2.internal Ready <none> 39m v1.18.9+k3s1

同樣查看下 ArgoCD 狀態,它是通過配置清單自動部署進去的:

$ kubectl get pods -n kube-system | grep argocd  
helm-install-argocd-5jc9s 0/1 Completed 1 40m
argocd-redis-774b4b475c-8v9s8 1/1 Running 0 40m
argocd-dex-server-6ff57ff5fd-62v9b 1/1 Running 0 40m
argocd-server-5bf58444b4-mpvht 1/1 Running 0 40m
argocd-repo-server-6d456ddf8f-h9gvd 1/1 Running 0 40m
argocd-application-controller-67c7856685-qm9hm 1/1 Running 0 40m

配置 DNS 

對於 DNS,我在 NameCheap 上擁有一個 atoy.dev 的域名,但是你可以使用任何你喜歡的 DNS 提供商。我們需要做的是創建一個通用的 CNAME 條目將所有的請求路由到管理應用程序入口的 AWS ELB 上。

首先,通過 AWS 控制檯 獲取 Elastic 負載均衡器的主機名,轉到 EC2,然後點擊菜單左側的 Load Balancers。到這裏,你可以看到使用隨機字符創建了一個負載均衡器。如果查看 tags,它引用了一個新的 Kubernetes 集羣:

你應該想從這裏拷貝 DNS 名稱。對我而言,我會轉到 NameCheap 域名中的高級 DNS 頁面輸入 CNAME 條目從而讓 *.demo.atoy.dev 指向從 AWS 拷貝的 DNS 名稱。你可以針對你的提供商/域名進行調整:

爲了驗證它是否運行,你可以安裝/使用 nslookup 來確保它解析爲正確的主機名:

$ nslookup test.demo.atoy.dev  
Server: 71.252.0.12
Address: 71.252.0.12#53Non-authoritative answer:
test.demo.atoy.dev canonical name = a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com.
Name: a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com
Address: 52.20.5.150
Name: a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com
Address: 23.20.0.2

現在我們轉到 Umbrella 應用上。

ArgoCD 和 Umbrella 應用程序 

我們已經知道 ArgoCD 已經部署進去了,但是現在我們需要把剩餘使用 ArgoCD App-of-Apps 部署模型的工具部署進去。因爲我們使用的是 GitOps,需要從你的 GitHub 賬號中 fork 出一個 k8s-tools-app 倉庫,然後需要在上面進行一些變更從而兼容你的當前環境:

  1. 需要對 https://github.com/atoy3731/k8s-tools-app.git 做一次全量的查找/替換變更到你 fork 出來的對應 URL 的新的 git 倉庫中。這樣可以讓你管理自己的這套 ArgoCD 需要拉取的環境。請確保你的 Git 倉庫是公開的這樣 ArgoCD 可以獲取到它。

  2. 在 resources/tools/resources/other-resources.yaml 中,將 argoHost 和 issuerEmail 修改爲你自己的域名和郵箱。

  3. 在 resources/tools/resources/rancher.yaml 中,將 hostname 和 email 修改爲你自己的域名和郵箱。

  4. 在 resources/apps/resources/hello-world.yaml 中,修改 2 個 app.demo.atoy.dev 引用爲你自己的域名。

這些變更完成後,將這些變更提交/推送到你 fork 的 Github 倉庫中。現在你已經準備好應用這個 umbrella 應用程序了。在你已經 clone 的倉庫中執行如下操作:

$ kubectl apply -f umbrella-tools.yaml  
appproject.argoproj.io/tools created
application.argoproj.io/umbrella-tools created

這樣,ArgoCD 的魔力開始了,將其他工具添加到之前爲集羣定義的倉庫中。你可以使用下面命令得到已部署應用的列表:

$ kubectl get applications -n kube-system  
NAME AGE
other-resources 56m
umbrella-tools 58m
rancher 57m
vault-impl 57m
vault-operator 58m
vault-webhook 57m
cert-manager 57m
cert-manager-crds 58m

你將有大概 5 分鐘的時間等待所有內容準備完成並讓 LetsEncrypt 生成臨時證書。所有運行正常的話,你可以看到生成了 2 個可以通過瀏覽器訪問的入口:

$ kubectl get ingress -A  
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
cattle-system rancher <none> rancher.demo.atoy.dev a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com 80, 443 59m
kube-system argocd-ingress <none> argo.demo.atoy.dev a4c6dfd75b47a4b1cb85fbccb390fe1f-529310843.us-east-1.elb.amazonaws.com 80, 443 58m

現在你可以通過 https://rancher.YOUR-DOMAIN 訪問 Rancher 通過 https://argo.YOUR-DOMAIN 訪問 ArgoCD。

注意事項 1: 爲了避免來自 LetsEncrypt 的速率限制,我們使用的臨時證書並不是一個有效的證書。這樣會給你使用瀏覽器訪問 Argo、Rancher 或其他 hello-world 應用程序跳過 SSL 驗證提供了機會。使用 Chrome,當例外頁面輸入 thisisunsafe 就會跳過它。你也可以更新爲 cert-manager 使用的 ClusterIssuer 來使用產品級的受信任的證書。

注意事項 2: K3s 預裝了 Traefik 作爲入口控制器,所以我們使用它來簡化操作。

注意事項 3: 第一次進入 Rancher,你需要生成一個密碼和接受一個用來訪問 Rancher 的 URI。URI 在頁面中已經預加載出來了,你只需要點擊 Okey 即可。

注意事項 4: 爲了登錄到 ArgoCD,它使用 admin 作爲用戶名,argocd-server pod 名稱作爲密碼。你可以通過執行如下操作獲取 pod 名(本例中名稱爲 argocd-server-5bf58444b4-mpvht):

$ kubectl get pods -n kube-system | grep argocd-server  
argocd-server-5bf58444b4-mpvht 1/1 Running 0 64m

現在你可以轉到 ArgoCD UI 界面了,會看到下面類似的界面:

現在我們的工具均部署完畢了,讓我們在 Vault 上存儲爲我們的 hello-world 程序需要提取的密鑰。

在 Vault 上創建一個密鑰 

爲了讓事情更容易一些,在工具倉庫中有一個幫助腳本。運行下面命令來獲取你的 Vault admin 令牌和 port-forward 命令:

$ sh tools/vault-config.sh   
Your Vault root token is: s.qEl4Ftr4DR61dmbH3umRaXP0Run the following:
export VAULT_TOKEN=s.qEl4Ftr4DR61dmbH3umRaXP0
export VAULT_CACERT=/Users/adam.toy/.vault-ca.crt
kubectl port-forward -n vault service/vault 8200 &You will then be able to access Vault in your browser at: [https://localhost:8200](https://localhost:8200/)

運行命令的輸出如上所示,然後轉到 https://localhost:8200。輸入上面的 root token 登錄。

登錄後,你應在 Secret Engine 頁面。點擊 secrets/ 入口然後點擊右上方的 Create Secret。我們將創建一個 demo 密鑰,所以在下方圖片中輸入信息然後點擊 Save:

現在你有一個爲你的 hello-world 提取的密鑰了。

部署 Hello World 應用程序 

回到倉庫的上一級目錄,運行下面的命令用來部署 hello-world 應用程序:

$ kubectl apply -f umbrella-apps.yaml  
appproject.argoproj.io/apps created
application.argoproj.io/umbrella-apps created

創建完成後,轉到 ArgoCD UI 你應該會看到兩個新的應用程序 umbrella-apps 和 demo-app 。點擊 demo-app 等待所有資源變成健康的狀態:

變成健康狀態後,你可以通過 https://app.YOUR-DOMAIN 訪問到你的應用程序:

我們也確認了 Vault 密鑰已經注入到我們應用程序的 pods 當中了。ArgoCD UI 中的 demo-app,點擊你應用程序中的其中一個 pod,然後點擊頂端的 Log tab 頁。左側應該會有 2 個容器,所以選擇 test-deployment 容器。在日誌開始,你會看到密鑰顯示在兩行等號中間:

測試 GitOps 

現在讓我們來測試下 ArgoCD 從而確保當我們的倉庫產生一些變更的時候它可以自動同步。

在工具倉庫中,找到 resources/apps/resources/hello-world.yaml 將 replicaCount 從 5 改成 10。將變更推送到 master 分支,然後轉到 ArgoCD UI 的 demo-app 處。當 ArgoCD 到了更新週期,它會自動啓動部署 5 個我們的應用程序副本(如果你不想等的話,可以在 Argo 的 umbrella-apps 應用程序中使用 Refresh 按鈕):

清理 

如果你準備清理集羣了,首先到 AWS 控制檯,EC2 service,點擊 Load Balancers。有一個 Kubernetes 雲提供商創建但沒有被 Terraform 管理的 ELB 需要清理。同樣需要刪除 ELB 使用的 Security Group。

清理完 ELB 之後,運行下面的命令然後在出現提示處輸入 “yes”:

terraform destroy -var-file=example.tfvars

接下來做什麼? 

太棒了!這樣我們就有一整套使用 GitOps 部署應用程序的工具鏈了。下一步要做些什麼呢?如果你準備好迎接新的挑戰了,除了 hello-world 應用程序之外嘗試部署一下自己的應用程序,甚至通過集成 CI/CD 在應用程序配置清單倉庫中更新鏡像 tag。這樣的話,當一個新的應用程序鏡像被構建完成,新的 tag 會自動更新到配置清單倉庫中,ArgoCD 將會自動部署新的版本。

希望你能享受本篇文章並能從中學到一些東西!感謝您的閱讀。

查看文中鏈接,請點擊閱讀原文】


推薦閱讀

Jenkins CLI 命令行 v0.0.26

歡迎使用流水線指令-矩陣

Jenkins 創始人 Kohsuke 的新篇章

自定義 Jenkins 發行版就是這麼簡單

Tekton 流水線發佈首個官方 Beta 版本

Jenkins 中文系列視頻教程

本文分享自微信公衆號 - Jenkins(Jenkins-Community)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章