docker 外网访问不了docker容器

出现问容基于镜像A创建新的镜像时,新的Dockerfile中使用 from A 指定基镜像时,会自动执行 ONBBUILD 指令内容,等价于在新的要构建镜像的Dockerfile中增加了两条指令:器是在linux上本机运行,并与其他容器共享主机的内核,它运行的一个的进程,不占用其他任何可执行文件的内存,非常轻量、高效、快速。题的原因有3种,

docker端口_docker端口映射原理docker端口_docker端口映射原理


docker端口_docker端口映射原理


2:docker在创建镜像的时候没有做端口映射,这是就出现能访问物理机,但访问不了docker,你可以使用docker ps 查看镜像的端口映射情况。

3:端口映射不正确,如你docker中某一容器的8080端口映射到安装docker物理机的80端口,加入你在镜像里面安装了tomcat,但是你tomcat使用的是8080以外的任意端口,这是你访问物理机ip+80端口也无法访问。

Docker(2)——构建镜像命令解析

格式: EVN key value

Dockerfile 中包括 FROM 、 MAINTAINER 、 RUN 、 CMD 、 EXPOSE 、 ENV 、 ADD 、 COPY 、 ENTRYPOINT 、 VOLUME 、 USER 、 WORKDIR 、 ONBUILD 、 LABEL 等14个指令。

1.FROM

格式: FROM image 或 FROM image:tag

含义:Dockerfile中条指令必须是FROM指令,且在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令。

docker17.05版本开始,dockerfile中允许使用多个FROM指令,主要是解决编译环境和运行环境分开的问题。

格式: MAINTAINER user_name user_email

含义:指定维护者信息,作者以及作者的邮箱地址

3.RUN

RUN command

RUN ["EXECUTABLE","PARAM1","PARAM2".....]

含义:前者在shell终端中运行命令, /bin/sh -c command ,例如: /bin/sh -c "echo hello" ;后者使用 exec 执行,指定其他运行终端使用 RUN["/bin/bash","-c","echo hello"] 。每条RUN指令将当前的镜像基础上执行指令,并提交为新的镜像,命令较长的时候可以使用 来换行。

1)host模式,--net=host指定,不支持多主机。4.CMD

支持三种格式:

CMD ["executable","param1","param2"] ,使用exec执行,这是的方式。

CMD command param1 param2 , 在 /bin/sh 中执行。

CMD ["param1","param2"] ,提供给 ENTERYPOINT 的默认参数。

含义: CMD 用于指定容器启动时执行的命令,每个 Dockerfile 只能有一个 CMD 命令,多个 CMD 命令只执行一个。若容器启动时指定了运行的命令,则会覆盖掉 CMD 中指定的命令。

5.EXPOSE

格式: EXPOSE port [port2,port3,...]

含义:例如 EXPOSE 80 这条指令告诉Docker暴露80端口,供容器外部连接使用。在启动容器的使用使用-P,Docker会自动分配一个端口和转发指定的端口,使用-p可以具体指定使用哪个本地的端口来映射对外开放的端口。

6.ENV

含义:用于指定环境变量,这些环境变量,后续可以被 RUN 指令使用,容器运行起来之后,也可以在容器中获取这些环境变量,例如:

ENV word hello

RUN echo $word

7.ADD

格式: ADD src dest

含义:该命令将指定本地目录中的文件到容器中的 dest 中, src 可以是是一个路径,也可以是一个 URL 或一个 tar 文件, tar 文件会自动解压为目录。

8.COPY

含义:本地主机src目录或文件到容器的desc目录,desc不存在时会自动创建。

9.ENTRYPOINT

ENTRYPOINT ["executable","param1","param2"]

ENTRYPOINT command param1,param2

10.VOLUME

格式: VOLUME ["/data"]

含义:作用是创建在本地主机或其他容器可以挂载的数据卷,用来存放数据。

格式: USER username

含义:指定容器运行时的用户名或UID,后续的RUN也会使用指定的用户。要临时使用权限可以使用sudo。在USER命令之前可以使用RUN命令创建需要的用户。

例如: RUN groupadd -r docker && useradd -r -g docker docker

12.WORKDIR

