目录
案例:查看DockerHub,拉取Nginx镜像,创建并运行Nginx容器
[编辑 把镜像保存到本地](#编辑 把镜像保存到本地)
[编辑 删除镜像](#编辑 删除镜像)
[编辑 网络](#编辑 网络)
[加入网络 编辑](#加入网络 编辑)

首先我们先来对比一下利用Docker来安装一个MySQL软件和传统的安装方式,哪个效率更高一些。
如果是利用传统方式部署MySQL,大概的步骤有:
-
搜索并下载MySQL安装包
-
上传至Linux环境
-
编译和配置环境
-
安装
使用docker安装的话,只需要一步即可
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql
-
docker run -d
:创建并运行一个容器,-d
则是让容器以后台进程运行 -
--name
mysqlmysql
,你可以叫别的 -
**
-p 3306:3306
:**设置端口映射。-
容器是隔离环境 ,外界不可访问。但是可以将 宿主机 端口 映射容器内到端口,当访问宿主机指定端口时,就是在访问容器内的端口了。
-
容器内端口往往是由容器内的进程决定,例如MySQL进程默认端口是3306,因此容器内端口一定是3306;而宿主机端口则可以任意指定,一般与容器内保持一致。
-
格式:
-p 宿主机端口:容器内端口
,示例中就是将宿主机的3306映射到容器内的3306端口
-
-
-``e`` TZ=Asia/Shanghai
: 配置容器内进程运行时的一些参数-
格式:
-e KEY=VALUE
,KEY和VALUE都由容器内进程决定 -
案例中,
TZ``=Asia/Shanghai
是设置时区;MYSQL_ROOT_PASSWORD=123
是设置MySQL默认密码
-
-
mysql
: 设置镜像名称,Docker会根据这个名字搜索并下载镜像-
格式:
REPOSITORY:TAG
,例如mysql:8.0
,其中REPOSITORY
可以理解为镜像名,TAG
是版本号 -
在未指定
TAG
的情况下,默认是最新版本,也就是mysql:latest
-

当我们执行命令后,docker做的第一件事情,是去自动搜索并下载了MySQL,然后会自动运行MySQL,我们完全不用插手
这种安装方式你完全不用考虑运行的操作系统环境,它不仅仅在CentOS系统是这样,在Ubuntu系统、macOS系统、甚至是装了WSL的Windows下,都可以使用这条命令来安装MySQL
要知道,不同操作系统下其安装包、运行环境是都不相同的!如果是手动安装,必须手动解决安装包不同、环境不同的、配置不同的问题.
而使用Docker,这些完全不用考虑。就是因为Docker会自动搜索并下载MySQL。注意:这里下载的不是安装包,而是镜像。镜像中不仅包含了MySQL本身,还包含了其运行所需要的环境、配置、系统级函数库。因此它在运行时就有自己独立的环境,就可以跨系统运行,也不需要手动再次配置环境了。这套独立运行的隔离环境我们称为容器。
当我们利用Docker安装应用时,Docker会自动搜索并下载应用镜像 (image)。镜像不仅包含应用本身,还包含应用
运行所需要的环境、配置、系统函数库。Docker会在运行镜像时创建一个隔离环境,称为容器(ontainer)
镜像仓库: 存储和管理镜像的平台,Docker官方维护了一个公共仓库: Docker Hub。
Docker基础
常见命令
Docker最常见的命令就是操作镜像、容器的命令,详见官方文档
Reference documentation | Docker Docs

案例:查看DockerHub,拉取Nginx镜像,创建并运行Nginx容器
可以直接拉取镜像

docker pull nginx

查看本地镜像
docker images

help命令
把镜像保存到本地但是现在不知道怎么写保存,怎么办呢?
可以通过help命令
docker save --help
把镜像保存到本地
docker save -o nginx.tar nginx:latest
删除镜像
docker rmi nginx:latest


只剩mysql镜像了
读取镜像
docker load -i nginx.tar


创建并运行容器
docker run -d --name nginx -p 80:80 nginx

查看容器是否运行
docker ps

停掉容器
docker stop nginx

后面加-a查看全部

启动容器
docker start nginx

查看容器的日志
docker logs 容器名字
进入容器
docker exec -it nginx bash

退出容器
输入exit就可以了

访问mysql
mysql -uroot -p
再输入密码即可


命令别名
可以看到我们用docker ps时查看到的数据很杂
我们可以使用
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
格式化一下

但是现在有个问题这一串太长了啊,写起来太麻烦了,
输入
vi /root/.bashrc
进入编辑模式
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
放进去就可以了

按esc键,之后在输入:wq即可保存退出编辑模式
然后再执行命令使别名生效
source /root/.bashrc
dps即可生效

数据卷挂卷
案例:利用Nginx容器部署静态资源

docker容器确实是给我们准备了应用程序运行所需要的系统函数库、系统环境,但是它里面只包含当前镜像它所对应的这个应用运行必备的这些系统函数,nginx运行并不需要ll、ls、vi,所以没有准备,所有的镜像其实都是最小化的运行环境,只具备它运行所必须的
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁
以Nginx为例,我们知道Nginx中有两个关键的目录:
-
html
:放置一些静态资源 -
conf
:放置配置文件
如果我们要让Nginx代理我们的静态资源,最好是放到html
目录;如果我们要修改Nginx的配置,最好是找到conf
下的nginx.conf
文件。
但遗憾的是,容器运行的Nginx所有的文件都在容器内部。所以我们必须利用数据卷将两个目录与宿主机目录关联,方便我们操作。

数据卷常用命令
docker volume create 创建数据卷
docker volume ls 查看所有数据卷
docker volume rm 删除指定数据卷
docker volume inspect 查看某个数据卷的详情
docker volume prune 清除数据卷
在执行docker run命令时,使用-v 数据卷:容器内目录可以完成数据卷挂载
注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建 。当创建容器时,如果挂载了数据卷且数据卷不存在 ,会自动创建数据卷 。
我这里面有所以先删除,再创建nginx容器
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx

查看数据卷

查看数据卷的详细信息

现在如果要修改index.html的话,点击👇


[root@192 _data]# docker exec -it nginx bash
root@ffd77d527696:/# cd /usr/share/nginx/html
root@ffd77d527696:/usr/share/nginx/html# ls
1.jpg 50x.html index.html
root@ffd77d527696:/usr/share/nginx/html#
root@ffd77d527696:/usr/share/nginx/html#

可以看到我在宿主机里做的一切操作,容器里自动出现
利用数据卷我们就实现了宿主机目录与容器内目录之间的自动的双向映射
本地目录挂载
创建数据库容器时没有挂载数据卷

这里显示数据库居然有数据卷(匿名数据卷)
可以发现,其中有几个关键属性:
-
Name:数据卷名称。由于定义容器未设置容器名,这里的就是匿名卷自动生成的名字,一串hash值。
-
Source:宿主机目录
-
Destination : 容器内的目录
上述配置是将容器内的/var/lib/mysql
这个目录,与数据卷7ce3bf98cfcf142ee06070b6f7d7ac4622224887f933d73da6ea11cd60000790
挂载。于是在宿主机中就有了/var/lib/docker/volumes/7ce3bf98cfcf142ee06070b6f7d7ac4622224887f933d73da6ea11cd60000790/_data
这个目录。这就是匿名数据卷对应的目录,其使用方式与普通数据卷没有差别。
基于宿主机目录实现MySQL数据目录、配置文件、初始化脚本的挂载
本地目录或文件必须以 /
或 ./
开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名
-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录
数据目录的地址
配置文件的地址

初始化脚本的挂载的地址

[root@192 ~]# docker run -d \
> --name mysql \
> -p 3306:3306 \
> -e TZ=Asia/Shanghai \
> -e MYSQL_ROOT_PASSWORD=123 \
> -v ./mysql/data:/var/lib/mysql \
> -v ./mysql/conf:/etc/mysql/conf.d \
> -v ./mysql/init:/docker-entrypoint-initdb.d \
> mysql
自定义镜像
镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建镜像的过程其实就是把上述文件打包的过程。
我们要从0部署一个Java应用,大概流程是这样:
-
准备一个linux服务(CentOS或者Ubuntu均可)
-
安装并配置JDK
-
上传Jar包
-
运行jar包
我们打包java镜像也是分成这么几步:
-
准备Linux运行环境(java项目并不需要完整的操作系统,仅仅是基础运行环境即可)
-
安装并配置JDK
-
拷贝jar包
-
配置启动脚本
第一步中需要的Linux运行环境,通用性就很强,所以Docker官方就制作了这样的只包含Linux运行环境的镜像。我们在制作java镜像时,就无需重复制作,直接使用Docker官方提供的CentOS或Ubuntu镜像作为基础镜像。然后再搭建其它层即可,这样逐层搭建,最终整个Java项目的镜像结构如图所示:
Dockerfile
Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。将来Docker可以根据Dockerfile帮我们构建镜像。常见指令如下:
常用指令
|----------------|----------------------------|
| FROM | 指定基础镜像 |
| ENV | 设置环境变量,可在后面指令使用 |
| COPY | 拷贝本地文件到镜像的指定目录 |
| RUN | 执行Linux的shell命令,一般是安装过程的命令 |
| EXPOSE | 指定容器运行时监听的端口,是给镜像使用者看的 |
| ENTRYPOINT | 镜像中应用的启动命令,容器运行时调用 |
有人提供了基础的系统加JDK环境,我们在此基础上制作java镜像,就可以省去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"]
# 进入镜像目录
cd /root/demo
# 开始构建
docker build -t docker-demo:1.0 .
[root@192 ~]# cd demo/
[root@192 demo]#
[root@192 demo]# docker build -t docker-demo .
-
docker build
: 就是构建一个docker镜像 -
-t docker-demo:1.0
:-t
参数是指定镜像的名称(repository
和tag
) -
.
: 最后的点是指构建时Dockerfile所在路径,由于我们进入了demo目录,所以指定的是.
代表当前目录,也可以直接指定Dockerfile目录

尝试运行该镜像:
[root@192 demo]# docker run -d --name dd -p 8080:8080 docker-demo
网络
默认情况下,所有容器都是以bridge方式连接到Docker的一个虚拟网桥上:
mysql容器端口为172.17.0.3
[root@192 ~]# cd demo/
[root@192 demo]# docker inspect mysql

dd容器端口号为172.17.0.2
dd容器ping mysql
可以访问
容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。
自定义网络
加入自定义网络 的容器才可以通过容器名互相访问,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 666
通过ip addr可以发现多了一个网桥,是18网段的

加入网络 
docker network connect 666 mysql
可以发现mysql多了一个网桥
我们也可以在一个容器创建时就让他加入网络 ,它就不会再加入默认网关了
docker run -d --name dd -p 8080:8080 --network 666 docker-demo

用容器名访问

这一期就到这里啦
努力遇见更好的自己!!!
