このトピックでは、eBPF を使用して、コンテナのパフォーマンスデータ、カーネルトレースデータ、およびネットワークメトリクスを侵入のない方法で取得する方法について説明します。 これにより、コンテナと関連するポッドのパフォーマンスの問題を特定できます。
背景情報
Extended Berkeley Packet Filter(eBPF)は、サンドボックス化されたプログラムを実行するためのテクノロジーです。 開発者は、システムカーネルでカスタムコードを安全に実行し、結果をリアルタイムで表示できます。 開発者は、カーネルソースコードを変更したり、カーネルモジュールをロードしたりする必要はありません。
Kubernetes エコシステムでは、eBPF は通常、次のシナリオで使用されます。
ネットワーク管理:Cilium プラグインを使用して、ネットワークポリシーを設定し、トラフィック転送を管理します。
トラブルシューティングとイベント追跡:Falco を使用して、Kubernetes クラスタ内のコンテナのシステムコールとアクセスをリアルタイムで監視し、セキュリティリスクを特定できます。
セキュリティ監視:eBPF は、ポートスキャンなどの侵入が検出されたときに、パケット送信をブロックし、攻撃を受けているコンテナを隔離できます。 これにより、セキュリティリスクが大幅に軽減されます。
パフォーマンス監視:Sysdig を使用して、クラスタまたはノードのパフォーマンスデータと異常を診断します。
eBPF は、ユーザー空間とカーネル空間で実行されます。
ユーザー空間:eBPF プログラムは通常、ユーザー空間で記述およびロードされます。 C 言語で eBPF プログラムを作成し、
bpftoolまたはlibbpfを使用してカーネルにロードできます。カーネル空間:eBPF プログラムは、カーネル空間にロードされて実行されます。 カーネル空間で実行されている eBPF プログラムは、カーネルデータとインターフェースに直接アクセスして、監視タスクと処理タスクを実行できます。
ACS は、eBPF ベースの可観測性を提供します。 ポッドの /sys/kernel/debug ディレクトリで監視設定とメトリクスを設定して、ポッドをきめ細かく監視できます。
前提条件
ACS ポッドで特権モードが有効になっています。
デフォルトでは、ACS は特権モードの使用を許可していません。 このモードを使用するには、チケットを送信 してください。
例
次の例は、ACS で eBPF プログラムを使用する方法を示しています。 この例のイメージには、Go 用の eBPF ソフトウェア ebpf-go が含まれています。 ebpf-go には、複数のサンプルアプリケーションが含まれています。 ベースイメージの詳細については、「ベースイメージ」をご参照ください。
この例では、fentry eBPF プログラムがコンテナの tcp_connect にロードされます。 コンテナが宛先に TCP SYN メッセージを送信すると、eBPF は対応するコマンド、IP アドレス、およびポートを出力します。
次の YAML コンテンツに基づいて、acs-test-ebpf-demo という名前のワークロードを作成します。 詳細については、「デプロイメントを使用してステートレスアプリケーションを作成する」をご参照ください。
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 ソケットを直接使用するための権限。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次のコマンドを実行して、eBPF プログラムを起動します。
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 プログラムを作成できます。
参考資料
次のイメージ Dockerfile は、この例の eBPF プログラムで使用されます。
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"]