kubernetes02

news2024/11/17 6:48:06

pod

pod生命周期

pod的状态

1.挂起pending:API server创建了pod资源对象已存入etcd中,但它尚未被调度完成,或者仍处于从仓库下载镜像的过程中
2.运行中running:pod已经被调度到某节点,并且所有容器都已经被kubelet创建完成
3.成功complet:pod中所有容器都已经成功终止并且不会重启
4.失败failed:pod中所有的容器都已经终止了,并且至少有一个容器是因为失败终止的,即容器以非0状态退出或者被系统禁止
5.未知unknown:APIserver无法正常获取到pod对象的状态信息,通常是由于无法与所在的工作节点的kubelet通信所致
6.ImgPullErr:镜像拉取失败
7.Containercreating:容器创建中

初始化容器

在这里插入图片描述
在这里插入图片描述
1.k8s的初始化容器(initContainer)优先级都是高于主容器(container)的。无论容器写在初始化容器前还是写在初始化容器后,会最先执行的都是初始化容器。只有初始化容器执行成功后才可以启动主容器。
2.初始化容器的应用场景应该是多pod。比如:mysql和业务分开两个pod。此时,业务pod添加初始化容器,初始化容器执行telnet,检查mysql是否启动了。若mysql启动,则业务pod启动;否则业务pod等待mysql启动。
定义pod-initcontainer-demo01.yml

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod-initcontainer
  namespace: mayikt-sit
spec:
  containers:
  - name: mayikt-main-container
    image: nginx:1.17.9
    ports:
    - name: nginx-port
      containerPort: 80
  initContainers:
  - name: mayikt-mysql
    image: busybox:1.30  
    command: [ "/bin/sh","-c","sleep 40;"]   
  - name: mayikt-redis
    image: busybox:1.30

busybox:1.30启动成功之后 是会立即停止40S 之后这个容器才会停止
当我们启动mayikt-main-container 容器 必须等待 初始化容器 mayikt-mysql 和mayikt-redis 启动完成并且容器结束之后,才可以启动mayikt-main-container
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit

执行命令:kubectl describe pods -n mayikt-sit mayikt-mysql启动成功之后 40s 结束容器 启动 mayikt-redis
在这里插入图片描述
在这里插入图片描述
等待mayikt-redis容器启动成功结束之后,开始开动我们的主容器。
执行:kubectl get pods -n mayikt-sit 有两个初始化容器未启动完成
在这里插入图片描述
在这里插入图片描述
kubectl describe pods -n mayikt-sit 开始启动nginx容器
在这里插入图片描述
在查看初始化容器 mayikt-redis、mayikt-mysql
在这里插入图片描述
Terminated 结束了

再次查询 主容器启动成功了
kubectl get pods -n mayikt-sit
在这里插入图片描述

钩子函数

在这里插入图片描述

k8s在主容器的启动之后和停止之前提供了两个钩子函数
1.post-start: 容器创建之后执行(相关命令),如果失败了则会自动重启容器, 容器创建后立即执行,注意由于是异步执行,它无法保证一定在 ENTRYPOINT 之前运行。如果失败,容器会被杀死,并根据 RestartPolicy 决定是 否重启
2.pre-stop :容器终止之前执行(相关命令) 例如 杀死进程等 容器终止前执行,常用于资源清理。执行完成之后容器将成功终止,如果失败,容器同样也会被杀死。在其完成之前 会阻塞删除容器的操作
钩子的回调函数支持三种方式
1.Exec命令 执行Exec命令

spec:
  containers:
  - name: main-container
    image: nginx:1.17.1
    lifecycle:
      postStart:
        exec: #容器创建之后执行(相关命令)修改nginx 页面
          command: ["/bin/sh","-c","echo mayikt > /usr/share/nginx/html/index.html"]
      preStop:
        exec: #容器停止之后 执行停止nginx服务
          command: [" /usr/sbin/nginx","-s" , "quit" ]

2.TCPSocket: 发送TCPSocket

  lifecycle:
    postStart:
      tcpSocket:
        port: 8080

3.HTTPGet: 发送http请求

lifecycle:
    postStart:
      httpGet:
        path: /init   # URI地址
        port: 80  # 端口号
        host: 192.168.110.1 # 主机地址
        scheme: HTTP   # 支持的协议,http或https

# http://192.168.110.1/init

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-nginx-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: main-container
    image: nginx:1.17.9
    lifecycle:
      postStart:
        exec: #容器创建之后执行(相关命令)修改nginx 页面
          command: ["/bin/sh","-c","echo mayikt > /usr/share/nginx/html/index.html"]
      preStop:
        exec: #容器停止之后 执行停止nginx服务
          command: [" /usr/sbin/nginx","-s" , "quit" ]

curl 172.17.0.4
在这里插入图片描述

容器探测

