一、Docker基本概念
当我们利用Docker安装应用时,Docker会自动搜索并下载应用镜像(image)。镜像不仅包含应用本身,还包含应用运行所需要的环境、配置、系统函数库。Docker会在运行镜像时创建一个隔离环境,称为容器(container)。
镜像仓库,就是专门保存镜像、管理镜像的地方。Docker官方维护了一个公共仓库:Docker Hub,任何注册了的用户都可以上传镜像到Docker Hub,也可以从上面下载镜像。
另外,国内也有很多类似的镜像仓库:比如 网易云镜像仓库、阿里云镜像仓库等。
1. Docker是做什么的?
- Docker可以帮助我们下载应用镜像,创建并运行镜像的容器,从而快速部署应用
什么是镜像?
- 将应用所需的函数库、依赖、配置等与应用一起打包得到的就是镜像
什么是容器?
- 为每个镜像的应用进程创建的隔离运行环境就是容器
什么是镜像仓库?
- 存储和管理镜像的服务就是镜像仓库,
2. Docker命令
bash 代码:docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql
docker run
是创建并运行一个容器,-d
参数是让容器在后台运行,在关掉终端后也可以运行
--name
参数是给容器起一个唯一的名字
-p
参数是设置端口映射,这个选项将容器的3306端口映射到宿主机的3306端口,这样你就可以从宿主机访问到MySQL服务了。
-e TZ=Asia/Shanghai \
参数是设置环境变量,影响mysql容器的时区设置
-e MYSQL_ROOT_PASSWORD=123 \
这个选项设置环境变量MYSQL_ROOT_PASSWORD为"123",这会影响到MySQL的root用户的密码。
mysql
是要运行的镜像的名字
3. Docker镜像命名规范
Docker镜像的命名规范主要包括以下几点:
- 使用小写字母和数字:因为Docker镜像名称是大小写敏感的,所以建议使用小写字母和数字来避免混淆。
- 使用短划线(-)或下划线(_)分隔:可以使用短划线或下划线来分隔不同的单词,例如
my-image
或my_image
。 - 以
library/project
形式命名:镜像名称通常表示其包含的库或项目,因此建议使用library/project
的形式来命名镜像,例如ubuntu:18.04
或nginx:latest
。 - 遵循命名空间规则:如果一个镜像同时包含多个库或项目,可以使用冒号(:)将它们分开,例如
redis:6.0.9
或node:14.17.0
。 - 不要使用特殊字符:尽量避免在镜像名称中使用特殊字符,如空格、斜杠、问号等。这些字符可能会导致镜像名称无法正确解析。
- 使用描述性名称:尽量给镜像起一个描述性的名称,以便于理解它包含的内容。例如,
webapp:latest
表示一个包含最新版本web应用程序的镜像。
二、Docker基础
1. 数据卷概念及挂载
因为容器与宿主机是隔离的,如果容器删除,容器内的数据会丢失。为了解决这个问题,有了数据卷。在后期宿主机目录发生变更,只要改变数据卷的指向即可。
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。它将宿主机目录映射到容器内目录,方便我们操作容器内文件。
数据卷创建的默认目录是/var/lib/docker/volumes
命令 | 说明 |
---|---|
docker volume creqate | 创建数据卷 |
docker volume ls | 查看所有数据卷 |
docker volume rm | 删除指定数据卷 |
docker volume inspect | 查看某个数据卷的详情 |
docker volume prune | 清除数据卷 |
在执行docker run
命令时,使用-v 数据卷:容器内目录 可以完成数据卷挂载
在创建容器时,如果挂在了数据卷且数据卷不存在,会自动创建数据卷。
2. 本地目录的挂载
使用docker run -v
命令挂载,具体命令为:
docker run -v 本地目录:容器内目录
l本地目录必须以“/”或 "./" 开头,如果直接以名称开头,会被识别为数据卷而非本地目录
-v mysql : /var/lib/mysql
会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷-v ./mysql : /var/lib/mysql
会被识别为当前目录下的mysql目录,如果不存在会自动创建
镜像中包含了应用程序所需要的运行环境、函数库、配置、以及应用本身,逐层构建而成。
3. 自定义镜像(Dockerfile)
镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建镜像的过程其实就是把上述文件按照顺序逐层打包。
Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。将来Docker可以根据Dockerfile帮我们构建镜像。常见指令如下:
指令 | 说明 | 示例 |
---|---|---|
FROM | 指定基础镜像 | 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 | 镜像中应用的启动命令,容器运行时调用 | ENTRYPOINT java -jar xx.jar |
配置示例:
dockerfile 代码:# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/
$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装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
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
往往不需要这么复杂,我们可以直接基于JDK为基础镜像省略前面的步骤:
dockerfile 代码:# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
构建镜像
在编写好Dockerfile后,可以使用以下命令来构建镜像:
bash 代码:# docker build -t 镜像名 Dockerfile目录
docker build -t myImage:1.0 .
-t
:时给镜像起名,格式依然是repository:tag的格式,不指定tag时,默认为latest.
:是指定Dockerfile所在目录,如果就在当前目录,则指定为:"."
实操如下:
bash 代码:docker load -i xxx.jar # 导入镜像
docker build -t demo: . # 使用当前目录的 Dockerfile 创建镜像,标签为 demo
docker run -d --name demo -p 8080:8080 # 启动容器在后台运行,容器名为demo,端口映射为8080
4. 网络
默认情况下,所有的容器都是以bridge方式连接到Docker的一个虚拟网桥上:
在安装docker之后,会生成一个虚拟网卡,生成一个虚拟网桥
虚拟网卡的名字叫做:docker0,ip为:172.16.0.2/16
前两个网段不能改
docker是允许我们自定义网络的,加入自定义网络的容器才可以通过容器名互相访问,Docker的网络操作命令如下:
命令 | 说明 |
---|---|
docker network create | 创建一个网络 |
docker network ls | 查看所有网络 |
docker network rm | 删除指定网络 |
docker network prune | 清除未使用的网络 |
docker network connect | 使指定容器链接加入某网络 |
docker network disconnect | 使指定容器连接离开某网络 |
docker network inspect | 查看网络详细信息 |
# 示例:
docker network create xiaobei
docker network ls
docker network rm demo
docker network prune
docker network connect xiaobei demo
docker network disconnect
docker network inspect xiaobei
三、Docker Compose
1. 基本概念
Docker Compose通过一个单独的docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器,帮助我们实现多个相互关联的Docker容器的快速部署。
一个容器就是一个服务
2. 文件结构
yaml 代码:version: "3.8" # 版本
services:
mysql:
image: mysql # 镜像名:mysql
container_name: mysql # 容器名:mysql
ports:
- "3306:3306" # 端口号:3306:3306
environment: # 环境变量
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123
volumes: # 数据卷挂载
- "./mysql/conf:/etc/mysql/conf.d"
- "./mysql/data:/var/lib/mysql"
- "./mysql/init:/docker-entrypoint-initdb.d"
networks: # 网络
- new
hmall: # 构建新镜像
build:
context: . # 指定当前目录
dockerfile: Dockerfile # 文件名为Dockerfile
container_name: hmall # 容器名:hmall
ports:
- "8080:8080" # 端口
networks:
- new # 网络
depends_on: # 依赖于谁,该应用依赖于mysql
- mysql
nginx:
image: nginx # 试着自己想想吧,我累了Ovo
container_name: nginx
ports:
- "18080:18080"
- "18081:18081"
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf"
- "./nginx/html:/etc/nginx/html"
depends_on:
- hmall
networks:
- new
networks:
new:
name: hmall