关于 Kubernetes中一些基本概念和术语笔记(一)

写在前面


  • 学习K8s,所以整理记忆
  • 大部分部分内容来源于《Kubernetes权威指南:从Docker到Kubernetes实践全接触》第一章,感兴趣小伙伴可以支持作者一波

一个不欣赏自己的人,是难以快乐的。-------三毛


一、简述

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

K8s中相关资源:随版本变化

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl api-resources
NAME(名字) SHORTNAMES(简称) APIVERSION(版本) NAMESPACED(命名空间隔离) KIND(种类)
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Podpodtemplates
replicationcontrollers rc v1 true ReplicationController
resourcequotas quota v1 true ResourceQuota
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition
apiservices apiregistration.k8s.io/v1 false APIService
controllerrevisions apps/v1 true ControllerRevision
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
tokenreviews authentication.k8s.io/v1 false TokenReview
localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling/v1 true HorizontalPodAutoscaler
cronjobs cj batch/v1 true CronJob
jobs batch/v1 true Jobcertificatesigningrequests
leases coordination.k8s.io/v1 true Lease
bgpconfigurations crd.projectcalico.org/v1 false BGPConfiguration
bgppeers crd.projectcalico.org/v1 false BGPPeer
blockaffinities crd.projectcalico.org/v1 false BlockAffinity
clusterinformations crd.projectcalico.org/v1 false ClusterInformation
felixconfigurations crd.projectcalico.org/v1 false FelixConfiguration
globalnetworkpolicies crd.projectcalico.org/v1 false GlobalNetworkPolicy
globalnetworksets crd.projectcalico.org/v1 false GlobalNetworkSet
hostendpoints crd.projectcalico.org/v1 false HostEndpoint
ipamblocks crd.projectcalico.org/v1 false IPAMBlock
ipamconfigs crd.projectcalico.org/v1 false IPAMConfig
ipamhandles crd.projectcalico.org/v1 false IPAMHandle
ippools crd.projectcalico.org/v1 false IPPool
kubecontrollersconfigurations crd.projectcalico.org/v1 false KubeControllersConfiguration
networkpolicies crd.projectcalico.org/v1 true NetworkPolicy
networksets crd.projectcalico.org/v1 true NetworkSet
endpointslices discovery.k8s.io/v1 true EndpointSlice
events ev events.k8s.io/v1 true Event
flowschemas flowcontrol.apiserver.k8s.io/v1beta1 false FlowSchema
prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1beta1 false PriorityLevelConfiguration
nodes metrics.k8s.io/v1beta1 false NodeMetrics
pods metrics.k8s.io/v1beta1 true PodMetrics
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
runtimeclasses node.k8s.io/v1 false RuntimeClass
poddisruptionbudgets pdb policy/v1 true PodDisruptionBudget
podsecuritypolicies psp policy/v1beta1 false PodSecurityPolicy
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
csidrivers storage.k8s.io/v1 false CSIDriver
csinodes storage.k8s.io/v1 false CSINode
csistoragecapacities storage.k8s.io/v1beta1 true CSIStorageCapacity
storageclasses sc storage.k8s.io/v1 false StorageClass
volumeattachments storage.k8s.io/v1 false VolumeAttachment

二、Kubernetes集群的两种管理角色: MasterNode

MasterNode
在这里插入图片描述

1、Master角色

Kubernetes里的Master指的是 集群控制节点,每个Kubernetes集群里需要有一个Master节点来负责整个集群的管理和控制,基本上Kubernetes的所有控制命令都发给它,它来负责具体的执行过程,我们后面执行的所有命令基本都是在Master节点上运行的。

Master节点通常会占据一个独立的服务器(高可用部署建议用3台服务器),其主要原因是它太重要了,是整个集群的“首脑”,如果宕机或者不可用,那么对集群内容器应用的管理都将失效。Master节点上运行着以下一组关键进程。

Master节点上关键进程
Kubernetes API Server (kube-apiserver) 提供了HTTP Rest接口的关键服务进程,是Kubernetes里所有资源的增、删、改、查等操作的唯一入口,也是集群控制的入口进程。
Kubernetes Controller Manager (kube-controller-manager) Kubernetes里所有资源对象的自动化控制中心,可以理解为资源对象的“大总管”。
Kubernetes Scheduler (kube-scheduler) 负责资源调度(Pod调度)的进程,相当于公交公司的“调度室”。
etcd 在Master节点上还需要启动一个etcd服务,因为Kubernetes里的所有资源对象的数据全部是保存在etcd中的。

