Docker小结

422 阅读14分钟

一、什么是Docker

Docker是一个开源的容器管理引擎,可以将应用程序直接打包到一个可移植的容器中,运行在任意支持Docker的环境上

  1. Docker的工作原理:使用操作系统级别的虚拟化技术实现容器的隔离和资源管理(可以简单理解成轻量化的虚拟机)与虚拟机相比,Docker更加轻量化,启动和停止速度更快,资源消耗更低,更容易管理和扩展
  2. Docker的核心特点
  • 轻量化:Docker容易只包含应用程序和最基本的系统组件,容易部署、管理和扩展
  • 可移植性:在所有支持Docker环境的服务器可以随意部署
  • 灵活性:通过镜像打包应用程序和依赖项,无需重新编译就能在不同环境运行
  • 可拓展性:支持动态增减容器,实现弹性扩展
  • 安全性:Docker提供数据卷和其它安全特性,保护数据和应用程序免受攻击
  1. Docker应用场景
  • 自动化部署:通过Docker自动化构建、部署应用程序
  • 持续集成/持续部署(CI/CD):Docker支持自动化测试和CI/CD
  • 微服务架构:Docker适合管理和构建微服务架构,每个服务可以独立部署和扩展

二、安装Docker

  1. Linux环境安装,以Centos为例,其它系统参考官方安装文档地址docs.docker.com/engine/inst…
# 1.移除旧版本docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

# 2.安装yum功能增强包
sudo yum install -y yum-utils

# 3.配置docker yum源地址
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

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

# 5.设置开机自启动
systemctl enable docker --now

# 6.配置docker加速镜像
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
    {
      "registry-mirrors": [
        "https://docker.m.daocloud.io"
      ]
  }
EOF

# 7.重新加载docker守护进程配置并重启dokcer
sudo systemctl daemon-reload
sudo systemctl restart docker

# 8.测试docker是否安装成功
docker -v

  1. Windows环境安装
  • 下载Docker Desktop,下载地址docs.docker.com/desktop/set…
  • 开启Hyper-V 左键单击电脑左下角开始按钮—>点击“设置”—>搜索“Windows功能”—>启用或关闭Windows功能—>勾选Hyper-v,启用后电脑会重启,安装环境配置成功

image.png

image.png

- 点击Docker Desktop安装包,默认安装即可 - 安装完成后配置加速镜像,打开Docker Desktop软件,依次点击设置->Docker Engine,修改加速镜像,将下面的内容替换已有的配置,最后点击apply
{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "experimental": false,
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://docker.aityp.com",
    "https://lispy.org"
  ]
}

image.png

  • 测试是否安装成功,打开cmd窗口执行docker -v看看是否打印docker版本信息,有版本信息输出即安装成功

三、Docker常用命令

  1. 查看指定命令有哪些操作
# 查看docker所有指令帮助手册
docker --help
# 例子:查看pull指令帮助手册
docker pull --help
# 例子:查看compose帮助手册
docker compose --help
  1. 镜像相关操作
# 没有指定镜像版本信息,默认下载latest版本,也就是最新版本
docker pull nginx
# 下载指定版本镜像
docker pull nginx:1.26.0
# 查看已下载镜像列表
docker images
# 根据id删除指定镜像
docker rmi imgaeId
# 批量删除所有镜像
docker rmi $(docker images -q)
  1. 容器相关操作
