关于 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
v1trueBinding
componentstatusescsv1falseComponentStatus
configmapscmv1trueConfigMap
endpointsepv1trueEndpoints
eventsevv1trueEvent
limitrangeslimitsv1trueLimitRange
namespacesnsv1falseNamespace
nodesnov1falseNode
persistentvolumeclaimspvcv1truePersistentVolumeClaim
persistentvolumespvv1falsePersistentVolume
podspov1truePodpodtemplates
replicationcontrollersrcv1trueReplicationController
resourcequotasquotav1trueResourceQuota
secrets
v1trueSecret
serviceaccountssav1trueServiceAccount
servicessvcv1trueService
mutatingwebhookconfigurations
admissionregistration.k8s.io/v1falseMutatingWebhookConfiguration
validatingwebhookconfigurations
admissionregistration.k8s.io/v1falseValidatingWebhookConfiguration
customresourcedefinitionscrd,crdsapiextensions.k8s.io/v1falseCustomResourceDefinition
apiservices
apiregistration.k8s.io/v1falseAPIService
controllerrevisions
apps/v1trueControllerRevision
daemonsetsdsapps/v1trueDaemonSet
deploymentsdeployapps/v1trueDeployment
replicasetsrsapps/v1trueReplicaSet
statefulsetsstsapps/v1trueStatefulSet
tokenreviews
authentication.k8s.io/v1falseTokenReview
localsubjectaccessreviews
authorization.k8s.io/v1trueLocalSubjectAccessReview
selfsubjectaccessreviews
authorization.k8s.io/v1falseSelfSubjectAccessReview
selfsubjectrulesreviews
authorization.k8s.io/v1falseSelfSubjectRulesReview
subjectaccessreviews
authorization.k8s.io/v1falseSubjectAccessReview
horizontalpodautoscalershpaautoscaling/v1trueHorizontalPodAutoscaler
cronjobscjbatch/v1trueCronJob
jobs
batch/v1trueJobcertificatesigningrequests
leases
coordination.k8s.io/v1trueLease
bgpconfigurations
crd.projectcalico.org/v1falseBGPConfiguration
bgppeers
crd.projectcalico.org/v1falseBGPPeer
blockaffinities
crd.projectcalico.org/v1falseBlockAffinity
clusterinformations
crd.projectcalico.org/v1falseClusterInformation
felixconfigurations
crd.projectcalico.org/v1falseFelixConfiguration
globalnetworkpolicies
crd.projectcalico.org/v1falseGlobalNetworkPolicy
globalnetworksets
crd.projectcalico.org/v1falseGlobalNetworkSet
hostendpoints
crd.projectcalico.org/v1falseHostEndpoint
ipamblocks
crd.projectcalico.org/v1falseIPAMBlock
ipamconfigs
crd.projectcalico.org/v1falseIPAMConfig
ipamhandles
crd.projectcalico.org/v1falseIPAMHandle
ippools
crd.projectcalico.org/v1falseIPPool
kubecontrollersconfigurations
crd.projectcalico.org/v1falseKubeControllersConfiguration
networkpolicies
crd.projectcalico.org/v1trueNetworkPolicy
networksets
crd.projectcalico.org/v1trueNetworkSet
endpointslices
discovery.k8s.io/v1trueEndpointSlice
eventsevevents.k8s.io/v1trueEvent
flowschemas
flowcontrol.apiserver.k8s.io/v1beta1falseFlowSchema
prioritylevelconfigurations
flowcontrol.apiserver.k8s.io/v1beta1falsePriorityLevelConfiguration
nodes
metrics.k8s.io/v1beta1falseNodeMetrics
pods
metrics.k8s.io/v1beta1truePodMetrics
ingressclasses
networking.k8s.io/v1falseIngressClass
ingressesingnetworking.k8s.io/v1trueIngress
networkpoliciesnetpolnetworking.k8s.io/v1trueNetworkPolicy
runtimeclasses
node.k8s.io/v1falseRuntimeClass
poddisruptionbudgetspdbpolicy/v1truePodDisruptionBudget
podsecuritypoliciespsppolicy/v1beta1falsePodSecurityPolicy
clusterrolebindings
rbac.authorization.k8s.io/v1falseClusterRoleBinding
clusterroles
rbac.authorization.k8s.io/v1falseClusterRole
rolebindings
rbac.authorization.k8s.io/v1trueRoleBinding
roles
rbac.authorization.k8s.io/v1trueRole
priorityclassespcscheduling.k8s.io/v1falsePriorityClass
csidrivers
storage.k8s.io/v1falseCSIDriver
csinodes
storage.k8s.io/v1falseCSINode
csistoragecapacities
storage.k8s.io/v1beta1trueCSIStorageCapacity
storageclassesscstorage.k8s.io/v1falseStorageClass
volumeattachments
storage.k8s.io/v1falseVolumeAttachment

二、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=linuxdisktype=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: 0projectcalico.org/IPv4Address: 192.168.26.82/24
                    projectcalico.org/IPv4IPIPTunnelAddr: 10.244.171.128
                    volumes.kubernetes.io/controller-managed-attach-detach: trueCreationTimestamp:  Thu, 07 Oct 2021 01:15:45 +0800
Taints:             <none>Unschedulable:      falseLease:
  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: v1kind: Pod                # Pod 定义metadata: 
  name: myweb            # Pod 名字
  lables:name: mywebspec:                    # 包含的容器组
  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: v1kind: Podmetadata:
  name: myweb  lables: app: myweb# 管理对象RC和Service 在 spec 中定义Selector 与 Pod 进行关联。apiVersion: v1kind: ReplicationControllermetadata:
  name: mywebspec: 
  replicas: 1
  selector:app: myweb  template:
  ...略...apiVersion" v1kind: Servicemetadata: 
  name: mywebspec: 
  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: v1kind: Podmetadata:
  creationTimestamp: null
  labels:run: podnodea  name: podnodeaspec:
  containers:
  - image: nginximagePullPolicy: IfNotPresentname: podnodearesources: {}
  affinity:nodeAffinity: #主机亲和性  requiredDuringSchedulingIgnoredDuringExecution: #硬策略nodeSelectorTerms:- matchExpressions:  - key: kubernetes.io/hostnameoperator: Invalues:- vms85.liruilongs.github.io- vms84.liruilongs.github.io  dnsPolicy: ClusterFirst  restartPolicy: Alwaysstatus: {}

5、 Replication Controller

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

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

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

apiVersion: v1kind: ReplicationControllermetadata: 
  name: frontendspec:
  replicas: 1
  selector:tier: frontend  template: metadata:  labels:app: app-demotier: frontendspec:  containers:  - name: tomcat-demoimage: tomcatimagePullPolicy: IfNotPresentenv:- name: GET_HOSTS_FROM          value: dnsports:- 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: v1kind: Deployment                     kind: ReplicaSetmetadata:                            metadata:
  name: nginx-deployment               name: nginx-repset

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

apiVersion: extensions/v1betalkind: Deploymentmetadata: 
  name: frontendspec: 
  replicas: 1
  selector: 
  matchLabels: tier: frontend  matchExpressions:- {key: tier, operator: In,value: [frontend]}
  template:metadata:  labels:app: app-demotier: frontendspec:  containers:  - name: tomcat-demoimages: tomcatimagePullPolicy:  IfNotPresentports:- containerPort: 8080

运行如下命令创建 Deployment:

kubectl create -f tomcat-deploment.yaml

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

数量解释
DESIREDPod副本数量的期望值,即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
(完)