K8S运维经验分享

K8S-OPS

1. namespace资源限制:CPU、内存、Pod、Service

命名空间设置了CPU或内存资源配额后,创建工作负载时,必须指定CPU或内存的请求值(request)和限制值(limit)

apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-test
  namespace: test
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 2Gi
    limits.cpu: "4"
    limits.memory: 4Gi
    requests.nvidia.com/gpu: 4
    pods: "3"
    services: "6"

2. pod的资源限制,Requests 和 limits

  • requests:需求,最低保障, 保证被调度的节点上至少有的资源配额

  • limits:限制,硬限制, 容器可以分配到的最大资源配额

  • JAVA内存估算参考:堆内存(1G) + 线程数 * 线程栈 (500*1M) + 永久代(metaspace)(256M) + 堆外内存(512M) = limits:2.25G

  • 重要服务请设置limit == request, 这样确保容器不会因为内存的使用量超过request但是没有超过limit的情况下被意外kill掉。

3. QoS等级

Requests 和 limits 的配置除了表明资源情况和限制资源使用之外,它决定了 pod 的 QoS 等级。

  • Guaranteed
limits == Requests,优先级高: pods 使用超过了它们的 limits,或者节点的内存压力很大而且没有 QoS 更低的 pod,否则不会被杀死。
  • Burstable
limits > Requests,优先级中。
  • Best Effort
无requests、limits,优先级低:在资源不足时也会被优先杀死。

4. 什么时候回收资源,驱逐pod:

# 默认驱逐触发条件:
memory.available<100Mi
nodefs.available<10%
nodefs.inodesFree<5%
imagefs.available<15%

# nodefs:保存 kubelet 的卷和守护进程日志等。
# imagefs:在容器运行时,用于保存镜像以及可写入层。
# 修改kubelet的启动参数可以修改默认值。
# 没有CPU,CPU是可压缩资源,不会导致pod被驱逐;内存是不可压缩资源。

手动驱逐

#设为不可调度状态:
kubectl cordon node1
#将pod赶到其他节点:
kubectl drain node1
#解除不可调度状态
kubectl uncordon node1

5. 资源调度

  • 资源计算方式:

    Node Capacity = kube-reserved + system-reserved + eviction-threshold + allocatable

Node Capacity:代表整个节点的资源容量:和 kubectl describe node node01 看到的 Capacity 一致。
#以下参数可在kubelet服务启动参数中添加标记来设置:
kube-reserved:为 k8s 后台服务预留资源:--kube-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi]
system-reserved:为系统后台服务预留资源:--system-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi]
eviction-threshold:为 k8s 节点设置空余资源阈值:--eviction-hard=[memory.available<500Mi]
  • 总资源和可用资源
# kubectl describe node "node01" | grep -A16 "Addresses:"
Addresses:
  InternalIP:  172.xx.xxx.xx
  Hostname:    node01
#总资源
Capacity:
 cpu:                4
 ephemeral-storage:  41926416Ki
 hugepages-1Gi:      0
 hugepages-2Mi:      0
 memory:             8010544Ki
 pods:               110
#可用资源
Allocatable:
 cpu:                3800m
 ephemeral-storage:  38639384922
 hugepages-1Gi:      0
 hugepages-2Mi:      0
 memory:             7408144Ki
 pods:               110
  • 已分配的资源
# kubectl describe node "node03" | sed '1,/Non-terminated Pods/d'
  Namespace                  Name                   CPU Requests  CPU Limits  Memory Requests  Memory Limits
  ---------                  ----                   ------------  ----------  ---------------  -------------
  default                    c3-registercenter-0    0 (0%)        0 (0%)      0 (0%)           0 (0%)
  kube-system                calico-node-dvmgv      150m (3%)     300m (7%)   64M (0%)         500M (6%)
  kube-system                kube-proxy-node03      150m (3%)     500m (12%)  64M (0%)         2G (25%)
  kube-system                nginx-proxy-node03     25m (0%)      300m (7%)   32M (0%)         512M (6%)
