K8s学习五(资源调度_2)

StatefulSet(有状态)

  • 有状态就是对本地有依赖,比如数据库的信息,删除之后,就没有之前的数据信息了,有依赖,如下图:
    在这里插入图片描述

  • statefulset 命令可以用sts来简写,比如命令kubectl get sts

定义配置文件
  • 配置文件如下:
---
apiVersion: v1 # 上面和后面的---是yaml文件嵌套了一段yaml文件
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet # StatefulSet类型
metadata:
  name: web # StatefulSet对象的名字
spec:
  serviceName: "nginx" # 使用哪个service来管理dns
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports: # 容器内要暴露的端口
        - containerPort: 80  # 具体暴露的端口号
          name: web # 该端口配置的名字
        volumeMounts: # 加载数据卷
        - name: www # 指定加载哪个数据卷
          mountPath: /usr/share/nginx/html # 加载到容器中哪个目录
  volumeClaimTemplates: # 数据卷模板
  - metadata: # 数据卷描述
      name: www # 数据卷的名称
      annotations: # 数据卷的注解
        volume.alpha.kubernetes.io/storage-class: anything
    spec: # 数据卷的规约
      accessModes: [ "ReadWriteOnce" ] #访问模式
      resources:
        requests:
          storage: 1Gi #需要1g存储资源

  • 创建之后看各个情况,pvc是持久卷声明(Persistent Volume Claim)
    在这里插入图片描述

  • 但是因为,目前存储卷没有加载成功,后面学到了再加,因此先删掉yaml文件中有关的信息
    在这里插入图片描述

  • 删了之后的为:


---
apiVersion: v1 # 上面和后面的---是yaml文件嵌套了一段yaml文件
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet # StatefulSet类型
metadata:
  name: web # StatefulSet对象的名字
spec:
  serviceName: "nginx" # 使用哪个service来管理dns
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports: # 容器内要暴露的端口
        - containerPort: 80  # 具体暴露的端口号
          name: web # 该端口配置的名字
  • 如果执行替换操作,就是执行这个命令kubectl replace -f sts web web.yaml,但是这里有的不能被替换,系统阻止,因此还是先删再create

  • 然后就已经running
    在这里插入图片描述

  • 访问两个pod,不能直接在主机上ping通,因为服务是在容器内的,映射到容器的端口。运行一个新的容器去访问

  • 运行一个busybox容器,这个容器包含很多linux常用工具,运行


kubectl run -it --image busybox:1.28.4 dns-test /bin/sh

# kubectl run: 这是 kubectl 命令的一部分,用于在集群中运行一个容器。
# -it: 这是两个选项的结合。-i 表示要保持标准输入流 (stdin) 打开,-t 表示要分配一个伪终端 (tty)。这两个选项结合起来允许你与容器进行交互。
# --image busybox:1.28.4: 指定要使用的容器镜像,这里是 BusyBox 的特定版本 1.28.4。
# dns-test: 这是 Pod 的名称,你为 Pod 指定的名称。
# /bin/bash: 这是容器中要运行的命令,这里是启动一个 Bash shell。

# 可加 --restart=Never 为永不重启, --rm为退出就删掉

  • 用这个容器就可以访问到,sts的访问为statefulSetName-{0…N-1}.serviceName.namespace.svc.cluster.local,可以只到statefulSetName-{0…N-1}.serviceName,后面省略,下图中的命令行就是用省略的,红框内为完整的格式。
    在这里插入图片描述
扩容与缩容
  • 扩容缩容可以用下面两条命令来实现:
 kubectl scale statefulset web --replicas=5
 
 kubectl patch statefulset web -p '{"spec":{"replicas":3}}'
  • 扩容缩容后查看stskubectl describe sts web
    在这里插入图片描述
滚动更新
  • 镜像更新(目前还不支持直接更新 image,比如set image,需要 patch 来间接实现,或者用kubectl edit sts web), 如
kubectl patch sts web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:1.9.1"}]'

# kubectl patch sts web: 这部分表示你要对名为 "web" 的 StatefulSet 执行 patch 操作。

# --type='json': 这个选项指定了使用 JSON 格式的补丁。

# -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:1.9.1"}]': 这是 JSON 补丁的内容,它包含了一组操作。在这个例子中,操作是 replace,它指示要替换某个路径上的值。具体来说:

# op: replace: 表示执行替换操作。

# path: /spec/template/spec/containers/0/image: 这是 JSON 路径,指定了要替换的目标位置,即 StatefulSet 中第一个容器的镜像路径。

