Kubernets 中的Node, Pod,Replication Controller, Service 等都可以看作一种资源对象,这些资源几乎都可以通过使用Kubernetes提供的kubectl 工具执行增删改查,并将其保存在etcd中持久化储存。通过跟踪对比etcd库中保存的“资源预设状态”与当前环境中的实际资源状态进行对比,对差异资源状态进行纠错,来实现自动控制集群状态的功能。下面将分别介绍这个组件角色。

管理角色

Kubernetes中有两种管理角色,Master和Node.

Master

Master是Kubernetes集群的控制节点,所有对于Kubernetes的命令操作都需要在控制节点执行。Master一般运行如下进程:

kube-apiserver: Kubernetes API Server, 提供了HTTP Rest接口的关键服务进程,是所有资源增,删,改,查的入口,也是集群控制的入口进程,kubectl是直接与 API Server交互的,默认监听 6443端口。

kube-controller-manager: 每个资源一般都对应有一个控制器,而controller manager就是负责管理这些控制器的,它是自动化的循环控制器,是Kubernetes的核心控制守护进程。默认监听10252端口。

kube-scheduler : 负责将pod资源调度到合适的node 上。其本身提供了复杂丰富的调度算法,可以根据node 节点的性能,负载,数据位置等各种情况进行合理的调度。默认监听10251 端口。

etcd: 一个高可用的键值存储系统,Kubernetes使用它来存储各个资源的状态,从而实现了Restful的API。默认监听2379和2380端口(2379提供服务,2380用于集群节点通信)

Node

除了Master节点,集群中的其它节点被称作Node节点,Node节点是业务应用实际的运行的平台,通过Master 调度不同的任务到Node节点上,以docker 的方式运行。当某个Node节点宕机时,其上的工作负载会被Master自动转移到其它Node节点上。
Node节点上运行着如下进程:

kubelet: Kubelet是在每个Node节点上运行agent,是Node节点上面最重要的模块,它负责维护和管理该Node上面的所有容器,但是Kubelet不会管理不是由Kubernetes创建的容器。本质上,它负责使Pod得运行状态与期望的状态一致。Kubelet会定时向Master汇报自己当前的自身信息,如操作系统,Docker版本,CPU,内存,pod运行状态等信息。

kube-proxy:该模块实现了Kubernetes中的服务发现和反向代理功能。反向代理支持TCP和UDP连接转发,默认基于Round Robin算法将客户端流量转发到与service对应的一组后端pod。服务发现方面,kube-proxy使用etcd的watch机制,监控集群中service和endpoint对象数据的动态变化,并且维护一个service到endpoint的映射关系,从而保证了后端pod的IP变化不会对访问者造成影响。

runtime: 这里一般使用docker 容器,Kubernetes也支持其他的容器。

Node节点的状态管理

1、通过在Master查看Node状态:

[root@node-1 ~]# kubectl get nodes
NAME      STATUS    ROLES     AGE       VERSION
node-1    Ready     master    22h       v1.10.2
node-2    Ready     <none>    22h       v1.10.2
node-3    Ready     <none>    1h        v1.10.2

2、查看Node的详细信息,如下命令会输出节点当前状态的详细信息,包括可用资源总量:

kubectl describe node node-2

Pod

Pod是Kubernetes中非常重要的基本单位。Pod是应用运行的载体,整个Kubernetes系统都是围绕着Pod展开的,比如如何部署运行Pod、如何保证Pod的数量、如何访问Pod等。Pod是一个或多个容器的集合。
在每一个Pod中都有一个特殊的Pause容器和一个或多个业务容器,Pause来源于pause-amd64镜像,Pause容器在Pod中具有非常重要的作用:

  • Pause容器作为Pod容器的根容器,其本地于业务容器无关,它的状态代表了整个pod的状态。
  • Pod里的多个业务容器共享Pause容器的IP,每个Pod被分配一个独立的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口。Pod内的容器可以使用localhost相互通信。k8s支持底层网络集群内任意两个Pod之间进行通信。
  • Pod中的所有容器都可以访问共享volumes,允许这些容器共享数据。volumes 还用于Pod中的数据持久化,以防其中一个容器需要重新启动而丢失数据。