格式: WORKDIR /path

含义:为后续的 RUN CMD ENTRYPOINT 指定配置工作目录,可以使用多个 WORKDIR 指令,若后续指令用得是相对路径,则会基于之前的命令指定路径。

13.ONBUILD

含义:该配置指定当所创建的镜像作为其他新建镜像的基础镜像时所执行的指令,例如下面的Dockerfile创建了镜像A:

ONBUILD ADD . /app

ONBUILD RUN python app.py

FROM A

ADD ./app

RUN python app.py

14.LABEL

格式: LABEL =""

含义:用来给镜像以键值对的形式添加一些元数据(metadata),如明镜像的作者、文档地址,commit ID。

RancherOS防火墙配置及IDEA连接Docker

采用Host模式的查看appium运行日志容器,可以直接使用宿主机的IP地址与外界进行通信,无需额外进行NAT转换。由于容器通信时,不再需要通过Linux Bridge等方式转发或者数据包的拆封,性能上有很大优势。当然, Host模式有利也有弊 ,主要包括以下缺点:

1、docker没有启动

ctl start docker

docker run -p 宿主机端口:容器端口

Docker容器网络-实现篇

前面介绍了: Docker容器网络-基础篇

前文说到容器网络对Linux虚拟化技术的依赖,这一篇章我们将一探究竟,看看Docker究竟是怎么做的。通常,Linux容器的网络是被隔离在它自己的Network Namespace中,其中就包括:网卡(Network Intece)、回环设备(Loopback Dev)、路由表(Routing Table)和iptables规则。对于一个进程来说,这些要素,就构成了它发起和响应网络请求的基本环境。

我们在执行 docker run -d --name xxx 之后,进入容器内部:

并执行 ifconfig:

我们看到一张叫0的网卡,它正是一个V Pair设备在容器的这一端。

我们再通过 route 查看该容器的路由表:

我们可以看到这个0是这个容器的默认路由设备。我们也可以通过第二条路由规则,看到所有对 169.254.1.1/16 网段的请求都会交由0来处理。

而V Pair 设备的另一端,则在宿主机上,我们同样也可以通过查看宿主机的网络设备来查看它:

在宿主机上,容器对应的V Pair设备是一张虚拟网卡,我们再用 brctl show 命令查看网桥:

可以清楚的看到V Pair的一端 vd08be47 就插在 docker0 上。

我现在执行docker run 启动两个容器,就会发现docker0上插入两个容器的 V Pair的一端。如果我们在一个容器内部互相ping另外一个容器的IP地址,是不是也能ping通?

容器1:

容器2:

从一个容器ping另外一个容器:

我们看到,在一个容器内部ping另外一个容器的ip,是可以ping通的。也就意味着,这两个容器是可以互相通信的。

我们不妨结合前文时所说的,理解下为什么一个容器能访问另一个容器?先简单看如一幅图:

当在容器1里访问容器2的地址,这个时候目的IP地址会匹配到容器1的第二条路由规则,这条路由规则的Gateway是0.0.0.0,意味着这是一条直连规则,也就是说凡是匹配到这个路由规则的请求,会直接通过0网卡,通过二层网络发往目的主机。而要通过二层网络到达容器2,就需要127.17.0.3对应的MAC地址。所以,容器1的网络协议栈就需要通过0网卡来发送一个ARP广播,通过IP找到MAC地址。

所谓ARP(Address Resolution Protocol),就是通过三层IP地址找到二层的MAC地址的协议。这里说到的0,就是V Pair的一端,另一端则插在了宿主机的docker0网桥上。0这样的虚拟网卡插在docker0上,也就意味着0变成docker0网桥的“从设备”。从设备会降级成docker0设备的端口,而调用网络协议栈处理数据包的资格全部交给docker0网桥。

所以,在收到ARP请求之后,docker0就会扮演二层交换机的角色,把ARP广播发给其它插在docker0网桥的虚拟网卡上,这样,127.17.0.3就会收到这个广播,并把其MAC地址返回给容器1。有了这个MAC地址,容器1的0的网卡就可以把数据包发送出去。这个数据包会经过V Pair在宿主机的另一端v26cf2cc,直接交给docker0。

