加载中...

Kubernetes系列(一)--核心概念与专业术语


1. 认识Kubernetes

1.1 应用部署方式演变

在部署应用程序的方式上,主要经历了三个时代:

  • 传统部署:互联网早期,会直接将应用程序部署在物理机上

    优点:简单,不需要其它技术的参与

    缺点:不能为应用程序定义资源使用边界,很难合理地分配计算资源,而且程序之间容易产生影响

  • 虚拟化部署:可以在一台物理机上运行多个虚拟机,每个虚拟机都是独立的一个环境

    优点:程序环境不会相互产生影响,提供了一定程度的安全性

    缺点:增加了操作系统,浪费了部分资源

  • 容器化部署:与虚拟化类似,但是共享了操作系统

    优点:

    可以保证每个容器拥有自己的文件系统、CPU、内存、进程空间等

    运行应用程序所需要的资源都被容器包装,并和底层基础架构解耦

    容器化的应用程序可以跨云服务商、跨Linux操作系统发行版进行部署

容器化部署方式给带来很多的便利,但是也会出现一些问题,比如说:

  • 一个容器故障停机了,怎么样让另外一个容器立刻启动去替补停机的容器
  • 当并发访问量变大的时候,怎么样做到横向扩展容器数量

这些容器管理的问题统称为容器编排问题,为了解决这些容器编排问题,就产生了一些容器编排的软件:

  • Swarm:Docker自己的容器编排工具
  • Mesos:Apache的一个资源统一管控的工具,需要和Marathon结合使用
  • Kubernetes:Google开源的的容器编排工具

1.2 什么是Kubernetes?

Kubernetes官方文档:https://kubernetes.io/zh-cn/docs/home/

Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,方便进行声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统,其服务、支持和工具的使用范围广泛。

Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。K8s 这个缩写是因为 K 和 s 之间有 8 个字符的关系。

1.3 为什么需要Kubernetes?

kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:

  • 自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器
  • 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
  • 自动部署和回滚:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
  • 服务发现和负载均衡:服务可以通过自动发现的形式找到它所依赖的服务,如果一个服务起动了多个容器,能够自动实现请求的负载均衡
  • 存储编排:可以根据容器自身的需求自动创建存储卷
  • 机密和配置管理
  • 批处理

2. 集群架构与组件

2.1 kubernetes组件

一个kubernetes集群主要是由**控制节点(master)、工作节点(node)**构成,每个节点上都会安装不同的组件。

Kubernetes架构图

2.1.1 控制面板组件(Control Plane Components)

Kubernetes组件:https://kubernetes.io/zh-cn/docs/concepts/overview/components/

管理集群的整体状态(这些组件都在master节点):

  • kube-apiserver

    公开 Kubernetes HTTP API 的核心组件服务器

    基于REST风格开放k8s接口的服务。

  • kube-controller-manager

    运行控制器来实现 Kubernetes API 行为。

    控制器管理器:管理各个类型的控制器,针对k8s中的各种资源进行管理。

    这些控制器包括:

    • 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应。
    • 任务控制器(Job Controller):监测代表一次性任务的Job对象,然后创建Pods来运行这些任务直至完成。
    • 端点分片控制器(EndpointSlice Controller):填充端点分片(EndpointSlice)对象(以提供Service和Pod之间的连接)。
    • 服务账号控制器(ServiceAccount Controller):为新的命名空间创建默认的服务账号(ServiceAccount)。
  • cloud-controller-manager (optional)

    与底层云驱动集成

    云控制管理器:第三方云平台提供的控制器API对接管理功能。

  • kube-scheduler

    查找尚未绑定到节点的 Pod,并将每个 Pod 分配给合适的节点

    调度器:负责将 Pod 基于一定算法,将其调用到更合适的节点(服务器)上。

  • etcd

    具备一致性和高可用性的键值存储,用于所有 API 服务器的数据存储

    理解为k8s的数据库,键值类型存储的分布式数据库,提供了基于Raft算法实现自主的集群高可用。

    新老版本存储区别:老版本(基于内存),新版本(持久化存储)

2.1.2 节点组件

