Docker 常见问题 (FAQ)-2015

内核需求

  • rhel/centos 要求内核在 2.6.32-431 (系统版本6.5) 及以上
  • debian/ubuntu 要求内核在 3.8 以上

修改镜像/容器文件的存储位置

方法一 修改 docker daemon 的启动参数

-g, --graph=""
  Path to use as the root of the Docker runtime. Default is /var/lib/docker.

如 docker -d --graph=/opt/dockermysql

docker daemon 的启动参数修改方法

rhel/centos 下, 默认启动参数在 /etc/sysconfig/docker, 如:linux

6.x:git

other_args="--graph=/opt/docker "

7.x: (update: 2015-01-21)github

OPTIONS="--graph=/opt/docker "

debian/ubuntu 下, 默认启动参数在 /etc/default/docker, 如:sql

DOCKER_OPTS="--graph=/opt/docker "

方法二 指定挂载目录

mount -o bind /var/lib/docker /opt/docker

永久修改在须要在 /etc/fatab 添加:docker

/opt/docker      /var/lib/docker         none    bind            0 0

方法三 软链接

ln -s /var/lib/docker /opt/docker

容器刚运行就退出了(Exited)

不少人发现刚刚执行了一个 docker run 的命令, 再用 docker ps -a 的时候, 刚刚那个容器就已经 Exited 了, 好比shell

docker run -d <IMAGE> service sshd start

上述命令一执行完就会发现容器就退出了, 那是由于 service sshd start 不是一个前台进程, 这个进程执行完之后就会退出, 因此这里必须使用前台方式(nodaemon)运行进程, 上述例子中要使用ubuntu

docker run -d <IMAGE> /usr/sbin/sshd -D

其余应用程序也要使用对应的 nodaemon 的参数, 没有的话就要加一个不会退出的命令, 如:centos

docker run -d <IMAGE> <CMD> && tail -f xxx.log

selinux (Permission denied)

当开启 selinux 常常会遇到 Permission denied 错误, 如:bash

docker run -i -v /data:/data ubuntu bash

而后运行 ls /data 时就会报以下错误

ls: cannot open directory .: Permission denied

解决方案有两个:

一是关闭宿主机的 selinux

二是在宿主机上添加 selinux 规则, 以上面为例:

chcon -Rt svirt_sandbox_file_t /data

其余情形下 若是是由于 selinux 引发 Permission denied 也要添加相应的规则或者直接关闭 selinux

容器固定 IP

pipework

  • OS: rhel/centos 6.x

在 rhel/centos 6.x 下使用 pipework 时会报以下错误:

Object "netns" is unknown, try "ip help".

缘由是 rhel/centos 6.x 的 iproute 包默认并不支持 ip netns 命令, 因此这里须要安装新的 iproute 包

这里使用 RDO 的源:

yum install -y https://repos.fedorapeople.org/repos/openstack/openstack-icehouse/rdo-release-icehouse-4.noarch.rpm
yum install -y iproute

注意: 在这里最新的 RDO 源(openstack-juno)已经不支持 rhel/centos 6.x 了, 若有更新能够到这个目录下查看
若是已经安装了 openstack-juno 的需先卸载

进入容器

由于容器自己其实就是把进程/资源隔离了, 严格意义上讲不存在所谓的进入容器, 一般这里的所说的进入容器指的是在容器的 namespace 内执行 shell

小于 1.3 版本

小于 1.3 版本的可使用 nsenter:

https://github.com/jpetazzo/nsenter

1.3 版本以上

若是 docker 版本已经在 1.3 以上了, 那么能够用 docker exec 这个命令:

docker exec -it <CONTAINER ID> bash

注意

ssh

不建议使用 ssh 进入容器, 关于为何不建议使用, 请参考以下文章:

docker attach

为何执行 docker attach 卡住了?

首先要明确的是 docker attach 不是一个用来进入容器的命令, 或者说他不是用来在容器内运行一个 bash(shell) 的命令, 它是用来链接到容器中运行中的进程, 也就是容器的 CMD, 容器内 PID=1 的那个进程, 若是这个进程没有 stdout/stderr 那么你将看不到任何输出, 若是它没有接收 stdin 你也没法发送指令给它. 这也就是为何你运行一个 bash 的容器, 就能够 attach 进去执行命令, 而你运行一个 mysql server 的容器就没法操做的缘由

如何退出 attach 的容器