lvs(k8s-service)+keepalived(心跳)
k8s提供了livenessProbe(可用性探针)和readinessProbe(就绪性探针)对容器的健康性进行检测,类似心跳机制
判断我们应用实例是否存活 如果是为宕机状态 则自动重启,同时如果发现该pod无法接受请求 则service不会转发到该pod上执行。
1.存活探针(可用性探针): 用于检测容器实例当前是否处于正常运行的状态,如果不是为运行状态,k8s则会重启容器;
2.就绪探针readinessProbe(就绪性探针): 就绪性探针,用于检测应用实例当前是否可以接收请求,如果不能接受实例,k8s不会转发到该实例
其实非常好理解,livenessProbe 判断是否 容器是否重启、readinessProbe 判断是否路由转发
支持三种探测方式
1.Exec命令 在容器内执行一次命令,如果命令执行的退出码为0,则认为程序正常,否则不正常
2.TCPSocket: 会尝试访问一个用户指定的容器的端口,如果能够成功建立连接 则认为正常,否则认为不正常
3.HTTPGet: 调用容器内Web系统的url,如果http状态码是在200和399之间,则认为程序正常,否则不正常

Exec命令

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe: ##存活探针(可用性探针)
      exec:  #执行一个查看文件的命令
        command: ["/bin/cat" ,"/tmp/mayikt.txt"] 

执行命令 显示主容器启动失败,重启了四次
在这里插入图片描述
kubectl describe pods -n mayikt-sit
在这里插入图片描述
修改为 执行pwd 没有任何问题则不会重启

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe: ##存活探针(可用性探针)
      exec:  #执行一个pwd
        command: ["/bin/pwd" ,"/"] 

kubectl get pods -n mayikt-sit
在这里插入图片描述

TCPSocket

会尝试访问一个用户指定的容器的端口,如果能够成功建立连接 则认为正常,否则认为不正常
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe: ##存活探针(可用性探针)
      tcpSocket:  ## 底层会尝试访问容器ip:8080
        port: 8080 

kubectl describe pods -n mayikt-sit
在这里插入图片描述
Liveness probe failed: dial tcp 172.17.0.4:8080: connect: connection refused
kubectl get pods -n mayikt-sit
在这里插入图片描述

修改成正确的

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe: ##存活探针(可用性探针)
      tcpSocket:  ## 底层会尝试访问容器ip:80
        port: 80 

就ok没有问题啦

HTTPGet

调用容器内Web系统的url,如果http状态码是在200和399之间,则认为程序正常,否则不正常----实际开发中 返回json数据 端口—200和399 500

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP
    livenessProbe:
      httpGet: #访问指定的scheme://host:port/path
        scheme: HTTP #支持的协议,http或者https
        port: 80 #端口号
        path: /mayikt #URI地址 该地址不存在 会报错404

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit

kubectl describe pods -n mayikt-sit
Warning Unhealthy 2s kubelet, node2 Liveness probe failed: HTTP probe failed with statuscode: 404
在这里插入图片描述
我们在node2节点 访问 curl 172.17.0.4/mayikt
在这里插入图片描述
kubectl get pods -n mayikt-sit 查看重启容器次数
在这里插入图片描述
修改成正确的

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP
    livenessProbe:
      httpGet: #访问指定的scheme://host:port/path
        scheme: HTTP #支持的协议,http或者https
        port: 80 #端口号
        path: / #URL地址 该地址不存在 会报错404

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo10.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
ok 没有报错啦

探测时间

容器探测原理本身就是心跳策略

  1. initialDelaySeconds # 容器启动后 等待多少秒 开始执行第一次探测
  2. timeoutSeconds # 探测超时时间。默认1秒,最小1秒
  3. periodSeconds # 执行探测的频率,默认是10秒,最小1秒
    4.failureThreshold # 连续探测失败多少次才被认定为失败、默认是3,最小值是1
    5.successThreshold # 连续探测成功多少次才被认定为成功,默认是1
apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP
    livenessProbe:
      httpGet: #访问指定的scheme://host:port/path
        scheme: HTTP #支持的协议,http或者https
        port: 80 #端口号
        path: /mayikt #URI地址 该地址不存在 会报错404
      initialDelaySecands: 10 #容器启动后10s开始探测   
      failureThreshold: 2 ##探测2次认为是失败      
  restartPolicy: Never #设置重启策略为Never 无论状态如何 不会重启

总结:
初始化容器 对pod启动顺序做一个编排 底层写脚本 脚本
钩子函数 容器停止之前或者容器启动成功之后 走回调的方法 (执行脚本、发送tcp、发送http请求)
容器探测 心跳策略 如果容器宕机了自动重启 重启策略定义(执行脚本、发送tcp、发送http请求)

重启策略

我们的重启策略有三种:

1.Always:出现问题时 自动重启该容器,默认方式。
2.OnFailure :容器终止运行且退出码不为0时重启
3.Never :不论状态为何,都不重启该容器

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP
    livenessProbe:
      httpGet: #访问指定的scheme://host:port/path
        scheme: HTTP #支持的协议,http或者https
        port: 80 #端口号
        path: / #URI地址 该地址不存在 会报错404
  restartPolicy: Never #设置重启策略为Never 无论状态如何 不会重启

在这里插入图片描述

pod调度策略

默认的情况下,Scheduler计算出一个Pod运行在那个Node节点上,我们也可以直接指定该pod运行在那个node节点上。
1.自动调度:是由Scheduler自动计算的 默认
在这里插入图片描述
default-scheduler Successfully assigned mayikt-sit/mayikt-sit-pod to node2

