LY Corporation Tech Blog

支持 LY Corporation 和 LY Corporation Group (LINE Plus, LINE Taiwan and LINE Vietnam) 服務,宣傳技術和開發文化。

淺談開發與DevOps @ APCS Camp 企業參訪

前言

我是 Engineering部門的SRE - Eric Huang,相信來參加這次參訪的同學都相當會寫程式,如果寫的程式需要給別人使用時,這些程式應該要如何被部署呢?又或者有多位的開發者同時開發同一個專案,我們又如何確保開發的環境是一樣的,不會有潛在的問題產生?這次的分享內容著重在開發的環境一致性以及程式如何自動化的被部署,減少前述的問題。

當天簡報:https://speakerdeck.com/line_developers_tw/introduce-development-and-devops

介紹

開發經驗問題

想問在座的同學三個問題:

  • 有開發過給別人使用的程式的經驗嗎?
  • 這些程式是怎麼被部署的?
  • 有沒有團隊開發經驗?

不知道同學針對這些問題心中的答案是什麼?其實不管現在有沒有相關的經驗,之後在工作上也一定會遇到,只可惜這些經驗在學校不一定可以累積,我也趁這個機會分享我過去以及目前在LINE的經驗給各位。

自身經驗分享

我曾在交大系計中擔任過TA,曾開發過給系上使用的網頁,在當時體悟到DevOps的重要性,也確切明白Docker對開發者來說有著巨幅的幫助:之前也在GitHub上有針對一些程式發issue以及PR,了解到community-driven的程式應該要怎麼在遵守社群規範下開發,如何跟其他人合作,以及CI/CD要如何設計等等。

出社會之後先在台積電短時間任職,之後到玉山銀行服務,當時主要做監控以及k8s管理,與現在的工作內容類似。目前在LINE要服務的團隊更多,問題也更為複雜與困難,更加有挑戰性。

開發 & DevOps

開發

寫程式時最怕遇到程式在我的電腦可以跑,但是在其他的電腦卻跑不起來。又或者在我的電腦上可以順利跑,但等到部署後在線上環境卻出現問題。我們應該要如何避免這問題呢?

得開玩笑的說,每個人都配Mac開發就不會有這困擾,但是每台電腦上的library, CLI以及程式語言版本都不盡相同,還是非常有可能會遇到環境上的問題。其實我們日常使用的服務大部分都是部署到Linux上,不如一開始就在Linux上開發呢?

我們可以選擇直接在裝有Ubuntu等Linux distribution上開發的OS上開發,也可以開一台Ubuntu的VM。但VM會大量消耗電腦資源,而且有些人可能不會把自己電腦灌成Ubuntu專作為開發使用。

取而代之的是,我們有新的選擇,那就是使用container。

container可以視為一種輕量級的APP,主流的container runtime (管控container的程式)都已支援各家OS。底層的實現是使用Linux kernel的技術,包含namespace以及cgroup,分別達成環境隔離以及資源限制的功能。也因為這些特性,container被大量在開發以及部署上被使用,是cloud native的基礎。

靜態的container稱作image,image內容可以藉由Dockerfile定義。在上面範例中,我們要去打包一個python的app,在base image中(FROM python),我們使用了python的image,裡面包含了運行python程式所需要的library及interpreter本身。

基於這個base image,我們在上面將我們需要的python package透過pip裝起來,最後將我們的程式複製進image內,最後跑起來。詳細的Dockerfile syntax可以參考Docker官網。

上面的Dockerfile一旦打包完成,就可以透過docker跑起來,image在開始執行時稱作container,此時的container就是一個獨立的python app,理想上可以在各個環境上跑起來。

然而,container只能解決app內部環境的問題,也就是程式語言版本,package版本,CLI以及環境變數等。但是如果container內部程式需要透過網路溝通,例如將資料存放在DB又或者呼叫別的API,container並不能保證可以正常運作。

原因是container上的網路封包終究要從container runtime上的本機發轉發去,如果這些機器的網路routing設定,或者DNS name server不一樣,就有可能會遇到問題。我就曾經遇過container在某一台可以正常git clone,但是另一台卻會失敗。檢查之後發現這兩台的DNS name server不一樣,導致失敗的那台不能正確解析git server的IP造成失敗。

DevOps

我們寫好程式之後會需要將我們的程式編譯,測試並打包,最後部署到線上環境。身為一位超級懶的工程師,我們會希望這些流程都能被自動化,盡可能減少手動操作。除了自動化之外,我們還可以保證這些流程都是穩定並可靠的,讓我們在部署上更添信心。

DevOps有兩個需要關心的議題,也就是CI與CD。CI全名是Continuous Integration,主要是程式部署之前需要做的各種檢查以及自定義流程。例如單元測試,整合測試,程式靜態掃描等。CD全名是Continuous Delivery,主要定義程式該如何被部署,除了使用Ansible協助部署之外,現在主流的GitOps例如ArgoCD也非常熱門。

CI/CD流程現在流行用pipeline定義,主流的git service provider例如GitHub以及Gitlab都有提供這些工具給開發者使用,通常都用YAML定義這些流程,可以幫忙做到lint, test, build或deploy等工作。

上面提供一個GitHub Actions的範例,主要目的是要打包一個docker image,並推送到名為harbor的image registry上(image registry用來存放image,就如同github存放程式一樣)。

一開始先將程式checkout下來,可以想像就是git clone一個repo,在使用帳密登入harbor之後,就可以在透過docker官方提供的action上build以及push image,完成image的打包。

上面僅是一個簡單的範例,事實上根據不同的情境,可以非常複雜,例如如果有程式支援Mac, Linux及Windows OS,就需要在這些OS上進行程式編譯並測試,最後打包成artifact,這些需求同樣可以使用YAML表示,但會稍微繁複一點。GitHub Actions細節的syntax同樣可以參考官方文件。

結論

開發者花費大量的時間進行程式的開發及測試,但是這些程式在提供給顧客使用之前,需要進行一連串的流程,我們希望這些流程都是自動化並可靠的,也會希望開發以及部署環境盡可能一致,減少後續維運的困難。

今天提到的container及pipeline平時可能不會在學校中學到,但是在工作上是被大量運用的工具及系統,都能協助解決我們遇到的種種問題。雖然說以後在職場上可能會有專職的DevOps Engineer負責處理,但是了解整體流程對開發者來說並不是件壞事,有時間的話可以多多研究,必能幫助自己。