# 查看运行中的容器
docker ps
# 查看所有容器,包含stop的镜像
docker ps -a
# 启动容器,nginx是镜像名称,没有指定版本默认是启动latest,如果镜像没下载会自动下载
docker run nginx
docker run nginx:v1.26.0
# 启动容器并给容器取名为mynginx,该名称可以方便停止或重启容器,以及自定义网络中与其它容器交互
docker run --name mynginx nginx:1.26.0
# 后台启动容器
docker run -d --name mynginx nginx:1.26.0
# 后台启动容器并暴露指定端口号,多个端口可以多个-p传参
docker run -d --name mynginx -p 8080:80 -p 8848:8848 nginx:1.26.0
# 停止容器
docker stop 容器名称/容器id
# 启动容器
docker start 容器名称/容器id
# 重启容器
docker restart 容器名称/容器id
# 查看容器资源占用情况
docker stats 容器名称/容器id
# 查看容器信息
docker inspect 容器名称/容器id
# 进入正在运行的容器
docker exec -it 容器名称/容器id /bin/bash
docker exec -it 容器名称/容器id /sh/bash
# 删除容器,删除之前需要stop容器
docker rm 容器名称/容器id
# 强制删除容器,不用stop容器
docker rm -f 容器名称/容器id
# 强制删除所有容器
docker rm -f $(docker ps -a -q)
# 如果容器有修改,想要持久化保存,可以打包容器成为一个新的镜像
docker commit -m "update xxxx" 容器名称/容器id 新镜像名称:新镜像版本
docker commit -m  "update 配置文件" mynginx newnginx:v.10
# 保存镜像为指定文件
docker save -o mynginx.rar mynginx:v.10
# 将保存的文件加载成镜像
docker load -i mynginx.rar

4.docker目录挂载和卷映射

# 1.目录挂载,带有/,将主机的/app/html和容器的/usr/share/nginx/html目录进行关联挂载,
# 目录不存在时docker会自动创建,方便在主机直接修改或者查看容器内的文件,创建默认是空目录
# 例如:java服务日志、上传的文件进行目录挂载
-v /app/html:/usr/share/nginx/html
# 2.卷映射,没有/,将/var/lib/docker/volumes/mysql-data与容器的/mysql/data做映射关联,
# mysql-data卷不存在的时候docker会在/var/lib/docker/volumes目录下自动创建,
# 创建的时候默认会将容器内的文件复制到主机对应的卷目录
# 例子:初次创建的时候会把容器/mysql/data有数据会复制到主机指定的卷/var/lib/docker/volumes/mysql-data
# 例如:把mysql的配置目录卷映射到主机,这样就可以直接修改mysql相关配置
-v mysql-data:/mysql/data
# 后台启动一个name=mysql的容器,暴露的端口号是3306:3306,目录挂载/app/mysql-data:/var/lib/mysql,卷映射mysql:/etc/mysql
docker run -d --name mysql -p 3306:3306 -v /app/mysql-data:/var/lib/mysql -v mysql:/etc/mysql mysql:8.0.37-debian
  1. 卷相关命令
# 1.查看所有卷
docker volume ls
# 2.创建卷,docker将会在/var/lib/docker/volumes目录下创建卷名目录
docker volume create 卷名
# 2.删除指定卷
docker volume rm 卷名称
# 3.查看卷信息
docker volume inspect 卷名称
  1. 自定义网络相关命令
# 1.查看所有网络
docker network ls
# 2.创建网络
docker network create 网络名
# 3.删除指定网络
docker network rm 网络名
# 4.查看网络信息,可以查看同一个网络下的容器有哪些,同一个网络的容器可以直接使用容器名称作为host访问
docker network inspect 网络名
  1. java项目创建Dockerfile,然后根据Dockerfile文件创建对应镜像,以gateway服务为例
  • Dockerfile文件内容,将该文件放在target同级目录,因为Dockerfile中声明jar文件地址是相对路径target/monkey-gateway-1.0-SNAPSHOT.jar
# 使用包含字体库的jdk8镜像
FROM frolvlad/alpine-java:jdk8-slim

# 设置工作目录为/app,目录不存在docker会自动创建。决定了后续 RUN、CMD、ENTRYPOINT、COPY 和 ADD 等指令的执行路径
WORKDIR /app

# 定义构建参数 JAR_FILE,默认值为 target/monkey-gateway-1.0-SNAPSHOT.jar
ARG JAR_FILE=target/monkey-gateway-1.0-SNAPSHOT.jar

# 将构建好的 JAR 文件复制到镜像中,并重命名为 app.jar
COPY ${JAR_FILE} app.jar

# 声明容器运行时监听的端口
EXPOSE 5700

