我如何將部落格遷移到 Kubernetes(上)

Wi1dcard發表於2019-09-12

最近 Kubernetes 的發展,以及在我司的大量應用,自己也迫不及待想要嚐嚐鮮,雖然我的部落格是基於 Hexo 的純靜態站點,但這並不能阻擋我把它遷移上 Kubernetes!畢竟... 相比於 GitHub Pages 靈活性更好可控性更高,emmmm... 好了我編不下去了,總之,生命在於折騰?,我們開始吧。

本文涉及的程式碼(也就是我的部落格)完全開源:https://github.com/wi1dcard/blog

構建 Docker 映象

要上 Kubernetes,首先要做的就是給專案打包映象。Dockerfile 非常簡單:

# 採用 nginx:stable-alpine 作為基礎映象
FROM nginx:stable-alpine
# 複製 ./public 到映象內 /usr/share/nginx/html
COPY ./public /usr/share/nginx/html
# 提示暴露 TCP 協議 80 埠
EXPOSE 80/tcp

我選用 Docker Hub 作為 Docker Registry,如果你有私有專案、許可權控制等相關需求,Quay.io 或許是更好的選擇。

CI 構建

當然啦,構建這種事情肯定是交給 CI。不推薦每次變更手動 Build,費時費力易出錯。

目前我給部落格用的是 Travis CI。我也考慮過:

  • Circle CI,試用後感覺配置檔案(以我個人的風格來看)有點反直覺,放棄。
  • GitLab CI,目前我認為最好的 CI/CD,我具備 CI/CD 需求的私人專案都在 GitLab。但是考慮到 (1) 要將部落格程式碼開源,(2) GitLab CI for GitHub repos 需要付費,(3) 兩套 VCS 感覺怪怪的,因此放棄。
  • GitHub Actions,正在 Beta 中,打敗各路 CI/CD 的種子選手之一。只可惜文件還不夠齊全,穩定欠佳,只好暫時放棄。
  • Docker Hub,若是隻用來構建公開映象感覺還不錯,但 (1) CI 和 Docker Registry 強繫結,想要換 Registry(比如上文中提到的 Quay.io)會很繁瑣,(2) 構建速度巨慢... 慢... 慢... 大概是使用者太多吧,情有可原,(3) 映象打包完成後需要使用 Helm 部署(即 CD)到叢集,明顯不適合該場景。

你可以在 這裡 找到我的 Travis 配置。其中定義了三個環境變數:

env:
  global:
    - DOCKER_USERNAME=wi1dcard # 我的 Docker Hub 使用者名稱
    - DOCKER_IMAGE=$DOCKER_USERNAME/blog # Docker 映象名
    - DOCKER_TAG=build-$TRAVIS_BUILD_NUMBER # Docker 映象 Tag

這些變數會在之後用到。

注意 $DOCKER_TAG,它的值是動態的,即每次構建都會變化,由 Travis CI 的 預定義環境變數 拼接而成。

before_script 內,定義了構建過程的指令碼:

before_script:
  - build/build.sh

由於構建、釋出過程比較複雜,同時為了未來(可能)遷移到 GitLab CI,我沒有將所有指令碼羅列在 .travis.yml 裡,像 alipay-sdk-php 等開源專案那樣。

所有與 CI 相關的內容我都放在了 build/ 目錄。

build/build.sh 的主要任務是:

  • 安裝依賴,例如 Hexo。
  • 執行 lint 過程,檢查 Markdown 語法等。
  • 渲染靜態站點,生成 PDF 格式簡歷。
  • 構建 Docker 映象。

釋出 Docker 映象

與 CD 相關的內容我放在了 deploy/ 目錄。正如 .travis.yml 定義的那樣,部署指令碼位於 deploy/deploy.sh

script:
  - deploy/deploy.sh

首先,登入 Docker Hub,接著推送映象:

echo "Logging in Docker Hub..."
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin

echo "Pushing images to Docker Hub..."
docker push "$DOCKER_IMAGE"

注意,這裡用到了之前定義的環境變數。其中,$DOCKER_PASSWORD 我定義在 Travis CI 的私有環境變數內:

我如何將部落格遷移到 Kubernetes(上)

還有兩個環境變數 INGRESS_HOSTKUBECONFIG_BASE64 稍後會用到。

關於 Immutable

你可以在 這裡 檢視推送的映象和 Tags。

還記得 $DOCKER_TAG 的值是動態的嗎,所以每次 CI 構建產生的映象都會有唯一的 Tag 與它的 Build ID 對應。

這對我來說好處顯而易見:

  1. Immutable。每次構建的映象就像 Git Commit 一樣留下不可變更的印記。
  2. 清晰明瞭,不易混淆。你無法快速得知當前 lastet 具體是哪一次構建的產物。
  3. 便於回滾。雖然你可以重新構建映象,但如果你將每次構建的映象保留,那麼就可以快速地、完美地回滾到任意版本(尤其能夠防止同一 Git Commit 多次 Build 產生不同的 Image)。
  4. ...

其實,做了一年運維之後我發現,有時候混淆比「我不知道」更可怕。一些隱性的宣告可能會導致你在某個極小的問題上,毫無意義地浪費一整天時間。因此如果某些時候「簡潔優雅」和「清晰明瞭」產生衝突的時候,我會毫不猶豫選擇 清晰明瞭 地顯式宣告,儘管現在看起來可能有點醜,但未來除錯的時候可能會幫上大忙。

(未完待續)

我感謝自己平凡,敢愛敢恨沒負擔。
我感謝自己不凡,可愛可恨都包攬。

相關文章