侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 285 篇文章
  • 累计创建 125 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Docker教程-1-学习及安装Docker

孔子说JAVA
2021-10-13 / 0 评论 / 0 点赞 / 131 阅读 / 20,000 字 / 正在检测是否收录...

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。让开发者可以打包他们的应用以及依赖包到一个轻量级、可移植的容器镜像中,然后发布到任何流行的 Linux或Windows、Macos机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似app),更重要的是容器性能开销极低。

1、Docker介绍

1.1 Docker的来源

2010年dotCloud公司成立,但是企业规模小,影响力不够,企业举步维艰。2013年dotCloud公司改名为Docker,并将他们的核心技术docker开源,托管于github,当时docker的功能就是将linux容器中的应用代码打包,并且可以轻松的在服务器之间进行迁移,逐渐的docker技术风靡全球。

1.2 Docker是什么

Docker是一个集开发、打包、运行应用于一体的开放式平台。Docker可以用来快速交付应用。使用Docker,你可以将应用程序从你的基础设施中分离出来,并将基础设施当做一个管理平台。Docker可以加快打包时间,加快测试,加快发布,缩短开发及运行代码之间的周期。Docker通过结合内核容器化特点和工作流,并使之工具化来实现这一切,帮助管理和发布你的应用。

  • Docker是一种容器技术,和虚拟机一样都属于虚拟化的技术,但是他是一个轻量级的虚拟化。容器与虚拟机不同,虚拟机是在物理机上运行的操作系统,容器是一个虚拟机的一个进程,不需要虚拟物理设备。Docker本身不是容器,它只是用来创建容器的一个工具,是一个应用容器的引擎。一台物理机器上vm可以安装3到10个实例,docker可以安装100到10000个实例。

由于容器是进程级别的,相比虚拟机有很多优势。

  • 启动快:容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。
  • 资源占用少:容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所有资源。另外,多个容器可以共享资源,虚拟机都是独享资源。
  • 体积小:容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。

容器与虚拟机的区别:

image-1648970879746

1)虚拟机

虚拟机就是在操作系统里面,装一个软件,然后通过这个软件,再模拟一台甚至多台“子电脑”出来,像VMWare。在这些虚拟出来的电脑上,一样可以运行程序,如果我愿意,可以虚拟出很多台“子电脑”,然后在上面运行各种软件,且“子电脑”之间是互相隔离的,互不影响。虚拟机一般需要几GB-几十GB的空间。

image-1648970962188

虚拟机

image-1648971049759

2)Docker

Docker是轻量级的虚拟化,容器的启动时间非常快,几秒钟就完成了,而且对资源的利用率非常高(一台主机可以同时运行几千个Docker容器)。此外,它占用的空间很小,是进程级别的,虚拟机一般需要几GB-几十GB的空间,而容器只是MB甚至KB级。

image-1648971080897

1.3 Docker特点

轻量级、可移植、资源占用少。

  • “Build, Ship and Run”。构建,交付,运行。
  • “Buidl once,Run anywhere”。搭建一次,哪都能用。

举例:

  • 公司有个项目要部署到87这台服务器,花了半天时间,在87服务器上安装好了jdk、mysql、redis、rabbitmq…,成功部署上线。

  • 过了一个月,因为某种原因,项目要重新部署上86的服务器。按照以前的办法,只能jdk、mysql…一条龙部署。

  • 而docker的做法就是,把各种容器运行时所需要的程序、库、资源、配置文件、环境变量等等打包成docker镜像,放进docker仓库里,什么时候要用了,拿来跑就行。

1.4 Docker的应用场景

① 简化配置,使同一个Docker配置在不同环境使用

  • 这是Docker公司宣传的Docker的主要使用场景。虚拟机的最大好处是能在你的硬件设施上运行各种配置不一样的平台(软件、系统),Docker在降低额外开销的情况下提供了同样的功能。它能让你将运行环境和配置放在代码中然后部署,同一个Docker的配置可以在不同的环境中使用,这样就降低了硬件要求和应用环境之间耦合度。

  • 如开发、测试、生产环境的jdk、tomcat版本不一致导致的程序运行失败等。Docker就可以解决这些运行环境不一致所带来的问题。

② 代码流水线(Code Pipeline)管理

  • 前一个场景对于管理代码的流水线起到了很大的帮助。代码从开发者的机器到最终在生产环境上的部署,需要经过很多的中间环境。而每一个中间环境都有自己微小的差别,Docker给应用提供了一个从开发到上线均一致的环境,让代码的流水线变得简单不少。

