上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有许多不同的命令,可用于对镜像和容器的操作,而本节,主要涉及了至关重要的一些命令
好了,本节到这里就要结束了,下一节的话,计划说说容器编排的相关知识。感兴趣的小伙伴请点个赞。
更多精彩内容,请微信搜索攻城狮客栈 或扫描下方二维码
------------------------------------------------------------------------------
公众号:攻城狮客栈
CSDN:画鸡蛋的不止达芬奇
让我们一起变的更优秀。