侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 285 篇文章
  • 累计创建 125 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

k8s入门教程-1:kubernetes(k8s)初步了解

孔子说JAVA
2022-04-04 / 0 评论 / 0 点赞 / 241 阅读 / 9,749 字 / 正在检测是否收录...

1、kubernetes介绍

image-1649668209027

kubernetes(以下简称k8s,k和s之间有8个字母),是一个全新的基于容器技术的分布式架构领先方案。它是谷歌十几年以来大规模应用容器技术的经验积累和升华的重要成果。确切地说,Kubernetes(k8s)是谷歌严格保密十几年的秘密武器–Borg的一个开源版本。Borg是谷歌的一个久负盛名的内部使用的大规模集群管理系统。它基于容器技术,目的是实现资源管理的自动化,以及跨多个数据中心的资源利用率的最大化。

  • 十几年以来,谷歌一直通过Borg系统管理着数量庞大的应用程序集群。由于谷歌员工都签署了保密协议,即便离职也不能泄露Borg的内部设计,所以外界一直无法了解关于它的更多信息。直到2015年4月,传闻许久的Borg论文伴随Kubernetes的高调宣传被谷歌首次公开,大家才得以了解它的更多内幕。正是由于站在Borg这个前辈的肩膀上,汲取了Borg过去十年间的经验与教训,所以Kubernetes(k8s)一经开源就一鸣惊人,并迅速称霸容器领域。

  • 如果我们的系统设计遵循了k8s的设计思想,那么就不必考虑传统的系统架构中的业务跟底层代码以及功能模块,不必枉费心思考虑负载均衡跟部署实施的问题。总之使用k8s提供的解决方案,不仅可以节省不少于30%的开发成本,还可以将精力集中于业务本身。而且由于k8s提供了强大的自动化机制,所以系统后期的运维成本跟难度会大幅度降低。

  • k8s是一个开放的开发平台。与J2EE不同,它不局限于任何一种编程语言,没有限定任何编程接口,所以不论用什么语言编写的服务,都可以被映射为k8s的Service(服务),并通过标准的TCP协议进行交互。此外,k8s平台对现有的编程语言、编程框架、中间件没有任何侵入性,因此现有的系统也很容易改造升级并迁移到k8s平台上。

  • k8s是一个完备的分布式系统支撑平台。k8s具有完备的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制。同时,k8s提供了完善的管理工具。

  • k8s构建在docker之上,提供应用部署、维护、扩展机制等功能,利用k8s能方便地管理跨机器运行容器化的应用。

近⼏年,k8s已经成为⾃有机房、云上⼴泛使⽤的容器编排⽅案,最⼴泛的使⽤⽅式是Kubernetes+Docker。从DevOps⼈员的⾓度,⼀方⾯⽤kubctl命令、k8s来操作集群,⼀方⾯在单机上⽤Docker命令来管理镜像、运⾏镜像。

  • 单独⽤Docker的情况,在⼀些公司的场景⾥⾯也是有的。⼀种场景是只分不合,把⼀台机器⽤Docker做资源隔离,但是不需要将多容器编排。单独⽤Kubernetes,下层不是Docker的情况,并不算很多。

2、kubernetes和Docker的关系

定义:

  • Docker是一个开源的应用容器引擎,开发者可以打包他们的应用及依赖到一个可移植的容器中,发布到流行的Linux机器上,也可实现虚拟化。
  • k8s是一个开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。

关系:

k8s和Docker的关系,简单来说,有互补,也有竞争。在⼀般的认知中,k8s和Docker是互补关系:Dockers属于下层–容器引擎;k8s属于上层–编排调度层。

  • Docker 源于Linux Container,可以将⼀台机器的资源分成N 份容器,做到资源的隔离,并将可运⾏的程序定义为标准的docker image;
  • k8s则可以把不同机器的每份容器进⾏编排、调度,组成分布式系统。

3、kubernetes出现的原因

image-1649670800531

“Docker镜像”的方式解决了应用打包和发布这一困扰业界多年的技术难题,大大降低了普通开发人员运维部署应用的门槛。正是因为解决了应用打包这个根本性的问题,才使得Docker很快就被广大开发/运维人员所接受,迅速成为炙手可热的技术,并在一定时间内引领了容器化技术发展的浪潮。

  • 但是Docker作为单一的容器技术工具并不能很好地定义容器的“组织方式”和“管理规范”,难以独立地支撑起生产级大规模容器化部署的要求。因此容器技术的发展就迅速走向了以Kubernetes为代表的“容器编排”的技术路线,而这也是为什么Docker容器没有直接在生产环境中大规模部署的关键原因。