③ 提高开发效率

  • Docker能提升开发者的开发效率。不同的开发环境中,我们都想把两件事做好。一是我们想让开发环境尽量贴近生产环境,二是我们想快速搭建开发环境。

  • 理想状态中,要达到第一个目标,我们需要将每一个服务都跑在独立的虚拟机中以便监控生产环境中服务的运行状态。然而,我们却不想每次都需要网络连接,每次重新编译的时候远程连接上去特别麻烦。这就是Docker做的特别好的地方,开发环境的机器通常内存比较小,之前使用虚拟的时候,我们经常需要为开发环境的机器加内存,而现在Docker可以轻易的让几十个服务在Docker中跑起来。

④ 隔离应用

  • 有很多种原因会让你选择在一个机器上运行不同的应用,比如之前提到的提高开发效率的场景等。我们经常需要考虑两点,一是因为要降低成本而进行服务器整合,二是将一个整体式的应用拆分成松耦合的单个服务(微服务架构)

⑤ 整合服务器

  • 正如通过虚拟机来整合多个应用,Docker隔离应用的能力使得Docker可以整合多个服务器以降低成本。由于没有多个操作系统的内存占用,以及能在多个实例之间共享没有使用的内存,Docker可以比虚拟机提供更好的服务器整合解决方案。

⑥ 调试能力

  • Docker提供了很多的工具,这些工具不一定只是针对容器,但是却适用于容器。它们提供了很多的功能,包括可以为容器设置检查点、设置版本和查看两个容器之间的差别,这些特性可以帮助调试Bug。

⑦ 多租户环境

  • 另外一个Docker有意思的使用场景是在多租户的应用中,它可以避免关键应用的重写。我们一个特别的关于这个场景的例子是为IoT(物联网)的应用开发一个快速、易用的多租户环境。这种多租户的基本代码非常复杂,很难处理,重新规划这样一个应用不但消耗时间,也浪费金钱。

  • 使用Docker,可以为每一个租户的应用层的多个实例创建隔离的环境,这不仅简单而且成本低廉,当然这一切得益于Docker环境的启动速度和其高效的diff命令。

⑧ 快速部署

  • 在虚拟机之前,引入新的硬件资源需要消耗几天的时间。虚拟化技术(Virtualization)将这个时间缩短到了分钟级别。而Docker通过为进程仅仅创建一个容器而无需启动一个操作系统,再次将这个过程缩短到了秒级。这正是Google和Facebook都看重的特性。

  • 你可以在数据中心创建销毁资源而无需担心重新启动带来的开销。通常数据中心的资源利用率只有30%,通过使用Docker并进行有效的资源分配可以提高资源的利用率。

⑨ 自动化测试和持续集成、持续部署

  • 互联网行业倡导敏捷开发,持续集成部署CI/CD便是最典型的开发模式。使用docker容器云平台,就能实现从代码编写完成推送到git/svn后,自动触发后端CaaS平台将代码下载、编译并构建成测试docker镜像,再替换测试环境容器服务,自动在Jenkins或者Hudson中运行单元/集成测试,最后测试通过后,马上就能自动将新版本镜像更新到线上,完成服务升级。整个过程全自动化,一气呵成,最大程度地简化了运维成本,而且保证线上、线下环境完全一致,而且线上服务版本与git/svn发布分支也实现统一。

⑩ 微服务架构使用

  • 微服务架构将传统分布式服务继续拆分解耦,形成一些更小服务模块,服务模块之间独立部署升级,这些特性与容器的轻量、高效部署不谋而合。如下图所示,每个容器里可以使用完全不同环境的镜像服务,容器启动即产生了一个独立的微服务主机节点(独立的网络ip),上层服务与下层服务之间服务发现通过环境变量注入、配置文件挂载等多种方式灵活解决,而且还可以直接将云平台提供的各种云服务与自定义的微服务整合组成一个强大的服务集群。

  • 更重要的是,拥有如此多服务的集群环境迁移、复制也非常轻松,只需选择好各服务对应的docker服务镜像、配置好相互之间访问地址就能很快搭建出一份完全一样的新集群。

image-1648971520649

1.5 Docker的优势

① 更快速的交付和部署

  • Docker在整个开发周期都可以完美的辅助你实现快速交付。Docker允许开发者在装有应用和服务本地容器做开发。可以直接集成到可持续开发流程中。

  • 例如:开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。