2.定向调度: 通过label 标签指定NodeSelector 或者 NodeName直接指定 该pod运行在那个工作节点上
3.(反)亲和性调度: NodeAffinity、Podffinity、 PodAntiAffinity
4.污点(容忍)调度: Taints、 Toleration
在这里插入图片描述

定向调度

1.直接指定 node节点
2.根据标签选择器 来进行决定
在这里插入图片描述
根据NodeName 直接定位到具体的 工作节点
cat /etc/hosts
在这里插入图片描述

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
yml相关配置:

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-sit-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx-container
    image: nginx:1.17.9
  nodeName: node2 #指定该pod运行在node1 节点

执行该配置文件 发现我们的 mayikt-sit-pod 运行在 node2 节点。

NodeSelector

1.需要给node节点加上标签,让后运行pod指定标签 就可以将该pod运行在 标签对应上的Node节点上
在这里插入图片描述
我们可以根据标签来实现调度
kubectl get nodes --show-labels
在这里插入图片描述
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit

kubectl label nodes node1 nodev=v1
kubectl label nodes node2 nodev=v2
kubectl label nodes node2 key=value
1.创建标签
在这里插入图片描述
2.查看node节点标签
kubectl get nodes --show-labels
在这里插入图片描述
更新标签:kubectl label nodes node2 nodev=v2 --overwrite
2.定义配置文件

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
  nodeSelector:
    nodev: v2 #指定调度到具有node=v2标签 node节点上

kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
在这里插入图片描述

亲和性调度

概念

亲和性:如果有两个pod频繁交互,亲和性让两个pod的尽可能的靠近,这样可以减少因网络通信而带来的性能损耗资资源。
在这里插入图片描述

反亲和性: 例如 nginxpod 集群 为了保证高可用的问题,需要将nginx 集群的pod 分摊不同的noe节点上。
nginx集群的时候 反亲和性
硬策略: 通过指定的规则,如果没有找到具体运行的Node节点 则会报错
软策略: 优先走指定的规则, 如果没有找到具体运行的Node节点 则采用自动随机方式运行在node节点上。
1.nodeAffinity(node亲和性) : pod根据node标签选择器 决定pod运行在那个node节点上
2.podAffinity(pod亲和性): pod根据参照pod标签选择器 解决多个pod运行在同一个node节点上
3.podAntiffinity(pod反亲和性): pod根据参照pod标签选择器 解决多个pod不允许在同一个node节点上

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers: 
  - name: nginx
    image: nginx:1.17.9
  affinity: #设置亲和性
    nodeAffinity: #亲和性node 设置
      requiredDuringSchedulingIgnoredDuringExecution: #硬限制
        nodeSelectorTerms:
        - matchExpressions: #匹配nodev的值在[v3,v4 ]中的标签 node节点
          - key: nodev
            operator: In
            values: ["v3" , "v4"]
            ------------------------------------------------------------------------
 ---------------------------------------------------------------------
  affinity: #亲和性设置
    nodeAffinity: #设置node亲和性
      preferredDuringSchedulingIgnoredDuringExecution: #软限制
      - weight: 1
        preference:
          matchExpressions: #匹配当前node节点标签是否有 ["v5","v6"]
          - key: nodev
            operator: In
            values: ["v5","v6"]            
matchFields   
      matchExpressions   按节点标签列出的节点选择器要求列表(推荐)
        key  键
        values值(可以直接写数组)
       operator关系符支持Exists, DoesNotExist, In, NotIn, Gt, Lt

硬限制
1.查看当前node节点对应的标签
kubectl get nodes --show-labels
在这里插入图片描述

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
执行该配置文件

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers: 
  - name: nginx
    image: nginx:1.17.9
  affinity: #设置亲和性
    nodeAffinity: #亲和性node 设置
      requiredDuringSchedulingIgnoredDuringExecution: #硬限制
        nodeSelectorTerms:
        - matchExpressions: #匹配nodev的值在[v3,v4 ]中的标签 node节点
          - key: nodev
            operator: In
            values: ["v3" , "v4"]

pod找不到 v3 v4 标签 则报错
在这里插入图片描述

修改成正确的
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers: 
  - name: nginx
    image: nginx:1.17.9
  affinity: #设置亲和性
    nodeAffinity: #亲和性node 设置
      requiredDuringSchedulingIgnoredDuringExecution: #硬限制
        nodeSelectorTerms:
        - matchExpressions: #匹配nodev的值在[v3,v4 ]中的标签 node节点
          - key: nodev
            operator: In
            values: ["v1" , "v4"]

kubectl describe pods -n mayikt-sit 调度到node1节点
在这里插入图片描述

软限制

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit

apiVersion: v1
kind: Pod
metadata: 
  name: mayikt-pod
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
  affinity: #亲和性设置
    nodeAffinity: #设置node亲和性
      preferredDuringSchedulingIgnoredDuringExecution: #软限制
      - weight: 1
        preference:
          matchExpressions: #匹配当前node节点标签是否有 ["v5","v6"]
          - key: nodev
            operator: In
            values: ["v5","v6"]

