1. 程式人生 > >Docker嚐鮮之Airflow快速安裝

Docker嚐鮮之Airflow快速安裝

個人初步理解使用Docker應該儘量滿足資料和應用隔離,資料儘量有mount在宿主機上;另外,與虛擬機器相比,容器有一個很大的差異,它們被設計用來執行單程序,無法很好地模擬一個完整的環境,所以不建議一個容器塞太多的應用——容器的啟動是非常廉價的。Docker設計者極力推崇“一個容器一個程序的方式”,所以遵循這樣的應用原則就沒錯了。另外,docker exec是支援使用者操作類似ssh這樣的操作的,可以進入到docker內部,但是同樣不推薦,這樣的場景儘量限制在測試就好。

Docker安裝

vim /etc/yum.repos.d/docker.repo
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7
/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg

然後安裝

yum install -y docker-engine

注意,安裝完畢後,需要啟動docker服務,systemctl start docker.service(就是那艘藍鯨大船),而後續執行的docker命令啟動的只是docker container(容器,即集裝箱)。好的,這個設計很棒是不是,有點類似Java JVM和Java應用的關係,只要有JVM在,就可以忽略底層作業系統;docker同樣滿足這樣的能力。

啟動Airflow

git clone https://github.com/puckel/docker-airflow.git

下載後可以看到相應目錄下有docker-airflow檔案,進入該資料夾,根據githup說明,執行docker run -d -p 8082:8080 puckel/docker-airflow,該命令會先檢視本地是否已經下載了相關的應用檔案,如果沒有,則需要從遠端倉庫下載,該遠端倉庫是國外網站,下載就需要碰運氣了。。。
等待了漫長的下載,看到如下結果
這裡寫圖片描述
就已經完成docker容器的啟動,非常快,秒級就啟動完畢。提醒下,很奇怪的一點是這種模式只啟動了Airflow的web-server,並沒有啟動scheduler,需要進入docker:docker exec -it [name] bash

關閉和啟動容器

[root@cdh docker-airflow]# docker ps  ##檢視docker程序
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS                                        NAMES
51051eb885d6        puckel/docker-airflow   "./entrypoint.sh"   38 minutes ago      Up 38 minutes       5555/tcp, 8793/tcp, 0.0.0.0:8082->8080/tcp   furious_wright
#其中,furious_wright是該docker容器的可讀名稱
docker stop furious_wright #停止容器
#注意,stop只是停止了容器,並沒有刪除容器
docker rm furious_wright #這才算移除容器

掛載目錄——實現應用和資料分離

資料卷讓你可以不受容器生命週期影響進行資料持久化。它們表現為容器內的空間,但實際儲存在容器之外,從而允許你在不影響資料的情況下銷燬、重建、修改、丟棄容器。Docker允許你定義應用部分和資料部分,並提供工具讓你可以將它們分開。使用Docker時必須做出的最大思維變化之一就是:容器應該是短暫和一次性的。 ——摘自《Docker入門實戰》

使用的時候發現要建立Airflow DAG需要進入到docker內部建立,這個很麻煩,因為一般為了節約docker使用資源,不會安裝太多不必要的工具,比如vi/vim等,所以在docker container內部編輯文字是非常麻煩的事情,要不就得安裝,這就多少違背了docker精簡的使用理念。那如何破呢?這個時候就可以考慮將docker內部目錄掛載在特定的宿主機目錄下。指定方式是使用-v {宿主機路徑}:{docker container路徑},我做了如下嘗試

[[email protected] docker-airflow]#  docker run -d -p 8082:8080 -v /data/airflow:/usr/local/airflow puckel/docker-airflow
c06524023e6b4b223386a39b4c133a7ded7918a50fdda21630440bf1cf0ba777
docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"./entrypoint.sh\\\": stat ./entrypoint.sh: no such file or directory\"\n".

從日誌看,已經可以正常啟動docker,但是不能正常啟動Airflow,這是為什麼,我們詳細分析日誌,雖然看著很凌亂,但確實說明了entrypoint.sh這個指令碼找不到。依然使用docker run -d -p 8082:8080 puckel/docker-airflow命令正常啟動容器,進入容器可以發現該指令碼就在/usr/local/airflow路徑下——所以,可以猜測,啟動docker,先執行了目錄掛載,然後啟動指定的指令碼,發現指令碼不存在,因而報錯。於是,處理方式就直接指定到/usr/local/airflow/dags子目錄,畢竟要的起始就是這個路徑而已。這樣的做的好處就是docker內部的dags目錄檔案可以託管到SVN,不怕docker刪除後的資料丟失。完整的命令如下enter code here

另外,提醒使用者,掛載目錄後,該目錄在docker內部是沒有操作許可權的,操作在宿主機上完成,這個可以接受,本來目的就是在宿主機上操作資料。

安裝docker-compose,部署Airflow的LocalExecutor和CeleryExecutor模式

根據githup/docker-airflow官方文件說明,啟動LocalExecutor和CeleryExecutor模式(這兩個模式與SequenceExecutor的差異回頭在Airflow介紹中詳述)需要先安裝docker-compose。這個安裝詳見docker-compose-install。執行curl -L "https://github.com/docker/compose/releases/download/1.8.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose,這個命令執行也是靠運氣,本人拉取花了5個小時…執行完畢後,需要給目錄授權chmod +x /usr/local/bin/docker-compose。完畢後,即可執行docker-compose。由於docker-compose是Python模組,也可以使用pip install安裝,速度會快很多,如下

yum install -y python-pip python-dev
pip install -U docker-compose

For LocalExecutor :

docker-compose -f docker-compose-LocalExecutor.yml up -d

For CeleryExecutor :

docker-compose -f docker-compose-CeleryExecutor.yml up -d

其中,可以通過修改docker-compose-*.yml檔案,設定volumes引數,實現資料卷在宿主機的掛載。

volumes:
     - /data/datadev/wise-data/dags:/usr/local/airflow/dags

注意,使用該版本的docker-LocalExecutor是無法讀取到日誌的,這個作者是這麼解釋的
Since Docker 1.10, Docker don't use (update) anymore /etc/hosts file, he use an embeded DNS server. 8793 is openned by airflow worker, not by scheduler or webserver. And worker works with CeleryExecutor...so for the moment I've no idea how to deal with that issue with airflow in LocalExecutor mode.
看來是破不了,我選擇使用了CeleryExecutor,不需要特別指定log的掛載日誌就能正常檢視到日誌。