建立於: 7年前 ( 更新: 7年前 )
Docker的功能很類似VM(虛擬機器),但是Docker不是VM。
這是Docker與Linux核心的關係。
在下圖中,使用Dockerfiler建立image,通常抓現成的官方image,
用docker run可自動抓下來image並產生container,
我們可以把更多的東西放入container內,
再commit這個container成為一個新的image,再更新push到DockerHub上,
提供給別人使用。
上方投影片的出處
Docker Engine使用了Linux Kernel(核心)的新功能 Namespaces 及 Control groups ,
用來隔離出工作空間,我們稱為容器(Container),所以不需要像VM安裝一整個作業系統。
Control groups 這裡簡稱 Cgroups , Cgroups 允許您在系統運行的用戶定義的任務組(執行序)中,
分配資源(例如CPU時間,系統記憶體、網路頻寬或這些資源的組合),
Namespaces : 用來隔離和虛擬化一系列執行序( processes )。
當我們安裝好Docker後,我們可以執行如下指令(例如Ubuntu的Linux環境下,需sudo)
如果我們未安裝這個image會自動安裝,如果有裝了,Docker就會直接執行,建立這個容器。
在上方的例子中並未指定tag,就會使用最新版本(latest)。
如果我們要指定版本,可補上:3.5,例如alpine:3.5。
如果不想每次都打sudo,可以執行如下指令,把你的使用者,加入docker群組。
登出再登入bash測試,就會發現,不需要打sudo囉。
下方實際執行不需sudo了,在下方的圖片中同時也發現到了,我們電腦不存在hello-world這個image時,
Docker會自動幫我們下載。
2. Client取得使用者的輸入,並且送給Daemon.
3. Daemon進行builds,run及distributes containers.
4. Client及Daemon可以執行在相同的主機或不同的主機上。
5. Client有命令列Client及GUI(Kitematic)兩種。
下方指令,用來查看Client及Server的版本:
可以把Dockerhb想像成是Docker的App Store.
- 開發者可以專心的在於他們的Apps上(Developers focus on building their apps)。
- 系統工程師專注於部屬 (System admins focus on deployment)。
Fast development cycle
- 如果需要可以輕易的開啟新的container,跑更多的應用程式在主機上。
Container with Terminal
-使用-i及-t旗標
-i 代表告訴docker去連接到container的STDIN.
-t 旗標,會取得一個pseudo-terminal.
Container內的程序(process)停了,就會同時停止container.
例如: 進入bash之後離開.
你輸入docker ps,並不會看到上方的echo "TEST"這個contaienr的process.
用下方指令可以看執行中的containers及container id
docker ps
查看,這個container的狀態會是執行中。
執行
再用
上方可以看到,建立了本地主機(host)的32856。
例如,上圖中我有兩個container
再用docker commit指令,建立新的image,如下指令
記得嗎?image是唯讀的,container才能被寫資料,在進行 Debug 及測試時很有用,
透過commit想保留最新的狀態到image中,這樣下次run這個image時,
產生出來的container就會是我們最後commit的狀態了。
我們可以用
一般而言,我們應該要用Dockerfile來管理我們image的變更 。
https://github.com/DevinY/fpm
進入clone下來的fpm工作目錄後,
cd 7.1/apache (進入7.1/apache資料夾)
這個資料夾內,會有一個Dockerfile.
我們就可以用下方指令來build自己的image了。下方的指令中,最後有一個(點).代表查看目前目錄下的Dockerfile,用他來建image。
如何用Dockerfile重build image實際操作,可以參考下方影片連結:
如何重build新的php-fpm image給D-Laravel使用。
首先如下方指令,列出所有的container:
1.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d2f21c4b5fc alpine "echo Hello World" 7 minutes ago Exited (0) 2 minutes ago nervous_mestorf
2. 我們可以透過CONTAINER ID或是Name,來重新執行一次echo Hello World,加上-a是因為,
要把container內的標準輸出轉發出來,這樣才能顯示出Hello World在畫面上.
Hello World
(題外話: 如果使用docker-compose時,
Docker rm移除Container
用
我們可以指定Container id或名稱來刪除container.
1.
2.
Container必需要在停址的狀態才有辨法刪除,STATUS還是Up我是無法移除的。
這裡 dlaravel_web_1 是Container的名稱
把自己的image push到dockerhub上,我們需先在dockhub上註冊帳號。
本機host會開8080在左邊,而nginx是 container 使用port 80,
下方指令的意思代表了,我們開瀏覽器 localhost:8080 就能開啟nginx的網頁服務了。
-可以被映射到主機資料夾(Can be mapped to a host directory)
-卷宗的路徑必需是絕對路徑(Volume paths specified must be absolute)
執行一個新的container並且掛載資料/myvolume到container的檔案系統內(我們要掛載的資料夾是主機上的絕對路徑)
執行一個新的container並且map(映射)/data/src資料夾,由主機(host)到container內的/test/src資料夾。
Docker預設會連到default bridge,container之間可用IP互通。
如果您要讓彼些容器名稱(container name)可以被解析成IP,
我們需使用user-defined networks (使用者定義的網路)
User-defined networks 練習:
上方的筆記中有提到,用
那麼要移除 image 怎麼做呢?
可以用 rmi (就想成 Remove Image 就對囉,要先把停止的相關container移除後,才能移除image哦)
docker run (建立並執行container)
docker start (啟動一個或多個停止的containers)
docker exec (在啟動中的container內,執行一個命令)
這是Docker與Linux核心的關係。
Docker的工作流程(Build、Ship & Run) | |
---|---|
1. Build an image: | 使用一個叫Dockerfile的純文字檔,來指定我們想要東西綁進image內,諸如: 基本的OS、函式庫及應用程式等,建好的image是一個唯讀的樣板,我們可變更container,並透過commit container來產生一個新的image。 |
2. Ship the image: | 經由Dockerh Hub或你私人的倉庫(private repository),你可以非常輕易的使用docker發佈這個應用程式或開發環境, 基本上這裡已經有大量的官方(official)預建好的image了,隨時可拿來用。 |
3. Run a container: | 要能夠跑container在一台主機上,我們需安裝Docker, 可把他部署成微服務(不同的container跑不同的服務), 我的D-Laravel Project一個Laravel平台的開發環境,就是使用微服務架構。 |
在下圖中,使用Dockerfiler建立image,通常抓現成的官方image,
用docker run可自動抓下來image並產生container,
我們可以把更多的東西放入container內,
再commit這個container成為一個新的image,再更新push到DockerHub上,
提供給別人使用。
上方投影片的出處
Docker Engine使用了Linux Kernel(核心)的新功能 Namespaces 及 Control groups ,
用來隔離出工作空間,我們稱為容器(Container),所以不需要像VM安裝一整個作業系統。
Control groups 這裡簡稱 Cgroups , Cgroups 允許您在系統運行的用戶定義的任務組(執行序)中,
分配資源(例如CPU時間,系統記憶體、網路頻寬或這些資源的組合),
Namespaces : 用來隔離和虛擬化一系列執行序( processes )。
Create a Container
用docker run
指令建容器當我們安裝好Docker後,我們可以執行如下指令(例如Ubuntu的Linux環境下,需sudo)
sudo docker run alpine echo Hello World
上方使用alpine linux建立的Docker image,只有5mb大小。如果我們未安裝這個image會自動安裝,如果有裝了,Docker就會直接執行,建立這個容器。
在上方的例子中並未指定tag,就會使用最新版本(latest)。
如果我們要指定版本,可補上:3.5,例如alpine:3.5。
如果不想每次都打sudo,可以執行如下指令,把你的使用者,加入docker群組。
sudo usermod -aG docker ${USER}
例如,我在AWS EC2的主機,預設的使用者是ubuntu,那麼<user>就改成ubuntu,執行完後,登出再登入bash測試,就會發現,不需要打sudo囉。
docker run hello-world
上方測試,使用hello-word的image來顯示資料。下方實際執行不需sudo了,在下方的圖片中同時也發現到了,我們電腦不存在hello-world這個image時,
Docker會自動幫我們下載。
Docker Client and Daemon.
1. Client/Server的架構。2. Client取得使用者的輸入,並且送給Daemon.
3. Daemon進行builds,run及distributes containers.
4. Client及Daemon可以執行在相同的主機或不同的主機上。
5. Client有命令列Client及GUI(Kitematic)兩種。
下方指令,用來查看Client及Server的版本:
docker version
Docker Containers and Images.
Images | ||
---|---|---|
-是一個唯讀的樣版,用於建立Containers。 | ||
-是由你自己建立或是其他的Docker用戶建立。 | ||
-儲存在Dockerhub或是你自己本地端的local Registry. |
Containers |
---|
-隔離的運用程式平台 |
-Container就是你所有應程式執行及安裝的地方 |
-Container基於一個或多個映像檔(Images) |
Registry and Repository
以Docker Hub為例,Reigistry內有很多Repo,在Repo內會有很多的images.可以把Dockerhb想像成是Docker的App Store.
Docker的效益
Sepration of concerns.- 開發者可以專心的在於他們的Apps上(Developers focus on building their apps)。
- 系統工程師專注於部屬 (System admins focus on deployment)。
Fast development cycle
- 如果需要可以輕易的開啟新的container,跑更多的應用程式在主機上。
如何查看host裝了那些images
可以使用docker images
查看已安裝的images。 不指定tag時,會預設使用latest版。
建立並執行Container(creating a container)
例如:
docker run ubuntu:14.04 echo "Hello World"
Container with Terminal
-使用-i及-t旗標
-i 代表告訴docker去連接到container的STDIN.
-t 旗標,會取得一個pseudo-terminal.
Container內的程序(process)停了,就會同時停止container.
例如: 進入bash之後離開.
docker run -it centos
所以下方的指令如下:
docker run centos echo "TEST"
這個process執行完後,container就停了。你輸入docker ps,並不會看到上方的echo "TEST"這個contaienr的process.
Container ID
用下方指令可以看執行中的containers及container id
docker ps
列出所有的containers,如果用
docker ps -a
可以看到之前所有建立的並且停止的container.
Running in Detached Mode
用-d進入detached mode
docker run -d centos ping 127.0.0.1 -c 1000
我們可以打docker ps
查看,這個container的狀態會是執行中。
執行
docker logs <short id>
可以看到結果,如果加上-f,就相當於tail -f指令。
docker logs c0299f4dc228 -f
docker run -d -P nginx
可以進行port mapping再用
docker ps
查看上方可以看到,建立了本地主機(host)的32856。
Commit container
先用docker ps -a
查出所有的containers例如,上圖中我有兩個container
再用docker commit指令,建立新的image,如下指令
docker commit c0299f4dc228 my_new_image
記得嗎?image是唯讀的,container才能被寫資料,在進行 Debug 及測試時很有用,
透過commit想保留最新的狀態到image中,這樣下次run這個image時,
產生出來的container就會是我們最後commit的狀態了。
我們可以用
docker images
查看是否有這個my_new_image。一般而言,我們應該要用Dockerfile來管理我們image的變更 。
用Dockerfile建images
可以git clone這個repo下來測試.https://github.com/DevinY/fpm
進入clone下來的fpm工作目錄後,
cd 7.1/apache (進入7.1/apache資料夾)
這個資料夾內,會有一個Dockerfile.
我們就可以用下方指令來build自己的image了。下方的指令中,最後有一個(點).代表查看目前目錄下的Dockerfile,用他來建image。
docker build -t testimage:1.0 .
如何用Dockerfile重build image實際操作,可以參考下方影片連結:
如何重build新的php-fpm image給D-Laravel使用。
執行已停止的container
我們可以用docker start
來執行停止中的container,首先如下方指令,列出所有的container:
1.
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d2f21c4b5fc alpine "echo Hello World" 7 minutes ago Exited (0) 2 minutes ago nervous_mestorf
2. 我們可以透過CONTAINER ID或是Name,來重新執行一次echo Hello World,加上-a是因為,
要把container內的標準輸出轉發出來,這樣才能顯示出Hello World在畫面上.
docker start -a 8d2f21c4b5fc
Hello World
(題外話: 如果使用docker-compose時,
docker-compose up -d
時會建立並執行container,docker-compose down
時,會移除container)Docker rm移除Container
用
docker rm
指令來移除container.我們可以指定Container id或名稱來刪除container.
1.
docker ps -a
(列出所有的container)2.
docker rm <container name 或id>
Container必需要在停址的狀態才有辨法刪除,STATUS還是Up我是無法移除的。
如何取得Terminal access.
指令如下:
docker exec -i -t [container ID] /bin/bash
例如,我要進入D-Laravel的web container,那麼可以用如下指令(Container ID或name都OK)docker exec -ti dlaravel_web_1 bash
這裡 dlaravel_web_1 是Container的名稱
登入docker
如果有註冊了dockerhub的帳號,就可以用docker login
把自己的image push到dockerhub上,我們需先在dockhub上註冊帳號。
docker push deviny/centos:6.6
The push refers to a repository [docker.io/deviny/centos]
網路本機host會開8080在左邊,而nginx是 container 使用port 80,
下方指令的意思代表了,我們開瀏覽器 localhost:8080 就能開啟nginx的網頁服務了。
docker run -d -p 8080:80 nginx
Mount a Volume
-當執行或建立一個container時卷宗被掛載(Volumes are mounted when creating or executing a container.-可以被映射到主機資料夾(Can be mapped to a host directory)
-卷宗的路徑必需是絕對路徑(Volume paths specified must be absolute)
執行一個新的container並且掛載資料/myvolume到container的檔案系統內(我們要掛載的資料夾是主機上的絕對路徑)
docker run -d -P -v /myvolume nginx
執行一個新的container並且map(映射)/data/src資料夾,由主機(host)到container內的/test/src資料夾。
docker run -i -t -v /data/src:/test/src nginx
Creating a Link
(官方已列為不建議使用了,未來將被移除)
Warning: The--link
flag is a deprecated legacy feature of Docker. It may eventually be removed.
Docker container networking
User-defined Network,Docker官方文件參考Docker預設會連到default bridge,container之間可用IP互通。
如果您要讓彼些容器名稱(container name)可以被解析成IP,
我們需使用user-defined networks (使用者定義的網路)
User-defined networks 練習:
讓Container在同一個網路下可以ping到彼此的Container Name
一、建立一個user-defined網路(這裡我取名叫 dodoro_net )
#列出網路指令
二、讓兩個Container在同一個 user-defined 的網路( dodoro_net )中,就可以用container name(容器名稱)ping到彼此
1. 建立第一個資料庫的container,並使用--network,設定網路為 dodoro_net
2. 建立第二個PHP-Apache的contaner,也使用相同的 dodoro_net網路
3. 進入website container,ping mysql的container name,在step 1,我把資料庫的container命名為db.
4.在Website的container內。
一、建立一個user-defined網路(這裡我取名叫 dodoro_net )
docker network create --driver bridge dodoro_net
#列出網路指令
docker network ls
二、讓兩個Container在同一個 user-defined 的網路( dodoro_net )中,就可以用container name(容器名稱)ping到彼此
1. 建立第一個資料庫的container,並使用--network,設定網路為 dodoro_net
docker run --network=dodoro_net --name db -e MYSQL_ROOT_PASSWORD=secret -d mysql:5.7.17
2. 建立第二個PHP-Apache的contaner,也使用相同的 dodoro_net網路
docker run --network=dodoro_net -d --name website php:7.1.6-apache
3. 進入website container,ping mysql的container name,在step 1,我把資料庫的container命名為db.
docker exec -ti website bash
4.在Website的container內。
ping db
上方的筆記中有提到,用
docker rm [container id或name]
,可以用來移除停止的 contaiener ,那麼要移除 image 怎麼做呢?
可以用 rmi (就想成 Remove Image 就對囉,要先把停止的相關container移除後,才能移除image哦)
docker rmi [Image ID]
關念再確立
希望您能確實了解,這些指令的用途:docker run (建立並執行container)
docker start (啟動一個或多個停止的containers)
docker exec (在啟動中的container內,執行一個命令)
HELP
如何取得指令的幫助? 例如我們想了解docker start的用法,可以執行如下指令:docker help start
No Comment
Post your comment