发现未匹配找到 v5、v6标签 则走软限制 在可用node随机选择一个。

pod亲和度

1.先创建好 mayikt-pod1 在node节点

apiVersion: v1 
kind: Pod
metadata:
  name: mayikt-pod01
  namespace: mayikt-sit
  labels:
    podinfo: pod01 #设置标签
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
  nodeName: node1 #将mayikt-pod01指定到node1节点上

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
在这里插入图片描述

2.创建mayikt-pod2 运行同一个node节点
kubectl create -f mayikt-pod02.yml
kubectl describe pods -n mayikt-sit

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod02
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
  affinity: #亲和性设置
    podAffinity: #设置pod亲和性
      requiredDuringSchedulingIgnoredDuringExecution: #策略
      - labelSelector:
          matchExpressions: #匹配podinfo的值在[mayikt-pod03]中的标签
          - key: podinfo
            operator: In
            values: ["mayikt-pod03"] 
        topologyKey: kubernetes.io/hostname

在这里插入图片描述
运行报错 没有找到 mayikt-sit labels mayikt-pod03

修改配置文件

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod02
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
  affinity: #亲和性设置
    podAffinity: #设置pod亲和性
      requiredDuringSchedulingIgnoredDuringExecution: #策略
      - labelSelector:
          matchExpressions: #匹配podinfo的值在[mayikt-pod03]中的标签
          - key: podinfo
            operator: In
            values: ["pod01"] 
        topologyKey: kubernetes.io/hostname

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod01.yml
kubectl create -f mayikt-pod02.yml
kubectl describe pods -n mayikt-sit
在这里插入图片描述
我们pod1和pod2 都在同一个node节点
kubectl get pod -n mayikt-sit -o wide --show-labels
在这里插入图片描述

反亲和性调度

不参照pod 运行在同一个node节点。
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod01.yml

apiVersion: v1 
kind: Pod
metadata:
  name: mayikt-pod01
  namespace: mayikt-sit
  labels:
    podinfo: pod01 #设置标签
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
  nodeName: node1 #将mayikt-pod01指定到node1节点上

kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
创建第二个pod
kubectl create -f mayikt-pod02.yml

apiVersion: v1
kind: Pod
metadata:
  name: mayikt-pod02
  namespace: mayikt-sit
spec:
  containers:
  - name: nginx
    image: nginx:1.17.9
  affinity: #亲和性设置
    podAntiAffinity: #设置pod反亲和性
      requiredDuringSchedulingIgnoredDuringExecution: #策略
      - labelSelector:
          matchExpressions: #匹配podinfo的值在[mayikt-pod03]中的标签
          - key: podinfo
            operator: In
            values: ["pod01"] 
        topologyKey: kubernetes.io/hostname

我们pod1和pod2 不在同一个node节点
kubectl get pod -n mayikt-sit -o wide --show-labels
在这里插入图片描述

调度污点

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
站在node节点角度 不允许哪些pod 运行在该node节点上 该过程称作为 污点
如果设置了污点 相当于 pod与node节点发生了排斥关系
1.PreferNoSchedule: kubernetes将尽 量避免把Pod调度到具有该污点的Node上,除非没有其他节点可调度
2.NoSchedule: kubernetes将不会把Pod调度到具有该污点的Node上,但不会影响当前Node上已存在的Pod
3.NoExecute: kubernetes将不会把Pod调度 到具有该污点的Node上,同时也会将Node.上已存在的Pod驱离
kubectl delete ns mayikt-sit 同时将175节点停止

pod控制器

1.k8s弹性扩容与缩容原理
2.Deployment设计原理
3.k8s实现滚动更新原理
4.k8s实现动态灵活版本回退

基本概念

Pod控制器是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建pod的资源。
pod控制器有多种类型:
ReplicaSet: 代用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。
ReplicaSet主要三个组件组成:
  (1)用户期望的pod副本数量
  (2)标签选择器,判断哪个pod归自己管理
  (3)当现存的pod数量不足,会根据pod资源模板进行新建
帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用Deployment。
Deployment:工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。
DaemonSet:用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如ELK服务
特性:服务是无状态的
服务必须是守护进程
Job:只要完成就立即退出,不需要重启或重建。
Cronjob:周期性任务控制,不需要持续后台运行,
StatefulSet:管理有状态应用

ReplicaSet

创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能,也就是
主要作用是保证一定数量的pod能够正常运行,它会持续监听这些pod的运行状态,一旦pod发生
在这里插入图片描述

故障,就会重启或重建
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-controller01.yml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: mayikt-rp
  namespace: mayikt-sit
spec:
  replicas: 3 
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.9

相关配置文件说明:
kubectl get pod -n mayikt-sit --show-labels
当前以该模板的形式 启动三个不同的pod 镜像是为1.17.9
labels标签 key是为app、value是为nginx-pod
selector: 选择器,pod控制器与pod之间建立联系,采用的Label Selector机制
matchLabels: Labels匹配规则
kubectl get pod -n mayikt-sit --show-labels

kubectl describe pods -n mayikt-sit
第一个nginx:
172.17.0.2 在 node3/192.168.75.177
在这里插入图片描述
第二个nginx:
在这里插入图片描述
第三个nginx
node1/192.168.75.167
在这里插入图片描述