在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行时环境:

  • kubelet

    确保 Pod 及其容器正常运行。

    负责 Pod 的生命周期、存储、网络。

  • kube-proxy(可选)

    维护节点上的网络规则以实现 Service 的功能。

    网络代理,负责 Service 的服务发现、负载均衡(4层负载)。(仅仅只是内部网络访问)

  • 容器运行时(Container runtime)

    负责运行容器的软件,阅读容器运行时以了解更多信息。

    容器运行时环境:docker、containerd、CRI-O

2.1.3 附加组件(Addons)

插件扩展了 Kubernetes 的功能。一些重要的例子包括:

  • DNS

    集群范围内的 DNS 解析

    负责为整个集群提供DNS服务

  • Web 界面(Dashboard)

    通过 Web 界面进行集群管理

  • 容器资源监控

    用于收集和存储容器指标

  • 集群层面日志

    用于将容器日志保存到中央日志存储

  • Ingress Controller

    为服务提供外网入口

2.2 分层架构

生态系统

接口层

管理层

系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态 Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)。

应用层

部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS 解析等)

核心层

Kubernetes最核心的功能,对外提供 API 构建高层的应用,对内提供插件式应用执行环境。

3. 核心概念与专业术语

3.1 服务的分类

3.1.1 无状态应用

无状态应用:不会对本地环境产生任何依赖,例如不会存储数据到本地磁盘

代表应用:Nginx、Apache

优点:对客户端透明,无依赖关系,可以高效实现扩容、迁移

缺点:不能存储数据,需要额外的数据服务支撑

3.1.2 有状态应用

有状态应用:会对本地环境产生任何依赖,例如需要存储数据到本地磁盘

代表应用:MySQL、Redis

优点:可以独立存储数据,实现数据管理

缺点:集群环境下需要实现主从、数据同步、备份、水平扩容复杂

3.2 资源和对象

3.2.1 资源的分类

3.2.1.1 元数据型

