Kubernetes 基本概念

2020-09-05 • 10 minutes to read

基本概念

Container

Container(容器)是一种便携式、轻量级的操作系统级虚拟化技术。它使用 namespace 隔离不同的软件运行环境,并通过镜像自包含软件的运行环境,从而使得容器可以很方便的在任何地方运行。

体积小巧启动迅速,对环境的依赖较少。应用程序在容器内的封装,直接将最终的产出隐藏在容器中,不需要运行过多的关注内部实现。

其他容器的优点还包括

  • 敏捷的应用程序创建和部署: 与虚拟机镜像相比,容器镜像更易用、更高效。
  • 持续开发、集成和部署: 提供可靠与频繁的容器镜像构建、部署和快速简便的回滚(镜像是不可变的)。
  • 开发与运维的关注分离: 在构建/发布时即创建容器镜像,从而将应用与基础架构分离。
  • 开发、测试与生产环境的一致性: 在笔记本电脑上运行和云中一样。
  • 可观测:不仅显示操作系统的信息和度量,还显示应用自身的信息和度量。
  • 云和操作系统的分发可移植性: 可运行在 Ubuntu, RHEL, CoreOS, 物理机, GKE 以及其他任何地方。
  • 以应用为中心的管理: 从传统的硬件上部署操作系统提升到操作系统中部署应用程序。
  • 松耦合、分布式、弹性伸缩、微服务: 应用程序被分成更小,更独立的模块,并可以动态管理和部署 - 而不是运行在专用设备上的大型单体程序。
  • 资源隔离:可预测的应用程序性能。
  • 资源利用:高效率和高密度。

core-packages

Pods

Kubernetes 使用 Pod 来管理容器,每个 Pod 可以包含一个或多个紧密关联的容器。

Pod 是一组紧密关联的容器集合,它们共享 PID、IPC、Network 和 UTS namespace,是 Kubernetes 调度的基本单位。Pod 内的多个容器共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。

Node

Node 是 Pod 真正运行的主机,可以是物理机,也可以是虚拟机。为了管理 Pod,每个 Node 节点上至少要运行 container runtime(比如 docker 或者 rkt)、kubeletkube-proxy 服务。

Namespace

Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pods, services, replication controllers 和 deployments 等都是属于某一个 namespace 的(默认是 default),而 node, persistentVolumes 等则不属于任何 namespace。

Service

Service 是应用服务的抽象,通过 labels 为应用提供负载均衡和服务发现。匹配 labels 的 Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。

每个 Service 都会自动分配一个 cluster IP(仅在集群内部可访问的虚拟地址)和 DNS 名,其他容器可以通过该地址或 DNS 来访问服务,而不需要了解后端容器的运行。

Label

Label 是识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上(key 最长不能超过 63 字节,value 可以为空,也可以是不超过 253 字节的字符串)。

Label 不提供唯一性,并且实际上经常是很多对象(如 Pods)都使用相同的 label 来标志具体的应用。

Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象(比如 ReplicaSet 和 Service 用 label 来选择一组 Pod)。Label Selector 支持以下几种方式:

  • 等式,如 app=nginxenv!=production
  • 集合,如 env in (production, qa)
  • 多个 label(它们之间是 AND 关系),如 app=nginx,env=test

Annotations

Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象,Annotations 则是用来记录一些附加信息,用来辅助应用部署、安全策略以及调度策略等。比如 deployment 使用 annotations 来记录 rolling update 的状态。

核心组件

etcd

Etcd 是 CoreOS 基于 Raft 开发的分布式 key-value 存储,可用于服务发现、共享配置以及一致性保障(如数据库选主、分布式锁等)。

API Server

kube-apiserver 是 Kubernetes 最重要的核心组件之一,主要提供以下的功能

  • 提供集群管理的 REST API 接口,包括认证授权、数据校验以及集群状态变更等
  • 提供其他模块之间的数据交互和通信的枢纽(其他模块通过 API Server 查询或修改数据,只有 API Server 才直接操作 etcd)

kube-scheduler

kube-scheduler 负责分配调度 Pod 到集群内的节点上,它监听 kube-apiserver,查询还未分配 Node 的 Pod,然后根据调度策略为这些 Pod 分配节点(更新 Pod 的 NodeName 字段)。

Controller Manager