# 设置环境变量,包括时区和 Java 运行时参数,用户启动可以覆盖掉环境变量
ENV TZ=Asia/Shanghai
ENV JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -Xms128m -Xmx256m"
ENV NACOS_HOST=127.0.0.1
ENV NACOS_PORT=8848
ENV NACOS_NAMESPACE=public
ENV NACOS_GROUP=DEFAULT_GROUP
ENV NACOS_USERNAME=nacos
ENV NACOS_PASSWORD=nacos

# 使用数组格式定义 CMD 指令,方便覆盖运行命令
CMD java $JAVA_OPTS -jar app.jar
  • cd到target目录下,创建镜像gateway:1.0,注意命令最后面的.表示Dockerfile所在的目录为当前目录
docker build -t gateway:1.0 .
  • 创建镜像成功后,将镜像推送到DockerHub或者私有镜像仓库,以推送DockerHUb为例,需要先创建DockerHub账号,具体百度
# 1.登陆DockerHub账号,按提示输入账号密码
docker login
# 2.给镜像打标签,一般带上DockerHub用户名,例如DockerHub用户名=monkey
docker tag gateway:1.0 monkey/gateway:1.0
# 3.推送镜像
docker push monkey/gateway:v1.0
  1. 编写docker-compose.yaml文件以及docker compose相关命令
  • docker compose是用于定义和运行多个容器的Docker程序,通过编写yaml文件定义多个容器以及容器之间的关系,简化应用程序的部署和管理过程
  • 通过docker run命令依次部署容器
#一、部署mysql,部署成功后创建nacos_config数据库,初始化nacos配置相关表
docker run -d --name mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=mk-cloud -v mysql-data:/var/lib/mysql -v mysql:/etc/mysql --restart always --network prod mysql:8.0.37-debian
#二、部署redis
docker run -d --name redis -p 6389:6379 -e REDIS_PASSWORD=123456 -v /app/redis/prodrd1:/bitnami/redis/data --restart always --network prod bitnami/redis
#三、部署nacos,设置数据库持久化,部署成功后访问nacos管理页面,导入项目配置文件,修改相关配置
docker run -d --name nacos -p 8848:8848 -p 9848:9848 -p 9849:9849 -p 7848:7848 -e MODE=standalone -v nacos:/home/nacos --restart always --network prod nacos/nacos-server:v2.5.1
#四、项目创建Dockerfile制造镜像,根据制造的镜像部署项目jar包
4.1.以gateway服务为例
根据Dockerfile的配置,需要cd到target同级别目录
#制造镜像,镜像后面的.表示在当前目录进行build,与Dockerfile中复制jar包的命令有关
docker build -t monkey-gateway:1.0 .
# windows启动测试制作的镜像是否正确
docker run -d --name gateway -p 5700:5700 -e NACOS_HOST=192.168.11.1 -e NACOS_PORT=8848 -e NACOS_NAMESPACE=dev -e NACOS_GROUP=mk -e NACOS_USERNAME=nacos -e NACOS_PASSWORD=nacos@2025 monkey-gateway:1.0
# 将制作的镜像保存为rar文件,方便上传服务器(也可将镜像直接上传DockerHub)
docker save -o gateway.rar monkey-gateway:1.0
# 上传服务器之后加载对应rar包得到镜像,在rar包路径下执行下面命令
docker load -i gateway.rar
# linux启动镜像命令,其中-v挂载了日志文件和上传文件目录
docker run -d --name gateway -p 5700:5700 -e NACOS_HOST=nacos -e NACOS_PORT=8848 -e NACOS_NAMESPACE=dev -e NACOS_GROUP=mk -e NACOS_USERNAME=nacos -e NACOS_PASSWORD=nacos@2025 -v /www/logs:/www/logs -v /www/upload:/www/upload --restart always --network prod monkey-gateway:1.0