这里要使用 CTRL-P CTRL-Q 来退出容器, 若是使用 CTRL+C 那么会致使容器结束(Exited), 由于它会发送 SIGKILL 给容器的进程, 而后这个容器就 Exited 了, 固然这里可使用 docker attach --sig-proxy=false 防止发送 SIGKILL 给进程

https://docs.docker.com/reference/commandline/cli/#attach
You can detach from the container again (and leave it running) with CTRL-p CTRL-q (for a quiet exit), or CTRL-c which will send a SIGKILL to the container, or CTRL-\ to get a stacktrace of the Docker client when it quits. When you detach from the container's process the exit code will be returned to the client.

Docker 私有库自签名 SSL 报错 (Invalid registry endpoint ... unknown CA certificate)

docker 升级到 1.3 之后使用 docker pull/push 等命令时必需要求 registry 使用 SSL, 不然就会报以下错误

Error: Invalid registry endpoint https://registry.xx.com/v1/: Get https://registry.xx.com/v1/_ping: EOF. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry registry.xx.com` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/registry.xx.com/ca.crt

这里是由于你使用了自签名的证书致使系统不信任, 如报错信息所描述, 解决方法有两个

一是添加 --insecure-registry registry.xx.com 参数到 docker daemon

二是把私有 docker registry 的 CA 证书放到指定的位置(/etc/docker/certs.d/registry.xx.com/ca.crt)

这里的 CA 证书是指你签发 registry.xx.com 这个域名的 SSL 证书所用的 CA
证书的制做方法可参见 http://www.lsproc.com/post/easyrsa-generate-ssl-cert/

docker daemon 重启后某些容器没法启动 (device or resource busy)

当重启 docker daemon 有时候会致使某些容器没法启动, 手动启动容器会报以下错误

Error response from daemon: Cannot start container 5e9bde9b409b:
Error getting container 5e9bde9b409b001bcc685c0b478e925a53a03bab8d8ef3210bf24aa39410e30d
from driver devicemapper:
Error mounting '/dev/mapper/docker-253:0-267081-5e9bde9b409b001bcc685c0b478e925a53a03bab8d8ef3210bf24aa39410e30d'
on
'/var/lib/docker/devicemapper/mnt/5e9bde9b409b001bcc685c0b478e925a53a03bab8d8ef3210bf24aa39410e30d':
device or resource busy

目前来看这应该是一个 bug: docker/docker#5684docker/docker#4036

解决办法有两个:

一是发现报错后, 在启动容器以前手动 umount:

umount /var/lib/docker/devicemapper/mnt/5e9bde9b409b001bcc685c0b478e925a53a03bab8d8ef3210bf24aa39410e30d

二是 docker daemon stop 时先中止容器运行, 修改 /etc/init.d/docker 以下

stop() {
    [ -x $exec ] || exit 5

    echo -n $"Stopping $prog: "
    if [[ -n $($exec ps -q) ]]; then
        $exec stop $($exec ps -q) > /dev/null
    fi
    killproc -p $pidfile -d 300 $prog
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

不过这样由于会中止全部容器, 因此重启速度会变慢

另外重启后全部容器默认都不会启动, 若是让容器在 daemon 启动时自动开启, 那么须要在 docker run 时添加参数 --restart always, 如:

docker run -d --restart always <IMAGE> <CMD>

docker 1.6.x 关闭 iptables 时不能 link 容器

2015-06-08 更新

使用 docker 1.6, daemon 参数关闭了 iptables 选项时(--iptables=false), link 容器时会报错:

Cannot start container 35437aa2c224d580d7555a2f900b95d6d5ab282bb91c34e96ae0cda106557ff0: (exit status 1)

解决方法一是 daemon 打开 iptables(--iptables=true), 或者手动建立 DOCKER clain:

iptables -N DOCKER

bug 详情在此: https://github.com/docker/docker/issues/12701

docker-compose 使用2进制方式安装后每过一段时间就不可用

2015-10-11 更新

使用 docker-compose 的过程当中发现每过一段时间2进制文件就不可用, 报以下错误

Cannot open self /usr/bin/docker-compose or archive /usr/bin/docker-compose.pkg

解决方法为(rhel/centos):

echo "-b /usr/bin/docker-compose" > /etc/prelink.conf.d/docker-compose.conf

debian/ubuntu 也找到 prelink 相应的配置文件地址增长上述配置便可

bug 详情在此: https://github.com/docker/compose/issues/1135

延伸阅读

相关文章
相关标签/搜索