docker有三大核心元件:1、映象(Image),一個Linux的檔案系統;2、容器(Container),映象的執行時範例;3、倉庫(Repository),集中儲存映象的地方。
本教學操作環境:linux5.9.8系統、docker-1.13.1版、Dell G3電腦。
Docker的三大核心元件
映象(Image)
容器(Container)
倉庫(Repository)
什麼是Docker映象?
簡單地理解,Docker映象就是一個Linux的檔案系統(Root FileSystem),這個檔案系統裡面包含可以執行在Linux核心的程式以及相應的資料。
談到這裡,我們可能需要先補充一點與Linux作業系統相關的知識:
一般而言, Linux分為兩個部分:Linux核心(Linux Kernel)與使用者空間,而真正的Linux作業系統,是指Linux核心,我們常用的Ubuntu、CentOS等作業系統其實是不同廠商在Linux核心基礎上新增自己的軟體與工具集(tools)形成的釋出版本(Linux Distribution)。
因此,我們也可以把映象看成是上面所說的使用者空間,當Docker通過映象建立一個容器時,就是將映象定義好的使用者空間作為獨立隔離的程序執行在宿主機的Linux核心之上。
這裡要強調一下映象的兩個特徵:
映象是分層(Layer)的:即一個映象可以多箇中間層組成,多個映象可以共用同一中間層,我們也可以通過在映象新增多一層來生成一個新的映象。
映象是唯讀的(read-only):映象在構建完成之後,便不可以再修改,而上面我們所說的新增一層構建新的映象,這中間實際是通過建立一個臨時的容器,在容器上增加或刪除檔案,從而形成新的映象,因為容器是可以動態改變的。
通過下面的示意圖,我可以更好地理解Docker映象與Linux的關係:
操作映象的命令
Docker中與映象操作相關的命令都在docker image這條子命令下,通過docker image --help這條命令,可以看到docker image子命令的詳細檔案,如下:
Usage: docker image COMMAND Manage images Commands: build Build an image from a Dockerfile(構建映象的命令) history Show the history of an image(顯示映象構建歷史過程) import Import the contents from a tarball to create a filesystem image(匯入一個由容器匯出的映象) inspect Display detailed information on one or more images(顯示一個映象的詳細資訊) load Load an image from a tar archive or STDIN(從一個檔案或標準輸入流中匯入映象) ls List images(檢視映象列表) prune Remove unused images(刪除虛懸映象) pull Pull an image or a repository from a registry(從倉庫拉取映象) push Push an image or a repository to a registry(推播映象到倉庫) rm Remove one or more images(刪除映象) save Save one or more images to a tar archive(streamed to STDOUT by default)(儲存映象到檔案) tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE(給映象打標籤)
獲取映象
在安裝了Docker之後,我們本地並沒有任何映象,當然我們可以自己構建,不過更方便還是從Docker官方提供的倉庫服務Docker Hub上拉取官方或第三方已經構建好的映象。
拉取映象可以使用docker image pull,其格式如下:
docker image pull [OPTIONS] NAME[:TAG|@DIGEST]
當然,docker image pull有更簡潔的用法:如:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
要拉取映象,需要指定Docker Registry的URL和埠號,預設是Docker Hub,另外還需要指定倉庫名和標籤,倉庫名和標籤唯一確定一個映象,而標籤是可能省略,如果省略,則預設使用latest作為標籤名,而倉庫名則由作者名和軟體名組成。
所以,在省略了那麼引數後,比如我們想拉取centos映象,可以使用下面簡單的命令從Docker Hub上拉到:
$ docker pull centos
檢視本地映象
通過上面的方法我們將映象拉取到了本地,那要如何檢視本地有哪些映象呢?通過下面的命令我們可以檢視原生的全部映象:
$ docker image ls
當然Docker提供了更簡潔的寫法,如下:
$ docker images
虛懸映象
我們知道Docker映象名由倉庫名和標籤組成,但有時候我們會看到倉庫名和標籤皆為<none>的映象,我們稱為這種映象為虛懸映象,如下圖所示:
虛懸映象一般是當我們使用docker pull拉取最新映象時,生成的新的映象,所以倉庫名和標籤給了新的映象,舊的映象倉庫和標籤則被取消,成為虛懸映象。
我們可以使用下面的語句列印所有的虛懸映象:
$ docker image ls -f dangling=true
一般的虛懸映象已經沒有什麼作用了,所以可以清理掉的,下面的命令可以清除所有的虛懸映象:
$ docker image prune
不過,如果我們想保留一些有用的虛擬映象時,可以使用docker tag命令重新給映象起個倉庫名和標籤:
$ docker tag 621d57f27e93 "test:1.0"
映象匯出與匯入
如果想與別人共用某個映象,除了從映象服務倉庫中pull映象和把映象push到倉庫上去之外,其實我們還可以將本地構建好的映象直接匯出並儲存為檔案傳送給別人,如下:
$ docker image save /tmp/test_image.tar.gz
而當你拿到別人匯出的映象檔案,你可以使用docker load命令把映象載入到原生的Docker映象列表中,如下:
$ docker load < /tmp/test_image.tar.gz
刪除本地映象
要刪除一個或多個原生的映象,可以使用下面的命令:
docker image rm [option] IMAGE1,IMAGE2,...IMAGEn
也可以使用更簡潔的方式,如:
docker rmi [option] IMAGE1,IMAGE2,...IMAGEn
可以使用映象的長ID、映象短ID、映象摘要以及映象名稱來刪除映象,如下:
$ docker rmi f7302e4ab3a8
一般更常用映象的短ID,如:
$ docker rmi f7302
使用映象的摘要也可以刪除映象,映象的摘要可以使用下面的命令查詢:
$ docker image ls --digests
當然我們想要清除本地全部映象時,可以使用下面的命令,不過一般不建議使用。
$ docker rmi $(docker images -qa)
另外,一般如果映象已經被使用來建立容器,使用上面的命令刪除會報下面的錯誤,告訴我們該映象已經被使用,不允許刪除。
Error response from daemon: conflict: unable to remove repository reference "mysql:5.7" (must force) - container ccd406c07a78 is using its referenced image e1e1680ac726
對於已經被用於建立容器的映象,刪除方法有兩種,一種是先把容器刪除,再刪除映象,另一種則只需要在刪除映象的命令中跟一個-f引數便可,如:
$ docker rim -f f7302
使用docker commit構建映象
上面的例子都是直接使用官方提供的映象,其實,除了從官方倉庫或其他映象倉庫拉取別人構建好的映象外,我們也可以構建自己的映象,一般有以下兩種構建方式。
使用docker commit命令,我們可以將修改過的容器重新提交為一個映象,如:
$ docker commit conntaner_id my-hello:1.0
使用這種方式構建的映象,我們稱為黑箱映象,就是一個黑箱子一樣,別人並不知道我們對容器做了哪些修改和操作,所以會對其安全性有所質疑。
所以不推薦使用這種方式構建映象,下面我們介紹一種更加通用且方便的方式。
使用Dockerfile構建映象
一般推薦編寫Dockerfile來構建一種映象,Docker Hub上的映象都是採用這種方式構建的,採用這種方式的好處就是,我們不用把映象分發給別人,而只是把Dockerfile和相應需要寫入映象的資料發給別人,別人也能自己構建映象,安全透明。
編寫一個簡單的Got程式
package main import "fmt" func main(){ fmt.Println("Hello Go") }
將Go程式編譯為可執行程式,如:
$ go build hello.go
編寫Dockerfile檔案
下面我們編寫一個簡單的Dockerfile檔案,構建自己的第一個映象,如下:
# 從一個空白的映象開始 FROM stratch ADD hello / # 執行 CMD /hello
開始構建映象
編寫好Dockerfile檔案後,需要使用docker build命令進行構建,docker build命令的格式如下:
$ docker build [OPTIONS] PATH | URL | -
# 注意最後的點(.)表示當前目錄,即Dockerfile所在的目錄 $ docker build -t "hello-go:1.0" .
上面只是簡單演示了使用Dockerfile檔案如何構建映象,關於Dockerfile,還有許多更加深入地用法,我們之後有機再談。
容器與映象的關係,就如同面向程式設計中物件與類之間的關係。
因為容器是通過映象來建立的,所以必須先有映象才能建立容器,而生成的容器是一個獨立於宿主機的隔離程序,並且有屬於容器自己的網路和名稱空間。
我們前面介紹過,映象由多箇中間層(layer)組成,生成的映象是唯讀的,但容器卻是可讀可寫的,這是因為容器是在映象上面添一層讀寫層(writer/read layer)來實現的,如下圖所示:
Usage: docker container COMMAND Manage containers Commands: attach Attach local standard input, output, and error streams to a runnin g container commit Create a new image from a container's changes(把容器儲存為映象) cp Copy files/folders between a container and the local filesystem create Create a new container(建立一個新的容器) diff Inspect changes to files or directories on a container's filesyste m exec Run a command in a running container(在一個執行的容器中執行命令) export Export a container's filesystem as a tar archive inspect Display detailed information on one or more containers kill Kill one or more running containers(殺死一個或多個正在執行的容器) logs Fetch the logs of a container ls List containers(顯示本地容器列表) pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container prune Remove all stopped containers rename Rename a container(重新命名容器) restart Restart one or more containers(重新啟動一個或多個容器) rm Remove one or more containers(刪除一個或多個容器) run Run a command in a new container(執行一個新的容器) start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers(停止一個或多個容器) top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers wait Block until one or more containers stop, then print their exit codes
啟動容器
啟動容器有幾種不同的方式,最常用的方法是使用docker run命令可以通過映象建立一個容器,如:
# /bin/bash表示執行容器後要執行的命令 $ docker run -it centos /bin/bash
docker run命令有一些比較常用的引數,比如容器是一種提供服務的守護行程,那麼通常需要開放埠供外部存取,如:
$ docker run -p 80:80 nginx
也可以為容器指定一個名稱,如:
$ docker run -p 80:80 --name webserver nginx
另外一種則是使用docker start命令重新啟動已經停止執行的容器,如:
# container_id表示容器的id $ docker start container_id
而對於正在執行的容器,也可以通過docker restart命令重新啟動,如:
# container_id表示容器的id $ docker restart container_id
檢視本地容器列表
執行容器後,我們可以通過下面的命令檢視本地所有容器:
$ docker container ls
不過docker container ls也簡潔的寫法:
$ docker ps
上面命令執行結果如下:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f4f184f5ffb9 redis:latest "docker-entrypoint.s…" 6 seconds ago Up 4 seconds 0.0.0.0:6379->6379/tcp myredis f7d970e7d4ce mysql:5.7 "docker-entrypoint.s…" 7 seconds ago Up 5 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp docker-mysql
上面的命令只會顯示正在執行的容器,如果要顯示全部容器,包含退出執行的,可以加引數-a,如:
$ docker ps -a
有時候,我們只想查到容器的ID,可以用下面的命令:
$ docker ps -aq
執行結果:
f4f184f5ffb9 f7d970e7d4ce
停止容器
對於已經不需要的容器,可以使用docker stop命令停止其執行,如:
$ docker stop container_id1,container_id2...
批次停止容器,如:
$ docker stop $(docker ps -qa)
容器的三種執行模式
概括而言,Docker容器大體上有三種執行模式,如下:
執行後退出
下面語句建立的容器,在執行後會退出。
$ docker run centos echo "hellowrold"
常駐記憶體,就是守護行程的模式
如果容器中執行一個守護行程,則容器會一直處於執行狀態,如:
$ docker run -d -p 80:80 nginx
互動式
我們也可以在執行容器時,直接與容器互動。
$ docker run -it centos /bin/bash
刪除容器
$ docker container rm container_id
刪除容器的命令也有簡潔的寫法,如下:
$ docker rm container_id
也可以像上面批次停止容器一樣,我們也可以批次刪除容器,如:
$ docker rm $(docker ps -qa)
進入容器
對於正在執行的容器,我們也可以通過docker exec命令再次進入容器,如:
$ docker exec -it f4f184f5ffb9 /bin/bash
需要指定容器的id或name,上面的命令我們用的是ID。
匯出容器為映象
$ docker export -o ./image.tar.gz f4f184f5ffb9
將容器匯出後,我們可以另外一臺有安裝Docker的電腦中將檔案包匯入成為映象,如:
$ docker import image.tar.gz
上面講的是容器的概念和一些常用的命令,關於容器,還可以設定資料卷和網路空間,這些我們有機會後面再談。
倉庫(Repository)是集中儲存映象的地方,這裡有個概念要區分一下,那就是倉庫與倉庫伺服器(Registry)是兩回事,像我們上面說的Docker Hub,就是Docker官方提供的一個倉庫伺服器,不過其實有時候我們不太需要太過區分這兩個概念。
公共倉庫
公共倉庫一般是指Docker Hub,前面我們已經多次介紹如何從Docker Hub獲取映象,除了獲取映象外,我們也可以將自己構建的映象存放到Docker Hub,這樣,別人也可以使用我們構建的映象。
不過要將映象上傳到Docker Hub,必須先在Docker的官方網站上註冊一個賬號,註冊介面如下,按要求填寫必要的資訊就可以註冊了,很簡單的。
註冊好了之後,可以在本地使用命令登入到Dokcer Hub了,過程如下:
# 在命令列中輸入 $ docker login
在輸入賬號密碼登入到Docker Hub之後,便可以使用docker push命令把映象推播到Docker Hub。
$ docker push test:1.0
私有倉庫
有時候自己部門內部有一些映象要共用時,如果直接匯出映象拿給別人又比較麻煩,使用像Docker Hub這樣的公共倉庫又不是很方便,這時候我們可以自己搭建屬於自己的私有倉庫服務,用於儲存和分佈我們的映象。
Docker官方提供了registry這個映象,可以用於搭建私有倉庫服務,我們把映象拉到本地之後,用下面命令建立該映象的容器便可以搭建一個倉庫服務,如下:
$ docker run -d -p 5000:5000 --restart=always --name registry registry
假設我們把一臺IP為192.168.0.100的伺服器作為倉庫服務,並執行上面的語句,那麼我們可以下面的語句重新構建上面的映象,如:
$ docker build -t "192.168.0.100/hello-go:1.0" .
然後使用下面的語句推播到自己的私有倉庫伺服器:
$ docker push 192.168.0.100/hello-word:1.0
映象是靜態的概念,構建完成之後便不能再修改,而容器則是一個動態的概念,使用Docker可以簡單輕鬆地建立或刪除容器,映象與容器的關係,就如同物件導向程式設計中的類與物件的關係,而倉庫則是儲存和分發映象的地方。
推薦學習:《》
以上就是docker的核心元件有哪些的詳細內容,更多請關注TW511.COM其它相關文章!