kubectl get pods -n mayikt-sit
在这里插入图片描述
查看该 -n mayikt-sit 副本( mayikt-rp):
kubectl get rs mayikt-rp -n mayikt-sit -o wide
在这里插入图片描述

弹性扩容

kubectl edit rs rs名称 -n 命名空间
kubectl edit rs mayikt-rp -n mayikt-sit
在这里插入图片描述

进行编辑 修改成6
在这里插入图片描述

在保存:
在这里插入图片描述
在这里插入图片描述
kubectl describe pods -n mayikt-sit
kubectl get rs mayikt-rp -n mayikt-sit -o wide
kubectl get pods -n mayikt-sit
在这里插入图片描述
在这里插入图片描述

弹性缩容

kubectl edit rs rs名称 -n 命名空间
kubectl edit rs mayikt-rp -n mayikt-sit
在这里插入图片描述
在这里插入图片描述
kubectl describe pods -n mayikt-sit
kubectl get rs mayikt-rp -n mayikt-sit -o wide
kubectl get pods -n mayikt-sit
在这里插入图片描述
通过命令的形式
kubectl scale rs mayikt-rp --replicas=2 -n mayikt-sit
在这里插入图片描述
在这里插入图片描述

更新镜像

设计灰度发布、滚动发布
kubectl edit rs rs名称 -n 命名空间
kubectl edit rs mayikt-rp -n mayikt-sit
在这里插入图片描述
在这里插入图片描述

kubectl get rs mayikt-rp -n mayikt-sit -o wide
在这里插入图片描述

删除副本

kubectl delete rs mayikt-rp -n mayikt-sit
k8s删除ReplicaSet前,会将ReplicaSet的replicasclear调整为0,等待所有的Pod被删除后,在执行RS对象的删除。
kubectl get pods -n mayikt-sit
在这里插入图片描述
在这里插入图片描述

或者通过:kubectl delete -f mayikt-pod-controller01.yml 来删除

Deployment

Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新。
只需要在 Deployment 中描述想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。也可以定义一个全新的 Deployment 来创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。
在这里插入图片描述

1.继承ReplicaSet的所有功能
2.新增滚动更新和版本回退
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-controller02.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mayikt-deployment
  namespace: mayikt-sit
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.9

kubectl describe pods -n mayikt-sit
kubectl get deploy -n mayikt-sit -o wide
在这里插入图片描述
kubectl get pods -n mayikt-sit
在这里插入图片描述

弹性扩容与缩容

弹性扩容

我们可以通过命令或者编辑的形式修改
kubectl edit deploy deploy的名称 -n 命名空间名称
kubectl scale deploy deploy的名称 --replicas=副本数 -n 命名空间名称
kubectl scale deploy mayikt-deployment --replicas=6 -n mayikt-sit
image.png
kubectl get pods -n mayikt-sit
在这里插入图片描述

弹性缩容

kubectl scale deploy mayikt-deployment --replicas=2 -n mayikt-sit
在这里插入图片描述

kubectl get pods -n mayikt-sit
在这里插入图片描述

更新镜像

Deployment 支持两种方式修改镜像 分别是重新建更新和滚动更新(默认)
type策略:
1.Recreate 先杀掉所有已存在的Pod,在创建出新的Pod
2.RollingUpdate(滚动更新) 杀死一部分, 就启动一部分 存在两个版本Pod----版本回退
rollingUpdate:当type为RollingUpdate时生效,用于为RollingUpdate设置参数, 支持两个属性:
maxUnavailable:用来指定在升级过程中不可用Pod的最大数量,默认为25%。
maxSurge:用来指定在升级过程中 可以超过期望的Pod的最大数量,默认为25%。
Deployment管理我们的ReplicaSet 集 不是管理我们的pod

重建更新

我们在修改pod里面 容器对应镜像版本时,都会产生一个新的 副本集
kubectl get rs -n mayikt-sit 方便以后做版本回退或者滚动更新
在这里插入图片描述
在这里插入图片描述

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
执行:kubectl create -f mayikt-pod-controller03.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mayikt-deployment
  namespace: mayikt-sit
spec:
  strategy: #策略
    type: Recreate #重建更新
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.9

单独开启一个Xshell窗口监听:
kubectl get pods -n mayikt-sit -w
在这里插入图片描述
修改镜像版本
kubectl get deploy -n mayikt-sit -o wide
在这里插入图片描述
kubectl set image deploy mayikt-deployment nginx=nginx:1.17.8 -n mayikt-sit
在这里插入图片描述
kubectl get pods -n mayikt-sit -w
在这里插入图片描述
kubectl get deploy -n mayikt-sit -o wide
在这里插入图片描述

滚动更新

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
执行:kubectl create -f mayikt-pod-controller04.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mayikt-deployment
  namespace: mayikt-sit
spec:
  strategy: #策略
    type: RollingUpdate #滚动更新
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25% 
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.9

修改镜像版本
kubectl get deploy -n mayikt-sit -o wide
在这里插入图片描述
kubectl set image deploy mayikt-deployment nginx=nginx:1.17.8 -n mayikt-sit
在这里插入图片描述
kubectl get pods -n mayikt-sit -w
在这里插入图片描述

