一、Docker的架構和底層技術
1.Docker Platform(平臺)
- Docker提供了一個開發、打包、運行App(應用application)的平臺
- 把app和底層infrastructure(基礎設備)隔離開來
2.Docker Engine
2.1 組成
- 后臺進程(dockerd)
- 用于一些后臺的操作,如image、container、網絡及存儲的管理
- REST API Server
- 用于dockerd和docker之間通信的接口服務
- CLI接口(docker)運行docker version命令是顯示的client 版本和server engine版本,client和server之間是一個cs架構的
- 運行docker version命令可以看到客戶端版本與服務端engine版本,查找docker進程可以看到后臺是執行的dockerd進程
3.Docker Architecture(架構)
4.底層技術支持
Namespaces:做隔離pid?.NET、ipc、mnt、uts
Control groups:做資源限制
Union file systems:Container和image的分層
二、Docker Image(鏡像)
1.概述
- 文件和meta data的集合(root filesystem)
- 分層的,并且每一層都可以添加改變刪除文件,成為一個新的image
- 不同的image可以共享相同的layer(層)
- image本身是read-only(只讀)
- 查看本地存在的image
docker image ls
2.獲取image的第一種方式
Build from Dockerfile
Docker提供一個配置文件Dockerfile,就好比之前博主使用Vagrant工具時的Vagrantfile文件一樣,通過Dockerfile文件就可以去定義一個docker image鏡像,build這個dockerfile文件就可以構建出一個image鏡像
- 在cdtaogang目錄下創建dockerfile文件,內容如下
- 執行docker build命令進行構建鏡像,-t 鏡像名稱,后面的.是表示當前dockerfile路徑
docker build -t cdtaogang123/redis:latest .
- 提示如下超時,docker安裝后默認沒有daemon.json這個配置文件,需要進行手動創建,配置文件的默認路徑:/etc/docker/daemon.json,在阿里云中復制加速器地址,進行添加
{
"registry-mirrors": ["https://xxxxxx.mirror.aliyuncs.com"]
}
- 重啟生效
sudo systemctl daemon-reload
sudo systemctl restart docker
- 再次build構建,顯示成功
- 在執行build構建時,dockerfile文件中每一行代碼都表示一個步驟,一共有7行代碼,所以build時,會顯示執行這7個步驟
- 此時查看本地image鏡像就可以看到以上創建的鏡像了
3.獲取image的第二種方式
Pull from Registry
類似github 倉庫,可以git clone拉取倉庫的文件,也可以將文件push到倉庫中,那么docker pull則是在docker hub上去拉取你要的鏡像
- 在docker hub網站上查看image基礎鏡像
- 如點擊centos進入后,選擇tags標簽,可以看到很多版本的centos鏡像,對應有拉取命令
- 博主拉取一個centos8鏡像,鏡像名后面不跟版本則表示拉取latest最新的
docker pull centos:centos8
- 除了官方提供的images鏡像外,還有第三方的鏡像(個人的或者公司的),比如搜索wordPress/ target=_blank class=infotextkey>WordPress第一個標記Official的則表示官方提供的,如下這種用戶名/wordpress的image則表示是個人或者公司的
- 拉取這個人的wordpress images,由于文件比較多,博主這里就不繼續下載了
4.如何制作一個Base Image
- 說明一點,博主之前在執行docker命令時是在root用戶下執行的,如博主exit退出root用戶,使用cdtaogang用戶那么每次執行命名docker命令都需要加上sudo就比較麻煩,不添加sudo則會提示權限不夠
- 將當前cdtaogang用戶添加到docker用戶組中,然后重啟docker服務,執行docker image ls命令結果還是提示權限不夠
- 原因是,需要xshell重新遠程連接centos即可
- 回到正軌,之前博主在centos虛擬機中安裝docker時,拉取過hello-world基礎鏡像,在這個base image中其實存在一個可執行文件,通過docker run 執行這個hello-world基礎鏡像就會創建一個容器并運行這個容器,打印出如下hello from docker這一段話
- 現在就模擬hello-world做一個基礎鏡像,就需要hello world程序,可以通過C語言編寫一個hello world 將這個hello world編譯成一個可執行的二進制文件
mkdir hello-world
cd hello-world
vi hello.c
- 編譯c語言腳本,需要安裝gcc
sudo yum install gcc
sudo yum install glibc-static
- 編譯hello.c文件輸出為hello可執行文件,執行hello文件,成功打印
- 通過dockerfile把這個可執行文件打成docker image,在hello-world目錄創建dockerfile文件,因為是我們自己創建基礎鏡像,所以FROM字段不以任何鏡像為基礎,寫法為FROM scratch,之前創建的dockerfile文件中FROM字段指定以ubuntu:14.04為基礎鏡像,具體配置如下
- 構建dockerfile文件,生成tag為cdtaogang/hello-world的image
- 對比cdtaogang/hello-world鏡像與hello-world文件中的hello可執行文件大小,差距很小,幾乎是基于hello可執行文件的大小下創建的image
- 通過docker history <image id>,查看構建的cdtaogang/hello-world鏡像的分層情況,第一層是執行hello文件,第二層這是添加文件到指定路徑,因為FROM 沒有指定基礎鏡像所以該層不顯示
- 創建并執行容器
三、Container(容器)
1.什么是Container
- 通過Image創建(copy)
- 在Image layer之上建立一個container layer(可讀寫)
- 類比面向對象:類(image)和實例(container)
- Image負責app的存儲和分發,Container負責運行app
2.運行容器
- 執行docker container ls命令可以查看當前正在運行的容器,目前是沒有容器正在運行,因為執行docker run命令后,創建并運行容器后,會退出,那么通過docker container ls -a命令列舉出來所有的容器包括運行或者退出的,可以到看到cdtaogang/hello-world鏡像創建的容器是已退出狀態
- 創建并運行centos:centos8鏡像的容器,同理也是在容器運行后就自動退出了
3.交互式運行容器
- 在docker run 添加-it交互式運行命令,可以看到命令運行成功會進入到一個系統里面
- 在另一個終端中,執行docker container ls就能看到我們剛交互式運行的容器沒有退出,可以發現上面進入的系統其實就是容器的ID,所以交互式運行容器就是指創建并進入到容器中
- 在容器中,因為鏡像是centos的,所以可以執行yum命令
- 那么退出容器,在執行docker container ls命令查看正在運行的容器則不會顯示該容器了,而執行docker container ls -a 則會顯示剛剛退出的容器
4.Docker和Docker Image簡寫命令及Container命令
- 首先在命令行輸入docker回車,查看docker所有命令,可見分為Management Commands(管理命令)和Commands(命令)
- 查看正在運行的容器及所有的容器
docker container ls >> docker ps
docker container ls -a >> docker ps -a
- 比如刪除一個容器,使用docker container rm命令,可以輸入docker container命令回車,查看能執行的命令
- 刪除容器簡寫命令,因為docker rm命令默認是刪除容器所以可以直接用
docker container rm >> docker rm
- 執行docker rm container id,這個id可以不寫全,但是需要保證你輸入的簡寫id是唯一的
- 輸入docker image查看可以執行的命令
- 查看所有的image鏡像
docker image ls >> docker images
- 刪除鏡像
docker image rm >> docker rmi
- 一次性刪除所有的容器,首先運行5個容器,然后查看所有的容器(已退出)
- 首先通過docker ps -aq 列舉出所有的容器ID
docker ps -aq
- 然后直接rm命令刪除列舉出所有的容器ID來刪除所有容器,需要使用$將以上命令當成一個結果進行刪除
docker rm $(docker ps -aq)
- 如果所有的容器中存在正在運行的容器以及已退出的容器,我只刪除已退出的容器,這種場景如何實現
- 實現以上的場景,首先需要獲取到所有容器中已退出的容器ID,通過-f 篩選出容器狀態status=exited已退出的容器,加上-q參數則表示列舉出容器ID,最后$包住結果,執行docker rm刪除即可,成功實現只刪除已退出的容器
四、構建自己的Docker Image
1.docker container commit(docker commit)
1.1 交互式運行容器
- 交互式運行centos容器,在容器中并沒有安裝vim命令,進行安裝vim工具
- exit退出容器,查看所有容器,顯示交互式運行的容器已退出
1.2 將容器commit成一個image
說明:上一步在容器中安裝了vim并退出了容器,那么在已退出的容器中可以看到該容器,現在則需要將這個容器commit成一個鏡像,這個鏡像是基于centos8基礎鏡像的,但是跟centos8基礎基礎鏡像不一樣的是它安裝了vim
- 通過docker container commit命令實現將容器提交成image,命令可以簡寫成docker commit
- 執行如下命令,生成image鏡像,
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
docker commit stupefied_fermat cdtaogang/centos-vim:centos8
- 查看生成的image
- 對比基礎image和自己構建的image分層情況,很明顯比基礎centos8鏡像多了一層,那就是安裝vim命令
以上創建image的方式不提倡使用,因為如果發布該image,用戶拿到該image是不知道該image是如何構建的,并且這種方式構建image很有可能把不安全的東西放到image里面發布出去,即該image肯定是不安全的
2.docker image build(docker build)
2.1 創建dockerfile
- 首先將上一步中commit容器生成的image刪除
- 在上一級目錄下創建一個目錄,進入目錄創建并編輯dockerfile文件
- dockerfile內容如下,指定基礎鏡像為centos:centos8版本,在基礎鏡像中運行安裝vim命令
2.2 通過dockerfile構建出image
- 執行docker build命令以當前路徑下的dockerfile構建出
- 查看構建的image
通過dockerfile構建鏡像和commit容器生成的鏡像差不多,但建議使用dockerfile構建image,這樣的話只需要分享dockerfile這個文件給別人就可以了,別人通過你分享的dockerfile文件就能構建出跟你一樣的image