docker0转发的过程,就是继续扮演二层交换机,docker0根据数据包的目标MAC地址,在CAM表查到对应的端口为v8762ad2,然后把数据包发往这个端口。而这个端口,就是容器2的V Pair在宿主机的另一端,这样,数据包就进入了容器2的Network Namespace,最终容器2将响应(Ping)返回给容器1。在真实的数据传递中,Linux内核Netfilter/Iptables也会参与其中,这里不再赘述。

CAM就是交换机通过MAC地址学习维护端口和MAC地址的对应表

这里介绍的容器间的通信方式就是docker中最常见的bridge模式,当然此外还有host模式、container模式、none模式等,对其它模式有兴趣的可以去阅读相关资料。

好了,这里不禁问个问题,到目前为止只是单主机内部的容器间通信,那跨主机网络呢?在Docker默认配置下,一台宿主机的docker0网桥是无法和其它宿主机连通的,它们之间没有任何关联,所以这些网桥上的容器,自然就没办法多主机之间互相通信。但是无论怎么变化,道理都是一样的,如果我们创建一个公共的网桥,是不是集群中所有容器都可以通过这个公共网桥去连接?

当然在正常的情况下,与的通信往往可以通过NAT的方式,但是,这个在互联网发展的今天,在容器化环境下未必适用。例如在向注册中心注册实例的时候,肯定会携带IP,在正常物理机内的应用当然没有问题,但是容器化环境却未必,容器内的IP很可能就是上文所说的172.17.0.2,多个都会存在这个IP,大概率这个IP是冲突的。

如果我们想避免这个问题1、Docker进程通过宿主机的某个端口,将该端口的数据包发送给Docker容器。,就会携带宿主机的IP和映射的端口去注册。但是这又带来一个问题,即容器内的应用去意识到这是一个容器,而非物理机,当在容器内,应用需要去拿容器所在的物理机的IP,当在容器外,应用需要去拿当前物理机的IP。显然,这并不是一个很好的设计,这需要应用去配合配置。所以,基于此,我们肯定要寻找其他的容器网络解决方案。

在上图这种容器网络中,我们需要在我们已有的主机网络上,通过软件构建一个覆盖在多个主机之上,且能把所有容器连通的虚拟网络。这种就是Overlay Network(覆盖网络)。

关于这些具体的网络解决方案,例如Flannel、Calico等,我会在后续篇幅继续陈述。

10. Docker 安装与配置

11.USER

Docker 是一个开源的应用容器引擎,基于LXC(Linux Container)内核虚拟化技术实现,提供一系列更强的功能,比如镜像、 Dockerfile等;Docker理念是将应用及依赖包打包到一个可移植的容器中,可发布到任意Linux发行版Docker引擎上。使用沙箱机制运行程序, 程序之间相互隔离;

2、docker暴露任意端口到宿主机端口2375,防火墙和安全组开放2375端口到指定公网IP。

虚拟机运行的是一个完成的作系统,通过虚拟机管理程序对主机资源进行虚拟访问,相比之下需要的资源更多。

参考:

Linux版本CentOS7

使用加速器可以提升获取Docker镜像的速度,下面使用 阿里云镜像 进行加速。

Docker 守护进程绑定在 Unix socket 而不是 TCP 端口。默认情况下 Unix socket 归属于 root 用户,其他用户只能通过 sudo 命令访问。所以 Docker 守护进程总是以 root 用户来运行。

如果你不希望每次运行 docker 命令时在前面加上 sudo,你可以创建一个 docker 用户组并把用户加进去。当 Docker 守护进程启动时,会创建一个 Unix socket 供 docker 用户组成员访问

创建 docker 用户组并添加你的用户

什么是 DockerHub 以及为什么它很重要?DockerHub 是一个由 Docker 公司运行和管理的基于云的存储库。它是一个在线存储库,Docker 镜像可以由其他用户发布和使用。

有两种库:公共存储库和私有存储库 。如果你是一家公司,你可以在你自己的组织内拥有一个私有存储库,而公共镜像可以被任何人使用。

镜像层和容器层

