zoukankan      html  css  js  c++  java
  • Kubernetes学习历程--了解Kubernetes和docker-1

    为什么我们需要kubernetes和docker?

      在过去,多数的应用都是大型单体应用,以单个进程或几个进程的方式,运行于几台服务器上,这些单体应用发布周期长,迭代不频繁。每个发布周期结束前,开发者都会把应用程序打包后发给运维团队,运维团队在处理部署、监控事宜,并在硬件发生故障之后手动迁移应用。

      在今天,大型单体应用被解耦成许多单个的,可独立运行的小组件,我们称之为微服务。它们可以被独立开发、部署、升级、伸缩,这使得我们可以对每一个微服务快速迭代,并且迭代与市场需求的速度保持一致。

    但是随着部署组件的增加和数据中心的增长,配置、管理并保持系统的运行变得越来越困难。如果我们想获得更高的资源利用率并控制硬件成本,把组件部署在什么地方变得越来越难以决策。

      所以我们需要一些自动化的措施,包括自动调度、配置、监管和故障处理。这正是Kubernetes的用武之地。

      单体应用的劣势:

      1.对于一个单体应用来说,即使是某个组件中一个小的修改,都需要重新部署整个应用。

      2.运行一个单体应用,通常需要一台能为整个应用提供足够资源的高性能服务器。为了应对日益剧增的系统负荷,我们要么从CPU、内存和其它系统资源扩容来对服务器做垂直拓展,要么增加更多的服务器做水平拓展,垂直拓展不需要对应用程序加以修改,但是烧钱。如果是水平拓展,就可能需要对应用程序代码做较大的改动,有时候甚至是不可行的。

    这迫使我们将大型单体应用拆解成多个可以独立部署的微服务组件。每个微服务组件以独立的进程运行,并通过简单且定义良好的接口(API)与其它的微服务器通信。

    微服务的劣势:

      1.当组件数量少时,那个组件部署在哪里完全不是个事儿,但是当组件数量有一定规模时,因为微服务以团队形式完成工作,需要找到彼此进行交流,所以部署微服务时,需要正确地配置所有的服务来确保作为一个单一系统进行运作,随着微服务数量不断增加,配置工作复杂且易错。

      2.微服务还带来了其他问题,比如因为跨了多个进程和机器,使得调试代码和定位异常调用变得困难。

      3.环境需求的差异。微服务结构被独立部署也被独立开发,因为它们的独立性,不同团队之间开发使用不同的组件,这导致了组件之间依赖的差异性,应用程序需要同一个库的不同版本是不可避免的,这可能会产生依赖冲突。

     部署的组件数量越大,满足这些组件的需求就越难。

     所以为应用程序提供一个一致的环境是个理想的选择。

    介绍容器技术

    在先了解kubernetes之前,我们先来了解一下容器,什么是容器?

      容器类似虚拟机,但开销小很多,容器允许你在同一台主机上面允许多个服务,并每个服务提供不同的环境,而且将它们相互隔离。

      一个容器里运行的服务实际上运行在宿主机的操作系统上,这不像虚拟机,进程是运行在不同的操作系统上的。

    容器与虚拟机的比较:

      1.容器更加轻量级,它允许在相同的硬件上运行更多数量的组件,主要是因为每个虚拟机都需要运行自己的一组系统进程,这就产生了除组件进程消耗外的额外计算资源损耗。

      2.运行在虚拟机中的应用程序会执行虚拟机的系统调用,然后虚拟机内核会通过管理程序在宿主机上的物理CPU执行x86指令,而多个容器则会完全执行运行在宿主机上的同一个内核的系统调用。

      3.虚拟机的主要好处是提供完全隔离的环境,因为每个虚拟机都运行在自己的内核上,而容器则是调用同一个内核,会有安全隐患。

      4.容器可以很快的被启动,而虚拟机因为都有自己的一组系统服务,需要消耗额外的时间。

      5.容器的文件系统是相互隔离的,而虚拟机的不是。

     

     那么问题来了, 容器这么棒,那是怎么实现的呢?

      有两个隔离机制可以用:

      1.第一个是linux的命名空间,它使每个进程只看到它自己的系统视图(文件、进程、网络接口、主机名等)

      2.第二个是linux控制组(cgroups)它限制了进程能使用的资源量(CPU、内存、网络带宽等。)

    1.用Linux的命名空间隔离进程

      默认情况下,每个LINUX系统都只有一个命名空间,所有系统资源(比如文件系统、用户ID、网络接口等)属于这一个命令空间。但是我们能创建额外的命名空间,并在它们之间组织资源。

      对一个进程而言,可以在其中一个命名空间中运行它。进程将能看到同一个命名空间下的资源。

      当然会存在多种类型的命名空间,所以一个进程不单单只属于一个命名空间,而属于每个类型的一个命名空间。

    存在以下类型的命名空间:

    Mount (mnt)

    Process ID (pid)

    Network (net)

    Inter-process communicaion (ipd)

    UTS

    User ID (user)

      每种命名空间都被用来隔离一组特定的资源。比方说,UTS命名空间决定了运行在命名空间里的进程能看见那些主机名和域名。

      同样地,一个进程属于什么Network命名空间决定了运行在进程里的应用程序能看见什么网络接口(每个网络接口属于一个命名空间,但是可以从一个命名空间转移到另一个命名空间)。每个容器都使用它自己的网络命名空间,因此每个容器都仅能看见它自己的一组网络接口。

    2.限制进程的可用资源

      另一个体现的隔离性就是限制容器能使用的系统资源,通过cgroups来实现。

      cgroups是一个Linux内核功能,它能被用来限制一个进程或是一组进程能使用的系统资源,一个进程的资源(CPU、内存、网络带宽)使用量不能超出被分配量。

     Docker的概念

      Docker是一个打包、分发和运行应用程序的平台,它允许将你的应用程序和应用程序所依赖的整个环境打包在一起。

      

    三个主要的概念构成了这种情形:

      镜像:Docker镜像里打包了应用程序和相关依赖环境,它包含应用程序可用的文件系统和其它元数据。

      镜像仓库:用于存放Docker镜像的一个镜像仓库,上传到仓库的镜像可以被拉取到另外一台电脑上运行,某些仓库是公开的,某些是私有的。

      容器:通常是一个linux容器,基于docker镜像被创建。一个运行中的容器是一个运行在docker宿主机上的一个进程,但它和主机以及其它docker容器进程都是隔离的,资源也是受限的。

    动作:构建、分发和运行docker镜像

     镜像层

      基于docker容器的镜像和虚拟机镜像的一个很大的不同是:容器镜像是有多层构成,它能在多个镜像之间共享和征用。如果某个已经被下载的容器镜像已经包含了后面下载镜像的某些层,那么后面下载的镜像就无须再下载这些层,有助于减少存储空间。

       当基于相同基础层的镜像被创建成两个容器时,它们就能够读取相同的文件。但是如果一个容器写入某些文件,另一个容器是无法看见文件的变更的。所以即使它们共享文件系统,但彼此也是互相隔离的。为什么?

      这是因为容器镜像层是只读的,容器运行时,一个新的可写层在镜像层之上被创建。容器中,进程写入位于底层的一个文件时,此文件的一个copy在顶层被创建,进程写的是copy层。

    Kubernetes介绍

      不应该错误地认为Kubernetes是一个专为Docker容器设计的容器编排系统,Kubernetes也支持其它类型的容器技术,Kubernetes的核心也远不止是编排容器。

    初衷:

      简化开发和管理,同时也提高了基础设施的利用率,当所在的组织足够庞大时,运行成千上万台机器哪怕一丁点的利用率提升都意味着你帮老板省了一大笔钱。所以开发这个系统的动机是如此浅显。

    深入浅出了解Kubernetes

      Kubernetes是一个软件系统,它允许你在其上很容易地部署和管理容器化的应用。

    Kubernetes的核心功能:

      

     开发者把一个应用列表提交到主节点,Kubernetes会将它们部署到集群的工作节点。组件被部署在那个节点对于开发者和系统管理员来说都不用关心。

    Kubernetes的好处:

    1.帮助开发者聚焦核心应用功能

      他们现在可以依赖Kubernetes来提供这些服务,包括服务发现、扩容、负载均衡、自恢复、甚至领导者的选举

    2.帮助运维团队获取更高的资源利用率

      Kubernetes能在任何时间迁移应用并通过混合和匹配应用来获得比手动调度高很多的资源利用率。

    Kubernetes集群架构

       一个Kubernetes由很多个节点组成,主要分为两类:

      1.主节点(MASTER),它承载了Kubernetes控制和管理整个集群系统的控制面板

      2.工作节点,他们运行用户实际部署的应用

     控制面板:

      控制面板用于控制集群并使它工作。它包含多个组件,组件可以运行在单个主节点上或者通过副本分别部署在多个主节点以确保高可用性。

      这些组件是:

      Kubernetes API服务器,通过它与其它控制面板组件通信

      Scheduler,它调度你的应用(为应用的每一个可部署组件分配一个工作节点)

      Controller Manager,它执行集群级别的功能,如复制组件、持续跟踪工作节点、处理失败节点

      etcd,一个可靠的分布式数据存储,它能持久化存储集群配置

    控制面板的组件持有并控制集群状态,但是它们不运行你的应用程序。这是由工作节点完成的。

    工作节点:

      工作节点就是运行容器化应用程序的机器。运行、监督和管理应用服务的任务是由以下组件实现的。

      Docker容器

      Kubelet,它与API服务器通信,并管理它所在节点的容器。

      Kubernetes Service Proxy(kube-proxy),它负责组件之间的负载均衡网络流量

     

    保持容器运行

      一旦应用程序运行起来,Kubernetes就会不断确认应用程序的部署情况与你提供的描述相匹配。例如:如果你指出你需要运行五个web服务器实例,那么Kubernetes将不多不少确保始终有五个web服务器运行,如果一个实例停止工作,比如宕机或者停止响应,Kubernetes就会自动重启它。

      同理,如果整个工作节点没了,Kubernetes将为在故障节点上运行的所有容器选择新节点,并在新选择的节点上运行它们。

    扩展副本数量

      当应用程序运行时,可以决定要增加或者减少副本量,可以把决定最佳副本数的工作交给Kubernetes。它可以根据实时指标(如CPU负载、内存消耗、每秒查询应用程序公开的任何其它指标)自动调整副本数。

    命中移动目标

      Kubernetes可能在需要的时候在集群中迁移你的容器。当它们运行的节点失败时,或者为了给其它容器腾地方而移除容器时,就会发生这种情况,如果容器正在对外提供服务,那么当容器在集群内频繁被调度时,它们该如何正确使用这个容器呢?当这些容器被复制并分布在整个集群中时,客户端如何连接到提供服务的容器呢?

        可以告诉Kubernetes那些容器提供相同的服务,而Kubernetes将通过一个静态IP地址暴露所有这些容器,并将该地址暴露给集群中所有运行的应用程序。

    总结,使用Kubernetes的好处

      1.简化应用程序的部署

       (1)不需要了解组成集群的服务器,实际上,现在所有节点都是一组等待应用程序使用它们的计算资源。

       (2)更好的利用硬件:

        当你告诉Kubernetes需要运行自己的应用程序时,它会根据应用程序的资源需求描述符和每个节点上的可用资源做对比,选择最适合的节点运行你的应用程序。

       (3)允许应用程序在任何时候都可在集群中自由迁移,而不用绑定在一个特定的集群节点上,确保节点的硬件资源得到更好的利用。

      2.健康检查和自修复

         Kubernetes会监控节点和运行在上面的应用程序,一旦节点出现故障时能将应用重新部署到其它节点上。这让运维团队不必费心于迁移应用组件,而是专注于修复节点本身并将其重新送回可用资源池中。

      3.自动扩容

         Kubernetes监视每个应用程序使用的资源,并不断调整每个应用程序的运行实例数量,如果Kubernetes部署在云设施上,添加额外节点将变得像喝水一样简单,Kubernetes甚至可以根据部署的应用程序需要,自动地将整个集群规模放大或缩小。

      4.简化应用部署

         应用程序的开发和生产流程中都运行在同一个环境中,这对发现bug并迅速解决有很大影响。

      还有一个好处:

         当应用的新版本发布时,Kubernetes会自动检测一个应用的新版本是否有问题,有就立即停止其滚动更新,这有利于应用的持续交付,对整个组织都有好处。

        

  • 相关阅读:
    骗分
    【WC2016】鏖战表达式
    emacs配置
    UOJ NOI Round #4补题
    调整法
    IOC(控制反转)与DI(依赖注入)的个人理解。
    WPF进阶技巧和实战06-控件模板
    WPF进阶技巧和实战05-样式与行为
    WPF进阶技巧和实战04-资源
    WPF进阶技巧和实战03-控件(2-特殊容器)
  • 原文地址:https://www.cnblogs.com/PurpleRain98/p/13110901.html
Copyright © 2011-2022 走看看