Controller Manager 由 kube-controller-manager 和 cloud-controller-manager 组成,是 Kubernetes 的大脑,它通过 apiserver 监控整个集群的状态,并确保集群处于预期的工作状态。

Kubelet

每个Node节点上都运行一个 Kubelet 服务进程,默认监听 10250 端口,接收并执行 Master 发来的指令,管理 Pod 及 Pod 中的容器。每个 Kubelet 进程会在 API Server 上注册所在Node节点的信息,定期向 Master 节点汇报该节点的资源使用情况,并通过 cAdvisor 监控节点和容器的资源。

kube-proxy

每台机器上都运行一个 kube-proxy 服务,它监听 API server 中 service 和 endpoint 的变化情况,并通过 iptables 等来为服务配置负载均衡(仅支持 TCP 和 UDP)。

kube-proxy 可以直接运行在物理机上,也可以以 static pod 或者 daemonset 的方式运行。

DNS

DNS 是 Kubernetes 的核心功能之一,通过 kube-dns 或 CoreDNS 作为集群的必备扩展来提供命名服务。

Federation

在云计算环境中,服务的作用距离范围从近到远一般可以有:同主机(Host,Node)、跨主机同可用区(Available Zone)、跨可用区同地区(Region)、跨地区同服务商(Cloud Service Provider)、跨云平台。K8s 的设计定位是单一集群在同一个地域内,因为同一个地区的网络性能才能满足 K8s 的调度和计算存储连接要求。而集群联邦(Federation)就是为提供跨 Region 跨服务商 K8s 集群服务而设计的。

kubeadm

kubeadm 是 Kubernetes 主推的部署工具

hyperkube

hyperkube是Kubernetes的allinone binary,可以用来启动多种kubernetes服务,常用在Docker镜像中。每个Kubernetes发布都会同时发布一个包含hyperkube的docker镜像,

kubectl

kubectl 是 Kubernetes 的命令行工具(CLI),是 Kubernetes 用户和管理员必备的管理工具。

kubectl 提供了大量的子命令,方便管理 Kubernetes 集群中的各种功能。这里不再罗列各种子命令的格式,而是介绍下如何查询命令的帮助

资源对象

Horizontal Pod Autoscaling (HPA)

Horizontal Pod Autoscaling (HPA) 可以根据 CPU 使用率或应用自定义 metrics 自动扩展 Pod 数量(支持 replication controller、deployment 和 replica set )。

ConfigMap

应用程序的运行可能会依赖一些配置,而这些配置又是可能会随着需求产生变化的,如果我们的应用程序架构不是应用和配置分离的,那么就会存在当我们需要去修改某些配置项的属性时需要重新构建镜像文件的窘境。现在,ConfigMap组件可以很好的帮助我们实现应用和配置分离,避免因为修改配置项而重新构建镜像。

ConfigMap 用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件。ConfigMap 跟 Secret 很类似,但它可以更方便地处理不包含敏感信息的字符串。

CronJob

CronJob 即定时任务,就类似于 Linux 系统的 crontab,在指定的时间周期运行指定的任务。

CustomResourceDefinition

CustomResourceDefinition(CRD)是 v1.7 新增的无需改变代码就可以扩展 Kubernetes API 的机制,用来管理自定义对象。它实际上是 ThirdPartyResources(TPR)的升级版本,而 TPR 已经在 v1.8 中弃用。

DaemonSet

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

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

Deployment

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的 ReplicationController 来方便的管理应用。

Ingress

Ingress 可以给 service 提供集群外部访问的 URL、负载均衡、SSL 终止、HTTP 路由等

Job

Job 负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束。

LocalVolume

本地数据卷(Local Volume)代表一个本地存储设备,比如磁盘、分区或者目录等。主要的应用场景包括分布式存储和数据库等需要高性能和高可靠性的环境里。本地数据卷同时支持块设备和文件系统,通过 spec.local.path 指定;但对于文件系统来说,kubernetes 并不会限制该目录可以使用的存储空间大小。

Namespace

Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pod, service, replication controller 和 deployment 等都是属于某一个 namespace 的(默认是 default),而 node, persistent volume,namespace 等资源则不属于任何 namespace。

Network Policy

随着微服务的流行,越来越多的云服务平台需要大量模块之间的网络调用。Kubernetes 在 1.3 引入了 Network Policy,Network Policy 提供了基于策略的网络控制,用于隔离应用并减少攻击面。它使用标签选择器模拟传统的分段网络,并通过策略控制它们之间的流量以及来自外部的流量。

