本文介紹利用eBPF技術無侵入地獲得容器性能數據、內核Trace數據或網絡指標數據等,從而快速發現目標容器和關聯的Pod存在的性能問題。
背景信息
eBPF(Extended Berkeley Packet Filter)是一項運行沙箱程序的技術,允許開發者在操作系統內核內安全運行自定義代碼,并即時獲得執行結果,而無需修改內核源代碼或加載內核模塊,從而避免復雜的運維操作。
在Kubernetes生態中,eBPF的主要應用場景有:
網絡管理:Cilium網絡插件,可以靈活更新網絡策略并實施流量轉發。
故障定位與事件追蹤:使用Falco等工具實時監控Kubernetes集群中容器的系統調用和訪問行為,幫助運維人員及時發現安全風險。
安全監控:在入侵檢測中,如端口掃描,一旦檢測到異常行為,eBPF程序能夠阻止數據包傳輸并隔離受攻擊的容器,最大限度減少安全風險。
性能監控:Sysdig等工具提供性能和故障診斷,監控集群或單機的性能數據。
eBPF的運行分為用戶態(User Space)和內核態(Kernel Space):
用戶態:通常是用于編寫和加載eBPF程序的應用程序。您可以使用如C語言等編寫eBPF程序,并通過工具(如
bpftool
,libbpf
等)將其加載到內核中。內核態:eBPF程序被加載并實際執行的環境。eBPF程序在內核態中運行,可以直接訪問內核數據結構和接口,進行特定的監控與處理工作。
對此,ACS提供了基于eBPF的可觀測能力,您可以在Pod的/sys/kernel/debug
目錄下配置監控項和指標,實現對細粒度數據的監控,幫助您優化性能和排查故障。
前置條件
已為ACS Pod開啟特權模式。
ACS默認不提供開啟特權模式的入口, 請提交工單申請。
應用示例
以下演示eBPF程序在實際ACS容器算力環境下的使用。本示例的鏡像中使用了社區開源的Go語言框架eBPF工具軟件ebpf-go,ebpf-go包含了多個示例應用。關于此示例基礎鏡像的詳細信息,請參見相關信息。
以其中的fentry eBPF程序為例,將fentry eBPF程序加載到容器的tcp_connect上。當容器向目標發送TCP SYN數據包時,eBPF會打印出對應的命令/IP/端口信息。
使用以下YAML內容,創建名為acs-test-ebpf-demo的工作負載。具體操作,請參見創建無狀態工作負載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-debugfs
部分配置項說明如下:
配置項
說明
.spec.template.volume.hostPath
指定需要掛載的路徑。
.spec.template.container.volumeMounts
設置掛載的路徑在容器內的目標路徑。
.spec.template.container.securityContext.capabilities.add
設置掛載的eBPF對所依賴路徑需要具備的權限。
SYS_ADMIN
:允許執行許多系統管理操作,是非常高風險的能力。NET_ADMIN
:允許進行網絡管理操作,例如更改網絡接口的狀態、修改路由表等。NET_RAW
:允許容器直接使用原始套接字(raw socket)。SYS_RESOURCE
:允許進程修改系統資源限制。SYS_PTRACE
:允許監控其他進程。IPC_LOCK
:允許進程鎖定內存頁。SYSLOG
:允許對系統日志寫入。重要上述示例中展示了多個可用的高風險權限,僅供測試使用。在生產環境,建議您遵循最小權限原則,只添加必要的能力。錯誤的配置可能會增加安全風險。
執行以下命令,進入容器。
kubectl exec -it deploy/acs-test-ebpf-demo -- bash
查看掛載的目錄。
cd /sys/kernel/debug && ls -al
預期輸出:
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 zswap
可以看到掛載正常。
進入示例應用目錄。
cd /app/ebpf && ls
預期輸出:
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 testdata
執行以下命令,運行示例程序。
cd /app/ebpf/examples/fentry/ && go run .
預期輸出:
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 80
此示例展示了最簡單的eBPF程序運行的過程,您可以根據業務需要開發更復雜并貼近業務實際情況的eBPF程序。
相關信息
以下是eBPF示例中鏡像的Dockerfile文件,供您參考和修改。
FROM alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:latest
# 1、更新包列表并安裝必要的工具
RUN yum update -y && \
yum install -y wget tar gzip git util-linux net-tools
# 2、安裝 Go 語言環境
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、設置Go環境變量
ENV PATH=$PATH:/usr/local/go/bin
ENV GOPATH=/go
ENV PATH=$PATH:$GOPATH/bin
# 4、下載ebpf庫示例代碼
RUN git clone https://github.com/cilium/ebpf.git /app/ebpf/
# 5、創建工作目錄
WORKDIR /app
ENTRYPOINT ["tail", "-f", "/dev/null"]