什么是容器化应用

之前我们运行容器的时候,显然不是从零开始的,而是要先拉取一个“镜像”(image),再从这个“镜像”来启动容器,像第一节课这样:

docker pull busybox      
docker run busybox echo hello world

如果还拿之前的“小板房”来做比喻的话,那么镜像就可以说是一个“样板间”,把运行进程所需要的文件系统、依赖库、环境变量、启动参数等所有信息打包整合到了一起。之后镜像文件无论放在哪里,操作系统都能根据这个“样板间”快速重建容器,应用程序看到的就会是一致的运行环境了。

从功能上来看,镜像和常见的 tar、rpm、deb 等安装包一样,都打包了应用程序,但最大的不同点在于它里面不仅有基本的可执行文件,还有应用运行时的整个系统环境。这就让镜像具有了非常好的跨平台便携性和兼容性,能够让开发者在一个系统上开发(例如 Ubuntu),然后打包成镜像,再去另一个系统上运行(例如 CentOS),完全不需要考虑环境依赖的问题,是一种更高级的应用打包方式。理解了这一点,我们再回过头来看看第一节课里运行的 Docker 命令。

docker pull busybox ,就是获取了一个打包了 busybox 应用的镜像,里面固化了 busybox 程序和它所需的完整运行环境。docker run busybox echo hello world ,就是提取镜像里的各种信息,运用 namespace、cgroup、chroot 技术创建出隔离环境,然后再运行 busybox 的 echo 命令,输出 hello world 的字符串。

这两个步骤,由于是基于标准的 Linux 系统调用和只读的镜像文件,所以,无论是在哪种操作系统上,或者是使用哪种容器实现技术,都会得到完全一致的结果。

推而广之,任何应用都能够用这种形式打包再分发后运行,这也是无数开发者梦寐以求的“一次编写,到处运行(Build once, Run anywhere)”的至高境界。所以,所谓的“容器化的应用”,或者“应用的容器化”,就是指应用程序不再直接和操作系统打交道,而是封装成镜像,再交给容器环境去运行。现在你就应该知道了,镜像就是静态的应用容器,容器就是动态的应用镜像,两者互相依存,互相转化,密不可分。之前的那张 Docker 官方架构图你还有印象吧,我们在第一节课曾经简单地介绍过。可以看到,在 Docker 里的核心处理对象就是镜像(image)和容器(container):

好,理解了什么是容器化的应用,接下来我们再来学习怎么操纵容器化的应用。因为镜像是容器运行的根本,先有镜像才有容器,所以先来看看关于镜像的一些常用命令。常用的镜像操作有哪些在前面的课程里你应该已经了解了两个基本命令,docker pull 从远端仓库拉取镜像,docker images 列出当前本地已有的镜像。docker pull 的用法还是比较简单的,和普通的下载非常像,不过我们需要知道镜像的命名规则,这样才能准确地获取到我们想要的容器镜像。镜像的完整名字由两个部分组成,名字和标签,中间用 : 连接起来。名字表明了应用的身份,比如 busybox、Alpine、Nginx、Redis 等等。标签(tag)则可以理解成是为了区分不同版本的应用而做的额外标记,任何字符串都可以,比如 3.15 是纯数字的版本号、jammy 是项目代号、1.21-alpine 是版本号加操作系统名等等。其中有一个比较特殊的标签叫“latest”,它是默认的标签,如果只提供名字没有附带标签,那么就会使用这个默认的“latest”标签。那么现在,你就可以把名字和标签组合起来,使用 docker pull 来拉取一些镜像了:

docker pull alpine:3.15
docker pull ubuntu:jammy
docker pull nginx:1.21-alpine
docker pull nginx:alpine
docker pull redis

在这个列表里,你可以看到,REPOSITORY 列就是镜像的名字,TAG 就是这个镜像的标签,那么第三列“IMAGE ID”又是什么意思呢?

它可以说是镜像唯一的标识,就好像是身份证号一样。比如这里我们可以用“ubuntu:jammy”来表示 Ubuntu 22.04 镜像,同样也可以用它的 ID“d4c2c……”来表示。

另外,你可能还会注意到,截图里的两个镜像“nginx:1.21-alpine”和“nginx:alpine”的 IMAGE ID 是一样的,都是“a63aa……”。这其实也很好理解,这就像是人的身份证号码是唯一的,但可以有大名、小名、昵称、绰号,同一个镜像也可以打上不同的标签,这样应用在不同的场合就更容易理解。

IMAGE ID 还有一个好处,因为它是十六进制形式且唯一,Docker 特意为它提供了“短路”操作,在本地使用镜像的时候,我们不用像名字那样要完全写出来这一长串数字,通常只需要写出前三位就能够快速定位,在镜像数量比较少的时候用两位甚至一位数字也许就可以了。

