docker 知识整理
Docker 是一个开源的应用容器引擎,可以让开发者打包他们的应用以及依赖包到一个轻量级,可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。
Docker的应用场景:
web应用的自动化打包和发布
自动化测试和持续集成。发布
在服务型环境中部署和调整数据库或其他的后台应用
从头编译或者扩展现有的OpenShift 或 Cloud Foundry平台来搭建自己的PaaS环境。
Docker 的优点:
1.快速,一致的交付你的应用程序
2.响应式部署和扩展
3.在同一硬件上运行更多的工作负载
Docker 镜像:
Docker镜像是用于创建Docker容器模板
Docker 容器:
容器时独立运行的一个或一组应用,是镜像运行时的实体
Docker 客户端:
Docker客户端同过命令行或者其他工具使用与docker的守护进程通信。
Docker主机:
一个物理或者虚拟的机器用于执行Docker守护进程和容器
1.使用docker run命令来在容器内运行一个应用程序
docekr run ubuntu:15.10 /bin/echo "Hello world"
docker run - i -t ubuntu:15.10 /bin/bash
-t:在新容器内指定一个伪终端或终端。 -i:允许你对容器内的标准输入进行交互。
exit:命令或者CTRL+D来退出容器
通过ID来查看对应的容器发生了什么。
docker ps 来查看
runoob@runoob:~$ docker ps
CONTAINER ID IMAGE COMMAND ...
5917eac21c36 ubuntu:15.10 "/bin/sh -c 'while t…" ...
输出详情介绍:
CONTAINER ID:容器ID。
IMAGE:使用的镜像
COMMAND:启动容器时运行的命令
CREATED:容器的创建时间
STATUS:容器状态
状态有7种:
created (已创建)
restarting(重启中)
running或up(运行中)
removing(迁移中)
paused(暂停)
exited(停止 )
dead(死亡)
POPTS:容器的端口信息和使用的连接类型
Names:自动分配的容器名称
停止容器
docker stop 命令来停止容器
Docker 客户端
docker命令可以产看到Docker客户端的所有命令选项
docker command --help 更深入的了解指定的Docker 命令使用
启动容器
使用命令ubuntu镜像启动一个容器,参数为以命令行模式进去该容器
docker run -it ubuntu /bin/bash
-i 交互式操作
-t 终端
ubuntu: ubuntu镜像。
/bin/bash:放在镜像后的是命令,这里我们希望有个交互式Shell,因此用的是/bin/bash.
使用 docker start 启动一个已停止的容器:
docker start b750bbbcfd88
重启容器
docker restart <容器 ID>
进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器
docker exec -it 243c32535da7 /bin/bash
导出和导入容器
导出容器:
如果要导出本地某个容器,可以使用docker export 命令。
docker export 1e560fca3906 > ubuntu.tar
导出容器 1e560fca3906 快照到本地文件 ubuntu.tar。
导入容器快照
可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:
cat docker/ubuntu.tar | docker import - test/ubuntu:v1
此外,也可以通过指定 URL 或者某个目录来导入,例如:
docker import http://example.com/exampleimage.tgz example/imagerepo
删除容器
docker rm -f 1e560fca3906
下面的命令可以清理掉所有处于终止状态的容器。
$ docker container prune
运行一个web应用
docker run -d -p training/webapp python app.py
-d:让容器在后台运行
-P:将容器内部使用的网络端口随机映射到我们使用的主机上
使用docker ps 来查看我们正在运行的容器
runoob@runoob:~# docker ps
CONTAINER ID IMAGE COMMAND ... PORTS
d3d5e39ed9d3 training/webapp "python app.py" ... 0.0.0.0:32769->5000/tcp
这里多了端口信息
PORTS
0.0.0.0:32769->5000/tcp
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32769 上。
这时我们可以通过浏览器访问WEB应用
网络端口的快捷方式:
docker还提供了另一个快捷方式docker port,使用docker port 可以查看指定(ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
docker port bf8b7f2cd99 或者docker port wizardly_chandrasekhar 来查看容器端口的映射情况。
runoob@runoob:~$ docker port bf08b7f2cd89
5000/tcp -> 0.0.0.0:5000
runoob@runoob:~$ docker port wizardly_chandrasekhar
5000/tcp -> 0.0.0.0:5000
查看WEB 应用程序日志
docker logs [ID或者名字] 可以查看容器内部的标准输出
runoob@runoob:~$ docker logs -f bf08b7f2cd89
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.239.1 - - [09/May/2016 16:30:37] "GET / HTTP/1.1" 200 -
192.168.239.1 - - [09/May/2016 16:30:37] "GET /favicon.ico HTTP/1.1" 404 -
-f :让docker logs 像使用tail -f 一样来输出容器内部的标准输出。 从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。
查看WEB应用程序容器的进程
我们还可以使用docker top来查看容器内部运行进程
docker top wizardly_chandrasekhar
停止 WEB 应用容器
runoob@runoob:~$ docker stop wizardly_chandrasekhar
wizardly_chandrasekhar
重启WEB应用容器
已经停止的容器,我们可以使用命令 docker start 来启动。
runoob@runoob:~$ docker start wizardly_chandrasekhar
wizardly_chandrasekhar
docker ps -l 查询最后一次创建的容器:
# docker ps -l
CONTAINER ID IMAGE PORTS NAMES
bf08b7f2cd89 training/webapp ... 0.0.0.0:5000->5000/tcp wizardly_chandrasekhar
移除WEB应用容器
runoob@runoob:~$ docker rm wizardly_chandrasekhar
wizardly_chandrasekhar
删除容器时,容器必须是停止状态,否则会报如下错误
列出镜像列表
docker images
runoob@runoob:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04 90d5884b1ee0 5 days ago 188 MB
php 5.6 f40e9e0f10c8 9 days ago 444.8 MB
nginx latest 6f8d099c3adc 12 days ago 182.7 MB
mysql 5.6 f2e8d6c772c0 3 weeks ago 324.6 MB
httpd latest 02ef73cf1bc0 3 weeks ago 194.4 MB
ubuntu 15.10 4e3b13c8a266 4 weeks ago 136.3 MB
hello-world latest 690ed74de00f 6 months ago 960 B
training/webapp latest 6fae60ef3446 11 months ago 348.8 MB
- REPOSITORY: 表示镜像的仓库源
- TAG: 镜像的标签
- IMAGE ID: 镜像ID
- CREATED: 镜像创建时间
- SIZE: 镜像大小
获取一个新镜像
docker pull 命令来下载它。
查找镜像
docker search 搜索镜像。(需要搜素httpd的镜像来作为我们的web服务)
docker search httpd
拖取镜像
docker pull
创建镜像
更新镜像之前,我们需要使用镜像来创建一个容器。
当docker镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过一下两种方式进行对镜像进行更改
- 从已经创建的容器中更新镜像,并且提交这个镜像
- 使用Dockerfile指令来创建一个新的镜像
~ $ docker run -t -i ubuntu:15.10 /bin/bash
e218edb10161:/#
在运行的容器内使用apt -get update 命令进行更新
在完成操作后,输入exit命令来退出这个容器
此时 ID 为 e218edb10161 的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本。
构建镜像
docker build 从零开始来创建一个新的镜像,为此,我们需要创建一个Dockerfile文件,其中包含一组指令来告诉
Docker如何构建我们的镜像。
root@root:~$ cat Dockerfile
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG="en_US.UTF-8"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker在镜像内执行命令,安装了什么。。。
然后,使用我们Dockerfile 文件,通过build 命令来构建一个镜像。
$ docker build -t runoob/centos:6.7 .
-t 指定要创建的目标镜像名
. :Dockerfile 文件所在目录,可以指定Dockerfile的绝对路径
使用docker images 查看创建的镜像已经在列表中存在,镜像ID为860c279d2fec
run@run:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
runoob/centos 6.7 860c279d2fec About a minute ago 190.6 MB
runoob/ubuntu v2 70bf1840fd7c 17 hours ago 158.5 MB
ubuntu 14.04 90d5884b1ee0 6 days ago 188 MB
php 5.6 f40e9e0f10c8 10 days ago 444.8 MB
nginx latest 6f8d099c3adc 12 days ago 182.7 MB
mysql 5.6 f2e8d6c772c0 3 weeks ago 324.6 MB
httpd latest 02ef73cf1bc0 3 weeks ago 194.4 MB
ubuntu 15.10 4e3b13c8a266 5 weeks ago 136.3 MB
hello-world latest 690ed74de00f 6 months ago 960 B
centos 6.7 d95b5ca17cc3 6 months ago 190.6 MB
training/webapp latest 6fae60ef3446 12 months ago 348.8 MB
docker tag 命令详解
作用
给本地镜像打一个标记(tag),可将其归入某一个仓库
有点像 Git里面给不同时段写的代码打不同的tag
语法格式:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
实际例子
docker tag docker tag jenkins/poloyy:latest poloyy/jenkins:new2
实际使用场景
- 当镜像配置到一定程度时,想打个 tag 进行记录当前版本,可以打个 V1
- 再次更新镜像时,又可以打个 V2
- 当是最新版本待上传时,可以不打默认就是 latest 最新
- 这样不仅能保存最新版本的镜像,也能保存历史版本的镜像,方便新版本镜像出问题时进行版本回溯
Docker 容器互联
端口映射并不是唯一把 docker 连接到另一个容器的方法。
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。
docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息
新建网络
$ docker network create -d bridge test-net
查看容器网络列表
docker network create -d bridge test-net
-d: 参数指定Docker网络类型, 有bridge overlay
连接容器
运行一个容器并连接到新建的test-net 网络
$ docker run -itd --name test1 --network test-net ubuntu /bin/bash
打开新的终端,在运行一个容器并加入到test-net 网络
$ docker run -itd --name test2 --network test-net ubuntu /bin/bash
通过ping验证test1容器和test2容器建立的互联关系
在test1容器中执行命令
先进入容器
docker exec -it test1 /bin/bash
ranhou ping test2
test2同理
Docker Dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
FORM:定值的镜像都给予FROM的镜像,这里的nginx就是定制需要的基础镜像,后续的操作都基于nginx RUN:用于执行后面耕者的命令行命令。有以下两种格式
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
以 && 符号连接命令,这样执行后,只会创建 1 层镜像。
FROM centos\
RUN yum -y install wget \\
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \\
&& tar -xvf redis.tar.gz
指令详解
COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
格式:
COPY [--chown=<user>:<group>] <源路径1>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
[-- chown= < user > :< group >] :可选参数,用户改变复制到容器内文件的拥有者和属组。
<目标路径> :容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
ADD
ADD 指令和COPY的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
ADD的优点:在执行为tar压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
CMD
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
ENTRYPOINT
类似于CMD指令,但不会被docker run 的命令行参数指定的指令所覆盖,但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
假设已通过DockerFile构建了nginx:test镜像
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
1.不传参运行
$ docker run nginx:test
2.传参运行
$ docker run nginx:test -c /etc/nginx/new.conf
容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
nginx -c /etc/nginx/new.conf
ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
格式:
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
设置 NODE_VERSION = 7.2.0,在后续的指令中可以通过¥NODE_VERSION引用
EXPOSE
声明端口
作用:帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射
在运行时使用随机端口映射,也就是docker run-P 时,会自动随机映射 EXPOSE的端口
EXPOSE <端口1> [<端口2>...]
USER
用于指定执行后续命令的用户和用户组,这只是切换后续命零执行的用户
USER <用户名>[:<用户组>]
LABEL
LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...