② 高效的部署和扩容

  • Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。 这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。

  • Docker的兼容性和轻量特性可以很轻松的实现负载的动态管理。你可以快速扩容或方便的下线的你的应用和服务,这种速度趋近实时。

③ 更高的资源利用率

  • Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。

④ 更简单的管理

  • 使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。

2、Docker版本及安装要求

2.1 Docker版本介绍

  • Docker 引擎可以从 Docker 网站下载,也可以基于 GitHub 上的源码进行构建。无论是开源版本还是商业版本,都有 Linux 和 Windows 版本。
  • Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),一般用社区版就可以了。
  • 每个季度,企业版和社区版都会发布一个稳定版本。社区版本会提供 4 个月的支持,而企业版本会提供 12 个月的支持。

2.2 Docker安装要求

1)操作系统

  • 推荐使用Ubuntu、Debian和RHEL(Centos、Fedora等)
  • 在Windows和OS X中也可以使用,但要安装Docker Toolbox工具

2)内核

  • 推荐3.8及以上的内核,虽然只是要求内核>=2.6,但是虽然一些老版本的也能运行,但运行结果会有很大的不同。
  • 内核必须支持并开启cgroup和命名空间功能

3)驱动

  • 内核必须支持一种合适的存储驱动,例如:Device Mapper、AUFS、vfs、btrfs、ZFS,默认存储驱动通常是Device Mapper或AUFS

4)架构

  • 运行64位架构的计算机(x86_64和amd64)

3、Docker的核心概念

3.1 Docker引擎

Docker引擎是一个在客户机与服务器的之间应用程序,具有以下的主要组件

  • ①server,它是一种长时间运行的程序,称为守护进程(dockerd命令)
  • ②REST API,接收来自客户端的请求,调取相应的接口与守护进程进行交互
  • ③client,命令行界面(docker命令)

image-1648971717279

3.2 Docker的组成

客户端与Docker服务器的守护进程进行通信,守护进程根据请求来实现构建、运行和发布。客户机可以与服务器在同一台主机,也可以在不同网络之间进行通信。

image-1648971740587

3.2.1 客户端(Docker Client)

用户与Docker交互的主要方式,Docker客户端可以与多个守护进程进行交互。

3.2.2 守护进程(Docker Daemon)

用来监听Docker API的请求并管理对象,例如镜像、容器、网络和卷,守护进程还可以与其他的守护进程通信以管理Docker服务。

3.2.3 镜像(image)

docker镜像就相当于是一个只读的模板(基础功能),可以通过这个模板来创建Docker容器服务。Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。

  • 例:tomcat镜像===>run===>tomcat01容器(提供服务器),可以通过这个tomcat镜像创建多个tomcat容器。

3.2.4 容器(container)

docker利用容器技术,独立运行一个或者一组应用,容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序

容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。这样就能保证镜像可以生成多个容器独立运行,没有任何干扰。

3.2.5 仓库(repository)

Docker 仓库就是集中存放存放镜像文件的地方,与maven/git仓库概念一样,分为公有仓库和私有仓库,注册服务器可以理解为 GitHub 这样的托管服务。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。

仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云、腾讯云、华为云、时速云、网易蜂巢等,可以提供大陆用户更稳定快速的访问。当然,用户也可以在本地网络内创建一个私有仓库。

当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。

  • 官方:Docker Hub(外网)。
  • 阿里云(配置镜像加速),类似maven配置阿里云镜像加速。

综述:

上面说的镜像可以理解为集装箱,仓库理解为超级码头,容器是我们运行程序的地方。Docker运行程序的过程就是去仓库把镜像拉到本地,然后用一条命令把镜像运行起来变成容器。

  • build:构建,就是构建镜像。
  • ship:运输镜像,从仓库和主机运输。
  • run:运行的镜像就是一个容器.。
  • build,ship,run和镜像,仓库,容器是一一对应的。

4、Linux Ubuntu 安装Docker

通过apt的docker官方源安装最新的Docker CE(Community Edition),即Docker社区版,是开发人员和小型团队的理想选择,可以指定安装版本。

4.1 查看系统当前的内核版本

安装Docker要求内核>=2.6,推荐3.8及以上的内核,版本过低有可能导致运行结果的差异。验证你的Linux版本是否支持 Docker 。通过 uname -r 命令查看你当前的内核版本。

image-1648972333353

4.2 安装依赖软件

1)首先更新apt包索引

sudo apt-get update

