Kubernetes 操作与优化指南

1、Kubernetes 的 Operator 操作步骤是什么?

  • 定义自定义资源定义 (CRD):创建一个自定义资源定义 (Custom Resource Definition, CRD) 来定义 Operator 将要管理的新类型资源。
  • 开发 Operator 逻辑:编写 Go 代码来实现 Operator 的业务逻辑,通常使用 Operator SDK 或其他框架。
  • 注册 Operator:将 Operator 注册到 Kubernetes 中,使其能够监听 Kubernetes API 的变化。
  • 使用自定义资源:创建自定义资源来配置和管理应用程序。
  • 监控和调试:监控 Operator 的行为并进行调试,确保一切按预期工作。

2、K8S 如何定义 CustomResourceDefinitions 步骤?

  • 定义 CRD YAML 文件:创建一个 YAML 文件来定义 CRD 的结构。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
apiVersion: apiextensions.k8s.io/v1  # CRD 的 API 版本
kind: CustomResourceDefinition # CRD 的种类
metadata: # CRD 的元数据
name: <plural>.<group> # CRD 的名称,格式为 <复数>.<API 组>
labels: # 可选的标签
app: my-app # 应用程序相关的标签
spec: # CRD 的规范
group: <group> # API 组名
versions: # CRD 支持的版本列表
- name: v1 # 版本名称
served: true # 是否为当前版本
storage: true # 是否为存储版本
scope: Namespaced # CRD 的作用域,Namespaced 或 Cluster
names: # CRD 名称相关设置
plural: <plural> # 复数形式的资源名称
singular: <singular> # 单数形式的资源名称
kind: <kind> # 资源的种类名称
listKind: <list-kind> # 资源列表的种类名称
shortNames: # 短名称列表
- <short-name>
additionalPrinterColumns: # 可选的附加列信息,用于展示在 `kubectl get` 输出中
- name: Age
type: date
jsonPath: .metadata.creationTimestamp
conversion: # 可选的转换策略,用于处理不同版本之间的转换
strategy: None # 转换策略
validation: # 可选的验证规则,用于验证资源的有效性
openAPIV3Schema: # OpenAPI v3 的模式定义
properties: # 资源的属性
spec: # 资源的规格定义
type: object
properties:
key: # 示例属性
type: string
status: # 资源的状态定义
type: object
properties:
message: # 示例状态属性
type: string
  • 安装 CRD:使用 kubectl apply 命令安装 CRD。
  • 验证 CRD:使用 kubectl get crd 命令检查 CRD 状态
  • 使用自定义资源:创建自定义资源实例并通过 kubectl apply 使用。

3、K8S版本升级步骤?

  • 了解新版本:在升级之前,详细了解新版本中的变化、新特性和已知问题。阅读官方文档、发行说明和社区讨论,确保你理解升级对集群和应用程序的影响。
  • 创建备份和快照:在开始升级之前,务必创建集群配置和数据的备份,并确保备份的完整性和可恢复性。如果可能的话,还可以创建集群的快照以便在需要时进行恢复。(
    ETCD, 控制器资源<configmap/secret/ingress/hpa/networkPolicy等>,本地镜像)
  • 检查兼容性:确保要升级到的 Kubernetes 版本与你的应用程序、插件和其他组件兼容。检查容器运行时、网络插件、存储驱动程序等组件是否支持目标版本。
  • 更新基础设施:在升级 Kubernetes 之前,确保底层基础设施(如操作系统、容器运行时等)也已经更新到与目标版本兼容的最新版本。

