Docker 简明笔记
初识 Docker
项目部署的问题
微服务虽然具备各种各样的优势,但服务的拆分通用给部署带来了很大的麻烦
- 分布式系统中,依赖的组件非常多,不同组件之间部署时往往会产生一些冲突
- 依赖关系复杂,容易出现兼容性问题
- 在数百上千台服务中重复部署,环境不一定一致,会遇到各种问题
- 开发、测试、生产环境有差异
Docker 解决依赖兼容问题
Docker 如何解决依赖的兼容问题的呢,采用了两个手段:
- 将应用的 Libs(函数库)、Deps(依赖)、配置与应用一起 打包
- 将每个应用放到一个 隔离 容器去运行,避免互相干扰
这样打包好的应用包中,既包含应用本身,也保护应用所需要的 Libs、Deps,无需再操作系统上安装这些,自然就不存在不同应用之间的兼容问题了
Docker 解决操作系统环境差异
虽然解决了不同应用的兼容问题,但是开发、测试等环境会存在差异,操作系统版本也会有差异,怎么解决这些问题呢?
- 计算机硬件:例如 CPU、内存、磁盘等
- 系统内核(内核与硬件交互,提供操作硬件指令):所有 Linux 发行版的内核都是 Linux,例如 CentOS、Ubuntu、Fedora 等。内核可以与计算机硬件交互,对外提供 内核指令,用于操作计算机硬件
- 系统应用(系统应用封装内核指令为函数,便于程序员调用):操作系统本身提供的应用、函数库。这些函数库是对内核指令的封装,使用更加方便
Ubuntu 和 CentOS 都是基于 Linux 内核,无非是系统应用不同,提供的函数库有差异。此时,如果将一个 Ubuntu 版本的 MySQL 应用安装到 CentOS 系统,MySQL 在调用 Ubuntu 函数库时,会发现找不到或者不匹配,就会报错了,那 Docker 如何解决不同系统环境问题的呢?
- Docker 将用户程序与所需要调用的系统 (比如 Ubuntu) 函数库一起打包
- Docker 运行到不同操作系统时,直接基于打包的函数库,借助于操作系统的 Linux 内核来运行
那么就可以认为 Docer 打包好的程序包可以应用在任何 Linux 内核的操作系统上
总结
Docker 是一个快速交付应用、运行应用的技术,具备下列优势:
- 可以将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意 Linux 操作系统
- 运行时利用沙箱机制形成隔离容器,各个应用互不干扰
- 启动、移除都可以通过一行命令完成,方便快捷
Docker 架构
镜像和容器
- 镜像(Image,硬盘中的文件):Docker 将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像
- 容器(Container,相当于进程):镜像中的应用程序运行后形成的进程就是容器,只是 Docker 会给容器进程做隔离,对外不可见
镜像都是只读的,这样可以防止容器对镜像数据的写入,造成数据污染;如果容器需要写数据,可以从镜像中拷贝一份数据到自己的空间中,在本空间中进行读写操作
DockerHub
DockerHub 是一个官方的 Docker 镜像的托管平台。这样的平台称为 Docker Registry,国内也有类似于 DockerHub 的公开服务,比如 网易云镜像服务、阿里云镜像库 等
我们一方面可以将自己的镜像共享到 DockerHub,另一方面也可以从 DockerHub 拉取镜像
Docker 架构
Docker 是一个 CS 架构的程序,由两部分组成
- 服务端 (server):Docker 守护进程,负责处理 Docker 指令,管理镜像、容器等
- 客户端 (client):通过命令或 RestAPI 向 Docker 服务端发送指令。可以在本地或远程向服务端发送指令
安装 Docker
Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。这里主要介绍 CentOS 安装 Docker
1.1、卸载(可选)
如果之前安装过旧版本的 Docker,可以使用下面命令卸载
1 | yum remove docker \ |
\
表示命令没有结束还需要继续往下读(换行),命令太长可以通过 \
提高可读性
1.2、安装 yum-utils 工具
1 | yum install -y yum-utils \ |
1.3、设置下载的镜像源
1 | # 设置docker镜像源 |
1.4、安装 docker
1 | yum install -y docker-ce |
至此 docker 安装完毕
启动 docker
Docker 应用需要用到各种端口,逐一去修改防火墙设置。非常麻烦,因此建议大家直接关闭防火墙。启动 docker 前,一定要关闭防火墙!
1、关闭防火墙
1 | # 关闭防火墙 |
2、启动 Docker
1 | systemctl start docker # 启动docker服务 |
3、可通过查看 Docker 状态或 Docker 版本查看是否已经启动
1 | systemctl status docker |
配置镜像
docker 官方镜像仓库网速较差,我们需要设置国内镜像服务,可参考阿里云的镜像加速文档:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
1 | sudo mkdir -p /etc/docker |
Docker 基本操作
镜像操作
镜像名称
镜名称一般分两部分组成:[repository]:[tag]
,在没有指定 tag 时,默认是 latest,代表最新版本的镜像。如这里的 mysql 就是 repository,5.7 就是 tag,合一起就是镜像名称,代表 5.7 版本的 MySQL 镜像
镜像命令
常见的镜像操作命令如图
- 从镜像服务器拉去镜像:docker pull
- 从本地文件构建镜像:docker build
- 查看本地存在哪些镜像:docker images
- 删除本地镜像:docker rmi
- 推送镜像到镜像服务器:docker push
- 将镜像打包成一个压缩包:docker save
- 加载压缩包为镜像:docker load
查看 docker 帮助文档
1 | //查看docker命令及简介 |
案例:从 DockerHub 中拉取镜像
需求:从 DockerHub 中拉取一个 nginx 镜像并查看
1、首先去镜像仓库搜索 nginx 镜像,比如 Docker Hub Container Image Library | App Containerization
1 | //这里官方示例中没有指定版本,那么默认就是最新版 |
2、查看镜像
1 | docker images |
可以查看到本地中已经有 Nginx 镜像了
1 | [root@localhost ~]# docker images |
案例:通过压缩包导出导入镜像
需求:利用 docker save 将 nginx 镜像导出磁盘,然后再通过 load 加载回来
1、利用 docker xx –help 命令查看 docker save 和 docker load 的语法
1 | docker save --help |
通过帮助文档可得知 save 的命令格式为:
1 | docker save -o [保存的目标文件名称] [镜像名称] |
2、使用 docker save 导出镜像到磁盘
1 | docker save -o nginx.tar nginx:latest |
-o
表示选项,注意此时镜像在本地还是有的
3、使用 docker load 加载镜像
3.1)先删除本地的 nginx 镜像
1 | docker rmi nginx:latest |
3.2)加载压缩包镜像
1 | docker load -i nginx.tar |
容器操作
容器相关命令
容器有三个状态:
- 运行:进程正常运行
- 暂停:进程暂停,CPU 不再运行,并不释放内存
- 停止:进程终止,回收进程占用的内存、CPU 等资源
容器操作的命令:
- docker run:创建并运行一个容器,处于运行状态
- docker pause:让一个运行的容器暂停
- docker unpause:让一个容器从暂停状态恢复运行
- docker stop:停止一个运行的容器
- docker start:让一个停止的容器再次运行
- docker rm:删除一个容器
- docker ps:查看所有运行的容器及状态
- docker logs:查看容器运行日志
- docker exec:进入容器执行命令
案例:创建运行一个容器
需求:创建并运行 nginx 容器的命令
可以去官网搜索 Nginx,并查看其文档:nginx - Official Image | Docker Hub,比如官网中给了如下运行命令示例:
1 | docker run --name some-nginx -d -p 8080:80 some-content-nginx |
这里以如下命令进行命令解读:
1 | docker run --name containerName -p 80:80 -d nginx |
- docker run :创建并运行一个容器
- –name : 给容器起一个名字,比如叫做 mn
- -p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口;此处宿主机端口不做要求,但容器端口基本上取决于容器本身(软件监听的端口可能就是某一个端口)
- -d:后台运行容器
- nginx:镜像名称,例如 nginx,没有写标签 tag 说明是最新版 latest
![[Pasted image 20230110202450.png]]
因为容器是隔离的,所以用户无法直接通过 80 端口来访问到容器,需要将容器的端口与宿主机端口映射。端口映射就相当于将原本隔离的容器暴露出一个小窗口,通过这个小窗口来对容器进行访问
容器创建完成后,会生成一个唯一 ID
1 | [root@localhost ~]# docker run --name mn -p 80:80 -d nginx |
通过访问宿主机 80 端口,就可访问 docker 中的 Nginx 服务了
1 | 192.168.119.128:80 |
通过 logs 命令可以查看容器日志
1 | //命令格式 |
案例:操作容器
需求:进入 Nginx 容器,修改 HTML 文件内容,添加 “coffeelize 欢迎您”
1、进入容器(容器是运行的)
1 | docker exec -it mn bash |
命令解读:
- docker exec :进入容器内部,执行一个命令
- -it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
- mn :要进入的容器的名称
- bash:进入容器后执行的命令,bash 是一个 linux 终端交互命令
注意:exec 命令可以进入容器修改文件,但是在容器内修改文件是不推荐的,修改了是没有记录(日志的),之后都不知道进行了哪些修改操作
2、进入 nginx 的 HTML 所在目录 /usr/share/nginx/html
容器内部会模拟一个独立的 Linux 文件系统,看起来如同一个 linux 服务器一样
1 | root@b8ae9bcbdde9:/# ls |
我们进入 Nginx 的目录(至于如何找到这个目录的可能需要在 DockerHub 查看 Nginx 的文档了),可以发现目录下包含 index.html
1 | cd /usr/share/nginx/html |
3、修改 index.html 的内容
容器内没有 vi 命令,无法直接修改,我们用下面的命令来修改
1 | sed -i -e 's#Welcome to nginx#coffeelize欢迎您#g' -e 's#<head>#<head><meta charset="utf-8">#g' index.html |
4、验证
访问虚拟机 80 端口,输出页面如下,说明修改成功
5、退出容器
1 | exit |
6、停止容器
1 | docker stop mn |
7、启动容器
1 | docker start mn |
8、删除容器
1 | //停掉容器之后删除容器 或者 强制删除运行中的程序 |
数据卷
在之前的 nginx 案例中,修改 nginx 的 html 页面时,需要进入 nginx 内部。并且因为没有编辑器,修改文件也很麻烦,这就是因为容器与数据(容器内文件)耦合带来的后果。要解决这个问题,必须将 数据与容器解耦,这就要用到数据卷了
数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录
一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录了,这样,我们操作宿主机的 /var/lib/docker/volumes/html 目录,就等于操作容器内的 /usr/share/nginx/html 目录了;多个容器可以挂在同一个卷,就可以 “共享” 修改操作了;如果哪一天将容器删除了,没关系,数据卷还在,将新容器在挂载到这个数据卷上就可以了访问之前的数据了
数据卷操作命令
数据卷操作的基本语法如下
1 | docker volume [COMMAND] |
- create:创建一个 volume
- inspect:显示一个或多个 volume 的信息
- ls:列出所有的 volume
- prune:删除未使用的 volume
- rm:删除一个或多个指定的 volume
案例:创建和查看数据卷
需求:创建一个数据卷,并查看数据卷在宿主机的目录位置
1、创建数据卷
1 | docker volume create html |
2、查看所有数据卷
1 | docker volume ls |
3、查看数据卷详细信息卷
1 | docker volume inspect html |
返回信息如下,其中重点关注 Mountpoint 挂载点
1 | [root@localhost ~]# docker volume inspect html |
4、小结
数据卷的作用:将容器与数据分离,解耦合,方便操作容器内数据,保证数据安全
挂载数据卷
我们在创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器内目录,命令格式如下:
1 | docker run \ |
这里的 -v 就是挂载数据卷的命令:
docker run
:创建并运行容器--name mn
:给容器起个名字叫 mn-v html:/root/html
:把 html 数据卷挂载到容器内的 /root/html 这个目录中-p 8080:80
:吧宿主机的 8080 端口映射到容器内的 80 端口- nginx:镜像名称
案例:给 nginx 挂载数据卷
需求:创建一个 nginx 容器,修改容器内的 html 目录内的 index.html 内容
分析:上个案例中,我们进入 nginx 容器内部,已经知道 nginx 的 html 目录所在位置 /usr/share/nginx/html ,我们需要把这个目录挂载到 html 这个数据卷上,方便操作其中的内容
0、查看容器是否在运行,并且已经提前创建好了 html 数据卷
1 | # 检查容器是否在运行 |
1、创建容器并挂载数据卷到容器内的 HTML 目录
1 | docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx |
2、进入 html 数据卷所在位置,并修改 HTML 内容
1 | # 查看html数据卷的位置 |
3、在做数据卷挂在时,如果要创建数据卷不存在,docker 会为我们自动创建数据卷
比如在我们使用如下命令前,docker 中是没有 html 数据卷的,一样可以正常使用如下命令,因为 docker 会为我们自动创建 html 数据卷
1 | docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx |
案例:给 MySQL 挂载本地目录
容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录上。关联关系如下
- 带数据卷模式:宿主机目录 –> 数据卷 –> 容器内目录
- 直接挂载模式:宿主机目录 –> 容器内目录
目录挂载与数据卷挂载的语法是类似的:
-v [宿主机目录]:[容器内目录]
-v [宿主机文件]:[容器内文件]
案例需求:创建并运行一个 MySQL 容器,将宿主机目录直接挂载到容器
1、将课前资料中的 mysql.tar 文件上传到虚拟机的 tmp 目录,通过 load 命令加载为镜像
1 | cd / |
2、创建目录 /tmp/mysql/data
1 | //-p表示多级目录创建 |
3、创建目录 /tmp/mysql/conf,将课前资料提供的 hmy.cnf 文件上传到 /tmp/mysql/conf
1 | //-p表示多级目录创建 |
hmy.cnf 的文件内容为
1 | [mysqld] |
4、去 DockerHub 查阅资料 mysql | Docker Hub,创建并运行 MySQL 容器,要求:
1)挂载 /tmp/mysql/data 到 mysql 容器内数据存储目录
2)挂载 /tmp/mysql/conf/hmy.cnf 到 mysql 容器的配置文件
3)设置 MySQL 密码
官网上给定的运行示例如下
1 | docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag |
其中 -e 表示运行环境,后面可以直接设置 mysql 密码;-d 表示后台运行;tag 为版本号,其中还缺少了端口号的设置,我们对这个命令进行修改
1 | docker run \ |
但是此时有个报错 (bind: address already in use),因为之前我们已经在虚拟机中运行 MySQL 了,也就是已经占用了宿主机的 3306 端口,这里我们改成 3305 试一下
1 | //删除刚才创建的mysql容器 |
注意:此处的 /etc/mysql/conf.d 目录,可以合并添加我们创建的 hmy.cnf 配置,而不是将 MySQL 默认的配置文件完全覆盖掉(因为我们创建的配置文件只包含了默认配置的少数配置信息,替换掉默认配置的话配置就不全了)
5、测试 MySQL 连接
通过 Navicat 测试可正常连接
6、小节
数据卷挂载与目录直接挂载的比较:
- 数据卷挂载耦合度低,由 docker 来管理目录,但是目录较深,不好找
- 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看
Dockerfile 自定义镜像
镜像结构
常见的镜像在 DockerHub 就能找到,但是我们自己写的项目就必须自己构建镜像了,而要自定义镜像,就必须先了解镜像的结构才行
镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。我们以 MySQL 为例,来看看镜像的组成结构
- 基础镜像(BaseImage):应用依赖的系统函数库、环境、配置、文件等
- 入口(Entrypoint):镜像运行入口,一般是程序启动的脚本和参数
- 层(Layer):在 BaseImage 基础上添加安装包、依赖、配置等,每次操作都形成新的层
Dockerfile
Dockerfile 是一个文本文件,其中包含一个个的 ** 指令 (Instruction)**,用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层 Layer。更新详细语法说明,可参考官网文档: https://docs.docker.com/engine/reference/builder
构建 Java 项目
基于 Ubuntu 构建 Java 项目
需求:基于 Ubuntu 镜像构建一个新镜像,运行一个 java 项目
1、新建一个空文件夹 docker-demo
1 | cd /tmp/ |
2、拷贝课前资料中的 docker-demo.jar 文件到 docker-demo 这个目录
3、拷贝课前资料中的 jdk8.tar.gz 文件到 docker-demo 这个目录
4、拷贝课前资料提供的 Dockerfile 到 docker-demo 这个目录
Dockerfile 中的内容如下
1 | # 指定基础镜像 |
5、进入 docker-demo
1 | cd docker-demo |
6、运行命令
1 | docker build -t javaweb:1.0 . |
-t 表示 tag;javaweb 为镜像名称;注意命令后面还有个 .
,表示 dockerfile 所在的目录(构建时告知 dockerfile 在哪)
可以看到 dockerfile 共有 9 个指令,也就分为了 9 个 step,每个指令执行都会创建出一个层
7、通过命令查看构建好的镜像
1 | [root@localhost docker-demo]# docker images |
可以看到我们基于 ubuntu 构建的(配置好 java 环境的)javaweb 项目的镜像已经构建好了
可以通过命令来运行镜像(8090 端口在 dockerfile 中已经声明暴露了端口)
1 | docker run --name web -p 8090:8090 -d javaweb:1.0 |
浏览器访问如下地址,可以发现我们的项目(之前我们的 docker-demo.jar 项目)正常跑起来了
1 | http://192.168.119.128:8090/hello/count |
虚拟机中运行 docker –> docker 中运行 ubuntu –> ubuntu 中运行 docker-demo java 项目😂,虚拟机内存开始吃紧了
小结
分析:其实我们的 java 项目真正只用到了如下一行
1 | COPY ./docker-demo.jar /tmp/app.jar |
dockerfile 文件内容:
1 | # 指定基础镜像 |
那么我们之后在构建 Java 项目镜像时,可以先构建如下不会改变的层做一个镜像,然后在基于这个镜像来构建。
1 | # 指定基础镜像 |
而实际上,有人也已经构建好了这个镜像了,我们直接拿来用就行,镜像名为 java:8-alpine
1 | # 指定基础镜像 |
DockerCompose
Docker Compose 可以基于 Compose 文件帮我们快速部署分布式应用,而无需手动一个个创建和运行容器
初识 DockerCompose
Compose 文件是一个文本文件,通过指令定义集群中的每个容器如何运行。格式如下(相当于把 docker run 中的所有指令转换为了 Compose 指令了):
1 | version: "3.8" |
上面的 Compose 文件就描述一个项目,其中包含两个容器
- mysql:一个基于
mysql:5.7.25
镜像构建的容器,并且挂载了两个目录- 为什么没有定义端口呢:因为 MySQL 运行在微服务当中,供内部使用无需对外开放
- 无需定义后台运行,默认就是后台运行
- web:一个基于
docker build
临时构建的镜像容器,映射端口时 8090- 为什么没有指定镜像:因为通过 build 就可以构建镜像
安装 DockerCompose
1、下载
1 | # 安装 |
或者通过本地文件准备好的文件直接上传,上传至 /usr/local/bin/
目录
2、修改文件权限
1 | # 修改权限 |
3、Base 自动补全命令
之后使用 Docker Compose 时就会有补全提示
1 | # 补全命令 |
此时可能会报:拒绝连接的错误,需要执行如下命令修改 hosts 文件
1 | echo "199.232.68.133 raw.githubusercontent.com" >> /etc/hosts |
案例:利用 DockerCompose 部署
需求:将之前学习的 cloud-demo 微服务集群利用 DockerCompose 部署
1、查看课前资料提供的 cloud-demo 文件夹,里面已经编写好了 docker-compose 文件
课前资料提供的 cloud-demo 文件夹,里面已经编写好了 docker-compose 文件,而且每个微服务都准备了一个独立的目录。对于每一个微服务目录,其中都包含一个 Dockerfile 文件和对于的微服务 jar 包。最外层包含 docker-compose.yml 配置文件,文件内容如下:
1 | version: "3.2" |
这几个微服务(mysql、userservice、orderservice 以及 gateway)中,只有网关暴露了端口,因为网关是外部访问微服务的入口。其他微服务都需要注册到 Nacos 服务中
MySQL 微服务中需要的表和数据课程资料也已经为我们准备好了
2、修改自己的 cloud-demo 项目,将数据库、nacos 地址都命名为 docker-compose 中的服务名
因为微服务将来要部署为 docker 容器,而容器之间互联不是通过 IP 地址,而是通过容器名。这里我们将 order-service、user-service、gateway 服务的 mysql、nacos 地址都修改为基于容器名的访问
比如 user-service 中的 bootstrap 配置文件
1 | spring: |
application.yml 配置文件中
1 | - url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false |
同理,order-service 和 gateway 微服务的配置文件也这样修改
3、使用 maven 打包工具,将项目中的每个微服务都打包为 app.jar
为什么都打包成 app.jar 呢 –> 因为我们在微服务目录下的 Dockerfile 文件里是这样配置的,我们配置的名称都是 app.jar
1 | FROM java:8-alpine |
那么,既然各个微服务打包完成都需要叫这个 app.jar 名字,我们是否可以修改配置文件实现项目打包自动叫这个名字呢 –> 可以的,在各个微服务的 pom 文件中添加如下配置
1 | <build> |
通过 Maven 的 Package 来打包
4、将打包好的 app.jar 拷贝到 cloud-demo 中的每一个对应的微服务子目录中
5、将 cloud-demo 上传至虚拟机 (tmp 目录),利用 docker-compose up -d 来部署
1 | cd / |
- up:表示创建并执行容器
- down:停止并删除容器
- 其他命令可以通过 help 命令查看
6、查看打包好的镜像和运行的容器
1 | docker images |
1 | [root@localhost cloud-demo]# docker images |
虚拟机 2G 内存快要炸了😳,开始借用交换内存了
7、通过查看日志可发现 order-service 有报错
1 | docker-compose logs -f |
原因是因为 Nacos 微服务启动晚于 order-service,导致报错。关键是报错之后没有进行重新启动 –> 因此,我们最好是先启动 Nacos 微服务,之后再启动 order-service 等系列微服务
浏览器访问如下,均可正常接收到数据
1 | http://192.168.119.128:10010/user/2?authorization=admin |
至此,DockerCompose 部署微服务完成
8、删除掉这些容器吧,虚拟机要炸了
1 | //删除通过docker-compose部署的容器,同时删除镜像 |
1 | [root@localhost cloud-demo]# docker-compose down --rmi all |
Docker 镜像仓库
简化版镜像仓库
Docker 官方的 Docker Registry 是一个基础版本的 Docker 镜像仓库,具备仓库管理的完整功能,但是没有图形化界面
1 | docker run -d \ |
命令中挂载了一个数据卷 registry-data 到容器内的 /var/lib/registry 目录,这是私有镜像库存放数据的目录,访问如下链接可以查看当前私有镜像服务中包含的镜像
1 | http://yourip:5000/v2/_catalog |
带有图形化界面版本
操作此步骤前,需要先完成 Docker 信任地址配置
使用 DockerCompose 部署带有图象界面的 DockerRegistry,命令如下
1 | cd / |
1 | version: '3.0' |
通过访问如下地址,即可访问我们创建的带有图形界面的 Docker 镜像仓库了
1 | 192.168.119.128:8080 |
配置 Docker 信任地址
我们的私服采用的是 http 协议,默认不被 Docker 信任,所以需要做一个配置
1 | # 打开要修改的文件 |
在添加内容时,注意多个配置之间别把逗号忘加了
1 | { |
在私有镜像仓库中推送或拉去镜像
推送镜像到私有镜像服务必须先 tag,步骤如下:
1、重新 tag 本地镜像(重命名镜像,并且以镜像仓库地址为前缀),名称前缀为私有仓库的地址:192.168.119.128:8080/
1 | docker tag nginx:latest 192.168.119.128:8080/nginx:1.0 |
利用 tag 命令,可以将一个镜像重命名,这里我们对之前下载的最新版 Nginx 镜像进行操作
此时,查看本地的镜像,就可以找到我们打包并且重命名后的镜像了,可以发现这两个镜像的 ID(605c77e624dd)其实是一样的
1 | 192.168.119.128:8080/nginx 1.0 605c77e624dd 12 months ago 141MB |
2、推送镜像
1 | docker push 192.168.119.128:8080/nginx:1.0 |
3、拉取镜像
1 | docker pull 192.168.150.101:8080/nginx:1.0 |