顯示具有 hosts 標籤的文章。 顯示所有文章
顯示具有 hosts 標籤的文章。 顯示所有文章

2015年11月18日 星期三

Ansible 筆記 - 找尋本機端資源並部署至遠端機器,包含複雜 shell 指令、資源尋找錯誤處理、hosts 之間變數傳遞等

這個需求其實還滿簡單實現的,但為了想要達成更仔細的錯誤偵測,後來越改越複雜 XD 順便筆記一下。完整的使用情境:每次部署遠端機器前,本地端會有一個 package 產出(rpm),透過 find 指令找到最新產出的 package 後,再部署到遠端機器(其實也可以把架設 yum server 來搞定啦 XD)

最簡單的方式,使用 vars 紀錄:

- hosts: YourTargetServers

  vars:
    rpm_dir: "/data/rpm/production/"
    rpm_name_prefix: "packagename*"
    rpm_find_command: "find {{ rpm_dir }} -name '{{ rpm_name_prefix }}' -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d ' ' "
    rpm_path: "{{ lookup('pipe', 'rpm_find_command') }}"

  tasks:
    - name: find rpm prefix name
      debug: msg="{{rpm_name_prefix}}"

    - name: find rpm command
      debug: msg="{{rpm_find_command}}"

    - name: find rpm path
      debug: msg="{{rpm_path}}"


這樣算是收工了,但是 rpm_path 若沒找到時,卻無法有洽當的錯誤偵測 Orz

所以第一次再改成這招:

- hosts: YourTargetServers

  vars:
    rpm_dir: "/data/rpm/production/"
    rpm_name_prefix: "packagename*"
    rpm_find_command: "find {{ rpm_dir }} -name '{{ rpm_name_prefix }}' -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d ' ' "

  tasks:
    - name: find rpm prefix name
      debug: msg="{{rpm_name_prefix}}"

    - name: find rpm command
      debug: msg="{{rpm_find_command}}"

    - name: find rpm path
      local_action: command /bin/bash -c "{{ rpm_find_command }}"
      sudo: False
      failed_when: " '' != rpm_path_result.stderr"

    - name: get rpm path
      debug: msg="{{ rpm_path_result.stdout }}"


但這樣仍有個缺點,那就是若有 roles 等一堆工作,會變成那堆工作做完才會跑 tasks,這時就會希望先偵測本地端的資料在跑 roles 工作,於是乎又改成:

- hosts: loclahost

  vars:
    rpm_dir: "/data/rpm/production/"
    rpm_name_prefix: "packagename*"
    rpm_find_command: "find {{ rpm_dir }} -name '{{ rpm_name_prefix }}' -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d ' ' "

  tasks:
    - name: find rpm prefix name
      debug: msg="{{rpm_name_prefix}}"

    - name: find rpm command
      debug: msg="{{rpm_find_command}}"

    - name: find rpm path
      local_action: command /bin/bash -c "{{ rpm_find_command }}"
      failed_when: " '' != rpm_path_result.stderr"

    - name: get rpm path
      debug: msg="{{ rpm_path_result.stdout }}"

- hosts: YourTargetServers

  vars:
    rpm_path: "{{ hostvars['localhost']['rpm_path_result']['stdout'] }}"

  tasks:
    - name: find rpm path
      debug: msg="{{rpm_path}}"


如此一來,就可以先確保在 localhost 把資源準備齊了,再進行遠端部署動作,也包含偵錯處理啦。

2015年11月17日 星期二

Ansible 筆記 - 動態取得 EC2 機器進行發佈更新 (Dynamic Inventory) @ Ubuntu 14.04

摸了好一陣子,終於搞懂了 :P 簡單的說,採用 Dynamic Inventory 進行動態取得機器列表,此例是透過 EC2 相關工具來取得的。

$ echo `EC2_INI_PATH=ec2.ini AWS_ACCESS_KEY_ID=KEY_ID AWS_SECRET_ACCESS_KEY=ACCESS_KEY python ec2.py --refresh-cache`
{ "_meta": { "hostvars": { "IP" : { ... } } } }


其中 ec2.ini 內容:

[ec2]

#https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini
#regions = all
regions = ap-northeast-1
regions_exclude =

destination_variable = public_dns_name
vpc_destination_variable = ip_address
route53 = False

cache_path = /tmp
cache_max_age = 0

rds = False
elasticache = False

#instance_filters = tag:Ansible=*


整體上,執行 ansible-playbook 方式就改成:

$ ANSIBLE_HOST_KEY_CHECKING=false EC2_INI_PATH=ec2.ini AWS_ACCESS_KEY_ID=KEY_ID AWS_SECRET_ACCESS_KEY=ACCESS_KEY ansible-playbook mysite.yml -i ec2.py --private-key=ansible-deploy.pem

並且在 mysite.yml 中定義的 hosts 也需調整,例如想要透過 EC2 上的 tag 資訊,例如我對 EC2 上的機器標記 Tag 為 Ansible=deploy 機器發佈,這時可以先透過 python ec2.py 觀看想要的 tag 被轉成什麼,接著再去修改 mysite.yml 的 hosts 資訊即可。而 ANSIBLE_HOST_KEY_CHECKING=false 是用在略過 ssh key checking

例如:

$ echo `EC2_INI_PATH=ec2.ini AWS_ACCESS_KEY_ID=KEY_ID AWS_SECRET_ACCESS_KEY=ACCESS_KEY python ec2.py --refresh-cache`
{ "_meta": { "hostvars": { "IP" : { ... } } }, "tag_Ansible_deploy": [ "IP" ] }

$ cat mysite.yml
- hosts: tag_Ansible_deploy
  ...


最後一提,此例使用的 ec2.py 是從官方文件提到的,執行時需安裝 python-boto 環境,此例為了搭配 Jenkins 使用,盡可能把執行 AWS API 所需的資料都透過環境變數傳遞。

2015年10月15日 星期四

使用 Firefox 瀏覽器測試 DNS Round Robin 的方式

關於 DNS round robin 得設置可以把 ttl=0 來方便測試,單純測試 DNS record 有沒有正常顯示,可以單純不斷用 ping 查看 ip address 即可:

$ ping test.domain.name

接著想驗證 server site 有沒有 session 相關的問題,單純用 wget/curl 也可以啦,但如果有一些圖片資料是跟 session 有關的(例如驗證碼,產生的來源資料一樣,但輸出每次都不一樣),這時又頭痛了一下 XD 原先一直想用 Chrome browser,但最後反而跑去用 Firefox! 測試 DNS round robin 是否正常!

首先要驗證 web service 跟 dns round robin 的方式,必須先把 http client 關掉 keep-alive 機制,以 firefox 來說,就是在網址列輸入 about:config 後,搜尋 keep 關鍵字就能找到 network.http.keep-alive.timeout ,把它設成 0 即可,但千萬不要把 network.tcp.keepalive.enabled 設成 false ,那會導致上述的所有設定都無效 XD

接著問題就降低成 DNS round robin 的事了,嗯,沒有最佳解,因為 DNS round robin 本來就沒有每一次 requests 都配置不同的 IP,所以為了提升測試效率,只好自行去寫死 /etc/hosts 等類似的位置了 XD 雖然小蠢,但還是堪用啦。總之,最重要的是要先把 http client 的 keep-alive 關掉才能測試。