私信  •  关注

Thomasleveil

Thomasleveil 最近创建的主题
Thomasleveil 最近回复了
6 年前
回复了 Thomasleveil 创建的主题 » 连接到upstram-Docker时连接被拒绝

docker-compose exec backend netstat -lnpt 向我们展示了用于服务的httpd web服务器 backend 正在监听端口 80 而不是 81

很可能,你的档案 apache/Dockerfile 它试图提供自定义httpd配置的方式不正确 apache/apache.conf .

进一步调查:

  • 确保apache conf的主要内容符合您的期望: docker-compose exec backend cat /usr/local/apache2/conf/httpd.conf
  • docker-compose logs backend

这样做,你就会意识到你错过了 Listen 81 阿帕奇/Dockerfile 文件:

# apache/Dockerfile
FROM httpd:2.4.32-alpine

RUN apk update; \
    apk upgrade;

# Copy apache vhost file to proxy php requests to php-fpm container
COPY apache/apache.conf /usr/local/apache2/conf/apache.conf

RUN echo "Listen 81" >> /usr/local/apache2/conf/httpd.conf
RUN echo "Include /usr/local/apache2/conf/apache.conf" >> /usr/local/apache2/conf/httpd.conf

为什么后端容器监听端口81?

使不同的容器打开不同的端口不会增加任何值。每个容器都有自己的IP地址,因此不需要避免docker compose项目中定义的服务之间的端口冲突。

6 年前
回复了 Thomasleveil 创建的主题 » Docker:我们可以重用一个图像层来构建另一个图像吗

从图像层缓存中获益的一个简单方法是只创建第一层的基础图像。

然后使用 FROM <base image> 在你的其他档案里。

Dockerfile基:

FROM scratch
ADD ./system.tar.gz /
docker build -f Dockerfile-base -t base .

文件1:

FROM base
COPY ./somefiles /
docker build -f Dockerfile-1 -t image1 .

FROM base
COPY ./otherfiles /
docker build -f Dockerfile-2 -t image2 .

建议读取

Best practices for writing Dockerfiles § Leverage build cache

编辑: 如果你正在使用 Docker-for-mac Docker-for-Windows 18.03+,只需使用主机连接到mysql服务 host.docker.internal .

从Docker 18.09.3开始,这在Docker for Linux上不起作用。 fix 已于2019年3月8日提交,有望合并到代码库中。在此之前,解决方法是使用容器,如 qoomon's answer .


TLDR

使用 --network="host" 在你 docker run 命令,然后 127.0.0.1 在Docker容器中将指向Docker主机。

注意:此模式仅适用于Docker for Linux, per the documentation .


关于Docker容器联网模式的说明

Docker提供 different networking modes 当运行容器时。根据您选择的模式,您将以不同的方式连接到Docker主机上运行的MySQL数据库。

docker run--network=“桥”(默认)

Docker创建一个名为 docker0 默认情况下。Docker主机和Docker容器在该网桥上都有一个IP地址。

在Docker主机上,键入 sudo ip addr show docker0 输出如下:

[vagrant@docker:~] $ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
       valid_lft forever preferred_lft forever

所以我的Docker主机有IP地址 172.17.42.1 道克尔0 网络接口。

现在,启动一个新容器并在上面放置一个外壳: docker run --rm -it ubuntu:trusty bash 在容器类型内 ip addr show eth0 要了解其主网络接口是如何设置的:

root@e77f6a1b3740:/# ip addr show eth0
863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
    inet 172.17.1.192/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
       valid_lft forever preferred_lft forever

这里我的容器有IP地址 172.17.1.192 . 现在看看路由表:

root@e77f6a1b3740:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.42.1     0.0.0.0         UG    0      0        0 eth0
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

所以Docker主机的IP地址 172.1742.1 设置为默认路由并可从容器访问。

root@e77f6a1b3740:/# ping 172.17.42.1
PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms

docker run--network=“主机”

或者,您可以使用 network settings set to host . 这样的容器将与Docker主机共享网络堆栈,从容器的角度来看, localhost (或 127.0.0.1 )将引用Docker主机。

请注意,在Docker容器中打开的任何端口都将在Docker主机上打开。而这不需要 -p or -P docker run option .

我的Docker主机上的IP配置:

[vagrant@docker:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

从码头的集装箱里 主办 模式:

[vagrant@docker:~] $ docker run --rm -it --network=host ubuntu:trusty ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

如你所见,Docker主机和Docker容器共享完全相同的网络接口,因此具有相同的IP地址。


从容器连接到mysql

桥式模式

从中的容器访问Docker主机上运行的MySQL 桥式模式 ,您需要确保mysql服务正在监听 172.1742.1 IP地址。

为此,请确保 bind-address = 172.17.42.1 bind-address = 0.0.0.0 在mysql配置文件(my.cnf)中。

如果需要使用网关的IP地址设置环境变量,可以在容器中运行以下代码:

export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')

然后在应用程序中,使用 DOCKER_HOST_IP 打开到MySQL的连接的环境变量。

注: 如果你使用 绑定地址=0.0.0.0 mysql服务器将监听所有网络接口上的连接。这意味着可以从Internet访问MySQL服务器;请确保相应地设置防火墙规则。

附注2: 如果你使用 绑定地址=172.17.42.1 你的mysql服务器不会监听连接到 127.0.0.1 . 在Docker主机上运行的进程要连接到MySQL,必须使用 172.1742.1 IP地址。

宿主模式

从中的容器访问Docker主机上运行的MySQL 宿主模式 ,你可以保留 bind-address = 127.0.0.1 在mysql配置中,您只需要连接到 127.0.0.1 从您的容器:

[vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

注: 确实使用 mysql -h 127.0.0.1 而不是 mysql -h localhost ;否则mysql客户端将尝试使用unix套接字进行连接。