概括

编辑

Kubernetes 与传统的 PaaS 不同,它更多的被称为 容器的PaaS 或者 CaaS(Containers as a service,容器即服务)。[1]

概念

编辑

Kubernetes 包含一系列抽象概念,这些抽象概念用于表示系统的状态,这包括:已部署的容器化应用和工作负载的抽象概念、与之相关的网络和磁盘资源的抽象、集群运行的其他信息的抽象。[2]

工作节点
    |--------------┐
    Pod 1          Pod 2
    |               |
   容器1           容器2
   容器2           容器3
 IP 10.1.0.1    IP 10.1.0.2

Kubernetes API

编辑

Kubernetes API是REST API,是 Kubernetes 的基础组件。组件间的操作和通信,以及外部用户命令都是通过该API完成的,因此,Kubernetes平台里的任何对象都可以说是该API的执行对象。该API由 API服务器(kube-apiserver)管理。[3]

对象

编辑

对象有两个内嵌对象字段:specstatusstatus 用于表示对象的当前状态,通过以下命令可以查看到pod的当前状态:[4]

# 通过以下命令可以获得status
# kubectl get pods 
# kubectl describe pods [Pod名称] 
$ kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
nginx-app   1/1     Running   0          20h

spec 表示集群期待的状态(Desired State)。用户可以使用YAML文件部署应用(创建对象),spec 字段则表示要部署的应用有什么特征。[4] 以下YAML文件描述了一个高级对象(Deployment),字段详情可查看该网站

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment # 对象的类型
metadata: # 该Deployment对象的元数据
  name: nginx-deployment
spec:
  selector: # Pods的标签选择器。选择哪些Pods受该Deployment管理。
    matchLabels:
      app: nginx
  replicas: 2 # 希望运行2个pod
  template:
    metadata: # Pods对象的元数据
      labels: # Pods对象的标签
        app: nginx 
    spec:
      containers:
      - name: nginx # Pod的容器名为nginx
        image: nginx:1.14.2 # 从Docker Hub拉去的镜像
        ports:
        - containerPort: 80

基础对象

编辑

Pod(英语:豆荚)是最小单元(atomic unit)。Pod封装了一个或若干个容器(Docker容器是最常用的容器),各容器可共享同一IP地址端口、存储资源(存储卷)。但通常,一个Pod只会装载一个容器,除非各容器间需要使用文件系统(存储资源)进行通讯。[5][6]

虽然Pod拥有独立的IP地址,但是该IP地址无法暴露在集群之外。此时,需要 服务 该对象进行帮助。[7]

服务

编辑

服务(service),可以理解为逻辑上的Pod。通过服务的DNS名称名(DNS name)可以找到服务,再通过服务可以调用Pod。[8] 调用方 通过调用服务的方式,避免了调用方与Pod的耦合,这样当Pod宕机时,也不会影响到调用方,这也可用于负载均衡服务发现等场景。[9]

                         选择一个Endpoint进行调用
            |-----------| -------- Endpoint 1 -----> [Pod 1 暴露端口:80 IP:10.244.0.25]
            |           |        [10.244.0.25:80]
   调用 --> | service   | -------- Endpoint 2 -----> [Pod 2 暴露端口:80 IP:10.244.0.26] 
            |10.96.92.53|        [10.244.0.26:80]      
            |-----------| -------- Endpoint 3 -----> [Pod 3 暴露端口:80 IP:10.244.0.27] 
                                 [10.244.0.27:80]

服务也是拥有IP地址(称为cluster IP)[9],通过kubectl get service 可查看到。服务没有通过选择器(selector)选择Pod时,Endpoint对象 将无法被自动生成,服务将无法调用;另外,可通过直接指定 IP端口 的方式,生成Endpoint对象,从而调用服务。[10] 可通过kubectl get endpoints 的方式查看Endpoint对象。

服务定义文件格式为 YAML(推荐) 和 JSON,示例如下:[7]

