体内灵气的量和纯度在逐渐增加。
文章目录
- [在 Kubernetes 中自定义 Service端口报错](#在 Kubernetes 中自定义 Service端口报错)
- 常用控制器
- [Kubernetes 中拉伸收缩副本失效](#Kubernetes 中拉伸收缩副本失效)
- 设置节点容忍异常时间
- [Deployment 控制器的升级和回滚](#Deployment 控制器的升级和回滚)
- 日志收集
- 资源监控
- [监控 Docker](#监控 Docker)
- [将 Master 节点设置为可调度](#将 Master 节点设置为可调度)
在 Kubernetes 中自定义 Service端口报错
一、可能的报错原因
-
端口冲突:
- 原因 :
- 当你为 Service 定义自定义端口时,可能会出现该端口与集群内其他服务使用的端口冲突的情况。这可能是因为选择了一个已经被其他 Service 或节点上的其他进程占用的端口号。
- 例如,你在一个 Service 中设置端口为 8080,而另一个 Service 或者节点上的某个服务已经在使用 8080 端口进行通信,这样就会导致冲突。
- 解决方法 :
- 首先,使用
kubectl get svc
检查集群中现有的服务端口,确保选择的自定义端口未被使用。 - 可以使用
netstat -tuln
或ss -tuln
等命令检查节点上的端口使用情况,查看是否有进程占用了该端口。 - 例如,如果发现 8080 端口被占用,可以选择其他未使用的端口,如 8081 或 8888 等,并修改 Service 的端口配置。
- 首先,使用
- 原因 :
-
端口范围违规:
- 原因 :
- Kubernetes 对于不同类型的 Service 有不同的端口范围规定。对于 NodePort 类型的 Service,默认端口范围是 30000-32767。如果自定义端口超出这个范围,可能会导致报错。
- 例如,如果你将 NodePort 类型的 Service 端口设置为 400000,这超出了规定范围。
- 解决方法 :
- 确保 NodePort 类型的 Service 端口在 30000-32767 范围内。如果需要使用其他端口,可以考虑使用 ClusterIP 或 LoadBalancer 类型的 Service,它们没有这个范围限制(但需要考虑网络环境和安全因素)。
- 例如,将 NodePort 的端口修改为 31000,使其处于允许的范围。
- 原因 :
-
配置错误:
-
原因 :
- 在配置 Service 的 YAML 文件时,可能会出现格式错误或参数错误。比如,错误地指定端口名称、端口协议,或者在
spec.ports
部分的结构设置错误。 - 例如,以下错误的 YAML 配置:
yamlapiVersion: v1 kind: Service metadata: name: my-service spec: ports: - port: 8080 targetPort: 8080 nodePort: 31000 protocol: TCP # 错误:缺少端口名称,可能导致解析错误
- 在配置 Service 的 YAML 文件时,可能会出现格式错误或参数错误。比如,错误地指定端口名称、端口协议,或者在
-
解决方法 :
- 仔细检查 Service 的 YAML 文件,确保符合 Kubernetes 的配置规范。
- 可以参考 Kubernetes 的官方文档,确保
spec.ports
部分包含必要的元素,如port
(服务端口)、targetPort
(容器端口)、nodePort
(对于 NodePort 类型)和protocol
(协议),并给端口设置正确的名称。 - 正确的 YAML 示例:
yamlapiVersion: v1 kind: Service metadata: name: my-service spec: ports: - port: 8080 targetPort: 8080 nodePort: 31000 protocol: TCP name: http
-
-
网络策略限制:
- 原因 :
- 集群内的网络策略可能会限制某些端口的使用,导致自定义服务端口无法正常工作。这可能是为了安全或其他策略性目的设置的。
- 例如,存在网络策略限制服务只能使用某些特定端口进行通信,而自定义端口不在允许范围内。
- 解决方法 :
- 检查集群内的网络策略,使用
kubectl get networkpolicies
查看现有的网络策略。 - 确认是否存在对服务端口的限制,如果有,可以修改网络策略或者调整 Service 的端口,使其符合网络策略要求。
- 检查集群内的网络策略,使用
- 原因 :
二、验证和调试方法
-
查看事件日志:
- 使用
kubectl describe svc <service-name>
查看 Service 的详细信息和事件日志。 - 这里可以看到服务的状态、事件、端点信息等,可能会显示报错信息,帮助你定位问题。
- 例如,如果存在端口冲突,可能会显示类似于 "Failed to allocate port" 的事件信息。
- 使用
-
检查服务端点:
- 使用
kubectl get endpoints <service-name>
检查服务的端点是否正确关联到后端的 Pod。 - 如果服务端点没有正确关联,可能是端口配置错误导致后端 Pod 无法被正确访问,从而引起服务异常。
- 使用
在 Kubernetes 中自定义 Svc 端口报错通常是由于端口冲突、范围违规、配置错误或网络策略限制等原因引起的。解决这些问题需要仔细检查端口使用情况、检查和修改配置文件、遵守端口范围规定,并对网络策略进行适当的检查和调整。同时,使用 kubectl describe
和 kubectl get endpoints
等命令可以辅助进行故障排除和调试,以确保服务能够正常工作。
常用控制器
一、Deployment 控制器
-
功能:
- Deployment 是一种高级别的控制器,用于管理无状态应用的部署。它可以确保指定数量的 Pod 副本在集群中运行,支持滚动更新和回滚功能。
- 例如,如果你有一个 Web 服务应用,使用 Deployment 可以方便地部署多个该服务的 Pod 副本,并在更新应用时,实现平滑的滚动更新,避免服务中断。
-
特点:
- 副本管理 :可以通过
replicas
参数设置期望的 Pod 副本数量,确保始终有指定数量的 Pod 运行。 - 滚动更新:在更新应用时,Deployment 可以按设定的更新策略(如最大不可用数、最大并发数等)进行滚动更新,逐步替换旧版本的 Pod 为新版本,减少服务中断风险。
- 版本回滚 :可以轻松回滚到之前的版本,使用
kubectl rollback deployment <deployment-name>
命令可以回滚到上一个或指定的历史版本。 - 声明式更新:通过修改 Deployment 的 YAML 文件中的镜像版本或其他配置,Kubernetes 会自动将实际状态调整为期望状态。
- 副本管理 :可以通过
二、StatefulSet 控制器
-
功能:
- StatefulSet 主要用于管理有状态应用,为每个 Pod 分配一个唯一的、稳定的标识符,即使在重新调度时也能保持不变。
- 例如,对于有状态的分布式数据库(如 MySQL 集群、ZooKeeper 集群),StatefulSet 可以保证 Pod 的身份标识和存储的一致性。
-
特点:
- 稳定的网络标识 :每个 Pod 会被分配一个唯一的名称,按照顺序编号,如
my-statefulset-0
、my-statefulset-1
等,并且在网络上有稳定的 DNS 名称。 - 稳定的存储:可以使用 Persistent Volume Claim 模板,确保每个 Pod 有自己的持久存储,即使 Pod 重新调度,存储也会重新挂载到对应的 Pod。
- 有序部署和扩展:StatefulSet 的 Pod 按照顺序创建和删除,在扩展或缩容时,也会按照顺序进行操作,以确保状态的有序性。
- 稳定的网络标识 :每个 Pod 会被分配一个唯一的名称,按照顺序编号,如
三、DaemonSet 控制器
-
功能:
- DaemonSet 确保每个节点(或部分节点)都运行一个特定的 Pod 副本,通常用于部署系统级的服务,如日志收集、监控代理等。
- 例如,在集群的每个节点上部署
fluentd
用于日志收集,或者node-exporter
用于节点指标的监控。
-
特点:
- 节点覆盖 :默认情况下,会在每个节点上部署一个 Pod 副本,也可以通过节点选择器(
nodeSelector
)和节点亲和性(nodeAffinity
)将 Pod 部署到特定节点。 - 自动调度:当新节点加入集群时,DaemonSet 会自动在新节点上部署相应的 Pod;当节点移除时,对应的 Pod 也会被删除。
- 节点覆盖 :默认情况下,会在每个节点上部署一个 Pod 副本,也可以通过节点选择器(
四、ReplicaSet 控制器
-
功能:
- ReplicaSet 确保指定数量的 Pod 副本运行,是 Deployment 的底层实现之一。
- 例如,当你只关心 Pod 的副本数量而不需要滚动更新等高级功能时,可以使用 ReplicaSet。
-
特点:
- 副本控制 :通过
replicas
参数设置期望的 Pod 副本数量,与 Deployment 类似,但功能相对简单。 - 基于标签选择器 :通过
selector
选择需要管理的 Pod,确保具有特定标签的 Pod 达到指定数量。
- 副本控制 :通过
五、Job 控制器
-
功能:
- Job 控制器用于运行一次性任务,任务完成后,Pod 会进入
Completed
状态。 - 例如,运行数据备份任务、数据迁移任务或批处理任务等。
- Job 控制器用于运行一次性任务,任务完成后,Pod 会进入
-
特点:
- 任务完成 :当任务完成(容器正常退出),Pod 状态变为
Completed
,可以通过设置restartPolicy
为Never
或OnFailure
控制任务的重启行为。 - 并行和串行执行 :可以设置
parallelism
参数控制并行运行的任务数量,通过completions
参数控制需要完成的任务总数,实现并行或串行任务执行。
- 任务完成 :当任务完成(容器正常退出),Pod 状态变为
六、CronJob 控制器
-
功能:
- CronJob 基于时间调度运行 Job,类似于 Linux 的 cron 任务。
- 例如,定期进行数据清理任务、备份任务或数据同步任务等。
-
特点:
- 时间调度 :使用
schedule
参数指定任务的调度时间,如0 * * * *
表示每小时执行一次。 - Job 模板 :使用
jobTemplate
定义要运行的 Job 的模板,每次调度时会根据该模板创建一个 Job。
- 时间调度 :使用
不同的控制器适用于不同的应用场景和需求,Deployment 适合管理无状态应用,StatefulSet 用于有状态应用,DaemonSet 用于节点级的服务,ReplicaSet 提供简单的副本控制,Job 用于一次性任务,CronJob 用于定时任务。了解这些控制器的特点和使用场景,有助于在 Kubernetes 集群中合理地部署和管理应用。
Kubernetes 中拉伸收缩副本失效
一、可能的原因
-
资源限制:
- 集群资源不足 :
- 当你尝试增加副本数量时,如果集群中没有足够的资源(如 CPU、内存)来容纳新的 Pod,Kubernetes 可能无法调度新的 Pod 到任何节点上。
- 例如,所有节点的可用 CPU 或内存已经接近或达到上限,新的 Pod 请求资源时,无法满足其
requests
或limits
中的资源要求。
- 解决方法 :
- 使用
kubectl describe nodes
查看节点的资源使用情况,检查是否有足够的可用资源。 - 可以考虑添加新的节点到集群中,使用
kubeadm
或其他集群管理工具,以增加集群的资源池。 - 或者优化现有节点上的资源分配,调整其他 Pod 的资源使用,如缩小一些非关键 Pod 的资源请求。
- 使用
- 集群资源不足 :
-
配置错误:
- YAML 文件错误 :
- 在 Deployment、StatefulSet 或 ReplicaSet 的 YAML 文件中,可能存在错误的配置,导致无法正确控制副本数量。
- 例如,
replicas
参数设置错误,或者在配置更新时,由于 YAML 文件的格式错误,使得 Kubernetes 无法正确解析所需的副本数。
- 解决方法 :
- 仔细检查 YAML 文件的结构和内容,确保
replicas
参数设置正确,并且符合 Kubernetes 的 YAML 配置规范。 - 可以使用
kubectl apply -f <deployment.yaml>
重新应用配置文件,观察是否有报错信息,使用kubectl describe deployment <deployment-name>
查看详细信息。
- 仔细检查 YAML 文件的结构和内容,确保
- YAML 文件错误 :
-
Pod 无法启动或异常:
- 容器启动失败 :
- 可能是容器镜像拉取失败、容器启动命令错误、端口冲突或容器内的应用程序错误等原因,导致新的 Pod 无法启动。
- 例如,使用了错误的镜像地址,或者容器内的应用程序配置错误,导致不断崩溃。
- 解决方法 :
- 使用
kubectl describe pod <pod-name>
查看 Pod 的事件和状态,检查容器启动失败的原因。 - 对于镜像拉取问题,检查镜像仓库的连接和权限,确保能正常拉取镜像。
- 对于容器内应用程序的问题,查看容器的日志,使用
kubectl logs <pod-name> <container-name>
查看日志,找出应用程序的错误。
- 使用
- 容器启动失败 :
-
调度问题:
- 节点选择问题 :
- 可能是由于节点的标签、污点和容忍度的设置不当,导致无法将新的 Pod 调度到合适的节点。
- 例如,设置了过于严格的节点亲和性或没有足够的节点能满足 Pod 的容忍度要求。
- 解决方法 :
- 检查 Deployment 或其他控制器的 YAML 文件中的
nodeSelector
、affinity
和tolerations
部分。 - 确保有足够的节点符合 Pod 的调度要求,必要时修改这些配置,扩大节点的选择范围。
- 检查 Deployment 或其他控制器的 YAML 文件中的
- 节点选择问题 :
-
配额限制(Resource Quotas):
- 命名空间配额 :
- 如果在命名空间中设置了资源配额,当你尝试增加副本数时,可能会超出该命名空间的配额限制。
- 例如,设置了 CPU 和内存的配额,拉伸副本可能导致总资源使用超过配额。
- 解决方法 :
- 使用
kubectl describe quota -n <namespace>
查看命名空间的资源配额限制。 - 可以考虑调整配额设置,或者优化命名空间内其他资源的使用,以满足新的副本所需的资源。
- 使用
- 命名空间配额 :
二、其他可能的问题及解决方法
-
网络问题:
- 服务发现和网络插件问题 :
- 可能是网络插件(如 Calico、Flannel 等)出现问题,影响了新 Pod 的网络配置,导致新的 Pod 无法正常通信,进而影响副本的拉伸和收缩。
- 例如,Calico 的 BGP 配置错误,导致网络路由异常,新的 Pod 无法加入网络。
- 解决方法 :
- 检查网络插件的配置和状态,查看网络插件的日志,如 Calico 的日志可以使用
calicoctl node status
或查看相应的系统日志文件。 - 确保网络插件正常工作,对于一些网络问题,可以尝试重启网络插件组件或节点,或者更新网络插件到最新版本。
- 检查网络插件的配置和状态,查看网络插件的日志,如 Calico 的日志可以使用
- 服务发现和网络插件问题 :
-
权限问题:
- RBAC 权限不足 :
- 可能是用户或服务账户没有足够的权限来操作副本的拉伸和收缩。
- 例如,使用的服务账户无法修改 Deployment 的副本数,导致操作失败。
- 解决方法 :
- 检查相关的 RBAC 角色和角色绑定,确保操作的用户或服务账户具有相应的权限。
- 可以使用
kubectl auth can-i <verb> <resource>
命令检查权限,如kubectl auth can-i scale deployments
。
- RBAC 权限不足 :
在 Kubernetes 中遇到拉伸收缩副本失效的问题时,需要从资源、配置、Pod 状态、调度、配额、网络和权限等多个方面进行检查和排查。通过使用各种 kubectl
命令查看信息、检查 YAML 文件、查看日志和调整相关配置,可以逐步找出问题所在并解决,确保副本拉伸和收缩操作的顺利进行。
设置节点容忍异常时间
一、概念理解
在 Kubernetes 中,节点容忍异常时间主要与 tolerations
中的 tolerationSeconds
属性相关,该属性用于 NoExecute
类型的 taints
(污点)。当节点出现异常情况(例如,节点变得不可用、资源不足等)并被添加了 NoExecute
类型的污点时,tolerationSeconds
决定了 Pod 在该节点上继续运行的容忍时间。
二、污点(Taints)和容忍度(Tolerations)基础
-
污点(Taints):
- 节点上的污点用于控制哪些 Pod 可以被调度到该节点上。可以使用
kubectl taint
命令添加污点。例如,添加一个NoExecute
类型的污点:
bashkubectl taint nodes <node-name> <key>=<value>:NoExecute
- 这个命令给指定的节点添加了一个
NoExecute
类型的污点,这意味着没有相应容忍度的 Pod 会被立即驱逐。
- 节点上的污点用于控制哪些 Pod 可以被调度到该节点上。可以使用
-
容忍度(Tolerations):
- 是 Pod 的属性,允许 Pod 在有相应污点的节点上继续运行,具体通过在 Pod 的
spec
部分添加tolerations
字段实现。
- 是 Pod 的属性,允许 Pod 在有相应污点的节点上继续运行,具体通过在 Pod 的
三、在 Pod 的 YAML 中设置容忍度和容忍时间
以下是一个包含 tolerations
及 tolerationSeconds
的 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
表示节点不可用时的情况。operator
为Exists
表示只要存在该键即可,不要求精确的value
匹配。effect
为NoExecute
表示当该污点被添加时,会影响已在节点上运行的 Pod。tolerationSeconds
为 300 秒,这意味着当节点被添加了node.kubernetes.io/not-ready
污点时,该 Pod 可以在节点上继续运行 300 秒,超过这个时间将被驱逐。
四、不同场景下的设置示例
- 节点维护时的容忍度设置:
- 假设你要对节点进行维护操作,你可以先给节点添加一个
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 分钟,给其他节点足够的时间来接管工作负载。
- 节点资源不足的情况:
- 当节点资源不足时,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
仅在effect
为NoExecute
时有效,它控制着 Pod 在出现相应污点时的容忍时间。
-
默认行为:
- 当没有设置
tolerationSeconds
且遇到NoExecute
类型的污点时,Pod 会被立即驱逐。
- 当没有设置
六、验证和监控
-
验证:
- 可以使用
kubectl describe pod <pod-name>
来查看 Pod 的状态和tolerations
是否生效。 - 当添加相应的污点后,观察
kubectl get pods
中 Pod 的状态变化,看是否在tolerationSeconds
后被驱逐。
- 可以使用
-
监控:
- 使用 Prometheus 等监控工具监控节点状态和 Pod 的驱逐情况,以便及时调整
tolerationSeconds
或处理异常。
- 使用 Prometheus 等监控工具监控节点状态和 Pod 的驱逐情况,以便及时调整
通过合理设置 tolerations
和 tolerationSeconds
,可以更好地控制 Pod 在节点异常情况下的行为,避免服务突然中断,同时确保集群的高可用性和稳定性。在不同的场景下,可以根据业务需求和节点的重要性灵活调整容忍时间,以实现更精细的资源管理和故障处理。
请根据实际的应用场景和业务需求,灵活设置 tolerations
和 tolerationSeconds
,以确保在节点异常时,Pod 能够有足够的时间进行迁移或进行其他处理,同时确保服务的可用性和集群的整体性能。
Deployment 控制器的升级和回滚
一、Deployment 升级
-
升级流程概述:
- 触发升级 :
- 通常通过修改 Deployment 的 YAML 文件中的容器镜像版本或其他配置参数,然后使用
kubectl apply -f deployment.yaml
命令重新应用该文件,即可触发升级操作。 - 例如,将
spec.template.spec.containers[0].image
中的镜像版本从v1.0
修改为v2.0
并应用文件,Kubernetes 会开始升级流程。
- 通常通过修改 Deployment 的 YAML 文件中的容器镜像版本或其他配置参数,然后使用
- 滚动更新机制 :
- Deployment 控制器使用滚动更新策略,逐步替换旧版本的 Pod 为新版本的 Pod,以确保服务的可用性。
- 可以在 Deployment 的 YAML 文件中设置
spec.strategy.rollingUpdate
参数来控制滚动更新的行为,如maxUnavailable
和maxSurge
。
- 触发升级 :
-
关键参数解释:
- maxUnavailable :
- 该参数决定了在更新过程中允许的最大不可用 Pod 数量。可以是一个绝对值(如 2)或百分比(如 25%)。
- 例如,设置
maxUnavailable: 1
表示在更新过程中最多允许 1 个 Pod 处于不可用状态,确保服务的可用性。
- maxSurge :
- 表示在更新过程中允许超过期望副本数的 Pod 数量,可以是绝对值或百分比。
- 例如,设置
maxSurge: 1
表示可以比期望的副本数多 1 个 Pod 同时运行,以加速更新过程。
- maxUnavailable :
二、查看升级进度和状态
- 使用 kubectl 命令查看 :
- 查看更新状态 :
- 使用
kubectl rollout status deployment/<deployment-name>
命令可以查看更新的进度。 - 它会显示当前更新的进度,包括已更新的 Pod 数量、期望的更新数量等信息。
- 使用
- 查看历史记录 :
- 使用
kubectl rollout history deployment/<deployment-name>
可以查看 Deployment 的更新历史记录,包括每次更新的版本号、更新原因等信息。
- 使用
- 查看更新状态 :
三、Deployment 回滚
- 回滚触发 :
- 回滚到上一版本 :
- 使用
kubectl rollout undo deployment/<deployment-name>
命令可以将 Deployment 回滚到上一个版本。 - 这会将 Deployment 的状态恢复到上一次的配置,包括镜像版本和其他配置参数。
- 使用
- 回滚到指定版本 :
- 使用
kubectl rollout undo deployment/<deployment-name> --to-revision=<revision-number>
命令可以回滚到指定的版本。 - 可以通过
kubectl rollout history deployment/<deployment-name>
查看历史版本号,然后选择要回滚的具体版本。
- 使用
- 回滚到上一版本 :
四、回滚的监控和验证
- 验证回滚结果 :
- 检查状态 :
- 回滚完成后,可以使用
kubectl get pods
查看 Pod 的状态,确保它们运行的是回滚后的版本。 - 例如,检查 Pod 的容器镜像是否为回滚后的版本。
- 回滚完成后,可以使用
- 检查服务状态 :
- 可以通过访问服务的方式来验证服务是否正常运行,确保服务的功能恢复到回滚前的状态。
- 检查状态 :
五、自定义更新策略和高级特性
-
暂停和恢复更新:
- 暂停更新 :
- 使用
kubectl rollout pause deployment/<deployment-name>
可以暂停更新过程,暂停后可以修改 Deployment 的配置而不会触发新的更新。 - 例如,在复杂的更新过程中,可以暂停更新,修改配置,然后再继续。
- 使用
- 恢复更新 :
- 使用
kubectl rollout resume deployment/<deployment-name>
可以恢复暂停的更新操作。
- 使用
- 暂停更新 :
-
金丝雀发布(Canary Deployment):
- 可以通过调整
maxSurge
和maxUnavailable
参数以及手动调整不同版本 Pod 的比例,实现金丝雀发布。 - 例如,先将
maxSurge
设为 1 并修改镜像版本,观察新的 Pod 性能,若满足要求,再逐步增加新 Pod 数量,实现渐进式更新。
- 可以通过调整
Deployment 控制器的升级通过修改配置文件并应用触发,通过滚动更新策略确保服务的连续性,通过 maxUnavailable
和 maxSurge
控制更新过程;回滚可以通过 undo
命令进行,可回滚到上一版本或指定版本;还可以暂停和恢复更新,并且可以通过调整参数实现更高级的发布策略,如金丝雀发布。这些功能可以帮助用户灵活管理应用的更新和版本控制。
日志收集
一、日志收集的目标和挑战
在 Kubernetes 集群中,日志收集的主要目标是从容器和节点中收集各种日志信息(如应用程序日志、系统日志等),并将其存储在一个集中的位置,以便进行查询、分析和故障排除。主要挑战包括处理大量日志数据、确保日志的完整性和安全性,以及适应不同的应用程序和容器运行时。
二、日志收集的主要工具和方法
- 基于 DaemonSet 的日志收集
-
Fluentd:
-
部署方式 :
- 作为 DaemonSet 部署,确保每个节点上都有一个 Fluentd 容器运行。这样可以收集该节点上所有容器的日志。
yamlapiVersion: 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 部署,更适合资源有限的环境。
yamlapiVersion: 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 或其他存储服务。
- 可以通过配置文件(通常是
-
- 使用 Sidecar 容器收集日志
-
适用场景:
- 对于某些特殊的日志收集需求,尤其是在单个 Pod 内的多个容器需要单独处理日志时,可以使用 Sidecar 容器。
- 例如,一个主容器生成日志,一个 Sidecar 容器收集并转发该日志。
-
示例配置:
yamlapiVersion: 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
转发)。
- 主容器
- 解释 :
- 日志收集的后端存储和分析
-
Elasticsearch:
-
功能和优势 :
- 是一个强大的分布式搜索和分析引擎,可存储大量日志数据,支持复杂的查询和聚合操作。
-
部署示例 :
yamlapiVersion: 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 图表进行部署,简化操作。例如:
bashhelm repo add grafana https://grafana.github.io/helm-charts helm install loki grafana/loki
-
使用说明 :
- 可以使用 Promtail(类似于 Fluentd/Fluent Bit)作为日志收集器,将日志发送到 Loki。
-
三、日志收集的最佳实践
-
日志分类和过滤:
- 在收集日志时,对不同类型的日志(如应用日志、系统日志、错误日志等)进行分类和过滤,以方便后续的存储和分析。
- 例如,使用 Fluentd/Fluent Bit 的过滤插件对日志进行分类和预处理。
-
日志保留和清理:
- 为存储的日志设置保留策略,避免占用过多的存储空间。
- 在 Elasticsearch 中,可以通过配置索引的生命周期管理(ILM)来自动清理过期的日志。
四、日志可视化和分析
-
Kibana :
- 与 Elasticsearch 配合使用,提供强大的日志可视化和分析功能。
- 可以使用以下 YAML 部署 Kibana:
yamlapiVersion: 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 使用率、内存使用率、网络流量、存储使用量等关键指标,以便进行性能优化、容量规划和故障排除。
二、主要的资源监控工具
- Prometheus
-
功能和优势:
- Prometheus 是一个开源的系统监控和警报工具,它通过拉取指标的方式收集数据,支持多维数据模型和强大的查询语言(PromQL),适合对集群进行精细的监控和告警。
-
部署和配置:
-
Prometheus Operator :
- 可以使用 Prometheus Operator 简化 Prometheus 的部署和管理。以下是一个简单的部署示例:
yamlapiVersion: monitoring.coreos.com/v1 kind: PrometheusOperator metadata: name: prometheus-operator spec: # 可根据需要添加更多配置信息,如监控的 Namespace 等
- 部署 Prometheus Operator 后,可以使用以下 YAML 部署 Prometheus 实例:
yamlapiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: name: prometheus spec: serviceAccountName: prometheus serviceMonitorSelector: matchLabels: team: frontend
-
ServiceMonitor :
- 用于定义 Prometheus 监控的服务,通过标签选择器(Label Selector)选择要监控的服务。例如:
yamlapiVersion: 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
收集容器的资源使用情况。
- 节点指标 :通过
- Prometheus 可以收集各种指标,包括但不限于:
- Grafana
-
功能和优势:
- Grafana 是一个开源的可视化平台,可以与 Prometheus 集成,将收集到的指标以直观的图表、仪表盘等形式展示,方便运维人员查看和分析。
-
部署和配置:
-
可以使用以下 YAML 部署 Grafana:
yamlapiVersion: 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 使用率、内存使用率随时间的变化图。
- 进入 Grafana 界面,添加数据源,输入 Prometheus 的服务地址(如
-
- Heapster(已弃用,可作为参考)
-
功能和优势:
- 曾经是 Kubernetes 官方推荐的资源使用监控工具,可收集节点和 Pod 的资源使用信息。
-
替代方案:
- 由于已弃用,推荐使用 Prometheus 及其生态系统(如
metrics-server
)代替。
- 由于已弃用,推荐使用 Prometheus 及其生态系统(如
三、其他监控工具和扩展功能
- metrics-server
-
功能和优势:
- 为 Kubernetes 集群提供核心指标(如 CPU、内存使用),是
kubectl top
命令的后端支持,可作为 Prometheus 的补充。
- 为 Kubernetes 集群提供核心指标(如 CPU、内存使用),是
-
部署方式:
-
可以使用以下命令进行部署:
bashkubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
-
- Datadog
-
功能和优势:
- 是一个商业化的监控和分析平台,支持 Kubernetes 监控,提供开箱即用的仪表盘和告警功能,易于集成。
-
部署和使用:
- 可以使用 Datadog 的 Kubernetes 集成工具进行部署,它会在集群中部署 Agent 收集数据。
- 按照 Datadog 的官方文档,配置 API 密钥和其他参数,将收集的数据发送到 Datadog 平台进行分析和展示。
四、监控指标的可视化和告警
-
可视化:
- 使用 Grafana 或其他可视化工具将指标数据以图形化的方式展示,包括但不限于:
- 节点资源使用趋势图(CPU、内存、磁盘、网络)。
- Pod 资源使用热力图,展示不同 Pod 的资源使用情况。
- 集群整体资源利用率的仪表盘,方便查看整体情况。
- 使用 Grafana 或其他可视化工具将指标数据以图形化的方式展示,包括但不限于:
-
告警:
-
Prometheus Alertmanager :
- 可以与 Prometheus 集成,设置告警规则,当指标超过阈值时触发告警。
- 以下是一个简单的告警规则示例:
yamlgroups: - 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:
yamlapiVersion: 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 内置命令和指标
-
Docker Stats 命令:
-
功能 :
docker stats
命令可以实时显示容器的资源使用情况,包括 CPU 使用率、内存使用量、网络 I/O 和存储 I/O 等。
-
使用示例 :
bashdocker stats <container-id>
或者查看所有容器:
bashdocker stats --all
-
局限性 :
- 该命令仅适用于手动检查,不适合长期监控和自动化监控,且无法存储历史数据。
-
-
Docker API:
-
功能 :
- Docker 提供了 API,可以通过 HTTP 请求获取容器和系统的信息。可以使用编程语言(如 Python)来调用 API 并获取所需的指标。
-
示例(使用 Python) :
pythonimport 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
-
功能:
- cAdvisor 是 Google 开发的容器监控工具,能够提供容器的资源使用信息,包括 CPU、内存、文件系统、网络等。
- 它可以自动发现运行在同一主机上的容器并收集其指标。
-
部署方式:
-
独立部署 :
- 可以使用以下命令独立运行 cAdvisor:
bashdocker 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
文件中:
yamlversion: '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 容器:
yamlapiVersion: 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
- 在 Docker Compose 中,可以将 cAdvisor 作为一个服务添加到
-
-
数据查看和使用:
- 可以通过访问
http://<host-ip>:8080
查看 cAdvisor 的 Web 界面,该界面提供了各种容器的资源使用信息和历史数据图表。
- 可以通过访问
三、Prometheus 与 Docker 集成
-
功能:
- Prometheus 是一个强大的开源监控和告警工具,可与 Docker 集成,通过拉取 cAdvisor 暴露的指标进行监控。
-
配置 Prometheus 监控 Docker:
-
Prometheus 配置文件示例 :
yamlglobal: scrape_interval: 15s scrape_configs: - job_name: 'docker' static_configs: - targets: ['<cadvisor-ip>:8080']
这里将 Prometheus 的
scrape_interval
设置为 15 秒,并将 cAdvisor 作为监控目标。 -
部署 Prometheus :
- 可以使用 Docker 容器运行 Prometheus:
bashdocker run -p 9090:9090 -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml prometheus/prometheus
-
-
可视化和告警:
- 可以使用 Grafana 与 Prometheus 集成,通过创建仪表盘展示 Docker 容器的资源使用情况。
- 同时,Prometheus 可以使用 Alertmanager 来设置告警规则,当容器的资源使用超过阈值时触发告警。
四、其他工具
-
Datadog:
- 功能 :
- 一个商业化的监控平台,提供 Docker 监控功能,可自动发现容器并收集资源使用数据。
- 使用方法 :
- 按照 Datadog 的官方文档,在 Docker 主机上安装 Datadog Agent,并配置相关参数,它会自动开始监控 Docker 容器并将数据发送到 Datadog 平台。
- 功能 :
-
Sysdig:
-
功能 :
- 提供容器和系统级别的监控,具有强大的可视化和故障排除功能。
-
使用方法 :
- 可以使用以下命令安装 Sysdig Agent:
bashcurl -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 信息: -
这表示 Master 节点被标记了
node-role.kubernetes.io/master:NoSchedule
的 Taint,阻止了普通 Pod 的调度。
-
-
移除 Taint:
- 要将 Master 节点设置为可调度,需要移除这个 Taint。使用以下命令:
bashkubectl 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
。 - 例如:
bashkubeadm init --ignore-preflight-errors=NodeTaint
- 这将在初始化集群时就避免给 Master 节点添加
NoSchedule
的 Taint。
- 如果你正在使用
-
修改已有的
kubeadm
配置文件:- 如果你已经使用
kubeadm
初始化了集群,并且想修改配置,可以编辑kubeadm
的配置文件(通常是/etc/kubernetes/kubeadm-config.yaml
)。 - 在配置文件中,确保
nodeRegistration
部分不包含taints
部分,或者将其修改为允许调度。例如:
yamlapiVersion: 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 节点上:
bashkubectl 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 来实现,但需要谨慎考虑资源竞争、集群稳定性和安全性等因素。在某些资源紧张或测试场景下可以考虑,但一般不建议在生产环境中这样做,除非你有足够的资源和充分的准备。