docker使用

CentOS 7中docker的安装和启动

若需要更新源

备份/etc/yum.repos.d/CentOS-Base.repo

1
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

下载源文件:

1
wget http://mirrors.163.com/.help/CentOS7-Base-163.repo

运行以下命令生成缓存:

1
2
yum clean all
yum makecache

安装docker

1
yum install docker

启动docker服务

安装完成后,使用下面的命令来启动docker服务,并将其设置为开机启动:
采用CentOS 7中支持的新式 systemd 语法,如下:

1
2
systemctl start docker.service
systemctl enable docker.service

ubuntu14.04安装

更新源

1
2
3
4
Precise 12.04 (LTS)	deb https://apt.dockerproject.org/repo ubuntu-precise main
Trusty 14.04 (LTS) deb https://apt.dockerproject.org/repo ubuntu-trusty main
Wily 15.10 deb https://apt.dockerproject.org/repo ubuntu-wily main
Xenial 16.04 (LTS) deb https://apt.dockerproject.org/repo ubuntu-xenial main
1
2
echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" > /etc/apt/sources.list.d/docker.list
apt-get update

安装docker

1
apt-get install docker-engine

启动

1
2
docker version
service docker start

使用registry容器

拉取镜像

1
docker pull daocloud.io/library/registry

启动registry

HOST_DIR为宿主机目录,存储镜像文件

1
docker run -d --restart always -p 5000:5000 -v <HOST_DIR>:/tmp/registry daocloud.io/registry

push docker镜像

在需要pull/push的机子上,centos下编辑/etc/sysconfig/docker,ubuntu下修改/etc/default/docker,在OPTIONS项后面加入–insecure-registry ip:5000,然后重启docker。

按照docker镜像命名规则为镜像打tag:

1
docker tag b477a2162de3 116.56.140.66:5000/jianzzz/red5:v1

push到私有docker-registry:

1
docker push 116.56.140.66:5000/jianzzz/red5:v1

docker中镜像的命名规则,如:registry.domain.com/mycom/base:latest,这是一个完整的image名称,各部分的作用:
registry.domain.com: image所在服务器地,如果是官方的hub部分忽略
mycom:namespace,被称为命名空间,或者说成是你镜像的一个分类
base:这个是镜像的具体名字
latest:这是此image的版本号,当然也可能是其它的,如1.1之类的

使用remote api

Centos docker配置文件位置:/etc/sysconfig/docker
Ubuntu docker配置文件位置:/etc/default/docker

修改配置文件中的内容如下:
OPTIONS='-H tcp://0.0.0.0:[docker_port] -H unix:///var/run/docker.sock --selinux-enabled'
将docker_port换成想要配置且未被占用的端口号,比如2375

ubuntu 14.04为:DOCKER_OPTS='-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --selinux-enabled'

重启docker服务

1
systemctl restart docker

查看服务启动

1
ps -ef | grep docker

开放防火墙端口

1
2
3
systemctl start firewalld
firewall-cmd --zone=public --add-port=2375/tcp --permanent
firewall-cmd --reload


1
iptables -I INPUT -p tcp --dport 2375 -j ACCEPT

非root用户直接使用docker

参考https://docs.docker.com/engine/installation/linux/centos/
创建docker组

1
sudo groupadd docker

将当前用户加入到docker组

1
sudo usermod -aG docker your_username

重启docker-daemon

1
sudo systemctl restart docker

log out并重新log in

docker run权限

有时候启动一个容器的时候可能会导致权限问题,导致容器一直restarting,比如启动mysql容器的时候,使用了volume,却发现启动不成功。
使用docker logs 容器id可以查看容器运行日志。

Centos7 可能出现Permission denied的问题。
原因:CentOS7中的安全模块selinux把权限禁掉了,至少有以下三种方式解决挂载的目录没有权限的问题:
1、在运行容器的时候,给容器加特权,及加上 –privileged 参数。使用该参数,container内的root拥有真正的root权限。该方法在centos7下有效,但在ubuntu14.04会出现docker run不成功的情况(ubuntu14.04倒不会出现Permission denied的问题)。
2、关闭selinux:
查看SELinux状态命令:/usr/sbin/sestatus -v 或 getenforce
临时关闭:
setenforce 0 #设置SELinux 成为permissive模式
setenforce 1 #设置SELinux 成为enforcing模式
永久关闭,需要重启机器:修改/etc/selinux/config文件,将SELINUX=enforcing改为SELINUX=disabled,重启机器。
3、添加selinux规则,改变要挂载的目录的安全性文本。
更改安全性文本的格式如下
chcon [-R] [-t type] [-u user] [-r role] 文件或者目录

