TH小破站

  • 首页
  • 容器
    • 认识Docker
    • DockerFile详解
  • k8s
    • 认识Kubernetes
    • Kubernetes部署--(kubeadm方式)
    • kubeasz部署k8s集群
    • Ansible-binary部署k8s集群-1.31.2
  • Ceph
    • 认识分布式存储
    • CPEH部署
  • CI/CD
    • DevOps认识
    • 部署--Gitlab
  • ELK
    • ELK简介
    • Elasticsearch
    • Kibana部署
    • Logstash
    • ELK--收集 tomcat 日志(实战)
  • HD
    • 认识--大数据
    • Hadoop-单机部署
    • Hadoop-伪分布部署
    • Hadoop-完全分布部署
    • Hadoop-(HA)完全分布部署
    • Ambari自动部署--Hadoop
  • Nginx
    • Nginx功能介绍
    • Nginx安全选项
    • Nginx配置文件简单介绍
    • 网站服务器部署
  • 监控
    • ZABBIX-部署(yum)
    • ZABBIX-编译安装
  • 云计算
    • KVM 概述
    • OpenStack企业级部署(T版)
    • OpenStack之dashboard部署
    • OpenStack-controller的高可用
    • openstack(Caracal版_ubuntu版本)部署
  • 数据库
    • mariadb与mysql
    • mysql主从
    • MySQL--冷备(实战)
    • MySQL--热备(dump表)
    • MySQL--热备(dump库)
    • 数据恢复实战案例
    • Xtrabackup实现MySql8.x全量备份
    • MyCat实现数据库读写分离
    • MHA实现数据库高可用
    • Percona XtraDB(PXC)实现数据库集群高可用
    • 数据库压力测试
    • PostgreSQL 基操
    • PostgreSQL备份恢复
    • PostgreSQL高可用
    • MongDB安装配置基础使用
    • MongoDB实现复制集
    • MongoDB备份还原
  • 自动化
    • ssh远程服务原理及配置
    • Ansible剧本文件应用
    • Ansible管理服务介绍
    • Ansible自动化部署node_exporter(包含升级,回滚)
    • Saltstack-部署安装
  • 脚本
    • 一键查看服务器资源利用率
    • 一键生成SSL证书
    • 保存指定数量的文件/目录
    • 初始化服务器
    • 扫描可用IP
    • 批量分发SSH密钥
    • 监控多主机磁盘脚本
    • 一键安装MySQL8.x脚本
    • Python脚本监控ES集群
    • 资源巡检脚本
    • 查看各用户使用的cpu占比
热衷于分享
架构师成长之路 !!!
  1. 首页
  2. 云原生
  3. 正文

Pyroscope 进行程序内部火焰图展示

2026年1月31日 675点热度 0人点赞 0条评论

部署安装

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm search  repo  grafana/pyroscope
kubectl create namespace pyroscope-test
helm -n pyroscope-test install pyroscope grafana/pyroscope
[root@master-1 keda]#kubectl get po -n pyroscope-test 
NAME                READY   STATUS    RESTARTS   AGE
pyroscope-0         1/1     Running   0          97m
pyroscope-alloy-0   2/2     Running   0          97m

侵入式

GO代码引入

package main
import (
    ...
    "github.com/grafana/pyroscope-go"
    ...
)

func initPyroScope() {
    runtime.SetMutexProfileFraction(5)
    runtime.SetBlockProfileRate(5)
    _, _ = pyroscope.Start(pyroscope.Config{
        ApplicationName: "tcp_backend",                                             // 应用名称
        ServerAddress:   "http://pyroscope.pyroscope-test.svc.cluster.local.:4040", // 上报地址
        Logger:          pyroscope.StandardLogger,
        Tags:            map[string]string{"hostname": os.Getenv("HOSTNAME")},
        ProfileTypes: []pyroscope.ProfileType{
            pyroscope.ProfileCPU,
            pyroscope.ProfileAllocObjects,
            pyroscope.ProfileAllocSpace,
            pyroscope.ProfileInuseObjects,
            pyroscope.ProfileInuseSpace,
            pyroscope.ProfileGoroutines,
            pyroscope.ProfileMutexCount,
            pyroscope.ProfileMutexDuration,
            pyroscope.ProfileBlockCount,
            pyroscope.ProfileBlockDuration,
        },
    })
}


