我想通过 docker Rest api 创建一个容器,可以从主机访问该容器,但无需外部网络访问。
我已经阅读了文档几次,但仍然无法让它工作。
当启动时传入网络名称作为要连接的网络时,没有暴露端口。
如果我稍后连接,容器将连接到 2 个网络 - 默认网桥和我的网络。在后一种情况下,暴露的端口可以正常工作。
我该如何配置?
编辑:
我做了更多实验 - 我正在设置
Internal: true
根据文档,只有其他连接的容器才能访问该容器。
我想从主机访问容器,这样网络就不能是内部的。
将其设置为 False 允许我访问容器,但我也可以从容器内连接到 google。
相关阅读:
https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerCreate
第二个链接讨论创建一个桥接网络,默认情况下不应有外部网关。
这是检查的网络以及其他一些有用的信息
=> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cecb660da65c datumai/mh-mock-runtime:latest "uvicorn app.main:ap…" 5 minutes ago Up 5 minutes 0.0.0.0:55807->80/tcp datumai-model
=> docker inspect ID_CONTAINER
"NetworkSettings": {
"Bridge": "",
"SandboxID": "f5509cdf337b740ad50290766854aebddadd802366c780cf4d5e31a7050ffbd7",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "55807"
}
]
},
"SandboxKey": "/var/run/docker/netns/f5509cdf337b",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"datumai-model-network-offline": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"cecb660da65c"
],
"NetworkID": "59d034f30a97de377c6d3745b1b5764c487d58a5aa2e69dedd2dc7f4ece71e33",
"EndpointID": "f12b9a39c85ecda7f60edea34c09cc8773eb61be90dee281228b59d7bb6eba47",
"Gateway": "172.27.0.1",
"IPAddress": "172.27.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:1b:00:02",
"DriverOpts": null
}
}
}
}
=> docker inspect ID_OF_NETWORK
[
{
"Name": "datumai-model-network-offline",
"Id": "59d034f30a97de377c6d3745b1b5764c487d58a5aa2e69dedd2dc7f4ece71e33",
"Created": "2024-01-07T02:48:35.182210136Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.27.0.0/16",
"Gateway": "172.27.0.1"
}
]
},
"Internal": false,
"Attachable": true,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"e42176ec9ae1b540a3703ccd6c09d44782dd17e5fba8bc7d4ff2a7403daf729a": {
"Name": "datumai-model",
"EndpointID": "e9ec6900d53c772a84f136d2599b1410aca0366518009a522a31b78de70a00d0",
"MacAddress": "02:42:ac:1b:00:02",
"IPv4Address": "172.27.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.datumai.model": "true"
}
}
]
我想从主机访问容器,这样网络就不能是内部的。
事实上,即使使用
internal
网络,只要直接访问容器ip(而不是使用端口发布),也可以从主机访问容器。例如,如果我们启动一个像这样的简单 Web 服务器:
docker network create --internal internal
docker run --net internal --rm --name web docker.io/alpinelinux/darkhttpd
我们可以这样获取容器的ip地址:
$ docker container inspect web --format '{{.NetworkSettings.Networks.internal.IPAddress}}'
192.168.224.2
我们可以成功连接到该容器中的 Web 服务:
$ curl 192.168.224.2:8080
<html>
...
</html>
因为它位于
internal
网络上,所以容器没有出站网络连接:
$ docker exec -it web wget -O- google.com
wget: bad address 'google.com'
$ docker exec -it web wget -O- 142.251.40.206
Connecting to 142.251.40.206 (142.251.40.206:80)
wget: can't connect to remote host (142.251.40.206): Operation timed out
第二个链接讨论创建一个桥接网络,默认情况下不应有外部网关。
这是非常不准确的。桥接网络是最常见的 Docker 网络类型,当然它有一个默认网关,因为大多数人do想要出站网络访问:
$ docker network create --driver=bridge mynetwork
52d2506adc651486300a95ea80855822180c2af0242ca1572ed6ab71e748de37
$ docker run --rm --net mynetwork docker.io/alpine ip route
default via 192.168.240.1 dev eth0
192.168.240.0/20 dev eth0 scope link src 192.168.240.2