Pod 的定义

Kubernetes中所有的资源对象都可以采用YAML或者JSON格式的文件来定义,比如,我们可以定义如下的Pod对象:

apiVersion: v1
kind: Pod
metadata:
  name: myweb
  labels:
    name: myweb
spec:
  containers:
  - name: myweb
    image: kubeguide/tomcat-app:v1
    ports:
    - containerPort: 8080
    env:
    - name: MYSQL_SERVER_HOST
      value: 'mysql'
    - name: MYSQL_SERVER_PORT
      value: '3306'

2、Pod Volume可以使用分布式文件系统,将Pod Volume定义在Pod上,然后被各个容器挂载到自身的容器。目前Kubernetes支持多种文件存储。

3、我们还可以对pod使用的资源进行配额,一般是对CPU和内存的限制:

apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    name: mysql
spec:
  containers:
  - name: db
    image: mysql
    resources:
      requests:                  # 最小资源申请量
        memory: "64Mi"     # 64M内存
        cpu: "250m"           # 0.25个CPU
      limits:                       # 最大配额
        memory: "128Mi"   # 128M 内存
        cpu: "500m"           # 0.5个CPU

4、 Pod 常用操作:

kubectl create -f  pod_file.yaml            # 创建pod
kubectl describe pods POD_NAME  # 查看pod详细信息
kubectl get pods                               # pods 列表
kubectl delete pod POD_NAME    # 删除pod
kubectl replace  pod_file.yaml      # 更新pod

Label

Label 是用户自定义的键值对,主要是用于标记资源对象,如Node,Pod,Service,RC等。一个资源可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去,Label 通常在资源对象定义时确定,也可以在对象创建后动态的添加或删除。

可以给资源对象绑定多个不同Label,来实现多维度的资源分组管理功能,一些常见的Label示例:

  • 版本标签:"release":"stable","release":"beta"
  • 环境标签:“environment”:"dev" , "environment":"qa" , "environment":"production"

提示:Deployment,ReplicaSet,DaemonSet和Job等管理对象可以在Selector中使用基于集合的筛选条件定义。

Label Selector (标签选择器) ,主要用于对拥有某些Label的资源对象进行查询和筛选,类似SQL的查询机制。
Label Selector可以通过基于等式集合的查询方式进行匹配查询,通过多个表达式的组合,从而实现复杂的条件选择,如:

name=mysql,env!=production
name notin (tomcat),env!=production

Replication Controller

Replication Controller(RC)是Kubernetes中的另一个核心概念,Kubernetes中通过RC来保证应用能够持续运行,它会确保任何时间Kubernetes中都有指定数量的Pod处于运行状态。在此基础上,RC还提供了一些更高级的特性,比如滚动升级、升级回滚等。

RC在Kubernetes中定义了一个期望的场景,即声明某种pod副本数量在任意时刻符合某个预期的值,其定义的内容如下:

  • Pod 期待的副本数(replicas)
  • 用于筛选目标Pod的Label Selector.
  • 当Pod 的副本数量小于预期的数量时,用于创建新的Pod

RC运行过程: 当我们定义了一个RC的YAML文件(或者调用kubectl命令)提交到Kubernets集群后,Master 上的Controller Manager组件就得到通知,定期巡检系统中当前存活的目标Pod,并确保目标Pod实例的数量刚好邓毅此RC的期望值。如果有过多的Pod副本在运行,系统就会停掉一些Pod,反之则会自动创建一些Pod。

自动伸缩

通过修改RC数量,实现Pod的动态缩放:

kubectl scale rc myweb --replicas=10        # 将pod 扩展到10个       
kubectl scale rc myweb --replicas=1          # 将pod 缩到 1个

滚动升级

使用RC可以进行动态平滑升级,保证业务始终在线。其具体实现方式:

 kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s

升级开始后,首先依据提供的定义文件创建V2版本的RC,然后每隔10s(--update-period=10s)逐步的增加V2版本的Pod副本数,逐步减少V1版本Pod的副本数。升级完成之后,删除V1版本的RC,保留V2版本的RC,及实现滚动升级。

