本文首發於我的個人網站: https://hewanyue.com/
本文作者: Hechao
本文鏈接: https://hewanyue.com/blog/5c39f4ef.html
安裝完Docker的服務,我們就可以開始使用Docker了。
Docker鏡像
之前我們提到,docker是一個運行容器的工具,可以單獨隔離每個服務的運行環境,達到互不干擾和節約資源的目的。而docker運行的容器,是基於一層一層的鏡像聯合掛載構建而成。所以我們需要先有鏡像。
所謂鏡像,其實可以理解爲,一個個的最簡化的安裝包,裏面只集成了一些必備的程序和文件,且每一層和每一層鏡像是可以相互一樣的,大大的節約了空間,提高了資源利用率。舉個最簡單的例子,我們從官方下載一個centos系統的鏡像包centos:apline,大小才5.55兆,而centos差不多至少200兆了,而centos安裝的ISO鏡像文件也都差不多1G左右。這是因爲容器使用的鏡像系統,需要依賴宿主機內核來運行,容器本身是沒有內核的,只包含一些基礎功能命令而已。可用docker images
查看本地鏡像,從大小來看,就知道容器確實很精簡。
root@DockerUbuntu:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest 965ea09ff2eb 6 weeks ago 5.55MB
centos latest 0f3e07c0138f 2 months ago 220MB
centos 7.6.1810 f1cb7c7d58b7 8 months ago 202MB
我們可以在docker官方鏡像倉庫https://hub.docker.com查看官方鏡像,也可以通過命令直接搜索centos的可用容器
docker search centos
注意:官方倉庫也有很多是個人的鏡像,爲避免未知風險,一定要採用官方鏡像,千萬別使用安全性未知或來源不明的的鏡像。一般排在第一個是官方鏡像。
使用命令docker pull centos
就可以自動從docker官方鏡像倉庫docker.io,下載centos鏡像了,因爲我們沒有指定版本標籤,所以這條命令會默認下載centos:latest
版本,也就是最新版。生產中我們出於穩定性和便於管理,都會推薦使用指定的穩定版本,而不會採用latest版本(,隨着版本髮型,之前的latest版本和幾個月之後的latest版很有可能就不是一個版本,不利於規範化統一)。我們本次以CentOS7.6中的最新版centos:7.6.1810
最爲本次演示的版本。下載鏡像命令如下:
docker pull centos:7.6.1810
使用docker image rm [ OPTION ] 容器ID
可以刪除不要的鏡像,如果已有容器基於此鏡像啓動,則會提示錯誤,無法刪除,需先停止容器,或直接加-f選項
強制刪除鏡像,此時容器也會被停止。注意,當容器被停止時,上面的數據也都會丟失,所以需要謹慎關閉容器和刪除鏡像。
此外,docker官方鏡像站,因爲在國外(美國,不過應該是有CDN或者國內鏡像加速站點的,不過還是有點點慢),肯定不如阿里的容器鏡像倉庫速度快。所以我們可以配置阿里的鏡像加速器,需要註冊阿里賬號。
進入阿里網站http://cr.console.aliyun.com,登陸之後,可以看到阿里的鏡像倉庫(之後再細說)還有鏡像加速器,點擊鏡像加速器,可看到如圖所示界面:
執行將下面代碼,便可實現鏡像加速了。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
之後使用docker info
命令就可以看到已經添加鏡像倉庫成功
Docker容器
有了鏡像之後我們就可以從中運行容器了。基礎的命令有docker pull
、docker push
、docker create
、docker run
、docker ps
、docker rm
、docker start
、docker stop
、docker images
、docker exec
、docker inspect
等等
pull push
root@DockerUbuntu:~# docker pull --help
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from a registry
Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
-q, --quiet Suppress verbose output
docker pull
命令我們之前也使用過,可以用來拉鏡像,相當於命令docker image pull
。根據官方幫助信息,我們可以知道,docker pull
如果要拉去指定版本,需要加:tag
版本標籤,加-a
選項可以拉取所有鏡像,不過生產中一般都是用的時候公司內部的本地鏡像倉庫Harbor,所以拉取鏡像時,格式要跟公司Harbor服務器的IP或者域名,指定拉取鏡像的源倉庫,如果不加,則默認從docker官網拉取。鏡像名稱格式爲:Harbor IP/項目名/image 名字:版本號
docker pull 172.18.32.101/centos/centos-base:v1
使用pull從公司Harbor拉取鏡像時時,需要先在docker啓動文件/lib/systemd/system/docker.service
的ExecStart選項
結尾加入參數--insecure-registry
,表示加入不安全的鏡像倉庫,可加多個,示例如下。
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.32.19 --insecure-registry 192.168.32.20
docker push
是用來推送本地鏡像至倉庫的,相當於命令docker image push
,用法格式與pull相似。不過第一次向鏡像倉庫推送鏡像前,都會需要使用命令docker login +harbor域名
進行登錄。拉取非公開倉庫鏡像前也需要登錄。
tag
root@DockerUbuntu:~# docker tag --help
Usage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
root@DockerUbuntu:~#
docker tag
命令可以用來打標記,格式如上。一般爲了區分不同版本,我們會在每次製作完鏡像後打上不同的標記,而且要分發到不同的鏡像倉庫時也要重新打一個對應倉庫IP/項目名
的鏡像,纔可以push
或pull
。
run
docker run
可以算是最常用的docker基礎命令了,意思是創建並運行容器,相當於docker create
和docker start
的組合。用法格式如下。
docker run [ OPTION ] 鏡像ID [ CMD ]
OPTION
常用選項有-i
、-t
、-d
、-p
、-v
、-e
、--name
、--net
。
-i
,–interactive, Keep STDIN open even if not attached
以交互式方式運行。不過只加-i
是沒法實現交互式的,通常需要-t
參數配合,來給容器加一個僞終端
實現交互式。-t
,–tty, Allocate a pseudo-TTY
給容器分配一個僞終端,與-i
配合使用,通常寫作-it
。-d
,–detach, Run container in background and print container ID
使容器啓動時後臺運行,如果不加這個選項,則會佔據宿主機當前終端,服務類容器等交互式容器一般都會加上這個選項。-p
,–publish, list Publish a container’s port(s) to the host
映射本地端口到容器的指定端口,同時映射多個端口,則寫多個-p 宿主機端口:容器端口
選項。-v
,–volume, list Bind mount a volume
使用-v 參數, 將宿主機目錄映射到容器內部, 默認是可讀寫的。-v SOUCE:DEST:ro
後面加ro
則可實現只讀。-e
,–env, list Set environment variables
可用-e
選項爲容器添加啓動時的環境變量。雖然大多環境變量都是在製作容器時就寫進容器裏,不過此選項應用在環境變量經常變化的場景,方便修改。--name
,Assign a name to the container
給創建的容器命名。同一個宿主機上的容器之間可以通過自定義的容器名稱相互訪問,由於容器在啓動的時候其內部 IP 地址是 DHCP 隨機分配的,所以如果通過內部訪問的話,自定義名稱是相對比較固定的,因此設置容器別名比較適用於此場景。--link
,Add link to another container
爲容器設置一個別名,相當於一個路徑名。自定義的容器名稱可能後期會發生變化, 那麼一旦名稱發生變化,程序之間也要隨之發生變化,比如程序通過容器名稱進行服務調用, 但是容器名稱發生變化之後再使用之前的名稱肯定是無法成功調用, 每次都進行更改的話又比較麻煩, 因此可以使用自定義別名的方式解決,即容器名稱可以隨意更,只要不更改別名即可。--net
爲容器指定網絡。容器網絡類型,常見的爲bridge、host、null,也可以自己創建自定義網絡。可用docker network list
查看當前已有的網絡。
root@DockerUbuntu:~# docker network list
NETWORK ID NAME DRIVER SCOPE
1eb441f702d2 bridge bridge local
241d3e94a6b3 host host local
7cc9cf9eb69e none null local
docker服務安裝完成後,默認在每個宿主機會生成一個名稱爲 docker0 的網卡其 IP 地址都是 172.17.0.1/16,並且會生成三種不同類型的網絡,也就是bridge、host和null,分別代表網橋(橋接)、宿主機網絡和無網絡訪問。
如果不加--net
選項則默認使用bridge,相當於橋接在宿主機的docker0
網卡上。
host
網絡就是指容器使用宿主機網絡,所以端口就不能重複使用,多個使用host網絡的容器間端口也不能重複。
null
網絡指容器只有迴環網卡,沒有外部網卡,無法與外部交流交流,不常使用,適用於某些不需要與外界通信的數據計算或圖形、數據處理服務。
還有一種比較特的類型就是container
模式,就是指定與一個已有容器共享網絡,格式爲--net=container:指定名稱或 ID
。使用此模式創建的容器需指定和一個已經存在的容器共享一個網絡,而不是和宿主機共享網,新創建的容器不會創建自己的網卡也不會配置自己的 IP,而是和一個已經存在的被指定的容器東西 IP 和端口範圍,因此這個容器的端口不能和被指定的端口衝突, 除了網絡之外的文件系統、進程信息等仍然保持相互隔離,兩個容器的進程可以通過 lo 網卡及容器 IP 進行通信。
CMD
docker run
後面跟的CMD表示指定啓動容器的命令,如果不指定,則爲容器默認命令。可用 命令docker inspect 容器ID
查看容器詳細參數查看容器創建時的的CMD。
因爲容器中沒有守護進程systemd,所以進程編號PID=1的根進程,就是我們啓動容器時指定的CMD命令或創建容器設定的默認CMD。如果這個PID=1的守護進程結束,則整個容器就將被關閉。所以我們一般會指定一個可以佔據前臺終端的服務來作爲守護進程,例如bash
或者tail -f /etc/hosts
命令,對於後臺nginx等服務來說,想讓他們作爲守護進程啓動容器,需要將在後臺執行的這個選項關閉
,如nginx可以通過docker run -it -d nginx:alpine nginx -g "daemon off;"
命令,加上-g "daemon off"
選項傳遞參數或者在配置文件中設置daemon off
來關閉後臺執行選項,否則容器啓動就會因爲沒有前臺進程而終止。爲了方便我們修改配置或者重啓服務,企業生產中我們都採用tail -f /etc/hosts
後爲前臺進程,這樣我們進入容器後重啓服務就不受影響了。
ps
root@DockerUbuntu:~# docker ps --help
Usage: docker ps [OPTIONS]
List containers
Options:
-a, --all Show all containers (default shows just running)
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print containers using a Go template
-n, --last int Show n last created containers (includes all states) (default -1)
-l, --latest Show the latest created container (includes all states)
--no-trunc Don't truncate output
-q, --quiet Only display numeric IDs
-s, --size Display total file sizes
docker ps
命令比較簡單,較長使用的參數是-a
、-q
,分別是顯示所有容器(包括爲未運行容器,ps默認只顯示正在運行的容器)和只顯示容器ID。也可以使用docker ps -aq
來顯示所有容器的ID,可配合其他命令如docker rm
命令使用。docker rm -f `docker ps -aq`
刪除本地所有容器(很危險,小心操作!)。
rm
docker rm
命令是用來刪除容器的,如果容器正在運行,使用docker rm
命令刪除時會報錯提示Error response from daemon: You cannot remove a running container XXX. Stop the container before attempting removal or force remove
,告訴我們無法刪除運行中的容器,需要先將容器停止或者強制刪除,使用docker rm -f
命令強制刪除,或者使用下面的停止命令
start stop
docker start 容器ID
啓動容器,可以加選項-i
,表示啓動容器並輸出容器內的標準輸出至宿主機終端。需要注意的是,如果當時用docker run
或者docker create
命令創建容器時,沒有加-it
或-d
等一些其它選項或者參數的話,在start容器這一步也沒法作出更改了的。容器怎麼創建的,啓動時就會按照創建時設定好的模式運行,這些是沒辦法再次修改了的,包括啓動CMD。
docker stop 容器ID
終止容器。需要注意:終止容器時,容器內的數據都將丟失,在備份重要數據之前不要終止容器。
images
docker images
命令其實相當於docker image ls
,顯示本地所有鏡像。docker image CMD
還有很多,之後介紹鏡像管理的時候 在詳細介紹。
exec
docker exec
命令可以向一個已運行容器發送命令。用法如下所示。
[root@DockerCentOS ~]# docker exec --help
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Run a command in a running container
Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container
最常使用的格式是docker exec -it 容器ID bash/sh
,可以進入正在運行的容器。