簡單的說鏡像就是一個容器的只讀模板,用來創建容器。
當運行容器時需要指定鏡像,如果本地沒有該鏡像,則會從 Docker Registry 下載。默認查找的是 Docker Hub。(Docker Hub 是官方提供的公共倉庫)
Docker 的鏡像是增量的修改,每次創建新的鏡像都會在老的鏡像上面構建一個增量的層,使用到的技術是Another Union File System(AUFS)。
比如一個鏡像名稱 ubuntu:14.04,冒號前面的 ubuntu 是倉庫名,后面的 14.04 是 TAG,不同的 TAG 可以對應相同的鏡像,TAG 通常設置為鏡像的版本號。
如果不加 TAG,這時 Docker 會使用默認的 TAG:latest。
鏡像管理涉及到下面的命令:
一、查看鏡像列表
# Management Commands $ docker image ls +[鏡像名稱] # 舊的命令格式如下: $ docker images
舉例
[root@TBEARZ206458 ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 72300a873c2c 10 days ago 64.2MB busybox latest 6d5fcfe5ff17 2 months ago 1.22MB hello-world latest fce289e99eb9 14 months ago 1.84kB [root@TBEARZ206458 ~]# docker image ls ubuntu REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 72300a873c2c 10 days ago 64.2MB
二、查看鏡像詳細信息
上一個文檔中也有 docker inspect 命令,它可以用來查看容器的信息,也可以用來查看鏡像的信息 (查看元數據信息)
$ docker image inspect ubuntu # 舊的命令格式如下: $ docker inspect ubuntu
舉例
[root@TBEARZ206458 ~]# docker image inspect ubuntu | grep Last "LastTagTime": "0001-01-01T00:00:00Z"
三、搜索鏡像
$ docker search ubuntu
例如上面的命令執行之后
[root@TBEARZ206458 ~]# docker search ubuntu NAME DESCRIPTION STARS OFFICIAL AUTOMATED ubuntu Ubuntu is a Debian-based Linux operating sys… 10575 [OK] dorowu/ubuntu-desktop-lxde-vnc Docker image to provide HTML5 VNC interface … 398 [OK] rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 243 [OK] consol/ubuntu-xfce-vnc Ubuntu container with "headless" VNC session… 211 [OK] ubuntu-upstart Upstart is an event-based replacement for th… 105 [OK] ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ansible 98 [OK]
其中:
1、Official Images指docker標准庫, 由docker 官方建立.
2、用戶建立的image則會有userid的prefix.
3、automated builds 則是通過代碼版本管理網站結合docker hub提供的接口生成的, 例如github, bitbucket,
你需要注冊docker hub, 然后使用github或bitbucket的在賬戶鏈接到docker hub, 然后就可以選擇在github或bitbucket里面的項目自動build docker image, 這樣的話只要代碼版本管理網站的項目有更新, 就會觸發自動創建image.
四、拉取鏡像
Registry中獲得鏡像或者倉庫的命令
# Management Commands $ docker image pull [OPTIONS] NAME[:TAG|@DIGEST] # 舊的命令格式如下: $ docker pull [OPTIONS] NAME[:TAG|@DIGEST]
比較常用的配置參數為 -a,代表下載倉庫中的所有鏡像,即下載整個存儲庫。
Name不僅可以指定Tag,也可以通過摘要(DIGEST)來進行拉取不同的鏡像。我們可以查看鏡像信息
舉例:拉取Ubuntu 14.04版本鏡像
[root@TBEARZ206458 ~]# docker image pull ubuntu:14.04 14.04: Pulling from library/ubuntu 2e6e20c8e2e6: Pull complete 30bb187ac3fc: Pull complete b7a5bcc4a58a: Pull complete Digest: sha256:ffc76f71dd8be8c9e222d420dc96901a07b61616689a44c7b3ef6a10b7213de4 Status: Downloaded newer image for ubuntu:14.04 docker.io/library/ubuntu:14.04
對於 pull 下來的鏡像來說,其默認的保存路徑為 /var/lib/docker。因為這里的存儲驅動為 aufs,所以具體路徑為 /var/lib/docker/aufs。
五、構建鏡像
對於我們 pull 的新鏡像 ubuntu:14.04 來說,如果我們需要對其進行更新,可以創建一個容器,在容器中進行修改,然后將修改提交到一個新的鏡像中。
# Management Commands $ docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] # 舊的命令格式如下: $ docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
該命令的解釋為從一個容器的修改中創建一個新的鏡像。例如,我們運行一個容器,然后在其中創建一個文件,最后使用 commit 命令。
舉例: 我們創建一個busybox的容器,里面添加兩個文件file1和file2,然后將其提交到一個新的鏡像中。
[root@TBEARZ206458 ~]# docker container run --name MyNewBusyBox -it busybox /bin/sh / # touch file1 file2
ctrl+p+q 后台運行
檢查一下是否創建
[root@TBEARZ206458 ~]# docker container diff MyNewBusyBox A /file1 A /file2 C /root A /root/.ash_history
創建一個新的鏡像
[root@TBEARZ206458 ~]# docker container commit MyNewBusyBox busybox busybox:latest hello-world hello-world:latest ubuntu ubuntu:14.04 ubuntu:latest [root@TBEARZ206458 ~]# docker container commit MyNewBusyBox busybox:mynew sha256:9d1d031bfd1efe1adaf7db123c30f974647e165899c3d3fd179df0c0c3a41631 [root@TBEARZ206458 ~]# docker image ls busybox REPOSITORY TAG IMAGE ID CREATED SIZE busybox mynew 9d1d031bfd1e 15 seconds ago 1.22MB busybox latest 6d5fcfe5ff17 2 months ago 1.22MB
通過上述操作我們創建了一個新的鏡像,但是本方法不推薦用在生產系統中,未來會很難維護鏡像。最好的創建鏡像的方法是 Dockerfile,修改鏡像的方法是修改 Dockerfile,然后重新從 Dockerfile 中構建新的鏡像。
構建 BUILD
docker 可以從一個 Dockerfile 文件中自動讀取指令構建一個新的鏡像。 Dockerfile 是一個包含用戶構建鏡像命令的文本文件。
docker image build [OPTIONS] PATH | URL
構建鏡像時,該過程的第一件事是將 Dockerfile 文件所在目錄下的所有內容遞歸的發送到守護進程。所以在大多數情況下,最好是創建一個新的目錄,在其中保存 Dockerfile,並在其中添加構建 Dockerfile 所需的文件。
DockerFile的基本語法:略
舉例:安裝一個擁有dotnet core環境的centos,並運行事例代碼。
預備工作:先創建一個dotnetCoreweb程序,然后通過FTP上傳到Linux服務器上
我是放在了/home/lic/dockerfiledir 文件夾下
[root@TBEARZ206458 dockerfiledir]# ll drwxr-xr-x 3 root root 4096 Mar 4 17:23 DotnetWebDemo
①在該文件夾下創建一個DockerFile
備注:這里我使用的是3.1版本的dotnetcore,注意下鏡像的倉庫位置,我在試驗過程中遇到了版本不一致的問題,主要是拉取的鏡像不能支持啟動的dotnet程序
It was not possible to find any compatible framework version
如果是1.0-2.x 可以使用 microsoft/aspnetcore 這是鏡像倉庫地址,從圖上也可以看到,這是一個過時的地址。
如果是3.0以上的可以使用下面的地址: https://hub.docker.com/_/microsoft-dotnet-core-aspnet/
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 MAINTAINER licheng_cumt@163.com # 容器暴露的端口 EXPOSE 5000 # 把當前目錄內容拷貝到容器的home目錄 COPY . /home # 設置工作目錄 WORKDIR /home # 啟動程序 ENTRYPOINT ["dotnet", "DotnetWebDemo/DotnetWebDemo.dll"]
② Builde一下鏡像,大概過程如下
[root@TBEARZ206458 dockerfiledir]# docker image build -t centosdotnet:1.0.0 . Sending build context to Docker daemon 344.6kB Step 1/6 : FROM docker.io/microsoft/dotnet ---> 56a634b88a04 Step 2/6 : MAINTAINER licheng_cumt@163.com ---> Running in f915b73424fc Removing intermediate container f915b73424fc ---> 690e1fe5200d Step 3/6 : EXPOSE 5000 ---> Running in 8befbf97b8c1 Removing intermediate container 8befbf97b8c1 ---> d50f54877f3b Step 4/6 : COPY . /home ---> 54953a90f171 Step 5/6 : WORKDIR /home ---> Running in ddab8f58d279 Removing intermediate container ddab8f58d279 ---> 7accfc7efc5b Step 6/6 : ENTRYPOINT ["dotnet", "DotnetWebDemo/DotnetWebDemo.dll"] ---> Running in 4a6d400603b2 Removing intermediate container 4a6d400603b2 ---> 12291ac40ff3 Successfully built 12291ac40ff3 Successfully tagged centosdotnet:1.0.0
查看一下鏡像
[root@TBEARZ206458 dockerfiledir]# docker image ls -a REPOSITORY TAG IMAGE ID CREATED SIZE centosdotnet 1.0.0 547d7924e8d2 21 minutes ago 208MB <none> <none> b81319ea9700 21 minutes ago 208MB <none> <none> fab8ef06bcba 21 minutes ago 208MB <none> <none> fc5b570e7e66 21 minutes ago 207MB <none> <none> 252cd9849401 21 minutes ago 207MB microsoft/dotnet-nightly latest 437f8c6bee32 37 hours ago 1.74GB busybox mynew 9d1d031bfd1e 3 days ago 1.22MB microsoft/dotnet latest 56a634b88a04 8 days ago 1.74GB mcr.microsoft.com/dotnet/core/aspnet 3.1 e2cd20adb129 8 days ago 207MB ubuntu latest 72300a873c2c 13 days ago 64.2MB centos latest 470671670cac 6 weeks ago 237MB busybox latest 6d5fcfe5ff17 2 months ago 1.22MB ubuntu 14.04 6e4f1fe62ff1 2 months ago 197MB hello-world latest fce289e99eb9 14 months ago 1.84kB microsoft/aspnetcore latest db030c19e94b 18 months ago 347MB
上面的none應該是和centosdotnet鏡像一起build之后出現的。
③啟動鏡像
[root@TBEARZ206458 dockerfiledir]# docker run -it -p 8080:80 centosdotnet:1.0.0 warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60] Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0] User profile is available. Using '/root/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest. info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58] Creating key {4cb11721-8b0e-48f9-9749-a17abe7ec075} with creation date 2020-03-06 02:38:36Z, activation date 2020-03-06 02:38:36Z, and expiration date 2020-06-04 02:38:36Z. warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35] No XML encryptor configured. Key {4cb11721-8b0e-48f9-9749-a17abe7ec075} may be persisted to storage in unencrypted form. info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39] Writing data to file '/root/.aspnet/DataProtection-Keys/key-4cb11721-8b0e-48f9-9749-a17abe7ec075.xml'. info: Microsoft.Hosting.Lifetime[0] Now listening on: http://[::]:80 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Production info: Microsoft.Hosting.Lifetime[0] Content root path: /home
這里主要是端口問題需要注意一下,一開始我也不理解
使用 -p 參數時,可以指定要映射的端口,並且在一個指定的端口上只可以綁定一個容器。支持的格式有:
1. IP:HostPort:ContainerPort
2. IP:ContainerPort
3. HostPort:ContainerPort
例如: docker run -d -p 8080:80 nginx
本地主機的 8080 端口被映射到了容器的 80 端口,通過localhost:8080就可以訪問容器的80的nginx歡迎頁面
驗證一下上面的操作:訪問一些 http://localhost:8080 就返回了一些信息
備注:這里我在部署程序之后,發現了一個問題,就是我 .net 程序能訪問通,但是所有的靜態文件訪問失敗了。
此問題的原因:在於剛剛那個DockerFile,里面這兩行
# 設置工作目錄 WORKDIR /home # 啟動程序 ENTRYPOINT ["dotnet", "DotnetWebDemo/DotnetWebDemo.dll"]
本意是在docker的 home目錄下 執行 dotnet DotnetWebDemo/DotnetWebDemo.dll 命令 以啟動站點,結果是站點的確啟動了,但是程序的啟動目錄也是/home
這時候,實際上我的wwwroot文件夾並不在該目錄下面,所以就會報錯。
兩種解決辦法
1.移動wwwroot目錄到/home下,重啟容器
2.編輯DockerFile,重新打一下鏡像,修改工作目錄如下:
# 設置工作目錄 WORKDIR /home/DotnetWebDemo //這里改一下 # 啟動程序 ENTRYPOINT ["dotnet", "DotnetWebDemo.dll"] //這里改一下
六、刪除鏡像
我們刪除 ubuntu:latest 鏡像就可以使用如下命令:需要注意的是,如果該鏡像正在被一個容器所使用,需要將容器刪除才能成功的刪除鏡像。
# Management Commands $ docker image rm ubuntu:latest # 舊的命令格式如下: $ docker rmi ubuntu:latest