#已分配的资源
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  CPU Requests  CPU Limits   Memory Requests  Memory Limits
  ------------  ----------   ---------------  -------------
  325m (8%)     1100m (28%)  160M (2%)        3012M (38%)
  • 统计是针对 limits 和 requests 的,并不是 pod 运行中实际使用的资源。
  • 如果一个 pod 没有设置 limits 和 requests,那么它就可以无限使用资源,还不会被纳入统计,这就使得统计结果不准确,可能节点已经超负荷运行了,但 Sheduler 还认为它有可用资源,直至节点被拖死,集群发生雪崩。
  • 节点的requests不足时,无法调度pod到该节点。跟实际使用量无关。

6. 健康检查

  • http检查:200~399,成功
  • 命令检查:返回结果是 0 则检查成功。
  • 存活探针:livenessProbe:失败则重启pod
  • 业务探针:readinessProbe:失败则不转发流量(endpoint里面不会有这个pod)
  • 延迟时间:预留给业务程序启动的时间
  • 超时时间:健康检查的时间。默认为1秒

7. 滚动升级

  • maxUnavailable:升级过程中最多可不提供服务的POD数量
  • maxSurge: 升级过程中可多出的POD数量

8. 镜像拉取策略imagePullPolicy

  • 默认IfNotPresent:只要本地有就使用,不管仓库是否正常,不管仓库与本地是否一致。
  • 建议配置Always:先连接仓库获取信息,仓库与镜像不一致则拉取,一致则不拉取,防止更新镜像未更换标签的问题。
  • Never:只使用本地镜像,如果本地不存在,则pod运行失败。

9. 污点和容忍

#node增加污点及标签
kubectl taint nodes k8snode1 INFAR_ONLY=:NoExecute
kubectl label node k8snode1 nodeAppType=INFAR_ONLY

#微服务配置容忍污点
  tolerations:
  - key: "INFAR_ONLY"
    operator: "Exists"
    effect: "NoExecute"

#微服务调度到指定的node
  nodeSelector:
  #NodeAffinity: #优先 INFAR_ONLY 节点,没有则调度其它节点
    nodeAppType: INFAR_ONLY

10. Pod状态

  • Pending:无法被正常的调度到节点上:资源不足,hostPort模式端口被占用。
  • Waiting:已经被调度到了一个节点,无法在那个节点上运行:可能无法下载镜像引起。
  • CrashLoopBackOff:容器曾经启动,但异常退出了:容器进程退出,健康检查失败退出,OOMKilled。
  • Pod无法正常运行可以使用kubectl describe以及kubectl logs排查问题。

11. 日志接入

阿里云:

    env:
      - name: aliyun_logs_sos-logs
        value: /opt/logs/*.log
      - name: aliyun_logs_sos-logs
        value: stdout

华为云:

    volumeMounts:
      - name: logs-volume
        mountPath: /opt/logs
        policy:
          logs:
            rotate: ''
            annotations:
              pathPattern: /*.log

12. 资源事件查看

  • kube-eventer

  • node-problem-detector

13. HPA

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-deploy-user-service
  namespace: vip
spec:
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - resource:
      name: memory
      target:
        averageUtilization: 80
        type: Utilization
    type: Resource
  - resource:
      name: cpu
      target:
        averageUtilization: 70
        type: Utilization
    type: Resource
  scaleTargetRef:
    apiVersion: apps/v1beta2
    kind: Deployment
    name: deploy-user-service

14. nodelocaldns

  • NodeLocal DNSCache在集群上运行一个dnsCache daemonset来提高clusterDNS性能和可靠性。相比于纯coredns方案,nodelocaldns + coredns方案能够大幅降低DNS查询timeout的频次,提升服务稳定性,能够扛住1倍多的QPS。

15. K8S监控

  • prometheus
    • cadvisor
    • kube-state-metrics
  • grafana
    • 13105

16. K8S管理

  • 客户端:lens
  • web:kuboard
  • Rancher

你可能感兴趣的:(经验分享)