Docker 服务端是Docker 所有后台服务的统称 。其中dockerd 是一个非常重要的后台管理进程,它负责响应和处理来自Docker 客户端的请求,然后将客户端的请求转化为Docker 的具体作。

例如:镜像、容器、网络和挂载卷等具体对象的作和管理。

Docker 从诞生到现在,服务端经历了多次架构重构。起初,服务端的组件是全部集成在docker 二进制里。但是从 1.11 版本开始, dockerd 已经成了的二进制,此时的容器也不是直接由dockerd 来启动了,而是集成了containerd、runC 等多个组件。

虽然 Docker 的架构在不停重构,但是各个模块的基本功能和定位并没有变化。它和一般的 C/S 架构系统一样,Docker 服务端模块负责和 Docker 客户端交互,并管理Docker 的容器、镜像、网络等资源。

Docker 有两个至关重要的组件: runC和containerd。

runC 是Docker 按照OCI 容器运行时标准的一个实现。通俗地讲,runC 是一个用来运行容器的轻量级工具,是真正用来运行容器的。

containerd 是Docker 服务端的一个核心组件,它是从dockerd 中剥离出来的 ,它的诞生完全遵循OCI 标准,是容器标准化后的产物。containerd通过containerd-shim 启动并管理runC,可以说containerd真正管理了容器的生命周期。

1. 容器中长期运行 程序

有两种方式:

2. 容器 开启和停止 程序

有两种方式

3. 进入容器

有2种方法

想要web部署在互联网上 或者 在Web问 应用;

个人电脑处于 私网 中; IP地址处于 IPV4 和 IPV6 ;

安装appium

测试adb

改变TCPIP连接方式

容器端口号为 4

开启nginx,就可以在web访问 192.168.0.100;

Dockerfile其实可以看做一个命令集 。每行均为一条命令。每行的个单词,就是命令command。后面的字符串是该命令所要接收的参数。比如ENTRYPOINT /bin/bash。ENTRYPOINT命令的作用就是将后面的参数设置为镜像的entrypoint。至于现有命令的含义,这里不再详述。DockOne上有很多的介绍。

FROM 指令用于指定其后构建新镜像所使用的基础镜像。FROM 指令必是 Dockerfile 文件中的首条命令,启动构建流程后,Docker 将会基于该镜像构建新镜像,FROM 后的命令也会基于这个基础镜像。

在镜像的构建过程中执行特定的命令,并生成一个中间镜像。格式:

最多127层,不是写shell ;

nas安装docker无法连接容器库

含义:后者会在shell中执行。用于配置容器启动后执行的命令,这些命令不能被 docker run 提供的参数覆盖。和 CMD 一样,每个Dockerfile中只能有一个 ENTRYPOINT ,当有多个时一个生效。

题主是否想询问“nas安装docker无法连接容器库怎么办”?

1、首先检查网络设置。docker无法连接容器库和网络设置有关。在群晖的控制面板中,点击网络选项卡,然后点击LAN选项卡。确保网络设置正确,也可以尝试更改为静态IP地址并重新启动群晖以生效。另外,确保docker容器设置中的网络设置正确且与群晖的网络设置一致。

2、其次检查防火墙设置。防火墙是保护计算机和网络资源的重要安全措施,但有时防火墙会阻止docker访问网络。在这种情况下,需要检查群晖的防火墙设置。在群晖的控制面板中,点击“安全”选项卡,然后点击“防火墙”选项,确保dock2.MAINTAINERer容器的端口号在防火墙中打开。

3、检查docker设置。如果网络设置和防火墙设置都正确,需要检查docker的设置。在群晖的控制面板中,点击docker选项卡,然后点击“网络”选项。确保docker的网桥设置正确,并且容器已经连接到正确的网络。此外,还要检查docker容器的端口设置,确保容器已经将端口映射到了正确的地址和端口。

9001是什么默认端口,启动docker run -it --name=mosquitto --privileged -p 1883:1883 -p 9001:9001?

格式: ONBUILD [INSTRUCTION]

9001是supervisor排错,困难程序启动的端口,supervisor是专门管理进程的软件。

题主的命令是映射了1883和9001两个端口到宿主机上,1883是应用的端口,9001是管理程序的端口。

