写在前面
学习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集群的两种管理角色: Master
和Node
Master 和Node |
---|
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角色
在较早的版本中也被称为Miniono
与Master
一样, 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'
Kubernetes
的Event
概念, 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
, DaemonSet
和Job
则可以在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
.
如果同时设置了matchLabels
和matchExpressions
,则两组条件为"AND"
关系,即所有条件需要同时满足才能完成Selector的筛选
。
Label Selector
在Kubernetes
中的重要使用场景有以下几处:
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) |
用于筛选目标Pod 的Label 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
对上述输出中涉及的数量解释如下。
数量 | 解释 |
---|---|
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(完)