Skip to content
Yi's Delivery Service
GitHubLinkedInHomepage

Google Summer of Code 2024

open source16 min read

前言

Google Summer of Code 是一個推廣開源貢獻的項目,由 Google 作為平台媒合 Organization 跟 Contributor。今年是我第一次報名 GSoC,很幸運地通過 Proposal 篩選得到了參加項目的資格。今年從五月底開始正式啟動。

貢獻進行式

Week 1

我的項目在於創建一個 local dev env 以能夠最貼近於 prod env。原先的 configuration management tools 使用的是 Salt Stack,但由於 Salt Stack 不再支援 Creative Commons 所使用的 Debian 12,遂決議改使用 Ansible。

在最一開始的時候,我對於整個 Dev Ops Lifecycle 還沒有很明確的認知。對於我的項目來說,主要是聚焦在 Deploy Stage。在這個 Deploy Stage 裡面又能夠分成 Provisioning 以及 Configuration。而我剛開始的時候並不知道 Creative Commons 目前是直接手動 Provision 的,還以為是要用 Ansible 來 Provision。然而用 Configuration management tools 來 Provision 並不是最好的狀況,可能會有資訊安全上的疑慮,並且最初 Ansible 也並非設計為 Provision 用途,這之中的複雜度會大為增加,故維持手動 Provision 的做法。

這個項目的最終目標是將目前現有的應用都放到分別的 Container 當中,Ansible Server 本身也是一個 Container,並用 SSH 與各個 Container 做溝通。Week 1 的部分,在做完 Docker Container 以及 Ansible 的 Getting Starter,並且參考 Docker Hub Ansible Dockerfile 後,我成功部署了一個 Initial Ansible Container。

Week 2

第二週的代辦事項為把原本的 index-dev(使用 Apache2 運行的網站)拆為 Web-dev 以及 Db-dev Container,以及為第三週的 Bastion Server 做先行的研究。這個部分由於我對於原先的架構(Linux Apache MySQL PHP)不太了解,所以在 configuration 上面把有的東西複製下來貼上。事後我的 Mentor 告訴我,我們應該要從最基本的開始 config,而不是一口氣因為有前任的 Project 參考,就直接把所有東西貼上。按照順序的 Commits 有助於讓開發者了解到思考的邏輯。

另外我們重新討論到了 Provisioning 跟 Configuration 的議題,包含 Dockerfile 跟 Docker-compose.yml 的任務歸屬。Dockerfile 主要用於 provisioning。它定義了如何構建 Docker Image,包括基礎鏡像、安裝的軟件包、複製的文件等。Dockerfile 的理念是 "build it once, use it multiple times"。Docker-compose.yml 更多地關注於 configuration。它定義了如何運行容器,包括容器之間的關係、端口映射、掛載的卷、環境變量等。這些設置往往因部署環境而異,所以 Docker-compose.yml 會更頻繁地變動。

本週我們改變了合作的模式,最後的 Deliverable 由我的 Mentor 產出,添加了產出 ssh key 的 shell script,以及設定 local <-> Ansible 的 ssh access ,我 Review 此次的 PR 並提出疑問。

Week 3

第三週的部分因為 #11 PR 所以我需要原創的部分較少,我這週負責了 local <-> Web-dev, local <-> Db-dev 的 ssh access,以及 ansible <-> Web-dev, Db-dev。 同時這週的 Sync 也因為我白天正職的實習開始了,延期到隔週一。這部分我比較慶幸的是前三週花了很多時間跟 Mentor 溝通、建立默契,所以一週的缺席並沒有影響太多進度。

Week 4 & 5

第四週開始寫 Ansible Playbook,把一些原本放在 web/Dockerfile 的東西移過去 Playbook。將 Dockerfile 和 Ansible Playbook 相結合的做法是一種常見的 Best practice: Dockerfile 負責基礎映像的構建,包括 OS 和基本工具的安裝,Ansible Playbook 則負責應用程式和服務的配置。這個部分比預期中花了一些時間,現在回頭看可能是因為在 Week 3 的時候,由於我沒有實際上開發過,也花太少時間去研究 LAMP(Linux, Apache, MySQL, PHP) Stack,所以不知道到底要怎麼設定各個 Component 的 Configuration,導致我一直無法成功啟用 Service,系統給予的錯誤訊息也引導我去錯誤的方向,原本以為是因為沒有權限從 Anisble Playbook access 到 web-dev Server,但後來發現不是這個問題(可能是因為沒有正確 Config Apache2 though...)。後來回頭去看了一下我的 Mentor 在第三週是怎麼寫每一個 Server 的 Dockerfile,發現 db 其實也需要一個 Startupservice 的 Shell script,這部分因為我 Shell Command 不熟所以之前都是看看就過了,不確定真正細節要怎麼處理,所以也額外花了一些時間補足 Linux Shell Script 的相關知識。