版本回退

根据指定的版本实现回退
查看历史更新的状态:
kubectl rollout history deploy mayikt-deployment -n mayikt-sit
在这里插入图片描述
该错误原因是: kubectl create -f mayikt-pod-controller04.yml 后面没有加上
–record
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-controller04.yml --record
在这里插入图片描述
再执行:kubectl rollout history deploy mayikt-deployment -n mayikt-sit
在这里插入图片描述
kubectl get rs -n mayikt-sit 当前有一个rs
在这里插入图片描述
修改nginx镜像
kubectl get deploy -n mayikt-sit -o wide
kubectl set image deploy mayikt-deployment nginx=nginx:1.17.8 -n mayikt-sit
在这里插入图片描述
在查看我们的rs kubectl get rs -n mayikt-sit
在这里插入图片描述
我们再执行
查看版本更新的状态:
kubectl rollout status deploy mayikt-deployment -n mayikt-sit
在这里插入图片描述
根据指定的版本回退
kubectl rollout history deploy mayikt-deployment -n mayikt-sit
kubectl rollout undo deployment mayikt-deployment --to-revision=1 -n mayikt-sit
在这里插入图片描述
查看回滚的版本
kubectl get deploy -n mayikt-sit -o wide
版本就变成了1.17.9
image.png

Horizontal Pod Autoscaler(HPA)

根据pod cpu使用率情况下 动态扩容与缩容,我们需要安装metrics-server可以用来收集集群中的资源使用情况
1.HPA(Horizontal Pod Autoscaler)Pod自动弹性伸缩,K8S通过对Pod中运行的容器各项指标(CPU占用、内存占用、网络请求量)的检测,实现对Pod实例个数的动态新增和减少。
2.早期的kubernetes版本,只支持CPU指标的检测,因为它是通过kubernetes自带的监控系统heapster实现的。
3.到了kubernetes 1.8版本后,heapster已经弃用,资源指标主要通过metrics api获取,这时能支持检测的指标就变多了(CPU、内存等核心指标和qps等自定义指标)

安装metrics-server

1.安装 yum install git -y
在这里插入图片描述
2.使用git下载metrics-server
git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server
在这里插入图片描述
在这里插入图片描述

注意在下载的过程中,可能会容易超时
3.cd metrics-server/deploy/1.8+/ 修改metrics-server-deployment.yaml

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: metrics-server
  namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    k8s-app: metrics-server
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  template:
    metadata:
      name: metrics-server
      labels:
        k8s-app: metrics-server
    spec:
      hostNetwork: true    
      serviceAccountName: metrics-server
      volumes:
      # mount in tmp so we can safely use from-scratch images and/or read-only containers
      - name: tmp-dir
        emptyDir: {}
      containers:
      - name: metrics-server
        image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
        imagePullPolicy: Always
        args:
        - --kubelet-insecure-tls
        - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP        
        volumeMounts:
        - name: tmp-dir
          mountPath: /tmp

在这里插入图片描述

4.在 /usr/local/metrics-server/deploy/1.8+ 目录中执行
kubectl apply -f ./
在这里插入图片描述
5.kubectl get pods -n kube-system
在这里插入图片描述
如果有metrics-server-6b976979db-dgh7k pod 则说明安装是成功的
6.在执行 kubectl top nodes
如果报错:
在这里插入图片描述
error: metrics not available yet 说明metrics-server 还没有启动完成
耐心等待一会 在执行
kubectl top nodes
在这里插入图片描述

创建nginx pod

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit

创建nginx pod deployment
kubectl run nginx --image=nginx:1.17.9 --requests=cpu=200m -n mayikt-sit
cpu 最小200MHZ
指定deployment service外部访问
kubectl expose deployment nginx --type=NodePort --port=80 -n mayikt-sit
kubectl get deploy,pod,svc -n mayikt-sit
在这里插入图片描述

kubectl describe pods -n mayikt-sit
192.168.75.177:32311
在这里插入图片描述

创建HPA

mayikt-hpa.yaml

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: mayikt-hpa
  namespace: mayikt-sit
spec:
  minReplicas: 1 # 设定最小pod数量
  maxReplicas: 10 # 设定最大pod数量
  targetCPUUtilizationPercentage: 2 # cpu使用率 达到2% 开始弹性扩容
  scaleTargetRef: 
    apiVersion: apps/v1
    kind: Deployment # 指定要控制的nginx信息
    name: nginx

当cpu使用率达到2%时,开始弹性扩容
kubectl create -f mayikt-hpa.yaml
在这里插入图片描述
kubectl get hpa -n mayikt-sit
在这里插入图片描述
TARGETS /2% 耐心等待
重试: kubectl get hpa -n mayikt-sit
在这里插入图片描述

压力测试

打开另外两个窗口
窗口1:
kubectl get pods -n mayikt-sit -w
在这里插入图片描述
窗口2:
kubectl get hpa -n mayikt-sit -w
在这里插入图片描述
模拟压力测试(httpclient、jmeter、postmen)
yum install httpd-tools -y
在这里插入图片描述
ab -n 100 0000 -c 1000 http://192.168.75.177:31503/