2)安装依赖软件

安装以下包以使apt可以通过HTTPS使用存储库(repository)。

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common lrzsz -y

image-1648973826603

4.3 卸载apt官方库里的旧版本

1)由于apt官方库里的docker版本可能比较旧,所以先卸载可能存在的旧版本,命令:

sudo apt-get remove docker docker-engine docker-ce docker.io

2)更新apt包索引:

sudo apt-get update

4.4 添加Docker官方的GPG密钥

sudo curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
  • sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

image-1648973991460

4.5 设置stable存储库

1)设置stable存储库

sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

image-1648974094119

2)更新一下apt包索引

sudo apt-get update

image-1648974109656

4.6 安装Docker

4.6.1 安装最新版本的Docker CE

sudo apt-get install -y docker-ce

image-1648974152923

4.6.2 安装特定版本的Docker CE

在生产系统上,可能会需要应该安装一个特定版本的Docker CE,而不是总是使用最新版本。

1)查看可用的版本

列出可用的版本命令:apt-cache madison docker-ce

image-1648974209998

  • 选择要安装的特定版本,第二列是版本字符串,第三列是存储库名称,它指示包来自哪个存储库,以及扩展它的稳定性级别。

2)安装特定的版本

要安装一个特定的版本,将版本字符串附加到包名中,并通过等号(=)分隔它们。命令:sudo apt-get install docker-ce=<VERSION>

sudo apt-get install docker-ce=5:20.10.8~3-0~ubuntu-focal

4.7 查看Docker版本信息

docker帮助命令及版本信息:

  • 查看帮助:docker --help
  • 查看信息:docker info
  • 查看详细版本信息:docker version
  • 查看简单版本信息:docker -v

image-1648974280301

image-1648974286553

4.8 Docker测试HelloWorld镜像

1) 拉取hello-world镜像

通过命令 docker pull hello-world 来拉取hello-world镜像。

image-1648974318019

2) 运行hello-world镜像

通过命令 docker run hello-world 来运行hello-world镜像。若本地没有hello-world镜像且没有执行第一步,执行本命令会自动拉取hello-world镜像。

image-1648974353817

  • 若是出现了上图的内容则说明hello-world运行成功。

5、Docker服务命令

5.1 Docker查看状态命令

查看Docker是否启动命令:systemctl status docker

image-1648974403367

5.2 Docker启动命令

启动Docker命令:systemctl start docker

image-1648974542378

5.3 Docker停止命令

停止Docker命令:systemctl start docker

image-1648974557001

5.4 Docker重启命令

docker重启命令:systemctl restart docker

5.5 Docker加入开机启动

加入开机启动命令:systemctl enable docker

image-1648974645392

5.6 重新加载Docker守护线程

systemctl daemon-reload

5.7 Docker其他命令

  • 查看帮助:docker --help
  • 查看信息:docker info
  • 查看详细版本信息:docker version
  • 查看简单版本信息:docker -v
  • docker自身的内存占用:docker system df
  • 清理磁盘,删除关闭的容器、无用的数据卷和网络,以及dangling镜像(即无tag的镜像):docker system prune
  • 查看容器运行内存cpu占用情况:docker stats

6、配置docker镜像加速

Docker 默认是从官方镜像地址 Docker Hub 下下载镜像,由于服务器在国外的缘故,导致经常下载速度非常慢。为了提升镜像的下载速度,我们可以手动配置国内镜像加速器,让下载速度飚起来。

  • 国内的镜像加速器选项较多,如:阿里云,DaoCloud 等。下面主要讲一下如何配置阿里云的镜像加速器。

6.1 登录阿里云获取加速信息

首先你需要注册一个阿里云账号,没有的话,通过下面的连接跳转注册:https://dev.aliyun.com/ ,注册登录后,直接访问镜像加速页 https://cr.console.aliyun.com/,获取加速器地址。

image-1648974742796

6.2 配置 Docker

6.2.1 确定 Docker Client 版本

在配置之前,首先需要确定 Docker Client 的版本,推荐是 1.10.0+,命令:docker version

6.2.2 停止docker服务

命令:systemctl status docker

6.2.3 配置镜像加速器

这里以Ubuntu 系统为例,通过修改 daemon 配置文件 /etc/docker/daemon.json 来使用加速器(如果是别的系统,可以参考阿里云配置加速器官方文档):

1)创建目录

sudo mkdir -p /etc/docker

2)创建daemon.json文件并保存内容