升级顺序:

  • 二进制:按照建议的顺序逐步升级集群中的各个组件,如
    etcd、控制平面组件(kube-apiserver、kube-controller-manager、kube-scheduler)和工作节点上的 kubelet 和
    kube-proxy。确保在升级期间保持集群的可用性。
  • kubeadm:升级主控制平面节点 –> 升级其他控制平面节点 –> 升级工作节点 –> 升级 kubelet 和 kubectl;
  • 逐步升级:可以通过逐步升级的方式减小风险,先升级一个节点或一个子集,然后观察和测试升级的结果。如果遇到问题,可以及时回滚或修复,并调整升级策略。
  • 测试和验证:在升级之后,进行全面的功能和性能测试,确保应用程序在新版本下正常运行。验证集群的网络、存储和安全等方面是否按预期工作。
  • 监控和故障排除:在升级期间和之后,密切监控集群的运行状况和性能指标。如果出现问题,及时进行故障排除并恢复。借助工具和日志记录,收集相关信息以便分析和排查问题。
  • 学习和文档更新:升级过程中积累经验和教训,并及时更新集群的文档和运维手册。记录升级步骤、遇到的问题和解决方法,以便未来参考和分享。
  • 预留时间窗口:升级 Kubernetes 集群可能需要较长的时间,根据集群规模和复杂度合理预估所需时间,并预留额外的时间以处理意外情况和故障修复。

4、K8S各个组件优化?

  • etcd 优化:
    1、etcd 采用本地 ssd 盘作为后端存储存储;
    2、etcd 独立部署在非 k8s node 上;
    3、etcd 快照(snap)与预写式日志(wal)分盘存储;

  • APIServer (kube-apiserver)

  • 提高缓存效率:增加 –request-timeout 参数值,减少长时间运行请求的影响。

  • 资源限制:限制最大并发客户端连接数,例如使用 –max-requests-inflight 参数。

  • 安全性增强:使用 –tls-cert-file 和 –tls-private-key-file 来启用 HTTPS 加密。

  • 独立部署:将 API Server 部署在专用的机器上,避免资源竞争。

  • Controller Manager (kube-controller-manager)
    调整 –leader-elect 参数以优化选举机制。
    调整 –controllers 参数以启用或禁用特定控制器。
    调整 –horizontal-pod-autoscaler-sync-period 参数以优化水平自动伸缩控制器的同步周期。

  • 资源限制:为 Controller Manager 设置合适的资源限制,例如内存和 CPU。
    优化配置:

  • Scheduler (kube-scheduler)
    调整 –algorithm-provider 参数以优化调度算法。
    调整 –bind-scheduler 参数以优化绑定过程。
    调整 –leader-elect 参数以优化选举机制。
    资源限制:为 Scheduler 设置合适的资源限制,例如内存和 CPU。
    优化配置:

Node (kubelet)
配置 –hairpin-mode 和 –non-masquerade-cidr 参数以优化网络性能。
调整 –eviction-hard 参数以优化驱逐阈值。

  • 资源限制:为 Node 上的容器设置合理的资源限制和请求值。
  • 网络配置:
    容器运行时:选择高性能的容器运行时,如 containerd 或 CRI-O。

Network (CNI)

  • 选择高性能 CNI 插件:使用高性能的 CNI 插件,如 Calico 或 Flannel。
  • 配置优化:调整 CNI 插件的配置以优化网络性能。
  • 独立部署:确保 CNI 插件的组件部署在专用的机器上,避免资源竞争。

5、K8S使用第三方网络插件如何定制网络策略步骤?
这个主要可以实现的组件比较多,挑一个自己擅长的,例如Calico,其实现的yaml文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
apiVersion: networking.k8s.io/v1  # 使用的 API 版本
kind: NetworkPolicy # 资源的种类
metadata: # 元数据
name: allow-internal-traffic # 网络策略的名称
namespace: default # 网络策略所属的命名空间
spec: # 网络策略的具体配置
podSelector: # 选择器,用于匹配受此策略影响的 Pod
matchLabels: # 根据 Pod 的标签来匹配
role: db # 匹配具有标签 `role: db` 的 Pod
policyTypes: # 策略类型
- Ingress # 允许入站流量
- Egress # 允许出站流量
ingress: # 入站流量规则
- from: # 允许来自哪些 Pod 的流量
- podSelector: # 匹配发送流量的 Pod
matchLabels: # 根据 Pod 的标签来匹配
role: frontend # 匹配具有标签 `role: frontend` 的 Pod
- namespaceSelector: # 允许来自同一命名空间的 Pod
matchLabels: # 根据命名空间的标签来匹配
app: web # 匹配具有标签 `app: web` 的命名空间
- ipBlock: # 允许来自特定 IP 地址的流量
cidr: 192.168.0.0/16 # CIDR 表示法
except: # 除了以下 IP 地址
- 192.168.1.0/24 # 排除的 CIDR 表示法
ports: # 允许的端口
- protocol: TCP # 协议类型
port: 3306 # 允许的端口号
egress: # 出站流量规则
- to: # 允许流向哪些 Pod 的流量
- podSelector: # 匹配接收流量的 Pod
matchLabels: # 根据 Pod 的标签来匹配
role: backend # 匹配具有标签 `role: backend` 的 Pod
- namespaceSelector: # 允许流向同一命名空间的 Pod
matchLabels: # 根据命名空间的标签来匹配
app: web # 匹配具有标签 `app: web` 的命名空间
ports: # 允许的端口
- protocol: TCP # 协议类型
port: 8080 # 允许的端口号

