Skip to content

Docker

技术文档:Get started | Docker Docs

概述

作用

  • 跨平台快速构建应用:通过打包为镜像,解决每次部署都需安装依赖、进行环境配置,以及不同设备上部署产生的各种问题。通过镜像中心可以快速获取镜像。
  • 各应用间隔离:Docker中不同容器间是相互隔离的,如一个容器内的应用发生内存泄漏,其最多影响到该容器,而不会导致整个系统的崩溃。且因为是相互隔离的,所以可以同时部署不同版本的相同应用,而不会出现冲突问题。

概念

仓库

仓库就是存放镜像的地方,仓库分为公有仓库和私有仓库。Docker 公司提供了公共的镜像仓库 https://hub.docker.com

镜像

Docker 将应用程序及其运行环境依赖项打包成镜像,镜像包含了应用程序所需的所有内容,包括代码、运行时环境、系统工具、库和依赖项。相当于面向对象中的类,而容器则是镜像的实例对象,一个镜像可以实例化出多个容器

容器

容器是镜像的运行时实例,可以被理解为一个隔离的、独立的运行时环境,其中包含了应用程序及其运行所需的一切。

  • 虚拟机技术: 使用Hypervisor在物理服务器上创建多个完整的虚拟机。每个虚拟机都包含了自己的操作系统、内核和用户空间,相互独立。
  • Docker容器:与宿主机共享同一个操作系统内核,但各自拥有自己的用户空间,这使得容器更为轻量级。

安装

shell
# 移除旧版本docker
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine


# 配置docker yum源。
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo


# 安装 最新 docker
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 启动& 开机启动docker; enable + start 二合一
systemctl enable docker --now


# 配置加速,如果registry-mirrors中镜像源无效,百度查找替换新的镜像源
# 如果镜像在下方的镜像源都找不到,最终还是会访问dockerhub官网的
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
      "https://docker.1ms.run",
      "https://registry.docker-cn.com",
      "https://dockerhub.azk8s.cn",
      "https://docker.1panelproxy.com/"
  ]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

使用

镜像命令

docker search(搜索镜像)

命令作用
docker search 镜像名称搜索镜像
docker search --limit 10 镜像名称搜索镜像,同时显示显示的结果,只显示10条,不加参数,默认显示25条

docker pull(拉取镜像)

指定镜像版本拉取时,使用Docker Hub搜索,找到对应镜像,点击tags查看其所有版本

命令作用
docker pull 镜像名称拉取latest版本的镜像
docker pull 镜像名称:版本tag拉取指定版本的镜像

docker images(查看现有镜像)

命令作用
docker images查看本地所有镜像
docker images -a查看本地所有镜像,包括中间层(intermediate layers)。
docker images -q只显示镜像的ID
docker images -aq只显示镜像的ID,且显示中间层

docker rmi(删除镜像)

要删除镜像,需要先删除用这个镜像创建的容器(删除容器后面再讲),或者使用强制删除。

命令作用
docker rmi 镜像ID删除镜像,不需要输入完整id,只需要输入前几位且与其他镜像不重复即可
docker rmi -f 镜像ID强制删除
docker rmi 镜像名称只会删除最新版本的镜像
docker rmi 镜像名称:版本tag删除指定版本的镜像
docker rmi 镜像ID1 镜像ID2删除多个
docker rmi -f $(docker images -qa)删除所有镜像,慎用或不用,docker images -qa是获取到镜像的ID

docker system df(查看镜像、容器占用)

镜像推送

命令作用
docker login登录 docker hub
docker tag mynginx:v1.0 leifengyang/mynginx:v1.0重新给镜像打标签
docker push leifengyang/mynginx:v1.0推送镜像

容器命令

docker run(启动容器)

docker run -d --name nginx nginx:latest:基于指定镜像nginx:latest创建一个容器(可以多次运行创建多个)

  • 交互式容器:需要在前台运行以便与用户进行交互,如Ubuntu 容器、CentOS 容器,使用-it
  • 守护式容器:适合在后台运行,例如 redis,使用-d
命令作用
docker run -d --name name 镜像-d表示后台启动,--name用于指定运行容器的名称
docker run -it --name name 镜像 /bin/bash-i 代表交互模式,使容器保持打开状态并等待用户命令输入;-t 分配一个伪终端或终端,使输入可见。
docker run -d -p 6379:6379 <br>-e REDIS_REPLICATION_MODE=master <br/>-e REDIS_PASSWORD=12345<br/>redis-e:用于设置启动应用的环境变量,通过参考DockerHub上镜像对应的说明来选择性配置。

