前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >NetCore在Docker中发布及运行 安装构建镜像启动容器DockerfileDocker-ComposeHttp连接请求过多问题

NetCore在Docker中发布及运行 安装构建镜像启动容器DockerfileDocker-ComposeHttp连接请求过多问题

作者头像
蓝夏
发布2020-07-10 10:06:27
8180
发布2020-07-10 10:06:27
举报
文章被收录于专栏:bluesummer

之前写过一篇关于Docker的文章,回头看了一眼自己差点没有看明白...最近有时间又仔细研究了一遍(主要是生产环境真的要用到了...),顺便从0学习了一下Linux,踩了不少坑。所以准备再写几篇关于Docker的文章。希望对大家有所帮助。

操作系统为Centos7。项目为asp .netcore webapp。先简单介绍下Docker的安装

安装

代码语言:javascript
复制
更新yum包
sudo yum update

安装需要的软件包, yum-util 提供yum-config-manager功能
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

设置Docker的yum源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

安装Docker 可以用【:版本号】加在后面安装指定的版本,不加就安装最新版本。安装的docker ce,还有个docker ee,是收费版的
sudo yum install docker-ce -y

启动docker
sudo systemctl start docker

使docker服务自动启动
sudo systemctl enable docker

配置镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF

重启docker以使用新的镜像地址
sudo systemctl daemon-reload
sudo systemctl restart docker   

构建镜像

这里就按照官方默认的文件及目录结构来构建镜像和容器,方便了解每个命令的含义

假设我的项目名称为:myapp1,Dockerfile文件名称为:Dockerfile_myapp1

目录结构如下

代码语言:javascript
复制
/mnt/vda1/code/myapp1
/mnt/vda1/docker/Dockerfile_myapp1

那么构建一个镜像的命令为:

代码语言:javascript
复制
docker build [选项] <上下文路径/URL/->

sudo docker build -t myapp1:v1 -f /mnt/vda1/docker/Dockerfile_myapp1 /mnt/vda1/code/myapp1 

-t 指定image的名称和版本,不加:v1 则默认版本为latest

-f 指定Dockerfile文件地址 

/mnt/vda1/code/myapp1为镜像构建的**上下文路径**。所谓的上下文就是说在Dokerfile中可以操作的宿主机器的根路径,超出该路径的文件容器中是访问不到的

启动容器

代码语言:javascript
复制
docker run  -d -p 8001:80 myapp1:v1 --myapp2uri=192.168.3.102 --myapp3uri=myapp3
  • -d:指定容器在后台运行
  • -p 8001:80:将容器内的80端口映射到宿主机器上的8001端口
  • 在镜像名称后面的内容则会作为cmd命令传入到程序中

Dockerfile

前面的内容很容易理解,Dockerfile文件照葫芦画瓢也可以写一个能用的,但是一旦涉及到功能需求的变化(比如说做自动构建和发布)就头大了。下面我给Dockerfile中常用到的每一个指令结合上面的项目来做一个详细的介绍

代码语言:javascript
复制
#FROM指定基础镜像,也就是说后面的的WorkDir,Run命令都是在这个镜像的基础上执行的
#使用sdk2.2执行项目发布 "AS"可以给该镜像起一个别名,可以为build也可以叫做build1,build2 。。。
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build

#WORKDIR设置容器内的工作目录。该命令之后的命令都已该目录为根目录进行相关的操作
#当容器启动之后,进入容器会首先进入该目录,容器的根目录为“/“。
WORKDIR /app1

#COPY将宿主机的文件拷贝到容器中去
#第一个“./”为上下文的根目录,上下文的定义在上面的镜像构建中提到过,第二个“./”等于/app1(工作目录)
#此命令将宿主的机的/mnt/vda1/code/myapp1中的所有文件拷贝到容器内的 /app1文件夹下
COPY ./ ./