vim /etc/docker/daemon.json 文件,将以下内容保存到文件中,其中加速地址用5.1中获取的减速器地址替换。

{
  "registry-mirrors": ["加速地址"]
}

或者用sudo tee命令,同vim的效果一样。sudo tee 表示把当前编辑的文件的内容当做标准输入输入到命令sudo tee 文件名里去。执行以下命令,可以一起执行,也可以分行执行。

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}
EOF

3)重新启动服务

重新加载配置:sudo systemctl daemon-reload
重启docker:sudo systemctl restart docker

  • 注:个人配置的阿里云加速器地址启动docker报错(Job for docker.service failed because the control process exited with error code.),改为163的加速器地址后正常。163加速器地址: http://hub-mirror.c.163.com

6.3 验证下载速度

以下载 mongodb 为例,看下速度,命令:docker pull mongo

image-1648974913623

6.4 其他加速器镜像地址

当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。

7、Docker配置

7.1 日志调优

vim /etc/docker/daemon.json 文件,保存/追加以下内容。然后重新加载配置:sudo systemctl daemon-reload, 重启docker:sudo systemctl restart docker

# max-file:日志文件上限个数, max-size:日志文件上限大小
{
      "log-driver":"json-file",
      "log-opts": {"max-size":"500m", "max-file":"3"}
}

image-1648974972659

7.2 目录迁移

-- 关闭docker服务
systemctl stop docker
-- 创建迁移后的目录
mkdir -p  /home/jamelli/docker/data/lib
-- 复制原有docker数据到新目录
rsync -r -avz /var/lib/docker /home/jamelli/docker/data/lib
mkdir -p /etc/systemd/system/docker.service.d/
-- 创建docker 映射文件
vi /etc/systemd/system/docker.service.d/devicemapper.conf
保存内容>>
	[Service]
	ExecStart=
	ExecStart=/usr/bin/dockerd  --graph=/home/creationpoint/docker/data/lib/docker
        
-- 重新加载 docker
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
    
-- 确认docker 路径[Docker Root Dir 属性列]
docker info
-- 确认镜像是否还在
docker images
-- 删除历史docker文件
rm -rf /var/lib/docker/

7.3 docker命令tab自动补全

#centos root
yum -y install bash_completion
 
#ubuntu  root
sudo apt-get purge bash-completion
sudo mv /etc/bash_completion.d /etc/bash_completion.d.bak
sudo apt-get install bash-completion
sudo apt-get update
 
#生效 ubuntu  和 centos  都是此命令
source /etc/profile.d/bash_completion.sh

7.4 提供外部访问docker

云服务器非必要不要开放2375端口,开放了也一定要设置自己的IP白名单访问,如果暴露所有IP,肯定会被挖矿。

1)编辑docker文件:/usr/lib/systemd/system/docker.service

sudo vim /usr/lib/systemd/system/docker.service

2)修改ExecStart行为下面内容

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
  • 注:2375 可以改为其他端口,如ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:999 -H unix://var/run/docker.sock,这里的 999 为自定义端口号,外网建议不要使用默认端口"2375"。

3)重启docker

# 加载docker守护线程
systemctl daemon-reload

# 重启docker
systemctl restart docker

4)查看是否设置成功

curl http://localhost:2375/version

7.5 Docker挂载本地目录

docker的镜像是由多个只读的文件系统叠加在一起形成的。当我们在我启动一个容器的时候,docker会加载这些只读层并在这些只读层的上面(栈顶)增加一个读写层。这时如果修改正在运行的容器中已有的文件,那么这个文件将会从只读层复制到读写层。该文件的只读版本还在,只是被上面读写层的该文件的副本隐藏。当删除docker,或者重新启动时,之前的更改将会消失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统)。

  • 为了很好的实现数据保存和数据共享,Docker提出了Volume这个概念,简单的说就是绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。又被称作数据卷。

  • 不要将数据储存在容器中,这也是 Docker 官方容器使用技巧中的一条。容器随时可以停止、或者删除。当容器被rm掉,容器里的数据将会丢失。为了避免数据丢失,用户可以使用数据卷挂载来存储数据。

1)挂载本地目录(Bind mounts)

docker可以支持把一个宿主机上的目录挂载到容器里。

docker run -it -v /home/dock/Downloads:/usr/Downloads ubuntu64 /bin/bash