资源占用限制

下方仅列出基本限制条件,这些限制条件可以组合使用

命令作用
docker run --cpus 2 image启动时指定容器占用CPU核心数,可以为小数
docker update --cpus=2 container启动后修改容器占用CPU核心数,可以为小数
docker run -m 512m image限制容器只能使用512MB的内存(单位m也可以替换为g)
docker run --memory-swap=1g image设置交换空间限制

docker exec/attach(进入容器)

命令作用
docker exec -it 容器ID或名称 /bin/bash在容器中打开新的终端,时候用 exit 退出容器,不会导致容器停止
docker attach 容器ID或名称不会启动新的进程,所以用 exit 退出,会终止当前容器运行

docker ps(查看容器)

命令作用
docker ps查看运行中的容器
docker ps -a查看所有的容器,包括停止的
docker ps -l查看最近创建的容器
docker ps -q查看容器,只显示容器编号
docker ps -n m查看最近m个创建的容器

docker stop/kill(停止容器)

命令作用
docker stop 容器ID/名称停止前会向容器发送信号,做好数据保存准备
docker kill 容器ID/名称直接杀死。

docker start(运行已停止的容器)

命令作用
docker start 容器ID/名称重新运行已停止的容器

docker restart(重启正在运行的容器)

命令作用
docker restart 容器ID/名称重启正在运行的容器

docker rm(删除容器)

命令作用
docker rm 容器ID/名称删除已停止的容器
docker rm -f 容器ID/名称强制删除容器,运行中的也可以删除
docker rm -f $(docker ps -a -q)删除全部容器
docker ps -a -q | xargs docker rm删除全部容器

端口映射

命令作用
docker run -p 6379:6379 镜像-p 表示端口映射,前面的 6379 表示宿主机的端口号,后面的 6379 表示容器的端口号。
docker run -p 80:80 -p 8080:8080 镜像指定多个端口映射

重启策略

  • no:默认策略,在容器退出时不进行重启。
  • always:无论容器退出状态如何,都会尝试重启容器。
  • on-failure:只有在容器以非零状态码退出时才尝试重启容器。
  • unless-stopped:在容器退出或守护进程重启时,始终重启容器,除非用户明确停止了容器。
命令作用
docker run -d -p 6379:6379 --restart=always redis容器未启动,指定容器的重启策略
docker update --restart=always <container_id>容器已经启动了,可以使用 update 命令修改容器的重启策略

docker logs(查看容器日志)

命令作用
docker logs 容器ID/名称查看容器日志

docker inspect(查看容器详细信息)

命令作用
docker inspect 容器ID/名称查看容器详细信息

docker cp(文件拷贝)

命令作用
docker cp 宿主机路径 容器ID:容器内路径将宿主机的文件拷贝到容器
docker cp 容器ID:容器内路径 宿主机路径将容器的文件拷贝到宿主机

保存镜像

  • export:把之前镜像的层级删干净,只保留最新的快照文件,只有一层。
  • commit+save:保留了一个镜像的所有历史文件和元数据,它把容器的内容作为一个新的层覆盖在原有镜像之上,然后实现持久化。原有的镜像没有改变。

docker load/save(镜像导入/导出)

  • docker save -o /opt/ nginx:latest
  • docker load -i /opt/naginx-image
命令作用
docker save -o /path/name image_name:tag对当前的镜像进行持久化,形成tar文件
docker load -i /path/name将tar文件加载为镜像

docker export/import(容器导入/导出)

命令作用
docker export 容器ID/名称 > 文件.tar对当前的容器状态建立快照,并持久化为tar文件
docker import 文件.tar 镜像名称:版本标签从tar包导入为镜像

docker commmit(导入/导出为镜像)

命令作用
docker commit -m="提交的描述信息" -a="作者" 容器ID 镜像名:[版本标签]把当前容器的内容新建一个层文件,覆盖在旧的镜像文件层之上,然后导出为新镜像

容器数据卷

当容器被删除后,内部运行的应用数据就会被删除。而将容器的目录与宿主机的目录进行映射,即使容器被删除,挂载到容器卷中的数据仍然会被保留在宿主机上。

目录挂载

如果宿主机或者容器内没有指定的目录(挂载的路径必须是绝对路径),则会自动创建(挂载的必须是目录)。

容器的目录变成了指向了宿主机的目录的一个链接,软件运行时使用的是宿主机目录下的内容,所以即使容器内目录有内容,也会丢失。