6、K8S集群中,给出这些动态数据指标的配置步骤?(以 Prometheus 为例)
先来说功能:Prometheus Server(收集指标和存储时间序列数据)、Client Library(客户端库)、Push
Gateway(短期存储指标数据)、Exporters(采集第三方服务监控指标)、Alertmanager(告警处理)以及Web UI(简单的Web控制台)

  • 1)需要创建RBAC(Role-Based Access Control)规则,部署Prometheus服务,并配置Prometheus来抓取指标数据
  • 2)设置scrape_configs来定义监控目标,例如 Kubernetes节点或核心组件监控。
  • 3)利用K8S的 sd 来自动发现新的节点或动态资源,以便Prometheus自动监控。
  • 4)使用cAdvisor来获取Pod和容器的性能指标数据,使用node_exporter收集节点资源利用率,使用kube-state-metrics来采集K8S中各种资源对象的状态信息。
  • 5)导入合适的Grafana模板,如集群资源监控、资源状态监控和Node监控模板,来直观展示监控数据。
  • 6)通过Alertmanager来处理告警并发送通知,如企微、钉钉、电话、短信等。

7、etcd备份出来数据量很大,如何把etcd备份数据进行分割、切割?或者其它有效方式?

  • 配置快照压缩:etcd 允许通过配置参数来设置快照的压缩级别,减少快照文件的大小。可以在 etcd 的配置文件中设置压缩相关的参数。
  • 调整快照计数:通过配置 etcd 来限制保留的快照数量,以减少存储占用。
  • 使用 etcd 集群模式:通过使用 etcd 的集群模式,可以在多个 etcd 成员之间分布数据。
  • 数据分区:通过 etcd 的租约(lease)机制,将数据分散到多个 etcd 实例上,每个实例负责一部分数据。

8、对于两地三中心的数据中心架构,K8S集群建议一套还是各区域搭建各自K8S集群?
可以从两个层面来看这个问题

  • 首先,建议还是各数据中心分别搭建K8s集群,尽量保证各数据中心和网络分区的隔离性。
    多活就是为了保证部分数据中心瘫痪时其他数据中心的持续可用,如果跨机房建一套K8s集群,master和node间网络抖动和时延带来的风险和不确定因素太多了,搞不好没问题的数据中心node都不可用。

  • 建议实现多活的各数据中心的交叉点尽量收敛,应用层的状态抽离,多活基于上层的DNS、SLB配合下层的存储复制实现,没必要每层都跨机房组集群。
    至于多集群带来的运维复杂度,可以通过统一的容器云管理平台比如Rancher、Kuboard、Lens等,实现多集群纳管,减少一部分运维工作量。

9、简要给出如何在 Kubernetes 中实现多租户?
重点挑一些如下的话题来聊下:

  • 使用命名空间来隔离不同的租户。
  • 配置资源配额和限额范围来限制每个租户的资源使用。
  • 使用 RBAC 来控制不同租户的访问权限。
  • 配置网络策略来限制租户间的网络访问。
  • 使用服务网格来实现更细粒度的服务间通信控制。

10、如何优化 Kubernetes 集群的成本?
重点挑一些如下的话题来聊下:

  • 使用成本优化工具(如 Kubernetes Cost Optimizer)来分析资源使用情况。
  • 使用预留实例或 Spot 实例来降低成本。
  • 使用 Kubernetes 的自动伸缩功能来减少资源浪费。
  • 使用成本标签和预算来跟踪和管理资源使用。
  • 定期审查和调整集群配置以提高效率。