Persistent Volume

PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 提供了方便的持久化卷:PV 提供网络存储资源,而 PVC 请求存储资源。这样,设置持久化的工作流包括配置底层文件系统或者云数据卷、创建持久性数据卷、最后创建 PVC 来将 Pod 跟数据卷关联起来。PV 和 PVC 可以将 pod 和数据卷解耦,pod 不需要知道确切的文件系统或者支持它的持久化引擎。

PodPreset

PodPreset 用来给指定标签的 Pod 注入额外的信息,如环境变量、存储卷等。这样,Pod 模板就不需要为每个 Pod 都显式设置重复的信息。

当然,你也可以给 Pod 增加注解 podpreset.admission.kubernetes.io/exclude: "true" 来避免它们被 PodPreset 修改。

ReplicationController 和 ReplicaSet

ReplicationController(也简称为 rc)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而异常多出来的容器也会自动回收。ReplicationController 的典型应用场景包括确保健康 Pod 的数量、弹性伸缩、滚动升级以及应用多版本发布跟踪等。

在新版本的 Kubernetes 中建议使用 ReplicaSet(也简称为 rs)来取代 ReplicationController。ReplicaSet 跟 ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector(ReplicationController 仅支持等式)。

虽然也 ReplicaSet 可以独立使用,但建议使用 Deployment 来自动管理 ReplicaSet,这样就无需担心跟其他机制的不兼容问题(比如 ReplicaSet 不支持 rolling-update 但 Deployment 支持),并且还支持版本记录、回滚、暂停升级等高级特性。

Resource Quotas

资源配额(Resource Quotas)是用来限制用户资源用量的一种机制。

它的工作原理为

  • 资源配额应用在 Namespace 上,并且每个 Namespace 最多只能有一个 ResourceQuota 对象
  • 开启计算资源配额后,创建容器时必须配置计算资源请求或限制(也可以用 LimitRange 设置默认值)
  • 用户超额后禁止创建新的资源

Secret

Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用。

Security Context 和 Pod Security Policy

Security Context 的目的是限制不可信容器的行为,保护系统和其他容器不受其影响。

Kubernetes 提供了三种配置 Security Context 的方法:

  • Container-level Security Context:仅应用到指定的容器
  • Pod-level Security Context:应用到 Pod 内所有容器以及 Volume
  • Pod Security Policies(PSP):应用到集群内部所有 Pod 以及 Volume

Service

Kubernetes 在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了 Service 资源,并通过 kube-proxy 配合 cloud provider 来适应不同的应用场景。随着 kubernetes 用户的激增,用户场景的不断丰富,又产生了一些新的负载均衡机制。目前,kubernetes 中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:

  • Service:直接用 Service 提供 cluster 内部的负载均衡,并借助 cloud provider 提供的 LB 提供外部访问
  • Ingress Controller:还是用 Service 提供 cluster 内部的负载均衡,但是通过自定义 Ingress Controller 提供外部访问
  • Service Load Balancer:把 load balancer 直接跑在容器中,实现 Bare Metal 的 Service Load Balancer
  • Custom Load Balancer:自定义负载均衡,并替代 kube-proxy,一般在物理部署 Kubernetes 时使用,方便接入公司已有的外部服务

Service Account

Service account 是为了方便 Pod 里面的进程调用 Kubernetes API 或其他外部服务而设计的。它与 User account 不同

StatefulSet

StatefulSet 是为了解决有状态服务的问题(对应 Deployments 和 ReplicaSets 是为无状态服务而设计),其应用场景包括

Volume

我们知道默认情况下容器的数据都是非持久化的,在容器消亡以后数据也跟着丢失,所以 Docker 提供了 Volume 机制以便将数据持久化存储。类似的,Kubernetes 提供了更强大的 Volume 机制和丰富的插件,解决了容器数据持久化和容器间共享数据的问题。

与 Docker 不同,Kubernetes Volume 的生命周期与 Pod 绑定

  • 容器挂掉后 Kubelet 再次重启容器时,Volume 的数据依然还在
  • 而 Pod 删除时,Volume 才会清理。数据是否丢失取决于具体的 Volume 类型,比如 emptyDir 的数据会丢失,而 PV 的数据则不会丢
devk8s

wentao

写点代码,解决点问题。

北京八大处