# value: "nginx:1.9.1": 这是要替换的新值,即希望更新成的容器镜像。

  • 查看信息
 kubectl describe sts web  
 kubectl rollout history sts web
 kubectl rollout history sts web --revision=1
 kubectl rollout status sts web
  • 更新的策略有两种,RollingUpdate和OnDelete
RollingUpdate
  • StatefulSet 也可以采用滚动更新策略,同样是修改 pod template 属性后会触发更新,但是由于 pod 是有序的,在 StatefulSet 中更新时是基于 pod 的顺序倒序更新的
  • 基于RollingUpdate可以实现灰度发布,又叫金丝雀发布
利用滚动更新中的 partition 属性,可以实现简易的灰度发布的效果

例如我们有 5 个 pod,如果当前 partition 设置为 3,那么此时滚动更新时,只会更新那些 序号 >= 3 的 pod

利用该机制,我们可以通过控制 partition 的值,来决定只更新其中一部分 pod,确认没有问题后再主键增大更新的 pod 数量,最终实现全部 pod 更新

也就是先让一小部分更新,确认更新之后,版本稳定不会出问题之后,再将剩下的滚动更新或者多步金丝雀发布。

如图:在这里插入图片描述

  • 下面进行操作
# 先将副本扩到5个,方便操作
kubectl scale sts web --replicas=5

#然后修改partition和image镜像版本号
kubectl edit sts web

在这里插入图片描述

  • 然后查看,确实只变动了3和4,然后0,1,2都没有更新
    在这里插入图片描述
OnDelete
  • 只有在 pod 被删除时会进行更新操作

  • 将更新策略改为ondelete,并且修改镜像版本为1.9.1
    在这里插入图片描述

  • 保存并退出,查看信息,kubectl describe po web-0发现镜像没有更改
    在这里插入图片描述

  • 当删除web-0时kubectl delete po web-0,然后再查看信息发现,镜像版本变了,也就是发生了更新。
    在这里插入图片描述

在这里插入图片描述

  • 并且刚删除,就会自动更新出来一个pod
级联删除和非级联删除
# 删除 StatefulSet 和 Headless Service
# 级联删除:删除 statefulset 时会同时删除 pods
kubectl delete statefulset web
# 非级联删除:删除 statefulset 时不会删除 pods,删除 sts 后,pods 就没人管了,此时再删除 pod 不会重建的
kubectl deelte sts web --cascade=false
# 删除 service
kubectl delete service nginx

在这里插入图片描述

DaemonSet

  • 介绍
    在这里插入图片描述

  • DaemonSet 保证在每个 Node 上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。典型的应用包括:

    • 日志收集,比如 fluentd,logstash 等
    • 系统监控,比如 Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond 等
    • 系统程序,比如 kube-proxy, kube-dns, glusterd, ceph 等

在这里插入图片描述

部署Fluent日志收集程序
  • 指定node节点有三种,分别是nodeSelector,nodeAffinity和podAffinity,后两种后面章节介绍,这节讲nodeSelector

  • 配置文件:

apiVersion: apps/v1
kind: DaemonSet # 创建daemonset资源
metadata:
  name: fluentd # 名字
spec:
  selector:
    matchLabels:
      app: logging
  template:
    metadata:
      labels:
        app: logging
        id: fluentd
      name: fluentd
    spec:
      containers:
      - name: fluentd-es
        image: agilestacks/fluentd-elasticsearch:v1.3.0
        env: # 环境变量
         - name: FLUENTD_ARGS # 环境变量的key
           value: -qq # 环境变量的value
        volumeMounts: # 加载数据卷,避免数据丢失
         - name: containers # 数据卷的名字
           mountPath: /var/lib/docker/containers # 将数据卷挂载到容器的哪个目录
         - name: varlog
           mountPath: /varlog
      volumes: # 定义数据卷
         - hostPath: # 数据卷类型,主机路径的模式,也就是与node共享目录
             path: /var/lib/docker/containers # 定义数据卷的名称
           name: containers
         - hostPath:
             path: /var/log
           name: varlog


# 解释一下labels:
# selector 中的标签条件:

# 这些标签条件用于选择在哪些节点上运行 DaemonSet 的 Pod。
# selector 中的标签条件是用来匹配节点上的Pod.
# template 中定义的标签:

# 这些标签是在每个选择的节点上运行的 Pod 的元数据。
# 这些标签在 template 中定义,它们是在创建 Pod 时将分配给 Pod 的标签。


  • 然后运行yaml文件,查看信息
kubectl create -f fluentd-ds.yaml

kubectl get ds
kubectl get daemonset

