第五节:自定义制作Centos镜像 和 制作Asp.Net Core WebApi8.x 镜像并发布

一. 自定义Centos镜像

1. 要求

 基于Centos7.0官方镜像制作一个自己的名为ypfcentos的镜像,版本为1.0,要求如下:

 (1). 默认的登录路径 /ypfusr

 (2). 可以使用vim

2. 步骤

(1). 下载一个centos7.0的官方镜像

 【docker pull centos:7.0】  宿主机已经存在该镜像

(1). 在工作目录下通过指令新建一个文件夹‘ypfcentos’,用于存放自己改造的centos镜像的Dockerfile文件

【mkdir ypfcentos】

(2). 进入ypfcentos文件夹,新建一个ypfcentos_Dockerfile文件,复制下面内容。

【cd ypfcentos】

【vi ypfcentos_Dockerfile】

相关dockerfile代码如下

#1.定义依赖镜像(宿主机中没有话则去下载)
FROM centos:7

#2.定义作者信息(可以不写)
MAINTAINER ypf <ypf@qq.com>

#3. 执行安装vim的命令(-y表示安装过程中不提示)
RUN yum install -y vim 

#4. 定义默认的工作目录
WORKDIR /ypfusr

#5 定义容器启动执行的命令
CMD /bin/bash

(3). 运行下面指令,进行镜像构建

【docker build -f ./ypfcentos_Dockerfile -t ypfcentos:1.0 .    】   其中 ./ 代表当前目录   等价于  【docker build -f ypfcentos_Dockerfile -t ypfcentos:1.0 .    】

或:【docker build  -t ypfcentos:1.2 .   】 使用默认的Dockerfile命名,且在当前目录,则不需要通过-f指定路径了。(已测试)

(4). 将镜像发布成容器,并进入容器内部(交互式容器)

 【docker run -it --name=ypfcentoscontainer1 ypfcentos:1.0 】

(5). 测试

【pwd】查看当前目录

【vim ypf.txt】测试vim指令是否可以使用

 

二. 制作WebApi8.x镜像并发布容器

1. 要求

 基于webapi8.x版本,制作一个Asp.Net Core WebApi镜像,名为ypfwebapi,版本号为2.1 ,并发布成容器,名为ypfapi,要求如下:

(1). 容器内的工作目录为userapi

(2). 容器仅对外暴露端口8080

(3). 用户可以通过 http://xxxxx:8000/swagger/index.html   访问接口,获取数据

 

2 步骤

(1).  新建项目

  新建一个Asp.Net Core WebApi项目,版本8.0 ,右键对其添加docker支持,会自动生成一个Dockerfile文件,如下:

PS:默认生成的Dockerfile文件不能直接使用,主要看看需要依赖哪些库,可以提前下载,查看一下最后的运行指令即可

默认的Dockerfile文件

# 请参阅 https://aka.ms/customizecontainer 以了解如何自定义调试容器,以及 Visual Studio 如何使用此 Dockerfile 生成映像以更快地进行调试。

# 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
WORKDIR /app
EXPOSE 8080


# 此阶段用于生成服务项目
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["WebApi8.csproj", "."]
RUN dotnet restore "./WebApi8.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "./WebApi8.csproj" -c $BUILD_CONFIGURATION -o /app/build

# 此阶段用于发布要复制到最终阶段的服务项目
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./WebApi8.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

# 此阶段在生产中使用,或在常规模式下从 VS 运行时使用(在不使用调试配置时为默认值)
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApi8.dll"]
View Code

经分析,依赖于下面两个库,可以提前下载(不下载的话,docker build 构建的时候将自动下载)

【docker pull mcr.microsoft.com/dotnet/aspnet:8.0】

【docker pull mcr.microsoft.com/dotnet/sdk:8.0】

下载后如下图:

(2) 根据上述需求,制作自己的Dockerfile文件

#1.依赖两个基础镜像
FROM mcr.microsoft.com/dotnet/aspnet:8.0
FROM mcr.microsoft.com/dotnet/sdk:8.0

#2.制作人
MAINTAINER ypf <ypf@qq.com>

#3.指定程序运行的端口(也可以在项目中通过UseUrls指定, 或者发布容器的时候通过--env ASPNETCORE_URLS=xxx动态指定) 
ENV ASPNETCORE_URLS=http://*:8080

#4.容器对外暴露的端口
EXPOSE 8080

#5.指定默认工作目录
WORKDIR /userapi

#6. 将当前目录(Dockerfile文件下)的所有文件拷贝到镜像的userapi工作目录下
COPY . /userapi/

#7.启动容器的时候执行shell命令:dotnet webapi1.dll,即运行该项目
ENTRYPOINT ["dotnet", "WebApi8.dll"]

