kubernetes 资源管理核心概念
k8s的设计理念—分层架构:
- 云原生生态系统是在接口层之上的kubernetes集群管理调度生态系统,有两个范畴:
kubernetes内部:CRI、CNI、CSI、镜像仓库
kubernetes外部:监控、日志、CI/CD、配置管理等 - 接口层包括kubectl命令行客户端工具和SDK等客户端访问接口。
- 管理层实现自动化(如pod弹性伸缩、动态存储卷创建和回收)和策略管理(资源限制、RBAC授权、NetworkPolicy等,主要解决项目之间的pod隔离、网络安全和自动伸缩等功能。)
- 应用层实现服务部署(无状态应用如nginx使用deployment、有状态应用如MySQL主从使用statefulSet)和路由(通过service实现服务之间调用)
- 核心层包括kubernetes的API、控制器、service、namespace、node等,是运行pod的基础环境.
k8s的设计理念—API设计原则:https://www.kubernetes.org.cn/kubernetes设计理念 - 所有API应该是声明式的。
- API对象是彼此互补而且可组合的(高内聚-将相同的功能放在同一个API下、即各API独立性强,低耦合-不同API之间没有强依赖关系,即各API尽量没有依赖关系)。
- 高层API以客户端操作意图为基础设计。
- 低层API根据高层API的控制需要设计。
- 尽量避免简单封装,不要有在外部API无法显式知道的内部隐藏的机制。
- API操作复杂度与对象数量成正比。
- API对象状态不能依赖于网络连接状态。
- 尽量避免让操作机制依赖于全局状态,因为在分布式系统中要保证全局状态的同步是非常困难的。
kubernetes API简介:
内置API: 部署好kubernetes集群后自带的API接口.
自定义资源:CRD(Custom Resource Definition),部署kubernetes之后通过安装其它组件等方式扩展出来的API。
/apis/myapi/v1/pods:分类;API组;API版本;资源对象;
kubernetes内置资源对象简介:
资源类型:资源名称
资源对象:Deployment、ReplicaSet、ReplicationController、StatefulSet、DaemonSet、Pod、Job、CronJob、
HorizontalPodAutoscaling、Node、Namespace、Service、Ingress、Label、CustomResourceDefinition、Deployment、ReplicaSet、ReplicationController、
StatefulSet、DaemonSet、Pod、Job、CronJob、HorizontalPodAutoscaling、Node、Namespace、Service、Ingress、Label、CustomResourceDefinition
存储对象: StorageClass、PersistentVolume、PersistentVolumeClaim、Secret、ConfigMap
策略对象: SecurityContext、ResourceQuota、LimitRange
身份对象: ServiceAccount、Role、ClusterRole
kubernetes 资源对象详解及示例
kubernetes 的几个重要概念:
- 资源对象:kubernetes基于声明式API,和资源对象进行交互。
- yaml文件:为了方便后期管理,通过使用yaml文件通过API管理资源对象。
- yaml必需字段:
- apiVersion - 创建该对象所使用的 Kubernetes API 的版本
- kind - 想要创建的对象的类型
- metadata - 定义识别对象唯一性的数据,包括一个 name 名称 、可选的 namespace
- spec:定义资源对象的详细规范信息(统一的label标签、容器名称、镜像、端口映射等)
- status(Pod创建完成后k8s自动生成status状态)
yaml文件及必需字段:
- 每个API对象都有3大类属性:元数据metadata、规范spec和状态status。
- spec和status的区别:spec是期望状态 status是实际状态
Pod: - pod是k8s中的最小单元。
- 一个pod中可以运行一个容器,也可以运行多个容器。(取决于服务启动的最小依赖环境)
- 运行多个容器的话,这些容器是一起被调度的。
- Pod的生命周期是短暂的,不会自愈,是用完就销毁的实体。
- 一般我们是通过Controller来创建和管理pod的
Pod-容器类型-sidecar:
sidecar模式:在不侵入主容器的前提下,可以进行服务功能扩展、一般都是一些共性的能力,比如说: -
日志收集,例如fluentd、filebeat -
监控指标收集,https://github.com/nginxinc/nginx-prometheus-exporter -
探活:检查某些主容器组件是不是处于正常运行中; -
其他辅助性的工作,比如拷贝文件、下载文件等;
Pod-容器类型-Adapter:
- Adapter模式:适配器模式(入口)、主要用于外部访问入口、负责转换主应用程序和外部系统之间的数据格式或通信协议,无论是转换数据格式、聚合指标还是
- 编排复杂的工作流,适配器容器都充当中间转发请求的作用,实现跨不同客户端和服务端环境的相互访问(异构系统场景)。
Pod-容器类型-Ambassador: - Ambassador模式:大使模式、主要是针对主容器对外的访问请求进行处理,通过Ambassador容器可以屏蔽主容器对外访问的一些复杂性问题,给主容器带来更简单的访问方式。
Job与cronjob:
job:https://kubernetes.io/docs/concepts/workloads/controllers/job/
cronjob:https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/
cronjob 默认保留最近3个历史记录
RC/RS 副本控制器:
- Replication Controller:副本控制器(selector = !=) #第一代pod副本控制器:
- https://kubernetes.io/zh/docs/concepts/workloads/controllers/replicationcontroller/
- https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/labels/
- ReplicaSet:副本控制器,和副本控制器的区别是:对选择器的支持(selector 还支持in notin) #第二代pod副本控制器:
- https://kubernetes.io/zh/docs/concepts/workloads/controllers/replicaset/
- replicas=3 #声明副本数
- selector: #精确匹配副本数
- labels:
-
myserver=app1
Deployment 副本控制器:
Deployment:比rs更高一级的控制器,除了有rs的功能之外,还有很多高级功能,
比如说最重要的:滚动升级、回滚等 #第三代pod控制器
- 滚动更新:支持逐步更新应用程序实例,确保在更新过程中应用保持可用。
- 版本回滚:如果新版本出现问题,可以轻松回滚到之前的稳定版本。
- 副本管理:通过指定副本数,确保应用程序始终运行指定数量的实例。
- 自愈能力:自动检测和替换失败的 Pod,确保应用程序的高可用性。
- 声明式配置:用户只需定义所需的状态,Deployment 控制器会自动实现该状态。
https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/
版本回退:kubectl rollout undo deployment -n myserver nginx-deployment
基于deployment控制器,熟练实现部署nginx服务、镜像更新、回滚、副本调整、ENV环境变量传递
nginx服务部署:kubectl apply -f nginx-deployment
镜像更新:image: registry.cn-hangzhou.aliyuncs.com/myhubregistry/nginx:1.27.0-alpine3.19 #镜像地址,修改镜像版本即可;
回滚:kubectl rollout undo deployment -n myserver nginx-deployment
副本数调整:replicas: 1 #创建出的pod的副本数,即多少个pod,默认值为1
ENV环境变量传递: env: #配置环境变量- name: "password" #变量名称。必须要用引号引起来value: "123456" #当前变量的值- name: "age" #另一个变量名称value: "18" #另一个变量的值
kind: Deployment #类型,是deployment控制器,kubectl explain Deployment
apiVersion: apps/v1 #API版本,# kubectl explain Deployment.apiVersion
metadata: #Deployment控制器的元数据信息,kubectl explain Deployment.metadatalabels: #自定义pod的标签,# kubectl explain Deployment.metadata.labelsapp: myserver-nginx-deployment-label #标签名称为app值为myserver-nginx-deployment-label,后面会用到此标签 name: myserver-nginx-deployment #pod的名称namespace: myserver #pod的namespace,默认是defaule
spec: #定义deployment中容器的详细信息,kubectl explain Deployment.specreplicas: 1 #创建出的pod的副本数,即多少个pod,默认值为1selector: #定义标签选择器matchLabels: #定义匹配的标签,必须要设置app: myserver-nginx-selector #匹配的目标标签,template: #定义模板,必须定义,模板是起到描述要创建的pod的作用metadata: #定义模板元数据labels: #定义模板label,Deployment.spec.template.metadata.labelsapp: myserver-nginx-selector #定义标签,等于Deployment.spec.selector.matchLabelsspec: #定义pod信息containers: #定义pod中容器列表,可以多个至少一个,pod不能动态增减容器- name: myserver-nginx-container #容器名称image: registry.cn-hangzhou.aliyuncs.com/myhubregistry/nginx:1.27.0-alpine3.19 #镜像地址#command: ["/apps/tomcat/bin/run_tomcat.sh"] #容器启动执行的命令或脚本#imagePullPolicy: IfNotPresentimagePullPolicy: Always #拉取镜像策略ports: #定义容器端口列表- containerPort: 80 #定义一个端口protocol: TCP #端口协议name: http #端口名称- containerPort: 443 #定义一个端口protocol: TCP #端口协议name: https #端口名称env: #配置环境变量- name: "password" #变量名称。必须要用引号引起来value: "123456" #当前变量的值- name: "age" #另一个变量名称value: "18" #另一个变量的值resources: #对资源的请求设置和限制设置limits: #资源限制设置,上限cpu: 500m #cpu的限制,单位为core数,可以写0.5或者500m等CPU压缩值memory: 2Gi #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数requests: #资源请求的设置cpu: 200m #cpu请求数,容器启动的初始可用数量,可以写0.5或者500m等CPU压缩值memory: 512Mi #内存请求大小,容器启动的初始可用数量,用于调度pod时候使用
Service 简介:
由于pod重建之后ip就变了,因此pod之间使用pod的IP直接访问会出现无法访问的问题,而service则解耦了服务和应用,service的实现方式就是通过label标签动态匹配后端endpoint。
- 负载均衡:自动将流量分发到后端的 Pod上,确保流量均匀分布。
- 稳定的网络标识:为一组动态变化的 Pod提供一个稳定的IP地址和 DNS 名称。
- 服务发现:通过Service可以访问新扩容的pod副本。
- 多种类型:支持 ClusterIP、NodePort、LoadBalancer 和 ExternalName 等多种类型,以满足不同的网络访问需求。
kube-proxy监听着k8s-apiserver,一旦service资源发生变化(调k8s-api修改service信息),kube-proxy就会对指定的ipvs/iptables规则的调整,这样就保证service的最新状态。
kube-proxy有三种调度模型 - userspace:k8s1.1之前
- iptables:1.2-k8s1.11之前
- ipvs:k8s 1.11之后,如果没有开启ipvs,则自动降级为iptables
service类型: - ClusterIP:用于内部服务基于service name的访问。
- NodePort:用于kubernetes集群以外的服务主动访问运行在kubernetes集群内部的服务。
- LoadBalancer:用于公有云环境的服务暴露。
- ExternalName:用于将k8s集群外部的服务映射至k8s集群内部访问,从而让集群内部的pod能够通过固定的servicename访问集群外部的服务,有时候也用于将不同namespace之间的pod通过ExternalName进行访问。
编写一个部署nginx服务的YAML文件并通过nodeport类型的svc实现访问(熟悉YAML文件的特性)
kind: Service #类型为service
apiVersion: v1 #service API版本, service.apiVersion
metadata: #定义service元数据,service.metadatalabels: #自定义标签,service.metadata.labelsapp: myserver-nginx #定义service标签的内容name: myserver-nginx-service #定义service的名称,此名称会被DNS解析namespace: myserver #该service隶属于的namespaces名称,即把service创建到哪个namespace里面
spec: #定义service的详细信息,service.spectype: NodePort #service的类型,定义服务的访问方式,默认为ClusterIP, service.spec.typeports: #定义访问端口, service.spec.ports- name: http #定义一个端口名称port: 80 #service 80端口protocol: TCP #协议类型targetPort: 80 #目标pod的端口nodePort: 30001 #node节点暴露的端口- name: https #SSL 端口port: 443 #service 443端口protocol: TCP #端口协议targetPort: 443 #目标pod端口nodePort: 30043 #node节点暴露的SSL端口selector: #service的标签选择器,定义要访问的目标podapp: myserver-nginx-selector #将流量路到选择的pod上,须等于Deployment.spec.selector.matchLabels
结合上面的deployment的yaml 启动SVC后不管后面几个pod都能通过svc地址访问: http(https): //nodeip:port