docker容器网络

支持两种格式:

利用Net Namespace可以为Docker容器创建隔离的网络环境,容器具有完全的网络栈,与宿主机隔离。也可以使Docker容器共享主机或者其他容器的网络命名空间,基本可以满足开发者在各种场景下的需要。

通过修改daemon配置文件 /etc/docker/daemon.json 来使用加速器

Docker支持 4种网络模式 :

2)container模式,--net = container : name_or_id指定,不支持多主机。

3)none模式,--net=none指定,不支持多主机。

4)bridge模式,--net=bridge指定,默认设置,不支持多主机。

启动容器的时候使用Host模式,那么该容器与宿主机共用一个Network Namespace,因此容器将不会虚拟自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。

1)容器没有隔离、的网络栈。容器因与宿主机共用网络栈而争抢网络资源,并且容器崩溃也可能导致宿主机崩溃,这在生产环境中是不允许发生的。

2)容器不再拥有所有的端口资源,因为一些端口已经被宿主机服务、Bridge模式的容器端口绑定等其他服务占用了。

需要补充说明的是,Host模式下的容器仅仅是网络命名空间与主机相同,但容器的文件系统、进程列表等还是和与宿主机隔离的。

Container模式是一种特殊的网络模式。该模式下的容器使用其他容器的网络命名空间,网络隔离性会处于Bridge模式与Host模式之间。当容器与其他容器共享网络命名空间时,这两个容器间不存在网络隔离,但它们与宿主机及其他容器又存在网络隔离。

在Kubernetes体系架构下引入Pod概念,Kubernetes为Pod创建一个基础设施容器, 同一Pod下的其他容器都以Container模式 共享这个基础设施容器的网络命名空间,相互之间以localhost访问,构成一个统一的整体。

与前两种不同,None模式的Docker容器拥有自己的Network Namespace,但并不为Docker容器进行网络配置。该Docker容器没有网卡、IP、路由等信息。需要用户为Docker容器添加网卡、配置IP等。

Bridge模式是Docker默认的网络模式,也是开发者最常使用的网络模式。在这种模式下,Docker为容器创建的网络栈,保证容器内的进程使用的网络环境,实现容器之间、容器与宿主机之间的网络栈隔离。同时,通过宿主机上的Docker0网桥,容器可以与宿主机乃至外界进行网络通信。

同一宿主机上,容器之间都是连接在Docker0这个网桥上,Docker0作为虚拟交换机使容器间相互通信 。但是, 由于宿主机的IP地址与容器v pair的IP地址均不在同一个网段 ,故仅仅依靠 v pair和NameSpace的技术 并不足以使宿主机以外的网络主动发现容器的存在。Docker采用了 端口绑定的方式(通过iptables的NAT) ,将宿主机上的端口流量转发到容器内的端口上,这样一来,外界就可以与容器中的进程进行通信。 iptables的介绍,请点我点我 。

创建容器,并将宿主机的3306端口绑定到容器的3306端口:docker run -tid --name db -p 3306:3306 mysql

在宿主机上,可以通过“iptables -t nat -L -n”,查到一条DNAT规则:DNAT tcp --0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.5:3306

Bridge模式的容器与外界通信时,必定会占用宿主机上的端口,从而与宿主机竞争端口资源,这会造成对宿主机端口管理很复杂。同时,由于容器与外界通信是基于三层上iptables NAT,性能和效率损耗是显而易见的。

NAT将地址空间分段的做法引入了额外的复杂度。比如容器中应用所见的IP并不是对外暴露的IP, 因为网络隔离,容器中的应用实际上只能检测到容器的IP,但是需要对外宣称的则是宿主机的IP,这种信息的不对称将带来诸如破坏自注册机制等问题 。

摘抄自陆平的《基于Kubernetes的容器云平台实战》一书的第10章Kubernetes网络

宿主机如何容器中执行的命令

1:你安装docker的没有关闭防火墙,也就是说你访问你安装docker的物理机都访问不了,物理机里的docker就更访问不了了。

2、宿主机可以打开格式为: COPY src desc防火墙让局域网其他设备通过访问宿主机的端口进而访问docker的端口。