所以如果宿主机的挂载目录下没有文件,则容器被挂载目录下有文件也不起作用,如:将nginx的配置文件目录直接挂载到宿主机的空目录下,由于不存在内容,将会无法启动。

命令作用
docker run -d --privileged=true -v 宿主机目录:容器内目录 镜像--privileged=true:这个选项会赋予容器内的 root 用户几乎所有在宿主机上的 root 用户的权限。<br>-v :指定容器内目录挂载到宿主机的位置

卷映射

  • 如果容器卷是空的而容器中的目录有内容,那么docker会将容器目录中的内容拷贝到容器卷中
  • 如果容器卷中已经有内容,则会将容器中的目录覆盖。
  • 容器卷由自己命名,存放在路径/var/lib/docker/volumes/下
命令作用
docker run --privileged=true -v 容器卷名:容器中目录 镜像--privileged=true:这个选项会赋予容器内的 root 用户几乎所有在宿主机上的 root 用户的权限。<br>-v :指定要挂载的容器目录
docker volume ls查看 docker 中存在的卷
docker inspect 卷名命令查看容器卷的信息,可以找到其位置
docker volume create 卷名称创建容器卷,启动时可以直接使用,多个容器可以使用同一个卷
###############添加这3行
proxy_buffer_size 64k;
proxy_buffers   32 32k;
proxy_busy_buffers_size 128k;
###############添加这3行
proxy_set_header Host $host;
proxy_set_header X-Real-IP       $remote_addr;
proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;

docker网络

常用命令

命令作用
docker network ls查看所有网络模式
docker network create 网络名称创建指定网络
docker network rm 网络ID/名称删除指定网络
docker network inspect 网络ID/名称查看指定网络详细信息

三种模式

docker run -it --network none --name ubuntu-1 ubuntu /bin/bash:通过--network指定

  • bridge网络模式:为每一个容器分配、设置 IP 等,并将容器连接到一个 docker0 虚拟网桥,Docker 网络默认使用的就是该模式。注意,分配给容器的ip不是固定的。
  • host网络模式:容器将不会虚拟出自己的网卡,而是使用宿主机的 IP 和端口,不需要映射端口,直接使用http://宿主机IP:端口号即可访问
  • none网络模式:不对容器进行任何网络设置,即无法使用网络,如果需要,只能自己添加网络配置。

自定义网络模式

