1. 引言

1.1. Docker概述

docker_logo

Docker是一个开放源代码的开放平台软件,用于开发应用、交付应用和运行应用。Docker允许用户将服务器中的应用单独分割出来,形成更小的颗粒(即分割为多个容器),从而提高交付软件的速度。

Docker容器与虚拟机类似,但二者在原理上不同。容器是将操作系统层虚拟化,虚拟机则将硬件虚拟化,因此容器更具有便携性、更能高效地利用服务器。 容器更多的用于表示软件的一个标准化单元。由于容器的标准化,因此它可以无视服务器的差异,部署到任何一个地方。

Docker应用运行在容器中,使用了沙箱机制,相互隔离

1.2. 基本概念

  • 镜像(Images)

​ 是一个 只读模板,用于 创建容器

​ 包含应用程序及其依赖、配置、运行环境、部分系统函数库文件。

  • 容器(Containers)

​ 通过镜像创建的 可运行的实例

2. 镜像操作

2.1. 镜像名称

  • 镜名称一般分两部分组成:[镜像名]:[tag]。(tag一般为版本号)
  • 在没有指定tag时,默认为latest,代表最新版本的镜像

2.2. 镜像常用命令

  • 查看所有镜像
docker images
  • 本地安装镜像
docker install -i 本地文件名
  • 镜像导出到本地
docker save -o 导出文件名 导出的镜像名:tag
  • 删除镜像
docker rmi 镜像名1:tag 镜像名2:tag 镜像名3:tag...
  • 搜索远程镜像
docker search 镜像名
  • 拉取远程镜像
docker pull 镜像名:tag

3. Docker基本操作

容器创建以后,会生成一个序列码。可以使用序列码的前四位替代命令中的容器名字

3.1. 容器相关操作

  • 查看所有运行中的容器
docker ps
  • 查看所有容器(包含停止)
docker ps -a
  • 创建容器
docker run --name 容器名字 -v 数据卷挂载信息 -p 对外映射端口:容器内端口 -e 环境参数key=value -d 镜像名:tag
  • 停止容器
docker stop 容器名字
  • 运行一个创建过的容器
# 运行
docker start 容器名字
# 重启
docker restart 容器名字
  • 删除容器
# 删除停止的容器
docker rm 容器名字1 容器名字2 容器名字3...
# 强制删除容器(可删除运行中的容器)
docker rm -f 容器名字1 容器名字2 容器名字3...
  • 进入容器内部
docker exec -it 容器名字 /bin/bash

3.2. 数据卷相关操作

  • 列出所有的数据卷
docker volume ls
  • 显示数据卷信息
# 显示所有数据卷信息
docker volume inspect 
# 显示指定名字的数据卷的信息
docker volume inspect 数据卷名字
  • 创建数据卷
# 创建的数据卷,位于宿主机的 /var/lib/docker/volumes/数据卷名字/_data/ 
docker volume create 数据卷名字
  • 删除指定数据卷
docker volume rm 数据卷名字1 数据卷名字2 数据卷名字3
  • 删除未使用的数据卷
docker volume prune

3.3. 具体配置案例

mysql启动容器时,如果是使用官方镜像启动,则需要设置root密码

此处以mysql5.7.25为例子,mysql官方镜像创建容器时,需要指定初始root密码

docker run --name mysqldemo -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.25

4. 自定义镜像

4.1.镜像结构

镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。

我们以MySQL为例,来看看镜像的组成结构:

image-20210731175806273

简单来说,镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。

我们要构建镜像,其实就是实现上述打包的过程。而分层的目的是为了提高复用性。因为一个镜像可以是在另一个镜像的基础上编写的。

4.2. Dockerfile语法

制作镜像的方式,其实就是我们编写一个名为Dockerfile的配置文件。它是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。

将Dockerfile文件和构建镜像所需要的所有内容放在一个文件夹里,在这个文件夹里执行下面的命令,docker就会根据Dockerfile的描述构建镜像。

docker build -t 镜像名:tag .

特殊的,如果你的配置文件名不叫Dockerfile的话,可以在上面的命令尾部追加 -f 文件名 ,用来执行你的配置文件。

Dockerfile说明

指令 说明 示例
FROM 指定基础镜像。
如果基础镜像本地已经安装,就先从本地获取。
也可以把基础镜像的tar包放在Dockerfile文件的目录下,安装时候会自动查找
FROM centos:6
ENV 设置环境变量,可在后面指令使用 ENV key value
COPY 拷贝本地文件到镜像的指定目录 COPY./mysql-5.7.rpm /tmp
RUN 执行Linux的shell命令,一般是安装过程的命令 RUN yum install gcc
EXPOSE 指定容器运行时监听的端口,是给镜像使用者看的 EXPOSE 8080
ENTRYPOINT 镜像中应用的启动命令,容器运行时调用 ENTRYPOINTjava -jar xx.jar