通过-v参数,冒号前为宿主机目录,必须为绝对路径,冒号后为容器内挂载的路径。ubuntu64为容器名称。现在容器内就可以共享宿主机里的文件了。在容器启动后,容器内会自动创建/soft的目录。

  • 容器目录不可以为相对路径,所谓的绝对路径,必须以下斜线“/”开头。
  • 宿主机目录如果不存在,则会自动生成。如果宿主机中存在目录,首先删除它。
  • 宿主机的目录如果为相对路径,会挂载到/var/lib/docker/volumes/test1/_data目录下。通过docker inspect命令,查看容器“Mounts”那一部分,我们可以得到这个问题的答案。
"Mounts": [
        {
            "Name": "test1",
            "Source": "/var/lib/docker/volumes/test1/_data",
            "Destination": "/soft",
            "Driver": "local",
            "Mode": "z",
            "RW": true
        }
    ],
    
# 可以看出,容器内的/soft目录挂载的是宿主机上的/var/lib/docker/volumes/test1/_data目录。所谓的相对路径指的是/var/lib/docker/volumes/,与宿主机的当前目录无关。

默认挂载的路径权限为读写。如果指定为只读可以用:ro

docker run -it -v /home/dock/Downloads:/usr/Downloads:ro ubuntu64 /bin/bash

2)数据卷(Volumes)

docker还提供了一种高级的用法。叫数据卷。

  • 数据卷:“其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的”。感觉像是由一个容器定义的一个数据挂载信息。其他的容器启动可以直接挂载数据卷容器中定义的挂载信息。

示例:

docker run -v /home/dock/Downloads:/usr/Downloads  --name dataVol ubuntu64 /bin/bash

#创建一个普通的容器。用--name给他指定了一个名(不指定的话会生成一个随机的名子)。

image-1648975228641

再创建一个新的容器,来使用这个数据卷。

docker run -it --volumes-from dataVol ubuntu64 /bin/bash
--volumes-from用来指定要从哪个数据卷来挂载数据。

image-1648975259034

3)查看容器的挂载目录

docker inspect container_name | grep Mounts -A 20
docker inspect container_id | grep Mounts -A 20

8、Docker镜像常用命令

1)docker查看系统中的镜像文件:

查看所有镜像:docker images 或 docker image list

docker images结果选项说明:

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

查找某个镜像文件:docker search xxxxx, 如docker search mysql

docker search 结果选项说明:

  • NAME:镜像说明
  • DESCRIPTION:镜像说明
  • STARTS:点赞数量
  • OFFICIAL:是否是官方的
  • AUTOMATED:是否是自动构建的

image-1648975394589

2)下载docker镜像:

下载最新版本:docker pull 容器名, 如 docker pull mysql
下载指定版本:docker pull 容器名:版本号,如 docker pull mysql:5.6

# docker pull 镜像名称
[root@docker ~]# docker pull nginx
Using default tag: latest
Trying to pull repository docker.io/library/nginx ... 
latest: Pulling from docker.io/library/nginx
c499e6d256d6: Pull complete 
74cda408e262: Pull complete 
ffadbd415ab7: Pull complete 
Digest: sha256:282530fcb7cd19f3848c7b611043f82ae4be3781cb00105a1d593d7e6286b596
Status: Downloaded newer image for docker.io/nginx:latest

3)添加镜像标签

#docker tag 旧名称 新名称
[root@docker ~]# docker tag docker.io/nginx:latest nginx:web
[root@docker ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/nginx     latest              ed21b7a8aee9        8 days ago          127 MB
nginx               web                 ed21b7a8aee9        8 days ago          127 MB
#相当于生成创建一个新的镜像

image-1648975685134

4)删除docker镜像(imageID表示镜像文件ID):

docker rmi imageID
docker image rm 容器名:版本号,如 docker image rm centos:latest

#docker rmi 镜像名
#使用镜像创建容器后,如果没有删除容器,镜像删除不了
[root@docker ~]# docker rmi nginx:web 
Untagged: nginx:web
Untagged: docker.io/nginx@sha256:282530fcb7cd19f3848c7b611043f82ae4be3781cb00105a1d593d7e6286b596
[root@docker ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/nginx     latest              ed21b7a8aee9        8 days ago          127 MB

5)导出镜像:

  • docker image save 镜像Id> 保存到本地的镜像名称,如 docker image save hello-world > docker-helloword.tar.gz ,语句中的镜像Id也可以用REPOSITORY或REPOSITORY:TAG替代,只要可以标识到唯一镜像即可。
  • docker save -o 文件名 镜像名

image-1648975802944