#RUN 执行命令行命令
#生成项目。这里的dotnet命令使用的是上面的sdk:2.2中的dotnet命令
RUN dotnet build

#发布项目的Release版本到publish文件夹下
#该命令会在sdk2.2生成的容器中的/app1文件夹下执行
RUN dotnet publish -c Release -o publish


#使用runtime2.2运行项目
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime

#设置容器内的工作目录
WORKDIR /app2

#生命准备使用的端口
EXPOSE 80

#--from=build指定这条命令的上下文是build容器,“./”等于/app2
COPY --from=build /app1/publish ./

#设置容器内的时区,如果不设置,默认时区是标准时间比北京时间晚8个小时
RUN echo "Asia/shanghai" > /etc/timezone
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

#程序入口点。这里的dotnet命令使用的是上面的aspnet:2.2中的dotnet命令
#该指令的含义是在容器启动时执行dotnet DockerWeb1.dll命令
#该数组后面还可以继续追加需要的参数,但是为了扩展性及安全性,我们把其余的变量在运行时指定或者在编排工具中指定
ENTRYPOINT ["dotnet", "myapp1.dll"]
#CMD命令同样可以实现ENTERPOINT的功能
#CMD ["dotnet", "myapp1.dll"]

上面的CMD命令被注释掉了,因为CMD很容易被运行时替换掉,拿上面的启动容器的命令来举例:

如果Dockerfile中使用的是CMD而非ENTRYPOINT,那么启动容器的命令就需要写为:

docker run -d -p 8001:80 myapp:v1 dotnet myapp1.dll --myapp2uri=192.168.3.102 --myapp3uri=myapp3

这是因为在myapp:v1后面的命令全是cmd命令,会替换掉Dockerfile中的cmd命令。

不过在执行CMD命令之前会先执行EnterPoint命令。所以实际的执行顺序为:

docker run -d -p 8001:80 myapp:v1 [ENTERPOINT] [CMD]

当然ENTERPOINT也可以被替换,但是并没有替换的必要,因为我们上面的Enterpoint只是指定了一个启动项而已

Dockerfile中的每一个命令都会生成一层镜像,注意是每一个,有时候还会生成多个。。。这个我还没搞明白。 所以上面的一个Dokerfile会生成十四五个image,有一些无用了会被删掉,还有一些会作为中间镜像以的名称存在于image中,可以执行docker images -a命令查看 目前还没有找到自动删除中间层的方法,可以用这个命令进行清理:docker rmi $(docker images --filter dangling=true -q)

Docker-Compose

总是通过那么大一长串命令启动容器和构建镜像实在很麻烦,用docker-compose来管理容器和镜像就会方便很多。

明白了Docker,Docker-compose就容易理解多了。这里只是简单贴一个DockerCompose的配置文件

代码语言:javascript
复制
version: "3"
services:
  myapp1:
    #build image的相关操作
    build:
       context: /mnt/vda1/code/myapp1
       dockerfile: /mnt/vda1/docker/Dockerfile_myapp1
    image: myapp1
    restart: always
	#设置容器名称
	container_name: myapp1container
    ports:
      - "8001:80"
	#设置文件夹挂载
    volumes:
      - /mnt/vda1/data/influxexcel:/app/wwwroot/Excels
  myapp2:
    build:
       context: /mnt/vda1/code/myapp2
       dockerfile: /mnt/vda1/docker/Dockerfile_myapp2
    image: myapp2
    restart: always
	container_name: myapp2container
	#CMD参数
    command: --ApiUrl1=myapp1container
    ports:
      - "8002:80"

Http连接请求过多问题

可能报错:Resource temporarily unavailable

修改 sysctl -w net.core.somaxconn=32768 立即生效

vi /etc/sysctl.conf 增加一行 net.core.somaxconn= 32768 sysctl -p 重启生效

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装
  • 构建镜像
  • 启动容器
  • Dockerfile
  • Docker-Compose
  • Http连接请求过多问题
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档