除了Master, Kubernetes集群中的其他机器被称为Node节点

2、Node角色

在较早的版本中也被称为MinionoMaster一样, Node节点可以是一台物理主机,也可以是一台虚拟机。 Node节点才是Kubermetes集群中的工作负载节点,每个Node都会被Master分配一些工作负载(Docker容器),当某个Node宕机时,其上的工作负载会被Master自动转移到其他节点上去。

每个Node节点上都运行着以下一组关键进程。

每个Node节点上都运行关键进程
kubelet 负责Pod对应的容器的创建、启停等任务,同时与Master节点密切协作,实现集群管理的基本功能。
kube-proxy 实现Kubernetes Service通信与负载均衡机制的重要组件。)
Docker Engine (docker): Docker引擎,负责本机的容器创建和管理工作。

Node节点可以在运行期间动态增加到Kubernetes集群中,前提是这个节点上已经正确安装、配置和启动了上述关键进程,在默认情况下kubelet会向Master注册自己,这也是Kubernetes推荐的Node管理方式

一旦Node被纳入集群管理范围, kubelet进程就会定时向Master节点汇报自身的情报,例如操作系统、Docker版本、机器的CPU和内存情况,以及当前有哪些Pod在运行等,这样Master可以获知每个Node的资源使用情况,并实现高效均衡的资源调度策略。而某个Node超过指定时间不上报信息时,会被Master判定为“失联", Node的状态被标记为不可用(Not Ready),随后Master会触发“工作负载大转移”的自动流程。

查看集群中的Node节点和节点的详细信息

┌──[root@vms81.liruilongs.github.io]-[~]
└─$kubectl get nodes
NAME                         STATUS     ROLES                  AGE   VERSION
vms81.liruilongs.github.io   Ready      control-plane,master   47d   v1.22.2
vms82.liruilongs.github.io   Ready      worker1                47d   v1.22.2
vms83.liruilongs.github.io   NotReady   worker2                47d   v1.22.2
┌──[root@vms81.liruilongs.github.io]-[~]
└─$kubectl describe  node vms82.liruilongs.github.io
# Node基本信息:名称、标签、创建时间等。
Name:               vms82.liruilongs.github.io
Roles:              worker1
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    disktype=node1
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=vms82.liruilongs.github.io
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/worker1=
Annotations:        dest: 这是一个工作节点
                    kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 192.168.26.82/24
                    projectcalico.org/IPv4IPIPTunnelAddr: 10.244.171.128
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Thu, 07 Oct 2021 01:15:45 +0800
Taints:             <none>
Unschedulable:      false
Lease:
  HolderIdentity:  vms82.liruilongs.github.io
  AcquireTime:     <unset>
  RenewTime:       Tue, 23 Nov 2021 23:08:16 +0800
# Node当前的运行状态, Node启动以后会做一系列的自检工作:
# 比如磁盘是否满了,如果满了就标注OutODisk=True
# 否则继续检查内存是否不足(如果内存不足,就标注MemoryPressure=True)
# 最后一切正常,就设置为Ready状态(Ready=True)
# 该状态表示Node处于健康状态, Master将可以在其上调度新的任务了(如启动Pod)  
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason
        Message
  ----                 ------  -----------------                 ------------------                ------
        -------
  NetworkUnavailable   False   Tue, 23 Nov 2021 23:02:52 +0800   Tue, 23 Nov 2021 23:02:52 +0800   CalicoIsUp
        Calico is running on this node
  MemoryPressure       False   Tue, 23 Nov 2021 23:05:32 +0800   Tue, 23 Nov 2021 22:45:03 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Tue, 23 Nov 2021 23:05:32 +0800   Tue, 23 Nov 2021 22:45:03 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Tue, 23 Nov 2021 23:05:32 +0800   Tue, 23 Nov 2021 22:45:03 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Tue, 23 Nov 2021 23:05:32 +0800   Tue, 23 Nov 2021 22:45:03 +0800   KubeletReady
        kubelet is posting ready status