剖析:

  A.  必须至指定程序运行的端口【ENV ASPNETCORE_URLS=http://*:8080】,否则无法匹配。

  B. 容器暴露的端口如上8080 一定要和程序运行的端口一致,上述Dockerfile文件是通过 ENV设置环境变量来设置程序运行端口的。 另外还有两种方式:程序中通过UseUrl来指定 或 构建容器的时候动态设置环境变量。(详见下面3补充)

  C. 可以自定义Dockerfile文件名,比如:ypfdockerfile,但需要在构建容器的时候通过 -f 指定一下路径即可 。指令如下docker build -f dockerfile文件路径 -t 镜像名称:版本号 .

 

(3) 发布项目,选择可移植

(4) 在centos系统,创建相应的目录,并拷贝发布包程序

【mkdir webapi】

【cd webapi】

【mkdir 8.0】

然后将发布包程序通过finalshell拷贝进来,默认发布包程序是不包含Dockerfile文件的,这里需要手动创建一个,然后把上面准备的内容copy进去

【mkdir Dockerfile】

(5). 进入8.0文件夹下,通过指令生成镜像

【docker build -t ypfwebapi:2.1 . 】,然后运行 【docker images】

(6). 通过下面指令,将镜像发布成容器

【docker run -id --name=ypfapi -p 8000:8080 ypfwebapi:2.1】 然后通过指令 【docker ps】查看镜像

(7). 测试

  A. 通过指令 【docker exec -it ypfapi bash】, 进入容器,发现默认路径为userapi

  B. 访问 http://xx. 205.120.80:8000/swagger/index.html  ,如下图

(8). 总结

 在该容器内,查看工作目录下的内容 【ls】,发现就是发布包中的内容哦,这时通过Dockerfile中的 【copy . /userapi/】实现的。

 说白了:

  这里webapi部署成容器就是把依赖的环境和发布包的内容整合到一起,最后通过Dockerfile中的  ENTRYPOINT ["dotnet", "webapi8.dll"] 运行该项目。

 

三. 补充说明

1. 关于程序端口的另外两种写法

A. Dockerfile文件中不指定程序运行端口,通过构建容器指令来指定程序运行端口。

dockerfile文件如下:

#1.依赖两个基础镜像
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim 
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster 

#2.制作人
MAINTAINER ypf <ypf@qq.com>

#3.容器对外暴露的端口
EXPOSE 9000

#4.指定默认工作目录
WORKDIR /userapi

#5. 将当前目录(Dockerfile文件下)的所有文件拷贝到镜像的userapi工作目录下
COPY . /userapi/

#6.启动容器的时候执行shell命令:dotnet webapi1.dll,即运行该项目
ENTRYPOINT ["dotnet", "webapi1.dll"]
View Code

相关指令如下:

#构建镜像
docker build -t ypfwebapi3 . 
#发布容器
docker run --env ASPNETCORE_URLS=http://*:9000  -id --name=ypfwebapicontainer3 -p 8002:9000 ypfwebapi3

测试连接:http://119.45.174.249:8002/weatherforecast

B. Dockerfile文件中不指定程序运行端口,在代码里指定端口

程序代码:

dockerfile文件同上一样:

#1.依赖两个基础镜像
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim 
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster 

#2.制作人
MAINTAINER ypf <ypf@qq.com>

#3.容器对外暴露的端口
EXPOSE 9000

#4.指定默认工作目录
WORKDIR /userapi

#5. 将当前目录(Dockerfile文件下)的所有文件拷贝到镜像的userapi工作目录下
COPY . /userapi/

#6.启动容器的时候执行shell命令:dotnet webapi1.dll,即运行该项目
ENTRYPOINT ["dotnet", "webapi1.dll"]
View Code 

相关指令:

#构建镜像
docker build -t ypfwebapi4 . 
#发布容器
docker run -id --name=ypfwebapicontainer4 -p 8004:9000 ypfwebapi4

 

2. 尝试一下,一个项目能不能同时挂多个端口。

答案:不行,当设置多个程序运行端口(非容器端口!!)的时候,仅最后一个有效。

 

3 . COPY 和 ADD 二者基本等效

只能复制Dockerfile所在目录下的文件;复制的镜像内的路径如果不存在,会自动创建。

 

 Linux中相关操作截图:

 

 

4. CMD 和 ENTRYPOINT 效果一致,下面四行指令等效

# 启动容器时候的指令等价于下面的4种写法:
# ENTRYPOINT ["dotnet", "webapi1.dll"]
# ENTRYPOINT dotnet webapi1.dll
# CMD ["dotnet", "webapi1.dll"]
# CMD dotnet webapi1.dll

 

 