Kubernetes容器编排技术可以很好地实现大规模容器的组织和管理,从而使容器技术实现了从“容器”到“容器云”的飞跃!

  1. 背景:Kubernetes是由Google与RedHat公司共同主导的开源“容器编排”项目,它起源于Google公司的Borg系统。所以它在超大规模集群管理方面的经验要明显优于其他容器编排技术,加上Kubernetes在社区管理方面的民主化,使得它很快打败了Docker公司推出的容器编排解决方案(Compose+Swarm),从而成为了容器编排领域事实上的标准。
  2. 功能:Kubernetes是一种综合的基于容器构建分布式系统的基础架构环境,它不仅能够实现基本的拉取用户镜像、运行容器,还可以提供路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力,而更重要的是Kubernetes可以按照用户的意愿和整个系统的规则,高度自动化的处理好容器之间的各种关系实现“编排”能力。
  3. 技术:Kubernetes的出现重新定义了微服务架构的技术方向,目前通常所说的“云原生”及“Service Mesh(服务网格)”等概念,很大程度上也是依赖于Kubernetes所提供的基础能力。

4、k8s主要功能及基本概念

4.1 k8s主要功能

  1. 使用Docker对应用程序包装、实例化。
  2. 以集群的方式运行、管理跨机器的容器。
  3. 解决Docker跨机器容器之间的通讯问题。
  4. Kubernetes的自我修复机制使得容器集群总是运行在用户期望的状态。

4.2 Kubernetes基本概念

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

名词 释义
集群(环境) 一个集群指容器运行所需要的云资源组合,关联了若干服务器节点、负载均衡、专有网络等云资源。
工作节点 工作节点是 Kubernetes 集群中承担工作负载的节点,可以是虚拟机也可以是物理机。工作节点承担实际的 Pod 调度以及与管理节点的通信等。一个工作节点上的服务包括 Docker 运行时环境、kubelet、Kube-Proxy 以及其它一些可选的 Addon 组件。
命名空间 命名空间为 Kubernetes 集群提供虚拟的隔离作用。Kubernetes 集群初始有 3 个命名空间,分别是默认命名空间 default、系统命名空间 kube-system 和 kube-public ,除此以外,管理员可以创建新的命名空间以满足需求。
Pod 容器镜像是一个轻量级的、独立的、可执行的软件包,它包含了运行它所需要的全部东西:代码、运行时间、系统工具、系统库、设置等等。Pod 是 Kubernetes 部署应用或服务的最小的基本单位。Pod可以是单个镜像,也可以是多个共享相同存储/网络的镜像,以及有关这些镜像如何交互的描述。Pod的内容总是共同定位以及共同调度,并在共享的context中运行。一个 Pod 封装多个应用容器(也可以只有一个容器)、存储资源、一个独立的网络 IP 以及管理控制容器运行方式的策略选项。
服务 Service 也是 Kubernetes 的基本操作单元,是真实应用服务的抽象,每一个服务后面都有很多对应的容器来提供支持,通过 Kube-Proxy 的 port 和服务 selector 决定服务请求传递给后端的容器,对外表现为一个单一访问接口,外部不需要了解后端如何运行,这给扩展或维护后端带来很大的好处。
工作负载 工作负载即Kubernetes对一组Pod的抽象模型,用于描述业务的运行载体,包括Deployment、Statefulset、Daemonset、Job、CronJob等多种类型。
Ingress 负载均衡器用于将你的应用程序从paas平台环境中公开,允许外部的访问。在Kubernetes的语言中,这个功能通常被称为Ingress。简而言之负载均衡器和Ingress扮演着相同的角色。
Deployment 无状态工作负载即 Kubernetes 中的“Deployments”,无状态工作负载支持弹性伸缩与滚动升级,适用于实例完全独立、功能相同的场景,如:nginx、wordpress 等
StatefulSet 有状态工作负载即 Kubernetes 中的“StatefulSets”,有状态工作负载支持实例有序部署和删除,支持持久化存储,适用于实例间存在互访的场景,如 ETCD、mysql-HA 等
DaemonSet 守护进程集即 Kubernetes 中的“DaemonSet”,守护进程集确保全部(或者某些)节点都运行一个 Pod 实例,支持实例动态添加到新节点,适用于实例在每个节点上都需要运行的场景,如 ceph、fluentd、Prometheus Node Exporter 等。
CronJob 定时任务即 kubernetes 中的“CronJob”,定时任务是按照指定时间周期运行的短任务。使用场景为在某个固定时间点,为所有运行中的节点做时间同步。
Job 普通任务即 Kubernetes 中的“Job”,普通任务是一次性运行的短任务,部署完成后即可执行。使用场景为在创建工作负载前,执行普通任务,将镜像上传至镜像仓库。
RKE RKE 全称是 Rancher Kubernetes Engine。可以通过 CLI 的方式独立于 Rancher 2.x 使用。可以在安装好 docker 的 linux 主机上,快速方便的搭建 Kubernetes 集群。在搭建生产可用的 Kubernetes 集群的工具里,RKE 的易用性应该是最好的。关于 RKE 和 Rancher 的关系,RKE 是 Rancher 2.x 中的一个重要组成部分,在 UI 上通过“自定义主机”创建的集群和通过“主机驱动”创建的集群,都是 Rancher Server 调用 RKE 模块来实现的。我们一般叫这种集群为 RKE 集群。英文文档和 Release Notes 里叫 Rancher-Launched Kubernetes cluster。
  • 表格中,集群(环境)为基本概念,RKE为Rancher概念,其余为Kubernetes 相关概念。

