选择不同的网络,尽管从未设置任何网络。

huangapple go评论91阅读模式
英文:

docker containers choosing different networks despite never setting any

问题

我在设置我的Go服务的Docker配置时遇到了很糟糕的问题。以下是我的设置概述:

    name = "main_arm64",
    embed = [":server_lib"],
    goarch = "arm64",
    goos = "linux",
    visibility = ["//visibility:public"],
)

container_image(
    name = "ww_server_image",
    base = "@go_image_static_arm64//image",
    entrypoint = ["/main_arm64"],
    files = [":main_arm64"],
    ports = [
        "8080",
        "3306",
    ],
)

我在http://localhost:8080上运行了一个GraphQL Playground(HTTP),尽管端口被暴露,但我无法访问Playground的用户界面。

我所尝试做的只是:

  1. 能够访问GraphQL Playground和容器中运行在其他端口上的任何其他API。
  2. 能够从我的Docker化的Go应用程序向单独的MySQL容器发出请求(我无法弄清楚如何使用rules_docker将它们放在同一个网络上)。
  3. docker exec -it ... /bin/bash 进入我的Docker容器(这没有起作用,因为bash没有安装,但我不知道如何通过container_image命令安装bash)。

这是错误信息:
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown

如果我获取生成的Docker镜像ID并运行docker run -p 8080:8080 IMAGE_ID,我可以访问GraphQL Playground,但无法与MySQL容器通信。

如果我更改网络设置为:docker run --network=host -p 8080:8080 IMAGE_ID,Docker化的Go应用程序可以成功与MySQL容器通信,但是GraphQL Playground变得无法访问。只有在保持--network=bridge的情况下,才能访问GraphQL Playground。我不确定为什么MySQL没有使用bridge,因为我在启动时没有指定网络。这是我获取MySQL容器的方式:
docker run -p 3306:3306 --name my-db -e MYSQL_ROOT_PASSWORD=testing -d mysql:8.0.31

英文:

I'm having a horrible time with setting up my Docker configuration for my go service. Below is an overview of my setup

go_binary(
    name = "main_arm64",
    embed = [":server_lib"],
    goarch = "arm64",
    goos = "linux",
    visibility = ["//visibility:public"],
)

container_image(
    name = "ww_server_image",
    base = "@go_image_static_arm64//image",
    entrypoint = ["/main_arm64"],
    files = [":main_arm64"],
    ports = [
        "8080",
        "3306",
    ],
)

I have a GraphQL Playgroud (HTTP) running on http://localhost:8080, and despite the port supposedly being exposed, i cant access the playground UI.

All I'm trying to do is:

  1. Be able to access the GraphQL playground and any other APIs running on other ports within the container
  2. Be able to make requests from my Dockerized Go app to a separate MySQL container (I can't figure out how to put them on the same network with rules_docker).
  3. docker exec -it ... /bin/bash into my docker container (this hasnt been working because bash isnt installed, yet i have no idea how to install bash via this container_image command)
    Here is the error:
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown

If i take the generated docker image ID and run docker run -p 8080:8080 IMAGE_ID, I'm able to access the GraphQL playground, but can't communicate with the MySQL container

If I change the network as such: docker run --network=host -p 8080:8080 IMAGE_ID the Dockerized Go app can successfully communicate with the MySQL container, but then the GraphQL playground becomes inaccessible. The GraphQL playground only becomes accessible if I maintain --network=bridge. I'm not sure why MySQL isn't using bridge as well, since i never specified the network when starting it. This is how I got the MySQL container

docker run -p 3306:3306 --name my-db -e MYSQL_ROOT_PASSWORD=testing -d mysql:8.0.31

答案1

得分: 1

所以,你这里有几个问题:

首先,你很可能可以通过 docker exec -it container_name /bin/sh 访问没有安装 bash 的容器,因为大多数容器至少都带有 sh。

其次,你的主机每个端口只能有一个服务,所以当你将网络主机分配给一个容器时,会覆盖其他容器的端口映射,这就是为什么在使用网络主机启动 go 应用后,GraphQL 变得无法访问的原因,因为它们都使用端口 8080。

第三,当你使用默认的桥接网络时,你的容器只能通过 IP 进行通信,而不能通过容器名称进行通信。

此外,你不需要端口映射来让容器彼此通信。端口映射只在 Docker 网络之外的某些东西需要访问时才需要。

你最好的选择是使用 docker network create network_name 创建一个网络,然后通过 Docker 运行命令使用 --network network_name 将网络分配给所有容器。

你不一定需要端口映射来运行应用程序,但是当你想从外部访问服务时(例如主机的浏览器),请确保为每个容器使用唯一的端口。外部端口不必与容器的内部端口相同,你可以进行映射,例如 -p 8081:8080

由于所有容器都属于一个应用程序,你可能还想检查一下是否使用 Docker Compose 是更好的选择,因为它允许你通过一个配置文件轻松管理所有容器。

英文:

So, you have several problems here:

First of all, you can most likely access containers that don't have bash installed through docker exec -it container_name /bin/sh, as most containers at least come with sh.

Second, your host machine can only have one service per port, so when you assign network host to a container, you overwrite the port mapping of other containers, which is why your GraphQL became unreachable after starting the go app with network host as a result of that they both use port 8080.

Third, when you use the default bridge network, your containers can only communicate by IP, not by container name.

Also, you don't need a port mapping to let the containers communicate with each other. Port mapping is only required, when something outside the Docker network needs the access.

Your best chance is to create a network with docker network create network_name and then to assign the network to all containers with --network network_name through the Docker run command.

You don't necessarily need a port mapping to get your application running, but when you want to access a service from outside - e.g. your hosts browser - make sure to take a unique port for each container. The port outside doesn't have to be the same as the container's internal port, you can map for instance -p 8081:8080.

Since all containers belong to one app, you also might want to check whether docker compose is the better alternative as it allows you to easily manage all your container by one config file.

答案2

得分: 0

答案在这里:
https://stackoverflow.com/questions/52504318/unable-to-connect-to-mysql-server-with-go-and-docker-dial-tcp-127-0-0-13306

结果表明,我需要使用以下地址实际访问MySQL,因为Mac上的Docker使用Linux虚拟机:

docker.for.mac.localhost:3306
英文:

the answer was here:
https://stackoverflow.com/questions/52504318/unable-to-connect-to-mysql-server-with-go-and-docker-dial-tcp-127-0-0-13306

turns out i need to actually access MySQL using the following address, since Docker on Mac uses Linux VM:

docker.for.mac.localhost:3306

huangapple
  • 本文由 发表于 2023年1月17日 07:49:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75140795.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定