原文地址:http://accjiyun.cn/wan-zhuan-dockerzhi-chang-yong-ming-ling-pian-san/python
首先咱们来解决一个小问题,使用docker每次都要用sudo,为了让非root用户使用docker,可将当前用户添加到docker用户组:mysql
sudo groupadd docker sudo gpasswd -a ${USER} docker # 当前用户添加到docker group
而后从新登入下用户就能够直接使用docker命令了。git
# 查看docker版本 docker version # 显示docker系统的信息 docker info # 全部Docker命令帮助 docker help
# 检索image docker search image_name # 下载image docker pull image_name # 列出镜像列表; -a, --all=false Show all images; --no-trunc=false Don't truncate output; -q, --quiet=false Only show numeric IDs docker images # 删除一个或者多个镜像; -f, --force=false Force; --no-prune=false Do not delete untagged parents docker rmi image_name # 显示一个镜像的历史; --no-trunc=false Don't truncate output; -q, --quiet=false Only show numeric IDs docker history image_name # 保存镜像到一个tar包; -o, --output="" Write to an file docker save image_name -o file_path # 加载一个tar包格式的镜像; -i, --input="" Read from a tar archive file docker load -i file_path # 机器a docker save image_name > /home/save.tar # 使用scp将save.tar拷到机器b上,而后: docker load < /home/save.tar
# 在容器中运行"echo"命令,输出"hello word" docker run image_name echo "hello word" # 交互式进入容器中 docker run -i -t image_name /bin/bash # 在容器中安装新的程序 docker run image_name apt-get install -y app_name # 运行一个新容器,同时为它命名、端口映射、文件夹映射。以redmine镜像为例 docker run --name redmine -p 9003:80 -p 9023:22 -d -v /var/redmine/files:/redmine/files -v /var/redmine/mysql:/var/lib/mysql sameersbn/redmine # 一个容器链接到另外一个容器 docker run -i -t --name sonar -d -link mmysql:db tpires/sonar-server sonar
-d:以守护进程方式运行(后台),并返回容器ID;
-P:默认匹配docker容器的5000端口号到宿主机的49153 to 65535端口
-p
--name: 指定容器的名称
--rm:退出时删除容器
-a stdin 指定标准输入输出内容类型,可选 STDIN/STDOUT / STDERR 三项;
-i 以交互模式运行容器,一般与 -t 同时使用;
-t 为容器从新分配一个伪输入终端,一般与 -i 同时使用;
--dns 8.8.8.8 指定容器使用的DNS服务器,默认和宿主一致;
--dns-search example.com 指定容器DNS搜索域名,默认和宿主一致;
-h "mars" 指定容器的hostname;
-e username="ritchie" 设置环境变量;
--env-file=[] 从指定文件读入环境变量;
--cpuset="0-2" or --cpuset="0,1,2"
绑定容器到指定CPU运行;
# 列出当前全部正在运行的container docker ps # 列出全部的container docker ps -a # 列出最近一次启动的container docker ps -l
# 保存对容器的修改; -a, --author="" Author; -m, --message="" Commit message docker commit ID new_image_name
# 删除全部容器 docker rm `docker ps -a -q` # 删除单个容器; -f, --force=false; -l, --link=false Remove the specified link and not the underlying container; -v, --volumes=false Remove the volumes associated to the container docker rm Name/ID # 中止、启动、杀死一个容器 docker stop Name/ID docker start Name/ID docker kill Name/ID # 从一个容器中取日志; -f, --follow=false Follow log output; -t, --timestamps=false Show timestamps docker logs Name/ID # 列出一个容器里面被改变的文件或者目录,list列表会显示出三种事件,A 增长的,D 删除的,C 被改变的 docker diff Name/ID # 显示一个运行的容器里面的进程信息 docker top Name/ID # 从容器里面拷贝文件/目录到本地一个路径 docker cp Name:/container_path to_path docker cp ID:/container_path to_path # 重启一个正在运行的容器; -t, --time=10 Number of seconds to try to stop for before killing the container, Default=10 docker restart Name/ID # 附加到一个运行的容器上面; --no-stdin=false Do not attach stdin; --sig-proxy=true Proxify all received signal to the process docker attach ID
# 登录registry server; -e, --email="" Email; -p, --password="" Password; -u, --username="" Username docker login # 发布docker镜像 docker push new_image_name
docker run -P:随机分配端口号 docker run -p 5000:5000:绑定特定端口号(主机的全部网络接口的5000端口均绑定容器的5000端口) docker run -p 127.0.0.1:5000:5000:绑定主机的特定接口的端口号 docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py:绑定udp端口号 docker port <CONTAINER_ID> 5000:查看容器的5000端口对应本地机器的IP和端口号 # 使用Docker Linking链接容器: Docker为源容器和接收容器建立一个安全的通道,容器之间不须要暴露端口,接收的容器能够访问源容器的数据 docker run -d -P --name <CONTAINER_NAME> --link <CONTAINER_NAME_TO_LINK>:<ALIAS>
Data Volumes:volume是在一个或多个容器里指定的特殊目录web
能够在容器启动的时候添加-v参数指定容器卷,也能够在Dockerfile里用VOLUMN命令添加sql
docker run -d -P --name web -v /webapp training/webapp python app.py
也能够将容器卷挂载到宿主机目录或宿主机的文件上, <容器目录或文件> 的内容会被替换为 <宿主机目录或文件> 的内容,默认容器对这个目录有可读写权限 docker
docker run -d -P --name web -v <宿主机目录>:<容器目录> training/webapp python app.py
能够经过指定ro,将权限改成只读数据库
docker run -d -P --name web -v <宿主机目录>:<容器目录>:ro training/webapp python app.py
在一个容器建立容器卷后,其余容器即可以经过--volumes-from共享这个容器卷数据,以下:ubuntu
docker run -d -v /dbdata --name db1 training/postgres echo Data-only container for postgres
首先启动了一个容器,并为这个容器增长一个数据卷/dbdata,而后启动另外一个容器,共享这个数据卷安全
docker run -d --volumes-from db1 --name db2 training/postgres
此时db2使用了db1的容器卷,当容器db1被删除时,容器卷也不会被删除,只有全部容器再也不使用此容器卷时,才会被删除
docker rm -v:删除容器卷
除了共享数据外,容器卷另外一个做用是用来备份、恢复和迁移数据
docker run --volumes-from db1 -v /home/backup:/backup ubuntu tar cvf /backup/backup.tar /dbdata
启动一个容器数据卷使用db1容器的数据卷,同时新创建一个数据卷指向宿主机目录/home/backup,将/dbdata目录的数据压缩为/backup/backup.tar
docker run -v /dbdata --name dbdata2 ubuntu /bin/bash docker run --volumes-from dbdata2 -v /home/backup:/backup busybox tar xvf /backup/backup.tar
启动一个容器,同时把backup.tar的内容解压到容器的backup
使用命令行的方式建立 Docker 镜像一般难以自动化操做。在更多的时候,咱们使用 Dockerfile 来建立 Docker 镜像。Dockerfile 是一个纯文本文件,它记载了从一个镜像建立另外一个新镜像的步骤。撰写好 Dockerfile 文件以后,咱们就能够垂手可得的使用 docker build
命令来建立镜像了。
Dockerfile 很是简单,仅有如下命令在 Dockerfile 中常被使用:
命令 | 参数 | 说明 |
---|---|---|
# | - | 注释说明 |
FROM | <image>[:<tag>] | 从一个已有镜像建立,例如ubuntu:latest |
MAINTAINER | Author <some-one@example.com> | 镜像做者名字,如Max Liu <some-one@example.com> |
RUN | <cmd>或者['cmd1', 'cmd2'⋯] | 在镜像建立用的临时容器里执行单行命令 |
ADD | <src> <dest> | 将本地的<src>添加到镜像容器中的<dest>位置 |
VOLUME | <path>或者['/var', 'home'] | 将指定的路径挂载为数据卷 |
EXPOSE | <port> [<port>...] | 将指定的端口暴露给主机 |
ENV | <key> <value> 或者 <key> = <value> | 指定环境变量值 |
CMD | ["executable","param1","param2"] | 容器启动时默认执行的命令。注意一个Dockerfile中只有最后一个CMD生效。 |
ENTRYPOINT | ["executable", "param1", "param2"] | 容器的进入点 |
下面是一个 Dockerfile 的例子:
# This is a comment FROM ubuntu:14.04 MAINTAINER Kate Smith <ksmith@example.com> RUN apt-get update && apt-get install -y ruby ruby-dev RUN gem install sinatra
这里其余命令都比较好理解,惟独 CMD
和 ENTRYPOINT
我须要特殊说明一下。CMD
命令可用指定 Docker 容器启动时默认的命令,例如咱们上面例子提到的 docker run -it ubuntu:latest sh -c '/bin/bash'
。其中 sh -c '/bin/bash'
就是经过手工指定传入的 CMD。若是咱们不加这个参数,那么容器将会默认使用 CMD 指定的命令启动。ENTRYPOINT 是什么呢?从字面看是进入点。没错,它就是进入点。ENTRYPOINT 用来指定特定的可执行文件、Shell 脚本,并把启动参数或 CMD 指定的默认值,看成附加参数传递给 ENTRYPOINT。
很差理解是吧?咱们举一个例子:
ENTRYPOINT ['/usr/bin/mysql'] CMD ['-h 192.168.100.128', '-p']
假设这个镜像内已经准备好了 mysql-client,那么经过这个镜像,不加任何额外参数启动容器,将会给咱们一个 mysql 的控制台,默认链接到192.168.100.128 这个主机。然而咱们也能够经过指定参数,来链接别的主机。可是无论不管如何,咱们都没法启动一个除了 mysql 客户端之外的程序。由于这个容器的 ENTRYPOINT 就限定了咱们只能在 mysql 这个客户端内作事情。这下是否是明白了~
所以,咱们在使用 Dockerfile 建立文件的时候,能够建立一个 entrypoint.sh
脚本,做为系统入口。在这个文件里面,咱们能够进行一些基础性的自举操做,好比检查环境变量,根据须要初始化数据库等等。下面两个文件是我在平常工做的项目中添加的 Dockerfile 和 entrypoint.sh,仅供参考:
https://github.com/starlight36/SimpleOA/blob/master/Dockerfile
https://github.com/starlight36/SimpleOA/blob/master/docker-entrypoint.sh
在准备好 Dockerfile 以后,咱们就能够建立镜像了:
docker build -t starlight36/simpleoa .
关于 Dockerfile 的更详细说明,请参考 https://docs.docker.com/reference/builder/。