4.2.以service-user-server服务为例
根据Dockerfile的配置,需要cd到target同级别目录
# 制造镜像,镜像后面的.表示在当前目录进行build,与Dockerfile中复制jar包的命令有关
docker build -t monkey-user-server:1.0 .
# windows启动测试制作的镜像是否正确
docker run -d --name user-server -p 5800:5800 -e NACOS_HOST=192.168.11.1 -e NACOS_PORT=8848 -e NACOS_NAMESPACE=dev -e NACOS_GROUP=mk -e NACOS_USERNAME=nacos -e NACOS_PASSWORD=nacos@2025 monkey-user-server:1.0
# 将制作的镜像保存为rar文件,方便上传服务器(也可将镜像直接上传DockerHub)
docker save -o user-server.rar monkey-user-server:1.0
# 上传服务器之后加载对应rar包得到镜像,在rar包路径下执行下面命令
docker load -i user-server.rar
# linux启动镜像命令,其中-v挂载了日志文件和上传文件目录
docker run -d --name user-server -p 5800:5800 -e NACOS_HOST=nacos -e NACOS_PORT=8848 -e NACOS_NAMESPACE=dev -e NACOS_GROUP=mk -e NACOS_USERNAME=nacos -e NACOS_PASSWORD=nacos@2025 -v /www/logs:/www/logs -v /www/upload:/www/upload --restart always --network prod monkey-user-server:1.0
  • 将上面docker run的所有命令转成通过编写yaml文件定义容器和容器之间的关系
#设置项目名称,不设置docker会自动创建一个项目名称
name: mk
#设置项目服务
services:
  # mysql容器,名称随意定义,在当前文件不要重复即可
  mysql:
    # 容器名称
    container_name: mysql
    # 容器镜像
    image: mysql:8.0.37-debian
    # 暴露端口,多个端口依次增加-即可
    ports:
      - 3307:3306
    # 定义环境变量
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=mk-cloud
    #解决mysql启动报错mbind: Operation not permitted,允许容器中的进程修改其优先级
    cap_add:
      - SYS_NICE
    # 定义容器挂载的目录和映射的卷,映射的卷需要在顶级元素volumes下面额外定义
    volumes:
      - mysql-data:/var/lib/mysql
      - mysql:/etc/mysql
      - /app/mysql/initsql/nacos-init.sql:/docker-entrypoint-initdb.d/nacos-init.sql
    # 是否自动重启
    restart: always
    # 定义加入的网络,网络需要在顶级元素networks下面额外定义,同一个网络的容器可以直接使用容器名称作为host访问
    networks:
      - prod
  # redis容器,名称随意定义,在当前文件不要重复即可
  redis:
    # 容器名称
    container_name: redis
    # 容器镜像
    image: bitnami/redis
    # 暴露端口,多个端口依次增加-即可
    ports:
      - 6389:6379
    # 定义环境变量
    environment:
      - REDIS_PASSWORD=123456
    # 定义容器挂载的目录和映射的卷,映射的卷需要在顶级元素volumes下面额外定义
    volumes:
      - /app/redis/prodrd1:/bitnami/redis/data
    # 是否自动重启
    restart: always
    # 定义加入的网络,网络需要在顶级元素networks下面额外定义,同一个网络的容器可以直接使用容器名称作为host访问
    networks:
      - prod
  # nacos容器,名称随意定义,在当前文件不要重复即可
  nacos:
    # 容器名称
    container_name: nacos
    # 容器镜像
    image: nacos/nacos-server:v2.5.1
    # 暴露端口,多个端口依次增加-即可
    ports:
      - 8848:8848
      - 9848:9848
      - 9849:9849
      - 7848:7848
    # 定义环境变量
    environment:
      - MODE=standalone
    # 定义容器挂载的目录和映射的卷,映射的卷需要在顶级元素volumes下面额外定义
    volumes:
      - nacos:/home/nacos
    # 是否自动重启
    restart: always
    # 定义加入的网络,网络需要在顶级元素networks下面额外定义,同一个网络的容器可以直接使用容器名称作为host访问
    networks:
      - prod
    # 容器依赖关系,按照配置的先后顺序,当前容器会在依赖的容器启动后再启动
    depends_on:
      - mysql
  # java服务gateway容器,名称随意定义,在当前文件不要重复即可
  gateway:
    # 容器名称
    container_name: gateway
    # 容器镜像
    image: monkey-gateway:1.0
    # 暴露端口,多个端口依次增加-即可
    ports:
      - 5700:5700
    # 定义环境变量
    environment:
      - NACOS_HOST=nacos
      - NACOS_PORT=8848
      - NACOS_NAMESPACE=dev
      - NACOS_GROUP=mk
      - NACOS_USERNAME=nacos
      - NACOS_PASSWORD=nacos@2025
    # 定义容器挂载的目录和映射的卷,映射的卷需要在顶级元素volumes下面额外定义
    volumes:
      - /www/logs:/www/logs
      - /www/upload:/www/upload
    # 是否自动重启
    restart: always
    # 定义加入的网络,网络需要在顶级元素networks下面额外定义,同一个网络的容器可以直接使用容器名称作为host访问
    networks:
      - prod
    # 容器依赖关系,按照配置的先后顺序,当前容器会在依赖的容器启动后再启动
    depends_on:
      - mysql
      - redis
      - nacos
  # java服务user-server容器,名称随意定义,在当前文件不要重复即可
  user-server:
    # 容器名称
    container_name: user-server
    # 容器镜像
    image: monkey-user-server:1.0
    # 暴露端口,多个端口依次增加-即可
    ports:
      - 5800:5800
    # 定义环境变量
    environment:
      - NACOS_HOST=nacos
      - NACOS_PORT=8848
      - NACOS_NAMESPACE=dev
      - NACOS_GROUP=mk
      - NACOS_USERNAME=nacos
      - NACOS_PASSWORD=nacos@2025
    # 定义容器挂载的目录和映射的卷,映射的卷需要在顶级元素volumes下面额外定义
    volumes:
      - /www/logs:/www/logs
      - /www/upload:/www/upload
    # 是否自动重启
    restart: always
    # 定义加入的网络,网络需要在顶级元素networks下面额外定义,同一个网络的容器可以直接使用容器名称作为host访问
    networks:
      - prod
    # 容器依赖关系,按照配置的先后顺序,当前容器会在依赖的容器启动后再启动
    depends_on:
      - mysql
      - redis
      - nacos

