發表文章

目前顯示的是有「Docker」標籤的文章

Docker Prune

圖片
Docker 在清理工作環境這方面,或者是說 Docker 的垃圾回收(Garbage Collection)機制是相對保守的,如果沒有明確指定,Docker 通常是不會主動去刪除不需要和沒在使用的東西。 因此,我們時常需要使用 docker rm 和 docker rmi 來清理工作環境,泰勞本身每天例行性的工作就是清除那些不需要的容器(Container),先列出所有容器,再依序將其刪除,如下列步驟: $ docker ps -a $ docker rm <container-id-1> $ docker rm <container-id-2> ...... 清除不需要的映像檔(Image)也是一樣,先列出所有映像檔,再依序將其刪除。如果需要清除的容器和映像檔很多,一個一個處理實在不是個好辦法。有些人可能會找到一些指令,透過 grep 或 awk 來過濾出想要的資訊,那個方法在很久以前很實用,但是現在已經是西元 2019 年了,當然有更好的選擇~那就是今天的主角 Prune! 參考資料: Prune unused Docker objects    What is a dangling image and what is an unused image ?   清理容器 從Docker 版本 1.13.0 開始,如果需要將所有不需要 、可刪除 、 已停止運作的容器一次清除,指令非常簡單: $ docker container prune 結果如下圖所示,這指令真的讓你瞬間變成清除達人! 雖然這指令很方便使用,不過還是要回到原始問題,如果你的容器在每一次執行結束時,都一定要清除掉,那你應該選擇在啟動容器時就一併使用 --rm 參數,會是更好的選擇喔! 清理映像檔 整理映檔之前,先來了解一下兩種時常需要被清理的映像檔類型。 Unused Images : An unused image means that it has not been assigned or used in a container . For example, when running docker ps –a, it will list all of your ex...

Docker Build Context

圖片
建立一個新的 Docker Image 不只需要準備一份 Dockerfile,還需要準備一個 Build Context 給它,放的是一些編譯映像檔所需的檔案或目錄,如此 Dockerfile 才能去 COPY 或 ADD 這些資料到映像檔裡面。Build Context 可以是一個指定的目錄或是 URL,下方是一個常見的編譯指令,最後面那個點的功能就是將 Build Context 設在當前目錄。 $ docker build -t test:1.0 . 當然這是一個理想的狀態,很多時候會遇到一些限制,像是編譯所需的檔案在上層目錄或是其他非常遙遠的地方,那該怎麼辦呢?來看看下面在 Dockerfile 裡面的嘗試。 FROM ubuntu:18.04 RUN apt-get -y update COPY ../test/test.sh /usr/local/bin/test.sh 若事情有這麼簡單就好了,編譯出錯,錯誤訊息如下: 官方文件有提到 ADD 或 COPY 時不允許使用 ../ 這類型的語法,因為指定的資源必須在 Build Context 目錄底下。看來在 Dockerfile 裡面行不通,那就改用其他方法吧! docker build -f 既然 Build Context 的指定方式限制太多,那就反過來指定 Dockerfile 的路徑吧!到 test 目錄底下,透過 -f (--file string) 來指定 Dockerfile 的路徑,這樣就可以將 test 目錄作為 Build Context,然後使用其他目錄的 Dockerfile ,範例如下: context/Dockerfile ............ COPY test.sh /usr/local/bin/test.sh 編譯指令 $ docker build -t test:1.0 -f ../context/Dockerfile . 當然也可以指定當下目錄的 Dockerfile,然後指定 test 目錄作為 Build Context,像是這樣: $ docker build -t test:1.0 -f ./Dockerfile ../test 這裡要小心的是你不能只用 docker...

Docker 用戶管理