6)导入镜像

  • docker image load -i 镜像文件名称
  • docker load < 镜像名

image-1648975820698

7)上传镜像到仓库

docker push 镜像名称
先登录仓库,再进行上传

9、Docker容器常用命令

1)docker 列出容器列表:

  • docker 列出run的容器: docker ps
  • docker 列出最近创建的容器:docker ps -aldocker ps -all
  • docker 列出所有的容器(包括未运行):docker ps -a 或 docker ps --all

image-1648975958538

image-1648975964851

2)docker 容器改名:

  • 因为容器的ID是随机码,而容器的名字又是看似无意义的命名,我们可以使用以下命令给这个容器命名。
docker rename old_name new_name

image-1648975997676

  • 以后我们再次启动或停止容器时,就可以直接使用这个名字。
docker [stop] [start]  new_name

image-1648976023745

3)运行docker 容器:

docker run 与 docker start区别

  • docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start)。
  • docker start的作用是,重新启动已存在的镜像。也就是说,如果使用这个命令,我们必须事先知道这个容器的ID,或者这个容器的名字,我们可以使用docker ps找到这个容器的信息。

docker run命令:

  • docker run xxxxx
  • docker run -p 8080:80 --name 自定义名称 -it 镜像名称  /bin/bash
  • docker自定义名称启动  --name,如docker run -d --name new_name_nginx nginx
  • docker rename serene_rosalind ssh,serene_rosalind:修改前的容器名称, ssh:修改后的容器名称
# 例子
#启动nginx   
docker run -d -p 80:80 nginx
#查看当前运行的容器    
docker ps

image-1648976131154

可以使用 -p 或 -P 标识来指定容器端口绑定到主机端口。两种方式的区别是:

  • -P :是容器内部端口随机映射到主机的高端口。
  • -p : 是容器内部端口绑定到指定的主机端口。
-p hostPort:containerPort       端口映射  -p 8080:80
-p ip:hostPort:containerPort    配置监听地址  -p 10.0.0.100:8080:80
-p ip::containerPort            随机分配端口  -p 10.0.0.100::80
-p hostPort:containerPort:udp   指定协议  -p 8080:80:tcp
-p 81:80 -p 443:443    	        指定多个端口
docker run
# -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
# -d: 后台运行容器,并返回容器ID;
# -p: 端口映射 hostport:containerPort;如 -p 8080:8081
# -i: 以交互模式运行容器,通常与 -t 同时使用;
# -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
# --name="nginx-lb": 为容器指定一个名称;
# --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
# --dns-search [example.com](http://example.com/): 指定容器DNS搜索域名,默认和宿主一致;
# -h "mars": 指定容器的hostname;
# -e username="ritchie": 设置环境变量;
# --env-file=[]: 从指定文件读入环境变量;
# --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
# -m :设置容器使用内存最大值;
# --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
# --link=[]: 添加链接到另一个容器;
# --expose=[]: 开放一个端口或一组端口

4)启动/重启docker容器:

  • 启动容器:docker start CONTAINERID或容器名
  • 重启容器(不管容器是否启动,直接重启容器):docker restart CONTAINERID或容器名

docker start 有两个参数

  • -i:以 交互模式启动
  • -t:以 附加进程方式启动

5)停止docker 容器运行(CONTAINERID 表示容器id):

优雅的停止容器docker stop CONTAINERID或容器名

  • 参数 -t:关闭容器的限时,如果超时未能关闭则用kill强制关闭,默认值10s,这个时间用于容器的自己保存状态
  • docker stop -t=60 容器ID或容器名

直接关闭容器docker kill 容器ID或容器名

stop和kill的主要区别:stop给与一定的关闭时间交由容器自己保存状态,kill直接关闭容器。

6)进入docker 容器:

  • 交互模式进入:docker run -it 容器名称 参数:-it 可交互终端 , 如 docker run -it nginx /bin/bash
  • exec进入(推荐):docker exec -it 容器id 参数 , 如docker exec -it d56af9aee578 /bin/bash
# 交互模式进入
root@xnzysq20210118001:~# docker run -it nginx /bin/bash
#显示ID标识进入成功
root@ae2d49c6bca6:/# 

# 按Ctrl+p, 再按Ctrl+q 退出当前容器