在查看窗口1:
cpu使用率瞬间飙高:
在这里插入图片描述
在查看容器 迅速在弹性库容
在这里插入图片描述
等流量下降 (耐心等待5-10分钟左右)服务器开始缩容
在这里插入图片描述
最后只剩下一个pod
在这里插入图片描述

Job

Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
Kubernetes支持以下几种Job:
非并行Job:通常创建一个Pod直至其成功结束
固定结束次数的Job:设置.spec.completions,创建多个Pod,直到.spec.completions个Pod成功结束
带有工作队列的并行Job:设置.spec.Parallelism但不设置.spec.completions,当所有Pod结束并且至少一个成功时,Job就认为是成功

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-job01.yml

apiVersion: batch/v1
kind: Job
metadata:
  name: mayikt-job
  namespace: mayikt-sit
spec:
  manualSelector: true
  completions: 4 #指定job运行成功Pods的次数。默认值: 1
  parallelism: 2 #指定job在任一时刻并发运行Pods的数量 。默认值: 1  
  selector:
    matchLabels:
      app: busybox-pod
  template:
    metadata:
      labels:
        app: busybox-pod
    spec:
      restartPolicy: Never
      containers:
      - name: counter
        image: busybox:1.30
        command: ["bin/sh","-c","for i in 9 8 7 6 5; do echo $i;sleep 5 ;done" ]

在打开另外窗口:
kubectl get pod -n mayikt-sit -w
在这里插入图片描述

修改策略:

  completions: 4 #指定job运行成功Pods的次数。默认值: 1
  parallelism: 2 #指定job在任一时刻并发运行Pods的数量 。默认值: 1

kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-job01.yml

apiVersion: batch/v1
kind: Job
metadata:
  name: mayikt-job
  namespace: mayikt-sit
spec:
  manualSelector: true
  completions: 4 #指定job运行成功Pods的次数。默认值: 1
  parallelism: 2 #指定job在任一时刻并发运行Pods的数量 。默认值: 1  
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      restartPolicy: Never
      containers:
      - name: counter
        image: busybox:1.30
        command: ["bin/sh","-c","for i in 9 8 7 6 5; do echo $i;sleep 5 ;done" ]

另外窗口:kubectl get pod -n mayikt-sit -w
在这里插入图片描述

CronJob

CronJob控制器以Job控制器资源为其管控对象, 可以根据设定的时间点运行我们pod 。
https://cron.qqe2.com/
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-job02.yml
concurrencyPolicy:
Allow: 允许Jobs并发运行(默认)
Forbid: 禁止并发运行, 如果上一次运行尚未完成,则跳过下一次运行
Replace:替换,取消当前正在运行的作业并用新作业替换它
schedule: # cron格式的作业调度运行时间点,用于控制任务在什么时间执行
concurrencyPolicy: #并发执行策略,用于定义前一-次作业运行尚未完成时是否以及如何运行后一次的作业
failedJobHistoryLimit: #为失败的任务执行保留的历史记录数,默认为1
successfulJobHistoryLimit: #为成功的任务执行保留的历史记录数,默认为3 startingDeadlineSeconds: #启动作业错误的超时时长
jobTemplate: # job控制器模板,用于为cronjob控制器生成job对象;下面其实就是job的定义

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: mayikt-cronjob
  namespace: mayikt-sit
  labels:
    controller: cronjob
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    metadata:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: counter
            image: busybox:1.30
            command: ["bin/sh","-c","for i in 9 8 7 6 5; do echo $i;sleep 5 ;done" ]

linux 中可以通过 crontab -e 来配置定时任务。不过,linux 中的 cron 只能精确到分钟
一分钟后打开另外窗口:
kubectl get pod -n mayikt-sit -w
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/570727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

物业设备管理系统

物业服务质量难以保证,工单处理慢,巡检记录不规范;物业设备设施管理混乱,维修保养成本高,风险隐患多;物业数据分散,难以统计分析,无法提供决策支持;每天需要检查和保养的…

Hadoop学习---8、Hadoop数据压缩

1、Hadoop数据压缩 1.1 概述 1、压缩的好处和坏处 (1)优点:减少磁盘IO、减少磁盘储存空间 (2)缺点:增加CPU开销 2、压缩原则 (1)运算密集型的Job,少用压缩 &#xff08…

亚马逊云科技赋能中国出海企业创新及开拓海外业务

向全球价值链上游奋进 中国企业增强国际竞争力的关键,是努力朝全球价值链上游奋进,发力技术出海。中国的出海新机遇,背后曾是疫情在全球按下数字互联和数字化升级的快进键,跨境电商、在线社交、移动支付、数字服务等数字经济迎来…

【技巧】如何保护Word文档不被改动?

工作上,很多小伙伴需要将Word文档发给对方看,但又不想在传看时,被对方改动上面的内容。这种情况,我们可以通过以下两种方法,让Word文档不能改动。 首先,我们可以把Word文档设置限制编辑,被限制后…

FPGA采集CameraLink相机Full模式解码输出,附带工程源码和技术支持

