浅析K8s使用之Docker基础知识

前言

本文章旨在交流个人学习总结,结合网上部分资料和书籍,外加部分自己理解,因此难免有不当之处,欢迎指出交流。


要使用K8s首先需要简单了解Docker的相关知识(不需要特别精通),虽然K8s的容器实现不一定绑定Docker但是市面上,Docker的接受度比较高,而且博客有很多使用Docker部署的资料,因此我们采用了Docker作为K8s的运行时容器实现方式,本文简单解释一些Docker的主要概念,后面总结关于K8s相关基础知识。

基础概念


docker定义概述

Docker是一个开源的应用容器引擎,它允许开发者将应用及其依赖打包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似iPhone的app)。更重要的是,容器性能开销极低。

以下是Docker的一些主要特点和优势:

  1. 可移植性:Docker容器可以在任何Docker环境中运行,无论是开发、测试还是生产环境,都保持了一致性。
  2. 轻量级:Docker容器共享主机的内核,因此它们比虚拟机更加轻量级,启动速度更快。
  3. 隔离性:每个Docker容器都是一个独立的进程,并且拥有自己的文件系统、网络栈和进程空间,这确保了它们之间的隔离性。
  4. 版本控制:通过Dockerfile,开发者可以定义构建镜像的每一步,并轻松地跟踪和管理更改。
  5. 扩展性:Docker容器可以轻松地扩展和复制,以满足应用程序的负载需求。
  6. 简化部署:使用Docker,开发者可以构建一次应用程序,然后在任何Docker环境中运行它,这大大简化了部署过程。
  7. 安全性:Docker通过Linux内核的cgroup和namespace技术实现了资源的隔离和限制,提高了应用程序的安全性。

主要原理


Docker为支持上诉的特性,主要采用以下两种技术实现。

容器的两大原理,即cgroup(控制组)和命名空间(Namespace),是实现容器技术核心功能的关键机制。以下是对这两个原理的详细概述:

  • cgroup(控制组)

    cgroupLinux内核提供的一种机制,用于限制分配监控系统资源。它是容器技术实现资源隔离和管理的基础。cgroup的主要功能包括:

    1. 限制资源cgroup可以限制CPU、内存、磁盘I/O、网络带宽等系统资源的使用。通过设置cgroup的资源限制,可以确保每个cgroup中的进程不会超过分配的资源,从而实现资源的隔离和保护。
    2. 分配资源cgroup可以将系统资源划分为不同的组,每个组可以被分配不同的资源限制。这样,可以根据应用程序的需求将资源分配给不同的cgroup,实现对资源的有效利用和分配。
    3. 监控资源:cgroup提供了对资源使用情况的监控和统计功能。通过查询cgroup的状态和统计信息,可以了解每个cgroup使用的资源量,从而进行性能分析、故障排查和优化调整。
    4. 层次结构cgroup支持层次结构,可以创建父子关系的cgroup。这样,可以对整个系统或者某个组织单元进行资源划分和管理。父cgroup可以设置一些默认的资源限制,子cgroup可以继承或者覆盖这些限制,实现更灵活的资源管理。
    5. 动态调整cgroup允许在运行时动态调整资源限制。通过修改cgroup的参数,如CPU配额、内存限制等,可以实时调整资源分配,满足不同的业务需求。
  • cgroup(控制组)

    命名空间是Linux提供的一种机制,用于将全局系统资源隔离成一个个的独立空间。每个命名空间都有自己的进程、网络、文件系统等资源,因此不同的命名空间可以相互隔离,使得不同的进程或者容器运行在不同的环境,从而实现隔离性。命名空间的主要功能包括:

    1. 进程隔离:每个命名空间都有自己的进程ID空间,不同的命名空间中的进程无法直接通信和交互,实现了进程级别的隔离。
    2. 网络隔离:每个命名空间都有自己的网络栈和网络设备,不同的命名空间中的进程无法直接访问其他命名空间的网络资源,实现了网络级别的隔离。
    3. 文件系统隔离:每个命名空间都有自己的文件系统和挂载点,不同的命名空间中的进程无法直接访问其他命名空间的文件系统,实现了文件系统级别的隔离。