在K8s中,Service是分布式集群架构的核心,一个Service对象拥有如下关键特征。

  1. 拥有唯一指定名称(比如mysql-server)。
  2. 拥有一个虚拟IP(Cluster IP、Service IP 或 VIP)和端口号。
  3. 能够提供某种远程服务能力。
  4. 被映射到提供这种服务能力的一组容器应用上。

Service的服务进程目前都基于Socket通信方式对外提供服务,比如Redis、Memcachhe、MySQL、Web Server,或者是实现了某个具体业务的特定TCP Server进程。虽然一个Service通常由多个相关的服务进程提供服务,每个服务进程都有一个独立的Endpoint(IP+Port)访问点,但Kubernetes能够让我们通过Service(虚拟Cluster IP + Service Port)连接到指定的Service。

容器提供了强大的隔离功能,所以有必要把为Service提供服务的这组进程放入容器中进行隔离。为此,Kubernetes设计了Pod对象,将每个服务进程都包装到相应的Pod中,使其为在Pod中运行的一个容器(Container)

Kubernetes整体系统架构

image-1649668808034

Kubernetes在架构上主要由Master和Node两种类型的节点组成,这两种节点分别对应着控制节点和计算节点。其中Master即控制节点,是整个Kubernetes集群的大脑,主要负责编排、管理和调度用户提交的作业,并能根据集群系统资源的整体使用情况将作业任务自动分发到可用Node计算节点。

1)Master节点

image-1649668925910

Master节点为集群控制管理节点,所有的命令都经由master处理。主要由三个紧密协作的独立组件组合而成,它们分别是:

  1. kube-apiserver:是Kubernetes集群API服务的入口,主要提供资源访问操作、认证、授权、访问控制及API注册和发现等功能机制。
  2. kube-scheduler:负责Kubernetes的资源调度,能按照预定的调度策略将Pod调度到相应的机器上。
  3. kube-controller-manager:负责容器编排及Kubernetes集群状态的维护,例如故障检测、自动扩展、滚动更新等。

上述组件在工作状态下还会产生许多需要进行持久化的数据,这些数据会通过kube-apiserver处理后统一保存到Etcd存储服务中。所以从这个角度看kube-apiserver不仅是外部访问Kubernetes集群的入口,也是维护整个Kubernetes集群状态的信息中枢。

2)Node节点

image-1649669108259

Node节点是kubernetes集群的工作负载节点。Master为其分配工作,当某个Node宕机时,Master会将其工作负载自动转移到其他节点。

  • Node节点可动态增加到kubernetes集群中,前提是这个节点已经正确安装、配置和启动了上述的关键进程,默认情况下,kubelet会向Master注册自己,这也kubernetes推荐的Node管理方式。一旦Node被纳入集群管理范围,kubelet会定时向Master汇报自身的情况,以及之前有哪些Pod在运行等,这样Master可以获知每个Node的资源使用情况,并实现高效均衡的资源调度策略。如果Node没有按时上报信息,则会被Master判断为失联,Node状态会被标记为Not Ready,随后Master会触发工作负载转移流程。

