Ao usar o OpenTelemetry eBPF Instrumentation (OBI) para enviar dados de rastreamento ao Application Real-Time Monitoring Service (ARMS) de forma não intrusiva, o ARMS inicia o monitoramento das suas aplicações. Visualize a topologia da aplicação, traces de chamadas, transações anômalas, transações lentas, análise de SQL e outros dados de monitoramento. Este tópico descreve como utilizar o OBI para monitorar aplicações e reportar dados.
Pré-requisitos
Caso encontre problemas ao usar o OpenTelemetry eBPF, entre em contato conosco pelo grupo de perguntas e respostas do DingTalk (número do grupo: 159215000379).
-
Prepare um servidor Linux (instância do Elastic Compute Service (ECS) ou ambiente on-premises) que atenda aos seguintes requisitos.
Requisito
Intervalo suportado
Versão do kernel
Linux 5.8 ou superior. Distribuições baseadas em RHEL (com patches de backport para eBPF) exigem no mínimo o Linux 4.18.
BTF
O kernel deve expor informações BTF (BPF Type Format).
Arquitetura da CPU
amd64 (x86_64), arm64 (aarch64).
Permissões
Permissões de root.
NotaO Alibaba Cloud Linux 3 e o Alibaba Cloud Linux 4 atendem aos requisitos acima por padrão.
Para verificar se o seu servidor atende aos requisitos, execute os comandos a seguir:
# Check the kernel version (must be >= 5.8, or >= 4.18 for RHEL-based distributions) uname -r # Check the CPU architecture (must be amd64 or arm64) uname -m # Check whether BTF is available (the file exists if supported) ls /sys/kernel/btf/vmlinux # Check whether you have root permissions whoami
Informações gerais
O OBI é um componente de instrumentação automática baseado em eBPF para observabilidade no Kubernetes. Implantado como DaemonSet nos nós do cluster, ele coleta automaticamente dados de métricas e traces das aplicações sem modificar o código ou injetar sidecars. O OBI detecta automaticamente os principais protocolos, como HTTP, gRPC, SQL, Redis e Kafka, além de extrair profundamente corpos de requisição e resposta para cenários de GenAI (OpenAI, Anthropic, Qwen, MCP, Embedding, Rerank, entre outros). Os dados de telemetria coletados são exportados via protocolo OTLP e integram-se perfeitamente a plataformas de observabilidade como o ARMS, permitindo alcançar observabilidade full-stack com zero intrusão e baixa sobrecarga.
Métodos de correspondência para descoberta de aplicações
O OBI descobre e associa processos para monitoramento por meio da seção de configuração discovery.instrument. Há suporte aos seguintes métodos de correspondência (todas as condições usam lógica AND — todos os critérios devem ser atendidos para haver correspondência):
|
Campo YAML |
Tipo |
Descrição |
Exemplo |
|
open_ports |
Número/faixa de porta |
Portas nas quais o processo escuta. Aceita valores separados por vírgula e intervalos. |
8080, 80,443, 8000-8999 |
|
exe_path |
Padrão Glob |
Corresponde ao caminho completo do arquivo executável do processo. |
/java, /nginx, myapp |
|
cmd_args |
Padrão Glob |
Corresponde aos argumentos de linha de comando do processo (excluindo o nome do executável). |
petclinic, --config=prod |
|
languages |
Padrão Glob |
Correspondência automática por linguagem de programação (go/java/python/ruby/nodejs/rust/dotnet/php/cpp). |
java, {go,rust} |
|
target_pids |
Lista de PIDs |
Especifica diretamente os PIDs dos processos. |
[12345, 67890] |
|
container_name |
Padrão Glob |
Corresponde a nomes de contêineres OCI (aplicável a implantações Docker). |
my-container-* |
|
containers_only |
Booleano |
Corresponde apenas a processos dentro de contêineres. |
true |
|
name |
String |
Nome da aplicação exibido no console do ARMS. |
my-app |
|
namespace |
String |
Namespace do serviço. |
production |
|
exports |
Lista de sinais |
Controla os tipos de sinais exportados (metrics/traces/logs). Um array vazio desativa todas as exportações. |
[metrics, traces] |
|
sampler |
Configuração de amostragem |
Amostra traces por proporção para reduzir o volume de dados. |
name: traceidratio, arg: "0.5" |
Exemplos de configuração para cenários comuns
Cenário 1: Correspondência por número de porta — Método mais simples, aplicável a qualquer tipo de aplicação web
discovery:
instrument:
- name: my-web-app
open_ports: 8080
Cenário 2: Aplicação Java (exe_path + cmd_args) — Localiza o processo pelo executável java e pelo nome do JAR
discovery:
instrument:
- name: my-java-app
exe_path: "*/java"
cmd_args: "*petclinic*"
Cenário 3: Descoberta automática por linguagem de programação — Detecta automaticamente todos os processos de uma linguagem especificada
discovery:
instrument:
- name: go-services
languages: go
- name: python-services
languages: "{python,nodejs}"
Cenário 4: Correspondência por caminho do arquivo executável — Adequado para binários compilados localmente
discovery:
instrument:
- name: my-binary
exe_path: "*/my-server"
Cenário 5: Correspondência por nome de contêiner Docker — Indicada para implantações Docker no ECS
discovery:
instrument:
- name: my-container-app
container_name: "my-container-*"
Cenário 6: Múltiplas faixas de portas — Monitora serviços em um intervalo de portas
discovery:
instrument:
- name: microservices
open_ports: 8080-8090,9090
Cenário 7: Especificar PIDs para depuração temporária — Define PIDs de processos específicos para monitoramento direto
discovery:
instrument:
- name: debug-target
target_pids: [12345]
Cenário 8: Apenas processos em contêineres + amostragem — Monitora exclusivamente processos em contêineres com amostragem de traces de 50%
discovery:
instrument:
- name: container-apps
containers_only: true
open_ports: 8080
sampler:
name: traceidratio
arg: "0.5"
Cenário 9: Múltiplas aplicações + regras de exclusão — Monitora várias aplicações enquanto exclui processos específicos
discovery:
instrument:
- name: api-gateway
open_ports: 80,443
- name: backend-java
exe_path: "*/java"
cmd_args: "*backend*"
- name: worker
exe_path: "*/python*"
cmd_args: "*celery*"
exclude_instrument:
- exe_path: "{obi,prometheus,otelcol*}"
Cenário 10: Controle de sinais exportados — Exporta apenas métricas, sem traces
discovery:
instrument:
- name: high-qps-app
open_ports: 8080
exports: [metrics]
Procedimento
Visão geral do procedimento: Instalar e implantar (obter informações do endpoint > baixar o OBI > escrever o arquivo de configuração > implantar o serviço) > Verificar dados de monitoramento
Instalação e implantação
Há dois métodos de implantação disponíveis: implantação via script com um clique (recomendado) e implantação manual passo a passo.
Método 1: Implantação via script com um clique (recomendado)
Todas as etapas estão reunidas em um único script obi-setup.sh compatível com modos interativo e não interativo.
#!/bin/bash
# ============================================================================
# OBI (OpenTelemetry eBPF Instrumentation) one-click deployment script
# Combines the complete flow of environment check, download, configuration generation, and service installation
#
# Usage:
# sudo bash obi-setup.sh install — Interactive installation (binary + systemd)
# sudo bash obi-setup.sh docker — Deploy with Docker
# sudo bash obi-setup.sh check — Perform environment check only
# sudo bash obi-setup.sh uninstall — Uninstall the OBI service
# sudo bash obi-setup.sh status — View the running status and logs
#
# Non-interactive deployment (using environment variables):
# export OTLP_ENDPOINT="http://xxx:4318"
# export OTLP_HEADERS="Authentication=xxx"
# export APP_NAME="my-app"
# export APP_MATCH_TYPE="port" # port|cmd|exe|lang|container|pid
# export APP_MATCH_VALUE="8080"
# sudo -E bash obi-setup.sh install
# ============================================================================
set -euo pipefail
# ========================= Global Variables =========================
VERSION="0.10.0"
SERVICE_NAME="obi"
INSTALL_DIR="/opt/obi"
CONFIG_FILE="${INSTALL_DIR}/config.yaml"
OBI_BINARY="${INSTALL_DIR}/obi"
DOCKER_IMAGE="registry.cn-hangzhou.aliyuncs.com/private-mesh/obi:${VERSION}"
OSS_BASE="https://arms-apm-cn-hangzhou-pre.oss-cn-hangzhou.aliyuncs.com/obi-agent/${VERSION}"
# Colors
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
# Application list (array)
declare -a APP_ENTRIES=()
# Exclusion pattern
EXCLUDE_PATTERN=""
# ========================= Utility Functions =========================
info() { echo -e "${CYAN}[INFO]${NC} $*"; }
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
fail() { echo -e "${RED}[FAIL]${NC} $*"; }
die() { fail "$*"; exit 1; }
prompt_input() {
local var_name="$1" prompt_msg="$2" default_val="${3:-}"
local current_val="${!var_name:-}"
if [[ -n "$current_val" ]]; then
info "Using environment variable ${var_name}=${current_val}"
return
fi
if [[ -n "$default_val" ]]; then
read -rp "$(echo -e "${BOLD}${prompt_msg} [${default_val}]: ${NC}")" input
eval "$var_name=\"${input:-$default_val}\""
else
while true; do
read -rp "$(echo -e "${BOLD}${prompt_msg}: ${NC}")" input
if [[ -n "$input" ]]; then
eval "$var_name=\"$input\""
return
fi
warn "This field is required"
done
fi
}
prompt_yesno() {
local prompt_msg="$1" default="${2:-n}"
local yn
read -rp "$(echo -e "${BOLD}${prompt_msg} [y/N]: ${NC}")" yn
case "${yn:-$default}" in
[Yy]*) return 0 ;;
*) return 1 ;;
esac
}
# ========================= Environment Check =========================
check_root() {
if [[ "$EUID" -ne 0 ]]; then
die "Please run with root permissions: sudo bash $0 $*"
fi
ok "Root permissions"
}
check_env() {
echo ""
echo -e "${BOLD}========== Environment Check ==========${NC}"
local kernel_ver major minor
kernel_ver=$(uname -r)
major=$(echo "$kernel_ver" | cut -d. -f1)
minor=$(echo "$kernel_ver" | cut -d. -f2)
local is_rhel=false
if [[ -f /etc/redhat-release ]] || grep -qi 'rhel\|centos\|rocky\|alma\|anolis\|alinux' /etc/os-release 2>/dev/null; then
is_rhel=true
fi
if [[ "$major" -gt 5 ]] || { [[ "$major" -eq 5 ]] && [[ "$minor" -ge 8 ]]; }; then
ok "Kernel version: ${kernel_ver} (>= 5.8)"
elif $is_rhel && { [[ "$major" -gt 4 ]] || { [[ "$major" -eq 4 ]] && [[ "$minor" -ge 18 ]]; }; }; then
ok "Kernel version: ${kernel_ver} (RHEL-based, >= 4.18)"
else
fail "Kernel version: ${kernel_ver} (Minimum requirement: 5.8, or 4.18 for RHEL-based systems)"
return 1
fi
local arch
arch=$(uname -m)
case "$arch" in
x86_64|amd64) ok "CPU architecture: ${arch} (amd64)" ;;
aarch64|arm64) ok "CPU architecture: ${arch} (arm64)" ;;
*) fail "CPU architecture: ${arch} (unsupported)"; return 1 ;;
esac
if [[ -f /sys/kernel/btf/vmlinux ]]; then
ok "BTF: Available"
else
fail "BTF: /sys/kernel/btf/vmlinux does not exist"
return 1
fi
echo -e "${GREEN}========== Environment Check Passed ==========${NC}"
echo ""
return 0
}
detect_arch() {
local arch
arch=$(uname -m)
case "$arch" in
x86_64|amd64) echo "amd64" ;;
aarch64|arm64) echo "arm64" ;;
*) die "Unsupported CPU architecture: ${arch}" ;;
esac
}
# ========================= Collect Single Application Configuration =========================
collect_one_app() {
local app_name match_type
local entry=""
prompt_input app_name "Application name (display name in the Cloud Monitor 2.0 console)" "my-app"
echo ""
echo -e " ${BOLD}Select application matching method:${NC}"
echo -e " 1) Match by port number — open_ports, such as 8080, 80,443, or 8000-8999"
echo -e " 2) Match by command line — exe_path + cmd_args, suitable for scenarios like java -jar"
echo -e " 3) Match by executable file path — exe_path, suitable for self-compiled binaries"
echo -e " 4) Auto-discover by programming language — languages, auto-detects go, java, python, nodejs, etc."
echo -e " 5) Match by Docker container name — container_name, suitable for running Docker on ECS"
echo -e " 6) Specify by PID — target_pids, for temporary debugging"
read -rp "$(echo -e "${BOLD}Select [1-6, default 1]: ${NC}")" match_choice
entry=" - name: ${app_name}"
case "${match_choice:-1}" in
1)
local ports
prompt_input ports "Listening port number (e.g., 8080, 80,443, 8000-8999)" "8080"
entry="${entry}
open_ports: ${ports}"
;;
2)
local exe_path cmd_args
prompt_input exe_path "Executable file path Glob (e.g., */java)" "*/java"
prompt_input cmd_args "Command line argument Glob (e.g., *petclinic*)"
entry="${entry}
exe_path: \"${exe_path}\"
cmd_args: \"${cmd_args}\""
;;
3)
local exe_path
prompt_input exe_path "Executable file path Glob (e.g., */my-server, */nginx)"
entry="${entry}
exe_path: \"${exe_path}\""
;;
4)
local lang
echo -e " Supported languages: go, java, python, ruby, nodejs, rust, dotnet, php, cpp"
echo -e " For multiple languages, use braces: {go,rust} or {python,nodejs}"
prompt_input lang "Programming language" "java"
entry="${entry}
languages: \"${lang}\""
;;
5)
local cname
prompt_input cname "Docker container name Glob (e.g., my-container-*)"
entry="${entry}
container_name: \"${cname}\""
;;
6)
local pids
prompt_input pids "PID list, comma-separated (e.g., 12345,67890)"
local pid_array
pid_array=$(echo "$pids" | tr ',' '\n' | sed 's/^[[:space:]]*//' | awk '{printf " - %s\n", $0}')
entry="${entry}
target_pids:
${pid_array}"
;;
*)
local ports
prompt_input ports "Listening port number" "8080"
entry="${entry}
open_ports: ${ports}"
;;
esac
# Optional: Container processes only
if [[ "${match_choice:-1}" != "5" ]]; then
if prompt_yesno "Match only processes inside containers (containers_only)?"; then
entry="${entry}
containers_only: true"
fi
fi
# Optional: Sampling
if prompt_yesno "Configure Traces sampling (to reduce data volume)?"; then
echo -e " Samplers: always_on, always_off, traceidratio, parentbased_traceidratio"
local sampler_name sampler_arg
prompt_input sampler_name "Sampler name" "traceidratio"
prompt_input sampler_arg "Sampler argument (e.g., 0.5 for 50% sampling)" "1.0"
entry="${entry}
sampler:
name: ${sampler_name}
arg: \"${sampler_arg}\""
fi
APP_ENTRIES+=("$entry")
ok "Added application: ${app_name}"
}
# ========================= Collect Full Configuration =========================
collect_config() {
echo -e "${BOLD}========== Configuration Information ==========${NC}"
echo ""
info "Please obtain the following information from the Cloud Monitor Integration Center:"
info " Cloud Monitor 2.0 console -> Integration Center -> OpenTelemetry card -> Click to get LicenseKey"
echo ""
prompt_input OTLP_ENDPOINT "OTEL_EXPORTER_OTLP_ENDPOINT (e.g., http://xxx:4318)"
prompt_input OTLP_HEADERS "OTEL_EXPORTER_OTLP_HEADERS (e.g., Authentication=xxx)"
echo ""
echo -e "${BOLD}========== Application Configuration ==========${NC}"
# Non-interactive mode: Build a single app from environment variables
if [[ -n "${APP_MATCH_TYPE:-}" ]]; then
local entry=" - name: ${APP_NAME:-my-app}"
case "$APP_MATCH_TYPE" in
port)
entry="${entry}
open_ports: ${APP_MATCH_VALUE:-8080}" ;;
cmd)
entry="${entry}
exe_path: \"${APP_EXE_PATH:-*/java}\"
cmd_args: \"${APP_CMD_ARGS}\"" ;;
exe)
entry="${entry}
exe_path: \"${APP_MATCH_VALUE}\"" ;;
lang)
entry="${entry}
languages: \"${APP_MATCH_VALUE}\"" ;;
container)
entry="${entry}
container_name: \"${APP_MATCH_VALUE}\"" ;;
pid)
local pid_array
pid_array=$(echo "${APP_MATCH_VALUE}" | tr ',' '\n' | sed 's/^[[:space:]]*//' | awk '{printf " - %s\n", $0}')
entry="${entry}
target_pids:
${pid_array}" ;;
*)
die "Unknown APP_MATCH_TYPE: ${APP_MATCH_TYPE} (Supported: port|cmd|exe|lang|container|pid)" ;;
esac
APP_ENTRIES+=("$entry")
ok "Added application: ${APP_NAME:-my-app} (${APP_MATCH_TYPE})"
return
fi
# Interactive mode: Loop to add applications
while true; do
echo ""
collect_one_app
echo ""
if ! prompt_yesno "Add another application?"; then
break
fi
done
# Optional: Exclusion rules
echo ""
if prompt_yesno "Configure exclusion rules (exclude_instrument)?"; then
echo -e " Enter the executable file path Glob to exclude"
echo -e " Example: {obi,prometheus,otelcol*,node_exporter}"
local exclude_val
prompt_input exclude_val "Exclusion path Glob"
EXCLUDE_PATTERN="$exclude_val"
ok "Added exclusion rule: ${exclude_val}"
fi
}
# ========================= Generate Configuration File =========================
generate_config() {
local endpoint_metrics="${OTLP_ENDPOINT}/v1/metrics"
# Concatenate the instrument section
local instrument_yaml=""
for entry in "${APP_ENTRIES[@]}"; do
instrument_yaml="${instrument_yaml}
${entry}"
done
# Concatenate the exclude section
local exclude_yaml=""
if [[ -n "$EXCLUDE_PATTERN" ]]; then
exclude_yaml="
exclude_instrument:
- exe_path: \"${EXCLUDE_PATTERN}\""
fi
cat > "${CONFIG_FILE}" <<YAML
log_level: WARN
otel_metrics_export:
endpoint: ${endpoint_metrics}
metrics:
features:
- application
- network
- stats_tcp_rtt
routes:
unmatched: low-cardinality
max_path_segment_cardinality: 500
ebpf:
context_propagation: all
track_request_headers: true
payload_extraction:
http:
genai:
openai:
enabled: true
anthropic:
enabled: true
jsonrpc:
enabled: true
mcp:
enabled: true
qwen:
enabled: true
rerank:
enabled: true
embedding:
enabled: true
gemini:
enabled: true
buffer_sizes:
http: 262144
otel_traces_export:
endpoint: ${OTLP_ENDPOINT}
batch_timeout: 10s
batch_max_size: 512
queue_size: 4096
backoff_initial_interval: 5s
backoff_max_interval: 15s
backoff_max_elapsed_time: 2m
instrumentations:
- http
- grpc
- sql
- redis
- kafka
- mqtt
- mongo
- couchbase
- memcached
- genai
nodejs:
enabled: true
discovery:
min_process_age: 30s
instrument:${instrument_yaml}${exclude_yaml}
YAML
ok "Configuration file generated: ${CONFIG_FILE}"
}
# ========================= Download OBI =========================
download_obi() {
local arch
arch=$(detect_arch)
local url="${OSS_BASE}/obi-linux-${arch}"
info "Downloading OBI v${VERSION} (${arch})..."
mkdir -p "${INSTALL_DIR}"
if command -v wget &>/dev/null; then
wget -q --show-progress "${url}" -O "${OBI_BINARY}"
elif command -v curl &>/dev/null; then
curl -fL --progress-bar "${url}" -o "${OBI_BINARY}"
else
die "Neither wget nor curl is available"
fi
chmod +x "${OBI_BINARY}"
ok "OBI downloaded to ${OBI_BINARY}"
}
# ========================= Systemd Service =========================
install_systemd() {
info "Creating systemd service..."
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
[Unit]
Description=OBI eBPF Instrumentation Service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=${INSTALL_DIR}
Environment="OTEL_EBPF_CONFIG_PATH=${CONFIG_FILE}"
Environment="OTEL_EXPORTER_OTLP_HEADERS=${OTLP_HEADERS}"
ExecStart=${OBI_BINARY}
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=${SERVICE_NAME}
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable "${SERVICE_NAME}" --quiet
ok "Systemd service created and enabled on boot"
}
start_service() {
info "Starting OBI service..."
systemctl start "${SERVICE_NAME}"
sleep 2
if systemctl is-active --quiet "${SERVICE_NAME}"; then
ok "OBI service started successfully!"
else
fail "Failed to start OBI service. The error log is as follows:"
journalctl -u "${SERVICE_NAME}" -n 30 --no-pager
exit 1
fi
}
# ========================= Docker Deployment =========================
deploy_docker() {
if ! command -v docker &>/dev/null; then
die "Docker is not installed"
fi
collect_config
mkdir -p "${INSTALL_DIR}"
generate_config
info "Pulling Docker image: ${DOCKER_IMAGE}"
docker pull "${DOCKER_IMAGE}"
if docker ps -a --format '{{.Names}}' | grep -q "^${SERVICE_NAME}$"; then
warn "Removing existing container..."
docker rm -f "${SERVICE_NAME}" >/dev/null 2>&1
fi
info "Starting OBI container..."
docker run -d \
--name "${SERVICE_NAME}" \
--pid=host \
--privileged \
--restart=always \
-v "${CONFIG_FILE}:/config/config.yaml:ro" \
-e "OTEL_EXPORTER_OTLP_HEADERS=${OTLP_HEADERS}" \
-e "OTEL_EXPORTER_OTLP_ENDPOINT=${OTLP_ENDPOINT}" \
"${DOCKER_IMAGE}" \
--config=/config/config.yaml
sleep 2
if docker ps --format '{{.Names}}' | grep -q "^${SERVICE_NAME}$"; then
ok "OBI container started successfully!"
else
fail "Failed to start container:"
docker logs "${SERVICE_NAME}" --tail 30
exit 1
fi
echo ""
echo -e "${BOLD}Docker Management Commands:${NC}"
echo " View logs: docker logs -f ${SERVICE_NAME}"
echo " Stop container: docker stop ${SERVICE_NAME}"
echo " Remove container: docker rm -f ${SERVICE_NAME}"
echo ""
}
# ========================= Uninstall =========================
uninstall() {
echo -e "${BOLD}========== Uninstall OBI ==========${NC}"
if systemctl is-active --quiet "${SERVICE_NAME}" 2>/dev/null; then
systemctl stop "${SERVICE_NAME}"
fi
if [[ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]]; then
systemctl disable "${SERVICE_NAME}" --quiet 2>/dev/null || true
rm -f "/etc/systemd/system/${SERVICE_NAME}.service"
systemctl daemon-reload
ok "Systemd service removed"
fi
if command -v docker &>/dev/null && docker ps -a --format '{{.Names}}' | grep -q "^${SERVICE_NAME}$"; then
docker rm -f "${SERVICE_NAME}" >/dev/null 2>&1
ok "Docker container removed"
fi
if [[ -d "${INSTALL_DIR}" ]]; then
rm -rf "${INSTALL_DIR}"
ok "Installation directory cleaned up"
fi
ok "OBI has been completely uninstalled"
}
# ========================= Show Status =========================
show_status() {
echo -e "${BOLD}========== OBI Running Status ==========${NC}"
if [[ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]]; then
echo -e "\n${CYAN}[Systemd Service]${NC}"
systemctl status "${SERVICE_NAME}" --no-pager 2>/dev/null || true
echo -e "\n${CYAN}[Recent Logs]${NC}"
journalctl -u "${SERVICE_NAME}" -n 20 --no-pager 2>/dev/null || true
fi
if command -v docker &>/dev/null && docker ps -a --format '{{.Names}}' | grep -q "^${SERVICE_NAME}$"; then
echo -e "\n${CYAN}[Docker Container]${NC}"
docker ps -f "name=${SERVICE_NAME}"
echo -e "\n${CYAN}[Recent Logs]${NC}"
docker logs "${SERVICE_NAME}" --tail 20 2>&1 || true
fi
if [[ -f "${CONFIG_FILE}" ]]; then
echo -e "\n${CYAN}[Configuration File: ${CONFIG_FILE}]${NC}"
cat "${CONFIG_FILE}"
fi
}
# ========================= Binary Installation Main Flow =========================
install_binary() {
check_env || die "Environment check failed"
collect_config
download_obi
generate_config
install_systemd
start_service
echo ""
echo -e "${GREEN}============================================${NC}"
echo -e "${GREEN} OBI deployment complete!${NC}"
echo -e "${GREEN}============================================${NC}"
echo ""
echo -e "${BOLD}Installation directory:${NC} ${INSTALL_DIR}"
echo -e "${BOLD}Configuration file:${NC} ${CONFIG_FILE}"
echo ""
echo -e "Common commands:"
echo " View status: sudo systemctl status ${SERVICE_NAME}"
echo " View logs: sudo journalctl -u ${SERVICE_NAME} -f"
echo " Restart service: sudo systemctl restart ${SERVICE_NAME}"
echo " Uninstall: sudo bash $0 uninstall"
echo ""
}
# ========================= Entry Point =========================
print_usage() {
echo ""
echo -e "${BOLD}OBI One-Click Deployment Script v${VERSION}${NC}"
echo ""
echo "Usage: sudo bash $0 <command>"
echo ""
echo "Commands:"
echo " install Install as a binary (managed by systemd)"
echo " docker Deploy with Docker"
echo " check Perform environment check only"
echo " status View running status and logs"
echo " uninstall Uninstall OBI"
echo ""
echo "Application matching methods (APP_MATCH_TYPE):"
echo " port Match by port number (open_ports)"
echo " cmd Match by command line (exe_path + cmd_args)"
echo " exe Match by executable file path (exe_path)"
echo " lang Auto-discover by programming language (languages)"
echo " container Match by Docker container name (container_name)"
echo " pid Specify by PID (target_pids)"
echo ""
}
main() {
local action="${1:-}"
case "$action" in
install) check_root "$@"; install_binary ;;
docker) check_root "$@"; check_env || die "Environment check failed"; deploy_docker ;;
check) check_root "$@"; check_env ;;
uninstall) check_root "$@"; uninstall ;;
status) check_root "$@"; show_status ;;
*) print_usage; exit 1 ;;
esac
}
main "$@"
Etapa 1: Obter informações do endpoint
Faça login no console do ARMS. No painel de navegação à esquerda, clique em Integration Center. Na seção de aplicações server-side, clique no cartão OpenTelemetry e obtenha os dois valores a seguir:
OTEL_EXPORTER_OTLP_ENDPOINT(por exemplo,http://xxx:4318)OTEL_EXPORTER_OTLP_HEADERS(por exemplo,Authentication=xxx)
Etapa 2: Baixar e preparar o script
chmod +x obi-setup.sh
Etapa 3: Instalação interativa (binário + systemd)
sudo bash obi-setup.sh install
O script executa sequencialmente as etapas a seguir: verificação de ambiente > coleta de endpoint/headers > seleção do método de correspondência da aplicação (6 cenários suportados) > adição de múltiplas aplicações > configuração opcional de regras de exclusão/amostragem/controle de exportação > detecção automática da arquitetura da CPU e download do OBI > geração do config.yaml > criação e inicialização de um serviço systemd.
Etapa 4: Implantação com Docker
sudo bash obi-setup.sh docker
Etapa 5: Implantação não interativa (cenários em lote)
Defina parâmetros por variáveis de ambiente para ignorar os prompts interativos. Há suporte aos seguintes tipos de correspondência:
# Match by port
export OTLP_ENDPOINT="http://xxx:4318"
export OTLP_HEADERS="Authentication=xxx"
export APP_NAME="my-app"
export APP_MATCH_TYPE="port"
export APP_MATCH_VALUE="8080"
sudo -E bash obi-setup.sh install
# Java application (exe_path + cmd_args)
export APP_MATCH_TYPE="cmd"
export APP_EXE_PATH="*/java"
export APP_CMD_ARGS="*petclinic*"
# Match by programming language
export APP_MATCH_TYPE="lang"
export APP_MATCH_VALUE="java"
# Match by executable file path
export APP_MATCH_TYPE="exe"
export APP_MATCH_VALUE="*/my-server"
# Match by Docker container name
export APP_MATCH_TYPE="container"
export APP_MATCH_VALUE="my-container-*"
# Match by PID
export APP_MATCH_TYPE="pid"
export APP_MATCH_VALUE="12345,67890"
Etapa 6: Outros comandos
sudo bash obi-setup.sh check # Run environment checks only
sudo bash obi-setup.sh status # View running status and logs
sudo bash obi-setup.sh uninstall # Uninstall OBI
Método 2: Implantação manual passo a passo
Para obter controle mais granular sobre cada etapa, siga estes passos manuais.
Etapa 1: Obter informações do endpoint
Conforme descrito acima. Obtenha OTEL_EXPORTER_OTLP_ENDPOINT e OTEL_EXPORTER_OTLP_HEADERS no console do ARMS.
Etapa 2: Baixar o OBI
# amd64 architecture
wget https://arms-apm-cn-hangzhou-pre.oss-cn-hangzhou.aliyuncs.com/obi-agent/0.10.0/obi-linux-amd64 -O obi
# arm64 architecture
wget https://arms-apm-cn-hangzhou-pre.oss-cn-hangzhou.aliyuncs.com/obi-agent/0.10.0/obi-linux-arm64 -O obi
chmod +x obi
Etapa 3: Escrever o arquivo de configuração
Crie um arquivo config.yaml. Substitua <OTLP_ENDPOINT> pelo valor real e modifique a seção discovery.instrument conforme sua aplicação (consulte a seção "Métodos de correspondência para descoberta de aplicações" acima para configurações adequadas):
log_level: WARN
otel_metrics_export:
endpoint: <OTLP_ENDPOINT>/v1/metrics
metrics:
features:
- application
- network
- stats_tcp_rtt
routes:
unmatched: low-cardinality
max_path_segment_cardinality: 500
ebpf:
context_propagation: all
track_request_headers: true
payload_extraction:
http:
genai:
openai:
enabled: true
anthropic:
enabled: true
jsonrpc:
enabled: true
mcp:
enabled: true
qwen:
enabled: true
rerank:
enabled: true
embedding:
enabled: true
gemini:
enabled: true
buffer_sizes:
http: 262144
otel_traces_export:
endpoint: <OTLP_ENDPOINT>
instrumentations:
- http
- grpc
- sql
- redis
- kafka
- mqtt
- mongo
- couchbase
- memcached
- genai
nodejs:
enabled: true
discovery:
instrument:
- name: my-app
open_ports: 8080
Etapa 4: Implantar o serviço
Implantação de binário (gerenciado pelo systemd):
Crie um arquivo de serviço systemd em /etc/systemd/system/obi.service:
[Unit]
Description=OBI eBPF Instrumentation Service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/path/to/obi-dir
Environment="OTEL_EBPF_CONFIG_PATH=config.yaml"
Environment="OTEL_EXPORTER_OTLP_HEADERS=<Replace with actual value>"
ExecStart=/path/to/obi-dir/obi
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=obi
[Install]
WantedBy=multi-user.target
Inicie o serviço:
sudo systemctl daemon-reload
sudo systemctl enable obi
sudo systemctl start obi
sudo systemctl status obi
Implantação com Docker:
docker pull registry.cn-hangzhou.aliyuncs.com/private-mesh/obi:0.10.0
docker run -d \
--name obi \
--pid=host \
--privileged \
--restart=always \
-v $(pwd)/config.yaml:/config/config.yaml:ro \
-e OTEL_EXPORTER_OTLP_HEADERS="<Replace with actual value>" \
-e OTEL_EXPORTER_OTLP_ENDPOINT="<Replace with actual value>" \
registry.cn-hangzhou.aliyuncs.com/private-mesh/obi:0.10.0 \
--config=/config/config.yaml
Verificar dados de monitoramento
Faça login no console do ARMS. No painel de navegação à esquerda, clique em Application Monitoring. Localize o nome da aplicação configurada na lista de aplicações e clique nele para visualizar detalhes de monitoramento, como topologia, traces e anomalias.
Comandos comuns de O&M
|
Operação |
Método systemd |
Método Docker |
|
Visualizar status |
sudo systemctl status obi |
docker ps -f name=obi |
|
Visualizar logs |
sudo journalctl -u obi -f |
docker logs -f obi |
|
Reiniciar |
sudo systemctl restart obi |
docker restart obi |
|
Parar |
sudo systemctl stop obi |
docker stop obi |
|
Desinstalar |
sudo bash obi-setup.sh uninstall |
docker rm -f obi |