cgroup和命名空间是实现容器技术的两大原理。cgroup通过限制、分配和监控资源实现资源的隔离和管理,而命名空间则通过隔离系统资源实现不同进程或容器之间的隔离。这两种机制共同保证了容器技术的有效性和安全性。

镜像概述


  • 概述
    镜像由多个层组成,每层叠加之后,从外部看来就如一个独立的对象。镜像内部是一个精简的操作系统(OS),同时还包含应用运行所必须的文件和依赖包。

    简易的一个示意图:
    在这里插入图片描述

    上述是采用一个基于ubuntu 添加jdk8arthas功能的基础镜像jdk8-arthas,编译方式参考博客自己编译带arthas工具的jdk8镜像,先采用其部署一个demo应用,并通过环境变量方式设置jvm参数,方便在k8s等方式部署的时候可以设置java堆之类的jvm参数。主要简述镜像的分层系统设计,除开From的设置基础镜像外,每一个引起(FROM, RUN, COPY, ADD,等)或间接引起文件系统变化的都会新创建一个层,例如启动了一个脚本,脚本有编辑文件的操作均会新增镜像层次。

  • 镜像和容器的关系
    二者关系可以类比java的类和对象,其分别是一个静态模版和运行时的表现。
    在这里插入图片描述

  • COW机制(Copy-On-Write)
    Docker的Copy-On-Write(COW)机制是Docker实现容器与镜像之间关系的关键技术之一。

    COW机制的概述

    • 多个容器复用同一份原始镜像:当从同一个镜像启动多个容器时,这些容器在初始状态下是共享同一份原始镜像的。这意味着,如果没有对容器中的文件进行修改,那么这些容器实际上是直接访问原始镜像中的文件。
    • 修改时复制:当某个容器中的文件需要被修改时(例如,通过写入、删除或修改操作),Docker不会直接修改原始镜像,而是会为该容器创建一个新的文件系统层(称为“容器层”),并将需要修改的文件从原始镜像复制到这个新的容器层中。然后,对文件的修改将只在这个新的容器层中进行,而原始镜像保持不变。

    优势和影响

    • 节省存储空间:由于多个容器在初始状态下共享同一份原始镜像,因此可以节省大量的存储空间。只有当容器中的文件需要被修改时,才会额外占用存储空间。
    • 提高性能:由于读取操作通常比写入操作要快得多,因此通过共享原始镜像的读取操作,可以提高容器的启动速度和运行性能。
    • 易于管理和维护:由于容器层是基于原始镜像创建的,因此可以轻松地删除或恢复容器层,而不会影响到原始镜像或其他容器。此外,由于每个容器都有自己独立的容器层,因此可以独立地对每个容器进行管理和维护

    综上所述,通过采用这种非必要即复用的方式,降低了存储空间膨胀的风险和方便统一管理,一定层次上提高性能,同时为了支持隔离性又加入了修改时先复制的机制,又保证可以定制容器之间的特定化差异设置。

容器网络


通过docker network ls命令可以查看当前docker的网络:

NETWORK ID     NAME           DRIVER    SCOPE
df8e0aef3cdc   bridge         bridge    local
f505c383caaa   host           host      local

