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

延伸閱讀

相關文章
相關標籤/搜索