元空间(元数据级别的资源),每一个资源都可以使用元空间的数据。

  • Horizontal Pod Autoscaler(HPA)

    Horizontal Pod Autoscaler(HPA)介绍
    
    Pod自动扩容:可以根据CPU使用率或自定义指标(metrics)自动对Pod进行扩/缩容。
    - 控制管理器每隔30s(可以通过-horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况
    - 支持三种metrics类型
      - 预定义metrics(比如Pod的CPU)以利用率的方式计算
      - 自定义的Pod metrics,以原始值(raw value)的方式计算
      - 自定义的object metrics
    - 支持两种metrics查询方式:Heapster和自走义的RESTAPI
    - 支持多metrics
        
  • PodTemplate

    Pod Template 是关于 Pod 的定义,但是被包含在其他的Kubernetes对象中(例如 Deployment、StatefulSet、Daemonset等控制器)。控制器通过 Pod Template 信息来创建Pod。

  • LimitRange

    可以对集群内 Request 和 Limits 的配置做一个全局的统一的限制,相当于批量设置了某一个范围内(某个命名空间)的 Pod的资源使用限制。

3.2.1.2 集群

集群级别的资源,作用于集群之上,集群下的所有资源都可以共享使用。

  • Namespace

  • Node

    不像其他的资源(如 Pod 和 Namespace),Node 本质上不是Kubernetes 来创建的,Kubernetes 只是管理 Node上的资源。虽然可以通过 Manifest 创建一个Node对象(如下json 所示)但 Kubernetes 也只是去检查是否真的是有这么一个 Node,如果检查失败,也不会往上调度 Pod。

  • ClusterRole

  • ClusterRoleBinding

    根据名字可知只能绑定到集群角色级别。

3.2.1.3 命名空间(重点关注的地方)

命名空间级别的资源,通常只能在该命名空间范围内使用。

  • 工作负载型

    Pod
    
    Pod(容器组)是 Kubernetes 中最小的可部署单元。一个Pod(容器组)包含了一个应用程序容器(某些情况下是多个容器)、存储资源、一个唯一的网络 IP 地址、以及一些确定容器该如何运行的选项。Pod 容器组代表了 Kubernetes 中一个独立的应用程序运行实例,该实例可能由单个容器或者几个紧耦合在一起的容器组成。
    Docker 是 Kubernetes Pod 中使用最广泛的容器引擎;
    Kubernetes Pod 同时也支持其他类型的容器引擎。
    Kubernetes 集群中的 Pod 存在如下两种使用途径:
    - 一个 Pod 中只运行一个容器。"one-container-per-pod"是Kubernetes 中最常见的使用方式。此时,您可以认为Pod容器组是该容器的 wrapper,Kubernetes 通过 Pod 管理容器,而不是直接管理容器。
    - 一个 Pod 中运行多个需要互相协作的容器。您可以将多个紧密耦合、共享资源且始终在一起运行的容器编排在同一个Pod 中。
        
    • 副本(replicas)
      
      先引入“副本”的概念——一个 Pod 可以被复制成多份,每一份可被称之为一个“副本”,这些“副本”除了一些描述性的信息(Pod的名字、uid 等)不一样以外,其它信息都是一样的,譬如Pod内部的容器、容器数量、容器里面运行的应用等的这些信息都是一样的,这些副本提供同样的功能。
      Pod 的“控制器”通常包含一个名为“replicas”的属性。“replicas”属性则指定了特定 Pod 的副本的数量,当当前集群中该 Pod 的数量与该属性指定的值不一致时,k8s会采取一些策略去使得当前状态满足配置的要求。
          
    • 控制器

      • 适用于无状态服务

        • ReplicationController(RC) (弃用)

        • ReplicaSet(RS)

          帮助我们动态更新 Pod 的副本数,可以通过 selector 来选择对哪些 Pod 生效(RC不支持selector)

        • Deployments(常用,重点)

          针对RS的更高层次的封装,提供了更丰富的部署相关的功能。

          比如:创建 Replica Set/Pod、滚动升级/回滚、平滑扩容和缩容、暂停与恢复Deployment

      • 适用有状态服务

        StatefulSet 是用来管理有状态应用的工作负载 API 对象。

        主要特点:

        • 稳定的持久化存储
        • 稳定的网络标志
        • 有序部署,有序扩展
        • 有序收缩,有序删除

        组成:

        • Headless Service(对于有状态服务的DNS管理)
        • volumeClaimTemplate(用于创建持久化卷的模板)

        注意事项:

        • 所有Pod的Volume必须使用PersistentVolume或者是管理员事先创建好
        • 为了保证数据安全,删除Statefulset时不会删除Volume
        • StatefulSet需要一个Headless Service 来定义 DNSdomain,需要在 StatefulSet 之前创建好
      • 守护进程

        Daemonset 保证在每个Node上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。典型的应用包括:

        • 日志收集,比如 fuentd,logstash等
        • 系统监控,比如 Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond 等
        • 系统程序,比如 kube-proxy,kube-dns,glusterd,ceph 等
      • 任务/定时任务

        • Job:一次性任务,运行完成后Pod销毁,不再重新启动新容器。
        • CronJob:CronJob是在Job基础上加了定时功能。
  • 服务发现

    • Service:实现 k8s 集群内部网络调用、负载均衡(四层负载)。
    • Ingress:Ingress实现将 k8s 内部服务暴露给外网访问的服务。
  • 存储

    • Volume:数据卷,共享 Pod 中容器使用的数据。用来存放持久化的数据,比如数据库数据。

    • CSI:Container Storage Interface 是由来自 Kubernetes、Mesos、Docker 等社区成员联合制定的一个行业标准接口规范,旨在将任意存储系统暴露给容器化应用程序。

      CSI规范定义了存储提供商实现 CSI 兼容的 Volume Plugin 的最小操作集和部署建议。CSI 规范的主要焦点是声明 Volume Plugin必须实现的接口。

  • 特殊类型配置

    • ConfigMap
    • Secret
    • DownwardAPI
  • 其他

    • Role
    • RoleBinging

3.2.2 资源清单

参数名 类型 字段说明
apiVersion String K8S APl 的版本,可以用 kubectl api versions 命令查询
kind String yam 文件定义的资源类型和角色
metadata Object 元数据对象,下面是它的属性
metadata.name String 元数据对象的名字,比如 pod 的名字
metadata.namespace String 元数据对象的命名空间
Spec Object 详细定义对象
spec.containers[] list 定义 Spec 对象的容器列表
spec.containers[].name String 为列表中的某个容器定义名称
spec.containers[].image String 为列表中的某个容器定义需要的镜像名称
spec.containers[].imagePullPolicy string 定义镜像拉取策略,有 Always、Never、IfNotPresent 三个值可选
- Always(默认):意思是每次都尝试重新拉取镜像
- Never:表示仅适用本地镜像
- IfNotPresent:如果本地有镜像就使用本地镜像,没有就拉取在线镜像。
spec.containers[].command[] list 指定容器启动命令,因为是数组可以指定多个,不指定则使用镜像打包时使用的启动命令。
spec.containers[].args[] list 指定容器启动命令参数,因为是数组可以指定多个。
spec.containers[].workingDir string 指定容器的工作目录
spec.containers[].volumeMounts[] list 指定容器内部的存储卷配置
spec.containers[].volumeMounts[].name string 指定可以被容器挂载的存储卷的名称
spec.containers[].volumeMounts[].mountPath string 指定可以被容器挂载的存储卷的路径
spec.containers[].volumeMounts[].readOnly string 设置存储卷路径的读写模式,ture 或者 false,默认是读写模式
spec.containers[].ports[] list 指定容器需要用到的端口列表
spec.containers[].ports[].name string 指定端口的名称
spec.containers[].ports[].containerPort string 指定容器需要监听的端口号
spec.containers[].ports[].hostPort string 指定容器所在主机需要监听的端口号,默认跟上面 containerPort 相同,注意设置了 hostPort 同一台主机无法启动该容器的相同副本(因为主机的端口号不能相同,这样会冲突)
spec.containers[].ports[].protocol string 指定端口协议,支持 TCP 和 UDP,默认值为 TCP
spec.containers[].env[] list 指定容器运行前需设置的环境变量列表
spec.containers[].env[].name string 指定环境变量名称
spec.containers[].env[].value string 指定环境变量值
spec.containers[].resources Object 指定资源限制和资源请求的值(这里开始就是设置容器的资源上限)
spec.containers[].resources.limits Object 指定设置容器运行时资源的运行上限
spec.containers[].resources.limits.cpu string 指定 CPU 的限制,单位为 Core 数,将用于 docker run –cpu-shares 参数
spec.containers[].resources.limits.memory string 指定 mem 内存的限制,单位为 MIB、GiB
spec.containers[].resources.requests Object 指定容器启动和调度时的限制设置
spec.containers[].resources.requests.cpu string CPU请求,单位为core数,容器启动时初始化可用数量
spec.containers[].resources.requests.memory string 内存请求,单位为MIB、GiB,容器启动的初始化可用数量
spec.restartPolicy string 定义 pod 的重启策略,可选值为 Always、OnFailure、Never,默认值为 Always。
- Always:pod 一旦终止运行,则无论容器是如何终止的,kubelet 服务都将重启它。
- OnFailure:只有 pod 以非零退出码终止时,kubelet 才会重启该容器。如果容器正常结束(退出码为0),则 kubectl 将不会重启它。
- Never:Pod 终止后,kubelet 将退出码报告给 master,不会重启该 pod
spec.nodeSelector Object 定义 Node 的 label 过滤标签,以 key:value 格式指定
spec.imagePullSecrets Object 定义 pull 镜像时使用 secret 名称,以 name:secretkey 格式指定
spec.hostNetwork Boolean 定义是否使用主机网络模式,默认值为 false。设置 true 表示使用宿主机网络,不使用 docker 网桥,同时设置了 true将无法在同一台宿主机上启动第二个副本

3.3 对象规约和状态

规约(Spec)

“spec”是“规约”、“规格” 的意思,spec 是必需的,它描述了对象的期望状态(Desired state)——希望对象所具有的特征。当创建 Kubernetes 对象时,必须提供对象的规约,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。

状态(Status)

表示对象的实际状态,该属性由 k8s 自己维护,k8s会通过一系列的控制器对对应对象进行管理,让对象尽可能的让实际状态与期望状态重合。


文章作者: 无夜
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 无夜 !
评论
  目录