DockerCNM(Container Network Model,容器网络模型)libnetwork以及驱动是Docker网络架构中的核心概念,它们共同构成了Docker的网络基础。

  1. CNM(Container Network Model)

    • 概念CNM定义了构建容器虚拟化网络的模型,它规定了Docker网络的基础组成要素。
    • 组成要素
      • 沙盒(Sandbox):一个沙盒代表一个容器的网络运行环境,类似于一个隔离的网络命名空间,即是一个独立的网络栈。每个容器都有自己的沙盒,其中包含网络接口、IP地址、路由表等网络配置。沙盒确保容器之间的网络隔离。
      • 终端(Endpoint):一个终端是容器网络的终端点,用于处理容器的网络通信。每个容器连接到一个或多个终端,并通过终端进行网络数据包的接收和发送,即将终端连接到网络上。
      • 网络(Network):网络是802.1d网桥的软件实现,可以看作是需要交互的终端的集合。一个网络可以包含多个终端。
  2. libnetwork

    • 概念libnetworkCNM的开源实现,由Docker公司开发并维护。它是一个跨平台的网络库,用于Docker容器的网络管理。
    • 功能libnetwork实现了CNM定义的三个核心组件,即沙盒、终端和网络。除此之外,它还提供了本地服务发现、容器负载均衡、网络控制层与管理层功能等。
    • 特点
      • 可插拔:支持多种网络驱动程序,如bridgehostoverlay等,满足不同的网络需求。
      • 可扩展:支持网络插件机制,允许第三方开发者编写自定义的网络插件,以扩展和定制网络功能。
      • 动态配置:支持在容器运行时动态地添加、删除或修改网络配置。
  3. 驱动(Driver)

    • 概念:驱动是libnetwork的重要组成部分,它负责具体的网络实现。Docker支持多种网络驱动,每种驱动都提供了不同的网络模式和通信方式。
    • 常见驱动
      • Bridge驱动Docker默认网络驱动,它使用Linux网桥技术实现容器之间的通信,容器不指名网络的时候默认使用该网络。启动Docker即会创建名为docker0虚拟网卡(通过ifconfig指令可以查看)。该种方式的时候,Docker会为每个容器创建成对veth设备,一个挂到容器内部,一个挂载到docker0上面,从而实现了容器和其他容器或和外部机器的网络通信。

      • Host驱动:容器直接使用宿主机的网络命名空间,相当于容器与宿主机共享网络,因为不存在网络隔离和NAT转换,因此性能叫其他模式高,但是无法进行扩多个主机的容器覆盖网络,而且由于容器可以直接使用宿主机的网络Ip、端口接口等,会有一定的安全风险,且不能使用相同端口。这种模式下,由于各个容器的Ip相同且和宿主机共享端口,因此可以采用宿主机的IP+端口方式访问其他服务,就像访问同一个宿主机上的不同进程服务一样。

      • Overlay驱动:使用网络虚拟化技术,可以在多个Docker主机之间构建虚拟扩展网络VXLAN,实现跨主机的容器通信,该方式主要通过基于三层的IP网络创建虚拟的二层网络完成,即将二层的数据帧包封装在UDP数据包,借助IP协议进行传输,因为这种实现**,所有节点需要一个可以将封装数据帧到UDP数据包和解封装的设备即VTEP**,这个设备作为虚拟网络隧道的终端,同时添加了一个Br0的虚拟交换机,VTEP的一端连接到VXLAN,一端连接到交换机,各容器采用和网桥类似的做法,使用Veth连接到Br0,从而完成通信,传输过程中Br0作为二层交换机转发各个容器的数据帧,VTEP就可以将数据帧封装成UDP报文再借助IP协议传输,对端节点VTEP设备逆向解包。
        VXLAN覆盖网络示意图:
        在这里插入图片描述

        三层传输网络:
        在这里插入图片描述

      • Macvlan驱动
        这种驱动主要可以将容器接入现有的物理网络,通过设置于宿主机共同的网路,则通过该网络通信到网络汲取内其他主机,使用这种网络模式运行下的docker容器容器Ip和该网络中的其他机器是一个网络,因此需要预先考虑好网段划分,避免由于DHCP或者其他网络主机自定义Ip造成的网络冲突问题。这种方式主要实现原理是通过使用真实网卡的子接口创建的多个虚拟网卡(即可以有多个),虚拟网卡可以共享真实网卡的外部连接,但拥有自己独立的MAC地址和IP地址,容器通过接入虚拟网卡的网络实现多机通信。
        简易示意图:
        在这里插入图片描述