# Node的主机地址与主机名。        
Addresses:
  InternalIP:  192.168.26.82
  Hostname:    vms82.liruilongs.github.io
# Node上的资源总量:描述Node可用的系统资源,包括CPU、内存数量、最大可调度Pod数量等,注意到目前Kubernetes已经实验性地支持GPU资源分配了(alpha.kubernetes.io/nvidia-gpu=0)
Capacity:
  cpu:                2
  ephemeral-storage:  153525Mi
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             4030172Ki
  pods:               110
# Node可分配资源量:描述Node当前可用于分配的资源量。
Allocatable:
  cpu:                2
  ephemeral-storage:  144884367121
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3927772Ki
  pods:               110
# 主机系统信息:包括主机的唯一标识UUID, Linux kernel版本号、操作系统类型与版本、Kubernetes版本号、kubelet与kube-proxy的版本号等。  
System Info:
  Machine ID:                 1ee67b1c4230405a851cf0107d6e89f5
  System UUID:                C0EA4D56-ED9A-39CF-6942-5B66704F6E6F
  Boot ID:                    b0e42864-9778-4ded-af4c-a88a64f988db
  Kernel Version:             3.10.0-693.el7.x86_64
  OS Image:                   CentOS Linux 7 (Core)
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  docker://20.10.9
  Kubelet Version:            v1.22.2
  Kube-Proxy Version:         v1.22.2
PodCIDR:                      10.244.1.0/24
PodCIDRs:                     10.244.1.0/24
# 当前正在运行的Pod列表概要信息
Non-terminated Pods:          (3 in total)
  Namespace                   Name                              CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                              ------------  ----------  ---------------  -------------  ---
  kube-system                 calico-node-ntm7v                 250m (12%)    0 (0%)      0 (0%)           0 (0%)         47d
  kube-system                 kube-proxy-nzm24                  0 (0%)        0 (0%)      0 (0%)           0 (0%)         35d
  kube-system                 metrics-server-bcfb98c76-wxv5l    0 (0%)        0 (0%)      0 (0%)           0 (0%)         27m
# 已分配的资源使用概要信息,例如资源申请的最低、最大允许使用量占系统总量的百分比。  
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                250m (12%)  0 (0%)
  memory             0 (0%)      0 (0%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-1Gi      0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%)
# Node相关的Event信息。
Events:
  Type    Reason                   Age                 From     Message
  ----    ------                   ----                ----     -------
  Normal  NodeHasSufficientMemory  23m (x3 over 3d4h)  kubelet  Node vms82.liruilongs.github.io status is now: NodeHasSufficientMemory
  Normal  NodeHasNoDiskPressure    23m (x3 over 3d4h)  kubelet  Node vms82.liruilongs.github.io status is now: NodeHasNoDiskPressure
  Normal  NodeHasSufficientPID     23m (x3 over 3d4h)  kubelet  Node vms82.liruilongs.github.io status is now: NodeHasSufficientPID
  Normal  NodeReady                23m (x2 over 3d4h)  kubelet  Node vms82.liruilongs.github.io status is now: NodeReady
┌──[root@vms81.liruilongs.github.io]-[~]
└─$

总结一下,我们要操作k8s,在管理节点那我们怎么操作,我们通过kube-apiserver来接受用户的请求,通过kubu-scheduler来负责资源的调度,是使用work1计算节点来处理还是使用work2计算节点来处理,然后在每个节点上要运行一个代理服务kubelet,用来控制每个节点的操作,但是每个节点的状态,是否健康我们不知道,这里我们需要kube-controller-manager

3、 Pod资源对象

Pod是Kubernetes的最重要也最基本的概念,

每个Pod都有一个特殊的被称为“根容器”的Pause容器Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器。

Pause容器

为什么Kubernetes会设计出一个全新的Pod的概念并且Pod有这样特殊的组成结构?
原因之一:在一组容器作为一个单元的情况下,我们难以对“整体”简单地进行判断及有效地进行行动。引入业务无关并且不易死亡的Pause容器作为Pod的根容器,以它的状态代表整个容器组的状态,就简单、巧妙地解决了这个难题。
原因之二: Pod里的多个业务容器共享Pause容器的IP,共享Pause容器挂接的Volume,这样既简化了密切关联业务容器之间的通信问题,也很好地解决了它们之间的文件共享问题。

Pod IP

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