目录 1、前言2、CameraLink协议基础3、目前我已有的CameraLink收发工程4、设计方案输入CameraLink相机视频缓存视频输出软件配置 5、vivado工程详解6、上板调试验证7、福利:工程代码的获取 1、前言 FPGA实现CameraLink视频编解码目前有两种方案: 一是使…

美团面试:接口被恶意狂刷,怎么办?

如果Java接口被恶意狂刷,我们一般可以采取以下措施: 用TimeStamp (兵不厌诈) 比如给客户端提供一个timestamp参数,值是13位的毫秒级时间戳,可以在第12位或者13位做一个校验位,通过一定的算法给…

Docker实战2-发布后端Java项目

有了上篇Docker实战1-发布前端Vue项目的经验,发布后端就轻车熟路了。 1 准备文件 java打包 运行maven的package,生成jar文件,target/dsm-service-1.0-SNAPSHOT.jar DockerFile # Docker image for springboot file run FROM openjdk:11.0.11-jdk-sli…

【JavaSE】Java基础语法(十二):ArrayList

文章目录 1. ArrayList的构造方法和添加方法2. ArrayList类常用方法3. ArrayList存储学生对象并遍历 集合和数组的区别 : 共同点:都是存储数据的容器不同点:数组的容量是固定的,集合的容量是可变的 1. ArrayList的构造方法和添加方法 ArrayL…

2023亚马逊云科技游戏开发者大会从技术角度探索游戏的广阔边界

自上世纪五十年代诞生以来,电子游戏产业蓬勃发展,这与人类想象力的解放有着无比紧密地联系。伴随着全球游戏市场竞争的加剧,“游戏人”面临着很多全新的挑战。因此,2023亚马逊云科技游戏开发者大会不仅带来了最新的游戏行业举措&a…

基于多智能体深度强化学习的体系任务分配方法

源自:指挥与控制学报 作者:林萌龙, 陈涛, 任棒棒, 张萌萌, 陈洪辉 摘 要 1 背景 1.1 集中式决策VS分布式决策 图1集中式决策示意图 1.2 多智能体强化学习 2 问题描述 2.1 场景描述 图2分布式决策场景下的体系任务分配 2.2 状态空间、动作…

PyTorch-DataLoader

DataLoader:从Dataset中取数据,怎么取,每次取多少可以由DataLoader中的参数进行设定,并将数据加载到神经网络中。 dataloader.py import torchvision from torch.utils.data import DataLoader from torch.utils.tensorboard im…

Python框架比较:Django、Flask和Pyramid三者的优缺点和应用场景

第一章:引言 在当今快节奏的软件开发行业中,选择合适的开发框架对于开发人员来说至关重要。Python作为一种流行的编程语言,拥有众多强大的框架,其中包括Django、Flask和Pyramid。本文将比较这三个Python框架的优缺点和应用场景&a…

企业级低代码开发,迈向企业数字化时代

当下,随着科技的快速发展,软件开发的成本不断降低,越来越多的人可以参与到软件开发的过程中。但是在这个过程中,我们也发现了一个问题,就是软件开发的成本越来越高。传统的开发模式需要投入大量人力物力,而…

旅游信息推荐系统

文章目录 旅游信息推荐系统一、系统演示二、项目介绍三、系统运行界面图四、系统部分功能截图五、部分代码展示六、底部获取源码 旅游信息推荐系统 一、系统演示 旅游信息推荐系统 二、项目介绍 数据库版本: mysql8.0 数据库可视化工具: navicat 服务器…

新技术越来越多,作为程序员,我们应该怎么规划职业生涯? | 社区征文

随着科技的不断进步,新技术不断涌现,对程序员的要求也在不断提高。作为一名程序员,要想在这个竞争激烈的行业中立足,就需要制定一份明确的职业规划,不断学习和掌握新技术,提升自己的职业能力和竞争力。 确定…

自古以来,反射也是兵家必争之地

成文耗时1小时,阅读5min,有用指数5颗星。 这几天收到一个战术性需求,将一大坨字段序列化为特定格式的字符串。 大概是下表: 序号字段名描述是否必填0logVersion日志版本是1productName产品是2serviceName服务是.........25extend3…

手写Spring源码(简化版)

导航: 【Java笔记踩坑汇总】Java基础进阶JavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线MySQL高级篇设计模式牛客面试题 参考视频: 周瑜大都督手写模拟Spring_哔哩哔哩 源码: https://gitee.com/vincewm/spring-master 目…

windows自动保存git密码

Windows平台在使用Git的时候经常会出现反复输入密码,生成密钥对的时候如果设置了密码,那么每次使用时都会要求输入密码,那可以通过下面的方式解决。 1. 配置ssh自动启动 管理员启动终端 Set-Service ssh-agent -StartupType Auto # 设置为…

C语言实现分数求和

代码&#xff1a; // 计算1/1 - 1/2 1/3 - 1/4 ...1/99 - 1/100的值 // 计算1/1 - 1/2 1/3 - 1/4 ...1/99 - 1/100的值 int main() {int i 0;double sum 0.0;int flag 1;for (i 1; i < 100; i) {sum sum flag*(1.0 / i);flag -flag;}printf("%lf\n", su…