apiVersion: v1
kind: Service
metadata:
  name: redis-master # DNS名
  labels:
    app: redis
    role: master
    tier: backend
spec:
  ports:
  - port: 6666  # 该服务暴露给外界的端口
    targetPort: 6379 # Pods暴露的端口
  selector: # 标签选择器,用于服务连接的Pod
    app: redis 
    role: master
    tier: backend

标签和选择器

编辑

标签(label)是键值对,用于存储对象的数据。这些数据是特意展示给用户看,具有意义和标志性。 用户通过 选择器(全称:标签选择器,Label selector)匹配标签,API 将可找到匹配对象。[11]

"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

高级对象

编辑

高级对象 是依赖于控制器 ,而控制器是建立于基础对象之上,并为之添加功能性和方便性。[2]

ReplicationController

编辑

ReplicationController 用于确保Pod的数量正常。[12]

ReplicaSet

编辑

ReplicaSet 是 ReplicationController 的升级版本,ReplicaSet 的标签选择器更加灵活。[13]

DaemonSet

编辑

DaemonSet(Daemon:守护进程) 为了每一个节点分配有且只有一个Pod,使用场景有:[14][15]

  • 存储用的守护进程。
  • 日志收集的守护进程。
  • 节点监控的守护进程。

Deployment

编辑

Deployment控制器 提供了声明式(使用YAML文件)的方式,更新PodReplicaSet[16][17][18] Deployment控制器可以管理其 Pod 组件的生命周期,还可以执行横向扩缩以根据需要更改 Pod 的数量。[19]

下例为查看deployment对象:

$ kubectl get deployments 
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
frontend       1/1     1            1           5d4h

Job控制器用于执行非持续性的任务(即任务是可执行完毕的),例如使用Pod发送一封邮件,发送完毕后Job控制器会被标记完成,失败的话则重新发送一封邮件。Job控制器可创建单个或者多个Pod,如果创建多个Pod的话,将以并行的方式执行。[20]

CronJob

编辑

CronJob控制器 在特定时间或按特定间隔运行任务,就像Cron工具。[21]

设计

编辑

开发者使用 Kubernetes 有两种方式:使用命令行工具(如:kubectlkubeadm)、客户端库。而这两种方式均是基于Kubernetes API[3]

当开发者想要部署 应用,那么需要通过命令行工具等方式要告诉Master,Master将会调度Pod(Pod装载着容器化的应用)到工作节点上。[22]

|-----------------------------------------------------------------------|
|                           cluster                                     |
|    Control Plane Components                                                              |
|         Master node                       Work node                   |
|   |------------------------|      |--------------------|              |
|   | kube-apiserver         |      |       kubelet      |              |
|   | kube-scheduler         |      |   kubelet-proxy    |              |
|   | kube-contoller-manager |      |  Container runtime |              |
|   |         etcd           |      |      [ Pods ]      |              |
|   |------------------------|      |--------------------|              |
|                                                                       |
|-----------------------------------------------------------------------|

Control Plane

编辑

控制平面(英語:Control Plane)位于主节点(Master node),包含主控件组(Master)、etcd。控制平面 通常用于与工作节点进行交互。[23]

Masters

编辑

由于Master是由三个进程组成的,所以可以翻译为“主控件组”。Master所在的工作节点将会被指定为 主节点。[2]主控组件包含的三个进程分别是:kube-apiserver、kube-controller-manager 和 kube-scheduler。[2]主控组件负责管理集群。[22]

  • kube-apiserver(API server), 用于与(集群的)外界进行通讯。API server将会判断接请求是否有效,如果有效就会处理。kubectl 等命令行实质就是和该组件通讯。[23]
  • kube-scheduler,用于调度资源。观察是否存在新创建的Pod没有指派到节点,如果存在的话,则将其指派到其中一个节点上。[24]
  • kube-controller-manager,通过控制器进行维护集群。从API server接收到的命令,将会修改集群某些对象的期待状态(desired state),控制器观察到这些期待状态的变化,就会将这些对象的当前状态(current state)变为期待状态(desired state)。[25][22][24]
    • Node controller:负责监视节点,当节点宕不可用时,进行通知。
    • Replication controller:负责维护每一个replication controller对象所关联的Pod数量。
    • Endpoints controller:负责填充 Endpoints对象。
    • Service Account & Token controllers:创建默认的账号和API访问令牌。
            |--------------------|                            
