相关文章推荐
潇洒的猴子  ·  [nginx][tls] ...·  4 月前    · 
飞翔的皮带  ·  在 Emacs 中编辑 ...·  1 年前    · 
乖乖的莲藕  ·  Python的pandas ...·  1 年前    · 

最近使用了Mac系统的电脑作为了测试服务器,但是在Mac系统的电脑使用docker安装nginx进行反向代理,以前在centos7系统的电脑上无往不利的docker容器启动方式,反而出现了问题。
启动方式:

docker run -it --name nginx --net host -v /Users/mac-server/Desktop/project:/var/www/html -v /Users/mac-server/Desktop/nginx:/nginx_conf -d nginx  

以前在centos7的系统上容器构建后,都可以访问成功。进入nginx执行nginx -t,配置文件没有问题;执行nginx -s reload,重启nginx也没有报错。但是就是不能通过浏览器访问。

排除防火墙和80端口的问题,还是不能访问。

解决过程一

在经过多次卸载重装nginx容器都没能成功的情况下,就是用最常见的容器启动命令启动:

docker run -it --name nginx -p 80:80 -d nginx  

结果浏览器可以直接进行访问了。

但是这样明显是不能满足我们的需求的,nginx需要进行反向代理的时候,未来项目的端口往往是位置的,所以使用 –net host共享宿主机端口 是比较好的解决方案。

对比上文的容器启动命令,一般来说不是-v映射目录的问题,要不启动时会报错。多以应该问题出自--net host上。

于是基于此进行分析,最终找到了原因。

Mac系统下docker容器无法使用–net host共享宿主机端口的原因

docker的网络配置

docker的网络配置分为四种,:host,overlay,macvlan,bridge

host模式

与宿主机共享网络,也就是在网络这块不会与宿主机隔离,而是共享宿主机的网络配置,并且 容器不会分配自己的ip地址

需要注意的是,因为容器是与宿主机共享网络,并且容器不存在自己的ip, 端口映射不生效, -p,–publish,-P,和–publish-all都将被忽略,并产生一个警告
WARNING: Published ports are discarded when using host network mode

使用方法:
在创建容器时添加如下配置

--net host

overlay模式

分布式网络模式。可参考:https://docs.docker.com/network/overlay/

macvlan模式

直接连接宿主机的物理网络,为每个容器的虚拟网络接口分配MAC地址,相当于直接连接了宿主机的物理网络接口。

但是使用改模式需要注意以下几点:

  • 会导致宿主机上有大量的MAC地址
  • 需要宿主机支持一个物理接口分配多个MAC地址
  • 如果应用程序可以使用bridge,overlay模式,那最好使用这两种方式建立网络

bridge模式

类似VMware的桥接网络,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。

docker架构

Linux的docker架构

在这里插入图片描述
docker是在linux内核容器基础上实现的,linux安装docker后,会创建一个为docker0的虚拟网卡,linux宿机与docker容器之间的通信,通过docker0虚拟网卡进行

Mac下的docker架构

在这里插入图片描述
docker在OSX的实现方式,是首先创建一个linux的虚拟机,在将docker放入到虚拟机中实现,而对于linux虚拟机,与OSX之间的通信,目前版本采用/var/run/docker.sock这种socket文件来通信,在OSX宿机中自然ping不通docker容器。

Mac系统对docker的限制

参考:https://docs.docker.com/docker-for-mac/networking/

  • 因为MacOS无法访问Docker桥接网络,而恰恰Docker默认是使用bridge模式,所以导致Docker无法联网,并且无法与宿主机沟通。

  • Host主机网络驱动程序仅适用于Linux主机,并且不支持Docker for Mac,Docker for Windows或Docker EE for Windows Server。

所以docker容器无法使用–net host共享宿主机端口

解决无法使用–net host的方案

docker容器使用--net host共享宿主机端口,无非是因为在未来使用容器的过程中,宿主机与容器通信的端口不能确定。既然--net host不能使用,不能共享宿主机端口,那么我们可以寻找一些替代方案。

docker映射某个范围内的端口列表代替–net host共享宿主机端口

不管在Dockerfile命令行docker-compose.yml中,都可以使用类似于8080-8090:8080-8090的格式,来映射多个端口

docker-compose.yml

#create by winton wang
version: '3.6'
services:
    image: nginx:1.18
    ports:
      # 将会映射8080到8090这个范围内的端口
      - 8080-8090:8080-8090
    volumes:
      - ./www:/www
docker run -p 8080-8090:8080-8090 nginx

Dockerfile

EXPOSE 8080-8090

注意:
使用这种形式去映射大范围的端口,会占用用户大量的内存,尽量不要这样子做

修改nginx容器的启动方式,映射端口列表