Kubernetes里,一个Pod里的容器与另外主机上的Pod容器能够直接通信。

普通的Pod静态Pod (Static Pod)

Pod其实有两种类型:普通的Pod静态Pod (Static Pod),如果使用kubeadm的方式部署,静态pod在node节点和master节点创建略有不同

Pod两种类型 描述
静态Pod (Static Pod) 不存放在Kubernetes的etcd存储 里,而是存放在某个具体的Node上的一个具体文件中,并且只在此Node上启动运行。
普通的Pod 一旦被创建,就会被放入到etcd中存储,随后会被Kubernetes Masten调度到某个具体的Node上并进行绑定(Binding),随后该Pod被对应的Node上的kubelet进程实例化成一组相关的Docker容器并启动起来

正常情况下,pod是在master上统一管理的,所谓静态pod就是,即不是由master上创建调度的,是属于node自身特的pod,在node上只要启动kubelet之后,就会自动的创建的pod。这里理解的话,结合java静态熟悉,静态方法理解,即的node节点初始化的时候需要创建的一些pod

比如 kubeadm的安装k8s的话,所以的服务都是通过容器的方式运行的。相比较二进制的方式方便很多,这里的话,那么涉及到master节点的相关组件在没有k8s环境时是如何运行,构建master节点的,这里就涉及到静态pod的问题。

在默认情况下,当Pod里的某个容器停止时,Kubernetes会自动检测到这个问题并且重新启动这个Pod(重启Pod里的所有容器),如果Pod所在的Node宕机,则会将这个Node上的所有Pod重新调度到其他节点上.

在这里插入图片描述

Kubernetes里的所有资源对象都可以采用yaml或者JSON格式的文件来定义或描述,下面是我们在之前Hello World例子里用到的myweb这个Pod的资源定义文件:

apiVersion: v1
kind: Pod                # Pod 定义
metadata: 
  name: myweb            # Pod 名字
  lables:
    name: myweb
spec:                    # 包含的容器组
  containers: 
    - name: myweb
      image: kubeguide/tomcat-app:v1
      ports:
        - containerPort: 8080   
      env:
        - name: MYSQL_SERVICE_HOST
          value: 'mysql'
        - name: MYSQL_SERVICE_PORT
          value: '3306'   

KubernetesEvent概念, Event是一个事件的记录,记录了事件的最早产生时间、最后重现时间、重复次数、发起者、类型,以及导致此事件的原因等众多信息。Event通常会关联到某个具体的资源对象上,是排查故障的重要参考信息,

Pod同样有Event记录,当我们发现某个Pod迟迟无法创建时,可以用kubectl describe pod xxxx来查看它的描述信息,用来定位问题的原因

Kubernetes里,一个计算资源进行配额限定需要设定以下两个参数。

计算资源进行配额限定
Requests:该资源的最小申请量,系统必须满足要求。
Limits:该资源最大允许使用的量,不能被突破,当容器试图使用超过这个量的资源时,可能会被Kubernetes Kill并重启。

通常我们会把Request设置为一个比较小的数值,符合容器平时的工作负载情况下的资源需求,而把Limit设置为峰值负载情况下资源占用的最大量。

比如下面这段定义,表明MysQL容器申请最少0.25个CPU及64MiB内存,在运行过程中MySQL容器所能使用的资源配额为0.5个CPU及128MiB内存:

....
resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"  
...

Pod Pod 周边对象的示意图

在这里插入图片描述

4 、Lable 标签

Label是Kubernetes系统中另外一个核心概念。一个Label是一个key-value的键值对。其中key与value由用户自己指定。

Label可以附加到各种资源对象上,例如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去, Label通常在资源对象定义时确定,也可以在对象创建后动态添加,或者删除。

可以通过给指定的资源对象捆绑一个或多个不同的Label来实现多维度的资源分组管理功能,以便于灵活、方便地进行资源分配、调度、配置、部署等管理工作。

例如:部署不同版本的应用到不同的环境中;或者监控和分析应用(日志记录、监控、告警)等。一些常用的Label示例如下。

版本标签: "release" : "stable", "release":"canary"....
环境标签: "environment":"dev", "environment":"ga","environment":"production"·
架构标签: "ier":"frontend," "tier":"backend", "tier":"midleware"
分区标签: "artition":"customerA", "partition": "customerB".
质量管控标签: "track": "daily","track":"weeky" 

