作者: Hui-Hong YOU

  • NHK World Premium 從台灣大寬頻類比頻道中消失

    今天凌晨,位在 CH95 的 NHK World Premium 突然斷訊,有幾秒的時間被調到 CH94,旋又消失,接著 CH95 換載 MTV 綜合台。

    求證有裝數位有線電視機上盒的岳家,NHK World Premium 還在數位頻道裡。

    親眼見證這段歷程,很有感觸,我在當下還抱著希望,以為像之前一樣只是被賣藥台排擠而換了頻道。重新掃描頻道掃了兩、三次,再按著遙控器一台接一台尋找,覺得這很像是國中時新買的自行車失竊,我茫然地在附近兜圈那樣。

    我知道類比頻道頻率範圍有限、數位頻道(理論上)無限的道理,但是今天台灣大寬頻可以這樣獨斷決定一個類比頻道的去留,我相信同樣的事情,很有可能也會在數位頻道裡發生。

    於是我(終於)決定去裝衛星碟。

  • 真假 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
  • OpsWorks + Docker 管理架構

    今(昨?)天在公司跟同仁分享的經驗,簡單筆記一下:

    • Elastic Beanstalk 自訂的彈性與便利性,都比不上 OpsWorks。
    • 公司在 Web 的主要使用語言是 Ruby:
      • OpsWorks = AWS + Chef
      • Chef 是用 Ruby 來管理 infrastructure
      • 所以相對來說,入門門檻相對較低
      • 理想上,應該可以跟 Vagrant 用同一套 Chef Cookbook(s),達成跨方案快速部署開發與營運環境
    • OpsWorks 每個 Stack 內只允許有一個 Rails App layer
      • 如果覺得在 custom layer 照抄 AWS 的 Rails App layer 套用的 recipes,就可以解決這個限制,你就會踩雷踩到想哭。
      • 如果為了要使用內建的 Rails App layer 而拆分到不同 stacks,又顯得太蠢,且無法佔到「放在同一個 stack 時可共用很多管理資料」的便宜。
    • 目前(我)已知最好的方法,就是架 Docker
      • 利用 Docker 的隔間特性,以 KTV 包廂為例,理想上 (container) A 房間開趴,不會影響到 (container) B 房間,更不會影響到大廳 (host)。
      • 所以我們甚至可以一台 EC2 instance 裡部署 A 應用,如果資源有餘裕,就可以堆 B 應用、C 應用、D 應用…而不互相打架,且不會被 OpsWorks 一堆未知的地雷炸到。
      • 實務上我會這樣堆疊:debian:stable → rvm-ruby-base → rails-base → app-base → app。
      • rvm-ruby-base 就是先在裡頭裝好 RVM 以及 Ruby。
      • rails-base 是預先裝 Rails 會用到的 Debian packages 如 NodeJS (XD)
      • app-base 預先 git clone 把 application 的 code 拉下來,先跑 bundle install,這樣預先裝好一堆落落長的 gems 後,往後疊 app 上去就不用把時間耗在重新安裝。
      • app 則是做 git pull,把異動拉下來後認 branch/tag 部署。這個放在 deploy 類的 recipes 底下,上面那些則是擺在 setup 類底下。
    • 好處:
      • 我們基於 Rails 的產品很多,用 AWS 也用很大,所以每個產品理想上都可以用同一套 cookbook(s) 做部署基礎,只需在 deploy 這邊自訂個別需求就好。
      • 就算不用 Rails,還是可以在 rvm-ruby-base 上疊其他的 Ruby 應用。
      • 好,就算不用 Ruby,你還是可以在 debian:stable 上堆其他應用。
      • 因為用了 OpsWorks & Chef,我們可以用 template 動態產生 Dockerfile 以及設定檔,可以當成「超彈性隨你玩加強版 ECS (EC2 Container Service)」來用。
    • 先決條件:
      • 規劃良好的 VPC subnets, security groups
      • 看 AWS 官方的 cookbooks 怎麼寫,模仿,並瞭解 node 物件有哪些東西可以方便我們部署
      • 考量日後發展,彈性劃分 Docker 堆疊
  • 編譯 B2G (Firefox OS)

    其實之前幫 ZTE Open (inari) 編過,這次是重新拉過一次 source code 下來,然後先試著編譯 emulator 確認基本可動。

    我是把 source code 放在外接硬碟上 (/run/media/yhh/500G/),因為筆電內的 SSD 已經沒有太多可用空間。

    先拉 source code:

    cd /run/media/yhh/500G/
    sudo git clone git://github.com/mozilla-b2g/B2G.git
    sudo chown -R yhh:users B2G
    

    然後先去編一個編譯過程中需要的 make 3.82:

    sudo tar xvfj make-3.82.tar.bz2
    cd make-3.82
    ./configure --prefix=/run/media/yhh/500G/
    make && sudo make install
    export PATH=/run/media/yhh/500G/bin:$PATH

    接著切換 JDK 版本至 openjdk-7:

    sudo archlinux-java set java-7-openjdk

    開始設定與建置:

    cd /run/media/yhh/500G/B2G
    BRANCH=v2.2 ./config.sh emulator
    ./build.sh -j1

    編譯過程只開一個 job,是因為之前發現若跑多個 jobs 會有前後相依衝突的問題,造成編譯失敗。

    snapshot74 snapshot72

    編出來的 emulator,實際跑起來發現在捲動畫面時,繪圖會不定時黑掉或破圖,不過沒關係,如一開始講的,我只是要確認這份 source code 編出來的東西基本可動而已。回台北後要再實際編一套 2.2 給 ZTE Open 用。