func main() {
    initPyroScope()
    .....
}

部署验证

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tcp-backend
  namespace: default
  labels:
    app: tcp-backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tcp-backend
  template:
    metadata:
      labels:
        app: tcp-backend
    spec:
      containers:
      - name: tcp-backend
        image: registry.cn-zhangjiakou.aliyuncs.com/tanghao-public/k8s-tcp-test:v0.3
        imagePullPolicy: IfNotPresent
        ports:
        - name: tcp
          containerPort: 8080
          protocol: TCP
        - name: metrics
          containerPort: 9090
          protocol: TCP
        readinessProbe:
          tcpSocket:
            port: tcp
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: tcp
          initialDelaySeconds: 15
          periodSeconds: 20
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"

---
apiVersion: v1
kind: Service
metadata:
  name: tcp-backend
  namespace: default
  labels:
    app: tcp-backend
spec:
  type: ClusterIP
  selector:
    app: tcp-backend
  ports:
  - name: tcp
    port: 8080
    targetPort: tcp
    protocol: TCP
  - name: metrics
    port: 9090
    targetPort: metrics
    protocol: TCP

查看收集的数据

半侵入式

GO 代码引入

import _ "net/http/pprof"

go func() {
    http.ListenAndServe(":6060", nil)
}()

部署验证

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tcp-backend
  namespace: default
  labels:
    app: tcp-backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tcp-backend
  template:
    metadata:
      annotations:
        profiles.grafana.com/memory.scrape: "true"
        profiles.grafana.com/memory.port: "6060"
        profiles.grafana.com/cpu.scrape: "true"
        profiles.grafana.com/cpu.port: "6060"
        profiles.grafana.com/goroutine.scrape: "true"
        profiles.grafana.com/goroutine.port: "6060"
      labels:
        app: tcp-backend
    spec:
      containers:
      - name: tcp-backend
        image: registry.cn-zhangjiakou.aliyuncs.com/tanghao-public/k8s-tcp-test:v0.4
        imagePullPolicy: IfNotPresent
        ports:
        - name: tcp
          containerPort: 8080
          protocol: TCP
        - name: metrics
          containerPort: 9090
          protocol: TCP
        - name: pprof
          containerPort: 6060
          protocol: TCP
        readinessProbe:
          tcpSocket:
            port: tcp
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: tcp
          initialDelaySeconds: 15
          periodSeconds: 20
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"

---
apiVersion: v1
kind: Service
metadata:
  name: tcp-backend
  namespace: default
  labels:
    app: tcp-backend
spec:
  type: ClusterIP
  selector:
    app: tcp-backend
  ports:
  - name: tcp
    port: 8080
    targetPort: tcp
    protocol: TCP
  - name: metrics
    port: 9090
    targetPort: metrics
    protocol: TCP

查看收集的数据

无侵入式

部署单独的alloy

配置

[root@master-1 pyroscope]# helm pull  grafana/alloy  --version=1.5.2
[root@master-1 pyroscope]#tar xf alloy-1.5.2.tgz 
[root@master-1 alloy]#cat values.yaml | grep -v '#'
nameOverride: null

namespaceOverride: null

fullnameOverride: null

global:
  image:
    registry: ""

    pullSecrets: []

  podSecurityContext: {}

crds:
  create: true

alloy:
  configMap:
    create: true
    content: ''

    name: null
    key: null

  clustering:
    enabled: false

    name: ""

    portName: http

  stabilityLevel: "generally-available"

  storagePath: /tmp/alloy

  enableHttpServerPort: true

  listenAddr: 0.0.0.0

  listenPort: 12345

  listenScheme: HTTP

  initialDelaySeconds: 10

  timeoutSeconds: 1

  uiPathPrefix: /

  enableReporting: true

  extraEnv: []

  envFrom: []

  extraArgs: []

  extraPorts: []

  hostAliases: []

  mounts:
    varlog: false
    dockercontainers: false

    extra:
      - name: proc
        mountPath: /proc
        readOnly: true

  securityContext:
    privileged: true
  resources: {}

  lifecycle: {}

  livenessProbe: {}

