Docker
docker总结和实例
常用命令
镜像管理
-
镜像搜索
docker seartch 镜像名或者关键词
-
镜像拉取
docker pull 镜像名:标签
-
镜像罗列
docker images
-
镜像删除
docker rmi 镜像id或者镜像名:标签
-
镜像导出
docker save -o 文件名.tar 镜像名:标签
-
镜像导入
docker load -i 文件名.tar
容器管理
-
运行新容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS:
-d
: 后台运行容器,并返回容器id-i
: 以交互模式运行容器,通常与-t
同时使用-t
:为容器分配一个伪输入终端,通常和-i
一起使用-p 3306:3306
:指定端口映射,格式为主机端口:容器端口
-v /path/on/host:/path/on/container
: 挂载目录,格式主机目录:容器目录
--name my-container
:为容器指定一个名称-e username=cmy
:设置环境变量--env-file app.env
:从指定文件读入环境变量--net=xxx
- bridge(默认),容器将会连接到 Docker 的默认桥接网络(通常是
docker0
),在此模式下,容器会获取一个独立的 IP 地址,并且可以与同一网络中的其他容器通信。 - host,容器将共享宿主机的网络栈,意味着它将直接使用宿主机的 IP 地址和端口,而不是分配给它的独立网络接口。
- none,容器没有网络功能,不会分配任何网络接口或IP地址。通常用于测试或其他不需要网络连接的情况。
- 自定义网络,如果你已经创建了一个自定义网络(如通过
docker network create
命令创建),你可以将容器连接到这个网络上
- bridge(默认),容器将会连接到 Docker 的默认桥接网络(通常是
-
列出容器
-
列出正在运行的所有容器
docker ps
-
列出所有的容器
docker ps -a
-
-
启动已存在的容器
docker start 容器id或者容器名
-
停止运行中的容器
docker stop 容器id或者容器名
-
重启容器
docker restart 容器id或者容器名
-
进入正在运行的容器内部
docker exec -it 容器id或者容器名 /bin/bash /bin/bash 是指定要在容器内执行的程序或命令
-
拷贝文件到容器或从容器中拷贝出来
# 拷贝文件到容器 docker cp 源路径 容器id:目标路径 # 从容器中拷贝文件到主机 docker cp 容器id:源路径 目标路径
-
删除容器
docker rm -f 容器id或者容器名 -f是强制的意思
-
查看容器日志
docker logs [OPTINOS] 容器id或者容器名 #OPTINOS 如下 docker logs -f 实时追踪日志输出,即持续打印新产生的日志 docker logs -t 针对每行日志添加时间戳 docker logs --tail 10 显示最后10行日志 docker logs --since 2020-03-26T15:00:00 #查看2020-03-26T15:00:00之后的日志 docker logs --since 2020-03-26T15:00:00 --until 2020-03-27T11:00:00 <CONTAINER> #查看2020-03-26T15:00:00到2020-03-27T11:00:00时间段的日志 docker logs|grep error 使用grep过滤指定条件的日志 docker logs -t 容器id或者容器名|grep error >> error_logs.txt
网络和卷管理
-
创建网络
docker network create 网络名
-
删除网络
docker network rm 网络名或者网络id
-
创建数据卷
docker volume create 卷名 # 比如 创建一个自定义容器 docker volume create test-vol
-
查看容器卷
docker volume ls docker volume inspect test-vol // 查看指定容器卷详情信息
-
使用卷
docker run -d -it --name=test -p 8080:8080 -v test-vol:/usr/share/nginx/html nginx
其中,-v代表挂载数据卷,这里使用自定数据卷edc-nginx-vol,并且将数据卷挂载到/usr/share/nginx/html (这个目录是yum安装nginx的默认网页目录)。如果没有通过-v指定,那么Docker会默认帮我们创建匿名数据卷进行映射和挂载。
-
删除数据卷,需要先停止容器
docker volume rm 卷名
注意:如果volume是空的而container中的目录有内容,那么docker会将container目录中的内容拷贝到volume中,但是如果volume中已经有内容,则会将container中的目录覆盖。
镜像构建
构建命令
# docker build命令是Docker中用于根据Dockerfile文件构建新的Docker镜像的核心命令。这个命令将读取Dockerfile中定义的各层构建指令,并按照顺序执行它们,最终生成一个新的镜像
docker build OPTIONS PATH
# 常用OPTIONS
#--build-arg,设置构建时的变量
#--no-cache,默认false。设置该选项,将不使用Build Cache构建镜像
#--pull,默认false。设置该选项,总是尝试pull镜像的最新版本
#--compress,默认false。设置该选项,将使用gzip压缩构建的上下文
#--disable-content-trust,默认true。设置该选项,将对镜像进行验证
#--file, -f,Dockerfile的完整路径,默认值为‘PATH/Dockerfile’
#--isolation,默认--isolation="default",即Linux命名空间;其他还有process或hyperv
#--label,为生成的镜像设置metadata
#--squash,默认false。设置该选项,将新构建出的多个层压缩为一个新层,但是将无法在多个镜像之间共享新层;设置该选项,实际上是创建了新image,同时保留原有image。
#--tag, -t,镜像的名字及tag,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个tag
#--network,默认default。设置该选项,Set the networking mode for the RUN instructions during build
#--quiet, -q,默认false。设置该选项,Suppress the build output and print image ID on success
#--force-rm,默认false。设置该选项,总是删除掉中间环节的容器
#--rm,默认--rm=true,即整个构建过程成功后删除中间环节的容器
## 命令示例: 构建 镜像并指定标签 . 单独的点,意思为根据当前目录下的Dockerfile文件生成镜像
docker build -t img:tag .
FROM
格式
FROM image:tag
- FROM指令必须是Dockerfile中非注释行的第一个指令,即一个Dockerfile从FROM语句开始
- FROM指令用于为镜像文件构建过程指定基础镜像,后续的指令运行于此基础镜像所提供的运行环境
- 实践中,基准镜像可以是任何可用镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会自动从Docker的公共库pull镜像下来。如果找不到指定的镜像文件,docker build会返回一个错误信息
- FROM可以在一个Dockerfile中出现多次,如果有需求在一个Dockerfile中创建多个镜像
- 如果FROM语句没有指定镜像标签,则默认使用latest标签
# 注释行
FROM mysql:8.0.23
MAINTAINER
格式
MAINTAINER xxx
MAINTAINER 'xxx <xxx@163.com>'
- 用于让dockerfile制作者提供本人的详细信息
- dockerfile并不限制MAINTAINER指令可在出现的位置,但推荐将其放置于FROM指令之后
# 注释行
FROM mysql:8.0.23
MAINTAINER 'xxx <xxx@163.com>'
COPY
格式
COPY sour target
- 用于从docker主机复制新文件或者目录至创建的新镜像指定路径中
COPY
命令只能访问构建上下文中的文件,也就是说,在运行docker build
时指定的-f
或--file
参数后跟随的路径下的文件以及该路径下的所有内容。上下文之外的文件不能直接被 COPY 命令引用。- 目标路径,即正在创建的image的文件系统路径;建议使用绝对路径,否则,COPY指定以WORKDIR为起始路径
- 如果是复制目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
# 注释行
FROM mysql:8.0.23
MAINTAINER 'xxx <xxx@163.com>'
# 这里注意 DockerFile统计目录下需要有app.jar
COPY app.jar /usr/local/myapp/
COPY myapp/ /usr/local/myapp/
ADD
格式
ADD sour target
- ADD指令类似于COPY指令,ADD支持使用TAR(解压)文件和URL路径
- 如果是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于"tar-x"命令;然而,通过URL获取到的tar文件将不会自动展开
# 注释行
FROM mysql:8.0.23
MAINTAINER 'xxx <xxx@163.com>'
# 这里注意 DockerFile统计目录下需要有app.jar
COPY app.jar /usr/local/myapp/
COPY myapp/ /usr/local/myapp/
ADD http://nginx.org/download/nginx-1.15.8.tar.gz /usr/local/src/
WORKDIR
格式
WORKDIR xxx
-
在Dockerfile中,
WORKDIR
指令用于设置构建镜像过程中的工作目录(或当前目录) -
WORKDIR /path/to/directory
这条指令会将容器内的当前工作目录更改为指定的绝对路径/path/to/directory
。后续的RUN
、CMD
、ENTRYPOINT
等指令将在该目录下执行。 -
如果提供的是一个相对路径,那么它将会相对于之前
WORKDIR
指令所设置的路径# 在这个例子中,最终的 pwd 命令将显示 /a/b/c 作为当前工作目录。 WORKDIR a WORKDIR b WORKDIR c RUN pwd
-
环境变量引用,
WORKDIR
支持使用之前通过ENV
设置的环境变量ENV APP_DIR /app WORKDIR ${APP_DIR}/subdir
-
自动创建目录, 如果指定的工作目录在构建过程中还不存在,Docker 会在执行
WORKDIR
指令时自动创建该目录。 -
影响容器启动时的默认目录,当容器基于包含
WORKDIR
指令的镜像启动时,默认情况下,容器内的工作目录就是最后被WORKDIR
设置的那个目录。
VOLUME
格式
VOLUME /xxx
VOLUME ["/xxx","/xxxx"]
-
通过Dockerfile的VOLUME指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点
-
区别是通过VOLUME指令创建的挂载点,无法指定主机上对应的目录,是自动生成的
#test FROM ubuntu MAINTAINER xxx VOLUME ["/data1","/data2"]
"Mounts": [ { "Name": "d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21", "Source": "/var/lib/docker/volumes/d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21/_data", "Destination": "/data1", "Driver": "local", "Mode": "", "RW": true }, { "Name": "6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36", "Source": "/var/lib/docker/volumes/6d3badcf47c4ac5955deda6f6ae56f4aaf1037a871275f46220c14ebd762fc36/_data", "Destination": "/data2", "Driver": "local", "Mode": "", "RW": true } ],
EXPOSE
格式
# 单个
EXPOSE port/protocol
# 多个
EXPOSE port/protocol port/protocol
- 用于声明容器运行时所监听的网络端口,EXPOSE并不会真正将宿主机上的端口暴露出来,它只是一个元数据,方便用户了解容器的网络设置
EXPOSE
命令本身并不意味着在宿主机和容器之间创建网络端口映射。容器内部暴露的端口并不直接对宿主机可见,除非在启动容器时通过-p
或-P
参数显式进行端口映射;当使用-P
参数运行容器时,Docker会自动将EXPOSE
过的端口映射到宿主机的一个随机端口- 用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议
- EXPOSE指令可一次指定多个端口,例如:
EXPOSE 11211/udp 11211/tcp
ENV
格式
# 单个
ENV key value
# 多个
ENV key1=value1 key2=value2
-
用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其它指令所用:
- ENV
- ADD
- COPY
- ENV
- EXPOSE
- FROM
- LABEL
- STOPSIGNAL
- USER
- VOLUME
- WORKDIR
- ONBUILD
-
使用环境变量的方式
# 方式1 $variable_name # 方式2 ${variable_name} # 方式2 支持以下指定的标准的bash修饰符 ${variable:-word} #表示如果设置了 variable,那么结果就是那个值;如果未设置变量,则结果将是 word ${variable:+word} #表示如果设置了 variable,则结果为 word,否则为空字符串 # 在所有情况下, word 可以是任何字符串,包括额外的环境变量 #####一个例子 FROM cmy ENV FOO=/bar WORKDIR ${FOO} # WORKDIR /bar ADD . $FOO # ADD . /bar COPY \$FOO /quux # COPY $FOO /quux 转义 ##### 定义多个 每个变量为一个”="的键值对,如果中包含空格,可以以反斜线(\)进行转义,也可通过对加引号进行标识;另外,反斜线也可用于续行 ENV a=b c=d e=\ f
-
查看和修改定义的环境变量
docker run --name mycontainer --rm -it img:tag printenv # mock --rm 参数表示容器退出后自动删除 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=1b31ed3b63aa TERM=xterm DOC_ROOT=/data/web/html/ WEB_SERVER_PACKAGE=nginx-1.15.8 HOME=/root ---------------------------------------------------------------------------------- ### 在启动容器时,使用docker run -e 设置修改变量 docker run --name mycontainer -e WEB_SERVER_PACKAGE=nginx-1.15.7 --rm -it img:tag printenv # mock PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=a7e01f493eec TERM=xterm WEB_SERVER_PACKAGE=nginx-1.15.7 DOC_ROOT=/data/web/html/ HOME=/root
RUN
格式
## shell 形式 该命令在 shell 中运行,在 Linux 上默认为/ bin/sh -c,在 Windows 上默认为 cmd / S / C
# 使用shell进行命令解析,支持shell特性,如管道符(|)、重定向(>、>>)、变量替换等。
# 如果命令中包含特殊字符或环境变量引用,shell会进行相应的处理
RUN command
RUN echo "Hello World"
## exec 形式
# 不通过shell执行,而是直接执行指定的可执行文件,并将后面的参数原样传递给它
# 不支持shell语法特性,但可以防止命令注入攻击,因为不会经过shell解析
# 提供更好的性能,因为没有shell的启动开销,而且对于信号传递更为准确
# 如果需要执行shell命令,需要明确指定shell,例如:["/bin/sh", "-c", "echo Hello World"]
RUN ["executable", "param1", "param2"]
RUN ["apt-get", "update"]
-
RUN
指令是一个非常关键的指令,用于在构建镜像的过程中执行命令或脚本。RUN
指令的主要作用是在当前镜像的基础之上执行命令,并将命令执行的结果作为一个新的镜像层提交。每个RUN
指令都会生成一个新的镜像层,因此它是镜像构建过程中创建新层的关键步骤之一 -
RUN
指令经常用于在镜像构建阶段执行各种任务,如安装软件包、设置环境变量、创建目录、复制文件、运行自定义脚本等。同时,为了优化镜像大小和构建速度,通常推荐合并多个命令到单个RUN
指令中# 这样做的好处是可以减少中间镜像层的数量,提高构建效率。 RUN apt-get update && \ apt-get install -y python3 python3-pip && \ pip3 install Flask && \ rm -rf /var/lib/apt/lists/*
CMD
格式
# shell 形式
CMD command
CMD echo "hello World"
# exec 形式
CMD ["executable","param1","param2"]
CMD ["java","-jar","/app.jar"]
# 和ENTRYPOINT配套使用
CMD ["param1","param2"]
- 类似于RUN指令,CMD指令也可用于运行任何命令或应用程序,不过,二者的运行时间点不同
- RUN指令运行于镜像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新镜像文件启动一个容器时
- CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,CMD指定的命令其可以被docker run的命令行选项所覆盖
- 在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效
ENTRYPOINT
格式
# shell 形式
ENTRYPOINT command
# exec 形式
ENTRYPOINT ["executable", "param1", "param2"]
#docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用
-
ENTRYPOINT
指令用于配置容器启动时运行的默认命令和参数,它的目的是设定容器的主要行为或者说主入口点 -
ENTRYPOINT
的内容一般是不可变的,即使在运行容器时使用docker run
后面跟有额外的命令,这些命令也会作为参数追加到ENTRYPOINT
定义的命令之后执行 -
不过,docker run命令的--entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序
-
Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效
-
ENTRYPOINT
和CMD
指令之间的关系- 如果同时设置了
ENTRYPOINT
和CMD
,并且CMD
使用的是默认参数形式(不是JSON数组形式),那么CMD
的内容将会作为参数追加到ENTRYPOINT
后面一起执行 - 若
ENTRYPOINT
未定义,CMD
将作为容器启动时的默认命令执行 - 在很多情况下,
ENTRYPOINT
和CMD
结合使用可以更好地管理容器的启动命令和参数。例如,可以将ENTRYPOINT
设定为一个固定的执行脚本或命令,然后用CMD
来传递可变的参数,这样既可以保证容器的核心行为不变,又能方便地根据需要调整参数
# 使用官方的Java运行时作为基础镜像 FROM openjdk:17-jdk-alpine # 将本地的应用JAR文件复制到容器的/app目录下 COPY target/my-app.jar /app/ # 设置工作目录为/app WORKDIR /app # 定义ENTRYPOINT为java命令,"-jar"是一个固定参数,表示接下来是要执行的JAR文件 ENTRYPOINT ["java", "-jar"] # CMD指定默认的JAR文件名和任何默认启动参数 CMD ["my-app.jar"] # 用户可以通过 `docker run` 命令来覆盖默认的JAR文件名或添加额外参数 # 例如: `docker run my-image-name other-app.jar --server.port=8080`
- 如果同时设置了
镜像加速
通过以上网址获取自己的加速器地址
阿里云镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器