docker
这几天学了一下docker的相关知识,记录一下
安装
官网有教程
卸载旧版本
1 | sudo yum remove docker \ |
安装新版本
需要centos7版本以上的
安装一些必要的系统工具:
1 | sudo yum install -y yum-utils device-mapper-persistent-data lvm2 |
添加软件源信息:
1 | sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo |
安装 Docker-ce:
1 | sudo yum install -y docker-ce |
启动 Docker 后台服务:
1 | sudo systemctl start docker |
Docker镜像加速
在拉取Docker镜像时如果未指明镜像地址则默认从docker-hub上拉取,国内访问docker-hub的速度较慢,所以需要将docker源更改为国内的源。
配置/etc/docker/daemon.json即可,我使用的是阿里云的源:
1 | sudo mkdir -p /etc/docker |
保存配置后需要重启服务:
1 | sudo systemctl daemon-reload |
相关命令
查看容器
1
2
3
4查看运行中的容器
docker ps
查看所有容器
docker ps -a删除镜像
1
docker rm 容器id
查看镜像
1
docker images
删除镜像
1
docker rmi 镜像id
进入容器内部
1
docker exec -it 容器id /bin/bash
构建Dockerfile
1
docker build -t runoob/ubuntu:v1 .
Dockerfile
Dockerfile的基本结构
Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,”#” 为 Dockerfile 中的注释。
文件说明
FROM:指定基础镜像,必须为第一个命令
指定基础镜像,必须为第一个命令
1
2
3
4
5
6
7#格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
#示例:
FROM mysql:5.6
# 注:tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像MAINTAINER: 维护者信息
1
2
3
4#格式:
MAINTAINER name<email address>
#示例:
MAINTAINER DLYT<xxx@163.com>RUN:构建镜像时执行的命令
1
2
3
4
5
6
7
8
9
10
11
12#RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
#shell执行
#格式:
RUN <command>
#exec执行
#格式:
RUN ["executable", "param1", "param2"]
#示例:
RUN ["executable", "param1", "param2"]
RUN apk update
RUN ["/etc/execfile", "arg1", "arg1"]
#注RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cacheADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
1
2
3
4
5
6
7
8
9
10
11
12#格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] #用于支持包含空格的路径
#示例:
# 添加所有以"hom"开头的文件
ADD hom* /mydir/
# ? 替代一个单字符,例如:"home.txt"
ADD hom?.txt /mydir/
# 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test relativeDir/
# 添加 "test" 到 /absoluteDir/
ADD test /absoluteDir/COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
CMD:构建容器后调用,也就是在容器启动时才进行调用
1
2
3
4
5
6
7
8# 格式:
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
# 示例:
CMD echo "This is a test." | wc -
CMD ["/usr/bin/wc","--help"]
# 注:CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。ENTRYPOINT:配置容器,使其可执行化。配合CMD可省去”application”,只使用参数
1
2
3
4
5
6
7
8#格式:
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)
#示例:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
#注:ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。LABEL:用于为镜像添加元数据
1
2
3
4
5#格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
#示例:
LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
#注:使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。ENV:设置环境变量
1
2
3
4
5
6
7#格式:
ENV <key> <value> #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
ENV <key>=<value> ... #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行
# 示例:
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat=fluffyEXPOSE:指定于外界交互的端口
1
2
3
4
5
6
7#格式:
EXPOSE <port> [<port>...]
#示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp
#注:EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口VOLUME:用于指定持久化目录
1
2
3
4
5
6
7
8
9
10
11#格式:
VOLUME ["/path/to/dir"]
#示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
#注:一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
# 1 卷可以容器间共享和重用
# 2 容器并不一定要和其它容器共享卷
# 3 修改卷后会立即生效
# 4 对卷的修改不会对镜像产生影响
# 5 卷会一直存在,直到没有任何容器在使用它WORKDIR:工作目录,类似于cd命令
1
2
3
4
5
6
7#格式:
WORKDIR /path/to/workdir
#示例:
WORKDIR /a (这时工作目录为/a)
WORKDIR b (这时工作目录为/a/b)
WORKDIR c (这时工作目录为/a/b/c)
#注:通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工构建镜像
docker build [OPTIONS]上下文路径|URL
[OPTIONS]:通常指令包括-t,用来指定image的名字。-f指定Dockfile的上下文路径。
上下文路径|URL:上下文路径,如果只有一个小圆点 “.” 代表当前目录。
示例 构建一个名字为 webtest
的镜像
1 | docker bulid -t webtest . |
docker-compose
基本格式
1 | version: '2' |
可以看到一份标准配置文件应该包含 version
、services
、networks
三大部分,其中最关键的就是 services
和 networks
两个部分,下面我们来看其书写规则。
services
image
1
2
3services:
web:
image: hello-world在
services
标签下的第二级标签是 web,这个名字是用户自己自定义,它就是服务名称。
image 则是指定服务的镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。container_name
相当于docker build 中的 –name
depends_on
在使用 Compose 时,最大的好处就是少打启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。
例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是 depends_on,这个标签解决了容器的依赖、启动先后的问题。
例如下面容器会先启动 redis 和 db 两个服务,最后才启动 web 服务:1
2
3
4
5
6
7
8
9
10
11version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgreslinks
还记得上面的depends_on吧,那个标签解决的是启动顺序问题,这个标签解决的是容器连接问题,与Docker client的–link一样效果,会连接到其它服务中的容器。
格式如下:1
2
3
4links:
- db
- db:database
- redis使用的别名将会自动在服务容器中的/etc/hosts里创建。例如:
1
2
3172.12.2.186 db
172.12.2.186 database
172.12.2.187 redis相应的环境变量也将被创建。
environment
这个标签的作用是设置镜像变量,它可以保存变量到镜像里面,也就是说启动的容器也会包含这些变量设置,这是与 arg 最大的不同。
一般 arg 标签的变量仅用在构建过程中。而 environment 和 Dockerfile 中的 ENV 指令一样会把变量一直保存在镜像、容器中,类似 docker run -e 的效果。
1 | environment: |
ports
映射端口的标签。
使用HOST:CONTAINER格式或者只是指定容器的端口,宿主机会随机映射端口。1
2
3
4
5ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"注意:当使用HOST:CONTAINER格式来映射端口时,如果你使用的容器端口小于60你可能会得到错误得结果,因为YAML将会解析xx:yy这种数字格式为60进制。所以建议采用字符串格式。
networks
加入指定网络,同一网络可以相互通讯,格式如下:
1
2
3
4
5services:
some-service:
networks:
- some-network
- other-network