来看另一个镜像操作命令 docker rmi ,它用来删除不再使用的镜像,可以节约磁盘空间,注意命令 rmi ,实际上是“remove image”的简写。

docker rmi redis    
docker rmi d4c

这里的第一个 rmi 删除了 Redis 镜像,因为没有显式写出标签,默认使用的就是“latest”。第二个 rmi 没有给出名字,而是直接使用了 IMAGE ID 的前三位,也就是“d4c”,Docker 就会直接找到这个 ID 前缀的镜像然后删除。Docker 里与镜像相关的命令还有很多,不过以上的 docker pull、docker images、docker rmi 就是最常用的三个了,其他的命令我们后续课程会陆续介绍。

常用的容器操作有哪些现在我们已经在本地存放了镜像,就可以使用 docker run 命令把这些静态的应用运行起来,变成动态的容器了。基本的格式是“docker run 设置参数”,再跟上“镜像名或 ID”,后面可能还会有附加的“运行命令”。比如这个命令:

docker run -h srv alpine hostname这里的 -h srv 就是容器的运行参数,alpine 是镜像名,它后面的 hostname 表示要在容器里运行的“hostname”这个程序,输出主机名。docker run 是最复杂的一个容器操作命令,有非常多的额外参数用来调整容器的运行状态,你可以加上 --help 来看它的帮助信息,今天我只说几个最常用的参数。-it 表示开启一个交互式操作的 Shell,这样可以直接进入容器内部,就好像是登录虚拟机一样。(它实际上是“-i”和“-t”两个参数的组合形式)-d 表示让容器在后台运行,这在我们启动 Nginx、Redis 等服务器程序的时候非常有用。--name 可以为容器起一个名字,方便我们查看,不过它不是必须的,如果不用这个参数,Docker 会分配一个随机的名字。下面我们就来练习一下这三个参数,分别运行 Nginx、Redis 和 Ubuntu:

docker run -d nginx:alpine            # 后台运行Nginx
docker run -d --name red_srv redis    # 后台运行Redis
docker run -it --name ubuntu 2e6 sh   # 使用IMAGE ID,登录Ubuntu18.04

因为第三个命令使用的是 -it 而不是 -d ,所以它会进入容器里的 Ubuntu 系统,我们需要另外开一个终端窗口,使用 docker ps 命令来查看容器的运行状态:

可以看到,每一个容器也会有一个“CONTAINER ID”,它的作用和镜像的“IMAGE ID”是一样的,唯一标识了容器。对于正在运行中的容器,我们可以使用 docker exec 命令在里面执行另一个程序,效果和 docker run 很类似,但因为容器已经存在,所以不会创建新的容器。它最常见的用法是使用 -it 参数打开一个 Shell,从而进入容器内部,例如:

docker exec -it red_srv sh

样我们就“登录”进了 Redis 容器,可以很方便地查看服务的运行状态或者日志。运行中的容器还可以使用 docker stop 命令来强制停止,这里我们仍然可以使用容器名字,不过或许用“CONTAINER ID”的前三位数字会更加方便。

docker stop ed4 d60 45c

容器被停止后使用 docker ps 命令就看不到了,不过容器并没有被彻底销毁,我们可以使用 docker ps -a 命令查看系统里所有的容器,当然也包括已经停止运行的容器: 

这些停止运行的容器可以用 docker start 再次启动运行,如果你确定不再需要它们,可以使用 docker rm 命令来彻底删除。注意,这个命令与 docker rmi 非常像,区别在于它没有后面的字母“i”,所以只会删除容器,不删除镜像。下面我们就来运行 docker rm 命令,使用“CONTAINER ID”的前两位数字来删除这些容器:

docker rm ed d6 45

执行删除命令之后,再用 docker ps -a 查看列表就会发现这些容器已经彻底消失了。你可能会感觉这样的容器管理方式很麻烦,启动后要 ps 看 ID 再删除,如果稍微不注意,系统就会遗留非常多的“死”容器,占用系统资源,有没有什么办法能够让 Docker 自动删除不需要的容器呢?办法当然有,就是在执行 docker run 命令的时候加上一个 --rm 参数,这就会告诉 Docker 不保存容器,只要运行完毕就自动清除,省去了我们手工管理容器的麻烦。我们还是用刚才的 Nginx、Redis 和 Ubuntu 这三个容器来试验一下,加上 --rm 参数(省略了 name 参数):

docker run -d --rm nginx:alpine 
docker run -d --rm redis
docker run -it --rm 2e6 sh

然后我们用 docker stop 停止容器,再用 docker ps -a ,就会发现不需要我们再手动执行 docker rm ,Docker 已经自动删除了这三个容器。

