docker开发时踩过的坑

本文记录在使用docker做开发时踩过的一些坑,包括docker本身的和在docker中使用其他工具的坑。

  1. 镜像层数存在限制
    暂时使用`docker export | import`重新制作新的镜像来解决
    
  2. CMD和ENTRYPOINT区别

    报错:docker run -ti ethereum/client-go /bin/sh
    正确:docker run -ti --entrypoint=/bin/sh ethereum/client-go
    
  3. pull不到最新的镜像 (超级坑,似乎是镜像层数到了一定数量,就会这样)

    • digest值不一样是肯定的
    • docker export | import 就解决了
    • 原因还未知,不能复现
  4. CMD指令报错

    Dockerfile如下:
    
      FROM busybox
      CMD ["/bin/ls /"]
    
    运行时报如下错误
    
    docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"/bin/ls /\": stat /bin/ls /: no such file or directory": unknown.
    
    原因是CMD使用错误,CMD应该为数组`CMD ["/bin/ls","/"]`
    
  5. /etc/hosts文件不能覆盖,在dockerfile中无法写入

    Dockerfile如下,无法修改/etc/hosts文件
    FROM busybox
    RUN echo > /etc/hosts
    
  6. 内网docker registry login报503错误

    原因未知,隔一段时间后再次登陆成功。可能是服务问题
    
  7. 脚本在拉取私有仓库时,pull镜像提示找不到

    [root@x ~]# docker pull internal.docker.registry/xxx/yyy:latest
    Pulling repository internal.docker.registry/xxx/yyy
    Error: image xxx/yyy:latest not found
    
    原因:
    未登录,坑爹的是私服响应中没有任何提示未登录
    解决:
    在脚本中每一次pull前docker login
    
  8. cache

    Dockerfile如下
    
      FROM xxx
      pip install --upgrade y
      ...
      CMD ["xxx.sh"]
    
    因为缓存的原因,y依赖包并没有升级
    
    解决办法:将镜像制作分为两部分,不需要缓存的build时添加--no-cache参数。参考1
    
    一行cache改变,接下来的指令都不会缓存
    
  9. pipenv无法安装私有仓库的库

    私有仓库因为没有证书,所以没有走https。pip安装的时候可以使用trust-host来使用http协议安装软件,但是pipenv命令行中没有找到类似trust-host的参数。
    
    这个问题属于pipenv的使用问题,只是因为在Dockerfile中用到了pipenv,也就记在这里了。
    
    解决办法:在配置中使用verify_ssl参数,示例配置如下
    
    [[source]]
    url = "https://pypi.python.org/simple"
    verify_ssl = true
    name = "pypi"
    
    [[source]]
    url = "http://pypi.home.kennethreitz.org/simple"
    verify_ssl = false
    name = "home"
    
  10. 容器运行一段时间后根目录只读

    现象:
    https://github.com/moby/moby/issues/18010
    
    应用层奇怪的bug和这个有关,比如代理无法正常工作,是因为没有空间创建证书了。
    
    原因:
    内核重新挂载文件系统 grep -B10 "read-only" /var/log/messages.
    重新挂载的原因好像是磁盘不够了
    
    解决办法:
    删除磁盘中的多余文件,腾出空间
    
  11. docker中python程序日志没有实时输出

    现象:
      docker log没有看到python打印的日志,过了一段时间后才能看到
    原因:
      存在输出缓冲区
    解决方法:
    * python -u <script> 禁止python的缓冲区
    

参考

  1. Bust cache bust within Dockerfile without providing external build args