Files
examination/topics/interview-prep/k8s-observability/single_choice.json
T

326 lines
21 KiB
JSON
Raw Normal View History

{
"topic": "k8s-observability",
"type": "single_choice",
"schema_version": "1.0.0",
"generated": "2026-09-09T16:10:00+08:00",
"questions": [
{
"id": "sc-001",
"type": "single_choice",
"difficulty": 2,
"tags": [
"kubernetes",
"deployment",
"rolling-update"
],
"question": "在 Kubernetes 中,Deployment 的 spec.strategy.rollingUpdate 配置 maxSurge: 25% 和 maxUnavailable: 25%,当集群中有 10 个 Pod 且需要更新到新版本时,最多会同时运行多少个新版本的 Pod?",
"options": {
"A": "2 个",
"B": "3 个",
"C": "5 个",
"D": "10 个"
},
"answer": "C",
"explanation": "maxSurge: 25% 表示最多可以超出期望副本数 25%,即 10 × 25% = 2.5,向上取整为 3,所以最多总 Pod 数为 10 + 3 = 13。maxUnavailable: 25% 表示最多有 25% 的 Pod 不可用,即 10 × 25% = 2.5,向上取整为 3,即最少需要 7 个可用 Pod。在滚动更新过程中,系统先创建新 Pod,新 Pod 就绪后才能终止旧 Pod。新 Pod 逐批创建时,当 3 个新 Pod 全部就绪且旧 Pod 还未完全终止,此时最多可同时运行 5 个新版本 Pod(13 个总 Pod 减去 8 个旧版本 = 5 个新版本)。但更直观的理解:每批次 maxSurge 允许额外创建 3 个新 Pod,加上同时允许不可用的 3 个旧 Pod,新版本最多可以有 5 个同时运行(7 个旧 + 5 个新 = 12 ≤ 13)。",
"source": null,
"related": []
},
{
"id": "sc-002",
"type": "single_choice",
"difficulty": 2,
"tags": [
"kubernetes",
"pod",
"liveness",
"readiness"
],
"question": "关于 Kubernetes 中三种探针的作用,以下说法正确的是?",
"options": {
"A": "Liveness Probe 失败后,Pod 会被重新调度到其他节点",
"B": "Readiness Probe 失败后,Pod 会被从 Service 的 Endpoints 中移除",
"C": "Startup Probe 在容器启动成功后会持续探测",
"D": "三种探针的检测结果都直接影响 Pod 的驱逐决策"
},
"answer": "B",
"explanation": "Readiness Probe 失败后,Pod 会被标记为 NotReady,并从关联 Service 的 Endpoints 列表中移除,从而不再接收流量。A 错误:Liveness Probe 失败后,kubelet 会重启该容器(restartPolicy 决定是否重建 Pod),而非调度到其他节点。C 错误:Startup Probe 只在容器启动阶段运行,一旦成功,后续不再探测,而是由 Liveness 和 Readiness 接管。D 错误:只有 Liveness Probe 失败会触发容器重启,Readiness 和 Startup 的结果不会导致 Pod 被驱逐。",
"source": null,
"related": []
},
{
"id": "sc-003",
"type": "single_choice",
"difficulty": 3,
"tags": [
"kubernetes",
"service",
"ingress",
"declarative-api"
],
"question": "以下关于 Kubernetes Service 类型与 Ingress 的描述,错误的是?",
"options": {
"A": "ClusterIP 类型的 Service 只能在集群内部访问",
"B": "NodePort 会在每个节点上开放一个固定端口,外部流量通过 <NodeIP>:<NodePort> 访问",
"C": "Ingress 资源可以提供 L7 层的 HTTP 路由和 TLS 终止,但需要 Ingress Controller 才能生效",
"D": "LoadBalancer 类型的 Service 在任何云环境中都会自动创建外部负载均衡器,无需云厂商支持"
},
"answer": "D",
"explanation": "LoadBalancer 类型的 Service 需要云厂商的 LoadBalancer 实现支持(如 AWS ELB、GCP Cloud Load Balancer)。在本地环境(如 Minikube、Kind)或没有云负载均衡器的裸金属环境中,LoadBalancer 类型可能无法正常工作或需要 MetalLB 等额外组件。A 正确:ClusterIP 是默认类型,仅集群内可达。B 正确:NodePort 在 30000-32767 范围内开放端口。C 正确:Ingress 本身是声明式的路由规则定义,需要 Ingress Controller(如 nginx-ingress、traefik)来实际执行路由。",
"source": null,
"related": []
},
{
"id": "sc-004",
"type": "single_choice",
"difficulty": 3,
"tags": [
"kubernetes",
"canary",
"blue-green",
"flagger"
],
"question": "在使用 Flagger 进行 Canary 发布时,以下哪个指标必须配置且 Flagger 默认会等待其达标后才继续推进金丝雀?",
"options": {
"A": "请求成功率(Request Success Rate)",
"B": "请求延迟 P99(Request Duration)",
"C": "HTTP 5xx 错误率(Request Error Rate)",
"D": "以上三项都是 Flagger 的默认分析指标"
},
"answer": "D",
"explanation": "Flagger 默认的 Canary 分析会检查三项核心指标:请求成功率(默认阈值 99%)、请求延迟(默认 P99 ≤ 500ms)、HTTP 5xx 错误率(默认阈值 1%)。这三项指标来自 Flagger 集成的 Prometheus 查询,如果任一指标不达标,Flagger 会自动回滚金丝雀。虽然理论上可以通过 CanaryAnalysis 配置只选部分指标,但 Flagger 的默认模板会同时包含这三项,这也是业界金丝雀发布的最佳实践。",
"source": null,
"related": []
},
{
"id": "sc-005",
"type": "single_choice",
"difficulty": 3,
"tags": [
"kubernetes",
"hpa",
"custom-metrics"
],
"question": "关于 Kubernetes HPA(Horizontal Pod Autoscaler)V2 版本的配置,以下哪个说法是正确的?",
"options": {
"A": "HPA V2 只能基于 CPU 和 Memory 进行自动扩缩容",
"B": "HPA V2 支持基于 Custom Metrics 和 External Metrics 进行扩缩容",
"C": "HPA V2 的 behavior 字段只能配置 scaleUp 操作,不能配置 scaleDown",
"D": "HPA V2 检测到指标变化后会在 15 秒内立即调整副本数,没有任何延迟"
},
"answer": "B",
"explanation": "HPA V2(autoscaling/v2)是 HPA 的增强版本,除了支持 CPU 和 Memory 这两个内置指标外,还支持 Custom Metrics(集群内资源暴露的指标,如每秒请求数)和 External Metrics(集群外部指标,如消息队列的队列长度)。A 错误:V2 的核心优势就是支持自定义和外部指标。C 错误:behavior 字段同时支持 scaleUp 和 scaleDown 两个方向的配置,可以分别设定稳定窗口、步进策略等。D 错误:HPA 有 stabilizationWindowSeconds 默认值(scaleUp 为 0,scaleDown 为 300),用于避免频繁抖动。",
"source": null,
"related": []
},
{
"id": "sc-006",
"type": "single_choice",
"difficulty": 2,
"tags": [
"prometheus",
"grafana",
"servicemonitor"
],
"question": "在 Prometheus Operator 中,ServiceMonitor 资源的正确作用是?",
"options": {
"A": "直接向 Prometheus 发送告警",
"B": "定义 Prometheus 应该从哪些 Service 抓取(scrape)指标",
"C": "存储 Prometheus 的长期历史数据",
"D": "定义 Grafana Dashboard 的可视化面板"
},
"answer": "B",
"explanation": "ServiceMonitor 是 Prometheus Operator 提供的 CRD(Custom Resource Definition),用于声明式地定义 Prometheus 的抓取目标。它通过 label selector 匹配 Service,告诉 Prometheus Controller 应该监控哪些 Service 的哪个端口和路径。A 错误:告警由 PrometheusRule 资源定义。C 错误:长期存储由 Thanos 或 VictoriaMetrics 等组件处理,或通过 Prometheus 的 remote write 实现。D 错误:Grafana Dashboard 通过 JSON 定义或 Grafana UI 创建,与 ServiceMonitor 无关。",
"source": null,
"related": []
},
{
"id": "sc-007",
"type": "single_choice",
"difficulty": 4,
"tags": [
"opentelemetry",
"otlp",
"context-propagation"
],
"question": "关于 OpenTelemetry 的 Context Propagation 机制,以下说法正确的是?",
"options": {
"A": "OpenTelemetry 只支持 W3C TraceContext 一种传播格式,没有其他选择",
"B": "Context Propagation 通过在 HTTP Header 中注入和提取 TraceID、SpanID 等信息,实现跨服务链路追踪",
"C": "Context Propagation 只能用于分布式追踪(Tracing),不能用于传播 Metrics 和 Logs 的上下文",
"D": "W3C TraceContext 标准中 traceparent 头的格式为 trace-id-span-id-trace-flags,不包含 version 和 trace-state"
},
"answer": "B",
"explanation": "Context Propagation 是 OpenTelemetry 实现跨服务可观测性的核心机制。它通过在服务间调用的 HTTP Header(如 W3C 标准的 traceparent、tracestate)或消息队列的元数据中注入 TraceID、SpanID、TraceFlags 等上下文信息,使下游服务能够提取这些信息并继续追踪链路。A 错误:OpenTelemetry 支持多种传播格式,包括 W3C TraceContext、B3(Zipkin)、Jaeger 等。C 错误:Context Propagation 可以同时传播 Trace、Metric、Log 的关联上下文(Baggage)。D 错误:traceparent 的标准格式为 version-trace-id-parent-id-trace-flags(5 段),且 tracestate 是可选的独立头。",
"source": null,
"related": []
},
{
"id": "sc-008",
"type": "single_choice",
"difficulty": 3,
"tags": [
"loki",
"promtail",
"logging"
],
"question": "Grafana Loki 与 ELK(Elasticsearch + Logstash + Kibana)在日志架构上的核心区别是?",
"options": {
"A": "Loki 不支持结构化日志,只能处理非结构化文本",
"B": "Loki 不对日志内容建立全文索引,只索引标签(Labels),因此存储成本更低、写入性能更好",
"C": "Loki 只能接收 Kubernetes 环境的日志,不支持裸金属或虚拟机",
"D": "Loki 不支持 PromQL 查询,使用完全不同的查询语法"
},
"answer": "B",
"explanation": "Loki 的核心设计理念是\"像 Prometheus 一样,但用于日志\"。它不像 Elasticsearch 那样对日志全文建立倒排索引,而是只对元数据标签(Labels)建立索引。这使得 Loki 的写入性能更高、存储成本更低(通常比 Elasticsearch 低数倍)。查询时先通过 Labels 缩小范围,再使用 LogQL 在匹配的日志流中做文本搜索。A 错误:Loki 完全支持结构化日志(JSON 等格式)。C 错误:Loki 通过 Promtail、Fluentd 等 Agent 支持各种环境的日志采集。D 错误:Loki 使用 LogQL 查询语言,语法上与 PromQL 有相似之处。",
"source": null,
"related": []
},
{
"id": "sc-009",
"type": "single_choice",
"difficulty": 2,
"tags": [
"kubernetes",
"configmap",
"secret"
],
"question": "以下关于 Kubernetes ConfigMap 和 Secret 的描述,正确的是?",
"options": {
"A": "ConfigMap 和 Secret 的内容都会以 base64 编码存储在 etcd 中",
"B": "Secret 的内容是加密存储的,可以直接作为安全凭证使用",
"C": "ConfigMap 可以被挂载为 Volume 或作为环境变量注入 Pod,Secret 也可以",
"D": "ConfigMap 和 Secret 都必须在创建 Pod 之前创建,不支持动态引用"
},
"answer": "C",
"explanation": "ConfigMap 和 Secret 都支持两种使用方式:一是通过 env 字段注入为 Pod 的环境变量;二是通过 volumes/volumeMounts 挂载为文件。A 错误:ConfigMap 以明文存储(base64 只是 YAML 编码方式,不是加密),Secret 虽然是 base64 编码但这只是编码不是加密(需要配合 encryption at rest 才算真正加密)。B 错误:Secret 的 base64 编码不是加密,任何能访问 etcd 的人都能解码。D 错误:两者都支持在 Pod 创建前先创建,但也支持通过 immutable 配置、外部配置工具(如 External Secrets Operator)动态管理。",
"source": null,
"related": []
},
{
"id": "sc-010",
"type": "single_choice",
"difficulty": 4,
"tags": [
"hpa",
"keda",
"elasticity"
],
"question": "KEDA(Kubernetes Event-driven Autoscaling)相比原生 HPA 的核心优势是?",
"options": {
"A": "KEDA 支持更丰富的事件源,可以根据 Kafka 消费者组的 lag、RabbitMQ 队列深度、Cron 调度等 60+ 种 Event Source 自动扩缩容",
"B": "KEDA 使用完全不同的 Pod 调度算法,能将 Pod 调度到更合适的节点上",
"C": "KEDA 替代了 Kubernetes 的 Pod 控制器,直接管理 Pod 的生命周期",
"D": "KEDA 只能将副本数扩展到 HPA 上限,无法超越 HPA 的能力"
},
"answer": "A",
"explanation": "KEDA 是一个 CNCF 毕业项目,它作为 HPA 的增强层工作。KEDA 的核心价值是提供了丰富的 Scaler(伸缩器),支持 60+ 种事件源的自动扩缩容,包括消息队列(Kafka、RabbitMQ、SQS)、数据库查询、外部监控系统、Cron 表达式等。KEDA 会根据事件源的指标自动计算所需的副本数(包括缩容到 0),然后通过 HPA 执行实际的扩缩容。B 错误:KEDA 不改变 Pod 调度算法。C 错误:KEDA 不替代 Pod 控制器,它只是提供指标和目标副本数。D 错误:KEDA 支持 Scale-to-Zero(将副本缩至 0),这是原生 HPA 做不到的。",
"source": null,
"related": []
},
{
"id": "sc-011",
"type": "single_choice",
"difficulty": 3,
"tags": [
"kubernetes",
"canary",
"istio"
],
"question": "使用 Istio 实现基于 Header 的 Canary 路由时,以下 VirtualService 配置片段中,哪种方式能将带有 x-canary: true Header 的请求路由到新版本?",
"options": {
"A": "在 match 中设置 headers.x-canary.exact: \"true\",并在 route 的 destination.host 中指向新版本的 service",
"B": "在 DestinationRule 中设置 trafficPolicy.loadBalancer.simple: ROUND_ROBIN",
"C": "在 Gateway 中配置 match.headers.x-canary.exact: \"true\"",
"D": "在 VirtualService 的 route 中直接设置 weight: 100 并写死 Header 条件"
},
"answer": "A",
"explanation": "Istio 的 VirtualService 中,可以通过 match.headers 指定请求匹配条件。具体来说,在 VirtualService 的 spec.http[].match[] 中设置 headers.x-canary.exact: \"true\",然后在对应的 route[] 中将 traffic 指向新版本的 Destination(如 svc-canary)。这样带有 x-canary: true Header 的请求会被路由到金丝雀版本,其他请求走主版本。B 错误:DestinationRule 的 loadBalancer 设置的是负载均衡策略,不是路由匹配。C 错误:Gateway 主要处理入口流量的 TLS 终止和主机匹配,Header 路由应在 VirtualService 中配置。D 错误:weight 和 match 条件是不同的配置维度,不可混用。",
"source": null,
"related": []
},
{
"id": "sc-012",
"type": "single_choice",
"difficulty": 5,
"tags": [
"opentelemetry",
"collector",
"otlp"
],
"question": "OpenTelemetry Collector 的 Pipeline 配置中,如果同时配置了 receivers.OTLP → processors.batch → exporters/prometheus 和 receivers.OTLP → processors.batch → exporters/logging,这意味着?",
"options": {
"A": "数据会被重复采集两次,导致指标翻倍",
"B": "数据会同时导出到 Prometheus 和标准输出(logging exporter),这是 Fan-out 模式,支持多目标导出",
"C": "只有第一个 exporter 能接收数据,第二个 exporter 会被忽略",
"D": "OTLP receiver 会根据数据类型自动路由:Metrics 到 Prometheus,Logs 到 logging"
},
"answer": "B",
"explanation": "OpenTelemetry Collector 的 Pipeline 支持 Fan-out 模式,即一个 Pipeline 的 processor 链处理完毕后,可以将数据同时发送给多个 exporter。在这个配置中,数据经过 OTLP receiver 接收和 batch processor 处理后,会同时被发送到 Prometheus exporter(将指标暴露为 Prometheus 格式供抓取)和 logging exporter(将遥测数据输出到标准输出用于调试)。这是一个完全合法且常用的配置。A 错误:数据不会被重复采集,receiver 只采集一次,分发到多个 exporter。C 错误:所有配置的 exporter 都会接收数据,不存在被忽略的情况。D 错误:OTLP receiver 不做路由决策,Pipeline 配置才决定数据流向。",
"source": null,
"related": []
},
{
"id": "sc-013",
"type": "single_choice",
"difficulty": 2,
"tags": [
"prometheus",
"promql"
],
"question": "在 PromQL 中,以下查询表达式 rate(http_requests_total{job=\"api\"}[5m]) 的含义是?",
"options": {
"A": "查询 5 分钟内 HTTP 请求的总数",
"B": "查询 HTTP 请求的每秒平均增长率(QPS),使用 5 分钟的时间窗口计算",
"C": "查询 5 分钟内 HTTP 请求的最大值",
"D": "查询 HTTP 请求的平均延迟时间"
},
"answer": "B",
"explanation": "rate() 是 PromQL 中用于计算 Counter 类型指标每秒平均增长率的函数。rate(http_requests_total{job=\"api\"}[5m]) 的含义是:取最近 5 分钟窗口内 http_requests_total 的增量,除以时间间隔,得到每秒的平均请求速率(即 QPS)。[5m] 是 range vector selector,定义了计算的时间窗口。A 错误:查询总数用 sum(http_requests_total),而不是 rate。C 错误:rate 不是取最大值。D 错误:请求延迟通常由 histogram/summary 类型的指标记录,如 histogram_quantile()。",
"source": null,
"related": []
},
{
"id": "sc-014",
"type": "single_choice",
"difficulty": 4,
"tags": [
"hpa",
"vpa",
"cluster-autoscaler"
],
"question": "在 Kubernetes 中同时使用 HPA 和 VPA 时需要注意什么?",
"options": {
"A": "HPA 和 VPA 完全独立,可以对同一指标(如 CPU)同时配置而不会冲突",
"B": "HPA 和 VPA 可以共存,但需要对相同的资源指标做互斥配置——如果 HPA 基于 CPU 扩缩 Pod 数量,VPA 不应再对 CPU 做垂直调整",
"C": "VPA 会自动替代 HPA 的功能,只需部署 VPA 即可",
"D": "HPA 和 VPA 不能在同一集群中使用,必须二选一"
},
"answer": "B",
"explanation": "HPA 和 VPA 可以在同一集群中共存,但需要避免对相同指标的冲突配置。最佳实践是:HPA 负责基于某类指标(如 custom metrics 或 CPU)调整副本数,而 VPA 负责基于另一类指标(如 Memory)调整 Pod 的资源请求和限制。如果两者同时基于 CPU 调整,HPA 扩缩 Pod 数量会影响 CPU 的聚合指标,VPA 调整 CPU request 又会影响 HPA 的计算,形成冲突。官方建议使用 VPA 的 Off 模式(recommendation-only),由管理员手动或通过脚本应用推荐值,避免与 HPA 冲突。",
"source": null,
"related": []
},
{
"id": "sc-015",
"type": "single_choice",
"difficulty": 3,
"tags": [
"kubernetes",
"blue-green",
"rolling-update",
"grafana"
],
"question": "在一个 Kubernetes 集群中,团队计划使用 Blue-Green 策略部署新版本应用。以下哪种方案是正确的 Blue-Green 实现方式?",
"options": {
"A": "使用单个 Deployment,通过修改镜像标签触发滚动更新,逐步替换旧版本 Pod",
"B": "同时运行两个 Deployment(blue 和 green),通过修改 Service 的 selector 指向新版本的 Deployment 来实现切换",
"C": "创建一个 DaemonSet 让新版本运行在所有节点上,然后删除旧版本的 Pod",
"D": "使用 StatefulSet 的分段发布(partition update)功能实现蓝绿切换"
},
"answer": "B",
"explanation": "Blue-Green 部署的核心是同时维护两个完全相同的生产环境(blue 和 green)。新版本先部署到 green 环境(新 Deployment),测试验证后,通过修改 Service 的 selector label(如将 app: myapp, version: blue 改为 app: myapp, version: green)将流量一次性切换到新版本。回滚时只需将 selector 改回旧版本即可。A 错误:这是 Rolling Update 策略,不是 Blue-Green。C 错误:DaemonSet 用于在每个节点上运行一个 Pod,不适用于 Blue-Green 场景。D 错误:StatefulSet partition update 用于有状态应用的分段更新,不等同于 Blue-Green。",
"source": null,
"related": []
}
]
}