Talk about the port problems of docker

Today, let's talk about docker ports in the system. Common ports include program port in container, container port, host port, EXPOSE port in Dockerfile, docker compose and port in docker run.

It seems that there are many ports, but when connecting, the real ports are only program ports and host ports. Others are declarations of ports and will not actually open the service of ports.

Next, take nginx and redis images as examples to introduce the relationship between these ports: nginx program port 80, mapping host port 30080; Redis program port 6379, mapping host port 36379. The actual communication is shown in the figure below

The program port is the container port

The program port is the actual container port. They are the same port. No other configuration is required. After the container is started, the local machine or other containers on the same network access the services of the container through the program port in the container (i.e. container port).

Take nginx as an example, start the container (web name)

[root@localhost ~]# docker run -d --name web nginx 
3cb58fd8e585e0b015e7e42e9587df95359e1d133ff5371c6838fd303132d2ef
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
3cb58fd8e585   nginx     "/docker-entrypoint...."   17 seconds ago   Up 15 seconds   80/tcp    web

The local server verifies the access to the container port, first check the container ip, and then check the communication of port 80 by telnet. The following highlighted information indicates that the port access is normal

[root@localhost ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
172.17.0.2
[root@localhost ~]# curl http://172.17.0.2:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
. . . . .

The access to the Internet is verified, and the connection is blocked

$ curl http://192.168.8.190:80
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
curl: (7) Failed to connect to 192.168.8.190 port 80: Connection refused

Export port in Dockerfile

  • Conclusion: the export in Dockerfile is only a declaration of the port, which is displayed during ps or inspect, but does not actually open the service of the port. The actual port is determined by the port of the program in the container

1. Modify the port of nginx in the web container to 88, and the restart takes effect

[root@localhost ~]# docker exec -it web /bin/bash
root@9ac59b2d523f:/# vi /etc/nginx/conf.d/default.conf 
  modify listen The parameter value is 88
[root@localhost ~]# docker restart web
web

2. Check the port of Expose in the Dockerfile file of the image: 80

[root@localhost ~]# docker history nginx
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
605c77e624dd   9 days ago    /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon...   0B        
<missing>      9 days ago    /bin/sh -c #(nop)  STOPSIGNAL SIGQUIT           0B        
<missing>      9 days ago    /bin/sh -c #(nop)  EXPOSE 80                    0B        

3. Check the port displayed in the container information: 80

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS      NAMES
c24aa7848e38   nginx         "/docker-entrypoint...."   39 seconds ago   Up 37 seconds   80/tcp     web

4. Verify the actual accessible port. 80 refused to connect, 88 access normal

[root@localhost ~]# curl http://172.17.0.2:80
curl: (7) Failed connect to 172.17.0.2:80; connection denied
[root@localhost ~]# curl http://172.17.0.2:88
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Container port mapping host port

  • Conclusion: if the container does not specify a host mapping port, the network outside the host cannot access the container, and only the local network can access it.

1. When the container is started and the host mapping port is not specified

[root@localhost ~]# docker run -d --name web nginx 
3cb58fd8e585e0b015e7e42e9587df95359e1d133ff5371c6838fd303132d2ef
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3cb58fd8e585 nginx "/docker-entrypoint...." 17 seconds ago Up 15 seconds 80/tcp web

Internet access to host port 80 is blocked

 

 

 2. Start the container and specify host mapping port 30080 mapping container port 80

[root@localhost ~]# docker run -d -p 30080:80 --name web nginx
04ef8440c357b81da934e91e786612b6027d20ea2e7cb3bd81ae91a9ca15a807

[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
04ef8440c357 nginx "/docker-entrypoint...." 8 minutes ago Up 8 minutes 0.0.0.0:30080->80/tcp, :::30080->80/tcp web

Internet access to host 30080 succeeded

 

 

Supplement: use - p to map ports in docker run and - port to map ports in docker compose. The effect is the same.

Connection between containers

Access the started container web above, container port 80, mapping host port 30080, container ip: 172.17.0.2, host ip: 192.168.8.190

  • Summary: container ip: container port, host ip: host port. Access can only be accessed when the ip matches the port.

Start a redis container and access the web container service from the redis container.

[root@localhost ~]# docker run -d --name redis redis:6.0.8 
[root@localhost ~]# docker exec -it redis /bin/bash
root@25d8d484aa5b:/data# curl http://172.17.0.2:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...........
root@25d8d484aa5b:/data# curl http://172.17.0.2:30080
curl: (7) Failed to connect to 172.17.0.2 port 30080: Connection refused

root@25d8d484aa5b:/data# curl http://192.168.8.190:30080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
............

  root@25d8d484aa5b:/data# curl http://192.168.8.190:80
  curl: (7) Failed to connect to 192.168.8.190 port 80: Connection refused

 

Keywords: Docker

Added by just me and php on Sat, 08 Jan 2022 10:58:45 +0200