仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

KubernetesのモニタリングツールのKubesharkを触ってみた

Kubesharkとは

図は公式 より抜粋

KubesharkはKubernetesのための観測性・監視ツールで、マイクロサービスの動的解析、異常の検出などを実現するツールです。 Wireshark、BPF Compiler Collection(BCC)ツールなどを組み合わせた、Kubernetesを意識したものとお考えください...と説明されています。

Kubesharkは、クラスタ内の一部またはすべてのTCPトラフィックをスニッフィングし、PCAPファイルに記録し、HTTP1.0, HTTP1.1, HTTP2, AMQP, Apache Kafka, Redisなどのアプリケーション層プロトコルを分析できるとのことです。

今回はHTTPに絞って実際に環境を動かしてみて、トラフィックを覗いてみたいと思います。

Kuberentesクラスターの用意

まず、Kuberentesクラスターを用意します。ローカルマシン上へのKuberentesクラスターの用意する方法はいろいろありますが、本例ではDocker Desktopで作ったクラスターを利用します。

minikubeやRancher Desktopのk3sクラスターなどでも動くと思います。

% kubectl get no
NAME             STATUS   ROLES           AGE   VERSION
docker-desktop   Ready    control-plane   25h   v1.25.2

Kubesharkのインストール

Kuberentesクラスターが用意できたら、次にKubesharkをインストールします。

インストールするには、Kubernetesクラスターが動いている環境で次を実行します。

% sh <(curl -Ls https://kubeshark.co/install)

ただ、スクリプトを実行する前に、スクリプトの中を覗いてみましょう。

% curl -LO https://kubeshark.co/install

このスクリプトを開いてみると、Kubesharkは現在LinuxとmacOSに対応しているようです。 amd64とarm64アーキテクチャーをサポートしています。

OSがアーキテクチャーを「x86_64」とか「aarch64」と返してきても、 適切に処理されるような記述が見られます。

スクリプトにはそのほか、特筆すべきところはなさそうです。

次のコマンドを実行すると、Kubernetesクラスターでkubeshark-api-serverが実行されます。これを使ってクラスター内のモニタリングができるようです。

% kubeshark tap   
Kubeshark will store up to 200MB of traffic, old traffic will be cleared once the limit is reached.
Tapping pods in namespaces "default"
Did not find any currently running pods that match the regex argument, kubeshark will automatically tap matching pods if any are created later. You can also try selecting a different namespace with -n or tap all namespaces with -A
Waiting for Kubeshark Agent to start...
Kubeshark is available at http://localhost:8899

起動直後のブラウザー表示は次のような感じです。 現在はモニタリングできるものがまだないため、何も表示されません。

Kubesharkでモニタリングを試してみる

Kubesharkでモニタリングを試すために適当なアプリケーションを動かしてみましょう。次のファイルを用意してください。

Ingressで指定しているkubernetes.docker.internalのところは、Kubernetesクラスターをどのように用意したかによって異なります。今回はKubesharkでモニタリングするのが目的なので、名前の通りわかると思いますがローカルでしかアクセスできないFQDNアドレスを設定しています。

apiVersion: v1
kind: Service
metadata:
  name: webapp1-nodeport-svc
  labels:
    app: webapp1-nodeport-svc
spec:
  type: NodePort
  ports:
    - port: 8080
      targetPort: 80
  selector:
    app: webapp1-nodeport-pod
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp1-nodeport-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webapp1-nodeport-pod
  template:
    metadata:
      labels:
        app: webapp1-nodeport-pod
    spec:
      containers:
        - name: webapp1-nodeport-container
          image: nginx:1.23.3-alpine
          ports:
            - containerPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sample-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-example
  rules:
    - host: kubernetes.docker.internal
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: webapp1-nodeport-svc
                port:
                  number: 8080

これを記述したマニフェストファイルを使って、アプリケーションを作成します。

% kubectl apply -f deployment.yaml
service/webapp1-nodeport-svc created
deployment.apps/webapp1-nodeport-deployment created
ingress.networking.k8s.io/sample-ingress created

アプリケーションが実行されるまで待ちましょう。

% kubectl get -f deployment.yaml
NAME                           TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/webapp1-nodeport-svc   NodePort   10.105.66.24   <none>        8080:31603/TCP   41s

NAME                                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/webapp1-nodeport-deployment   2/2     2            2           40s

NAME                                       CLASS           HOSTS                        ADDRESS   PORTS   AGE
ingress.networking.k8s.io/sample-ingress   nginx-example   kubernetes.docker.internal             80      40s

まず、curlコマンドを使ってこのアプリケーションにアクセスしてみます。

% curl http://kubernetes.docker.internal:31603

リロードすると、ブラウザー上にHTTP200のステータスの結果が現れます。

画面右側には「リクエスト」と「レスポンス」タブが用意されており、どのアドレスにどのバージョンのクライアントからアクセスしたのかが表示されます。リクエストに対する応答が「レスポンス」に表示されます。

応答結果だけでなく、内容も確認できます。

右上のいくつかボタンがありますが、「サービスマップ」を開くと、サービスとアクセス経路を視覚化して表示してくれます。

トラフィックの状態もグラフで表示できるようです。

次に、wgetコマンドを使ってこのアプリケーションにアクセスしてみます。

% wget http://kubernetes.docker.internal:31603

表示される結果はほとんどcurlと一緒なので省略しますが、きちんとKubesharkはwgetを使ったアクセスだと判別します。

ブラウザーでのアクセスについて

KubesharkはデフォルトはClusterIPでアプリケーションが実行されているため、クラスター外部からはアクセスできません。別にサービスを作ってKubesharkを公開サービスとする方法も取れるといえば取れるものの、取得できる情報情報ですしKubeshark自身にユーザー認証するような機能も現時点ではないように見えるため、あまり適切ではないと思います。

% kubectl get svc -n kubeshark 
NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubeshark-api-server   ClusterIP   10.102.56.80   <none>        80/TCP    43m

動かした後の片付け

こちらに書かれている通りkubeshark cleanを実行した後、K8sクラスターをそれぞれの方法で停止(もしくは削除)します。

docs.kubeshark.co

まとめ

こちらのページ をみると、いろいろなツールと連携して使えそうで、Kubesharkはなかなか有用なツールに感じました。 これからもチェックしていきたいと思います。