Docker Volume权限管理可参考: https://yq.aliyun.com/articles/53990

dockerfile中entrypoint和cmd

1、ENTRYPOINT,表示镜像在初始化时需要执行的命令,不可被重写覆盖,需谨记。
2、CMD,表示镜像运行默认参数,可被重写覆盖。
3、ENTRYPOINT/CMD都只能在文件中存在一次,并且最后一个生效 多个存在,只有最后一个生效,其它无效!
4、需要初始化运行多个命令,彼此之间可以使用 && 隔开,但最后一个须要为无限运行的命令,需切记!

参考 Dockerfile Best Practices论docker中 CMD 与 ENTRYPOINT 的区别

cmd的两种格式

entrypoint类似

1
2
3
CMD /bin/echo
# or
CMD ["/bin/echo"]

格式1不是数组,命令在执行前会被加上/bin/sh -c;格式2是数组,执行效果如愿。

给entrypoint传递参数

docker run期间可以给entrypoint传递参数。CMD 和 ENTRYPOINT 放在一起效果更佳:

1
2
3
ENTRYPOINT ["/usr/bin/mysql"]

CMD ["--help"]

一旦设置了entrypoint,docker run期间传递的所有参数将作为ENTRYPOINT(”/usr/bin/mysql”)的参数。而CMD默认被设为["--help"],一旦docker run期间没有传递任何参数,则docker run会输出help的信息。

基于mysql镜像构建新镜像

https://github.com/docker-library/mysql/blob/c207cc19a272a6bfe1916c964ed8df47f18479e7/5.7/Dockerfile
查看docker hub上mysql的Dockerfile:

1
2
3
4
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306
CMD ["mysqld"]

可以看出该Dockerfile已经占据了ENTRYPOINT和CMD,且”mysqld”作为”docker-entrypoint.sh”的默认参数。假设我们扩展该镜像,加上vnc等服务,则可以将mysql启动放置到supervisor中,并且在新的dockerfile中直接运行supervisor。请注意在supervisor中启动mysql并不是command=docker-entrypoint.shcommand=mysqld,而是command=docker-entrypoint.sh mysqld

Dockerfile

vnc.sh

supervisord.conf

上述方案的缺点是:假如我们使用该镜像启动了一个容器,并且启动另一个容器连接该镜像,然后执行数据库导入语句,如docker run -v /home/ubuntu/Desktop/web/db/mysql_5_7_16_vnc_latest_1482889787/data:/tmp/data:rw --link mysql_5_7_16_vnc_latest_1482889787:mysql --rm mysql-5.7.16-vnc:latest /bin/sh -c 'mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD" -e "DROP DATABASE IF EXISTS expand;CREATE DATABASE expand DEFAULT CHARSET utf8 COLLATE utf8_general_ci;use expand;source tmp/data/system-expand.sql;"'。关于第二个容器,因为它要执行mysql语句,因此需要mysql服务,一般选择跟第一个容器相同的mysql镜像来启动第二个连接容器。但由于我们将supervisor作为ENTRYPOINT,因此可能会出现以下错误:

出错原因是docker run的参数被当作supervisor的参数了,因此我们继续修改上述文件,将supervisor放到脚本中执行:
Dockerfile

vnc.sh

supervisord.conf

继续完善:上述方案仍有缺陷,连接容器是基于vnc-mysql镜像启动的,但是并不需要vnc等相关服务,因此应该添加一个环境变量控制是否启动vnc。另外,vnc.sh会wait等待supervisor进程,因此为了使得docker run过程指定的/bin/sh -c "..."能够生效,应该在wait之前添加exec "$@"
Dockerfile

vnc.sh

supervisord.conf

最终的docker run实例:

docker run -v /home/ubuntu/Desktop/web/db/mysql_5_7_16_vnc_latest_1482889787/data:/tmp/data:rw --link mysql_5_7_16_vnc_latest_1482889787:mysql -e MYSQL_ROOT_PASSWORD=any_noused -e RUN_VNC=no --rm mysql-5.7.16-vnc:latest /bin/sh -c 'mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD" -e "DROP DATABASE IF EXISTS expand;CREATE DATABASE expand DEFAULT CHARSET utf8 COLLATE utf8_general_ci;use expand;source tmp/data/system-expand.sql;"'

奇怪的是,原本不使用supervisor管理mysqld的时候,连接容器是不需要指定MYSQL_ROOT_PASSWORD的(奇怪于为什么不需要,因为mysql容器的启动是需要指定MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD,MYSQL_RANDOM_ROOT_PASSWORD其中之一的),而使用supervisor之后就需要指定了,虽然这个密码在这里是没有实际作用的。

显示 Gitment 评论