圖片
Docker 容器啟動之後,預設登入的使用者帳號是 root,這會造成一些困擾,像是編譯過程生成的檔案,將會屬於 root 使用者,之後要進行修改或刪除就會碰到權限的問題。因此泰勞找了幾個方式來管理 Docker 用戶與權限設定的問題,在此簡單介紹。 參考資料: [Github]tianon/gosu [Deni Bertovic]Handling permissions with Docker volumes [redbubble]Running a docker container as a non-root user   1. --user 第一種方式,透過參數 --user 來指定容器啟動之後的 UID,這樣一來,在容器內生成的檔案都會屬於特定 UID,方便用戶管理。指令簡短易懂,但也有一些缺點,其中之一就是容器無法得知用戶名稱,如下圖所示。 2. useradd 第二種方式,透過 Dockerfile 建立 Docker 映像檔時,直接新增一個使用者並且將其設定為預設用戶。 Dockerfile FROM ubuntu:18.04 MAINTAINER Kuanlin Chen RUN useradd -ms /bin/bash build USER build 接著編譯 Dockerfile 並且執行 Docker 映像檔,可以看到容器啟動之後,預設的用戶已經不再是 root 了,如下圖所示。 3. gosu 使用 gosu 套件主要目的不僅僅是避免使用 root 帳戶,它最重要的功能是將啟動 Docker 容器的用戶 UID 傳入容器內,意即容器外與容器內的 UID 是一樣的。 撰寫一份 Dockerfile 以及啟動容器時需要的腳本,然後編譯一份新的 Docker 映像檔。 Dockerfile FROM ubuntu:18.04 MAINTAINER Kuanlin Chen RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get -y --no-install-recommends install ca-certificates curl gnupg # Install gosu p...

Docker 圖形界面

