网络端口映射
Docker网络端口映射使得通过访问宿主机器上的某个端口,可以访问到某个Docker容器上的端口。这样Docker容器就可以对外提供服务了。
查看某个容器的端口映射情况
$ docker port [containerId]
https://docs.docker.com/engine/reference/commandline/run/
Create a network
The -d
flag tells Docker to use the bridge
driver for the new network.
Once you have prepared the overlay
network prerequisites you simply choose a Docker host in the cluster and issue the following to create the network:
$ docker network create -d overlay my-multihost-network
Network names must be unique. The Docker daemon attempts to identify naming conflicts but this is not guaranteed. It is the user’s responsibility to avoid name conflicts.
Demo
To build web applications that act in concert but do so securely, create a network. Networks, by definition, provide complete isolation for containers. You can add containers to a network when you first run a container.
Launch a container running a PostgreSQL database and pass it the --net=my_bridge
flag to connect it to your new network:
$ docker run -d --net=my_bridge --name db training/postgres
If you inspect your my_bridge
you can see it has a container attached. You can also inspect your container to see where it is connected:
$ docker inspect --format='{{json .NetworkSettings.Networks}}' db
{"my_bridge":{"NetworkID":"7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99",
"EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"10.0.0.1","IPAddress":"10.0.0.254","IPPrefixLen":24,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}}
Now, go ahead and start your by now familiar web application. This time don’t specify a network.
$ docker run -d --name web training/webapp python app.py
Which network is your web
application running under? Inspect the application to verify that it is running in the default bridge
network.
$ docker inspect --format='{{json .NetworkSettings.Networks}}' web
{"bridge":{"NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812",
"EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"172.17.0.1","IPAddress":"10.0.0.2","IPPrefixLen":24,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}}
Then, get the IP address of your web
$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
172.17.0.2
Now, open a shell to your running db
container:
$ docker container exec -it db bash
root@a205f0dd33b2:/# ping 172.17.0.2
ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
^C
--- 172.17.0.2 ping statistics ---
44 packets transmitted, 0 received, 100% packet loss, time 43185ms
After a bit, use CTRL-C
to end the ping
and notice that the ping failed. That is because the two containers are running on different networks. You can fix that. Then, use the exit
command to close the container.
Docker networking allows you to attach a container to as many networks as you like. You can also attach an already running container. Go ahead and attach your running web
app to the my_bridge
.
$ docker network connect my_bridge web
Open a shell into the db
application again and try the ping command. This time just use the container name web
rather than the IP address.
$ docker container exec -it db bash
root@a205f0dd33b2:/# ping web
PING web (10.0.0.2) 56(84) bytes of data.
64 bytes from web (10.0.0.2): icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from web (10.0.0.2): icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from web (10.0.0.2): icmp_seq=3 ttl=64 time=0.066 ms
^C
--- web ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.060/0.073/0.095/0.018 ms
The ping
shows it is contacting a different IP address, the address on the my_bridge
which is different from its address on the bridge
network.
Display Info of a specified Network
docker network inspect [OPTIONS] NETWORK [NETWORK...]
Returns information about one or more networks. By default, this command renders all results in a JSON object.
List all networks
Lists all the networks the Engine daemon
knows about. This includes the networks that span across multiple hosts in a cluster.
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
7fca4eb8c647 bridge bridge local
9f904ee27bf5 none null local
cf03ee007fb4 host host local
78b03ee04fc4 multi-host overlay swarm
Use the --no-trunc
option to display the full network id:
Ref to https://docs.docker.com/engine/reference/commandline/network_ls/
Connect containers
When you start a container, use the --network
flag to connect it to a network. This example adds the busybox
container to the mynet
network:
$ docker run -itd --network=mynet busybox
If you want to add a container to a network after the container is already running, use the docker network connect
subcommand.
You can connect multiple containers to the same network. Once connected, the containers can communicate using only another container’s IP address or name. For overlay
networks or custom plugins that support multi-host connectivity, containers connected to the same multi-host network but launched from different Engines can also communicate in this way.
You can disconnect a container from a network using the docker network disconnect
command.
Specify the IP address a container will use on a given network
You can specify the IP address you want to be assigned to the container’s interface.
$ docker network connect --ip 10.10.36.122 multi-host-network container2
Misc
Access the Host from Containers
On Linux, Docker manipulates iptables
rules to provide network isolation. While this is an implementation detail and you should not modify the rules Docker inserts into your iptables
policies, it does have some implications on what you need to do if you want to have your own policies in addition to those managed by Docker.
If you’re running Docker on a host that is exposed to the Internet, you will probably want to have iptables policies in place that prevent unauthorized access to containers or other services running on your host. This page describes how to achieve that, and what caveats you need to be aware of.
You may need to modify the iptables
rules on your host to permit connections from Docker containers. Something like this will do the trick:
# iptables -A INPUT -i docker0 -j ACCEPT
This would permit access to any ports on the host from Docker containers. Note that:
- iptables rules are ordered, and this rule may or may not do the right thing depending on what other rules come before it.
- you will only be able to access host services that are either (a) listening on
INADDR_ANY
(aka 0.0.0.0) or that are explicitly listening on thedocker0
interface.
Ref
Reference
- https://docs.docker.com/engine/reference/commandline/network_create/
- https://docs.docker.com/network/
- https://docs.docker.com/engine/tutorials/networkingcontainers/
- https://docs.docker.com/network/iptables/