升级过程中,发生了错误中途退出时,可以选择继续升级。Kubernetes能够智能的判断升级中断之前的状态,然后紧接着继续执行升级。当然,也可以进行回退,命令如下:

 kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s --rollback

ReplicaSet

replica set,可以被认为 是“升级版”的Replication Controller。replica set也是用于保证与label selector匹配的pod数量维持在期望状态。区别在于,replica set引入了对基于子集的selector查询条件,而Replication Controller仅支持基于值相等的selecto条件查询。replica set很少被单独使用,目前它多被Deployment用于进行pod的创建、更新与删除的编排机制。

RC(Replica Set)特性和作用

  • 通过定义一个RC实现Pod的创建过程及副本数量的自动控制。
  • RC 里包括完整的Pod定义模板。
  • RC通过Label Selector 机制是对Pod副本的自动控制。
  • 通过改变RC的副本数量,可以实现Pod副本的扩容和缩容。
  • 通过改变RC里Pod模板中的镜像版本,可以实现Pod滚动升级。

Deployment

Deployment主要职责同样是为了保证pod的数量和健康,90%的功能与Replication Controller完全一样,可以看做新一代的Replication Controller。Deployment内部使用了Replica Set来实现。
Deployment 相对于RC一个最大的升级是我们可以随时知道当前Pod "部署"的进度,和详细的运行状态。
具有以下使用场景:

创建Pod: 可以创建一个Deployment对象来生成对应的Replica Set,完成Pod副本的创建。
查看事件状态: 通过检查Deployment的状态来查看部署动作是否完成,如副本数量是否达到了预期的值。
升级:更新Deployment以创建新的Pod,同时还可以清理不再需要的旧版本ReplicaSet。
回滚: 如果当前的Pod不稳定或者有bug,可以回滚到一个早期的稳定版本。
暂停和恢复:可以随时暂停Deployment对象,修改对应的参数配置,之后再恢复Deployment继续发布。

Deployment 定义

Deployment的定义和Replica Set的定义几乎一样,仅仅是API版本和kind类型不同:

# Deployment的声明
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

# Replica Set的声明
apiVersion: v1
kind: ReplicaSet
metadata:
  name: mysql
...

创建一个deployment

1、这里以上面的nginx为例,创建nginx:

[root@node-1 ~]# kubectl create -f nginx.yaml 
deployment.apps "nginx-deployment" created

2、查看Deployment信息:

# 刚执行时,显示的AVAILABLE数量时0
[root@node-1 ~]# kubectl get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            0           22s

# 1分钟后显示已经有3个可用nginx-deployment
[root@node-1 ~]# kubectl get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           1m

# 查看pods
[root@node-1 ~]# kubectl get pods | grep nginx
nginx-deployment-666865b5dd-cfmfp   1/1       Running   0          11m
nginx-deployment-666865b5dd-nhxtv   1/1       Running   0          11m
nginx-deployment-666865b5dd-qj7sf   1/1       Running   0          11m