command-->  |   kube-apiserver   | ---> change object's 
            |--------------------|      desired state       
                                             ∧
                                             || watch
                                |---------------------------| 
       change object's  <---    |   kube-contoller-manager  |
       current state            |---------------------------|

一致性和高可用的键值存储软件,用于备份k8s的所有集群。[26]

cloud-controller-manager

编辑

在v1.11版本(2018年),cloud-controller-manager用于云服务提供商

####TODO

工作节点

编辑

节点(Node)默认表示 工作节点,而不代表 主节点。工作节点 运行着容器化的应用。 工作节点装载着 Pod ,Pod是application workload的构成要素。[27]

  • kubelet,作为节点的代理者,用于与 Master 进行通信,并管理着容器。[22][28]
  • kube-proxy,一种网络代理,将 Kubernetes 的网络服务代理到每个节点上。
  • 容器运行时(Container Runtime),用于操作容器,如:Docker[22][28]

网络

编辑

服务

编辑

服务有五种类型:[29]

  • ClusterIP(默认类型):只能在集群里访问服务。
  • NodePort:通过每个节点IP的某一特定端口,访问服务(Node=节点,Port=端口)。
  • LoadBalancer:通过云服务商的负载均衡器,访问服务。
  • ExternalName:该服务 为外部 DNS 名称提供内部别名。内部客户端使用内部 DNS 名称发出请求,然后请求会被重定向到外部名称。[30]

通过节点IP地址进行暴露服务,可使用;通过云服务提供商的负载均衡器暴露服务,则使用LoadBalancer[31]而当服务不在集群内,在集群之外,可以使用ExternalName 模式的服务进行重定向。

存储

编辑

存储方案有很多。托管式的有如:网络附加存储(NAS)、数据库、文件服务器;非托管式的则利用Kubernetes 存储抽象,如:[32]

对于应用而言,将数据写入容器中的磁盘文件是最简单的途径,但这种方法存在缺陷。如果容器因其他任何原因崩溃或停止,文件将会丢失。此外,一个容器内的文件不可供同一 Pod 中运行的其他容器访问。 卷(Volume)可以解决这两个问题。[33][34]

临时卷

编辑

临时卷 与Pod的生命周期一样,随着包裹其的Pod终止或被删除时,该卷也会随之终止或删除。[33][34]

持久性卷

编辑

持久性卷(Persistent Volumes),在 Pod 被移除时,系统只是卸载该卷,数据将保留,并可将其数据传递到另一个 Pod。[34]

健康检查

编辑

K8s的对于容器的健康检查(Health Check)有三种:存活探测(Liveness Probe)、就绪探测(Readiness Probe)、启动探测(Startup Probe)。[35][36] 执行顺序如下

启动容器 -->  Startup Probe  ------>  Readiness Probe
                              |---->  Liveness Probe

存活探测

编辑

存活探测(Liveness Probe):当不符合条件时,容器将会被重启。通常用于遇到Bug,无法进行下去的情况,如:死锁。[36]

常见的存活探测如下:根据命令、根据HTTP返回码、根据TCP是否连接成功。可用于判定命令是否执行成功,当失败且返回值为非0时,容器将会被重启;对于HTTP服务,可通过发送HTTP请求,并根据是否 400>返回码>=200,判断是否存活;对于TCP连接,则在指定的时间内观察容器是否能连接成功,如果不能则重启容器。[36]

就绪探测

编辑