#设置项目网络,docker会根据配置创建相关网络
networks:
  prod:
    #设置网络实际名称,不设置会按照项目名称_网络名称(mk_prod)
    name: prod
    #网络存在的时候使用已存在的网络,否则新创建
    external: true
#设置项目卷映射,docker会更具配置创建相关卷,目录挂载不需要配置
volumes:
  mysql-data:
    #设置卷实际名称,不设置会按照项目名称_卷名(mk_mysql-data)
    name: mysql-data
    #卷存在的时候使用已存在的卷,否则新创建
    external: true
  mysql:
    #设置卷实际名称,不设置会按照项目名称_卷名(mk_mysql)
    name: mysql
    #卷存在的时候使用已存在的卷,否则新创建
    external: true
  nacos:
    #设置卷实际名称,不设置会按照项目名称_卷名(mk_nacos)
    name: nacos
    #卷存在的时候使用已存在的卷,否则新创建
    external: true
  • docker compose常用命令
# 1.按照compose.yaml依次后台启动容器,没有指定yaml文件的情况docker默认以当前目录下compose.yaml启动
docker compose up -d
# 2.指定yaml文件依次后台启动容器
docker compsoe -f my-compose.yaml up -d
# 3.根据指定yaml文件删除容器、网络,默认不删除卷
docker compose -f my-compose.yaml down
# 4.根据指定yaml文件删除容器、网络,删除卷
docker compose -f my-compose.yaml down -v
# 5.停止指定compose文件启动的所有容器,没有指定默认按照compose.yaml
docker compose -f my-compose.yaml stop
# 6.启动指定compose文件启动的所有容器,没有指定默认按照compose.yaml,该命令不能用于第一次启动,只能用于docker compose stop停止的
docker compose -f my-compose.yaml start

四、Docker镜像的分层机制

  1. 镜像层空间共享:相同镜像启动的不同容器共享同一个镜像的存储空间,镜像层是只读的
  2. 容器层空间独立:每个容器都有自己独立的容器层空间,对容器的修改实际就是修改容器层,因此不同容器之间是独立

五、Docker可以编写Dockerfile并与CI/CD相关工具(Jenkins)集成实现全自动的项目部署