Docker基本概念

什么是Docker

Docker是使用 Google公司推出的Go 语言进行开发实现,基于Linux 内核的cgroup、namespace、以及AUFS类的Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术,由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

Docker在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得Docker技术比虚拟机技术更为轻便、快捷。下面的图片比较了Docker和传统虚拟化方式的不同之处。

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程。

而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比 传统虚拟机更为轻便。

introduction-1
introduction-2

为什么要使用Docker

作为一种新兴的虚拟化方式,Docker跟传统的虚拟化方式相比具有众多的优势。

  • 更高效的利用系统资源:
    由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高。

  • 更快速的启动时间:

    Docker容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间

  • 一致的运行环境:

    Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现这段代码在我机器上没问题啊这类问题。

  • 持续交付和部署:

    Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。可以通过Dockerfile来进行镜像构建,结合持续集成系统进行集成测试、自动部署。

  • 更轻松的迁移:

    由于Docker确保了执行环境的一致性,使得应用的迁移更加容易,而不用担心运行环境的变化导致应用无法正常运行的情况。

  • 更轻松的维护和扩展:

    Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker团队提供了一大批高质量的官方镜像,既可以直接使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个

基本概念

镜像Image

镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含任何动态数据,其内容在构建之后也不会被改变。

Docker设计时,将其设计为分层存储的架构。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除 前一层的文件,而是仅在当前层标记为该文件已删除。分层存储的特征使得镜像的复用、定制变的更为容易。

容器Container

镜像和容器的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。容器也具备分层存储的特征。

Kubernetes

什么是Kubernetes

Kubernetes是一个完备的分布式系统支撑平台。Kubernetes具有完备的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建的智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制,以及多粒度的资源配额管理能力。同时,Kubernetes提供了完善的管理工具,这些工具涵盖了包括开发、部署测试、运维监控在内的各个环节。因此,Kubernetes是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式的完备的分布式系统开发和支撑平台。

Kubernetes英文中字母K和S中间有8个英文,所以也简称为K8S。

为什么要使用Kubernetes

  • 轻装上阵地开发复杂系统

  • 可以全面拥抱微服务架构

  • 可以随时随地迁移系统

  • 拥有横向弹性扩容机制

Kubernetes基本概念

Kubernetes中的大部分概念如Node、Pod、Replication Controller、Service等都可以被看作一种资源对象,几乎所有资源对象都可以通过Kubernetes提供的kubectl工具(或者API编程调用)执行增、删、改、查等操作并将其保存在etcd中持久化存储。从这个角度来看,Kubernetes其实是一个高度自动化的资源控制系统,它通过跟踪对比etcd库里保存的“资源期望状态”与当前环境中的“实际资源状态”的差异来实现自动控制和自动纠错的高级功能。

Master

Kubernetes里的Master指的是集群控制节点,在每个Kubernetes集群里都需要有一个Master来负责整个集群的管理和控制,基本上Kubernetes的所有控制命令都发给它,它负责具体的执行过程,我们后面执行的所有命令基本都是在Master上运行的。Master通常会占据一个独立的服务器(高可用部署建议用3台服务器),主要原因是它太重要了,是整个集群的“首脑”,如果它宕机或者不可用,那么对集群内容器应用的管理都将失效。

Master上运行着以下关键进程:

  • Kubernetes API Server(kube-apiserver)

    提供了HTTP Rest接口的关键服务进程,是Kubernetes里所有资源的增、删、改、查等操作的唯一入口,也是集群控制的入口进程。

  • Kubernetes Controller Manager(kube-controller-manager)

    Kubernetes里所有资源对象的自动化控制中心,可以将其理解为资源对象的大总管

  • Kubernetes Scheduler(kube-scheduler)

    负责资源调度(Pod调度)的进程,相当于公交公司的调度室,在Master上通常还需要部署etcd服务,因为Kubernetes里的所有资源对象的数据都被保存在etcd中。

Node

除了Master,Kubernetes集群中的其他机器被称为Node,在较早的版本中也被称为Minion。与Master一样,Node可以是一台物理主机,也可以是一台虚拟机。Node是Kubernetes集群中的工作负载节点,每个Node都会被Master分配一些工作负载(Docker容器),当某个Node宕机时,其上的工作负载会被Master自动转移到其他节点上。

在每个Node上都运行着以下关键进程:

  • kubelet

    负责Pod对应的容器的创建、启停等任务,同时与Master密切协作,实现集群管理的基本功能。

  • kube-proxy

    实现Kubernetes Service的通信与负载均衡机制的重要组件。

  • Docker Engine(docker)

    Docker引擎,负责本机的容器创建和管理工作。

Node可以在运行期间动态增加到Kubernetes集群中,前提是在这个节点上已经正确安装、配置和启动了上述关键进程,在默认情况下kubelet会向Master注册自己,这也是Kubernetes推荐的Node管理方式。

