1. 项目概述与核心价值
如果你正在 Kubernetes 集群中管理微服务,那么“可观测性”这个词对你来说一定不陌生。当服务数量膨胀到几十上百个,一次用户请求可能穿越十几个不同的服务,一旦出现性能瓶颈或错误,定位问题就像大海捞针。传统的日志监控已经力不从心,我们需要的是能清晰描绘服务间调用链路、追踪每个请求完整生命周期的工具。这就是分布式链路追踪(Distributed Tracing)的核心价值,而 Apache SkyWalking 正是这个领域的佼佼者。
简单来说,Apache SkyWalking 是一个开源的应用程序性能管理(APM)和可观测性平台。它能自动监控、追踪分布式系统中的请求流,并以可视化的方式展示服务拓扑、调用链详情、性能指标和错误信息。而apache/skywalking-helm这个项目,则是将 SkyWalking 这套复杂的系统,通过 Helm Chart 的方式“打包”起来,让你在 Kubernetes 上部署和管理 SkyWalking 变得像安装一个普通应用一样简单。它封装了 OAP(后端分析平台)、UI(前端界面)、存储依赖(如 Elasticsearch)以及可选组件(如 Satellite 网关)的部署配置,你只需要关注几个关键参数,就能一键拉起一套生产可用的 APM 系统。
2. 核心架构与 Helm Chart 设计解析
在深入部署细节前,理解 SkyWalking 在 Kubernetes 中的核心架构和 Helm Chart 的设计思路至关重要。这能帮助你在后续的配置和排错中做到心中有数。
2.1 SkyWalking 核心组件在 K8s 中的角色
一个完整的 SkyWalking 部署通常包含以下几个核心部分,它们在 Helm Chart 中都有对应的配置模块:
OAP Server (Observability Analysis Platform):这是 SkyWalking 的大脑。它负责接收来自各种探针(Agent、eBPF、Service Mesh 等)上报的遥测数据(Traces, Metrics, Logs),进行实时分析和聚合,并将结果持久化到存储中。在 Helm Chart 中,它被部署为一个或多个
StatefulSet或Deployment,以确保有状态服务的稳定运行。UI (SkyWalking Web UI):这是用户交互的界面。一个
Deployment和一个Service对外提供 Web 服务,你通过浏览器访问它来查看服务拓扑图、调用链、告警等信息。UI 通过 GraphQL 接口与 OAP Server 通信。Storage (存储后端):这是 SkyWalking 的“记忆”。OAP 处理后的数据需要存下来。Helm Chart 原生支持多种存储:
- Elasticsearch (默认且最常用):适合大规模、高吞吐量的场景。Chart 可以集成 ECK (Elastic Cloud on Kubernetes) 自动部署一个 ES 集群,也支持连接外部已有的 ES。
- BanyanDB:Apache SkyWalking 社区自研的时序数据库,专为可观测性数据优化,旨在降低存储成本、提升查询效率。
- PostgreSQL:关系型数据库选项,适合数据量不大或对 SQL 生态有强依赖的环境。
Satellite (卫星,可选):这是一个独立的 Sidecar 或网关组件。在高并发或需要解耦的场景下,可以将数据先上报给 Satellite,再由 Satellite 批量、异步地转发给 OAP,起到流量缓冲和协议转换的作用。这在 Service Mesh(如 Istio)集成时非常有用。
2.2 Helm Chart 的模块化设计
skywalking-helmChart 采用了高度模块化的values.yaml设计。你可以把它理解为一个乐高套装,每个功能组件都是一个独立的模块,可以按需开启或关闭,并精细配置。
# 这是一个简化的 values.yaml 结构示意 oap: enabled: true image: repository: apache/skywalking-oap-server tag: 10.3.0 storageType: elasticsearch replicas: 2 resources: requests: memory: "2Gi" cpu: "1000m" config: {} # 用于覆盖 OAP 的 application.yml 配置 ui: enabled: true image: repository: apache/skywalking-ui tag: 10.3.0 service: type: LoadBalancer # 或 NodePort, ClusterIP elasticsearch: enabled: true # 是否部署内置的 ES 集群 config: # 如果 enabled=false,则在此配置外部 ES 连接信息 host: external-es.example.com port: 9200 banyandb: enabled: false # 与 elasticsearch.enabled 通常二选一 satellite: enabled: false这种设计的好处是灵活性极高。你可以轻松实现多种部署形态:从最简单的“All-in-One”(OAP+UI+内置ES)测试环境,到复杂的“生产高可用”架构(OAP 多副本、外置高可用 ES 集群、启用 Satellite 网关)。
注意:
oap.storageType必须与你启用的存储后端匹配。例如,如果你设置storageType: elasticsearch,但elasticsearch.enabled=false且未配置外部 ES,OAP 将无法启动,因为它找不到存储。
3. 实战部署:从零搭建 SkyWalking 可观测性平台
理论讲完,我们进入实战环节。我将以最常用的Elasticsearch 作为存储后端,在 Kubernetes 上部署一套完整的 SkyWalking 10.3.0 版本。假设你的集群已经安装了 Helm 3 并配置了正确的 kubeconfig。
3.1 环境准备与前置检查
部署前,请确保你的 Kubernetes 集群满足以下条件:
- 资源充足:至少 4-6 个可用 CPU 和 8-12 GB 可用内存,用于运行 OAP、UI 和 Elasticsearch。
- 存储类(StorageClass):如果启用内置 Elasticsearch 并需要数据持久化,集群必须配置好可用的 StorageClass。可以使用
kubectl get storageclass检查。 - 网络策略:确保 Pod 之间可以通信,特别是 OAP 需要能访问存储服务(ES/BanyanDB/PostgreSQL)的端口。
为了方便管理,我们首先设置一些环境变量。这比每次在命令中硬编码要好得多。
# 设置 SkyWalking 的 Helm 发布名称和命名空间 export SKYWALKING_RELEASE_NAME="skywalking-prod" export SKYWALKING_RELEASE_NAMESPACE="observability" # 指定要安装的 Helm Chart 版本 export SKYWALKING_HELM_VERSION="4.7.0" # 指定 SkyWalking 组件镜像版本 export SKYWALKING_IMAGE_TAG="10.3.0"然后,为这次部署创建一个独立的命名空间,这是一个好的隔离实践。
kubectl create namespace $SKYWALKING_RELEASE_NAMESPACE3.2 使用 Docker 官方仓库安装(推荐方式)
从 4.3.0 版本开始,SkyWalking Helm Chart 已发布到 Docker 官方 OCI 仓库,这是最简洁的安装方式。
基础安装命令:
helm install $SKYWALKING_RELEASE_NAME \ oci://registry-1.docker.io/apache/skywalking-helm \ --version $SKYWALKING_HELM_VERSION \ -n $SKYWALKING_RELEASE_NAMESPACE \ --set oap.image.tag=$SKYWALKING_IMAGE_TAG \ --set oap.storageType=elasticsearch \ --set ui.image.tag=$SKYWALKING_IMAGE_TAG这条命令做了以下几件事:
helm install: 安装一个名为skywalking-prod的 Helm Release。oci://...: 从 Docker Hub 的 OCI 仓库拉取 Chart。--version: 指定 Chart 版本为 4.7.0。-n: 指定安装到observability命名空间。--set: 覆盖 Chart 的默认值。这里我们设置了 OAP 和 UI 的镜像标签为 10.3.0,并指定存储类型为 Elasticsearch。
执行后,Helm 会输出一系列创建的资源列表(Deployment, Service, StatefulSet 等)。你可以用以下命令观察部署进度:
# 查看所有相关 Pod 的状态,等待它们都变为 Running kubectl get pods -n $SKYWALKING_RELEASE_NAMESPACE -w # 查看 Helm Release 的状态 helm list -n $SKYWALKING_RELEASE_NAMESPACE实操心得:第一次部署时,Elasticsearch Pod 的启动可能较慢(尤其是需要拉取镜像和初始化数据卷),可能需要 2-5 分钟。OAP Server 会等待 ES 就绪后才启动。耐心等待所有 Pod 状态变为
Running且READY列为1/1或2/2。
3.3 访问 SkyWalking UI
默认情况下,UI 服务类型是ClusterIP,只能在集群内部访问。为了从外部访问,我们可以在安装时或之后修改服务类型。
安装时直接暴露:
helm install $SKYWALKING_RELEASE_NAME ... \ --set ui.service.type=NodePort \ --set ui.service.nodePort=30080或者使用LoadBalancer(如果云提供商支持):
helm install $SKYWALKING_RELEASE_NAME ... \ --set ui.service.type=LoadBalancer安装后修改:如果已经安装,可以使用helm upgrade或直接修改 Service。
kubectl patch svc $SKYWALKING_RELEASE_NAME-ui \ -n $SKYWALKING_RELEASE_NAMESPACE \ -p '{"spec": {"type": "NodePort"}}' # 然后查看分配的节点端口 kubectl get svc $SKYWALKING_RELEASE_NAME-ui -n $SKYWALKING_RELEASE_NAMESPACE假设我们使用 NodePort 方式,并且端口是 30080,集群任意节点 IP 为192.168.1.100,那么可以在浏览器中访问http://192.168.1.100:30080即可打开 SkyWalking 的 Web 控制台。
3.4 高级配置:使用自定义 values.yaml 文件
命令行--set参数适合简单覆盖,对于复杂的生产配置,强烈推荐使用自定义的values.yaml文件。这便于版本控制和复用。
创建一个名为my-skywalking-values.yaml的文件:
# my-skywalking-values.yaml oap: image: tag: 10.3.0 storageType: elasticsearch replicas: 2 # 生产环境建议至少 2 个副本以实现高可用 resources: requests: memory: "4Gi" cpu: "2000m" limits: memory: "8Gi" cpu: "4000m" # 通过环境变量配置 OAP,优先级高于 config 文件 env: SW_CORE_RECORD_DATA_TTL: 90 # 指标数据保留 90 天 SW_CORE_METRICS_DATA_TTL: 90 # 追踪数据保留 90 天 ui: image: tag: 10.3.0 service: type: LoadBalancer resources: requests: memory: "1Gi" cpu: "500m" elasticsearch: enabled: true # 配置 ES 资源,根据数据量调整 elasticsearch: nodeSets: - name: default count: 3 # 3个节点集群 config: node.store.allow_mmap: false podTemplate: spec: containers: - name: elasticsearch resources: requests: memory: "2Gi" cpu: "1000m" limits: memory: "4Gi" cpu: "2000m" volumeClaimTemplates: - metadata: name: elasticsearch-data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "fast-ssd" # 替换为你集群的 StorageClass resources: requests: storage: "100Gi"然后使用-f参数安装或升级:
helm upgrade --install $SKYWALKING_RELEASE_NAME \ oci://registry-1.docker.io/apache/skywalking-helm \ --version $SKYWALKING_HELM_VERSION \ -n $SKYWALKING_RELEASE_NAMESPACE \ -f my-skywalking-values.yaml--install参数使得upgrade命令在 Release 不存在时会自动执行安装,这是一个非常实用的技巧。
4. 存储方案选型与深度配置
存储是 SkyWalking 的基石,选型和配置直接影响性能、成本和稳定性。Helm Chart 提供了极大的灵活性。
4.1 Elasticsearch 方案详解
方案一:使用 Chart 内置的 ECK Elasticsearch(默认)这是最省心的方式。Chart 会通过依赖(eck-operator)自动部署一个 Elasticsearch 集群。
- 优点:一键部署,集成度高,配置统一管理。
- 缺点:对集群资源要求较高,部署的 ES 版本相对固定。
- 关键配置:在
values.yaml中,elasticsearch.enabled=true(默认),并通过elasticsearch.elasticsearch下的配置来定义 ES 集群的规格、存储、资源等。如上一节的示例所示。
一个重要陷阱:CRD 冲突问题ECK Operator 需要 Custom Resource Definitions (CRDs)。在 Helm 依赖管理中,如果 CRD 已存在,重复安装会导致失败。因此,官方文档提供了先手动安装 CRD 的步骤。但在实际使用中,更稳妥的做法是:
- 检查集群是否已存在 ECK CRDs:
kubectl get crd | grep elastic - 如果不存在,按照文档手动安装一次。
- 在 Helm 安装命令中,必须添加
--set eck-operator.installCRDs=false,以避免 Chart 尝试重复安装。
方案二:连接外部 Elasticsearch 集群如果你已经有成熟的 ES 集群,或者希望由专门的团队维护存储,可以采用此方案。
# external-es-values.yaml elasticsearch: enabled: false # 关键:禁用内置 ES 部署 config: host: "your-elasticsearch-host.example.com" # 外部 ES 服务地址 port: http: 9200 # 如果启用了安全认证 user: "elastic" passwordSecretName: "skywalking-es-credentials" # 密码存于 Secret passwordSecretKey: "password"你需要提前创建一个包含密码的 Secret:
kubectl create secret generic skywalking-es-credentials \ -n $SKYWALKING_RELEASE_NAMESPACE \ --from-literal=password='your-elastic-password'4.2 BanyanDB 方案初探
BanyanDB 是 SkyWalking 生态的新星,专为可观测性数据设计。如果你对降低 ES 的运维成本和存储开销感兴趣,可以尝试。
helm install $SKYWALKING_RELEASE_NAME ... \ --set oap.storageType=banyandb \ --set elasticsearch.enabled=false \ --set banyandb.enabled=true \ --set banyandb.image.tag=0.9.0 \ --set banyandb.storage.persistence.size=50Gi注意:BanyanDB 目前仍处于快速发展阶段,对于超大规模的生产环境,建议先在小规模场景或测试环境中进行评估。其 Helm 配置项(如
banyandb.cluster.replicationFactor)需要根据官方文档仔细调优。
4.3 存储方案选择建议
| 特性 | Elasticsearch (内置ECK) | Elasticsearch (外部) | BanyanDB |
|---|---|---|---|
| 部署复杂度 | 中等(一键部署,但需处理CRD) | 低(仅配置连接) | 中等(一键部署) |
| 运维成本 | 高(需维护K8s内ES集群) | 低(由外部团队负责) | 待评估(较新) |
| 性能与规模 | 成熟稳定,适合大规模 | 取决于外部集群能力 | 为可观测性优化,潜力大 |
| 成本 | 占用集群资源多 | 可能有额外云服务费用 | 目标为降低成本 |
| 生产建议 | 中小规模,希望All-in-One管理 | 大规模,已有成熟ES运维体系 | 技术尝新,成本敏感型测试环境 |
5. 高级特性与集成配置
5.1 启用 Satellite 作为数据网关
在 Service Mesh(如 Istio)或高数据上报量的场景,启用 Satellite 可以解耦 Agent 与 OAP,提升系统弹性。
# values-with-satellite.yaml satellite: enabled: true image: tag: v0.4.0 # Satellite 本身可以配置接收协议和转发规则 config: receivers: istio: enabled: true ports: - 11800 # 接收 Istio Mixer 的数据 forwarders: oap: enabled: true addresses: skywalking-oap:12800 # 转发给 OAP gRPC 端口安装后,你的应用 Agent 或 Istio 需要将数据上报地址改为 Satellite 的 Service,例如:skywalking-satellite.observability:11800。
5.2 自定义 OAP 配置文件
有时你需要修改 SkyWalking OAP 的详细配置(如调整分析器、采样率等)。Helm Chart 提供了oap.config字段来覆盖默认的application.yml。
oap: config: # 这里的内容会被合并到 OAP 的 application.yml 中 core: default: # 将采样率调整为 50% selector: ${SW_CORE_SAMPLE_N_PER_3_SECS:2} # 修改命名空间分隔符 namespace: ${SW_NAMESPACE:MyApp-} # 配置 Kafka fetcher 用于接收日志 fetcher: kafka: selector: ${SW_FETCHER_KAFKA:default} enabled: ${SW_FETCHER_KAFKA_ENABLED:true} bootstrapServers: ${SW_FETCHER_KAFKA_BOOTSTRAP_SERVERS:localhost:9092}重要提示:通过环境变量(
oap.env)设置的配置项拥有最高优先级,会覆盖oap.config文件和默认配置。这是 SkyWalking 的配置加载顺序决定的。
5.3 初始化 Job 的管理
SkyWalking OAP 在首次启动时,可能需要运行一个初始化 Job 来创建索引或表结构。这个 Job 通常只运行一次。但如果存储结构变更或初始化失败,你可能需要重新运行它。
官方文档提供了删除并重新创建 Job 的复杂方法。在实际操作中,一个更简单的技巧是直接让 Deployment 或 StatefulSet 的 Pod 重启,因为 OAP 服务器本身在启动时会检查存储结构并自动执行必要的初始化操作(如果配置了oap.env.SW_STORAGE_AUTO_RECOVERY: true)。你可以通过滚动更新 OAP 镜像版本来触发重启:
kubectl rollout restart deployment/$SKYWALKING_RELEASE_NAME-oap -n $SKYWALKING_RELEASE_NAMESPACE6. 生产环境部署清单与避坑指南
基于多次在生产环境部署 SkyWalking 的经验,我总结了一份检查清单和常见问题解决方案。
6.1 生产部署前检查清单
资源规划:
- OAP:根据 Trace 量预估。中等流量(每秒数千跨度)建议至少 2 副本,每副本 4CPU/8GiB 内存起步。开启 JVM 堆内存监控(
-XX:+UseContainerSupport -XX:MaxRAMPercentage=80)。 - Elasticsearch:这是资源消耗大户。生产环境至少 3 个节点(主节点+数据节点分离更佳),每个节点建议 4CPU/8GiB 内存,并使用 SSD 存储。预留足够的存储空间(数据保留天数 × 每日数据增量 × 副本数)。
- UI:1-2 副本,每副本 1CPU/2GiB 内存通常足够。
- OAP:根据 Trace 量预估。中等流量(每秒数千跨度)建议至少 2 副本,每副本 4CPU/8GiB 内存起步。开启 JVM 堆内存监控(
存储与持久化:
- 务必为 Elasticsearch 或 BanyanDB 配置持久化存储卷(PersistentVolume),否则数据在 Pod 重启后会丢失。
- 确认 StorageClass 的回收策略(
ReclaimPolicy)是否符合预期(通常是Retain或Delete)。
高可用与健康检查:
- 为 OAP、UI 配置
readinessProbe和livenessProbe。 - 考虑将 OAP 的 Service 设置为
ClusterIP并配合多个副本,实现负载均衡和故障转移。 - 为 Elasticsearch 配置反亲和性(
podAntiAffinity),避免同一节点运行多个数据节点。
- 为 OAP、UI 配置
安全配置:
- 为 Elasticsearch 启用 TLS 和密码认证(ECK 默认开启)。
- 通过 NetworkPolicy 限制对 SkyWalking 组件(尤其是 OAP 接收端口 11800/12800)的访问。
- 考虑为 UI 配置 Ingress 并集成 SSO。
6.2 常见问题与排查实录
问题一:OAP Pod 持续 CrashLoopBackOff,日志显示连接存储失败。
- 排查思路:
- 检查 OAP 日志:
kubectl logs -f <oap-pod-name> -n $SKYWALKING_RELEASE_NAMESPACE。重点看启动初期的错误。 - 常见错误
“Failed to connect to Elasticsearch”:检查oap.storageType是否与启用的存储一致;检查存储服务(如 ES)的 Pod 是否Ready;检查网络策略是否阻止了 OAP 到存储服务的连接(如 9200 端口)。 - 使用
kubectl exec进入 OAP Pod,尝试用curl或telnet手动连接存储服务的主机和端口,验证网络连通性。
- 检查 OAP 日志:
- 解决方案:确保存储服务先于 OAP 启动并健康。如果是外置存储,仔细核对
elasticsearch.config.host/port/user/password的配置。
问题二:UI 可以访问,但拓扑图空白,或显示“No data”。
- 排查思路:
- 检查 UI Pod 日志,看是否有连接 OAP 后端的错误。
- 在浏览器开发者工具的“网络”选项卡中,查看 UI 向 OAP(通常是
/graphql接口)发起的请求是否返回错误(如 502, 503)。 - 检查 OAP Pod 是否正常处理数据。可以查看 OAP 日志中是否有接收和处理 Trace 的记录。
- 解决方案:这通常意味着 OAP 没有收到任何应用上报的数据。你需要检查:
- 应用是否正确集成了 SkyWalking Agent 或配置了 Service Mesh 的数据上报。
- Agent 或 Mesh 的上报地址(
backend_service)是否指向了正确的 OAP 或 Satellite 服务名和端口(例如skywalking-oap.observability:11800)。 - 在 OAP Pod 内使用
netstat -tlnp或ss -tlnp确认 11800(gRPC)和 12800(HTTP)端口在监听。
问题三:Elasticsearch Pod 处于 Pending 状态,事件显示“pod has unbound immediate PersistentVolumeClaims”。
- 排查思路:这是典型的 PVC 无法绑定 PV 的问题。
kubectl describe pvc -n $SKYWALKING_RELEASE_NAMESPACE查看 PVC 的详细信息。- 检查
storageClassName是否正确,以及集群中是否存在该 StorageClass:kubectl get storageclass。 - 检查 StorageClass 的配置,例如是否设置了
volumeBindingMode: WaitForFirstConsumer导致延迟绑定。
- 解决方案:确保指定的 StorageClass 存在且可用。如果使用本地存储或特定云存储,可能需要管理员提前创建好对应的 PV 或 StorageClass。在测试环境,可以临时将
volumeClaimTemplates的storageClassName改为""(空字符串)以使用默认 StorageClass,或将accessModes改为ReadWriteOnce。
问题四:升级 Helm Release 后,配置未生效或出现意外回滚。
- 排查思路:Helm 升级是声明式的,但有时
values.yaml的合并逻辑可能导致意外。- 使用
helm get values $SKYWALKING_RELEASE_NAME -n $SKYWALKING_RELEASE_NAMESPACE查看当前生效的配置。 - 使用
helm upgrade --dry-run --debug ...命令模拟升级,查看生成的 Kubernetes 资源清单,确认配置变更是否符合预期。
- 使用
- 解决方案:对于生产环境,任何升级操作前,务必先进行
--dry-run。对于关键配置,考虑使用helm rollback命令回退到上一个版本。维护好每次升级所使用的values.yaml文件,这是回滚和审计的依据。
部署和运维 SkyWalking 是一个持续调优的过程。从存储方案的选型、资源配额的限制,到与现有监控告警体系的整合,每一步都需要结合实际的业务流量和技术栈来决策。skywalking-helm项目提供的这份 Chart,极大地简化了在 Kubernetes 上的部署复杂度,让你能更专注于利用 SkyWalking 提供的强大可观测能力去洞察和优化你的微服务系统。