5. -P 随机端口映射的问题

A. 使用上述的ypfwebapi1镜像,是-P随机指定端口

【docker run -id --name=test1 -P ypfwebapi1】

B. 使用一个新的Dockerfile文件,对外暴露3个端口,通过-P随机指定所有暴露端口。 

 

docker build -t ypfwebapi5 . 
docker run -id --name=ypfwebapicontainer5 -P ypfwebapi5

 

 

 

 

 

四. 制作WebApi镜像并发布容器--旧版

1. 要求

 制作一个Asp.Net Core WebApi镜像,名为ypfwebapi1,并发布成容器,名为ypfwebapicontainer1,要求如下:

(1). 容器内的工作目录为userapi

(2). 容器仅对外暴露端口9000

(3). 用户可以通过 http://xxxxx:8000/weatherforecast 访问接口,获取数据

2. 步骤

(1). 新建一个Asp.Net Core WebApi项目,版本3.1 ,右键对其添加docker支持,会自动生成一个Dockerfile文件,如下:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["webapi1/webapi1.csproj", "webapi1/"]
RUN dotnet restore "webapi1/webapi1.csproj"
COPY . .
WORKDIR "/src/webapi1"
RUN dotnet build "webapi1.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "webapi1.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "webapi1.dll"]
View Code

分析Dockerfile文件,我们得知,该项目需要依赖的两个基础镜像为,其它内容,我们自行来编辑

 mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim

 mcr.microsoft.com/dotnet/core/sdk:3.1-buster  

(2). 根据要求,自定义的Dockerfile文件内容如下:

#1.依赖两个基础镜像
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim 
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster 

#2.制作人
MAINTAINER ypf <ypf@qq.com>

#3.指定程序运行的端口(也可以在项目中通过UseUrls指定, 或者发布容器的时候通过--env ASPNETCORE_URLS=xxx动态指定) 
ENV ASPNETCORE_URLS=http://*:9000

#4.容器对外暴露的端口
EXPOSE 9000

#5.指定默认工作目录
WORKDIR /userapi

#6. 将当前目录(Dockerfile文件下)的所有文件拷贝到镜像的userapi工作目录下
COPY . /userapi/

#7.启动容器的时候执行shell命令:dotnet webapi1.dll,即运行该项目
ENTRYPOINT ["dotnet", "webapi1.dll"]

说明:

  A. 可以自定义Dockerfile文件名,比如:ypfdockerfile,但需要在构建容器的时候通过 -f 指定一下路径即可 。指令如下 【docker build -f dockerfile文件路径 -t 镜像名称:版本号 .

  B. 容器暴露的端口如上9000 一定要和程序运行的端口一致,上述Dockerfile文件是通过 ENV设置环境变量来设置程序运行端口的。 另外还有两种方式:程序中通过UseUrl来指定 或 构建容器的时候动态设置环境变量。(详见下面3补充)

(3). 将项目进行发布,目标运行时选择:可移植,并把Dockerfile文件复制到发布包根目录下

 

(4). 登录linux服务器,运行下面指令,下载必备的程序镜像

 docker pull mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim
 docker pull mcr.microsoft.com/dotnet/core/sdk:3.1-buster

PS: 这里也可以不下载,等构建镜像的时候如果检测到Linux宿主机上没有该镜像,也会自动下载,这里建议提前下载。

(5). 在Linux的工作目录下新建myprogram文件夹,用于存放需要程序的发布包,进入该目录,然后新建ypfwebapi1文件夹,用于存放该项目的发布包。

【mkdir myprogram】

【cd myprogram】

【mkdir ypfwebapi1】

(6). 通过WinSCP软件,将项目发布包复制到ypfwebapi1文件夹下

(7). 进入ypfwebapi1文件夹下,通过指令生成镜像

【docker build -t ypfwebapi1 . 】

(8). 通过下面指令,将镜像发布成容器

【docker run -id --name=ypfwebapicontainer1 -p 8000:9000 ypfwebapi1】

(9). 测试:

A. 通过指令【docker exec -it 8ff5c6e7a5d8 bash】进入,容器查看工作目录为userapi

 

B. 用PostMan进行get请求    http://119.45.174.249:8000/weatherforecast,获取返回值,测试通过。

(10). 总结:

 在该容器内,查看工作目录下的内容 【ls】,发现就是发布包中的内容哦,这时通过Dockerfile中的 【copy . /userapi/】实现的。

 说白了:

  这里webapi部署成容器就是把依赖的环境和发布包的内容整合到一起,最后通过Dockerfile中的  ENTRYPOINT ["dotnet", "webapi1.dll"] 运行该项目。

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2020-09-15 07:19  Yaopengfei  阅读(521)  评论(2)    收藏  举报