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=httpd
  template:                    ##Pod的模板信息,根据模板信息来创建Pod
    metadata:                  ##Pod的元数据
      labels:                  ##Pod的标签
        app: httpd             ##标签app=httpd
    spec:                      ##容器的信息
      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: mysql
  serviceName: mysql
  replicas: 3
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
      - name: init-mysql
        image: mysql:5.7
        command:
        - 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]}   #表示拿取第一个数字0
          echo [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   #如果取到的数字为0
            cp /mnt/config-map/master.cnf /mnt/conf.d/  #拷贝master
          else
            cp /mnt/config-map/slave.cnf /mnt/conf.d/    #否则拷贝slave
          fi   
        volumeMounts:
        - name: conf
          mountPath: /mnt/conf.d
        - name: config-map
          mountPath: /mnt/config-map
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ALLOW_EMPTY_PASSWORD
          value: "1"
        ports:
        - name: mysql
          containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql   #挂在点里创建一个子目录
        - name: conf
          mountPath: /etc/mysql/conf.d
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
        livenessProbe:
          exec:
            command: ["mysqladmin", "ping"]
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            # Check we can execute queries over TCP (skip-networking is off).
            command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
          initialDelaySeconds: 5
          periodSeconds: 2
          timeoutSeconds: 1
      volumes:
      - name: conf
        emptyDir: {}
      - name: config-map
        configMap:
          name: mysql
  volumeClaimTemplates:      
  - metadata:
      name: data
    spec:
      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: pi
        image: 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: crontab
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo hello world
          restartPolicy: OnFailure
查看kubectl get CronJob
删除kubectl delete CronJob crontab
6,endpoints
apiVersion: v1
kind: Endpoints
metadata:
  name: mysql
subsets:
  - addresses:
    - ip: 10.98.4.200
    ports:
    - port: 3306
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  clusterIP: 10.0.0.200
  ports:
  - port: 3306
    targetPort: 3306
    protocol: 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: NodePort
   ports:
 - port: 80
     protocol: TCP
     targetPort: 80
     nodePort: 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-system
     	mode: "ipvs"/mod
    
  • 二进制集群

vim k8s根目录/cfg/kube-proxy-config.yml
                       kind: KubeProxyConfiguration
                          mode: "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-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  sessionAffinity: ClientIP
  type: 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.200
    ports:
    - port: 3306
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  clusterIP: 10.0.0.200
  ports:
  - port: 3306
    targetPort: 3306
    protocol: TCP

你可能感兴趣的:(kubernetes,kubernetes,容器,云原生)