本文主要是介绍kubernetes里面那些事————控制器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
资源-控制器
- 一,控制器作用
- 二,控制器类型
- 2.1,Deployment:无状态应用部署
- 2.2,DaemonSet:确保所有Node运行同一个pod
- 2.3,StatefulSet:有状态应用部署
- 2.4,Job:一次性任务
- 2.5,CronJob:定时任务
- 2.6,pod
- 2.7,service
- 2.8,replicaset
- 2.9,endpoints
- 三,控制器yaml应用
- 3.1,Deployment
- 3.2,DaemonSet
- 3.3,StatefulSet
- 3.4,Job
- 3.5,Crontab
- 3.7,Service控制器
- 3.7.1,service三种常用类型
- 3.7.2,service代理模式实现方式
- 3.7.3,Service DNS名称
- 3.8,endpoints
SharedInformer 作为控制器的代理,可以缓解入口压力
一,控制器作用
管理pod对象
使用标签与pod关联
控制器实现了pod运维,例如滚动更新、伸缩副本管理,维护pod状态等
二,控制器类型
2.1,Deployment:无状态应用部署
功能:管理pod和replicas
应用场景: 网站、API、微服务
2.2,DaemonSet:确保所有Node运行同一个pod
功能:在每一个node上运行一个pod
新加入的node也同样会自动运行一个pod
应用场景:网络插件(kube-proxy、calico)、其他agent应用
2.3,StatefulSet:有状态应用部署
结合headless service使用
功能特性:
- 稳定的、唯一的网络标识符
- 稳定的、持久化的存储
- 有序的、优雅的部署和伸缩
- 有序的、优雅的删除和终止
- 有序的、自动滚动更新
Headless Service 特性:
未配置 ClusterIP,不通过 SVC 分配的 VIP 负载均衡访问 Pod
直接以 DNS 记录方式解析到 Pod 对应的IP地址
应用场景:
- 稳定的持久化存储,即 Pod 重新调度后,还能够访问到相同的持久化数据,基于PVC来实现
- 稳定的网络标识,即 Pod 重新调度后其 PodName 和 HostName 不变,基于 Headless Service (即没有Cluster IP的Service)来实现
- 有序部署、有序扩展,即Pod是有序的,在部署和扩展时,要按照定义的顺序依次进行 (即从 0 到N - 1, 在下一个Pod 运行前,所有 Pod 必须是 Running 和 Ready 状态),基于 Init Containers 来实现
- 有序收缩、有序删除(即从 N-1 到 0)
2.4,Job:一次性任务
功能:一次性执行
应用场景:离线数据处理
2.5,CronJob:定时任务
功能:定时任务
应用场景:通知、备份类任务
2.6,pod
Kubernetes应用程序的最小化部署和管理单元。
可以是一个容器也可以是多个容器组成
2.7,service
2.8,replicaset
维持一组pod副本的运行,保证运行数量
监听pod运行状态,pod增加或者故障减少时维持副本数量
2.9,endpoints
代理集群外部服务到kubernetes内部访问
三,控制器yaml应用
3.1,Deployment
Deployment进行pod升级时,采用滚动更新方式
更新策略:
-
maxSurge:滚动更新过程中最大pod副本数,确保在更新时启动的pod数量比期望(replicas)pod数量最大多出25%
-
maxUnavailable:滚动更新过程中最大不可用pod副本数,确保在更新时最大25%pod数量不可用,即确保75%pod是可用状态
yaml例:
apiVersion: apps/v1 ##版本
kind: Deployment ##类型
metadata: ##Deployment的元数据name: httpd ##Deployment的名字labels: ##标签app: httpd ##标签app=httpd
spec: ##Pod的信息replicas: 3 ##Pod的副本数selector: ##标签选择器matchLabels: ##查找匹配的标签app: httpd ##app=httpdtemplate: ##Pod的模板信息,根据模板信息来创建Podmetadata: ##Pod的元数据labels: ##Pod的标签app: httpd ##标签app=httpdspec: ##容器的信息containers: ##容器- name: httpd ##容器名image: httpd ##容器所需的镜像ports: ##端口- containerPort: 80 ##容器暴露的端口
3.2,DaemonSet
yaml 例:
apiVersion: apps/v1
kind: DaemonSet
...
3.3,StatefulSet
管理策略:spec.podManagementPolicy
- OrderedReady:按顺序性就绪,默认
- Parallel:并行就绪/终止
更新策略:.spec.updateStrategy.type
- OnDelete: 只有手动删除旧的 Pod 才会创建新的 Pod
- RollingUpdate:自动删除旧的 Pod 并创建新的Pod,如果更新发生了错误,这次“滚动更新”就会停止
dns域名命名规则
myservice.mynamespace.svc.cluster.local
解析podIP地址
nslookup -query=A demodb-0.demodb
demodb-0.demodb.default.svc.cluster.local
域名解析
kubectl create deployment dnsutils --image=tutum/dnsutils -- sleep infinity
#kubectl exec dnsutils-77ccd77fb6-czfd2 -- nslookup redis-cluster-master.default.svc.cluster.local
kubectl exec dnsutils-77ccd77fb6-czfd2 -- nslookup redis-cluster-master
yaml例
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql
spec:selector:matchLabels:app: mysqlserviceName: mysqlreplicas: 3template:metadata:labels:app: mysqlspec:initContainers:- name: init-mysqlimage: mysql:5.7command:- bash- "-c"- |set -ex# Generate mysql server-id from pod ordinal index.[[ `hostname` =~ -([0-9]+)$ ]] || exit 1 #过滤第一个pod名mysql,其中hostname表示容器内pod名字ordinal=${BASH_REMATCH[1]} #表示拿取第一个数字0echo [mysqld] > /mnt/conf.d/server-id.cnf #创建一个server-id.cnf 文件,往里面写mysqld表示这个文件里的配置针对server生效# Add an offset to avoid reserved server-id=0 value.echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf #往server-id.conf 追加一条server-id=100+上面取到的数字# Copy appropriate conf.d files from config-map to emptyDir. 拷贝conf.d 文件到空卷if [[ $ordinal -eq 0 ]]; then #如果取到的数字为0cp /mnt/config-map/master.cnf /mnt/conf.d/ #拷贝masterelsecp /mnt/config-map/slave.cnf /mnt/conf.d/ #否则拷贝slavefi volumeMounts:- name: confmountPath: /mnt/conf.d- name: config-mapmountPath: /mnt/config-mapcontainers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ALLOW_EMPTY_PASSWORDvalue: "1"ports:- name: mysqlcontainerPort: 3306volumeMounts:- name: datamountPath: /var/lib/mysqlsubPath: mysql #挂在点里创建一个子目录- name: confmountPath: /etc/mysql/conf.dresources:requests:cpu: 500mmemory: 1GilivenessProbe:exec:command: ["mysqladmin", "ping"]initialDelaySeconds: 30periodSeconds: 10timeoutSeconds: 5readinessProbe:exec:# Check we can execute queries over TCP (skip-networking is off).command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]initialDelaySeconds: 5periodSeconds: 2timeoutSeconds: 1volumes:- name: confemptyDir: {}- name: config-mapconfigMap:name: mysqlvolumeClaimTemplates: - metadata:name: dataspec:accessModes: ["ReadWriteOnce"]storageClassName: "managed-nfs-storage"resources:requests:storage: 5Gi
3.4,Job
重启策略使用Never
例:
apiVersion: batch/v1
kind: Job
metadata:name: pi
spec:template:spec:containers:- name: piimage: perl command: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"]restartPolicy: Never
3.5,Crontab
每次运行会启动一个pod,但是停止后不占用资源
重启策略使用OnFailure
例:
apiVersion: batch/v1
kind: CronJob
metadata:name: crontab
spec:schedule: "*/1 * * * *"jobTemplate:spec:template:spec:containers:- name: crontabimage: busyboxargs:- /bin/sh- -c- date; echo hello worldrestartPolicy: OnFailure
查看kubectl get CronJob
删除kubectl delete CronJob crontab
6,endpoints
apiVersion: v1
kind: Endpoints
metadata:name: mysql
subsets:- addresses:- ip: 10.98.4.200ports:- port: 3306
---
apiVersion: v1
kind: Service
metadata:name: mysql
spec:clusterIP: 10.0.0.200ports:- port: 3306targetPort: 3306protocol: TCP
3.6 pod
3.7,Service控制器
service存在的意义
- 服务发现:防止pod失联,找到提供同一个服务的pod
- 负载均衡:定义一组pod的访问策略
pod和service的关系
- 资源类型中的标签选择器和pod模板中的标签是一致的,service通过它们关联一组pod
- service为一组pod提供负载均衡能力
headless service
- Headless服务就是一组Pod组成的只供集群内访问(没有ClusterIP)的Service,一般结合StatefulSet用于部署有状态应用的场景。
- 在某些场景中,无需对外提供访问能力,只需要在内部找到自己想找到的Pod资源时,可以通过Headless Service来实现。
- 这种不具有ClusterIP的Service资源就是Headless Service,该 Service 的请求流量不需要
kube-proxy 处理,也不会有负载均衡和路由规则,而是由ClusterDNS的域名解析机制直接去访问固定的Pod资源。
3.7.1,service三种常用类型
- ClusterIP:集群内部使用(pod)
默认,只分配一个稳定的IP地址,即VIP,只能在集群内部访问
yaml使用:
spec:type:ClusterIP
可访问对象:
集群中其他应用
集群中其他应用的外部机器
-
NodePort:对外暴露应用(浏览器)
一个端口只能一个服务使用,如果指定端口需要提前规划
只支持四层负载均衡
在每个节点启用一个端口来暴露服务,可以在集群外部访问。也会分配一个稳定内部集群IP地址
访问地址:任意nodeIP:NodePort
默认NodePort端口范围:30000-32767
yaml例:
spec:type: NodePortports:- port: 80protocol: TCPtargetPort: 80nodePort: 30009
selector:app: web
- LoadBalancer:对外暴露应用,适用公有云
与NodePort相似,在每个节点上启用一个端口来暴露服务。除此之外,kubernetes会请求底层云平台(例如阿里云、腾讯云,AWS等)上的负载均衡器,将每个Node的服务([NodeIP]:[NodePort])作为后端添加进去
3.7.2,service代理模式实现方式
- iptables 默认使用此方式
特点:
灵活、功能强大
规则遍历匹配和更新,呈线性时延
适合小规模流量
- ipvs
特点:
工作在内核态,有更好性能
调度算法丰富:rr、wrr、lc、wlc、ip hash等
适合大规模流量
修改方式
-
kubeadm集群
kubectl edit cm kube-proxy -n kube-systemmode: "ipvs"/mod
-
二进制集群
vim k8s根目录/cfg/kube-proxy-config.ymlkind: KubeProxyConfigurationmode: "ipvs"
3.7.3,Service DNS名称
CoreDNS:一个DNS服务器,kubernetes默认采用,以pod部署在集群中
CoreDNS服务监视kubernetes API,为每一个Service创建DNS记录用于域名解析
3.7.4,service负载均衡策略
- k8s service 负载均衡策略
在Kubernetes中,Service资源是用来提供一种方式,使得一组Pod能够被统一的方式访问。Service定义了如何访问它的Pod,通过分配一个集群内独一无二的IP地址。Service的负载均衡功能是基于内核的虚拟服务器(IPVS)或者iptables来实现的。 Kubernetes Service的负载均衡策略主要有以下几种:
轮询(RoundRobin):每个新的连接由轮询方式分配到下一个Pod
会话保持(SessionAffinity):来自同一个客户端的请求被定向到同一个Pod。
最少连接(LeastConnections):负载均衡器选择连接数最少的Pod。
请求最少(Shortest Expected Delay):负载均衡器选择预期等待时间最短的Pod。
随机(Random):负载均衡器随机选择一个Pod。
默认情况下,Kubernetes使用的是轮询策略。在Service的配置中设置spec.sessionAffinity为ClientIP,以启用会话保持。
会话保持策略:
apiVersion: v1
kind: Service
metadata:name: my-service
spec:selector:app: my-appports:- protocol: TCPport: 80targetPort: 9376sessionAffinity: ClientIPtype: ClusterIP
在这个配置中,sessionAffinity: ClientIP 表示启用了基于客户端IP的会话保持。type: ClusterIP 表示Service类型为集群内部的服务,它会分配一个集群内部的IP地址。
请注意,Kubernetes默认的负载均衡器实现不支持最少连接或请求最少的策略。这些高级功能可能需要第三方的负载均衡器或Ingress控制器来实现。
3.8,endpoints
apiVersion: v1
kind: Endpoints
metadata:name: mysql
subsets:- addresses:- ip: 10.98.4.200ports:- port: 3306
---
apiVersion: v1
kind: Service
metadata:name: mysql
spec:clusterIP: 10.0.0.200ports:- port: 3306targetPort: 3306protocol: TCP
这篇关于kubernetes里面那些事————控制器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!