Docker 指定netcore端口后无效的原因
除夕夜,没回家,在广州敲代码,学习得超级快呀,今天记录一下学习的内容。
我们在使用docker命令行时,在生成docker的container容器时,通常都会指定端口运行,比如: docker run -it -p 6666:6666 net imagename
启动后,容器开放的端口与容器内部的kestrel宿主不是相同端口,无法进行端口转发映射,这个时候访问端口外部端口6666是无法访问的。
Kestrel原理配置理解
ASP.NET Core项目使用Kestrel作为默认的web服务器。
而集成Kestrel的ASP.NET Core有4中方式指定终结点URL:
-
ASPNETCORE_URLS
环境变量 全局配置法 【这种方案需要频繁得配置生成镜像,使得镜像要一对一对应容器,端口配置只能配置一次,在运行容器时不可变。】 -
--urls
命令行参数 【这种方案可以让一个镜像生成多个容器,端口配置多样化。建议 -
urls
主机配置键 【这种方案可以让一个镜像生成多个容器,端口配置多样化。建议 -
UseUrls
扩展方法 【这种方案可以让一个镜像生成多个容器,端口配置多样化,但需要配置代码。】
这段原理配置说明了这个问题有四种处理方案:
方案1 : ASPNETCORE_URLS
环境变量 全局配置法
要端口能映射到你对应寄生宿主端口中,则需要配置Dockerfile文件,如下:
ENV ASPNETCORE_URLS=http://+:6666
这句话的意思是说: 把寄生宿主端口设置为6666。
接下来的操作就是:
1.重新生成镜像
#创建 image文件 (-t参数用来指定 image 文件的名字,后面还可以用冒号指定标签 PS:注意最后的 点)
docker build -t aspnetcoredocker1.1 .
2.运行
#生成容器,每运行一次,就会新建一个容器(这里的5000:5000 代表把容器内的5000端口映射到你主机的5000端口,容器端口在后)
docker run -it -p 6666:6666 aspnetcoredocker1.1
#docker run -it -p 6666:6666 aspnetcoredocker1.1:TAG // 默认TAG是latest
3.查看运行状态
docker ps -a
4.获取站点状态
wget 127.0.0.1:6666
5.这种方案的问题总结:
其实这个问题本质上是由于kestrel配置的终结点URL由环境变量Dockfile配置ASPNETCORE_URLS所决定,如果不配置默认为80端口,故每次生成容器后,需要指定一个端口来配置运行。这样的话,就势必会出现一个镜像对应一个容器,那么一个docker 要 运行两个相同项目,就必须要对dockfile进行配置urls,生成镜像并运行启动容器,否则无法映射到外部端口中,这样导致:1个镜像对应一个容器,无法在同一个docker中使用1个镜像多个容器的作法,如果命令行配置 command 来 运行指定 kestrel运行端口,这样话我就不需要每次都去配置dockerfile了。(处理一个镜像可以多个容器运行,并且不用频繁的生成镜像):
方案2. UseUrls
扩展方法 :
在net core 代码启动项中使用useurls的参数获取:
然后在启动docker容器时, 命令加上 对应监听的端口
经过wget后。访问正常
方案3:urls
命令行参数配置方案 和 --url 命令行配置方案
在命令行中代入 --urls="" 即可监听对应端口
总结:
一般来说,一台服务器都是一个镜像一个容器的,如果有特殊需求的话,可能一个镜像多个容器,那么就可以用这个方案。
这里需要注意的一点是:
容器虽然是隔离的,但是容器彼此间的端口还是共用的,如果一个容器占用了一个容器内部端口,其他容器是无法占用的。
容器的环境隔离,但容器彼此间使用的硬件,带宽,网络,端口,外部虚拟化的系统都是一样的,不一样的是容器间互相隔离的环境个体。就好像日本酒店以前的共享房间一样。