卷是作为容器需要持久化存储的时候进行的存储方式,现今容器最火热的运用就是进行微服务应用的集群部署,因为大多数微服务属于是无状态的,因此卷日常使用相对低频,但是有些场景,比如微服务落盘日志后,异步FileBeat采集上报,或者某个容器服务本身是必须要持久化保存的服务,如Docker仓库、数据库应用等。卷的支持是通过驱动方式实现,默认的Local实现可以实现实现本节点容器的卷挂载,当然在集群的场景下,网络卷的支持也是有的,可以通过三方插件实现(块、文件、对象存储)。但目前因为Docker一般是结合K8s使用,因此后续这块会在K8s简单使用中浅析。

后言

Docker和虚拟机在多个方面存在显著的差异。以下是它们之间的主要对比:

  1. 启动速度

    • Docker容器的启动是秒级别的,大量节约了开发、测试、部署的时间。
    • 虚拟机的启动通常需要几分钟,相对较慢。
  2. 性能损耗

    • Docker通过内核级虚拟化技术(namespaces及cgroups cpu、内存、磁盘I/O等)来提供容器的资源隔离与安全保障等,因此Docker相比传统虚拟机在运行同样应用的情况下性能损耗更少。
    • 虚拟机由于独立的Guest OS存在,在虚拟化过程中不得不占用一部分资源进行Guest OS的运行和管理,因此不可避免地带来了性能损耗。
  3. 系统利用率

    • Docker更轻量,Docker的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境,Docker运行的镜像数远多于虚拟机数量,对系统利用率非常高。
    • 虚拟机是完整的操作系统,运行多个虚拟机将占用更多的系统资源。
  4. 隔离性

    • 与虚拟机相比,Docker隔离性更弱,Docker属于进程之间的隔离,虚拟机可实现系统级别隔离。
    • 虚拟机提供了更好的隔离性,每个虚拟机都有自己独立的操作系统。
  5. 安全性

    • Docker的安全性相对较低,但可以通过设置安全策略来提高安全性。
    • 虚拟机由于具有独立的操作系统,因此在某些方面可能具有更高的安全性。
  6. 移植性

    • Docker的镜像提供了可移植性,可以轻松地在不同的机器和环境中部署。
    • 虚拟机虽然也可以迁移,但过程可能更复杂,需要考虑更多的兼容性问题。
  7. 资源需求

    • Docker容器共享宿主机的内核,因此它们不需要额外的操作系统开销,这使得Docker更加轻量级且资源高效。
    • 虚拟机需要为每个实例提供一个完整的操作系统环境,这增加了资源需求。
  8. 易用性和管理

    • Docker提供了简洁明了的命令行界面和API,使得容器的创建、启动和管理变得相对简单。
    • 虚拟机管理可能涉及更多的配置和设置,尤其是在涉及多个虚拟机时。

上诉特点概述了虚拟机和Docker容器化的主要区别,其中最重要的是,虚拟机通过虚拟化技术模拟了包括硬件在内的完整的计算机环境,且完整的操作系统意味着具备系统运行调度能力,因此在大多数使用场景和真实物理机没有区别,其内部可以安装各种应用、容器,而且虚拟化的硬件比如CPU,其在真实物理机上面,其实可以视为物理机上面运行的一个作业,因此会收到物理机作业调度的影响。而Docker由于其只包含了主要的指令没有完整的操作系统,更重要的是没有虚拟逻辑上的硬件设备,因此直接是使用宿主机的资源,简单验证容器内部通过free -h显示的是宿主机真实的内存资源,运行时整个容器表现为宿主机上面的一个进程,但是由于命名空间的隔离性,因此在内部看来可以视为一个概念上的节点。

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值