docker run -it --name nginx -p 80:80 -p 7000-8000:7000-8000  -v /Users/mac-server/Desktop/project:/var/www/html -v /Users/mac-server/Desktop/nginx:/nginx_conf -d nginx 
  • 使用不常用的7000-8000端口,用于nginx的反向代理未来的项目,当然端口范围可根据实际情况修改。
  • 如果这样做了,7000-8000端口就会都被占用,所以慎用。
  • 如果7000-8000有端口已经被占用,则容器启动失败。

参考博客:

背景最近使用了Mac系统的电脑作为了测试服务器,但是在Mac系统的电脑使用docker安装nginx进行反向代理,以前在centos7系统的电脑上无往不利的docker容器启动方式,反而出现了问题。启动方式:docker run -it --name nginx --net host -v /Users/mac-server/Desktop/project:/var/www/html -v /Users/mac-server/Desktop/nginx:/nginx_conf -d nginx 抛弃docker for mac自带的linux虚拟机(尽管轻量,但其与OSX通信采用socket文件的方式),使用docker-machine 安装virtualbox。virtualbox创建后,会添加一个虚拟网卡,可以通过ifconfig命令查看。我们实现的方式,就是利用这个虚拟网卡。 使用docker-machine创建默认linux虚拟机,命令docker-machine create 切换docker环境,使用eval $(docker-machine env)命令 查看创建的虚拟机的ip地址:docker-machine ip default或者直接docker-mac
简单的说Docker是一个构建在LXC之上的,基于进程容器(Processcontainer)的轻量级VM解决方案 拿现实世界中货物的运输作类比,为了解决各种型号规格尺寸的货物在各种运输工具上进行运输的问题,我们发明了集装箱 Docker的初衷也就是将各种应用程序和他们所依赖的运行环境打包成标准的container/image,进而发布到不同的平台上运行
nginx-proxy设置了一个运行nginx和的容器docker-gen为nginx生成反向代理配置,并在容器启动和停止时重新加载nginx。 请参阅了解为什么要使用它。 要运行它: $ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy 然后使用env var VIRTUAL_HOST=subdomain.youdomain.com启动要代理的任何容器 $ docker run -e VIRTUAL_HOST=foo.bar.com ... 被代理的容器必须要代理的端口,方法是在其Dockerfile使用EXPOSE指令,或者通过使用--expose标志使--expose docker run或--expose docker create并位于同一网络中。 默认情况下,如果在创建nginx-proxy容器时未传递--net标志,它将仅附加到默认的桥接网络。 这意味着它将无法连接到网桥以外的容器。 如果您的DNS设置为将foo.bar.com转发
--net=host: (1).加了--net=host以后就不需要再做端口映射了.比如docker容器内在8080端口起了一个web server.不加的话需要把本机的某个port比如7979和docker内的8080做一个映射关系,访问的时候访问7979. 加了net=host则直接访问8080. 另外,加了net=host后会使得创建的容器进入命令行好名称显示为主机的名称而不是一串id.  root@box:/# (2).容器中的app1无法访问到宿主机的app2,因为两者不在一个网络内。最简
dockernginx无法代理转发到容器外部,且–net=host无效; Host 模式只支持 Linux 系统,Windows 和 macOS 此参数无效。因此容器nginx转发中的localhost是指向容器本身,所以要访问容器外的,需要明确指出宿主机的IP地址。 官网:https://docs.docker.com/network/host/
最近部署一套系统使用nginx作反向代理,其中nginx使用docker方式运行: $ docker run -d --name nginx $PWD:/etc/nginx -p 80:80 -p 443:443 nginx:1.15 需要代理的API服务运行在宿主机的 1234 端口nginx.conf 相关配置如下: server { location /api { proxy_pass http://localhost:1234 结果访问的时候发现老是报 502 Bad Gateway 错误,错误日志显示无法连接到upstream。
使用 docker 容器 aria2-pro 下载 m3u8 文件的步骤如下: 1. 首先,安装 docker。如果你还没有安装 docker,请参考官方文档或者网上教程进行安装。 2. 下载 aria2-pro 镜像。在命令行中输入以下命令: docker pull aria2-pro 3. 启动 aria2-pro 容器。输入以下命令: docker run -d --name aria2-pro -p 6800:6800 aria2-pro 4. 使用 aria2c 命令下载 m3u8 文件。输入以下命令: aria2c -c -s10 -x10 -j10 -i <m3u8文件的URL> 其中,`-c` 参数表示继续下载,`-s10 -x10 -j10` 参数表示使用 10 个线程下载,`-i` 参数表示输入 m3u8 文件的 URL。 注意:在使用 aria2c 命令之前,需要先进入 aria2-pro 容器内。输入以下命令进入容器内: docker exec -it aria2-pro /bin/bash