上2节,主要介绍了docker和Kubernetes的安装,并用dockerhub自带的测试镜像完成了初步体验。
那么,本节的话,主要通过一个.NET Core项目构建自己的镜像,并用该镜像深入学习一下docker镜像和容器的管理,以为下节docker的容器编排打下基础。(什么项目都没有关系,主要的是理解这个过程)
你将了解如何:
- 创建并发布简单的 .NET Core 应用
- 创建并配置用于 .NET Core 的 Dockerfile
- 生成 Docker 映像
- 创建并运行 Docker 容器
动手构建自己的第一个镜像
应用创建
我们这里就直接写一个简单的控制台程序吧,进入你要放项目的路径,不设置的话是默认路径,然后执行
dotnet new console -o NetCoreImage
这里,我们让程序实现一个每秒执行一次的计数器功能,若输入次数,则执行到指定次数后退出,代码如下
using System; namespace NetCoreImage { class Program { static void Main(string[] args) { var counter = 0; var max = args.Length != 0 ? Convert.ToInt32(args[0]) : -1; while (max == -1 || counter < max) { counter++; Console.WriteLine($"Counter: {counter}"); System.Threading.Tasks.Task.Delay(1000).Wait(); } } } }
这里,我们需要先将应用发布,以方便下一步将它添加到Docker镜像。我们先进入刚刚创建的项目文件夹,然后执行以下命令
dotnet publish -c Release
然后,在netcoreapp3.1文件夹下会生成publish文件夹
镜像创建
应用创建好了,下一步该将该应用生成镜像了。
docker build 命令使用 Dockerfile 文件来创建容器镜像,该文件没有扩展名,就叫Dockerfile。
Dockerfile创建
在项目文件夹根目录,创建Dockerfile文件,用文本编辑器打开并编辑
1.根据要容器化的应用类型,选择相应的运行时,我们这里选择.NET Core运行时,在文件中添加
FROM mcr.microsoft.com/dotnet/core/runtime:3.1
FROM 命令指示 Docker 从指定存储库中拉取标记为“3.1” 的映像。 请确保拉取的运行时版本与 SDK 面向的运行时一致。
此时,如果,我们直接生成镜像,将会得到2个IMAGE ID相同的镜像,因为,dockerfile中的唯一命令是在现有镜像的基础上生成新的镜像。所以,我们还需要将应用拷贝到镜像中
COPY bin/Release/netcoreapp3.1/publish/ NetCoreImage/ ENTRYPOINT ["dotnet", "NetCoreImage/NetCoreImage.dll"]
通过COPY命令,我们可以将publish文件夹拷贝到镜像中的netcoreimage文件夹,这里我们要特别注意COPY的路径,如果不对,会导致build失败。
ENTRYPOINT命令 指示docker将容器配置为可执行文件,在容器启动时,运行ENTRYPOINT命令,命令结束后,则容器自动停止。
2.通过docker build命令创建镜像
docker会处理Dockerfile中的每一行,这里的 . 代表在当前目录搜索Dockerfile,否则需要指定路径,还需要注意的是,镜像名称只支持小写,只支持小写,只支持小写。
docker build -t myimage -f Dockerfile .
这里注意,在执行命令时,一定要保证docker是运行状态,否则报错。
效果图如下,我们可以通过docker images命令查看镜像。
>docker build -t myimage -f Dockerfile . Sending build context to Docker daemon 653.3kB Step 1/3 : FROM mcr.microsoft.com/dotnet/core/runtime:3.1 ---> e6780479db63 Step 2/3 : COPY bin/Release/netcoreapp3.1/publish/ NetCoreImage/ ---> 8c084a5d4a1f Step 3/3 : ENTRYPOINT ["dotnet", "NetCoreImage/NetCoreImage.dll"] ---> Running in 8478deb0c4eb Removing intermediate container 8478deb0c4eb ---> 2d4f6dd078ce Successfully built 2d4f6dd078ce Successfully tagged myimage:latest SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
>docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimage latest 2d4f6dd078ce About a minute ago 190MB
这里,可以看到刚刚创建的myimage镜像了。
用自建的镜像生成容器
创建容器
我们可以用docker create myimage来创建镜像的容器
>docker create myimage 7b7ef593c32e803fe9ade7fa1804d2a1b2e442faae08575d67bf633724aed15e
我们也可以用docker create --name 参数来指定生成的容器名称
>docker create --name firstimage myimage 47fedb32416b84ecc3048aa3b9f9719bc652f1b3c4fb1e6e7a2ef19a5a299fc6
并通过docker ps -a来查看容器列表
>docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 47fedb32416b myimage "dotnet NetCoreImage…" 47 seconds ago Created firstimage 7b7ef593c32e myimage "dotnet NetCoreImage…" 3 minutes ago Created gallant_turing
管理容器
启动容器
可以用docker start 来启动容器,使用docker ps显示正在运行的容器
>docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES >docker start firstimage firstimage >docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e4af23979adf myimage "dotnet NetCoreImage…" 24 seconds ago Up 2 seconds firstimage
从上述过程可以看出,docker create创建的容器并没有直接运行,而是要start才运行。
连接到容器
在start容器后,我们可以通过docker attach来连接到容器并查看其输出,使用ctrl+C可停止容器中的进程,进而结束容器运行,我们可以通过参数--sig-proxy=false来确保从容器中分离后还可以重新连接,验证如下
>docker attach firstimage Counter: 61 Counter: 62 Counter: 63 Counter: 64 Counter: 65 Counter: 66 Counter: 67 >docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e4af23979adf myimage "dotnet NetCoreImage…" 10 minutes ago Up About a minute firstimage >docker attach --sig-proxy=false firstimage Counter: 102 Counter: 103 Counter: 104 Counter: 105 >docker attach --sig-proxy=false firstimage Counter: 110 Counter: 111 Counter: 112 Counter: 113 Counter: 114 Counter: 115 Counter: 116 Counter: 117 Counter: 118
注意,这里预期的结果和上述描述不符,Ctrl+C并没有让容器退出,不知道是否是windows命令行的原因,这里有待确认一下。
停止容器
同样,可以用docker stop 来停止容器
>docker stop firstimage firstimage >docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
单次运行
用docker run命令,可将容器作为单一命令进行创建和运行。即,无需依次执行docker create 和docker start
另外,还可以将其设置为在容器停止时自动删除容器
如,使用docker run -it --rm可先自动创建并连接容器,再在容器完成时删除容器。
>docker run -it --rm myimage Counter: 1 Counter: 2 Counter: 3 Counter: 4 Counter: 5 Counter: 6 ^C >docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
更改ENTRYPOINT
使用docker run,还可修改Dockerfile中的ENTRYPOINT命令,并运行其他内容,但只能针对相应的容器。例如,可将ENTRYPOINT更改为运行cmd.exe或bash,这里取决于你设置的容器类型是Windows还是linux,我这里是linux的,所以,演示如下
>docker run -it --rm --entrypoint "bash" myimage root@25f9f877bfa4:/# ls NetCoreImage bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@25f9f877bfa4:/# exit exit
若是Windows的,则相应的是
> docker run -it --rm --entrypoint "cmd.exe" myimage Microsoft Windows [Version 10.0.17763.379] (c) 2018 Microsoft Corporation. All rights reserved. C:\>docker --version Docker version 19.03.8, build afacb8b C:\>^C
清理资源
在可能的情况下,我们需要清理我们创建的镜像或容器,那么删除这些资源可以通过如下命令
1.docker ps查看正在运行的容器
>docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e4af23979adf myimage "dotnet NetCoreImage…" 33 minutes ago Up 2 seconds firstimage
2.docker stop 停止正在运行的容器
>docker stop firstimage firstimage
3.docker rm 删除容器
>docker rm firstimage firstimage
4.docker rmi 依次删除Dockerfile创建的镜像,可使用IMAGE ID或REPOSITORY:TAG
>docker rmi myimage Untagged: myimage:latest Deleted: sha256:6b9660fa78f634598562a7ab47a33e5944d14e8f52262fe2abcc99f0a659bdf9 Deleted: sha256:5792ce48e4638eed4f8d9dfd86c7a0f59216b0d617e510ff20771c41491610b2 Deleted: sha256:480528a380b2f4087901b278fb5a76203e9a2ad12fd173a4012f5dd72ed995ef >docker rmi mcr.microsoft.com/dotnet/core/runtime:3.1 Untagged: mcr.microsoft.com/dotnet/core/runtime:3.1 Untagged: mcr.microsoft.com/dotnet/core/runtime@sha256:77a212d5b1e89856c6567a11eed8f76f24fbe5151011f50d0171207df450075f Deleted: sha256:e6780479db63a85cb396c45eb8be2f5a471dc9009d3ec1ba8ce0ed5eefb322c2 Deleted: sha256:a376db5c92a81339f1beb476b42457a753cc73f8706970e61346e41685ecc970 Deleted: sha256:d3aa2754ac92d73b28c2e84ab86dd3d0c27a6b10d3188f397a285656af92578a Deleted: sha256:58b46dca51a7c1d1ef607c85f7d13e631538ebe6b66f47aaa8f1609590ba69a0
重要命令
docker有许多不同的命令,可用于对镜像和容器的操作,而本节,主要涉及了至关重要的一些命令
好了,本节到这里就要结束了,下一节的话,计划说说容器编排的相关知识。感兴趣的小伙伴请点个赞。