可以通过多个Label Selector表达式的组合实现复杂的条件选择,多个表达式之间用“,”进行分隔即可,几个条件之间是“AND"的关系,即同时满足多个条件,比如下面的例子:

name=标签名
env != 标签名
name in (标签1,标签2)
name not in(标签1)
name in (redis-master, redis-slave):匹配所有具有标签`name=redis-master`或者`name=redis-slave`的资源对象。
name not in (phn-frontend):匹配所有不具有标签name=php-frontend的资源对象。
name=redis-slave, env!=production
name notin (php-frontend),env!=production
apiVersion: v1
kind: Pod
metadata:
  name: myweb
  lables: 
    app: myweb
# 管理对象RC和Service 在 spec 中定义Selector 与 Pod 进行关联。
apiVersion: v1
kind: ReplicationController
metadata:
  name: myweb
spec: 
  replicas: 1
  selector:
    app: myweb
  template:
  ......
apiVersion" v1
kind: Service
metadata: 
  name: myweb
spec: 
  selector:
    app: myweb
  ports:
    port: 8080

新出现的管理对象如Deployment, ReplicaSet, DaemonSetJob则可以在Selector中使用基于集合的筛选条件定义,例如:

selector:
  matchLabels:
     app: myweb
  matchExpressions:
     - {key: tire,operator: In,values: [frontend]}
     - {key: environment, operator: NotIn, values: [dev]}
     

matchLabels用于定义一组Label,与直接写在Selector中作用相同; matchExpressions用于定义一组基于集合的筛选条件,可用的条件运算符包括: In, NotIn, Exists和DoesNotExist.

如果同时设置了matchLabelsmatchExpressions,则两组条件为"AND"关系,即所有条件需要同时满足才能完成Selector的筛选

Label SelectorKubernetes中的重要使用场景有以下几处:

kube-controller进程通过资源对象RC上定义的Label Selector筛选要监控的Pod副本的数量,从而实现Pod副本的数量始终符合预期设定的全自动控制流程

kube-proxy进程通过Service的Label Selector来选择对应的Pod, 自动建立起每个Service到对应Pod的请求转发路由表,从而实现Service的智能负载均衡机制

通过对某些Node定义特定的Label,并且在Pod定义文件中使用NodeSelector这种标签调度策略, kube-scheduler进程可以实现Pod “定向调度”的特性

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: podnodea
  name: podnodea
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: podnodea
    resources: {}
  affinity:
    nodeAffinity: #主机亲和性
      requiredDuringSchedulingIgnoredDuringExecution: #硬策略
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - vms85.liruilongs.github.io
            - vms84.liruilongs.github.io
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

5、 Replication Controller

RC是Kubernetes系统中的核心概念之一,简单来说,它其实是定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值,所以RC的定义包括如下几个部分。

RC的定义
Pod期待的副本数(replicas)
用于筛选目标PodLabel Selector
Pod的副本数量小于预期数量时,用于创建新Pod的Pod模板(template)。

下面是一个完整的RC定义的例子,即确保拥有tier-frontend标签的这个Pod (运行Tomcat容器)在整个Kubernetes集群中始终只有一个副本:

apiVersion: v1
kind: ReplicationController
metadata: 
  name: frontend
spec:
  replicas: 1
  selector:
    tier: frontend
  template: 
    metadata:
      labels:
        app: app-demo
        tier: frontend
    spec:
      containers:
      - name: tomcat-demo
        image: tomcat
        imagePullPolicy: IfNotPresent
        env:
        - name: GET_HOSTS_FROM
          value: dns
        ports:
        - containerPort: 80

当我们定义了一个RC并提交到Kubernetes集群中以后, Master节点上的Controller Manager组件就得到通知,定期巡检系统中当前存活的目标Pod,并确保目标Pod实例的数量刚好等于此RC的期望值,如果有过多的Pod副本在运行,系统就会停掉一些Pod,否则系统就会再自动创建一些Pod

通过RC, Kubernetes实现了用户应用集群的高可用性,并且大大减少了系统管理员在传统IT环境中需要完成的许多手工运维工作(如主机监控脚本、应用监控脚本、故障恢复脚本等)

