网络互访问题、入口脚本问题等

网络

主机互访

宿主机指运行docker服务的主机,容器指宿主机上运行的各个container。

**注意:**localhost127.0.0.1永远是发起请求的程序所在的系统(命名空间)

  • 在宿主机内,localhost127.0.0.1是宿主机本身
  • 在各个容器内,localhost127.0.0.1是各个容器本身(同命名空间)

提示:进入容器内执行IP addr可以获取到容器本身的IP,如172.17.0.28。将该IP的最后一段数字改成1,即172.17.0.1是这个容器的网关(宿主机)的IP。

假设宿主机容器之间已经配置好了网络,且容器绑定宿主机端口时绑定了宿主机的所有网卡(默认)

  1. 宿主机访问容器
    • 通过localhost127.0.0.1加上容器绑定的宿主机端口
    • 通过要访问的容器本身的IP加上容器内服务监听的端口
  2. 容器访问宿主机
          容器内localhost127.0.0.1是不能访问到宿主机的
    • 通过宿主机内网、公网等IP加上宿主机端口
    • 通过容器网关的IP加上宿主机端口
    • 其他方案:qoomon/docker-host
  3. 容器访问本容器
    • 通过localhost127.0.0.1加上容器内服务监听的端口
    • 通过宿主机内网、公网等IP加上容器绑定的宿主机端口
  4. 容器访问其他容器
    • 通过目标容器的容器IP加上目标容器内服务监听的端口
    • 通过目标容器的主机名、容器名加上目标容器内服务监听的端口
    • 通过宿主机内网、公网等IP加上目标容器绑定的宿主机端口

容器入口

ENTRYPOINT与CMD的异同

表现

  • 如果设置了ENTRYPOINT,容器启动run或者容器执行命令exec时的入口程序。每次都会执行
  • 所有命令都会作为ENTRYPOINT的参数,交由ENTRYPOINT脚本(程序)处理并执行。如果没有设置ENTRYPOINT,所有的命令会直接执行
  • CMD是容器启动时的默认命令,通常是一个守护进程
  • ENTRYPOINTCMD的第一个参数必须是PATH能找到的可执行文件

执行情况

No ENTRYPOINT ENTRYPOINT exec_entry p1_entry ENTRYPOINT [“exec_entry”, “p1_entry”]
No CMD error, not allowed /bin/sh -c exec_entry p1_entry exec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”] exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry exec_cmd p1_cmd
CMD [“p1_cmd”, “p2_cmd”] p1_cmd p2_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry p1_cmd p2_cmd
CMD exec_cmd p1_cmd /bin/sh -c exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

终止信号

自定义ENTRYPOINT需要注意终止信号的传递问题(PID 0的进程接受终止信号),否则终止容器时必须等容器终止超时才会停止容器。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/env bash
set -e

if [ "$1" = 'postgres' ]; then
    chown -R postgres "$PGDATA"

    if [ -z "$(ls -A "$PGDATA")" ]; then
        gosu postgres initdb
    fi

    exec gosu postgres "$@"
fi

exec "$@"

执行多个命令

  • 自定义ENTRYPOINT或CMD脚本(制作镜像或者通过Volume替换原有的可执行文件)
  • 将多行脚本作为shell参数执行(docker-compose.yaml)示例
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    version: "3"
    services:
      app:
        image: nginx:alpine
        command:
        - sh
        - "-c"
        - |
          cd /
          ls
          nginx -s "daemon off;"
    

参考文章