Loading

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 命令创建),你可以将容器连接到这个网络上
  • 列出容器

    • 列出正在运行的所有容器

      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。后续的 RUNCMDENTRYPOINT 等指令将在该目录下执行。

  • 如果提供的是一个相对路径,那么它将会相对于之前 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指令,但仅有最后一个会生效

  • ENTRYPOINTCMD 指令之间的关系

    • 如果同时设置了 ENTRYPOINTCMD,并且 CMD 使用的是默认参数形式(不是JSON数组形式),那么 CMD 的内容将会作为参数追加到 ENTRYPOINT 后面一起执行
    • ENTRYPOINT 未定义,CMD 将作为容器启动时的默认命令执行
    • 在很多情况下,ENTRYPOINTCMD 结合使用可以更好地管理容器的启动命令和参数。例如,可以将 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`
    

镜像加速

容器镜像服务 (aliyun.com)

通过以上网址获取自己的加速器地址

阿里云镜像加速

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来使用加速器

posted @ 2024-02-27 14:21  VoidCm  阅读(25)  评论(0编辑  收藏  举报