# 查看 rs
[root@node-1 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-666865b5dd   3         3         3         25m

# 查看deployments的详细部署信息
[root@node-1 ~]# kubectl describe deployments
...

对于上述kubectl get deployments的输出,其含义:

  • DESIRED : Pod副本数量的期望值,即Deployment里定义的Replica。
  • CURRENT: 当前实际的Replica数量,当这个值不断增加,达到DESIRED时表明部署完成。
  • UP-TO-DATE:最新版本的Pod副本数量,用于指示在滚动升级过程中有多少Pod副本已经成功升级。
  • AVAILABLE: 当前集群中可用的Pod副本数量(当前存活的Pod数量)

使用kubectl describe deployments命令可以获取指定Deployment的详细状态

滚动升级

例如,我们要对当前的nginx-deployment进行升级或者回滚,可以使用如下两种方式。

* 直接 set 镜像

1、若要对docker镜像进行更新,直接 set 镜像:

[root@node-1 ~]# kubectl set image deployment/nginx-deployment nginx=nginx:1.12.2

2、查看状态,可以发现在保证pod 可用的状态下,会平滑的替换旧的deployment对象,并且会记录此过程:

[root@node-1 ~]# kubectl  get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         4         1            3           3h

[root@node-1 ~]# kubectl  get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         4         2            3           3h

[root@node-1 ~]# kubectl  get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           4h

[root@node-1 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-666865b5dd   0         0         0         4h
nginx-deployment-69647c4bc6   3         3         3         3m

[root@node-1 ~]# kubectl describe deployments   # 会显示详细events事件
* 直接edit Deployment

1、执行 edit命令修改Deployment配置,类似KVM的virsh edit 命令,修改后立即生效(如果没有修改,将不会发生任何变化):

[root@node-1 ~]# kubectl edit deployments/nginx-deployment

2、查看deployment状态:

[root@node-1 ~]# kubectl get deployments 
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         4         1            3           5h

[root@node-1 ~]# kubectl get deployments 
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         4         3            3           5h

[root@node-1 ~]# kubectl get deployments 
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           5h

3、一般常见的修改是修改镜像版本和参数。

回滚

1、执行回滚命令,到上一个版本:

[root@node-1 ~]# kubectl rollout undo deployment/nginx-deployment

2、使用如下命令,可以查看保存的deployment历史:

[root@node-1 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-666865b5dd   0         0         0         5h
nginx-deployment-68dfb7c95b   3         3         3         27m
nginx-deployment-69647c4bc6   0         0         0         1h

命令参考

  • kubectl describe deployments #查询详细信息,获取升级进度
  • kubectl get deployments # 获取升级进度的简略信息
  • kubectl get rs # 获取RS记录,每执行一次deployment就会生成一个RS记录。
  • kubectl set image deployment/nginx-deployment nginx=nginx:1.12.2 # 升级
  • kubectl edit deployments/nginx-deployment # 修改deployment 参数
  • kubectl rollout pause deployment/nginx-deployment #暂停升级
  • kubectl rollout resume deployment/nginx-deployment #继续升级
  • kubectl rollout undo deployment/nginx-deployment #回滚到上一版本
  • kubectl scale deployment nginx-deployment --replicas 10 #弹性伸缩Pod数量

Service

Service是Kubernetes中的核心对象之一。Kubernetes中的Pod,RC,等资源对象最终都是为Service服务。
Service定义了一个服务访问的入口地址,前端应用Pod通过这个地址访问后端的Pod集群实例,Service通过Label Selector来实现与后端Pod集群的通讯。其中,RC的作用是保障集群中始终有可用的Pod集群,从而确保了服务质量。

Service原理

Service的服务原理图:

Kubernetes 核心概念简介

在上图中,我们需要理解以下几点:

  • Service其实就是一个对外的服务接口,当我们创建一个service时,k8s会自动创建一个全局唯一的Cluster IP,这个IP是一个虚拟的IP,如果尝试使用PING是无法ping通的,但是,它是连通前端Pod和后端服务Pod的桥梁,虽然不能ping通,但是可以通过IP+端口的方式访问后端Pod。后端的Pod组成了一个集群,通过RC的控制来提供永不间断的服务。
  • 在Service的整个生命周期内,Cluster IP不会发生改变,Service Name与Cluster IP形成固定的映射关系(这里一般使用的是DNS,早期使用的是环境变量的方式),这样就不存在服务发现的问题。
  • Service的Cluster IP和Endpoint属于Kubernetes集群内部的地址,无法在集群外部使用,一般会使用Flannel、Weave、Romana等第三方网络服务来实现Pod之间的通讯。这里涉及网络的部分我们会在后续的博文中单独讨论。

  • Kubernetes在每个Node节点上都运行着一个kube-proxy的进程,它扮演了负载均衡器的角色,它负责将对service的请求转发到后端的某个Pod实例上,并在内部实现了负载均衡和会话保持的机制。

外部访问Service

由于Cluster IP是一个内部地址,外部的node 节点无法直接访问到,当我们的外部用户需要访问这些服务时,需要在定义Service时添加NodePort的扩展。下面的文件定义了一个nginx服务添加外部NodePort的示例。
编辑service文件:

apiVersion: v1
kind: Service
metadata: 
  name: nginx
spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 30008   # 对外的用户访问端口,默认范围是30000-32767
  selector:
    app: nginx

当我们创建这个service后,所有的节点上都会有30008的端口映射,访问任意节点都会转发到对应的Pod集群中。

命令参考

  • kubectl get services # 获取service列表,可以指定具体的service
  • kubectl describe services # 显示service的详细信息,可以指定具体的service
  • kubectl get endpoints # 获取Endpoint 信息
  • kubectl delete services mysql # 删除指定的service

Volume

在Kubernetes中,Volume是能被Pod中多个容器访问的共享目录。由于Pod中的容器随时可能会被销毁或重建,对于一些需要数据共享或要持久化保存的数据,我们需要使用单独的存储空间,挂载到对应的Pod上。当容器终止时,Volume中的数据不会丢失。

Volume的定义格式:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}                    # 指定Volume类型

Kubernetes支持多种类型的Volume,下面会对一些常见的Volume做出说明。

本地存储

  • emptyDir: 无需指定宿主机的对应目录路径,由Pod自动创建,Pod移除时数据会永久删除,作为容器间的共享目录。上面的示例就是此格式的Volume。
  • hostPath: Pod挂载宿主机上的文件和目录,可用于永久保存日志,容器内部访问宿主机数据,定义方式如下:
    apiVersion: v1
    kind: Pod
    metadata:
    name: test-pd
    spec:
    containers:
    - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
    volumes:
    - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

网络存储

  • gce Persistemt Disk: 谷歌公有云提供的永久磁盘,这里要求使用谷歌的公有云,节点是GCE虚拟机才行。
  • AWS Elastic Block Store: 与GCE类似,此类型的Volume使用亚马逊公有云提供的EBS数据存储。
  • NFS: NFS网络文件系统的数据存储,这个需要部署NFS服务器,定义如下:
volumes:
  - name: nfs
    nfs:
          server: NFS-SERVER-IP   # NFS 服务器地址
            path: "/"
  • iscsi: 使用iSCSI存储设备上的目录挂载到Pod中。
  • glusterfs: 使用GlusterFS挂载到Pod中。
  • rbd: 使用Ceph对象存储挂载到Pod。
    除此之外,Kubernetes还支持其他的存储方式,具体详情可以查看官方文档。

Persistent Volume

理解并管理五花八门的存储是一件让人头疼的事情,Kubernetes为了解决这些问题,对所有的网络存储进行了抽象,让我们在管理这些存储时不必考虑后端的实现细节,对于不同的网络存储统一使用一套相同的管理手段。
PersistentVolume为用户和管理员提供了一个API,它抽象了如何提供存储以及如何使用它的细节。 为此,引入两个新的API资源:PersistentVolume和PersistentVolumeClaim。
PersistentVolume(PV): 是管理员设置的单独的网络存储集群,它不属于任何节点,但是可以被每个节点访问。 PV是Volumes之类的卷插件,具有独立于的生命周期。 此API对象用于捕获存储实现的细节,如NFS,iSCSI,GlusterFS,CephFS或特定于云提供程序的存储系统。
PersistentVolumeClaim(PVC):是用户对存储的请求的定义。 它与pod相似。pods消耗节点资源,PVC消耗PV资源, Pods可以请求特定级别的资源(CPU和内存)。Claim可以配置特定的存储资源大小和访问模式(例如,多种不同的读写权限),并根据用户定义的需求去使用合适的Persistent Volume。

定义Persistent Volume

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /somepath
    server: 10.2.2.2

accessModes有三种权限:

  • ReadWriteOnce:读写权限,只能被单个Node挂载
  • ReadOnlyMany: 只读权限,允许被多个Node挂载
  • ReadWriteMany: 读写权限、允许被多个Node挂载。

定义Persistent Volume Claim

如果某个Pod想申请某种类型的PV,可以做如下定义:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      stroage: 8Gi

定义之后再Pod的Volume中引用上述PVC:

volumes:
  - name: mypd
    persistentVolumeClaim:
          claimName: myclaim

PV的状态

PV是有状态的对象,有如下几种状态:

  • Available: 空闲状态
  • Bound: 已经绑定到某个PVC上
  • Released: 对应的PVC已经删除,但是资源还没有被释放
  • Failed: PV自动回收失败

Namespace

Namespace(命名空间)是Kubernetes中非常重要的概念,Namespace在很多情况下实现多租户的资源隔离,将集群中的不同资源对象分配到不同的Namespace中,形成逻辑上分组的不同项目,便于不同分组在使用集群资源的同时还能被分别管理。
Kubernetes在启动之后,默认会创建一个default的Namespace:

[root@node-1 ~]# kubectl get namespaces
NAME          STATUS    AGE
default       Active    3d

当我们创建对象时,不指定namespace就会使用默认的default:

[root@node-1 ~]# kubectl get pods --all-namespaces
NAMESPACE     NAME                                READY     STATUS    RESTARTS   AGE
default       mysql-fw2pj                         1/1       Running   2          1d
default       myweb-4jk8j                         1/1       Running   2          1d
default       myweb-68zfl                         1/1       Running   2          1d
default       myweb-bv8pt                         1/1       Running   2          1d
default       nginx-deployment-68dfb7c95b-6zcj4   1/1       Running   2          1d
default       nginx-deployment-68dfb7c95b-g89nd   1/1       Running   3          1d
default       nginx-deployment-68dfb7c95b-zvtkf   1/1       Running   2          1d
kube-system   etcd-node-1                         1/1       Running   7          3d
 ...

Namespace的定义

使用yaml文件定义一个名为deployment的Namespace:

apiVersion: v1
kind: Namespace
metadata:
  name: deployment

当创建对象时,就可以指定这个资源对象属于哪个Namespace:

apiVersion: v1
kind: Pod
metadata:
  name: myweb
  namespace: development

当我们指定非默认的namespace之后,使用如下命令就只能查看默认区域的namespaces:

# kubectl get pods

查看所有namespace区域的对象要使用--all-namespaces参数:

# kubectl get pods --all-namespaces

#也可以指定namespaces:
# kubectl get pods --namespace=kube-system

Horizontal Pod Autoscaler

HPA与之前介绍的RC,deployment一样,也是属于Kubernetes的一种资源对象。HPA通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性的调整目标Pod的副本数。HPA有以下两种方式来度量Pod的负载情况:

  • CPU Utilization Percentage: CPU利用率百分比
  • 自定义的度量指标

CPU的利用率百分比通常是度量的Pod CPU 1min内的平均值,使用Heapster扩展组件来得到这个值,这里定义一个简单的例子:

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: myweb
  namespace: default
spec:
  maxReplicas: 10
  minReplicas: 2
  scaleTargetRef:
    kind: Deployment
    name: myweb
  targetCPUUtilizationPercentage: 90

当Pod 副本的CPU利用率超过90%时会触发自动扩容行为,且Pod数量最多不能超过10,最少不能低于2.
除此之外,也可以使用命令操作:

kubectl autoscale deployment myweb  --cpu-percent=90 --min=1 --max=10

StatefulSet

在Kubernetes系统中,Pod管理的对象如 RC,Deployment,DaemonSet 和Job 都是面向无状态的服务。对于无状态的服务我们可以任意销毁并在任意节点重建,但是在实际的应用中,很多服务是有状态的,特别是对于复杂的中间件集群,如Mysql集群,MongoDB集群,Zookeeper集群,etcd集群等,这些服务都有固定的网络标识,并有持久化的数据存储,这就需要使用StatefulSet对象。
StatefulSet具有以下特性:

  • StatefulSet里的每个Pod都有稳定且唯一的网络标识, 可以用来发现网络中的其他成员。
  • StatefulSet 控制的Pod副本的启停顺序是受控的,比如操作第n个Pod时,前n-1个Pod必须是正常运行的状态。
  • Pod 采用稳定的持久化存储卷,删除Pod时默认不会删除与StatefulSet相关的储存卷。

参考资料:
https://kubernetes.io/docs/concepts/
https://www.cnblogs.com/zhenyuyaodidiao/p/6500720.html
《Kubernets权威指南》