【k8s面试题2025】3、练气中期

体内灵气的量和纯度在逐渐增加。

文章目录

  • [在 Kubernetes 中自定义 Service端口报错](#在 Kubernetes 中自定义 Service端口报错)
  • 常用控制器
  • [Kubernetes 中拉伸收缩副本失效](#Kubernetes 中拉伸收缩副本失效)
  • 设置节点容忍异常时间
  • [Deployment 控制器的升级和回滚](#Deployment 控制器的升级和回滚)
  • 日志收集
  • 资源监控
  • [监控 Docker](#监控 Docker)
  • [将 Master 节点设置为可调度](#将 Master 节点设置为可调度)

在 Kubernetes 中自定义 Service端口报错

一、可能的报错原因

  1. 端口冲突

    • 原因
      • 当你为 Service 定义自定义端口时,可能会出现该端口与集群内其他服务使用的端口冲突的情况。这可能是因为选择了一个已经被其他 Service 或节点上的其他进程占用的端口号。
      • 例如,你在一个 Service 中设置端口为 8080,而另一个 Service 或者节点上的某个服务已经在使用 8080 端口进行通信,这样就会导致冲突。
    • 解决方法
      • 首先,使用 kubectl get svc 检查集群中现有的服务端口,确保选择的自定义端口未被使用。
      • 可以使用 netstat -tulnss -tuln 等命令检查节点上的端口使用情况,查看是否有进程占用了该端口。
      • 例如,如果发现 8080 端口被占用,可以选择其他未使用的端口,如 8081 或 8888 等,并修改 Service 的端口配置。
  2. 端口范围违规

    • 原因
      • Kubernetes 对于不同类型的 Service 有不同的端口范围规定。对于 NodePort 类型的 Service,默认端口范围是 30000-32767。如果自定义端口超出这个范围,可能会导致报错。
      • 例如,如果你将 NodePort 类型的 Service 端口设置为 400000,这超出了规定范围。
    • 解决方法
      • 确保 NodePort 类型的 Service 端口在 30000-32767 范围内。如果需要使用其他端口,可以考虑使用 ClusterIP 或 LoadBalancer 类型的 Service,它们没有这个范围限制(但需要考虑网络环境和安全因素)。
      • 例如,将 NodePort 的端口修改为 31000,使其处于允许的范围。
  3. 配置错误

    • 原因

      • 在配置 Service 的 YAML 文件时,可能会出现格式错误或参数错误。比如,错误地指定端口名称、端口协议,或者在 spec.ports 部分的结构设置错误。
      • 例如,以下错误的 YAML 配置:
      yaml 复制代码
      apiVersion: v1
      kind: Service
      metadata:
        name: my-service
      spec:
        ports:
        - port: 8080
          targetPort: 8080
          nodePort: 31000
          protocol: TCP
          # 错误:缺少端口名称,可能导致解析错误
    • 解决方法

      • 仔细检查 Service 的 YAML 文件,确保符合 Kubernetes 的配置规范。
      • 可以参考 Kubernetes 的官方文档,确保 spec.ports 部分包含必要的元素,如 port(服务端口)、targetPort(容器端口)、nodePort(对于 NodePort 类型)和 protocol(协议),并给端口设置正确的名称。
      • 正确的 YAML 示例:
      yaml 复制代码
      apiVersion: v1
      kind: Service
      metadata:
        name: my-service
      spec:
        ports:
        - port: 8080
          targetPort: 8080
          nodePort: 31000
          protocol: TCP
          name: http
  4. 网络策略限制

    • 原因
      • 集群内的网络策略可能会限制某些端口的使用,导致自定义服务端口无法正常工作。这可能是为了安全或其他策略性目的设置的。
      • 例如,存在网络策略限制服务只能使用某些特定端口进行通信,而自定义端口不在允许范围内。
    • 解决方法
      • 检查集群内的网络策略,使用 kubectl get networkpolicies 查看现有的网络策略。
      • 确认是否存在对服务端口的限制,如果有,可以修改网络策略或者调整 Service 的端口,使其符合网络策略要求。

二、验证和调试方法

  1. 查看事件日志

    • 使用 kubectl describe svc <service-name> 查看 Service 的详细信息和事件日志。
    • 这里可以看到服务的状态、事件、端点信息等,可能会显示报错信息,帮助你定位问题。
    • 例如,如果存在端口冲突,可能会显示类似于 "Failed to allocate port" 的事件信息。
  2. 检查服务端点

    • 使用 kubectl get endpoints <service-name> 检查服务的端点是否正确关联到后端的 Pod。
    • 如果服务端点没有正确关联,可能是端口配置错误导致后端 Pod 无法被正确访问,从而引起服务异常。

在 Kubernetes 中自定义 Svc 端口报错通常是由于端口冲突、范围违规、配置错误或网络策略限制等原因引起的。解决这些问题需要仔细检查端口使用情况、检查和修改配置文件、遵守端口范围规定,并对网络策略进行适当的检查和调整。同时,使用 kubectl describekubectl get endpoints 等命令可以辅助进行故障排除和调试,以确保服务能够正常工作。

常用控制器

一、Deployment 控制器

  1. 功能

    • Deployment 是一种高级别的控制器,用于管理无状态应用的部署。它可以确保指定数量的 Pod 副本在集群中运行,支持滚动更新和回滚功能。
    • 例如,如果你有一个 Web 服务应用,使用 Deployment 可以方便地部署多个该服务的 Pod 副本,并在更新应用时,实现平滑的滚动更新,避免服务中断。
  2. 特点

    • 副本管理 :可以通过 replicas 参数设置期望的 Pod 副本数量,确保始终有指定数量的 Pod 运行。
    • 滚动更新:在更新应用时,Deployment 可以按设定的更新策略(如最大不可用数、最大并发数等)进行滚动更新,逐步替换旧版本的 Pod 为新版本,减少服务中断风险。
    • 版本回滚 :可以轻松回滚到之前的版本,使用 kubectl rollback deployment <deployment-name> 命令可以回滚到上一个或指定的历史版本。
    • 声明式更新:通过修改 Deployment 的 YAML 文件中的镜像版本或其他配置,Kubernetes 会自动将实际状态调整为期望状态。

二、StatefulSet 控制器

  1. 功能

    • StatefulSet 主要用于管理有状态应用,为每个 Pod 分配一个唯一的、稳定的标识符,即使在重新调度时也能保持不变。
    • 例如,对于有状态的分布式数据库(如 MySQL 集群、ZooKeeper 集群),StatefulSet 可以保证 Pod 的身份标识和存储的一致性。
  2. 特点

    • 稳定的网络标识 :每个 Pod 会被分配一个唯一的名称,按照顺序编号,如 my-statefulset-0my-statefulset-1 等,并且在网络上有稳定的 DNS 名称。
    • 稳定的存储:可以使用 Persistent Volume Claim 模板,确保每个 Pod 有自己的持久存储,即使 Pod 重新调度,存储也会重新挂载到对应的 Pod。
    • 有序部署和扩展:StatefulSet 的 Pod 按照顺序创建和删除,在扩展或缩容时,也会按照顺序进行操作,以确保状态的有序性。

三、DaemonSet 控制器

  1. 功能

    • DaemonSet 确保每个节点(或部分节点)都运行一个特定的 Pod 副本,通常用于部署系统级的服务,如日志收集、监控代理等。
    • 例如,在集群的每个节点上部署 fluentd 用于日志收集,或者 node-exporter 用于节点指标的监控。
  2. 特点

    • 节点覆盖 :默认情况下,会在每个节点上部署一个 Pod 副本,也可以通过节点选择器(nodeSelector)和节点亲和性(nodeAffinity)将 Pod 部署到特定节点。
    • 自动调度:当新节点加入集群时,DaemonSet 会自动在新节点上部署相应的 Pod;当节点移除时,对应的 Pod 也会被删除。

四、ReplicaSet 控制器

  1. 功能

    • ReplicaSet 确保指定数量的 Pod 副本运行,是 Deployment 的底层实现之一。
    • 例如,当你只关心 Pod 的副本数量而不需要滚动更新等高级功能时,可以使用 ReplicaSet。
  2. 特点

    • 副本控制 :通过 replicas 参数设置期望的 Pod 副本数量,与 Deployment 类似,但功能相对简单。
    • 基于标签选择器 :通过 selector 选择需要管理的 Pod,确保具有特定标签的 Pod 达到指定数量。

五、Job 控制器

  1. 功能

    • Job 控制器用于运行一次性任务,任务完成后,Pod 会进入 Completed 状态。
    • 例如,运行数据备份任务、数据迁移任务或批处理任务等。
  2. 特点

    • 任务完成 :当任务完成(容器正常退出),Pod 状态变为 Completed,可以通过设置 restartPolicyNeverOnFailure 控制任务的重启行为。
    • 并行和串行执行 :可以设置 parallelism 参数控制并行运行的任务数量,通过 completions 参数控制需要完成的任务总数,实现并行或串行任务执行。

六、CronJob 控制器

  1. 功能

    • CronJob 基于时间调度运行 Job,类似于 Linux 的 cron 任务。
    • 例如,定期进行数据清理任务、备份任务或数据同步任务等。
  2. 特点

    • 时间调度 :使用 schedule 参数指定任务的调度时间,如 0 * * * * 表示每小时执行一次。
    • Job 模板 :使用 jobTemplate 定义要运行的 Job 的模板,每次调度时会根据该模板创建一个 Job。

不同的控制器适用于不同的应用场景和需求,Deployment 适合管理无状态应用,StatefulSet 用于有状态应用,DaemonSet 用于节点级的服务,ReplicaSet 提供简单的副本控制,Job 用于一次性任务,CronJob 用于定时任务。了解这些控制器的特点和使用场景,有助于在 Kubernetes 集群中合理地部署和管理应用。


Kubernetes 中拉伸收缩副本失效

一、可能的原因

  1. 资源限制

    • 集群资源不足
      • 当你尝试增加副本数量时,如果集群中没有足够的资源(如 CPU、内存)来容纳新的 Pod,Kubernetes 可能无法调度新的 Pod 到任何节点上。
      • 例如,所有节点的可用 CPU 或内存已经接近或达到上限,新的 Pod 请求资源时,无法满足其 requestslimits 中的资源要求。
    • 解决方法
      • 使用 kubectl describe nodes 查看节点的资源使用情况,检查是否有足够的可用资源。
      • 可以考虑添加新的节点到集群中,使用 kubeadm 或其他集群管理工具,以增加集群的资源池。
      • 或者优化现有节点上的资源分配,调整其他 Pod 的资源使用,如缩小一些非关键 Pod 的资源请求。
  2. 配置错误

    • YAML 文件错误
      • 在 Deployment、StatefulSet 或 ReplicaSet 的 YAML 文件中,可能存在错误的配置,导致无法正确控制副本数量。
      • 例如,replicas 参数设置错误,或者在配置更新时,由于 YAML 文件的格式错误,使得 Kubernetes 无法正确解析所需的副本数。
    • 解决方法
      • 仔细检查 YAML 文件的结构和内容,确保 replicas 参数设置正确,并且符合 Kubernetes 的 YAML 配置规范。
      • 可以使用 kubectl apply -f <deployment.yaml> 重新应用配置文件,观察是否有报错信息,使用 kubectl describe deployment <deployment-name> 查看详细信息。
  3. Pod 无法启动或异常

    • 容器启动失败
      • 可能是容器镜像拉取失败、容器启动命令错误、端口冲突或容器内的应用程序错误等原因,导致新的 Pod 无法启动。
      • 例如,使用了错误的镜像地址,或者容器内的应用程序配置错误,导致不断崩溃。
    • 解决方法
      • 使用 kubectl describe pod <pod-name> 查看 Pod 的事件和状态,检查容器启动失败的原因。
      • 对于镜像拉取问题,检查镜像仓库的连接和权限,确保能正常拉取镜像。
      • 对于容器内应用程序的问题,查看容器的日志,使用 kubectl logs <pod-name> <container-name> 查看日志,找出应用程序的错误。
  4. 调度问题

    • 节点选择问题
      • 可能是由于节点的标签、污点和容忍度的设置不当,导致无法将新的 Pod 调度到合适的节点。
      • 例如,设置了过于严格的节点亲和性或没有足够的节点能满足 Pod 的容忍度要求。
    • 解决方法
      • 检查 Deployment 或其他控制器的 YAML 文件中的 nodeSelectoraffinitytolerations 部分。
      • 确保有足够的节点符合 Pod 的调度要求,必要时修改这些配置,扩大节点的选择范围。
  5. 配额限制(Resource Quotas)

    • 命名空间配额
      • 如果在命名空间中设置了资源配额,当你尝试增加副本数时,可能会超出该命名空间的配额限制。
      • 例如,设置了 CPU 和内存的配额,拉伸副本可能导致总资源使用超过配额。
    • 解决方法
      • 使用 kubectl describe quota -n <namespace> 查看命名空间的资源配额限制。
      • 可以考虑调整配额设置,或者优化命名空间内其他资源的使用,以满足新的副本所需的资源。

二、其他可能的问题及解决方法

  1. 网络问题

    • 服务发现和网络插件问题
      • 可能是网络插件(如 Calico、Flannel 等)出现问题,影响了新 Pod 的网络配置,导致新的 Pod 无法正常通信,进而影响副本的拉伸和收缩。
      • 例如,Calico 的 BGP 配置错误,导致网络路由异常,新的 Pod 无法加入网络。
    • 解决方法
      • 检查网络插件的配置和状态,查看网络插件的日志,如 Calico 的日志可以使用 calicoctl node status 或查看相应的系统日志文件。
      • 确保网络插件正常工作,对于一些网络问题,可以尝试重启网络插件组件或节点,或者更新网络插件到最新版本。
  2. 权限问题

    • RBAC 权限不足
      • 可能是用户或服务账户没有足够的权限来操作副本的拉伸和收缩。
      • 例如,使用的服务账户无法修改 Deployment 的副本数,导致操作失败。
    • 解决方法
      • 检查相关的 RBAC 角色和角色绑定,确保操作的用户或服务账户具有相应的权限。
      • 可以使用 kubectl auth can-i <verb> <resource> 命令检查权限,如 kubectl auth can-i scale deployments

在 Kubernetes 中遇到拉伸收缩副本失效的问题时,需要从资源、配置、Pod 状态、调度、配额、网络和权限等多个方面进行检查和排查。通过使用各种 kubectl 命令查看信息、检查 YAML 文件、查看日志和调整相关配置,可以逐步找出问题所在并解决,确保副本拉伸和收缩操作的顺利进行。


设置节点容忍异常时间

一、概念理解

在 Kubernetes 中,节点容忍异常时间主要与 tolerations 中的 tolerationSeconds 属性相关,该属性用于 NoExecute 类型的 taints(污点)。当节点出现异常情况(例如,节点变得不可用、资源不足等)并被添加了 NoExecute 类型的污点时,tolerationSeconds 决定了 Pod 在该节点上继续运行的容忍时间。

二、污点(Taints)和容忍度(Tolerations)基础

  • 污点(Taints)

    • 节点上的污点用于控制哪些 Pod 可以被调度到该节点上。可以使用 kubectl taint 命令添加污点。例如,添加一个 NoExecute 类型的污点:
    bash 复制代码
    kubectl taint nodes <node-name> <key>=<value>:NoExecute
    • 这个命令给指定的节点添加了一个 NoExecute 类型的污点,这意味着没有相应容忍度的 Pod 会被立即驱逐。
  • 容忍度(Tolerations)

    • 是 Pod 的属性,允许 Pod 在有相应污点的节点上继续运行,具体通过在 Pod 的 spec 部分添加 tolerations 字段实现。

三、在 Pod 的 YAML 中设置容忍度和容忍时间

以下是一个包含 tolerationstolerationSeconds 的 Pod YAML 示例:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  tolerations:
  - key: "node.kubernetes.io/not-ready"
    operator: "Exists"
    effect: "NoExecute"
    tolerationSeconds: 300  # 容忍 300 秒
  containers:
  - name: my-container
    image: my-image
    ports:
    - containerPort: 8080

在这个示例中:

  • key 是污点的键,可以是自定义的,也可以使用 Kubernetes 预定义的键,如 node.kubernetes.io/not-ready 表示节点不可用时的情况。
  • operatorExists 表示只要存在该键即可,不要求精确的 value 匹配。
  • effectNoExecute 表示当该污点被添加时,会影响已在节点上运行的 Pod。
  • tolerationSeconds 为 300 秒,这意味着当节点被添加了 node.kubernetes.io/not-ready 污点时,该 Pod 可以在节点上继续运行 300 秒,超过这个时间将被驱逐。

四、不同场景下的设置示例

  1. 节点维护时的容忍度设置
  • 假设你要对节点进行维护操作,你可以先给节点添加一个 NoExecute 类型的污点,让 Pod 有时间迁移。例如:
bash 复制代码
kubectl taint nodes <node-name> maintenance=true:NoExecute
  • 对应的 Pod 可以设置如下的容忍度:
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  tolerations:
  - key: "maintenance"
    operator: "Equal"
    value: "true"
    effect: "NoExecute"
    tolerationSeconds: 600  # 容忍 600 秒
  containers:
  - name: my-container
    image: my-image
    ports:
    - containerPort: 8080
  • 这样,当你添加污点时,Pod 可以继续在该节点上运行 10 分钟,给其他节点足够的时间来接管工作负载。
  1. 节点资源不足的情况
  • 当节点资源不足时,Kubernetes 可以给节点添加 node.kubernetes.io/out-of-resource 类型的 NoExecute 污点。
  • 你可以在 Pod 的 YAML 中设置相应的容忍度:
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: another-pod
spec:
  tolerations:
  - key: "node.kubernetes.io/out-of-resource"
    operator: "Exists"
    effect: "NoExecute"
    tolerationSeconds: 120  # 容忍 120 秒
  containers:
  - name: my-container
    image: my-image
    ports:
    - containerPort: 8080

五、使用 tolerationSeconds 的注意事项

  • 影响范围

    • tolerationSeconds 仅在 effectNoExecute 时有效,它控制着 Pod 在出现相应污点时的容忍时间。
  • 默认行为

    • 当没有设置 tolerationSeconds 且遇到 NoExecute 类型的污点时,Pod 会被立即驱逐。

六、验证和监控

  • 验证

    • 可以使用 kubectl describe pod <pod-name> 来查看 Pod 的状态和 tolerations 是否生效。
    • 当添加相应的污点后,观察 kubectl get pods 中 Pod 的状态变化,看是否在 tolerationSeconds 后被驱逐。
  • 监控

    • 使用 Prometheus 等监控工具监控节点状态和 Pod 的驱逐情况,以便及时调整 tolerationSeconds 或处理异常。

通过合理设置 tolerationstolerationSeconds,可以更好地控制 Pod 在节点异常情况下的行为,避免服务突然中断,同时确保集群的高可用性和稳定性。在不同的场景下,可以根据业务需求和节点的重要性灵活调整容忍时间,以实现更精细的资源管理和故障处理。

请根据实际的应用场景和业务需求,灵活设置 tolerationstolerationSeconds,以确保在节点异常时,Pod 能够有足够的时间进行迁移或进行其他处理,同时确保服务的可用性和集群的整体性能。


Deployment 控制器的升级和回滚

一、Deployment 升级

  1. 升级流程概述

    • 触发升级
      • 通常通过修改 Deployment 的 YAML 文件中的容器镜像版本或其他配置参数,然后使用 kubectl apply -f deployment.yaml 命令重新应用该文件,即可触发升级操作。
      • 例如,将 spec.template.spec.containers[0].image 中的镜像版本从 v1.0 修改为 v2.0 并应用文件,Kubernetes 会开始升级流程。
    • 滚动更新机制
      • Deployment 控制器使用滚动更新策略,逐步替换旧版本的 Pod 为新版本的 Pod,以确保服务的可用性。
      • 可以在 Deployment 的 YAML 文件中设置 spec.strategy.rollingUpdate 参数来控制滚动更新的行为,如 maxUnavailablemaxSurge
  2. 关键参数解释

    • maxUnavailable
      • 该参数决定了在更新过程中允许的最大不可用 Pod 数量。可以是一个绝对值(如 2)或百分比(如 25%)。
      • 例如,设置 maxUnavailable: 1 表示在更新过程中最多允许 1 个 Pod 处于不可用状态,确保服务的可用性。
    • maxSurge
      • 表示在更新过程中允许超过期望副本数的 Pod 数量,可以是绝对值或百分比。
      • 例如,设置 maxSurge: 1 表示可以比期望的副本数多 1 个 Pod 同时运行,以加速更新过程。

二、查看升级进度和状态

  1. 使用 kubectl 命令查看
    • 查看更新状态
      • 使用 kubectl rollout status deployment/<deployment-name> 命令可以查看更新的进度。
      • 它会显示当前更新的进度,包括已更新的 Pod 数量、期望的更新数量等信息。
    • 查看历史记录
      • 使用 kubectl rollout history deployment/<deployment-name> 可以查看 Deployment 的更新历史记录,包括每次更新的版本号、更新原因等信息。

三、Deployment 回滚

  1. 回滚触发
    • 回滚到上一版本
      • 使用 kubectl rollout undo deployment/<deployment-name> 命令可以将 Deployment 回滚到上一个版本。
      • 这会将 Deployment 的状态恢复到上一次的配置,包括镜像版本和其他配置参数。
    • 回滚到指定版本
      • 使用 kubectl rollout undo deployment/<deployment-name> --to-revision=<revision-number> 命令可以回滚到指定的版本。
      • 可以通过 kubectl rollout history deployment/<deployment-name> 查看历史版本号,然后选择要回滚的具体版本。

四、回滚的监控和验证

  1. 验证回滚结果
    • 检查状态
      • 回滚完成后,可以使用 kubectl get pods 查看 Pod 的状态,确保它们运行的是回滚后的版本。
      • 例如,检查 Pod 的容器镜像是否为回滚后的版本。
    • 检查服务状态
      • 可以通过访问服务的方式来验证服务是否正常运行,确保服务的功能恢复到回滚前的状态。

五、自定义更新策略和高级特性

  1. 暂停和恢复更新

    • 暂停更新
      • 使用 kubectl rollout pause deployment/<deployment-name> 可以暂停更新过程,暂停后可以修改 Deployment 的配置而不会触发新的更新。
      • 例如,在复杂的更新过程中,可以暂停更新,修改配置,然后再继续。
    • 恢复更新
      • 使用 kubectl rollout resume deployment/<deployment-name> 可以恢复暂停的更新操作。
  2. 金丝雀发布(Canary Deployment)

    • 可以通过调整 maxSurgemaxUnavailable 参数以及手动调整不同版本 Pod 的比例,实现金丝雀发布。
    • 例如,先将 maxSurge 设为 1 并修改镜像版本,观察新的 Pod 性能,若满足要求,再逐步增加新 Pod 数量,实现渐进式更新。

Deployment 控制器的升级通过修改配置文件并应用触发,通过滚动更新策略确保服务的连续性,通过 maxUnavailablemaxSurge 控制更新过程;回滚可以通过 undo 命令进行,可回滚到上一版本或指定版本;还可以暂停和恢复更新,并且可以通过调整参数实现更高级的发布策略,如金丝雀发布。这些功能可以帮助用户灵活管理应用的更新和版本控制。


日志收集

一、日志收集的目标和挑战

在 Kubernetes 集群中,日志收集的主要目标是从容器和节点中收集各种日志信息(如应用程序日志、系统日志等),并将其存储在一个集中的位置,以便进行查询、分析和故障排除。主要挑战包括处理大量日志数据、确保日志的完整性和安全性,以及适应不同的应用程序和容器运行时。

二、日志收集的主要工具和方法

  1. 基于 DaemonSet 的日志收集
  • Fluentd

    • 部署方式

      • 作为 DaemonSet 部署,确保每个节点上都有一个 Fluentd 容器运行。这样可以收集该节点上所有容器的日志。
      yaml 复制代码
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: fluentd
      spec:
        selector:
          matchLabels:
            app: fluentd
        template:
          metadata:
            labels:
              app: fluentd
          spec:
            tolerations:
            - key: node-role.kubernetes.io/master
              effect: NoSchedule
            containers:
            - name: fluentd
              image: fluent/fluentd-kubernetes-daemonset:v1.12-debian-elasticsearch7
              env:
                - name: FLUENT_ELASTICSEARCH_HOST
                  value: "elasticsearch.default.svc.cluster.local"
                - name: FLUENT_ELASTICSEARCH_PORT
                  value: "9200"
              volumeMounts:
              - name: varlog
                mountPath: /var/log
              - name: varlibdockercontainers
                mountPath: /var/lib/docker/containers
                readOnly: true
              - name: config-volume
                mountPath: /fluentd/etc/fluentd.conf
                subPath: fluentd.conf
            volumes:
            - name: varlog
              hostPath:
                path: /var/log
            - name: varlibdockercontainers
              hostPath:
                path: /var/lib/docker/containers
            - name: config-volume
              configMap:
                name: fluentd-config
    • 配置说明

      • tolerations 部分允许 Fluentd 在主节点上运行(如果需要)。
      • volumeMounts 挂载了 /var/log/var/lib/docker/containers 以收集节点和容器的日志。
      • configMap 可用于挂载自定义的 Fluentd 配置文件,以便灵活配置日志收集和传输规则。
  • Fluent Bit

    • 部署方式

      • 与 Fluentd 类似,作为 DaemonSet 部署,更适合资源有限的环境。
      yaml 复制代码
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: fluent-bit
      spec:
        selector:
          matchLabels:
            app: fluent-bit
        template:
          metadata:
            labels:
              app: fluent-bit
          spec:
            containers:
            - name: fluent-bit
              image: fluent/fluent-bit:1.7.9
              volumeMounts:
              - name: varlog
                mountPath: /var/log
              - name: varlibdockercontainers
                mountPath: /var/lib/docker/containers
                readOnly: true
            volumes:
            - name: varlog
              hostPath:
                path: /var/log
            - name: varlibdockercontainers
              hostPath:
                path: /var/lib/docker/containers
    • 配置说明

      • 可以通过配置文件(通常是 fluent-bit.conf)设置输入源、过滤器和输出目的地。例如,可以将日志发送到 Elasticsearch、Kafka 或其他存储服务。
  1. 使用 Sidecar 容器收集日志
  • 适用场景

    • 对于某些特殊的日志收集需求,尤其是在单个 Pod 内的多个容器需要单独处理日志时,可以使用 Sidecar 容器。
    • 例如,一个主容器生成日志,一个 Sidecar 容器收集并转发该日志。
  • 示例配置

    yaml 复制代码
    apiVersion: v1
    kind: Pod
    metadata:
      name: myapp-pod
    spec:
      containers:
      - name: myapp-container
        image: myapp-image
        volumeMounts:
        - name: log-volume
          mountPath: /var/log/myapp
      - name: log-sidecar-container
        image: busybox
        command: ["sh", "-c", "tail -n+1 -F /var/log/myapp/*.log | ncat <log-collector>:<port>"]
        volumeMounts:
        - name: log-volume
          mountPath: /var/log/myapp
      volumes:
      - name: log-volume
        emptyDir: {}
    • 解释
      • 主容器 myapp-container 生成日志并存储在 /var/log/myapp 目录。
      • Sidecar 容器 log-sidecar-container 使用 tail 命令读取日志并将其转发到指定的日志收集器(如通过 ncat 转发)。
  1. 日志收集的后端存储和分析
  • Elasticsearch

    • 功能和优势

      • 是一个强大的分布式搜索和分析引擎,可存储大量日志数据,支持复杂的查询和聚合操作。
    • 部署示例

      yaml 复制代码
      apiVersion: v1
      kind: Service
      metadata:
        name: elasticsearch
      spec:
        ports:
        - port: 9200
          protocol: TCP
          targetPort: 9200
        selector:
          app: elasticsearch
      ---
      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: elasticsearch
      spec:
        serviceName: elasticsearch
        replicas: 3
        template:
          metadata:
            labels:
              app: elasticsearch
          spec:
            containers:
            - name: elasticsearch
              image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
              ports:
              - containerPort: 9200
              env:
                - name: discovery.type
                  value: "zen"
                - name: cluster.initial_master_nodes
                  value: "elasticsearch-0,elasticsearch-1,elasticsearch-2"
    • 使用说明

      • 通过 StatefulSet 部署 Elasticsearch 集群,确保数据的可靠性和高可用性。
  • Loki

    • 功能和优势

      • 由 Grafana 开发,专注于日志聚合,可与 Prometheus 生态系统集成,提供轻量级的日志存储和查询。
    • 部署示例

      • 可以使用 Helm 图表进行部署,简化操作。例如:
      bash 复制代码
      helm repo add grafana https://grafana.github.io/helm-charts
      helm install loki grafana/loki
    • 使用说明

      • 可以使用 Promtail(类似于 Fluentd/Fluent Bit)作为日志收集器,将日志发送到 Loki。

三、日志收集的最佳实践

  1. 日志分类和过滤

    • 在收集日志时,对不同类型的日志(如应用日志、系统日志、错误日志等)进行分类和过滤,以方便后续的存储和分析。
    • 例如,使用 Fluentd/Fluent Bit 的过滤插件对日志进行分类和预处理。
  2. 日志保留和清理

    • 为存储的日志设置保留策略,避免占用过多的存储空间。
    • 在 Elasticsearch 中,可以通过配置索引的生命周期管理(ILM)来自动清理过期的日志。

四、日志可视化和分析

  • Kibana

    • 与 Elasticsearch 配合使用,提供强大的日志可视化和分析功能。
    • 可以使用以下 YAML 部署 Kibana:
    yaml 复制代码
    apiVersion: v1
    kind: Deployment
    metadata:
      name: kibana
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: kibana
        spec:
          containers:
          - name: kibana
            image: docker.elastic.co/kibana/kibana:7.10.2
            ports:
            - containerPort: 5601
            env:
              - name: ELASTICSEARCH_URL
                value: "http://elasticsearch:9200"

通过选择合适的日志收集工具(如 Fluentd、Fluent Bit),结合不同的部署方式(DaemonSet 或 Sidecar),并将收集的日志存储在后端存储(如 Elasticsearch、Loki),可以实现对 Kubernetes 集群的全面日志收集和管理。同时,利用可视化工具(如 Kibana)可以帮助运维人员更好地分析和理解日志数据,提高集群的可维护性和故障排除能力。


资源监控

一、资源监控的目标和关键指标

在 Kubernetes 中,资源监控的主要目标是实时监测集群内的资源使用情况,包括节点、Pod、容器的 CPU 使用率、内存使用率、网络流量、存储使用量等关键指标,以便进行性能优化、容量规划和故障排除。

二、主要的资源监控工具

  1. Prometheus
  • 功能和优势

    • Prometheus 是一个开源的系统监控和警报工具,它通过拉取指标的方式收集数据,支持多维数据模型和强大的查询语言(PromQL),适合对集群进行精细的监控和告警。
  • 部署和配置

    • Prometheus Operator

      • 可以使用 Prometheus Operator 简化 Prometheus 的部署和管理。以下是一个简单的部署示例:
      yaml 复制代码
      apiVersion: monitoring.coreos.com/v1
      kind: PrometheusOperator
      metadata:
        name: prometheus-operator
      spec:
        # 可根据需要添加更多配置信息,如监控的 Namespace 等
      • 部署 Prometheus Operator 后,可以使用以下 YAML 部署 Prometheus 实例:
      yaml 复制代码
      apiVersion: monitoring.coreos.com/v1
      kind: Prometheus
      metadata:
        name: prometheus
      spec:
        serviceAccountName: prometheus
        serviceMonitorSelector:
          matchLabels:
            team: frontend
    • ServiceMonitor

      • 用于定义 Prometheus 监控的服务,通过标签选择器(Label Selector)选择要监控的服务。例如:
      yaml 复制代码
      apiVersion: monitoring.coreos.com/v1
      kind: ServiceMonitor
      metadata:
        name: kube-state-metrics
      spec:
        selector:
          matchLabels:
            k8s-app: kube-state-metrics
        endpoints:
        - port: http-metrics
      • 这个 ServiceMonitor 会让 Prometheus 监控具有 k8s-app: kube-state-metrics 标签的服务。
  • 指标收集

    • Prometheus 可以收集各种指标,包括但不限于:
      • 节点指标 :通过 node_exporter 收集节点的 CPU、内存、磁盘、网络等指标。
      • Pod 指标 :通过 kube-state-metrics 收集 Pod 的状态、副本数、资源请求和限制等信息。
      • 容器指标 :通过 cAdvisor 收集容器的资源使用情况。
  1. Grafana
  • 功能和优势

    • Grafana 是一个开源的可视化平台,可以与 Prometheus 集成,将收集到的指标以直观的图表、仪表盘等形式展示,方便运维人员查看和分析。
  • 部署和配置

    • 可以使用以下 YAML 部署 Grafana:

      yaml 复制代码
      apiVersion: v1
      kind: Deployment
      metadata:
        name: grafana
      spec:
        replicas: 1
        template:
          metadata:
            labels:
              app: grafana
          spec:
            containers:
            - name: grafana
              image: grafana/grafana:7.4.3
              ports:
              - containerPort: 3000
    • 配置 Grafana 时,需要添加 Prometheus 作为数据源,然后可以创建自定义的仪表盘。例如:

      • 进入 Grafana 界面,添加数据源,输入 Prometheus 的服务地址(如 http://prometheus:9200)。
      • 利用 Grafana 的 UI 创建仪表盘,使用 PromQL 从 Prometheus 获取数据绘制图表,如 CPU 使用率、内存使用率随时间的变化图。
  1. Heapster(已弃用,可作为参考)
  • 功能和优势

    • 曾经是 Kubernetes 官方推荐的资源使用监控工具,可收集节点和 Pod 的资源使用信息。
  • 替代方案

    • 由于已弃用,推荐使用 Prometheus 及其生态系统(如 metrics-server)代替。

三、其他监控工具和扩展功能

  1. metrics-server
  • 功能和优势

    • 为 Kubernetes 集群提供核心指标(如 CPU、内存使用),是 kubectl top 命令的后端支持,可作为 Prometheus 的补充。
  • 部署方式

    • 可以使用以下命令进行部署:

      bash 复制代码
      kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
  1. Datadog
  • 功能和优势

    • 是一个商业化的监控和分析平台,支持 Kubernetes 监控,提供开箱即用的仪表盘和告警功能,易于集成。
  • 部署和使用

    • 可以使用 Datadog 的 Kubernetes 集成工具进行部署,它会在集群中部署 Agent 收集数据。
    • 按照 Datadog 的官方文档,配置 API 密钥和其他参数,将收集的数据发送到 Datadog 平台进行分析和展示。

四、监控指标的可视化和告警

  1. 可视化

    • 使用 Grafana 或其他可视化工具将指标数据以图形化的方式展示,包括但不限于:
      • 节点资源使用趋势图(CPU、内存、磁盘、网络)。
      • Pod 资源使用热力图,展示不同 Pod 的资源使用情况。
      • 集群整体资源利用率的仪表盘,方便查看整体情况。
  2. 告警

    • Prometheus Alertmanager

      • 可以与 Prometheus 集成,设置告警规则,当指标超过阈值时触发告警。
      • 以下是一个简单的告警规则示例:
      yaml 复制代码
      groups:
      - name: example
        rules:
        - alert: HighCPUUsage
          expr: container_cpu_usage_seconds_total{container="my-container"} > 0.8
          for: 1m
          labels:
            severity: warning
          annotations:
            summary: "High CPU usage in my-container"
            description: "The CPU usage of my-container is above 80% for more than 1 minute."
      • 可以使用以下 YAML 部署 Alertmanager:
      yaml 复制代码
      apiVersion: monitoring.coreos.com/v1
      kind: Alertmanager
      metadata:
        name: alertmanager
      spec:
        replicas: 1
        templateFiles:
          # 可以添加自定义的告警模板

通过使用 Prometheus 及其相关组件(如 Prometheus Operator、ServiceMonitor)收集指标,结合 Grafana 进行可视化,再加上 Alertmanager 进行告警,可以实现对 Kubernetes 集群全面的资源监控。此外,使用 metrics-server 可以支持 kubectl top 命令,而 Datadog 等商业化工具可以提供更全面和定制化的监控服务,根据具体需求和环境可以灵活选择监控方案。


监控 Docker

一、Docker 内置命令和指标

  1. Docker Stats 命令

    • 功能

      • docker stats 命令可以实时显示容器的资源使用情况,包括 CPU 使用率、内存使用量、网络 I/O 和存储 I/O 等。
    • 使用示例

      bash 复制代码
      docker stats <container-id>

      或者查看所有容器:

      bash 复制代码
      docker stats --all
    • 局限性

      • 该命令仅适用于手动检查,不适合长期监控和自动化监控,且无法存储历史数据。
  2. Docker API

    • 功能

      • Docker 提供了 API,可以通过 HTTP 请求获取容器和系统的信息。可以使用编程语言(如 Python)来调用 API 并获取所需的指标。
    • 示例(使用 Python)

      python 复制代码
      import docker
      client = docker.from_env()
      containers = client.containers.list()
      for container in containers:
          stats = container.stats(stream=False)
          print(stats)

      上述 Python 代码使用 Docker SDK 从 Docker 环境中列出容器并获取它们的统计信息。

    • 注意事项

      • 需要处理身份验证和错误情况,同时 API 调用频率可能受 Docker 守护进程的性能影响。

二、cAdvisor

  1. 功能

    • cAdvisor 是 Google 开发的容器监控工具,能够提供容器的资源使用信息,包括 CPU、内存、文件系统、网络等。
    • 它可以自动发现运行在同一主机上的容器并收集其指标。
  2. 部署方式

    • 独立部署

      • 可以使用以下命令独立运行 cAdvisor:
      bash 复制代码
      docker run \
        --volume=/:/rootfs:ro \
        --volume=/var/run:/var/run:rw \
        --volume=/sys:/sys:ro \
        --volume=/var/lib/docker/:/var/lib/docker:ro \
        --volume=/dev/disk/:/dev/disk:ro \
        --publish=8080:8080 \
        --detach=true \
        --name=cadvisor \
        google/cadvisor:latest
      • 这会将 cAdvisor 作为一个 Docker 容器运行,将其监听端口 8080 暴露出来。
    • 与 Docker Compose 或 Kubernetes 集成

      • 在 Docker Compose 中,可以将 cAdvisor 作为一个服务添加到 docker-compose.yml 文件中:
      yaml 复制代码
      version: '3'
      services:
        cadvisor:
          image: google/cadvisor:latest
          container_name: cadvisor
          volumes:
            - /:/rootfs:ro
            - /var/run:/var/run:rw
            - /sys:/sys:ro
            - /var/lib/docker/:/var/lib/docker:ro
            - /dev/disk/:/dev/disk:ro
          ports:
            - "8080:8080"
      • 在 Kubernetes 中,可以将 cAdvisor 作为一个 DaemonSet 部署,确保每个节点上都运行一个 cAdvisor 容器:
      yaml 复制代码
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: cadvisor
      spec:
        selector:
          matchLabels:
            app: cadvisor
        template:
          metadata:
            labels:
              app: cadvisor
          spec:
            containers:
            - name: cadvisor
              image: google/cadvisor:latest
              volumeMounts:
              - name: rootfs
                mountPath: /rootfs
                readOnly: true
              - name: var-run
                mountPath: /var/run
                readOnly: false
              - name: sys
                mountPath: /sys
                readOnly: true
              - name: var-lib-docker
                mountPath: /var/lib/docker
                readOnly: true
              - name: dev-disk
                mountPath: /dev/disk
                readOnly: true
            volumes:
            - name: rootfs
              hostPath:
                path: /
            - name: var-run
              hostPath:
                path: /var/run
            - name: sys
              hostPath:
                path: /sys
            - name: var-lib-docker
              hostPath:
                path: /var/lib/docker
            - name: dev-disk
              hostPath:
                path: /dev/disk
  3. 数据查看和使用

    • 可以通过访问 http://<host-ip>:8080 查看 cAdvisor 的 Web 界面,该界面提供了各种容器的资源使用信息和历史数据图表。

三、Prometheus 与 Docker 集成

  1. 功能

    • Prometheus 是一个强大的开源监控和告警工具,可与 Docker 集成,通过拉取 cAdvisor 暴露的指标进行监控。
  2. 配置 Prometheus 监控 Docker

    • Prometheus 配置文件示例

      yaml 复制代码
      global:
        scrape_interval: 15s
      scrape_configs:
      - job_name: 'docker'
        static_configs:
        - targets: ['<cadvisor-ip>:8080']

      这里将 Prometheus 的 scrape_interval 设置为 15 秒,并将 cAdvisor 作为监控目标。

    • 部署 Prometheus

      • 可以使用 Docker 容器运行 Prometheus:
      bash 复制代码
      docker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prometheus/prometheus
  3. 可视化和告警

    • 可以使用 Grafana 与 Prometheus 集成,通过创建仪表盘展示 Docker 容器的资源使用情况。
    • 同时,Prometheus 可以使用 Alertmanager 来设置告警规则,当容器的资源使用超过阈值时触发告警。

四、其他工具

  1. Datadog

    • 功能
      • 一个商业化的监控平台,提供 Docker 监控功能,可自动发现容器并收集资源使用数据。
    • 使用方法
      • 按照 Datadog 的官方文档,在 Docker 主机上安装 Datadog Agent,并配置相关参数,它会自动开始监控 Docker 容器并将数据发送到 Datadog 平台。
  2. Sysdig

    • 功能

      • 提供容器和系统级别的监控,具有强大的可视化和故障排除功能。
    • 使用方法

      • 可以使用以下命令安装 Sysdig Agent:
      bash 复制代码
      curl -s https://s3.amazonaws.com/download.draios.com/stable/install-sysdig | sudo bash

五、总结

  • Docker 内置工具:适用于简单的手动检查和短期监控。
  • cAdvisor:适合容器资源的实时监控和可视化,可独立部署或与 Docker Compose 和 Kubernetes 集成。
  • Prometheus:强大的开源监控和告警工具,可与 cAdvisor 结合进行长期、系统的监控,配合 Grafana 实现可视化和告警。
  • 商业工具:如 Datadog 和 Sysdig,提供更全面的监控和分析服务,但可能需要付费。

通过这些方法和工具,可以对 Docker 容器的资源使用情况进行有效的监控,根据不同的需求和环境,可以选择合适的监控方案,以确保 Docker 容器的稳定运行和资源的合理使用。


将 Master 节点设置为可调度

在 Kubernetes 中,默认情况下,为了保证集群的稳定性和安全性,Master 节点是不可调度的,即不会将普通的 Pod 调度到 Master 节点上运行。但在某些情况下,你可能需要将 Master 节点设置为可调度,以下是详细的操作步骤和相关解释:

一、使用 kubectl taint 命令

  • 查看当前的 Taints 信息

    • 首先,使用 kubectl describe node <master-node-name> 命令查看 Master 节点的 Taints 信息。通常,你会看到类似以下的 Taint 信息:

      Taints: node-role.kubernetes.io/master:NoSchedule

    • 这表示 Master 节点被标记了 node-role.kubernetes.io/master:NoSchedule 的 Taint,阻止了普通 Pod 的调度。

  • 移除 Taint

    • 要将 Master 节点设置为可调度,需要移除这个 Taint。使用以下命令:
    bash 复制代码
    kubectl taint nodes <master-node-name> node-role.kubernetes.io/master:NoSchedule-
    • 这里的 - 符号表示移除该 Taint。注意将 <master-node-name> 替换为实际的 Master 节点名称。

二、使用 YAML 配置(适用于集群初始化时)

  • 在集群初始化时设置

    • 如果你正在使用 kubeadm 初始化 Kubernetes 集群,可以在 kubeadm init 命令中添加 --ignore-preflight-errors=NodeTaint 参数,同时在 --node-taint 选项中不添加 node-role.kubernetes.io/master:NoSchedule
    • 例如:
    bash 复制代码
    kubeadm init --ignore-preflight-errors=NodeTaint
    • 这将在初始化集群时就避免给 Master 节点添加 NoSchedule 的 Taint。
  • 修改已有的 kubeadm 配置文件

    • 如果你已经使用 kubeadm 初始化了集群,并且想修改配置,可以编辑 kubeadm 的配置文件(通常是 /etc/kubernetes/kubeadm-config.yaml)。
    • 在配置文件中,确保 nodeRegistration 部分不包含 taints 部分,或者将其修改为允许调度。例如:
    yaml 复制代码
    apiVersion: kubeadm.k8s.io/v1beta2
    kind: InitConfiguration
    nodeRegistration:
      # 确保没有或修改以下 taints 部分
      # taints:
      #  - effect: NoSchedule
      #    key: node-role.kubernetes.io/master
    • 然后使用 kubeadm init phase control-plane 重新配置 Master 节点。

三、验证和注意事项

  • 验证节点是否可调度

    • 执行 kubectl describe node <master-node-name> 再次查看节点的 Taints 信息,确认 node-role.kubernetes.io/master:NoSchedule 已被移除。
    • 你可以尝试部署一个简单的 Pod,使用 kubectl run 命令,观察是否会将该 Pod 调度到 Master 节点上:
    bash 复制代码
    kubectl run test-pod --image=nginx --restart=Never
    kubectl get pods -o wide
    • 查看 Pod 的位置,如果调度到了 Master 节点,说明 Master 节点已变为可调度。
  • 注意事项

    • 资源竞争:将 Master 节点设置为可调度后,Master 节点会参与普通 Pod 的运行,可能会导致资源竞争,影响集群的控制平面组件(如 API Server、Controller Manager 等)的性能,因为它们也在 Master 节点上运行。
    • 稳定性和安全性:可能会降低集群的稳定性和安全性,因为 Master 节点承载着重要的控制平面组件,这些组件可能会受到普通 Pod 的影响。

将 Master 节点设置为可调度可以通过移除 node-role.kubernetes.io/master:NoSchedule 的 Taint 来实现,但需要谨慎考虑资源竞争、集群稳定性和安全性等因素。在某些资源紧张或测试场景下可以考虑,但一般不建议在生产环境中这样做,除非你有足够的资源和充分的准备。

相关推荐
卫玠_juncheng3 小时前
使用 Kubernetes 实现负载均衡
容器·kubernetes·负载均衡
秒云5 小时前
MIAOYUN信创云原生项目亮相西部“中试”生态对接活动
云原生·云计算·创业创新·信创·中试·成果转化
ZPC82105 小时前
Docker获取 Ubuntu 镜像
云原生·eureka
小峰编程5 小时前
Linux浅谈——管道、网络配置和客户端软件的使用
linux·运维·服务器·网络·windows·云原生·ai原生
前端 贾公子6 小时前
如何在Mac上彻底删除Docker及其相关组件:清理指南
spring cloud·云原生·eureka
昵称难产中6 小时前
浅谈云计算17 | 分布式存储
分布式·网络协议·云原生·系统架构·云计算
matrixlzp7 小时前
K8S 亲和性与反亲和性 深度好文
运维·服务器·kubernetes
x66ccff8 小时前
【Docker】使用Dev Container进行开发
运维·docker·容器
nbsaas-boot8 小时前
架构设计:微服务还是集群更适合?
微服务·云原生·架构