Docker-容器化应用相关推荐

  1. Docker容器化部署config-server无法直接访问

    Docker容器化部署config-server无法直接访问 1. 本机ip启动方式: 2. Docker容器启动 1)问题 2)解决办法 - 本机启动 - 服务器启动俩种方式 3. dockerfi ...

  2. 通过 Azure Pipelines 实现持续集成之docker容器化

    Intro Azure DevOps Pipeline 现在对于公开的项目完全免费,这对于开源项目来讲无疑是个巨大的好消息,在 Github 的 Marketplace 里有个 Azure Pipel ...

  3. Docker容器化技术教程,24小时快速入门

    Docker介绍 Docker简介和安装 Docker是什么 为什么使用Docker 和普通虚拟机的对比 打包.分发.部署 小结 Docker部署的优势 Docker通常用来做什么 重要概念:镜像.容 ...

  4. 如何在开发和生产环境中使用 Docker 容器化 Golang 应用

    你是否想写一个使用 Docker 容器化的 Golang 应用程序?本文的目的就是帮助你快速将你的 Golang 应用程序容器化,以用于 开发 (带热加载)和 生产 目的. 开始之前 请先安装 Doc ...

  5. 悟空CRM11.0 PHP版本docker容器化部署全流程

    由于本地服务器为PHP5.3,项目部署需要PHP >= 7.0.*,所以选择docker容器化部署,服务器系统为centos7.3,所有的sql文件都在项目路径 public/sql下 目录 一 ...

  6. Docker 容器化部署

    文章目录 思维导图 概念 安装(基于 centos7) 结构 Docker 命令 进程(daemon)相关命令 镜像(image)相关命令 容器(container))相关命令 数据卷 数据卷容器 d ...

  7. docker rails mysql_MySQL 进行 Docker 容器化之体验与感悟

    原则 Docker 的使用原则是所有容器化的应用程序都应该是无状态的 ,即容器内部只跑业务逻辑,容器应用的所有配置文件.日志文件和持久化数据 都应该挂载到宿主机文件系统,不应该存储在容器内部,以免容器 ...

  8. docker容器化python开发环境_如何 Docker 化 Python Django 应用程序

    Docker 是一个开源项目,为开发人员和系统管理员提供了一个开放平台,可以将应用程序构建.打包为一个轻量级容器,并在任何地方运行.Docker 会在软件容器中自动部署应用程序. Django 是一个 ...

  9. Docker容器化部署python

    1. 简介 Docker是目前主流IT公司广泛接受和使用的,用于构建.管理和保护它们应用程序的工具. 容器,例如Docker允许开发人员在单个操作系统上隔离和运行多个应用程序,而不是为服务器上的每个应 ...

  10. Docker容器化开发

    目录 1.初识Docker 1.1.Docker概念 1.2.安装Docker 1.3.docker架构 3.docker命令 3.1.进程相关命令 3.2.镜像相关命令 3.3.容器相关命令 4.D ...

最新文章

  1. Pytorch - GPU ID 指定 pytorch gpu 指定
  2. AI开放只是幌子?科技巨头边承诺开放边申请专利
  3. java线程分类_Java 线程类别
  4. 街景图像分割_借助深度学习和街景图像进行城市的大规模树木死亡率研究
  5. java 登陆验证失败_使用Java 8流进行快速失败的验证
  6. 无线业务需求的线路设计以及拓扑图实现
  7. macos brew zookeeper,安装后zookeeper启动失败?
  8. 计算机多媒体应用软件有超媒体特点吗,《多媒体技术与应用》(本)阶段练习一...
  9. pig0.15+hadoop2.x安装 (注意版本匹配)
  10. 解决VS2003查询卡死的问题
  11. 【老生谈算法】matlab实现一维曲线分形维数算法源码——一维曲线分形维数
  12. python相关性分析的散点图怎么做_相关性分析 散点图
  13. 《Delphi 4 开发大全》作者、Delphi研发团队开发工程师:史蒂夫·特谢拉(Steve Teixeira)访谈
  14. mysql1682错误_ERROR 1682 (HY000)
  15. numpy.take()用法总结
  16. 0725(016天 多态复习 java中级-抽象类01)
  17. 2019年实习过的同学来领钱啦!我可以退4000多!附:退税攻略
  18. 【小程序】promise在小程序中的运用
  19. NKOJ 4247 老蒋的数列(乱搞)
  20. java屏蔽游戏中骂人的话,替换为*,屏蔽敏感词汇

热门文章

  1. 结果集没有当前行的解决方法
  2. uniapp ----小程序上下滑动页面,视频自动播放(完整代码)
  3. 【机器学习】最大均值差异MMD详解
  4. 新式单片机视频教程下载
  5. UE4灰度图生成地图记录blender生成城市地形
  6. mac os升级到Catalina版本原先根目录下自己创建的目录找不到解决方案
  7. glog使用与说明(转载)
  8. matlab怎么开始使用方法,matlab怎么使用,matlab基本使用方法
  9. win10系统下jdk环境变量配置
  10. Oracle技巧:如何诊断一些未预料的 Oracle 错误(ORA-NNNN)