This topic describes how to use eBPF to obtain container performance data, kernel trace data, and network metrics in an intrusion-free way. This helps you identify performance issues in containers and the relevant pods.
Background Information
Extended Berkeley Packet Filter (eBPF) is a technology for running sandboxed programs. It allows developers to run custom code safely in system kernels and view the results in real time. The developers do not need to modify the kernel source code or load kernel modules.
In the Kubernetes ecosystem, eBPF is commonly used in the following scenarios:
Network management: The Cilium plug-in is used to configure network policies and manage traffic forwarding.
Troubleshooting and event tracking: Falco can be used to monitor the system calls and access of containers in Kubernetes clusters in real time in order to identify security risks.
Security monitoring: eBPF can block packet transmission and quarantine the container that is under attack when intrusions are detected, such as port scanning. This greatly reduces security risks.
Performance monitoring: Sysdig is used to diagnose the performance data and anomalies of clusters or nodes.
eBPF runs in user space and kernel space:
User space: eBPF programs are usually written and loaded in user space. You can write an eBPF program in C and use
bpftoolorlibbpfto load it to the kernel.Kernel space: eBPF programs are loaded and executed in kernel space. An eBPF program running in kernel space can directly access kernel data and interfaces to perform monitoring and processing tasks.
ACS provides eBPF-based observability. You can configure monitoring settings and metrics in the /sys/kernel/debug directory of a pod to monitor the pods in a fine-grained manner.
Prerequisites
The privileged mode is enabled for ACS pods.
By default, ACS does not allow you to use the privileged mode. To use this mode, submit a ticket.
Example
The following example shows how an eBPF program is used in ACS. The image in this example contains the eBPF software ebpf-go for Go. ebpf-go contains multiple sample applications. For more information about the base image, see Base image.
In this example, the fentry eBPF program is loaded to tcp_connect of a container. When the container sends TCP SYN messages to the destination, eBPF prints the corresponding command, IP address, and port.
Create a workload named acs-test-ebpf-demo based on the following YAML content. For more information, see Create a stateless application by using a Deployment.
apiVersion: apps/v1 kind: Deployment metadata: labels: app: acs-test-ebpf-demo name: acs-test-ebpf-demo namespace: default spec: progressDeadlineSeconds: 600 replicas: 1 selector: matchLabels: app: acs-test-ebpf-demo strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: labels: alibabacloud.com/compute-class: general-purpose alibabacloud.com/compute-qos: default app: acs-test-ebpf-demo spec: containers: - command: - /bin/sh - -c - sleep 36000 image: registry-cn-hangzhou.ack.aliyuncs.com/acs/ebpf-example:v1-alpha imagePullPolicy: Always name: test-ebpf resources: requests: cpu: "2" memory: 4Gi securityContext: capabilities: add: - SYS_ADMIN - NET_ADMIN - NET_RAW - SYS_RESOURCE - SYS_PTRACE - IPC_LOCK - SYSLOG volumeMounts: - mountPath: /sys/kernel/debug name: volume-debugfs readOnly: true restartPolicy: Always volumes: - emptyDir: {} name: emptydir-volume - hostPath: path: /sys/kernel/debug type: "" name: volume-debugfsThe following table describes some of the parameters.
Parameter
Description
.spec.template.volume.hostPathThe path to be mounted.
.spec.template.container.volumeMountsThe container path to which the preceding path is mapped.
.spec.template.container.securityContext.capabilities.addThe permissions granted to eBPF on the mount path.
SYS_ADMIN: the permissions to perform system management operations, which may pose high security risks.NET_ADMIN: the permissions to perform network management operations, such as changing the status of network interface or modifying route tables.NET_RAW: the permissions to directly use raw sockets in containers.SYS_RESOURCE: the permissions to modify system resource limits.SYS_PTRACE: the permissions to monitor other processes.IPC_LOCK: the permissions to lock memory pages.SYSLOG: the permissions to write system logs.ImportantThe preceding example shows several high-risk operations, which are only for testing purpose. In a production environment, we recommend that you follow the least privilege principle. Excessive permissions may result in security risks.
Run the following command to access the container:
kubectl exec -it deploy/acs-test-ebpf-demo -- bashView the mount path.
cd /sys/kernel/debug && ls -alExpected output:
drwx------ 37 root root 0 Dec 17 08:30 . drwxr-xr-x 15 root root 0 Dec 17 08:30 .. drwxr-xr-x 2 root root 0 Dec 17 08:30 acpi drwxr-xr-x 4 root root 0 Dec 17 08:30 bdi drwxr-xr-x 4 root root 0 Dec 17 08:30 block ... drwxr-xr-x 3 root root 0 Dec 17 08:30 zram drwxr-xr-x 2 root root 0 Dec 17 08:30 zsmalloc drwxr-xr-x 2 root root 0 Dec 17 08:30 zswapThe mount path is displayed.
Switch to the directory of the sample application.
cd /app/ebpf && lsExpected output:
CODEOWNERS attachtype_string.go docs fuzz_test.go linker.go perf types.go CODE_OF_CONDUCT.md btf elf_reader.go go.mod linker_test.go prog.go types_string.go CONTRIBUTING.md cmd elf_reader_test.go go.sum map.go prog_test.go variable.go LICENSE collection.go elf_sections.go helpers_test.go map_test.go ringbuf variable_test.go MAINTAINERS.md collection_test.go example_sock_elf_test.go info.go marshaler_example_test.go rlimit Makefile cpu.go example_sock_extract_dist_test.go info_test.go marshalers.go syscalls.go README.md cpu_test.go examples internal marshalers_test.go syscalls_test.go asm doc.go features link netlify.toml testdataRun the following command to launch the eBPF program.
cd /app/ebpf/examples/fentry/ && go run .Expected output:
2024/12/17 08:40:49 Comm Src addr Port -> Dest addr Port 2024/12/17 08:40:49 ilogtail 172.20.87.70 34742 -> 100.xxx.xxx.208 80 2024/12/17 08:40:53 ilogtail 172.20.87.70 37232 -> 100.xxx.xxx.112 80 2024/12/17 08:40:53 ilogtail 172.20.87.70 48676 -> 100.xxx.xxx.200 80 2024/12/17 08:40:54 ilogtail 172.20.87.70 59592 -> 100.xxx.xxx.7 80 2024/12/17 08:40:54 ilogtail 172.20.87.70 50048 -> 100.xxx.xxx.132 80 2024/12/17 08:40:54 ilogtail 172.20.87.70 51096 -> 100.xxx.xxx.210 80 2024/12/17 08:40:54 ilogtail 172.20.87.70 37808 -> 100.xxx.xxx.134 80 2024/12/17 08:40:57 ilogtail 172.20.87.70 58272 -> 100.xxx.xxx.113 80 2024/12/17 08:40:57 ilogtail 172.20.87.70 58278 -> 100.xxx.xxx.113 80 2024/12/17 08:40:57 ilogtail 172.20.87.70 58294 -> 100.xxx.xxx.113 80 2024/12/17 08:40:58 ilogtail 172.20.87.70 56356 -> 100.xxx.xxx.208 80 2024/12/17 08:41:00 ilogtail 172.20.87.70 48692 -> 100.xxx.xxx.200 80The eBPF program in this example is for reference only. You can write complex eBPF programs on demand.
References
The following image dockerfile is used by the eBPF program in this example.
FROM alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:latest
# 1. Update the package list and install tools
RUN yum update -y && \
yum install -y wget tar gzip git util-linux net-tools
# 2. Install the Go environment
ENV GO_VERSION=1.22.3
RUN wget https://golang.org/dl/go$GO_VERSION.linux-amd64.tar.gz && \
tar -C /usr/local -xzf go$GO_VERSION.linux-amd64.tar.gz && \
rm go$GO_VERSION.linux-amd64.tar.gz
# 3. Configure Go environment variables
ENV PATH=$PATH:/usr/local/go/bin
ENV GOPATH=/go
ENV PATH=$PATH:$GOPATH/bin
# 4. Download sample code from the eBPF repository
RUN git clone https://github.com/cilium/ebpf.git /app/ebpf/
# 5. Create a working directory
WORKDIR /app
ENTRYPOINT ["tail", "-f", "/dev/null"]