当前位置: 首页 > 科技观察

16个核心概念带你入门Kubernetes

时间:2023-03-13 00:15:16 科技观察

Kubernetes是谷歌开源的容器集群管理系统,是谷歌多年的大规模容器管理技术Borg的开源版本。主要功能包括:基于容器的应用部署、维护和滚动升级负载均衡和服务发现跨机器、跨区域的集群调度无状态服务和有状态服务的自动伸缩广泛的卷支持插件机制,确保可伸缩性Kubernetes已开发发展非常迅速,已经成为容器编排领域的领导者。接下来,我们将解释Kubernetes涉及的一些主要概念。1.PodPod是密切相关的容器的集合。它支持多个容器在一个Pod中共享网络和文件系统。它可以通过进程间通信和文件共享,以简单高效的方式完成服务。它是Kubernetes调度的基本单元。Pod的设计理念是每个Pod都有一个独一无二的IP。Pod具有以下特点:包含共享IPC、Network和UTC命名空间的多个容器,并且可以通过localhost直接通信。Pod中的所有容器都可以访问共享Volume,并且可以访问共享数据。进程发送SIGTERM,等待一段时间(graceperiod),然后强行停止还在运行的进程。特权容器(通过SecurityContext配置)有更改系统配置的权限(大量应用在网络插件中)支持三种重启策略(restartPolicy),分别为:Always、OnFailure、Never支持三种镜像拉取策略(imagePullPolicy),即:Always、Never、IfNotPresent资源限制,Kubernetes通过CGroup限制容器的CPU和内存资源,可以设置request和limit值为healthyCheck,提供了两个健康检查探针,分别是livenessProbe和redinessProbe.前者用于检测容器是否存活。如果检测失败,则按照重启策略进行重启操作。后者用于检查容器状态是否正常。如果检查容器的状态不正常,则请求不会到达PodInit容器,在所有容器运行之前执行。常用于初始化和配置容器生命周期钩子函数,用于监听容器生命周期中的特定事件,并在事件发生时执行注册的回调函数,支持两个钩子函数:postStart和preStop,前者在容器启动后执行,后者在容器停止前执行2.Namespace命名空间(namespace)是一组资源和对象的抽象集合,比如Objects系统内分为不同的项目组或用户组。常见的pod、services、replicaSets、deployments都属于某个namespace(默认为default),而nodes、persistentVolumes等不属于任何namespace。常用命名空间操作:kubectlgetnamespace,查询所有命名空间kubectlcreatenamespacens-name,创建命名空间kubectldeletenamespacens-name,删除命名空间删除命名空间时,需要注意以下几点:删除命名空间会自动删除属于该命名空间的所有资源。default和kube-system命名空间无法删除。PersistentVolumes不属于任何命名空间,但PersistentVolumeClaim属于特定的命名空间。Events是否属于命名空间取决于生成事件的对象。3、NodeNode是Pod实际运行的宿主机,可以是物理机也可以是虚拟机。Node本质上不是Kubernetes创建的,Kubernetes只是管理Node上的资源。为了管理Pod,至少需要在每个Node节点上运行容器运行时(Docker)、kubelet和kube-proxy服务。常用的节点操作:kubectlgetnodes,查询所有节点kubectlcordon$nodename,将节点标记为不可调度kubectluncordon$nodename,将节点标记为可调度设置taint后,与Pod存在互斥关系,允许Node拒绝Pod的调度执行,甚至驱逐Node上已经存在的Pod。各个taint的组成:key=value:effect,目前的tainteffect支持以下三个选项:thistaintNoExecuteonthetaintedNode:表示k8s不会将Pod调度到有污点的Node上,并会驱逐该Node上已有的Pod。常用命令如下:kubectltaintnodenode0key1=value1:NoShedule,即node0设置不可调度的污点kubectltaintnodenode0key-,移除node0上key值为key1的污点kubectltaintnodenode1node-role。kubernetes.io/master=:NoSchedule,为kube-master节点node1设置不可调度污点kubectltaintnode1node-role.kubernetes.io/master=PreferNoSchedule,为kube-master节点设置尽可能不可调度污点容忍度(Tolerations)kube主节点。设置了taints的节点会根据taint的影响进行交互:NoSchedule、PreferNoSchedule、NoExecute和Pod由于排斥关系,Pod在一定程度上不会被调度到Node。但是我们可以在Pod上设置容忍度(Toleration),也就是说设置了容忍度的Pod可以容忍taint的存在,可以调度到有taint的Node上。4.ServiceService是对一组提供相同功能的Pod的抽象,并为它们提供统一的入口。借助Service应用,可以轻松实现服务发现和负载均衡,实现应用的零宕机升级。Service通过标签来选择后端Pod,一般配合ReplicaSet或者Deployment来保证后端容器的正常运行。service有四种,默认是ClusterIP:ClusterIP:默认类型,自动分配一个只能在集群内访问的虚拟IPNodePort:在ClusterIP的基础上,在每台机器上绑定一个端口给Service,所以可以通过NodeIP:NodePort访问服务LoadBalancer:在NodePort的基础上,借助云提供商创建一个外部负载均衡器,将请求转发到NodeIP:NodePortExternalName:将服务转发到指定域name通过DNSCNAME记录另外,也可以将已有的服务以Service的形式添加到Kubernetes集群中。只需要在创建Service时不指定Label选择器,而是在创建后手动为Service添加端点。5.Volume存储卷默认情况下,容器的数据是非持久化的,容器消亡后数据会丢失。因此,Docker提供了Volume机制来持久化存储数据。Kubernetes提供了更强大的Volume机制和插件来解决容器数据持久化和容器间数据共享的问题。Kubernetes存储卷的生命周期与Pod绑定。容器挂掉后,当Kubelet再次重启容器时,volume中的数据还在。当pod被删除时,volume将被清理。数据是否丢失取决于具体的Volume类型。比如emptyDir的数据会丢失,但是PV的数据不会丢失。目前Kubernetes主要支持以下几种Volume类型:emptyDir:Pod存在,emptyDir会存在,容器故障不会导致emptyDir目录下的数据丢失,但是如果pod被删除或者迁移,emptyDir也会被删除。hostPath:hostPath允许将Node上的文件系统挂载到Pod上。NFS(NetworkFileSystem):网络文件系统,在Kubernetes中很容易配置,可以将NFS挂载到Pod上,NFS中的数据可以永久保存,并且NFS支持同时写操作。Glusterfs:和NFS一样,是一个网络文件系统。Kubernetes可以将glusterfs挂载到Pod上并永久保存。cephfs:分布式网络文件系统,可以挂载到Pod并永久存储。subpath:Pod多个容器使用同一个Volume时,常使用secret:密钥管理,可以加密敏感信息,保存并挂载到Pod中6.PersistentVolume(PV)PersistentVolume(PV)是集群中的一块网络存储。和Node一样,也是集群的资源。PersistentVolume(PV)和PersistentVolumeClaim(PVC)提供方便的持久卷:PV提供网络存储资源,PVC请求存储资源并挂载到Pod中。PV的三种访问模式(accessModes):ReadWriteOnce(RWO):最基本的方法,可以读写,但只支持单个Pod挂载。ReadOnlyMany(ROX):可以被多个Pod以只读方式挂载。ReadWriteMany(RWX):这个存储可以以读写的方式被多个Pod共享。并非每种类型的存储都支持这三种方法。比如共享方式目前支持的比较少,比较常用的是NFS。PVC绑定PV的时候,通常会根据两个条件进行绑定,一个是存储大小,一个是访问方式。PV恢复策略也有三种(persistentVolumeReclaimPolicy)Retain,不清理,keeptheVolume(需要手动清理)Recycle,删除数据,即rm-rf/thevolume/*(仅NFS和HostPath支持)Delete,删除存储资源7、DeploymentNoneStatefulapplications一般来说,我们不需要手动创建Pod实例,而是使用更高层次的抽象或定义来管理Pod。对于无状态应用,Kubernetes使用DeloymentController对象与之对应。其典型应用场景包括:定义Deployment创建Pod和ReplicaSets滚动升级和回滚应用伸缩暂停和继续Deployment常用的操作命令如下:kubectlrunwww--image=10.0.0.183:5000/hanker/www:0.0.1--port=8080生成部署对象kubectlgetdeployment--all-namespaces查找部署kubectldescribedeploymentwww查看部署kubectleditdeploymentwww编辑部署定义kubectldeletedeploymentwww删除部署kubectlscaledeployment/www--replicas=2伸缩缩容操作,即修改Deployment下的Pod实例数kubectlsetimagedeployment/nginx-deploymentnginx=nginx:1.9.1更新镜像kubectlrolloutundodeployment/nginx-deploymentrollbackoperationkubectlrolloutstatusdeployment/nginx-deployment查看回滚进度kubectlautoscaledeploymentnginx-deployment--min=10--max=15--cpu-percent=80启用horizontalscaling(HPA-horizo??ntalpodautoscaling),设置最小和最大实例数和目标cpu使用率kubectlrolloutpausedeployment/nginx-deployment暂停更新DeploymentkubectlrolloutresumedeploynginxResumeupdateDeploymentupdatestrategy.spec.strategy指的是用新Pod替换旧Pod的策略。RollingUpdate有两种滚动升级方式,可以保证应用在升级过程中。正常对外提供服务。Recreate重建策略会在创建新的Pod之前杀死所有现有的Pod。Deployment与ReplicaSet的关系使用Deployment创建ReplicaSet。ReplicaSet在后台创建pod,检查启动状态以查看它是成功还是失败。当执行更新操作时,将创建一个新的ReplicaSet,Deployment将以受控的速率将pod从旧的ReplicaSet移动到新的ReplicaSet。8.StatefulSet有状态应用Deployments和ReplicaSets都是为无状态服务设计的,所以StatefulSet是为有状态服务设计的,其应用场景包括:稳定的持久化存储,即Pod重新调度后仍然可以访问相同的持久化数据,以及基于PVC的稳定网络标志,即Pod重新调度后,其PodName和HostName保持不变,基于HeadlessService(即没有ClusterIP的Service)实现有序部署和有序扩展,即Pod是有序的,部署或扩展时必须按照定义的顺序依次执行操作(即从0到N-1,下一个Pod运行前所有之前的Pod必须处于Running和Ready状态),基于init容器实现有序收缩,有序删除(即从N-1到0)支持两种更新策略:wPod是在用户手动删除这些旧的Pod后自动创建的。这是默认的更新策略,兼容v1.6RollingUpdate的行为:当.spec.template更新时,旧的Pod会被自动删除,并创建一个新的Pod来替换它。在更新过程中,这些Pod以相反的顺序执行,即删除、创建,等待Pod变为Ready后再更新下一个Pod。9.DaemonSetDaemonSet保证一个Pod实例运行在特定或所有Node节点上,常用于部署一些集群日志收集、监控或其他系统管理应用。典型应用包括:日志采集,如fluentd、logstash等系统监控,如PrometheusNodeExporter,collectd等系统程序,如kube-proxy、kube-dns、glusterd、ceph、ingress-controller等。Node节点DaemonSet会忽略Node处于不可调度状态,有两种方式指定Pod只运行在指定的Node节点上:nodeSelector:只调度到与指定标签匹配的NodenodeAffinity:功能更丰富的Node选择器,如支持集合操作条件Pod所在的Node目前支持两种策略OnDelete:默认策略,模板更新后,只有手动删除旧Pod后才会创建新的PodRollingUpdate:DaemonSet模板更新后,oldPod自动删除,创建新的Pod我们在Pod10和IngressKubernetes中主要使用以下两种机制进行负载均衡:Service:使用Service提供集群内的负载均衡,kube-proxy负责均衡服务请求到后端的Pod。IngressController:使用Ingress提供集群外部负载均衡Service和Pod的IP,只能在集群内访问。集群外的请求需要通过负载均衡转发到服务所在节点暴露的端口,再由kube-proxy通过边缘路由器转发到相关的Pod。Ingress可以为服务提供URL、负载均衡和HTTP以供外部访问集群。路由等。为了配置这些Ingress规则,集群管理员需要部署一个IngressController,它监控Ingress和服务的变化,根据规则配置负载均衡,并提供访问入口。常用的ingresscontroller:nginxtraefikKongOpenresty11、Job&CronJob任务和定时任务Job负责批量处理短期的一次性任务(shortlived>CronJob是定时任务,类似于Linux系统的crontab,运行指定的时间期任务。12.HPA(Horizo??ntalPodAutoscaling)Horizo??ntalPodAutoscaling可以根据CPU、内存使用率或应用自定义指标(支持replicationcontroller、deployment和replicaset)自动扩展Pod的数量。controlmanager默认每30s查询一次metrics的资源使用情况(可通过--horizo??ntal-pod-autoscaler-sync-period修改),支持三种metrics。定义的Pod指标计算为原始值。自定义对象指标支持两种指标查询方式:Heapster和自定义RESTAPI。支持多个指标。HPA可以通过以下命令创建:kubectlautoscaledeploymentphp-apache--cpu-percent=50--min=1--max=1013,ServiceAccountServiceaccount是为了方便Pod中进程调用KubernetesAPI而设计的或其他外部服务。ServiceAccount为服务机制提供了一种方便的认证,但不关心授权问题。可以配合RBAC(RoleBasedAccessControl)对ServiceAccount进行认证,通过定义Role、RoleBinding、ClusterRole、ClusterRoleBinding对sa进行授权。14.SecretKeySercert-Secretkey解决了密码、token、key等敏感数据的配置问题,而不会将这些敏感数据暴露给镜像或PodSpecs。Secret可以用作Volume或环境变量。分为以下三种:ServiceAccount:用于访问KubernetesAPI,由Kubernetes自动创建,会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录下;Opaque:base64编码格式的Secret,用于存储密码、密钥等;kubernetes.io/dockerconfigjson:用于存储私有docker注册表的身份验证信息。15.ConfigMap配置中心ConfigMap用于保存键值对的配置数据,可用于保存单个属性或一个配置文件。ConfigMap类似于secret,但是可以更方便的处理不包含敏感信息的字符串。ConfigMap在Pod中可以通过三种方式使用:设置环境变量、设置容器命令行参数、直接挂载Volume中的文件或目录。可以使用kubectlcreateconfigmap从文件、目录或键值字符串创建创建ConfigMap。也可以通过kubectlcreate-fvalue.yaml创建。16.资源配额资源配额(ResourceQuotas)是一种用来限制用户资源使用的机制。资源配额有以下几种类型:计算资源,包括cpu和内存cpu、limits.cpu、requests.cpumemory、limits.memory、requests.memory存储资源,包括存储资源总量和资源总量指定存储类requests.storage:存储资源总量,比如500Gipersistentvolumeclaims:pvc的个数可以创建的对象的pod,replicationcontrollers,configmaps,secretsresourcequotas,persistentvolumeclaimesservices,services.loadbalancers,services.nodeports其工作原理是:资源配额应用于Namespaces,每个Namespace最多只能有一个ResourceQuota对象。启用计算资源配额后,创建容器时必须配置计算资源请求或限制(默认值也可以用LimitRange设置),用户超过限制后禁止创建新资源