就绪探测(Readiness Probe):当符合条件时,容器将被视为已就绪。就绪探测的一个用途:当一个Pod的所有容器就绪后,将会告诉 服务 该Pod可被使用。[36]

通过TCP进行就绪探测,那么会循环进行TCP连接,直到连接成功,容器将会被视为就绪。通过命令行方式进行就绪探测,当返回值为0时,容器将会被视为就绪。[36]

启动探测

编辑

启动探测(Startup Probe):当符合条件时,容器被视为已启动。当应用需要长时间进行启动时,启动探测 会在一定时间内不断地探测应用是否启动成功,当应用启动成功后,存活探测或就绪探测 可被启动;超过探测时间的话,容器将会被杀死,并且根据 restartPolicy 来做出相应操作。[36] [37]

日志架构

编辑

容器化应用写入 stdoutstderr 的任何数据,都会被容器引擎捕获并被重定向到某个位置。[38] 如:Docker容器 的日志,可以在节点上查找得到。



常见问题

编辑

连接应用

编辑

Dashboard

编辑

Dashboard 是关于Kubernetes用户接口相关操作的网页。通过Dashboard,用户可以对容器化应用进行部署、查看的概览信息、故障排除,以及管理集群资源。

直接连接

编辑

通常想要在Pod里运行命令,会通过使用 kubectl exec [Pod名字] [命令] 命令,这与Docker一样。[39] 如果想要通过HTTP协议连接Pod(REST API),则可运行代理模式的 kubectl ,[40] 也可以编程的方式去访问 REST API。[41]



控制平面

编辑

控制平面(Control Plane)管理着集群中的 工作节 和 Pod。在生产环境里,控制平面 经常会 连接(runs across)若干个计算机。[42]

容器编排层暴露出来的

The container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.

Control Plane [43]

控制平面组件 用于对集群进行全局决策(如:调度),并检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。虽然 控制平面组件 可在集群中的任何节点上运行,但通常会安装在同一机器上。[42][44]


kube-scheduler

编辑

kube-controller-manager

编辑

集群中的工作节点,将会运行着两个进程:[2]

  • kubelet,用于与 master节点 进行通信。
  • kube-proxy,一种网络代理,将 Kubernetes 的网络服务代理到每个节点上。


其他

编辑

代理服务器

编辑

通过 kubectl proxy 该命令将会运行一个反向代理,通过该代理,我们能直接访问 REST API (通过CURL或浏览器访问的方式)。[45] 再通过 http://代理地址/api/v1/namespaces/default/pods/应用地址/proxy 的方式方问

如若想访问应用的其他端口,则应使用 kubectl port-forward ,建立端口转发,如:调试数据库。




设计

编辑

Kubernetes在設計結構上定义了一系列的构建模块,其目的是為了提供一個可以共同提供部署、维护和扩展应用程序的机制。组成Kubernetes的组件设计概念为松耦合和可扩展的,这样可以使之满足多种不同的工作负载。可扩展性在很大程度上由Kubernetes API提供,此API主要被作为扩展的内部组件以及Kubernetes上运行的容器來使用。[46]

对象

编辑

Kubernetes的基本调度单元称为“pod”。通過該種抽象類別可以把更高级别的抽象内容增加到容器化组件。一个pod一般包含一个或多个容器,这样可以保证它们一直位于主机上,并且可以共享资源。[46]Kubernetes中的每个pod都被分配一个唯一的(在集群内的)IP地址就可以允许应用程序使用同一端口,而避免了發生冲突的問題。[47] Pod可以定义一个卷,例如本地磁盘目录或网络磁盘,并将其暴露在pod中的一个容器之中。[48]。pod可以通过Kubernetes API手动管理,也可以委托给控制器来實現自動管理。[46]

标签和选择器

编辑

Kubernetes使客户端(用户或内部组件)将称为“标签”的键值对附加到系统中的任何API对象,如pod和节点。相应地,“标签选择器”是针对匹配对象的标签的查询方法。[46]

