Docker 核心概念

Docker 核心概念总结

容器

  • 容器就是将软件打包成标准化单元,以用于开发、交付和部署
    • 容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置
    • 容器化软件适用于基于 Linux 和 Windows 的应用,在任何环境中都能够始终如一地运行
    • 容器赋予了软件独立性,使其免受外在环境差异(例如,开发和预演环境的差异)的影响
image-20230101160652123
  • 容器和虚拟机

    image-20230101185615810
    • 容器虚拟化的是操作系统而不是硬件,容器内没有自己的内核,而且也没有进行硬件虚拟,容器之间共享同一套操作系统资源;虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统
    • 容器是一个应用层抽象,将代码和依赖资源打包在一起。多个容器各自作为独立的进程在用户空间中运行
    • 虚拟机 (VM) 是一个物理硬件层抽象,将一台服务器变成多台服务器。 每个 VM 都包含一整套操作系统、一个或多个应用、必要的二进制文件和库资源

Docker

  • Docker 是软件容器平台
    • Docker对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器
    • Docker 能够自动执行重复性任务,例如搭建和配置开发环境,从而解放了开发人员以便他们专注在真正重要的事情上:构建杰出的软件。
    • 用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
  • 思想:

    • 集装箱
    • 标准化: ① 运输方式 ② 存储方式 ③ API 接口
    • 隔离
  • Docker 容器的特点

    • 轻量:一台机器上运行的多个 Docker 容器可以共享这台机器的操作系统内核;只占用很少的计算和内存资源。镜像通过文件系统层构造,共享一些公共文件,尽量降低磁盘用量
    • 标准 : Docker 容器基于开放式标准,能够在所有主流 Linux 版本、Microsoft Windows 以及包括 VM、裸机服务器和云在内的任何基础设施上运行
    • 安全 : Docker 赋予的隔离性不仅限于彼此隔离,还独立于底层的基础设施。应用出现问题,也只是单个容器的问题,而不会波及到整台机器
  • 使用Docker的好处

    • 一致的运行环境——镜像提供除内核外完整的运行时环境,确保应用运行环境一致性
    • 更快速的启动时间——秒级、甚至毫秒级的启动时间
    • 隔离性——避免资源受到其他用户的影响
    • 弹性伸缩,快速扩展——处理集中爆发的服务器使用压力
    • 迁移方便——可以将在一个平台上运行的应用,迁移到另一个平台上
    • 持续交付和部署——过定制应用镜像实现持续集成、持续交付、部署
  • 镜像(Image):一个特殊的文件系统

    • Linux 在内核启动后,会挂载 root 文件系统为其提供用户空间支持。Docker 镜像(Image)就相当于是一个 root 文件系统
    • Docker 镜像除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)
    • 镜像不包含任何动态数据,其内容在构建之后也不会被改变
    • 利用 Union FS 的技术,设计为分层存储的架构——镜像实际是由多层文件系统联合组成,前一层是后一层的基础。每一层构建完就不会再发生改变
    • 删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。容器运行的时候不会看到这个文件,但实际上该文件会一直跟随镜像
  • 容器(Container):镜像运行时的实体

    • 镜像(Image)和容器(Container)的关系,类似于类和实例的关系。镜像是静态的定义,容器是镜像运行时的实体,可以被创建、启动、停止、删除、暂停等
    • 容器的实质是进程,容器进程运行于属于自己的独立的命名空间
    • 容器同样分层存储,存储层的生存周期和容器一样
    • 容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,它们的读写会跳过容器存储层,直接对宿主发生读写
    • 数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡——使用数据卷后,容器可以随意删除、重新 run,数据却不会丢失
  • 仓库(Repository):集中存放镜像文件

    • 需要集中的存储、分发镜像的服务,例如Docker Registry
    • 一个 Docker Registry 可以包含多个仓库(Repository),每个仓库包含多个标签(Tag),每个标签对应一个镜像
    • Docker Registry 公开服务开放给用户使用、允许用户管理镜像的 Registry 服务,例如官方的Docker Hub

常见命令

基本命令

1
2
3
4
5
docker version # 查看docker版本
docker images # 查看所有已下载镜像,等价于:docker image ls 命令
docker container ls # 查看所有容器
docker ps #查看正在运行的容器
docker image prune # 清理临时的、没有被使用的镜像文件。-a, --all: 删除所有没有用的镜像,而不仅仅是临时文件;

拉取镜像

1
2
3
docker search mysql # 查看mysql相关镜像
docker pull mysql:5.7 # 拉取mysql镜像
docker image ls # 查看所有已下载镜像

删除镜像

  • 通过 docker rmi [image] (等价于docker image rm [image])删除镜像前,要确保这个镜像没有被容器引用(可以通过标签名称或者镜像 ID删除)。通过 docker ps命令即可查看。

    1
    2
    3
    ➜  ~ docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    c4cd691d9f80 mysql:5.7 "docker-entrypoint.s…" 7 weeks ago Up 12 days 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
  • mysql 在被 id 为 c4cd691d9f80 的容器引用,通过 docker stop c4cd691d9f80 或者 docker stop mysql容器,然后查看 mysql 镜像的 id,通过 IMAGE ID 或者 REPOSITORY 名字删除

    1
    2
    3
    ➜  ~ docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    mysql 5.7 f6509bac4980 3 months ago 373MB
    1
    docker rmi f6509bac4980 #  或者 docker rmi mysql 

