| 項目 | 日期 | |
|---|---|---|
| * |
Docker
| |
| 1 | docker 基本指令 |
2018/01/03
|
| 2 | 製作包含 java 的 docker 鏡像 |
2018/01/05
|
| 3 | 使用 Dockerfile 創建 docker 鏡像 |
2018/01/06
|
| 4 | 部署 RESTful service 到 docker |
2019/04/05
|
| 5 | docker logs |
2018/02/27
|
Google Code Prettify
2020年1月27日 星期一
Docker
2019年4月5日 星期五
部署 RESTful service 到 docker
我用 spring boot 寫了一個 hello 的 RESTful service,如下,傳入名稱,服務就會回覆 Hello $name。
@RestController
public class HelloController {
@RequestMapping("/hello/{name}")
public String hello(@PathVariable String name) {
return "Hello " + name + " !";
}
}
這個 RESTful service 我打包成 jar 檔,要部署到 docker 上執行。打包好的 jar 檔名為 Hello-1.0.0.jar,在 docker 中要安裝 open JDK 11 (openjdk-11_linux-x64_bin.tar.gz),Dockerfile 是 docker 提供的自動化部署方式,繼續往下看之前,可以先看一下這一篇 -- 使用 Dockerfile 創建 docker 鏡像。public class HelloController {
@RequestMapping("/hello/{name}")
public String hello(@PathVariable String name) {
return "Hello " + name + " !";
}
}
- Dockerfile
FROM centos:latest
MAINTAINER "Steven Shi"<hi.steven@gmail.com>
ADD openjdk-11_linux-x64_bin.tar.gz /usr/local
COPY Hello-1.0.0.jar /home
RUN ln -s /usr/local/jdk-11 /usr/bin/java
ENV JAVA_HOME /usr/local/jdk-11
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 9080
CMD java -jar /home/Hello-1.0.0.jar
MAINTAINER "Steven Shi"<hi.steven@gmail.com>
ADD openjdk-11_linux-x64_bin.tar.gz /usr/local
COPY Hello-1.0.0.jar /home
RUN ln -s /usr/local/jdk-11 /usr/bin/java
ENV JAVA_HOME /usr/local/jdk-11
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 9080
CMD java -jar /home/Hello-1.0.0.jar
- FROM centos:latest: 指定這個 image 的基礎鏡像為 centos 的最新版。
- ADD openjdk-11_linux-x64_bin.tar.gz /usr/local: 把 jdk 部署到 /usr/local 目錄下,ADD 指令不只會 copy 指定的檔案到指定目錄,還具有解壓縮的功能。
- COPY Hello-1.0.0.jar /home: 把 RESTful service 的 jar 檔部署到 /home 目錄下。
- EXPOSE 9080: 這個 container 對外開放出 9080 這個 port。
- CMD java -jar /home/Hello-1.0.0.jar: 在 container 啟動時,讓 hello 服務啟動。
- 部署服務到 docker
docker build -t steven/hello .
在上面那三個檔案所在目錄執行上述指令,就會在 docker 產生鏡像,名稱為 steven/hello,注意,最後面有個句點,指出是在目前目錄。- 啟動 container
docker run -p 9080:9080 --name hello-container -d steven/hello
- -p 9080:9080 : container 外要連入 container 的 port 也設為 9080 和 container 開放給外界的 port 相連通 (port 號不需要一樣)。
- --name : container 啟動後的名稱。
- -d : 啟動為 daemon 狀態,後面接的是鏡像名稱。
- 測試
curl localhost:9080/hello/Steven
用 curl 發一個 http request 如上,會傳回 Hello Steven,確認服務部署成功。
2018年2月27日 星期二
docker logs
在「docker 基本指令」中了解了一些 docker 的基本操作指令,這裡來看一下怎麼觀察 docker 運行的過程產生的 logs,就以 Apache HTTP Server 來當例子好了。
-d: 在背景執行
-p: port 的映射,將 httpd service 80 port 對映到本機的 80 port。
安裝好之後以 docker images 查一下,應該可以看到如下:
-f: 查看 log 尾部的意思,也就是說,這個指令只會顯示 log 最後的幾行,如果有新的 log 產生會顯示新的 log,內容差不多如下。
因為這是個 http server,我的電腦的 IP 是 192.168.0.200,在瀏覽器輸入 http://192.168.0.200 會看到如下畫面,表示服務確實在運行。
同時,因為瀏覽器有對 http server 進行 request,可以在剛剛的畫面看到又新增了 log。
進到 http server container 的 log 目錄,可以找到一個 {container id}-json.log 的檔案 (檔名很長的那個),看一下內容,如下,非常類似於前面用指令查看到的 log,但仔細看,是 json 格式。
docker info 指令可以看到 docker 的一些設定,其中一項 Logging Driver 就是設定 log 儲存格式,預設如下,可以看到設定為 json-file。
- 安裝 Apache HTTP Server
docker run -d -p 80:80 --name httpd httpd
-p: port 的映射,將 httpd service 80 port 對映到本機的 80 port。
安裝好之後以 docker images 查一下,應該可以看到如下:
- 查看 docker logs
docker logs -f httpd
因為這是個 http server,我的電腦的 IP 是 192.168.0.200,在瀏覽器輸入 http://192.168.0.200 會看到如下畫面,表示服務確實在運行。
同時,因為瀏覽器有對 http server 進行 request,可以在剛剛的畫面看到又新增了 log。
- log file
進到 http server container 的 log 目錄,可以找到一個 {container id}-json.log 的檔案 (檔名很長的那個),看一下內容,如下,非常類似於前面用指令查看到的 log,但仔細看,是 json 格式。
- Logging Driver
docker info | grep 'Logging Driver'
2018年1月6日 星期六
使用 Dockerfile 創建 docker 鏡像
繼「製作包含 java 的 docker 鏡像」手動的製作 docker image 後,這一篇要將手動的流程自動化。docker 提供了一個自動化的方式,就是寫一個叫作 Dockerfile 的 script 文檔,這個文檔不一定要命名為 Dockerfile,這只是預設的檔名。上一篇的 images 是在 centos 中安裝 java 9,所以,我先在 home 目錄下建立一個暫時的目錄 tmp,將 openjdk-9.0.1_linux-x64_bin.tar.gz 放入目錄裡,並於目錄中新增如下的 Dockerfile。
然後下這樣的指令:
console 會出現如下的訊息後,幾秒就完成了一個鏡像,其中有了 -t 參數後面才能帶我們想要的鏡像名稱,最後的句點 (.) 是指在現在的目錄裡尋找 Dockerfile。
接下來說明一下 Dockerfile 中指令的用途:
【補充】
製作好 image 可以試著把它推到 docker hub,首先當然要註冊一個帳號,我註冊的是 twleader,接著 create 一個 repository,我 create 一個命名為 java9 的 repository,接著如下:
FROM centos:latest MAINTAINER "Steven Shi"<hi.steven@gmail.com> ADD openjdk-9.0.1_linux-x64_bin.tar.gz /usr/local RUN ln -s /usr/local/jdk-9.0.1 /usr/bin/java ENV JAVA_HOME /usr/bin/java ENV PATH $JAVA_HOME/bin:$PATH CMD java -version
docker build -t steven/java9 .
接下來說明一下 Dockerfile 中指令的用途:
- FROM centos:latest
每個鏡像需要有個"基礎鏡像",FROM 即指出要使用的基礎鏡像是 centos 的最新版本。
- MAINTAINER "Steven Shi"<hi.steven@gmail.com>
MAINTAINER 指令指出這個鏡像由誰創建和維護,後面的參數並沒有規定格式,姓名加上 email,這只是眾多用法中的一種。
- ADD openjdk-9.0.1_linux-x64_bin.tar.gz /usr/local
ADD 指令的第一個參數是要安裝的檔案的路徑,因為我將 openjdk-9.0.1_linux-x64_bin.tar.gz 和 Dockerfile 放在同一路徑,所以直接寫檔名即可,第二個參數是安裝進 container 的路徑。ADD 指令具有解壓縮的功能,另外一個類似的指令 COPY 就只能將檔案複製到指定的路徑。
- RUN ln -s /usr/local/jdk-9.0.1 /usr/bin/java
上一篇在解壓縮好 JDK 後,我們有建立一個連結以方便後續的存取,要在 container 中執行命令就用 RUN。如果有多個命令要執行,可以寫好幾個 RUN,但是,建議是在每個命令後加上反斜線 \,然後於次行寫下一個命令,這個方式製作出來的鏡像會比較小,因為每執行一次 RUN,docker 會產生一個鏡像層,多出一點體積。
- ENV JAVA_HOME /usr/bin/java
- ENV PATH $JAVA_HOME/bin:$PATH
上一篇手工製作時,我們沒有指定 JAVA_HOME 並設定 PATH,但是一般來說,Java 安裝好之後,這是必要的事。如果要設定環境變數,就用 ENV。
- CMD java -version
CMD 可以用來在 container 啟動後執行命令,要特別注意的是 CMD 只可以不寫或只寫一次! 這裡簡單的執行 java -version 以確定鏡像製作有成功。想要了解更多? 可以參考官網 https://docs.docker.com/engine/reference/builder/。
【補充】
製作好 image 可以試著把它推到 docker hub,首先當然要註冊一個帳號,我註冊的是 twleader,接著 create 一個 repository,我 create 一個命名為 java9 的 repository,接著如下:
- docker login
登入 docker hub,輸入帳號、密碼。
- docker tag f6cc7ec468a3 docker.io/twleader/java9
- docker push docker.io/twleader/java9
使用 tag 指令,為原本的 steven/java9 加上一個標籤,我命名 docker.io/twleader/java9 這樣才能 push 到 docker hub 的 twleader 帳號裡的 java9 repository,接著就是下 push 指令推到 docker hub 上。
2018年1月5日 星期五
製作包含 java 的 docker 鏡像
在看完「docker 基本指令」後,我們已經可以製作一個 centos 的鏡像,這篇要在這個鏡像中安裝 Java 9,並且包裝成鏡像。首先下載 Open JDK,下載後我將它放在 /home/steven/Software 目錄下,如下: (openjdk-9.0.1_linux-x64_bin.tar.gz)
接下來 … 要開始了 …
接下來 … 要開始了 …
- docker run -i -t -v /home/steven/Software:/mnt/software centos /bin/bash
下了 docker run 後,因為我之前安裝的 centos 鏡像已經被我移除,在本機找不到後,docker 自動連到 docker hub 再下載一個。這次的 docker run 指令後又多了 -v 參數,這是要掛載磁碟,將本機的 /home/steven/Software 掛載到 centos container 裡的 /mnt/software,所以,在進入 container 後,下 ls -l 指令,又可以看到和本機 /home/steven/Software 一樣的內容。
-i: 即 --interactive, 這個參數要求 docker 保持標準輸入裝置 (stdin)
-t: 即 --tty,這個參數要求 docker 分配一個終端裝置
- tar zxvf openjdk-9.0.1_linux-x64_bin.tar.gz -C /usr/local
進入 /mnt/software 目錄後,以上述指令將 open jdk 9 解壓縮到 /usr/local 目錄下,如上圖,可以看到 /usr/local 目錄裡產生了 jdk-9.0.1。
- ln -s /usr/local/jdk-9.0.1 /usr/bin/java
為了方便存取,建立一個連結到 /usr/bin/java。
- ./java -version
進入 /usr/bin/java/bin 目錄,下 java -version 指令看一下 jdk 版本,如上,果然是 9.0.1 版。
- docker ps -a
離開 container 回到本機,下 docker ps -a 看一下剛剛創建的 container,如上圖。
- docker commit 87426bc47a5e steven/java9
如上下 docker commit 提交一個鏡像,我們將它命名為 steven/java9 (87426bc47a5e 為 container ID),這個指令執行需要一點點時間,然後提交後顯示出鏡像 ID。
- docker images
下 docker images 列出所有鏡像,果然可以看到 steven/java9,IMAGE ID 也正確。
- docker run --rm steven/java9 /usr/bin/java/bin/java -version
使用 docker run 指令啟動剛製作好的鏡像的 container,並且執行該 container 中的 /usr/bin/java/bin/java -version 看看是不是和之前安裝好後執行出來的版本一樣? 如上圖這樣就確認我們確實有安裝好了! --rm 參數是要求 docker 在執行完指令退出 container 後立即刪除該 container。
2018年1月3日 星期三
docker 基本指令
在「Installing and Configuring Docker (Scientific Linux 7.3)」中已經安裝好 docker,這裡來試用看看 …
- docker images
這個指令會列出所有已安裝的鏡像,因為這個時候才剛安裝好 docker,沒有任何鏡像。
- docker pull centos
由 docker hub 上拉取 CentOS 鏡像,再下一次 docker images,如下,可以看到 centos 鏡像已經存在本機。
上圖列出來的項目共有五欄,說明如下:
- REPOSITORY: 鏡像名稱 (docker.io/centos)
- TAG: 鏡像的標籤,上圖顯示 latest,表示這個鏡像是最新版本。
- IMAGE ID: 鏡像的序號,這個序號很重要,每個 image 會有一個唯一的序號,後續如果要操作這個鏡像,會用到這個序號。
- CREATED: 鏡像創建的時間,表示的方式是離現在的時間多久。
- SIZE: 鏡像的大小
- docker search centos
search 指令可以在 docker hub 上找出指定的鏡像,如上圖,列出了所有 centos 的鏡像。
- docker save centos > centos.tar
想把鏡像存起來? 用這個指令,導出成一個 tar 檔,完成後,可以 ls 看一下,約 200 MB,帶著這個 tar 檔,可以在別的 docker 機器上導入,這在公司裡應該會常用到,因為大部分的公司會有防火牆,server 不一定可以隨意的連線到 docker hub,所以在可以連線的地方先拉取一個鏡像儲存後,帶到要安裝的 server 導入。
- docker load < centos.tar
上面就是導入鏡像的指令
- docker run -i -t centos /bin/bash
如上,即可啟動容器,參數說明如下:
- -i : 啟動容器打開標準輸入 (STDIN) ,之後即可使用鍵盤輸入。
- -t : 啟動容器後給予容器一個虛擬的終端設備 (pseudo-TTY),讓使用者可以與容易對話。
- centos : 要運行的鏡像名稱,更嚴謹的輸入方式是 centos:latest,表示要使用最新版本,沒有打 latest,就預設是最新版本。
- /bin/bash : 容器啟動後執行的程式,這裡指定 bash (UNIX 的一種 shell),所以可以看到如上圖所示,進入了一個提示字元為 [root@27b5c5977301 /] 的環境,27b5c5977301 是容器的序號。
- docker ps
在本機開啟另一個命令視窗,輸入如上指令,可以看到正在運行的容器,各欄位說明如下:
- CONTAINER ID: 容器序號
- IMAGE: 鏡像名稱
- COMMAND: 啟動容器時執行的命令
- CREATED: 容器創建的時間
- STATUS: 容器運行的狀態
- PORTS: 容器暴露的端埠號
- NAMES: 容器的名稱,由 docker 自動產生,不喜歡這個名稱? 可以在 run 時加上 -name 來指定名稱。
docker ps 後面還可以帶參數,常用的如下:
- -a : 列出所有容器 (包含運行中及已停止的)
- -l : 列出最近創建的容器
- -n : 列出 n 個最近創建的容器
- -q : 僅列出 CONTAINER ID 欄位
- -s : 在輸出的欄位中,增加 SIZE 欄位,用來顯示容器大小。
- docker attach 27b5c5977301
剛剛下 run 啟動容器後,如果離開了又想重新進入,就用 attach 指令,並以容器序號當參數。
- docker start 27b5c5977301
容器關閉後要啟動就用 start,關閉用 stop,重新啟動用 restart,除了 stop 外,也可以用 kill 關閉容器,兩者差別在於 kill 是立即關閉,stop 則會略等一小段時間後關閉。
- docker rm 27b5c5977301
刪除容器用 rm,運行中的容器無法直接刪除,可以加上 -f 強制刪除。
- docker rmi -f docker.io/centos
rmi 指令用在刪除鏡像,加上 -f 也是強制刪除。上面的參數用鏡像名稱,也可以使用鏡像序號。
- docker export 容器序號(或容器名稱) > xxx.tar
- docker import xxx.tar 容器名稱/centeos:latest
前面提供使用 save、load 儲存鏡像和導入鏡像,如果要儲存容器及導入容器則是用上面這兩個指令。差別在於,儲存容器是指儲存正在運行的容器的當時狀態,這會包含容器已運行的一些歷史紀錄,所以檔案會比較大。
訂閱:
意見 (Atom)



