Node节点最核心的部分就是kubelet组件。它的核心功能如下:

  1. 通过CRI(Container Runtime Interface)远程接口同容器运行时(如Docker)进行交互,对容器生命周期进行维护。其中CRI接口会定义了容器运行时的各项核心操作,例如启动容器所需的命令及参数等。
  2. 通过GRPC协议同Device Plugin插件交互,实现Kubernetes对宿主机物理设备的管理。
  3. 此外kubelet另一个重要的功能则是通过CNI(Container Networking Interface)来调用网络插件为容器配置网络,以及通过CSI(Container Storage Interface)和存储插件交互为容器配置持久化存储。

3)Pod

image-1649669532968

Pod是K8s最重要最基本的概念,是K8s中最基础的编排对象及最小的调度单元,也是Kubernetes实现容器编排的载体,其本质上是一组共享了某些系统资源的容器集合。每个Pod都会包含一个“根容器”,还会包含一个或者多个紧密相连的业务容器。

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

4)Label

image-1649670396618

Label是一个key=value的键值对,其中key与value由用户自己指定。可以附加到各种资源对象上,一个资源对象可以定义任意数量的Label。可以通过 LabelSelector(标签选择器)查询和筛选资源对象。

5)RC

image-1649670556275

Replication Controller(RC)声明某个Pod的副本数在任意时刻都符合某个预期值。定义包含如下:

  1. Pod期待的副本数(replicas)
  2. 用于筛选目标Pod的Label Selector
  3. 当Pod副本数小于期望时,用于新的创建Pod的模板template
  4. 通过改变RC里的Pod副本数量,可以实现Pod的扩容或缩容功能
  5. 通过改变RC里Pod模板中的镜像版本,可以实现Pod的滚动升级功能

5、k8s容器编排概述

处理任务之间的各种关系,实现容器编排是K8s的核心技术能力,也是其大规模流行的关键原因。那么容器编排到底是个什么概念?在K8s中是如何实现容器编排的呢?

  • 其实所谓容器编排,通俗点举例就是如果两个应用调用关系比较紧密,那么我们希望运行时将它们部署在同一台机器上,从而提升服务之间的通信效率。而能够支持自动将具有此类关系的应用,以容器的方式部署在同一台机器上的技术就是容器编排。

  • 当然,这里所说的紧密关系只是一种形象的说法,实际的技术场景中这种紧密关系可以被划分为很多类型,例如Web应用与数据库之间的访问关系、负载均衡和它后端服务之间的代理关系、门户应用与授权组件之间的调用关系等。

  • 而对于K8s来说,这样的关系描述显然还是过于具体,因为K8s的设计目标不仅仅是能够处理前面提到的所有类型的关系,还要能够支持未来可能出现的更多种类的关系。这就要求K8s要从更宏观地角度来定义任务之间的各种关系,并且能为将来支持更多种类的关系留有余地。

  • 具体来说,K8s是对容器间的访问进行了分类,如果这些应用之间需要非常频繁的交互和访问,或者它们之间存在直接通过本地文件进行信息交换的情况,那么在K8s中可以将这些容器划分为一个“Pod”,而Pod中的容器将共享同一个Network Namespace、同一组数据卷,从而实现高效率通信。

  • Pod是Kubernetes中最基础的编排对象,是Kubernetes最小的调度单元,也是Kubernetes实现容器编排的载体,其本质上是一组共享了某些系统资源的容器集合。在Kubernetes中围绕Pod可以延伸出其他核心概念,具体如下图所示:

image-1649670186581

如上图所示,在Kubernetes中Pod解决了容器间紧密协作(即编排)的问题,而Pod要实现一次启动多个Pod副本就需要Deployment这个Pod多实例管理器;而有了这样一组Pod后,我们又需要通过一个固定网络地址以负载均衡的方式访问它,于是又有了Service。

  • 而根据不同的编排场景Pod又衍生出描述一次性运行任务的Job编排对象、描述每个宿主机上必须且只能运行一个副本的守护进程服务DaemonSet、描述定义任务的CronJob编排对象、以及针对有状态应用的StatefulSet等多种编排对象。而这些编排对象正是Kubernetes定义容器间关系和形态的主要方法。

6、etcd

6.1 etcd概念

etcd是一个分布式键值对存储系统(键值存储仓库),用于配置共享和服务发现。etcd受Zookeeper与doozer启发而催生的项目。

  • etcd由coreos开发,内部采用 raft 协议作为一致性算法,用于可靠、快速地保存关键数据,并提供访问。通过分布式锁、leader选举和写屏障(write barriers),来实现可靠的分布式协作。etcd集群是为高可用、持久化数据存储和检索而准备。