4.3. 示例:自定义java应用镜像-1

本案例的步骤:

  1. 本案例基于ubuntu:16.04镜像生成。

  2. 在基础镜像之上,设置好java环境(拷贝本地的jdk到镜像中,配置java_home等环境变量)

  3. 拷贝本地的java应用的jar包到某个目录

  4. 暴露端口

  5. 设置启动命令,使用 java -jar 命令运行java程序

准备工作:(在一个文件夹中存放如下文件)

  • ubuntu:16.04的镜像tar包(非必须,没有的话会从远程拉取)

  • jdk8.tar.gz(jdk)

  • docker-demo.jar(应用程序)

  • Dockerfile


Dockerfile文件内容:

# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local

# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar

# 安装JDK
RUN cd $JAVA_DIR \
 && tar -xf ./jdk8.tar.gz \
 && mv ./jdk1.8.0_144 ./java8

# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin

# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar

  • 使用docker build命令构建镜像
docker build -t javaweb:2.0 . -f Dockerfile

如果Dockerfile的文件名就叫Dockerfile,那么可以省略命令最后的 -f Dockerfile

4.4. 示例:自定义java应用镜像-2

本案例步骤:

  1. 本案例基于java官方的镜像 java:8-alpine 生成

  2. 拷贝本地的java应用的jar包到某个目录

  3. 暴露端口

  4. 设置启动命令,使用 java -jar 命令运行java程序

本示例和上一个示例的区别是,本案例使用java官方提供的java:8-alpine镜像作为基础镜像,该镜像中已经包含了java运行需要的基本环境。

相比于上一个示例中的Ubuntu镜像,java镜像删除了很多冗余的内容,更为精简。

准备工作:(在一个文件夹中存放如下文件)

  • java:8-alpine的镜像tar包(非必须,没有的话会从远程拉取)

  • docker-demo.jar(应用程序)

  • Dockerfile


Dockerfile文件内容:

FROM java:8-alpine
COPY ./docker-demo.jar /tmp/app.jar
EXPOSE 8090
ENTRYPOINT java -jar /tmp/app.jar

  • 使用docker build命令构建镜像
docker build -t javaweb:2.0 . 

5.docker-compose

Docker-Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器

docker-compose.yml

使用docker-compose部署集群,需要编写一个文本文件docker-compose.yml,用于指定构建规则。

我们的目标是一次创建多个docker容器。在docekr-compose中,配置的是一个个的服务

服务指的就是,通过什么样的规则创建docker容器。一个服务会默认创建一个容器,之后也可以通过服务名创建和删除容器。

配置服务的时候,我们可以指定通过通过镜像构建,也可以根据dockerfile,先构建镜像,再构建容器。

具体的 docker-compose.yml 文件配置规则,请看下一篇笔记。

或访问 docker compose 配置文件 .yml 全面指南

命令

  • 部署:
docker-compose up -d
  • 停止:
docker-compose down -d
  • 服务扩容缩容:
docker-compose up --scale 服务名=数量 -d
  • 其他
# 查看
docker-compose ps
# 开启服务
docker-compose start 服务名
# 关闭服务
docker-compose stop 服务名
# 重启服务
docker-compose restart 服务名

.示例:部署一个java应用集群

需求描述

该应用由 网关模块、用户模块、订单模块、数据库、nacos 共五部分组成

其中,网关模块和nacos模块需要被外部访问,其他模块仅存在内部调用。


docker-compose.yml文件:

version: "3.2"

services:
  nacos:
    image: nacos/nacos-server
    environment:
      MODE: standalone
    ports:
      - "8848:8848"
  mysql:
    image: mysql:5.7.25
    environment:
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "$PWD/mysql/data:/var/lib/mysql"
      - "$PWD/mysql/conf:/etc/mysql/conf.d/"
  userservice:
    build: ./user-service
  orderservice:
    build: ./order-service
  gateway:
    build: ./gateway
    ports:
      - "10010:10010"

最上方是指定docker-compose的版本号

之后service标签下是五个服务。其中nacos和mysql是通过镜像构造容器,并分别指定了环境、端口、数据卷挂载

而userservice、orderservice、gateway三个服务,则是通过制定目录下的Dockerfile文件,临时构造镜像后创建容器。

如人饮水,冷暖自知。
最后更新于 2023-08-20