标签和选择器是Kubernetes中的主要分组机制,用于确定操作适用的组件。[49]

例如,如果应用程序的Pods具有系统的标签 tier (比如"front-end"、"back-end") 和一个 release_track (比如"canary"、"production"),那么对所有"back-end" 和 "canary" 节点的操作可以使用如下所示的标签选择器:[50]

tier=back-end AND release_track=canary

控制器

编辑

控制器是通过管理一组pod来实现來将实际集群状态转移到所需集群状态的对帐循环機制[51]。一种控制器指的是一組具有相同特徵的“复制控制器”,控制器通过在集群中运行指定数量的pod副本来处理复制和缩放。在基础节点出现故障的情況下,它还可以用於处理创建替换pod。[51]其它控制器也是核心Kubernetes系统的一部分,包括“DaemonSet控制器”为每台机器(或机器的一些子集)上运行的單個pod,和用于运行pod的“作业控制器”。[52] 控制器管理的pod組由作为控制器定义的部分的标签选择器來确定。[50]

服务

编辑

Kubernetes服务本質是一组协同工作的pod,類同多层架构应用中的一层。构成服务的pod组通过标签选择器来定义。[46]Kubernetes通过给服务分配静态IP地址和域名来提供服务发现机制,并且以轮循调度英语Round-robin DNS的方式将流量负载均衡到能与选择器匹配的pod的IP地址的网络连接上(即使是故障导致pod从一台机器移动到另一台机器)。[47] 默认情况下,服务任務会暴露在集群中(例如,多个后端pod可能被分组成一个服务,前端pod的请求在它们之间负载平衡);除此以外,服务任務也可以暴露在集群外部(例如,从客户端访问前端pod)。[53]

参考文献