daemonset# kubectl describe po fluentd-9xl99
  • 如下图
    在这里插入图片描述

  • 然后去查看更详细的信息,发现虽然没有指定具体在哪个node部署,但是在每一个非master节点上面都部署有一个

kubectl get po -o wide

kubectl get nodes

kubectl get nodes --show-labels
  • 如图:
    在这里插入图片描述

  • 然后我们给node-1加上一个type=microservices标签,然后在yaml文件中编辑,在template中加上nodeSelector,因为是匹配node然后创造一个pod,所以应该是template。然后来测试daemonset。

kubectl label no node-1 type=microservices

kubectl get nodes --show-labels


kubectl edit ds fluentd

kubectl get ds

get po -l app=logging -o wide
  • 增加如下
    在这里插入图片描述

  • 发现在yaml文件中配置node选择之后,因为给node-1加入了对应的标签,所以daemonset会自动在node-1上部署pod
    在这里插入图片描述

  • 然后给node-2也加上标签,会发现立即也会在node-2上部署pod
    在这里插入图片描述

  • 注:不建议使用 RollingUpdate,建议使用 OnDelete 模式,这样避免频繁更新 ds

HPV 自动扩容/缩容
  • Pod 自动扩容:可以根据 CPU 使用率或自定义指标(metrics)自动对 Pod 进行扩/缩容。

  • 控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况

  • 支持三种metrics类型

    • 预定义metrics(比如Pod的CPU)以利用率的方式计算
    • 自定义的Pod metrics,以原始值(raw value)的方式计算
    • 自定义的object metrics
  • 支持两种metrics查询方式:Heapster和自定义的REST API

  • 支持多metrics

  • 通过观察 pod 的 cpu、内存使用率或自定义 metrics 指标进行自动的扩容或缩容 pod 的数量。

  • 通常用于 Deployment,不适用于无法扩/缩容的对象,如 DaemonSet,也可以用于statefulset

  • 控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况

开启服务指标
  • 安装服务指标相关东西,要不然下面的kubectl top po指令用不了
# 下载 metrics-server 组件配置文件
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -O metrics-server-components.yaml

# 修改镜像地址为国内的地址
sed -i 's/k8s.gcr.io\/metrics-server/registry.cn-hangzhou.aliyuncs.com\/google_containers/g' metrics-server-components.yaml

# 修改容器的 tls 配置,不验证 tls,在 containers 的 args 参数中增加 --kubelet-insecure-tls 参数

# 安装组件
kubectl apply -f metrics-server-components.yaml

# 查看 pod 状态
kubectl get pods --all-namespaces | grep metrics


# 执行完上面的操作之后就可以直接使用kubectl top pods

cpu,内存指标监控
  • 实现 cpu 或内存的监控,首先有个前提条件是该对象必须配置了 resources.requests.cpu 或 resources.requests.memory 才可以,可以配置当 cpu/memory 达到上述配置的百分比后进行扩容或缩容
  • 这里以deploy为例,加入resources的限制之后创建deploy
    在这里插入图片描述
流程:
创建一个 HPA:
先准备一个好一个有做资源限制的 deployment
执行命令 kubectl autoscale deploy nginx-deploy --cpu-percent=20 --min=2 --max=5

可以通过 kubectl top pod来查看cpu,内存使用情况

通过 kubectl get hpa 可以获取 HPA 信息

测试:
自己创建一个svc
找到对应服务的 service,编写循环测试脚本提升内存与 cpu 负载
while true; do wget -q -O- http://<ip:port> > /dev/null ; done

可以通过多台机器执行上述命令,增加负载,当超过负载后可以查看 pods 的扩容情况 kubectl get pods

查看 pods 资源使用情况
kubectl top pods

扩容测试完成后,再关闭循环执行的指令,让 cpu 占用率降下来,然后过 5 分钟后查看自动缩容情况

  • 自己创建的svc:
apiVersion: v1 # 上面和后面的---是yaml文件嵌套了一段yaml文件
kind: Service
metadata:
  name: nginx-svc
  labels:
    app: nginx
spec:
  selector:
    app: nginx-deploy # 选择label为这个的pod
  ports:
  - port: 80
    targetPort: 80
    name: web
  type: NodePort


  • 一开始为:

在这里插入图片描述

  • 执行循环命令后,自动扩容到了5个,:

在这里插入图片描述

在这里插入图片描述

  • 然后停止循环,等待缩容

在这里插入图片描述

在这里插入图片描述

上一篇:jquery 日期格式转化


下一篇:idea链接gitlab的token到期