すべてのプロダクト
Search
ドキュメントセンター

Container Compute Service:ACS コンテナの状態を監視するために eBPF を使用する

最終更新日:Jan 04, 2025

このトピックでは、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 アドレス、およびポートを出力します。

  1. 次の 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:システムログを書き込むための権限。

    重要

    上記の例では、いくつかの高リスクの操作を示していますが、これらはテスト目的のみです。 本番環境では、最小特権の原則に従うことをお勧めします。 過剰な権限は、セキュリティリスクにつながる可能性があります。

  2. 次のコマンドを実行して、コンテナにアクセスします。

    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

    マウントパスが表示されます。

  3. サンプルアプリケーションのディレクトリに切り替えます。

    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
  4. 次のコマンドを実行して、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"]