编辑
  1. ^ PaaS将吞噬云计算?Kubernetes的市场冲击波-InfoQ. www.infoq.cn. [2020-03-31]. 
  2. ^ 2.0 2.1 2.2 2.3 2.4 Concepts. kubernetes.io. [2020-03-31] (英语). 
  3. ^ 3.0 3.1 Kubernetes API Overview. kubernetes.io. [2020-03-31] (英语). 
  4. ^ 4.0 4.1 Understanding Kubernetes Objects. kubernetes.io. [2020-04-08] (英语). 
  5. ^ Pod Overview. kubernetes.io. [2020-04-01] (英语). 
  6. ^ Pod | Kubernetes Engine Documentation. Google Cloud. [2020-04-13] (英语). 
  7. ^ 7.0 7.1 Using a Service to Expose Your App. kubernetes.io. [2020-04-12] (英语). 
  8. ^ DNS for Services and Pods. kubernetes.io. [2020-04-09] (英语). 
  9. ^ 9.0 9.1 Service. kubernetes.io. [2020-04-09] (英语). 
  10. ^ 没有选择器的服务. kubernetes.io. [2020-04-10] (英语). 
  11. ^ Labels and Selectors. kubernetes.io. [2020-04-04] (英语). 
  12. ^ ReplicationController. kubernetes.io. [2020-05-03] (英语). 
  13. ^ ReplicaSet. kubernetes.io. [2020-05-03] (英语). 
  14. ^ DaemonSet. kubernetes.io. [2020-05-03] (英语). 
  15. ^ DaemonSet | Kubernetes Engine Documentation. Google Cloud. [2020-05-03] (英语). 
  16. ^ Using kubectl to Create a Deployment. kubernetes.io. [2020-04-11] (英语). 
  17. ^ kubernetes/kubernetes. GitHub. [2020-04-14] (英语). 
  18. ^ Declarative Management of Kubernetes Objects Using Configuration Files. kubernetes.io. [2020-04-14] (英语). 
  19. ^ Pod | Kubernetes Engine Documentation. Google Cloud. [2020-04-14] (英语). 
  20. ^ Running a job | Kubernetes Engine Documentation. Google Cloud. [2020-05-02] (英语). 
  21. ^ CronJob. kubernetes.io. [2020-05-03] (英语). 
  22. ^ 22.0 22.1 22.2 22.3 22.4 Using Minikube to Create a Cluster. kubernetes.io. [2020-04-11] (英语). 
  23. ^ 23.0 23.1 Introduction to Kubernetes architecture. www.redhat.com. [2020-04-20] (英语). 
  24. ^ 24.0 24.1 Kubernetes Components. kubernetes.io. [2020-04-29] (英语). 
  25. ^ Controllers. kubernetes.io. [2020-04-20] (英语). 
  26. ^ Kubernetes 组件. kubernetes.io. [2020-04-29] (中文). 
  27. ^ Kubernetes Components. kubernetes.io. [2020-03-31] (英语). 
  28. ^ 28.0 28.1 node-components. kubernetes.io. [2020-04-12] (英语). 
  29. ^ Service. kubernetes.io. [2020-05-03] (英语). 
  30. ^ Exposing applications using services | Kubernetes Engine Documentation. Google Cloud. [2020-05-15] (英语). 
  31. ^ publishing-services-service-types. kubernetes.io. [2020-04-12] (英语). 
  32. ^ Storage overview | Kubernetes Engine Documentation. Google Cloud. [2020-04-14] (英语). 
  33. ^ 33.0 33.1 Volumes | Kubernetes Engine Documentation. Google Cloud. [2020-04-13] (英语). 
  34. ^ 34.0 34.1 34.2 Volumes. kubernetes.io. [2020-04-13] (中文). 
  35. ^ Health checks overview | Load Balancing. Google Cloud. [2020-04-17] (英语). 
  36. ^ 36.0 36.1 36.2 36.3 36.4 36.5 Configure Liveness, Readiness and Startup Probes. kubernetes.io. [2020-04-16] (英语). 
  37. ^ Pod Lifecycle. kubernetes.io. [2020-04-17] (英语). 
  38. ^ 日志架构. kubernetes.io. [2020-04-18] (中文). 
  39. ^ Get a Shell to a Running Container. kubernetes.io. [2020-04-02] (英语). 
  40. ^ directly-accessing-the-rest-api. kubernetes.io. [2020-04-02] (英语). 
  41. ^ programmatic-access-to-the-api. kubernetes.io. [2020-04-02] (英语). 
  42. ^ 42.0 42.1 Kubernetes Components. kubernetes.io. [2020-03-31] (英语). 
  43. ^ The container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.
  44. ^ Kubernetes 组件. kubernetes.io. [2020-03-31] (中文). 
  45. ^ Accessing Clusters. kubernetes.io. [2020-04-02] (英语). 
  46. ^ 46.0 46.1 46.2 46.3 46.4 An Introduction to Kubernetes. DigitalOcean. [24 September 2015]. 
  47. ^ 47.0 47.1 Langemak, Jon. Kubernetes 101 – Networking. Das Blinken Lichten. 2015-02-11 [2015-11-02]. 
  48. ^ Strachan, James. Kubernetes for Developers. Medium (publishing platform). 2015-05-21 [2015-11-02]. 
  49. ^ Surana, Ramit. Containerizing Docker on Kubernetes. LinkedIn. 2015-09-16 [2015-11-02]. 
  50. ^ 50.0 50.1 Intro: Docker and Kubernetes training - Day 2. Red Hat. 2015-10-20 [2015-11-02]. (原始内容存档于2015-10-29). 
  51. ^ 51.0 51.1 Overview of a Replication Controller. Documentation. CoreOS. [2015-11-02]. 
  52. ^ Sanders, Jake. Kubernetes: Exciting Experimental Features. Livewyer. 2015-10-02 [2015-11-02]. 
  53. ^ Langemak, Jon. Kubernetes 101 – External Access Into The Cluster. Das Blinken Lichten. 2015-02-15 [2015-11-02].