一旦Node被纳入集群管理范围,kubelet进程就会定时向Master汇报自身的情报,例如操作系统、Docker版本、机器的CPU和内存情况,以及当前有哪些Pod在运行等,这样Master就可以获知每个Node的资源使用情况,并实现高效均衡的资源调度策略。

而某个Node在超过指定时间不上报信息时,会被Master判定为“失联”,Node的状态被标记为不可用(Not Ready),随后Master会触发“工作负载大转移”的自动流程。

我们可以执行下述命令查看在集群中有多少个Node
introduction-3

然后可以通过kubectl describe node <node_name>查看某个Node的详细信息:
introduction-4

Pod

Pod是Kubernetes最重要的基本概念,下图所示是Pod的组成示意图,我们看到每个Pod都有一个特殊的被称为根容器的Pause容器。Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器。

introduction-5

为什么Kubernetes会设计出一个全新的Pod的概念并且Pod有这样特殊的组成结构?

原因之一:在一组容器作为一个单元的情况下,我们难以简单地对“整体”进行判断及有效地行动。比如,一个容器死亡了,此时算是整体死亡么?是N/M的死亡率么?引入业务无关并且不易死亡的Pause容器作为Pod的根容器,以它的状态代表整个容器组的状态,就简单、巧妙地解决了这个难题。

原因之二:Pod里的多个业务容器共享Pause容器的IP,共享Pause容器挂接的Volume,这样既简化了密切关联的业务容器之间的通信问题,也很好地解决了它们之间的文件共享问题。

Kubernetes为每个Pod都分配了唯一的IP地址,称之为Pod IP,一个Pod里的多个容器共享Pod IP地址。Kubernetes要求底层网络支持集群内任意两个Pod之间的TCP/IP直接通信,这通常采用虚拟二层网络技术来实现,例如Flannel、Open vSwitch

因此我们需要牢记一点:在Kubernetes里,一个Pod里的容器与另外主机上的Pod容器能够直接通信,同一个Pod里的容器之间仅需通过localhost就能互相通信。

Pod、容器与Node的关系:
introduction-6

一个Pod中的应用容器共享同一组资源:

  • PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID

  • 网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围

  • IPC命名空间:Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信

  • UTS命名空间:Pod中的多个容器共享一个主机名

  • Volumes(共享存储卷):Pod中的各个容器可以访问在Pod级别定义的Volumes

Pod的生命周期通过Replication Controller来管理;通过模板进行定义,然后分配到一个Node上运行,在Pod所包含容器运行结束后,Pod结束。

Kubernetes为Pod设计了一套独特的网络配置,包括:为每个Pod分配一个IP地址,使用Pod名作为容器间通信的主机名等。

Label

Label(标签)是Kubernetes系统中另外一个核心概念。一个Label是一个key=value的键值对,其中key与value由用户自己指定。Label可以被附加到各种资源对象上,例如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上。Label通常在资源对象定义时确定,也可以在对象创建后动态添加或者删除。

我们可以通过给指定的资源对象捆绑一个或多个不同的Label来实现多维度的资源分组管理功能,以便灵活、方便地进行资源分配、调度、配置、部署等管理工作。

Label相当于我们熟悉的“标签”。给某个资源对象定义一个Label,就相当于给它打了一个标签,随后可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,Kubernetes通过这种方式实现了类似SQL的简单又通用的对象查询机制。

Service

在Kubernetes的世界里,虽然每个Pod都会被分配一个单独的IP地址,但这个IP地址会随着Pod的销毁而消失,这就引出一个问题:如果有一组Pod组成一个集群来提供服务,那么如何来访问它呢?Service

一个Service可以看作一组提供相同服务的Pod的对外访问接口,Service作用于哪些Pod是通过Label Selector来定义的。

  • 拥有一个指定的名字(比如my-mysql-server)

  • 拥有一个虚拟IP(Cluster IP、Service IP或VIP)和端口号,销毁之前不会改变,只能内网访问

  • 能够提供某种远程服务能力

  • 被映射到了提供这种服务能力的一组容器应用上

  • 如果Service要提供外网服务,需指定公共IP和NodePort,或外部负载均衡器

Service可以通过配置NodePort,在Node上打开一个主机的真实端口,这样,能够访问Node的客户端就能通过这个端口访问到内部的Service

Replication Controller

Replication Controller(简称RC)是Kubernetes系统中的核心概念之一,简单来说,它其实定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值

  • 目标Pod的定义
  • 目标Pod需要运行的副本数量
  • 要监控的目标Pod标签(Label)

Kubernetes通过RC中定义的Label筛选出对应的Pod实例,并实时监控其状态和数量,如果实例数量少于定义的副本数量(Replicas),则会根据RC中定义的Pod模板来创建一个新的Pod,然后将此Pod调度到合适的Node上启动运行,直到Pod实例数量达到预定目标。

最后更新: 2020年05月26日 12:00

原始链接: https://midkuro.gitee.io/2020/05/21/kubernetes-introduction/

× 请我吃糖~
打赏二维码