下面我们以3个Node节点的集群为例,说明Kubernetes如何通过RC来实现Pod副本数量自动控制的机制。假如我们的RC里定义redis-slave这个Pod需要保持3个副本,系统将可能在其中的两个Node上创建Pod。

在运行时,我们可以通过 修改RC的副本数量,来实现Pod的动态缩放(Scaling)功能,这可以通过执行kubectl scale命令来一键完成:

kubectl scale rc redsi-slave --replicas=3

需要注意的是,删除RC并不会影响通过该RC已创建好的Pod,为了删除所有Pod,可以设置replicas的值为0,然后更新该RC。另外, kubectl提供了stop和delete命令来一次性删除RC和RC控制的全部Pod。

应用升级时,通常会通过Build一个新的Docker镜像,并用新的镜像版本来替代旧的版本的方式达到目的。在系统升级的过程中,我们希望是平滑的方式,比如当前系统中10个对应的旧版本的Pod,最佳的方式是旧版本的Pod每次停止一个,同时创建一个新版本的Pod,在整个升级过程中,此消彼长,而运行中的Pod数量始终是10个,通过RC的机制, Kubernetes很容易就实现了这种高级实用的特性,被称为“滚动升级” (Rolling Update)

6、 Deployment

Deployment是Kubernetes v1.2引入的新概念,引入的目的是为了更好地解决Pod的编排问题。

Deployment相对于RC的一个最大升级是我们可以随时知道当前Pod “部署”的进度。实际上由于一个Pod的创建、调度、绑定节点及在目标Node上启动对应的容器这一完整过程需要一定的时间,所以我们期待系统启动N个Pod副本的目标状态,实际上是一个连续变化的“部署过程"导致的最终状态。

Deployment的典型使用场景有以下几个。

Deployment的典型使用场景
创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建过程。
检查Deployment的状态来看部署动作是否完成(Pod副本的数量是否达到预期的值)
更新Deployment以创建新的Pod (比如镜像升级)。
如果当前Deployment不稳定,则回滚到一个早先的Deployment版本。
暂停Deployment以便于一次性修改多个PodTemplateSpec的配置项,之后再恢复Deployment,进行新的发布。
扩展Deployment以应对高负载。
查看Deployment的状态,以此作为发布是否成功的指标。
清理不再需要的旧版本ReplicaSets。

Deployment的定义与Replica Set的定义很类似,除了API声明与Kind类型等有所区别:

apiversion: extensions/vlbetal       apiversion: v1
kind: Deployment                     kind: ReplicaSet
metadata:                            metadata:
  name: nginx-deployment               name: nginx-repset

创建一个 tomcat-deployment.yaml Deployment 描述文件:

apiVersion: extensions/v1betal
kind: Deployment
metadata: 
  name: frontend
spec: 
  replicas: 1
  selector: 
  matchLabels: 
    tier: frontend
  matchExpressions:
    - {key: tier, operator: In,value: [frontend]}
  template:
    metadata:
      labels:
        app: app-demo
        tier: frontend
    spec:
      containers:
      - name: tomcat-demo
        images: tomcat
        imagePullPolicy:  IfNotPresent
        ports:
        - containerPort: 8080  

运行如下命令创建 Deployment:

kubectl create -f tomcat-deploment.yaml

对上述输出中涉及的数量解释如下。

数量 解释
DESIRED Pod副本数量的期望值,即Deployment里定义的Replica.
CURRENT 当前Replica的值,实际上是Deployment所创建的Replica Set里的Replica值,这个值不断增加,直到达到DESIRED为止,表明整个部署过程完成。
UP-TO-DATE 最新版本的Pod的副本数量,用于指示在滚动升级的过程中,有多少个Pod副本已经成功升级。
AVAILABLE 当前集群中可用的Pod副本数量,即集群中当前存活的Pod数量。

运行下述命令查看对应的Replica Set,我们看到它的命名与Deployment的名字有关系:

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get rs -A
NAMESPACE     NAME                                 DESIRED   CURRENT   READY   AGE
kube-system   calico-kube-controllers-78d6f96c7b   1         1         1       47d
kube-system   coredns-545d6fc579                   0         0         0       47d
kube-system   coredns-7f6cbbb7b8                   2         2         2       36d
kube-system   kuboard-78dccb7d9f                   1         1         1       11d
kube-system   metrics-server-bcfb98c76
(完)