image:
  registry: "docker.io"
  repository: grafana/alloy
  tag: null
  digest: null
  pullPolicy: IfNotPresent
  pullSecrets: []

rbac:
  create: true

  namespaces: []

  rules:
    - apiGroups: ["", "discovery.k8s.io", "networking.k8s.io"]
      resources: ["endpoints", "endpointslices", "ingresses", "pods", "services"]
      verbs: ["get", "list", "watch"]
    - apiGroups: [""]
      resources: ["pods", "pods/log", "namespaces"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["monitoring.grafana.com"]
      resources: ["podlogs"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["monitoring.coreos.com"]
      resources: ["prometheusrules"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["monitoring.coreos.com"]
      resources: ["alertmanagerconfigs"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["monitoring.coreos.com"]
      resources: ["podmonitors", "servicemonitors", "probes", "scrapeconfigs"]
      verbs: ["get", "list", "watch"]
    - apiGroups: [""]
      resources: ["events"]
      verbs: ["get", "list", "watch"]
    - apiGroups: [""]
      resources: ["configmaps", "secrets"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["apps", "extensions"]
      resources: ["replicasets"]
      verbs: ["get", "list", "watch"]

  clusterRules:
    - apiGroups: [""]
      resources: ["nodes", "nodes/proxy", "nodes/metrics"]
      verbs: ["get", "list", "watch"]
    - nonResourceURLs: ["/metrics"]
      verbs: ["get"]

serviceAccount:
  create: true
  additionalLabels: {}
  annotations: {}
  name: null
  automountServiceAccountToken: true

configReloader:
  enabled: true
  image:
    registry: "quay.io"
    repository: prometheus-operator/prometheus-config-reloader
    tag: v0.81.0
    digest: ""
  customArgs: []
  resources:
    requests:
      cpu: "10m"
      memory: "50Mi"
  securityContext:
    privileged: true

controller:
  type: 'daemonset'

  replicas: 1

  extraLabels: {}

  extraAnnotations: {}

  parallelRollout: true

  minReadySeconds: 10

  hostNetwork: true

  hostPID: true

  dnsPolicy: ClusterFirst

  terminationGracePeriodSeconds: null

  updateStrategy: {}

  nodeSelector: {}

  tolerations: []

  topologySpreadConstraints: []

  priorityClassName: ''

  podAnnotations: {}

  podLabels: {}

  podDisruptionBudget:
    enabled: false
    minAvailable: null
    maxUnavailable: null

  enableStatefulSetAutoDeletePVC: false

  autoscaling:
    enabled: false
    minReplicas: 1
    maxReplicas: 5
    targetCPUUtilizationPercentage: 0
    targetMemoryUtilizationPercentage: 80

    scaleDown:
      policies: []
      selectPolicy: Max
      stabilizationWindowSeconds: 300

    scaleUp:
      policies: []
      selectPolicy: Max
      stabilizationWindowSeconds: 0

    horizontal:
      enabled: false

      minReplicas: 1
      maxReplicas: 5
      targetCPUUtilizationPercentage: 0
      targetMemoryUtilizationPercentage: 80

      scaleDown:
        policies: []
        selectPolicy: Max
        stabilizationWindowSeconds: 300

      scaleUp:
        policies: []
        selectPolicy: Max
        stabilizationWindowSeconds: 0
    vertical:
      enabled: false

      recommenders: []

      resourcePolicy:
        containerPolicies:
        - containerName: alloy
          controlledResources:
          - cpu
          - memory
          controlledValues: "RequestsAndLimits"
          maxAllowed: {}
          minAllowed: {}

      updatePolicy:

  affinity: {}

  volumes:
    extra:
      - name: proc
        hostPath:
          path: /proc

  volumeClaimTemplates: []

  initContainers: []

  extraContainers: []

networkPolicy:
  enabled: false
  flavor: kubernetes

  policyTypes:
    - Ingress
    - Egress

  ingress:
    - {}
  egress:
    - {}

service:
  enabled: true
  type: ClusterIP
  nodePort: 31128
  clusterIP: ''
  internalTrafficPolicy: Cluster
  annotations: {}

serviceMonitor:
  enabled: false
  additionalLabels: {}
  interval: ""
  metricRelabelings: []

  tlsConfig: {}

  relabelings: []
ingress:
  enabled: false
  annotations:
    {}
  labels: {}
  path: /
  faroPort: 12347

  pathType: Prefix

  hosts:
    - chart-example.local
  extraPaths: []

  tls: []

extraObjects: []
[root@master-1 alloy]#cat config/example.alloy 
// =========================
// 全局日志
// =========================
logging {
  level = "info"
}

// =========================
// Pyroscope 写入端
// =========================
pyroscope.write "default" {
  endpoint {
    url = "http://10.96.153.34:4040"
  }
}

// =========================
// 1. Kubernetes 服务发现
// =========================
discovery.kubernetes "k8s_pods" {
  role = "pod"
  
  // 命名空间过滤
  namespaces {
    names = ["default"] 
  }
}

// =========================
// 2. 必须增加:过滤本机 Pod (防止重复采集)
// =========================
// 如果 Alloy 是以 DaemonSet 运行的,必须只处理本节点的 Pod
// 否则集群里 10 个 Alloy 会同时采集同一个 Pod 10 次
discovery.relabel "k8s_pods_local" {
  targets = discovery.kubernetes.k8s_pods.targets

  rule {
    source_labels = ["__meta_kubernetes_pod_node_name"]
    target_label  = "__host__" // 仅作临时对比用
  }

  // 这里的 HOSTNAME 必须是 Alloy Pod 里的环境变量 (通常 DaemonSet 会注入 spec.nodeName)
  // 如果你没有注入 HOSTNAME 环境变量,需要去 DaemonSet yaml 里加一下
  // 1. 必须保留:过滤本机 Pod
  rule {
    source_labels = ["__meta_kubernetes_pod_node_name"]
    regex         = sys.env("HOSTNAME") 
    action        = "keep"
  }
  // 2. 映射 Namespace (这样你就能在 Pyroscope 面板看到 namespace 标签了)
  rule {
    source_labels = ["__meta_kubernetes_namespace"]
    target_label  = "namespace"
  }
  // 3. 映射 Pod Name
  rule {
    source_labels = ["__meta_kubernetes_pod_name"]
    target_label  = "pod"
  }
  // 4. 映射 Container Name
  rule {
    source_labels = ["__meta_kubernetes_pod_container_name"]
    target_label  = "container"
  }
  rule {
    source_labels = ["__meta_kubernetes_pod_label_app"]
    target_label  = "service_name"
  }
}

// =========================
// 3. eBPF Profiling
// =========================
pyroscope.ebpf "kubernetes" {
  forward_to = [pyroscope.write.default.receiver]

  // 使用经过 relabel 过滤后的 targets (只包含本节点的 Pod)
  targets = discovery.relabel.k8s_pods_local.output

  sample_rate = 97 
}

部署

[root@master-1 alloy]# helm upgrade  alloy --namespace alloy .

查看数据

目前只能采集 CPU 信息

标签: 暂无
最后更新:2026年1月31日

tanghao946

这个人很懒,什么都没留下

点赞
< 上一篇

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复
文章目录
  • 部署安装
  • 侵入式
    • GO代码引入
    • 部署验证
    • 查看收集的数据
  • 半侵入式
    • GO 代码引入
    • 部署验证
    • 查看收集的数据
  • 无侵入式
    • 部署单独的alloy
      • 配置
      • 部署
    • 查看数据

COPYRIGHT © 2025 TH小破站. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

渝ICP备2023013789号

渝公网安备50011702500926号