圖片
大部份使用 Docker 的時候都僅有終端界面,只能透過指令來操作,但是本人好吃懶做,希望有美美的圖形界面可以使用,因此做了一些功課,發現其實有幾種方式可以讓 Docker 容器運行時具有圖形界面! 參考資料: [Fabio Rehm's Blog]Running GUI apps with Docker Docker這樣學才有趣:從入門,到玩直播、挖礦 Firefox+X11 第一種方式是將 Linux 自身的 X11 分享給 Docker 容器使用,就這麼簡單一句話而已,直接來實作,這裡用 Firefox 瀏覽器作為範例。 Dockerfile FROM ubuntu:18.04 RUN apt-get update && apt-get install -y firefox RUN useradd -ms /bin/bash developer USER developer ENV HOME /home/developer CMD /usr/bin/firefox 接著編譯 Docker 映像檔,然後啟動容器,指令如下所示。 $ docker build -t firefox . $ docker run -ti --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix firefox 若一切順利,就會看到一個貨真價實的 Firefox 被啟動,差別只在於它存在 Docker 容器裡。有沒有覺得很有趣阿! Ubuntu+VNC 這方法是從 「Docker這樣學才有趣 」這本書裡看到的,有興趣的可以去買一本來看。其實原理很簡單,就是安裝一個輕量的桌面環境和一個可以分享螢幕畫面並且遠端操作的軟體,再透過 CMD 指令讓 Docker 容器啟動時執行 VNC Server,啟動之後就可以使用遠端桌面連線工具,連線至具有 GUI 界面的容器囉! Dockerfile FROM ubuntu:14.04 RUN apt-get update && \   DEBIAN_FRONTEND=noninteractive apt-get install -y lxde-core lxterminal tightv...

Docker Image Layer

圖片
上面這張圖,如果你已經使用過 Docker,一定不會感到陌生,當我們 Pull 一個 Docker Image 時,時常會看到這樣的畫面,司空見慣 、 不足為奇,那泰勞為什麼要以這張圖為開頭呢?嘿嘿~當然是有其重要之處阿! 不知道有沒有人有過一樣的疑惑,為什麼 Pull 的時候要顯示這些資訊?這些資訊又代表著什麼含意呢?如果你有興趣,那就繼續看下去吧! 參考資料: [StackOverflow]Docker images "Already exists"?   [StackOverflow]What are docker image layers ?   [Docker Docs]Images and Layers   先思考一下,Pull 時顯示的資訊應該跟那個 Image 有相關,而 Pull 的過程列出了很多個雜湊值,這些值所代表的東西,有些已經存在 (Already exists),有些剛完成 Pull (Pull complete),有些還在等待 Pull 的動作 (Waiting),難道這些東西全部合在一起就是一個 Image? 沒錯!這些雜湊值代表的就是一個個 Docker Image Layer ,而一個 Docker Image 就是由數個 Image Layer 所組成!來看一段 Docker 的基本觀念。 (1) Docker container are running systems defined by Docker images. (2) Docker images are made up of one or more Docker layers. (3) Every line in Dockerfile adds up a Docker layer which makes up your Docker image. (1) 如果將 Docker image 比喻成 Java 的類別(Class),那麼 Docker container 就如同在 Java 裡面從某個類別 new 一個實例(Instance)出來。 (2) Docker image 由一或多個 Docker layer 所組成。 (3) 撰寫並且編譯 Dockerfile 可以生成 Docker...

使用 Dockerfile 建立自定義的映像檔

圖片
泰勞先前有簡單介紹過如何使用Docker,不知道各位在使用的過程當中是否有遇到一些困難,例如:某個映像檔缺少了一些編譯特定軟體所需要的套件,或者是某個函式庫的版本不是我想要的,因而造成編譯失敗 、進度延遲 、專案停擺 、主管譴責 、老闆不滿 、飯碗不保 等等,其他可怕 情況自行想像。此時你就可以選擇使用Dockerfile來建立自定義的映像檔! 參考資料: Dockerfile reference   Docker提供使用者自行編譯映像檔的方法,透過撰寫Dockerfile文件,讓Docker讀取裡面的指令來進行編譯。步驟很簡單,直接創建一個空目錄並在裡面建立一份名為[Dockerfile]的文件即可。 接著透過指令將想要加入的套件或是需要更新的函式庫版本,寫入Dockerfile裡面。需要注意的是必須遵守Dockerfile的撰寫規則,該有的定義一定要有,而最重要且會放置於第一行的就是 「 新的映像檔要以哪個舊有的映像檔為基礎 」。 通常會加上維護者的名字,雖然官方沒強制規定,但有建議說明一下。再來就要加入指令來操作映像檔,這裡使用"RUN"來定義編譯時需要執行的指令,例如:我想讓新的映像檔以[ubuntu]這個映像檔為基礎並且安裝libfile-copy-recursive-perl這個套件進去。 撰寫完畢就可以開始進行編譯囉!指令如下所示,此指令會編譯出一個名為kuanlin且標籤為1.0的映像檔。 $ docker build -t kuanlin:1.0 .    // -t:指定標籤資訊     看似順利,但人生總是不如意,此時docker編譯出現了錯誤訊息,原來是因為安裝套件時,需要輸入Yes或No,若是透過預先寫好的指令,就要加上-y這個參數。 編譯成功!看一下是否有多出一個名為kuanlin的映像檔。 Proxy 若是你的工作環境比較封閉,有經過代理伺服器(Proxy)的管理,那在編譯時有可能會出現錯誤,類似下圖。 上網搜尋了一些 資料 ,出現此錯誤訊息跟Proxy的設定有關。此時可以試試透過--build-arg參數將Proxy指給docker,讓docker在編譯時不會迷失方向,指令如下所示。 $ docker build...

Docker 安裝與使用

圖片
由於Android Nougat必須使用Open JDK 8來編譯,若同時又要持續維護舊版Marshmallow的原始碼,時常需要將Java版本換來換去,造成了許多不便。因此在天時地利人和之下,泰勞也開始學習使用近幾年非常火熱的虛擬化工具- Docker ! 參考資料: 什麼是Docker? <<Docker--從入門到實踐>> Docker虛擬化容器技巧-凍仁的筆記 簡單的說,Docker能夠讓你在原有的工作環境底下, 依照自己的需求 來選擇合適的映像檔,並 建立一個虛擬的工作容器(Container), 接著只需要將想處理的東西掛載至這個與外界隔絕的工作容器裡面即可。然而,它並不完全是一個虛擬的作業系統,因此可以節省許多的硬碟空間,泰勞最近使用過的Docker映像檔大約落在1GB到3GB之間喔! 安裝 泰勞的工作環境是Ubuntu14.04,以下指令可以直接透過系統內建套件安裝,按照參考資料的教學一步一步走,沒有遇到太大的問題。 $ sudo apt-get update $ sudo apt-get install -y docker.io $ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker $ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io 安裝完成後,查看一下版本,順便設定Usermod並啟動Docker服務。 $ docker version $ sudo usermod -a -G docker $USER     //下一次登入才會生效 $ sudo service docker start 檢查一下是否有確實啟動。 $ ps -ef | grep docker 使用 成功啟動之後就可以開始使用Docker囉!首要步驟當然是先取得一份映像檔,就從萬年不敗的hello-world開始吧! $ docker pull hello-world $ docker images    //查看本地端有哪些映像檔 $ docker ...