Week 6

前兩週我也提前把 Midterm Evaluation 的 Blog Post 寫好,沒想到拖到 Week 6 都還沒 Post。不過也好險他們把我的文章放到最後修改,讓我有長一點的 Deadline 可以觀摩別人怎麼寫的。本週需要精修的地方是把文章的架構再分得更細一些,然後要加上 GitHub Repo 的 Link 以及 Chart。

順利收到 Google 給的 Stipend,還有我 Mentor 的 Feedback:要對自己更有自信,問問題的時候,要對自己提出的改善方案有數據以及理由支持。

另外回頭接續去做 Bastion Server 的相關設定,我在這裡直接在 Docker Compose 使用了現成的 Bastion Image(https://hub.docker.com/r/binlab/bastion),但是我的 Mentor 卻說他出現了出現平台不一致的問題:! bastion-dev The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested. 並且告知我所有的 Server 都應該使用 debian:bookworm-slim,並且 customized。然而我在後續修改的部分,因為我一直覺得 Bastion Server 應該是要有什麼特殊的定義,所以我就算換成了 customized Dockerfile 我還是試圖的想要安裝 Prebuild Repo(https://github.com/ovh/the-bastion)。

Week 7

這個禮拜 Mentor 應該覺得我聽不懂人話,事後回想起來才發現是怎麼回事:我剛好在公司的 All Hands Meeting 上面聽到這個概念「YAGNI」。意思是「You Aren't Gonna Need It」,這個原則強調應在實際需要功能時才去實現它,而不是預先實現可能未來才會需要的功能。這樣做的目的是避免不必要的複雜性和浪費時間,專注於當前的需求。當然如果我們用現成的 Image 或 Repo 可以把維護的成本交給別的團隊,但我們真的需要這麼多功能嗎?其實沒有。這樣的想法讓我一直在糾結「如果我們只是用一個普通的 SSH Jump Server,可以稱呼他為 Bastion Server 嗎?」其實這是一個假命題,因為 Bastion Server 並沒有一個特殊的定義怎麼樣才可以是 Bastion,雖然 Bastion Server 通常是一個更加專業化和強化安全的 SSH Jump Server。

除此之外,我還收到了 SSH 轉跳不要用 Private Key 的要求,所以我用 SSH Agent。這個作法被退回要求使用 Proxy Jump。

Week 8

本週 Creative Commons 放假,但剛好可以整理我上禮拜的知識盲區:

特性無密碼登錄(Passwordless SSH)SSH Agent代理跳轉(ProxyJump)
描述使用 SSH 公鑰認證無需密碼管理和使用私鑰的工具,允許在多次連接中使用同一私鑰通過跳板機連接到內部網絡中的其他伺服器
優勢提高安全性和便利性提高私鑰安全性和管理便利性集中控制和簡化多跳連接配置
影響每個伺服器需要配置公鑰本地機器需要運行 SSH Agent 並加載私鑰跳板機需要允許 TCP 轉發和代理轉發
安全性更高,由於私鑰保存在內存中高,通過跳板機進行控制和監控
配置難度中等中等,需要在本地配置 SSH Agent中等,需要配置跳板機和目標伺服器
多跳連接支持不支持支持,通過代理轉發實現支持,通過 ProxyJump 配置
使用場景頻繁連接多個伺服器頻繁使用私鑰和多跳連接需要通過跳板機訪問內部伺服器
缺點每個伺服器都需要配置公鑰本地需要運行 SSH Agent需要配置和維護跳板機

結論

  • 無密碼登錄:適合需要提高登錄安全性和便利性的場景,尤其是頻繁連接多個伺服器時。缺點是每個伺服器都需要配置公鑰。
  • SSH Agent:適合需要頻繁使用私鑰和多跳連接的場景,提高了私鑰的安全性和管理便利性。缺點是需要在本地運行 SSH Agent。
  • 代理跳轉:適合需要通過跳板機訪問內部伺服器的場景,提供集中控制和簡化多跳連接的配置。缺點是需要配置和維護跳板機。

還有另外研究了要怎麼讓容器重新啟動之後,保留在 Server 做的 Change:用 Volume。

Week 9

終於把 Bastion Container 的 Pull Request Merge 了。還有研究了要怎麼在本地上面 Access 到跳板主機。 這禮拜研究 How can ansible be used to configure docker? How does this differ from ansible configuring hosts? How to minimize the configuration in Dockerfile and include in Ansible

選項 1:使用 Ansible Host 或 Docker Compose with All Services

  • 概念: 所有服務(bastion, ansible, web, db)都運行在同一個 Docker 網絡中。Ansible 直接通過 Docker 網絡使用容器名稱或 IP 來管理 web 和 db。Bastion 服務器被包括在內,但僅在需要時用作跳板機。這種方法將每個容器視為一個獨立的主機,並在這些主機上安裝和配置所需的軟體。
  • Docker Compose 配置: 所有服務(bastion, ansible, web, db)都在 Docker Compose 文件中定義並啟動。
  • Ansible 配置: Ansible 直接管理和配置 web 和 db 容器。

選項 2:使用 community.docker.docker_container_exec

  • 概念: 使用 community.docker.docker_container_exec 是指利用這個 Ansible 模組來在 Docker 容器內部執行命令。這種方法通過 Ansible Playbook 使用 docker_container_exec 模組來在容器內部執行命令,完成安裝和配置應用程序的任務。
  • Docker Compose 配置: 所有服務(bastion, ansible, web, db)都在 Docker Compose 文件中定義並啟動。
  • Ansible 配置: Ansible 使用 community.docker.docker_container_exec 模組來在容器內部執行命令,安裝和配置應用程序。

選項 3:Docker Compose with Bastion & Ansible Only; Ansible Configures External Web & DB

  • 概念: 只有 bastion 和 ansible 在 Docker 中運行,而 web 和 db 是外部服務或容器。Ansible 通過 Bastion 服務器連接到 web 和 db,將它們視為外部資源。
  • Docker Compose 配置: 只有 bastion 和 ansible 在 Docker Compose 文件中定義並啟動。web 和 db 是外部服務或容器。
  • Ansible 配置: Ansible 通過 Bastion 服務器管理和配置外部的 web 和 db 服務。

比較三個選項

管理層級:

  • 選項 1:在應用層級管理容器內的應用程序,所有服務都在同一個 Docker 網絡中運行。
  • 選項 2:在 Docker 層級管理容器,並在容器內部執行命令。
  • 選項 3:只有 bastion 和 ansible 在 Docker 中運行,web 和 db 是外部服務。

靈活性和可移植性:

  • 選項 1:適用於需要對容器內部應用程序進行細粒度控制的情況,簡化了在單一環境中的設置。
  • 選項 2:更靈活且易於移植,適合快速部署和管理應用程序。
  • 選項 3:更安全,模擬生產環境,服務之間有更好的隔離。

隔離性:

  • 選項 1:直接在容器內部執行任務,所有變更都影響容器內部的系統,缺乏隔離,可能導致安全問題。
  • 選項 2:提供應用程序級別的隔離,每個容器都有自己的文件系統、網絡和進程空間。
  • 選項 3:服務之間有更好的隔離,模擬生產環境。

資源管理:

  • 選項 1:資源管理依賴於容器內部的資源配置和管理,簡化了資源管理,但可能不反映真實的生產環境。
  • 選項 2:容器可以動態分配資源,並且可以輕鬆地啟動和停止。
  • 選項 3:更複雜的設置,但提供更好的資源隔離和管理。

我們決定選擇選項一,通過將大部分配置從 Dockerfile 中移到 Ansible Playbook 中,可以保持 Dockerfile 的簡潔,並利用 Ansible 的靈活性來管理和配置應用程序。這樣做不僅簡化了 Dockerfile,還使得配置管理更加靈活和可維護。

Week 10

TBD...

© 2024 by Yi's Delivery Service. All rights reserved.
Theme by LekoArts