etcd概念词汇:

  • Raft:etcd所采用的保证分布式系统强一致性的算法。
  • Node:一个Raft状态机实例。
  • Member: 一个etcd实例。它管理着一个Node,并且可以为客户端请求提供服务。
  • Cluster:由多个Member构成、可以协同工作的etcd集群。
  • Peer:对同一个etcd集群中另外一个Member的称呼。
  • Client: 向etcd集群发送HTTP请求的客户端。
  • WAL:预写式日志,etcd用于持久化存储的日志格式。
  • snapshot:etcd防止WAL文件过多而设置的快照,存储etcd数据状态。
  • Proxy:etcd的一种模式,为etcd集群提供反向代理服务。
  • Leader:Raft算法中,通过竞选而产生的、处理所有数据提交的节点。
  • Follower:竞选失败的节点作为Raft中的从属节点,为算法提供强一致性保证。
  • Candidate:当Follower超过一定时间接收不到Leader的心跳时转变为Candidate开始竞选。
  • Term:某个节点成为Leader到下一次竞选时间,称为一个Term。
  • Index:数据项编号。Raft中通过Term和Index来定位数据。

6.2 etcd架构

image-1649671135843

  • HTTP Server: 用于处理用户发送的API请求,以及其它etcd节点的同步与心跳信息请求。
  • Store:用于处理etcd支持的各类功能的事务,包括数据索引、节点状态变更、监控与反馈、事件处理与执行等等,是etcd对用户提供的大多数API功能的具体实现。
  • Raft:Raft强一致性算法的具体实现,是etcd的核心。
  • WAL:Write Ahead Log(预写式日志),是etcd的数据存储方式。除了在内存中存有所有数据的状态以及节点的索引以外,etcd就通过WAL进行持久化存储。在WAL中,所有的数据提交前都会事先记录日志。Snapshot是为了防止数据过多而进行的状态快照;Entry表示存储的具体日志内容。

通常,一个用户的请求发送过来,会经由HTTP Server转发给Store,以进行具体的事务处理。如果涉及到节点修改,则交给Raft模块进行状态变更、日志记录;然后,再同步给别的etcd节点,以确认数据提交;最后,进行数据提交,再次同步。

6.3 etcd优点

etcd作为一个受到ZooKeeper与doozer启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点:

  1. 简单:安装配置简单,而且提供了 HTTP API 进行交互,使用也很简单
  2. 安全:支持 SSL 证书验证
  3. 快速:根据官方提供的 benchmark 数据,单实例支持每秒 2k+ 读操作
  4. 可靠:采用 raft 算法,实现分布式系统数据的可用性和一致性

6.4 etcd存储

etcd的存储分为内部存储和持久化(硬盘)存储两部分。内存中的存储除了顺序化地记录所有用户对节点数据变更的记录外,还会对用户数据进行索引、建堆等方便查询的操作。而持久化则使用WAL进行记录存储。在k8s中,所有数据的存储以及操作记录都在etcd中进行存储,所以对于k8s集群来说,etcd是相当重要的,一旦故障,可能导致整个集群的瘫痪或者数据丢失。

  1. 在WAL体系中,所有的数据在提交之前都会进行日志记录。持久化存储的目录分为两个:snap和wal。snapshot相当于数据压缩,默认会将10000条wal操作记录merge成snapshot,节省存储,又保证数据不会丢失。
  2. WAL:存储所有事务的变化记录
  3. Snapshot:用于存放某一时刻etcd所有目录的数据

注意:由于etcd是负责存储,所以不建议搭建单点集群,如zookeeper一样,由于存在选举策略,所以一般推荐奇数个集群,如3,5,7。只要集群半数以上的结点存活,那么集群就可以正常运行,否则集群可能无法正常使用。

6.5 etcd使用案例

  • Kubernetes:将docker集群的配置信息存储到etcd中,用于服务发现和集群管理;etcd 的一致性对于正确安排和运行服务至关重要。Kubernetes API 服务器将群集状态持久化在 etcd 中。它使用etcd的 watch API监视集群,并发布关键的配置更改。
  • CoreOS的容器Linux: 在Container Linux上运行的应用程序,获得自动的不宕机 Linux 内核更新。容器Linux使用locksmith来协调更新。locksmith 在 etcd 上实现分布式信号量,确保在任何给定时间只有集群的一个子集重新启动。
  • cloudfoundry:使用etcd作为hm9000的应用状态信息存等。

6.6 应用场景

  • 场景一:服务发现(Service Discovery)
  • 场景二:消息发布与订阅
  • 场景三:负载均衡
  • 场景四:分布式通知与协调
  • 场景五:分布式锁、分布式队列
  • 场景六:集群监控与Leader竞选
0

评论区