# 查看正在运行的容器
root@xnzysq20210118001:/etc/docker# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                               NAMES
d56af9aee578   nginx     "/docker-entrypoint.…"   21 minutes ago   Up 21 minutes   0.0.0.0:81->80/tcp, :::81->80/tcp   infallible_villani
# exec进入
root@xnzysq20210118001:/etc/docker# docker exec -it d56af9aee578 /bin/bash
root@d56af9aee578:/# 

image-1648976517241

7)退出docker 容器但不停止运行:

  • 方式一:Ctrl+P & Ctrl+Q, 先按Ctrl+P,接着按Ctrl+Q。
  • 方式二:exit

8)删除docker 容器(CONTAINERID 表示容器id):

  • 只能删除停止的容器:docker rm CONTAINERID
  • 强制删除容器:docker rm -f CONTAINERID
  • 批量删除所有容器:docker ps -a | awk ‘{print "docker rm " $1}’ | bash

image-1648976549987

9)获取容器信息(imageID表示镜像文件ID)

  • docker inspect imageID  或 docker image inspect imageID  或  docker image inspect REPOSITORY:TAG

image-1648976578452

image-1648976585189

image-1648976589381

10)查看容器IP地址:

  • 查看容器IP地址:docker inspect CONTAINERID | grep IPAddress

11)查看容器映射端口:

  • 查看容器映射端口:docker port CONTAINERID

12)容器日志内容查询

  • less /var/lib/docker/containers/容器ID/容器ID-json.log

13)容器日志内容实时查看

  • docker logs --tail=10 -f 容器名称/容器id

14)容器导出

#docker export 镜像ID
[root@docker abc]# docker export de7b916f83fe > nginx_1
[root@docker abc]# ls
nginx_1

15)容器导入

#cat 文件名 | docker import - 镜像名
#上传导入的是镜像,不会生成容器
[root@docker abc]# cat nginx_1 | docker import - nginx
sha256:88960c2fb5f526bcfae0a747b25fcba690607fc77013338dc9189096843852c8
[root@docker abc]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              88960c2fb5f5        3 seconds ago       125 MB
[root@docker abc]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

15)将容器转化成镜像

docker commit -m="ssh" -a="kz" ce11e0ab75c8 centos7/ssh:v1

# -m:提交的描述信息
# -a:指定镜像作者
# ce11e0ab75c8:容器ID
# centos7/ssh:v1:制定要创建的镜像名
# 设置镜像标签:
docker tag ce39e0ff75f8 centos7/ssh:v1
##ce39e0ff75f8:容器ID
# centos7/ssh:v1:制定要修改的镜像名

16)从容器内拷贝文件到主机上

docker cp <containerId>:/file/path/within/container /host/path/target

17)从主机上拷贝文件到容器内

1.用-v挂载主机数据卷到容器内
docker run -v /path/to/hostdir:/mnt $container  
# 在容器内拷贝  
cp /mnt/sourcefile /path/to/destfile  

2.直接在主机上拷贝到容器物理存储系统
# A 获取容器名称或者id
docker ps  
# B 将主机/tmp/my_data目录下的所有文件拷贝到容器my_container的/my_data目录,注意/tmp/my_data/.后面的.:
docker cp /tmp/my_data/. my_container:/my_data

3.直接在主机上拷贝到容器物理存储系统
# A 获取容器名称或者id
docker ps  
# B 获取整个容器的id
$ docker inspect -f '{{.Id}}' 容器id或名称  
# C 在主机上拷贝文件:
$ sudo cp path-file-host /var/lib/docker/aufs/mnt/FULL_CONTAINER_ID/PATH-NEW-FILE   
或者  
$ sudo cp path-file-host /var/lib/docker/devicemapper/mnt/123abc<<id>>/rootfs/root 

如:sudo cp my.cnf /var/lib/docker/aufs/mnt/**f7db9cf96cda5524bf7746d05b16135ae4f0c80127408c115c3e076a9aa6f9f0

4.用输入输出符
docker run -i ubuntu /bin/bash -c 'cat > /path/to/container/file' < /path/to/host/file/  
或者
docker exec -it <container_id> bash -c 'cat > /path/to/container/file' < /path/to/host/file/

18)容器内更新依赖安装vim命令等

# 进入容器
docker exec -it docker-redis-master bash

# 更新依赖命令
apt-get update
# 安装vim命令
apt-get install -y vim
# 安装ps命令
apt-get install -y procps

19)Docker查看容器IP

docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container-ID>
# 或
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id

示例:

docker inspect --format '{{ .NetworkSettings.IPAddress }}' activemq

显示所有容器IP

docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
0

评论区