粗略配置作法:
- Git
- 主要特色還是 branch 的規劃,跟公司文化有關
- master:正式網站的狀態
- alpha:內部最新網站狀態
- develop:最新程式碼
- 開發者都是從 develop branch 開發服務,當有版本要釋出時,merge 進 alpha branch 後,發佈到 alpha site 測試,妥當後再把 alpha branch merge 進 master branch
- 概念上有點從 develop -> alpha -> master 角度
- 若有 hotfix 時,從 master 產生 branch 修正後,在 merge 回 alpha 跟 develop
- 在 alpha site 測試出問題時,不斷地在 alpha branch 處理,到最後才 merge 回 develop branch,以及發佈到 master branch
- 透過 Jenkins 每一次發版時,會下 git tag 標記狀態
- develop-version-number
- alpha-version-number
- production-version-number
- 相關資料:A successful Git branching model
- Jenkins
- 新增 Slack Notification Plugin/Version Number Plug-In
- 權限設定,為了不要暴露太多專案給開發者,做了簡易的權限管控
- 設定全域安全性
- 安全性領域:採用 Jenkins 內建使用者資料庫 且不允許註冊
- 授權:採用專案型矩陣授權策略
- 每一個 task 都可以自訂可以觀看的使用者
- 管理方面,新增工作分成 build 跟 deploy 兩種
- build 就是把 source code 包成 RPM ,方便作業系統管理和除錯追蹤,另外,對於開發者測試機的準備也有幫助
- 取得最新程式碼後,透過 RPMBuild 包裝起來,擺至指定位置
- 每一次 build 都會下 git tag 標記版本狀態,方便之後除錯
- 若封裝過程可以接觸到 git 資訊,則把 source code 最後 3 筆 commit log 拉出來製作版本資訊
- git log -3 --pretty=format:"{\"commit\":\"%H\",\"update\":\"%ad\",\"author\":\"%an\"}"
- deploy 就是透過 ansible 進行發佈,因此也可以把 ansible 操作用 git 管理
- 發布過程中,第一步先到指定位置找出最新的 RPM files
- 第二部透過 AWS EC2 API 得知待更新機器列表
- 透過 ssh remote command 進行機器更新
- 盡量把所有動作濃縮至 Ansible command,而透過 Jenkins Web UI 撰寫幾個指令就好
- 工作通知
- 每一次 build 或 deploy 都可以透過 slack plugin 將更新訊息發佈至指定頻道通知相關開發者
- 採用輪詢 SCM 方式,由 Jenkins 主動確認程式碼狀態,以此決定是否出 build ,不採用 git hook 等被動方式進行工作任務
- 無法規範開發者 git push 行為,擔心 push 太多造成大量 build event
- build 完畢後,可以設立相關專案,自動進行 deploy 任務
- AWS
- 透過 AIM 建立一個只有 AmazonEC2ReadOnlyAccess 權限的帳號
- 對於需被管理的機器,都透過 Tag 標記管理
- 使用 AWS EC2 API 來動態查詢指定的機器,以此取得機器列表,例如指定 ELB 裡所有的機器
- 關於 Auto Scaling
- 由於機器 IP 非固定,在不同 data center 溝通容易踩到 Security Group 限制,建議還是把服務以 data center 切開
- 例如有美西跟日本時,若 db server 開在美西,那需要存取此 db server 的機器就擺在美西就好,這樣 Security Group 比較好做(類似限制 LAN 即可)
- Ansible
- 將 RPM 複製到機器上安裝,在 Ubuntu server 可偷懶用 alien :P
- 依照腳本,進行機器的環境配置,如 limits、web server 等
- 埋入一個 boot script ,當開機時透過 ssh remote command 向 deploy server 要求更新自己
- RPM 打包目錄專用
- https://github.com/changyy/rpm-builder
- 若打包目錄有 .git 時,會抓出最後幾筆 commit log 塞進 version.json 檔案內,可協助往後的偵錯
- 由於 RPMBuild 很吃環境變數,面對 Jenkins 同時出 build 會衝到共用資源的部分,在此已經透過修改 $HOME 目錄來避開共用資源的問題,因此不用再擔心 Jenkins 一次只能出一個 build
- AWS EC2 機器查詢
- http://docs.ansible.com/ansible/intro_dynamic_inventory.html#example-aws-ec2-external-inventory-script
- Jenkins 建置範例(script),只要修改 yml 檔案名稱即可:
- develop site
- export ANSIBLE_HOST_KEY_CHECKING=False
export EC2_INI_PATH=$WORKSPACE/dynamic-inventory-ec2.ini
export AWS_ACCESS_KEY_ID=XXX
export AWS_SECRET_ACCESS_KEY=OOO
export DEPLOY_TARGET=site-develop.yml
ansible-playbook $WORKSPACE/$DEPLOY_TARGET -i $WORKSPACE/bin/ec2.py --private-key=$HOME/.ssh/ansible-deploy.pem - alpha site
- export ANSIBLE_HOST_KEY_CHECKING=False
export EC2_INI_PATH=$WORKSPACE/dynamic-inventory-ec2.ini
export AWS_ACCESS_KEY_ID=XXX
export AWS_SECRET_ACCESS_KEY=OOO
export DEPLOY_TARGET=site-alpha.yml
ansible-playbook $WORKSPACE/$DEPLOY_TARGET -i $WORKSPACE/bin/ec2.py --private-key=$HOME/.ssh/ansible-deploy.pem - production site
- export ANSIBLE_HOST_KEY_CHECKING=False
export EC2_INI_PATH=$WORKSPACE/dynamic-inventory-ec2.ini
export AWS_ACCESS_KEY_ID=XXX
export AWS_SECRET_ACCESS_KEY=OOO
export DEPLOY_TARGET=site-production.yml
ansible-playbook $WORKSPACE/$DEPLOY_TARGET -i $WORKSPACE/bin/ec2.py --private-key=$HOME/.ssh/ansible-deploy.pem - Ansible 找尋最新 package files
- $ ansible-galaxy install changyy.find-package
- https://github.com/changyy/ansible-role-find-package
- Ansible 設置自動要求更新
- $ ansible-galaxy install changyy.self-update
- https://github.com/changyy/ansible-role-self-update
- 比較雜亂一點,原理:
- 機器部署時,建立一個 auto update script (負責通報 deploy server 更新指定 host),將此 script 埋入開機執行區( /etc/rc.local )
- 當機器啟動時執行該 script ,把部署此機器該有的資訊以 ssh remote command 丟給 deploy server
- 該 ssh remote command 包含的動作
- 登入 deploy server 並切換至 ansible workspace
- 透過 dynamic inventory 建立動態 host 資訊
- 執行 ansble-playbook 批次指令
- Deploy server workspace 範例:
- $ cat bin/echo.sh
#!/bin/bash
echo "{\"$HOST\":$DATA}"
$ HOST=MySite DATA=[\"SERVER_IP\"] bash bin/echo.sh
{"MySite":["SERVER_IP"]}
$ cd ansible-deploy-dir && \
ANSIBLE_HOST_KEY_CHECKING=false \
HOST=MySite \
DATA=[\"SERVER_IP\"] \
ansible-playbook MySite.yml \
-i bin/echo.sh \
--private-key=mysite-login-key.pem
沒有留言:
張貼留言