Monthly Archives: July 2015

真假 DevOps

今天談到一個話題:「不熟 OP 的 developer 如果缺少 OP 相關知識,那怎麼做好 DevOps?」

我覺得這是個假議題。

今天就是因為 developer 都認為 OP 會負責 deploy 到好、負責出來坦,所以開發時毫不考慮 OP 負荷,logs 也不看不管,這才是真正導致 DevOps 做不起來的原因,也就是我一直批評的「假 DevOps 之名,行傳統 OP 之實」。

而 developer 真的需要很強的 OP/sysadmin 知識嗎?不用,真的不用,developer 缺的是很強的 DRY 意識。

如果能時時設想「我做的這個東西,能不能在 10 分鐘內整套自動 setup run 起來?」那 developer 自然會去想「程式能不能通過測試?」、「設定、部署能不能簡單輕鬆?」這才是以 developer 這一側要實行 DevOps 該有的思維。

我親愛的網站案件客戶,您好

我自大學開始學習如何製作「帶有語意的網頁」、「樣式與本體分開處理的網頁」,早在 SEO(搜尋引擎最佳化)這個詞出現之前,便已瞭解「一個讓搜尋引擎覺得『好』的網頁,其結構應該是如何如何」的眉眉角角。

從碩士班開始,又學到 IA(資訊架構學),深知內容如何妥善編排,導覽動線該如何設計。

製作「帶有語意的網頁」、「樣式與本體分開處理的網頁」是讓機器(搜尋引擎、瀏覽器)高興。

妥善編排內容,設計良好的導覽動線,則是讓高興。

能夠兼顧「機器」與「人」的 Web 設計師在這市場上真的不多,許多從業者照本宣科跟著「專家」做 SEO,還不如我們這類圖資系出身的、一直被以為只能在圖書館櫃台處理借還書的人,動手調整一下網站架構,結果立即大不同。

您的網站,因為我的勸阻,沒花錢去買當初您不知聽了哪位「專家」說的關鍵字廣告,但是在搜尋引擎排名還是名列前茅,實不相瞞,就是我提供給您如上述的專業服務,正如貴寶號也提供專業服務給客戶那般。

您在意「效果」、「設計」、「美學」,是的,這些的確很重要,但並非一個網站的全部。當我向您表達我擅長的 Semantic Web, Information Architecture 如何幫助貴寶號的時候,希望請您不要認為那些不重要,而不當一回事,執意要做您認為「視覺效果好才是硬道理、壓倒一切」的網站,因為若忽略這些要素,您的網站只能吸睛,但不會好用,搜尋引擎也不愛來爬資料。

無論之後我們還是不是可以繼續合作,我衷心感謝您看完我這篇苦口婆心、肺腑之言,謝謝!

架設 Docker Registry v2

我的架設方式與官方文件不太一樣,所以踩了不少雷。

官方文件傾向把 nginx 與 docker-registry 都用 Docker container 的方式連接 (link) 部署,而我的方式與層次是:

  1. AWS ELB
  2. Nginx on EC2 Host OS
  3. Dockerized  docker-registry (registry:2)

因為我想要閃掉 SSL/TLS 的設定,還有惱人的 private key passphrase,所以讓現成已經掛好了憑證的 ELB 充當 SSL/TLS termination proxy。在 ELB 後面的 nginx 與 docker-registry 就不用煩惱憑證的設定問題。

Nginx 主要是負責提供 HTTP basic access authentication,在 docker-registry 前提供一層帳密安全關卡,由於我個人實在是很討厭使用 link,所以把它放在 host 裡。設定檔大致如下:

server {
  listen 8080;
  server_name docker.registry.in.my.com;
  client_max_body_size 0;
  chunked_transfer_encoding on;

  access_log    /var/log/nginx/docker-registry-access.log;
  error_log     /var/log/nginx/docker-registry-error.log;

  location / {
    # Do not allow connections from docker 1.5 and earlier
    # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
    if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*\$" ) {
      return 404;
    }

    # To add basic authentication to v2 use auth_basic setting plus add_header
    auth_basic "registry.localhost";
    auth_basic_user_file /etc/nginx/conf.d/registry.password;
    add_header Docker-Distribution-Api-Version  registry/2.0    always;

    proxy_pass                          http://127.0.0.1:5000;
    proxy_set_header  Host              $http_host;
    proxy_set_header  X-Real-IP         $remote_addr;
    proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto https;
    proxy_set_header  X-Original-URI    $request_uri;
    proxy_set_header  Docker-Distribution-Api-Version   registry/2.0;
    proxy_read_timeout                  900;
  }
}

過程中我遇到的幾個大地雷有:

  • Ubuntu 14.04 內的 nginx 版本太舊,不支援 add_header 的 always 指令,導致不會送出該識別 header,所以 docker login 會判斷這個 docker-registry 為 Invalid registry endpoint,解決方法就是要從 nginx 官網裝新版(至少 1.7.5 以上,這顆地雷是從 [Running Secured Docker Registry 2.0 – Container Solutions] 這篇看到提示才解掉的)。
  • 由於 nginx <-> docker-registry 之間通訊是走 http://,所以在 push image 的時候,一開始從 remote 下 PUT 指令還是 https://,但是接著 docker-registry 會根據 X-Forwarded-Proto 的值送出 Location: http://xxx HTTP header 請 client 轉址,導致接下來的 PUT 操作失敗,解決方法就是要把 X-Forwarded-Proto 強制指定為 https

幾個經驗:

  • 善用 curl -v 給的資訊來判斷,不要瞎猜。
  • V2 目前還是很多坑,使得你不得不去看 source code,但是還好小的我還學過一點 Go