Docker 容器指令

  • 通过镜像运行一个容器:

    1
    docker run tomcat:8.0-jre8
  • 通过该方式运行的 tomcat 是不能直接被外部访问的,因为容器具有隔离性。直接通过 8080 端口访问容器内部的 tomcat,需要对宿主机端口与容器内的端口进行映射——第一个 8080 为宿主机端口,第二个 8080 为容器内的端口。外部访问 8080 端口就会通过映射访问容器内的 8080 端口

    1
    docker run -p 8080:8080 tomcat:8.0-jre8
  • 每次运行的容器都是相互独立的,所以同时运行多个 tomcat 容器并不会产生端口的冲突

  • 容器还能够以后台的方式运行,不占用终端

    1
    docker run -d -p 8080:8080 tomcat:8.0-jre8
  • 启动容器时默认会给容器一个名称,但也可以设置,容器名称必须是唯一:

    1
    docker run -d -p 8080:8080 --name tomcat01 tomcat:8.0-jre8
  • 容器的停止、重启指令:(可以通过容器的 id 启动,也可以通过容器的名称启动)

    1
    2
    3
    4
    docker start c2f5d78c5d1a
    docker restart c2f5d78c5d1a
    docker stop c2f5d78c5d1a
    docker kill c2f5d78c5d1a
  • 容器删除:(容器的 id 无需全部写出来,只需唯一标识)

    1
    docker rm d5b6c177c151
    • 删除所有容器,则可以使用组合指令:

      1
      docker rm -f $(docker ps -qa)
      • 先通过docker ps -qa查询出所有容器的 id,然后通过docker rm -f进行删除
  • 查看容器的运行日志:

    1
    docker logs 289cc00dc5ed
    • 显示的日志并不是实时的,若是想实时显示,需要使用-f参数(-t参数还能够显示日志的时间戳,通常与-f参数联合使用)

      1
      docker logs -ft 289cc00dc5ed
  • 查看容器内运行了哪些进程:

    1
    docker top 289cc00dc5ed
  • 将容器打包成一个镜像:

    1
    docker commit -m "描述信息" -a "镜像作者" tomcat01 my_tomcat:1.0
  • 将镜像备份出来

    1
    docker save my_tomcat:1.0 -o my-tomcat-1.0.tar
  • .tar格式的镜像加载到 Docker

    1
    docker load -i my-tomcat-1.0.tar
    1
    2
    3
    4
    5
    6
    7
    8
    root@centos-7 ~]# docker load -i my-tomcat-1.0.tar
    b28ef0b6fef8: Loading layer [==================================================>] 105.5MB/105.5MB
    0b703c74a09c: Loading layer [==================================================>] 23.99MB/23.99MB
    ......
    Loaded image: my_tomcat:1.0
    [root@centos-7 ~]# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    my_tomcat 1.0 79ab047fade5 7 minutes ago
  • 向 tomcat 容器中部署一个项目:通过docker cp指令能够将文件从 CentOS 复制到容器中。/usr/local/tomcat/webapps为容器的资源路径

    1
    docker cp ./test.html 289cc00dc5ed:/usr/local/tomcat/webapps
    1
    2
    3
    4
    5
    6
    [root@izrcf5u3j3q8xaz ~]# docker exec -it 289cc00dc5ed bash
    # 与容器进行交互,终端将会进入容器内部,执行的指令都将在容器中生效
    root@289cc00dc5ed:/usr/local/tomcat# cd webapps
    root@289cc00dc5ed:/usr/local/tomcat/webapps# ls
    test.html
    root@289cc00dc5ed:/usr/local/tomcat/webapps#
  • 将容器内的文件复制到 CentOS 中,反过来写即可:

    1
    docker cp 289cc00dc5ed:/usr/local/tomcat/webapps/test.html ./

Build Ship and Run

  • Build(构建镜像)
  • Ship(运输镜像):主机和仓库间运输
  • Run (运行镜像)
  • Docker 运行过程就是去仓库把镜像拉到本地,用一条命令把镜像运行起来变成容器

Docker 底层原理

虚拟化技术

  • Docker 容器虚拟化技术是基础

  • 虚拟化技术:

    虚拟化技术是一种资源管理技术,是将计算机的各种实体资源)(CPUopen in new window内存open in new window磁盘空间open in new window网络适配器open in new window等),予以抽象、转换后呈现出来并可供分割、组合为一个或多个电脑配置环境。由此,打破实体结构间的不可切割的障碍,使用户可以比原本的配置更好的方式来应用这些电脑硬件资源。这些资源的新虚拟部分是不受现有资源的架设方式,地域或物理配置所限制。一般所指的虚拟化资源包括计算能力和数据存储。

基于 LXC 虚拟容器技术

  • Docker 基于 LXC(Linux container- Linux 容器)虚拟容器技术

  • LXC:

    • Linux 软件容器,一种操作系统层虚拟化(Operating system–level virtualization)技术,Linux 内核容器功能的一个用户空间接口
    • 将应用软件系统打包成一个软件容器(Container),含应用软件本身的代码,以及所需要的操作系统核心和库
  • LXC 借助 Linux 内核中的 CGroup 功能和 namespace 实现的,为软件提供一个独立的操作系统运行环境

  • cgroup 和 namespace

    • namespace 是 Linux 内核用来隔离内核资源的方式

      • 通过 namespace 可以让一些进程只能看到与自己相关的一部分资源
      • 具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中
      • Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程,对其他 namespace 中的进程没有影响
    • CGroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组 (process groups) 所使用的物力资源 (如 cpu memory i/o 等等) 的机制

    • 对比:

      • 两者都是将进程进行分组
      • namespace 隔离进程组之间的资源,cgroup 是对一组进程进行统一的资源监控和限制