1、通过docker network create 网络名创建,新创建的网络模式也是桥接模式(因为默认桥接网络不提供内置的服务发现机制,而自定义的提供,所以其才可以通过服务名来访问

2、创建容器时指定新建网络的名称vv

shell
# 创建ubuntu-1容器,并加入到doubi-network网络
docker run -it --network doubi-network --name ubuntu-1 ubuntu /bin/bash

# 创建ubuntu-2容器,并加入到doubi-network网络
docker run -it --network doubi-network --name ubuntu-2 ubuntu /bin/bash

3、直接在容器1中执行ping ubuntu-2,可以ping通容器2

Dockerfile(构建镜像)

流程

1、编写一个 Dockerfile 文件(Dockerhub上可以直接查看对应应用的Dokcerfile文件)

dockerfile
# 例:构建SpringBoot的Dockerfile
FROM openjdk:17
LABEL author=leifengyang
COPY app.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

2、使用 docker build 命令运行脚本文件,构建成为一个镜像;

shell
# -t指定镜像名称和版本,.表示在当前目录寻找Dockerfile文件
docker build -t myubuntu:1.0.0 .

常用命令

FROM

指明构建的新镜像是基于哪个基础镜像

shell
FROM <image>:<tag>
LABEL

用于向镜像添加键值对,提供关于镜像的描述信息。

LABEL <key>=<value> <key>=<value> <key>=<value> ...
RUN

在构建镜像时执行命令。RUN命令会在执行docker build命令的时候执行。每⼀条 RUN 指令都会在镜像上构建⼀层,可以将多个 RUN 命令合并为一条命令(会降低可读性),从而减少镜像的层数。

shell
# 使用shell格式的run命令
RUN apt update && apt install -y vim

# 使用exec格式的run命令
RUN ["apt", "update", "&&", "apt", "install", "-y", "vim"]
COPY

拷贝文件或目录到镜像中。

ADD

src 可以是一个本地文件或者是一个本地压缩文件,压缩文件会自动解压拷贝到镜像。还可以是一个 url,效果类似于 wget 命令,然后自动下载和解压。

dockerfile
ADD <src> <dest>

ADD https://example.com/file.tar.gz /tmp/
WORKDIR

用于设置工作目录,此后的 RUN、CMD、ENTRYPOINT、COPY 、AND 等命令将在这个工作目录下执行。

dockerfile
WORKDIR 路径
ENV

用于在构建镜像过程中设置环境变量

shell
# 格式1
ENV key value

# 格式2
ENV key1=value1 key2=value2


# 设置一个名为 "WORK_HOME" 的环境变量
ENV WORK_HOME /home/doubi
# 通过$引用
WORKDIR $WORK_HOME


# 容器启动时可以通过-e覆盖环境变量
docker run -d -e SPRING_PROFILES_ACTIVE=dev -p 8080:8080 my_image
ARG

ENV 命令作用一样,和 ENV 命令不同的是:这些变量只在构建过程中有效,构建完成后不会被保留在最终的镜像中。

shell
# 定义构建参数  
ARG VERSION=latest  
ARG BUILD_DATE  
  
# 使用构建参数设置环境变量  
ENV APP_VERSION=$VERSION  
ENV BUILD_DATE=$BUILD_DATE 
EXPOSE

表明容器在运行时会监听指定的网络端口,让使用者知道应用程序会使用哪些端口,实际上还需要run时指定端口映射。

# 暴露80端口
EXPOSE 80

# 暴露多个端口
EXPOSE 80 443

# 指定端口和协议
EXPOSE 8080/tcp
CMD

为容器指定默认的执行命令或应用程序,当容器启动时,这个命令将被执行。如果在 Dockerfile 中存在多个 CMD命令,只有最后一个会生效

shell
# 同样支持shell和exec两种格式
# Shell格式
CMD <command>

# Exec格式
CMD ["参数1", "参数2", ...]

# /bin/bash会替换掉 Tomcat Dockerfile文件中的 CMD
docker run -it -p 8080 tomcat /bin/bash
VOLUME

VOLUME 命令用来做匿名挂载,在启动容器时忘记挂载数据卷,会自动挂载到匿名卷(/var/lib/docker/volumes/xxxx/_data下)

shell
# 方式1
VOLUME <路径>

# 方式2
VOLUME <路径1> <路径2>

# 方式3
VOLUME ["<路径1>", "<路径2>"...]=

Docker Compose

命令作用
docker compose config -q查看编写的compose文件是否存在问题,存在问题才会输出内容
docker compose up -d后台启动所有容器
docker compose down该命令不仅停止容器,还会直接删除容器、网络、容器卷,镜像不会删除,下次启动会重新启动。
docker compose stop停止服务
docker compose stop 容器服务名停止docker-compose文件中定义的某一个容器服务 (yaml中定义的容器服务名称)
docker compose start启动已停止的容器
docker compose start 容器服务名启动docker-compose文件中定义的某一个容器服务(yaml中定义的容器服务名称)
docker compose restart重启
docker compose restart 容器服务名重启docker-compose文件中定义的某一个容器服务(yaml中定义的容器服务名称)
docker compose ps显示docker compose 编排的所有正在运行的容器
docker compose ps -a容器服务名指的是docker-compose.yaml中定义的容器服务名称
yml
name: myblog
services:
  mysql:
    container_name: mysql
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=wordpress  
    volumes:
      # 卷映射,需要在下方声明mysql-data
      - mysql-data:/var/lib/mysql
      # 目录挂载
      - /app/myconf:/etc/mysql/conf.d
    restart: always
    # 加入网络,可以加入一个,也可以加入多个
    networks:
      - blog

  wordpress:
    image: wordpress
    ports:
      - "8080:80"
    environment:
      #因为加入到了同一个网络,直接使用容器名就可以访问了
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: 123456
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress:/var/www/html
    restart: always
    networks:
      - blog
    # 依赖于哪个服务,需要在这些服务后启动
    depends_on:
      - mysql

  #服务名称:compose-boot,名称是自己定义的
  compose-boot:     
    # 使用当前目录下的 Dockerfile 构建镜像,如果编排的镜像需要使用多个Dockerfile,那就需要将多个Dockerfile放到不同的目录了后指定路径
    build: .              									
    volumes: 
      - /home/doubi/compose-boot/logs:/logs
    ports: 
      - 8080:8080
    restart: always                            
    networks: 
      - blog
    depends_on: 														
      - mysql

volumes:
  mysql-data:
  wordpress:

# 声明网络
networks:
  blog: