Parca es una plataforma de perfilado continuo de código abierto que usa eBPF para recopilar datos de perfilado en toda tu infraestructura con sobrecarga casi nula. Consiste en Parca Agent (recopilador basado en eBPF) y Parca Server (motor de almacenamiento y consultas).
Instalación
Linux/Ubuntu
# Install Parca Server (binary)
curl -sL https://github.com/parca-dev/parca/releases/latest/download/parca_Linux_x86_64.tar.gz | tar xz
sudo mv parca /usr/local/bin/
# Install Parca Agent (binary)
curl -sL https://github.com/parca-dev/parca-agent/releases/latest/download/parca-agent_Linux_x86_64.tar.gz | tar xz
sudo mv parca-agent /usr/local/bin/
# Verify installation
parca --version
parca-agent --version
Docker
# Run Parca Server
docker run -d --name parca \
-p 7070:7070 \
ghcr.io/parca-dev/parca:latest \
/parca --config-path=/parca.yaml
# Run Parca Agent
docker run -d --name parca-agent \
--privileged \
--pid=host \
-v /sys:/sys:ro \
-v /lib/modules:/lib/modules:ro \
ghcr.io/parca-dev/parca-agent:latest \
/parca-agent --node=my-host \
--store-address=parca-server:7070 \
--insecure
Configuración del servidor Parca
# parca.yaml — Configuración del servidor Parca
object_storage:
bucket:
type: "FILESYSTEM"
config:
directory: "/var/lib/parca/data"
# Iniciar servidor con configuración
# parca --config-path=parca.yaml --cors-allowed-origins="*"
# Iniciar servidor Parca con valores predeterminados (almacenamiento en memoria)
parca --config-path=parca.yaml
# Dirección de escucha personalizada
parca --config-path=parca.yaml --http-address=:7070
# Habilitar CORS para acceso a la interfaz web
parca --config-path=parca.yaml --cors-allowed-origins="*"
# Con registro de depuración
parca --config-path=parca.yaml --log-level=debug
# Acceder a la interfaz web
# http://localhost:7070
Agente Parca
# Iniciar agente con perfilado eBPF (requiere root/privileged)
sudo parca-agent \
--node=my-hostname \
--store-address=localhost:7070 \
--insecure
# Perfilar a frecuencia personalizada (predeterminado 19 Hz)
sudo parca-agent \
--node=my-hostname \
--store-address=localhost:7070 \
--insecure \
--profiling-cpu-sampling-frequency=49
# Perfilar solo cgroups específicos
sudo parca-agent \
--node=my-hostname \
--store-address=localhost:7070 \
--insecure \
--profiling-cgroup-path=/sys/fs/cgroup/system.slice/my-service.service
# Deshabilitar desenrollado de pila del kernel
sudo parca-agent \
--node=my-hostname \
--store-address=localhost:7070 \
--insecure \
--profiling-disable-kernel
# Habilitar extracción de información de depuración
sudo parca-agent \
--node=my-hostname \
--store-address=localhost:7070 \
--insecure \
--debuginfo-upload-disable=false
Despliegue en Kubernetes
# parca-server.yaml — Desplegar servidor Parca en Kubernetes
# Aplicar con: kubectl apply -f parca-server.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: parca
namespace: parca
spec:
replicas: 1
selector:
matchLabels:
app: parca
template:
metadata:
labels:
app: parca
spec:
containers:
- name: parca
image: ghcr.io/parca-dev/parca:latest
args:
- /parca
- --config-path=/etc/parca/parca.yaml
- --cors-allowed-origins=*
ports:
- containerPort: 7070
---
apiVersion: v1
kind: Service
metadata:
name: parca
namespace: parca
spec:
selector:
app: parca
ports:
- port: 7070
targetPort: 7070
# parca-agent-daemonset.yaml — Desplegar agente Parca como DaemonSet
# Aplicar con: kubectl apply -f parca-agent-daemonset.yaml
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: parca-agent
namespace: parca
spec:
selector:
matchLabels:
app: parca-agent
template:
metadata:
labels:
app: parca-agent
spec:
hostPID: true
containers:
- name: parca-agent
image: ghcr.io/parca-dev/parca-agent:latest
args:
- /parca-agent
- --store-address=parca.parca.svc:7070
- --insecure
- --node=$(NODE_NAME)
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
securityContext:
privileged: true
volumeMounts:
- name: sys
mountPath: /sys
readOnly: true
volumes:
- name: sys
hostPath:
path: /sys
# Desplegar usando Helm
helm repo add parca https://parca-dev.github.io/helm-charts
helm repo update
helm install parca parca/parca -n parca --create-namespace
helm install parca-agent parca/parca-agent -n parca
Integración pprof
# El agente Parca puede recopilar endpoints pprof de aplicaciones Go
# Tu aplicación Go expone /debug/pprof/ por defecto con net/http/pprof
# Configurar objetivos de recopilación mediante anotaciones de Kubernetes
# Agregar a la especificación del pod:
# metadata:
# annotations:
# parca.dev/port: "6060"
# O configurar objetivos de recopilación estáticos en parca.yaml
# parca.yaml con configuración de recopilación
object_storage:
bucket:
type: "FILESYSTEM"
config:
directory: "/var/lib/parca/data"
scrape_configs:
- job_name: "my-go-service"
scrape_interval: "15s"
static_configs:
- targets: ["my-service:6060"]
profiling_config:
pprof_config:
process_cpu:
enabled: true
path: "/debug/pprof/profile"
delta: true
memory:
enabled: true
path: "/debug/pprof/heap"
delta: true
goroutine:
enabled: true
path: "/debug/pprof/goroutine"
Consulta de perfiles
# Acceder a la interfaz web de Parca en http://localhost:7070
# Usar el constructor de consultas o escribir consultas tipo PromQL
# El lenguaje de consulta de Parca soporta:
# - Selección de perfiles por etiquetas
# - Selección de rango temporal
# - Selección de tipo de perfil (cpu, memoria, goroutine, etc.)
# Consultas de ejemplo en la interfaz:
# process_cpu:cpu:nanoseconds:cpu:nanoseconds{node="my-host"}
# memory:alloc_objects:count:space:bytes{job="my-service"}
Comparación de perfiles
# En la interfaz web de Parca:
# 1. Seleccionar un perfil de la línea de tiempo
# 2. Hacer clic en "Compare" para habilitar el modo de comparación
# 3. Seleccionar un segundo perfil de un rango temporal diferente
# 4. Ver el flame graph diferencial
# Los flame graphs diferenciales muestran:
# - Marcos rojos: aumento en el uso de recursos
# - Marcos verdes: disminución en el uso de recursos
# - Marcos grises: sin cambios
Uso de la API
# Consultar perfiles mediante API gRPC
# Parca expone una API gRPC en el mismo puerto que HTTP
# Instalar grpcurl para exploración de API
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
# Listar servicios disponibles
grpcurl -plaintext localhost:7070 list
# Consultar tipos de perfil
grpcurl -plaintext localhost:7070 parca.query.v1alpha1.QueryService/ProfileTypes
# Consultar perfiles
grpcurl -plaintext -d '{
"mode": "QUERY_MODE_MERGE",
"report_type": "REPORT_TYPE_FLAMEGRAPH_ARROW",
"query": "process_cpu:cpu:nanoseconds:cpu:nanoseconds{}"
}' localhost:7070 parca.query.v1alpha1.QueryService/Query
Solución de problemas
# Verificar si eBPF es compatible
sudo bpftool prog list 2>/dev/null || echo "bpftool not available"
# Verificar versión del kernel (4.18+ requerido para eBPF)
uname -r
# Verificar registros del agente
journalctl -u parca-agent -f
# Verificar soporte BTF (requerido para CO-RE)
ls /sys/kernel/btf/vmlinux
# Probar conectividad entre agente y servidor
curl -s http://localhost:7070/api/v1/status
# Verificación de salud del agente
curl -s http://localhost:7071/healthz
Referencia rápida
| Componente | Puerto predeterminado | Propósito |
|---|
| Parca Server | 7070 | Almacenamiento, consultas, interfaz web |
| Parca Agent | 7071 | Agente de perfilado eBPF |
| pprof endpoints | 6060 | Recopilación de perfiles de aplicaciones |
| Característica | Descripción |
|---|
| Perfilado eBPF | Perfilado de sistema completo sin instrumentación |
| Recopilación pprof | Obtener perfiles desde endpoints Go/lenguajes |
| Vista diferencial | Comparar perfiles a lo largo del tiempo |
| Filtrado por etiquetas | Consultar por nodo, pod, contenedor, job |
| Info de depuración | Resolución automática de símbolos |