github.com/inspektor-gadget/inspektor-gadget@v0.28.1/docs/ig.md (about)

     1  ---
     2  title: ig
     3  weight: 80
     4  description: >
     5    Description of the ig tool.
     6  ---
     7  
     8  Inspektor Gadget relies on the Kubernetes API server to work. However, there are
     9  [some cases](#use-cases) where it is necessary, or preferred, to trace
    10  containers without passing through Kubernetes. In such scenarios, you can use
    11  the `ig` tool, as it allows you to collect insights from the nodes to
    12  debug your Kubernetes containers without relying on Kubernetes itself, but on
    13  the container runtimes. It is important to remark that `ig` can also
    14  be used to trace containers that were not created via Kubernetes.
    15  
    16  Some characteristics of `ig`:
    17  
    18  - It uses eBPF as its underlying core technology.
    19  - Enriches the collected data with the Kubernetes metadata.
    20  - Easy to install as it is a single binary (statically linked).
    21  
    22  The architecture of `ig` is described in the main
    23  [architecture](core-concepts/architecture.md#ig) document.
    24  
    25  ## Use cases
    26  
    27  - In a Kubernetes environment, when the Kubernetes API server is not working
    28    properly, we cannot deploy Inspektor Gadget. Therefore, we still need a way to
    29    debug the containers of the cluster.
    30  - In some cases, you might have root SSH access to the Kubernetes nodes of a
    31    cluster, but not to the `kubeconfig`.
    32  - If you don't want to install `kubectl-gadget` on your machine, you can run
    33    `ig` in a Kubernetes pod and read the output directly.
    34  - If you are implementing an application that needs to get insights from the
    35    Kubernetes node, you could include the `ig` binary in your container
    36    image, and your app simply execs it. In such a case, it is suggested to use
    37    the JSON output format to ease the parsing.
    38  - Outside a Kubernetes environment, for observing and debugging standalone
    39    containers.
    40  
    41  ## Installation
    42  
    43  The instruction to install `ig` are available in the main
    44  [installation](getting-started/install-linux.md#installing-ig) guide.
    45  
    46  ## Usage
    47  
    48  Currently, `ig` can trace containers managed by Docker regardless
    49  of whether they were created via Kubernetes or not. In case of containerd,
    50  we are using containerd API directly and containerd namespace (default `k8s.io`)
    51  can be configured using `--containerd-namespace` flag. It uses the CRI to trace
    52  containers managed by CRI-O. Similarly, it uses the [podman API](https://docs.podman.io/en/latest/markdown/podman-system-service.1.html) to trace podman containers.
    53  
    54  By default, `ig` will try to communicate with all the supported container runtimes (docker, containerd, CRI-O, podman):
    55  
    56  ```bash
    57  $ docker run -d --name myContainer nginx:1.21
    58  95b814bb82b9e30dd935b03d04a7b00b6978ce018a6f55d6a9c7a824b31ec6b5
    59  
    60  $ sudo ig list-containers
    61  RUNTIME.RUNTIMENAME RUNTIME.CONTAINERID                                              RUNTIME.CONTAINERNAME
    62  containerd          c7dfa4c92fec235626157417bf45745969006bd3bfd2607e87fdd0a176547603 konnectivity-agent
    63  containerd          cd8ce885c115adbc87da5243630b90935e5bf1c2af96b00154ec475fd9b393b0 nsenter
    64  containerd          b436a9886ee6e59ac7d38d1b76f8a306e2efeb3f1b6679ea1a58028edb198db3 azure-ip-masq-agent
    65  containerd          642fc58b15fbaf578340f4bd656b427db51be63a94a7b6eb663388486e73d855 azuredisk
    66  containerd          466a9d7e7b2087966621eacd792cc492f48f08f741f9dc82d88ef62a9d7d3e0f liveness-probe
    67  containerd          f79db0f2ea6518869c89e1d0a0892221047b23e04e4dab59dc7e42d6808e2530 azurefile
    68  containerd          85d74aeb6d29aaa38b282f3e51202bb648f7ba16a681d0d39dda684e724bb8a3 node-driver-registrar
    69  containerd          a126df15fba5713f57f1abad9c484cb75569e9f48f1169bd9710f63bb8af0e46 kube-proxy
    70  containerd          428c933882f1e4459c397da20bd89bbe7df7d437880a254472879d33b125b4da node-driver-registrar
    71  containerd          cd75a08ea2e69756cd7b1de5935c49f5ba08ba7495b0589567dcd9493193d712 cloud-node-manager
    72  containerd          d4bdf83ba71c7b22ee339ae5bb6fa7359f8a6bc7cd2f35ccd5681c728869cd39 liveness-probe
    73  docker              b72558e589cb95e835c4840de19f0306d4081091c34045246d62b6efed3549f4 myContainer
    74  ```
    75  
    76  To check which paths `ig` is using, you can use the `--help` flag:
    77  
    78  ```bash
    79  $ sudo ig list-containers --help
    80  List all containers
    81  
    82  Usage:
    83    ig list-containers [flags]
    84  
    85  Flags:
    86    ...
    87        --containerd-namespace string    Namespace used by containerd (default "k8s.io")
    88        --containerd-socketpath string   containerd CRI Unix socket path (default "/run/containerd/containerd.sock")
    89        --crio-socketpath string         CRI-O CRI Unix socket path (default "/run/crio/crio.sock")
    90        --docker-socketpath string       Docker Engine API Unix socket path (default "/run/docker.sock")
    91        --podman-socketpath string       Podman Unix socket path (default "/run/podman/podman.sock")
    92    ...
    93    -r, --runtimes string                Container runtimes to be used separated by comma. Supported values are: docker, containerd, cri-o, podman (default "docker,containerd,cri-o,podman")
    94    -w, --watch                          After listing the containers, watch for new containers
    95    ...
    96  ```
    97  
    98  If needed, we can also specify the runtimes to be used and their UNIX socket
    99  path:
   100  
   101  ```bash
   102  $ sudo ig list-containers --runtimes docker --docker-socketpath /some/path/docker.sock
   103  RUNTIME.RUNTIMENAME RUNTIME.CONTAINERID                                              RUNTIME.CONTAINERNAME
   104  docker              b72558e589cb95e835c4840de19f0306d4081091c34045246d62b6efed3549f4 myContainer
   105  ```
   106  
   107  ### Common features
   108  
   109  Notice that most of the commands support the following features even if, for
   110  simplicity, they are not demonstrated in each command guide:
   111  
   112  - JSON format and `columns` output mode are supported through the
   113    `--output` flag.
   114  - It is possible to filter events by container name using the `--containername`
   115    flag.
   116  - It is possible to trace events from all the running processes, even though
   117    they were not generated from containers, using the `--host` flag.
   118  
   119  For instance, for the `list-containers` command:
   120  
   121  ```bash
   122  $ sudo ig list-containers -o json --containername kube-proxy
   123  [
   124    {
   125      "runtime": {
   126        "runtimeName": "containerd",
   127        "containerId": "a126df15fba5713f57f1abad9c484cb75569e9f48f1169bd9710f63bb8af0e46",
   128        "containerName": "kube-proxy"
   129      },
   130      "k8s": {
   131        "namespace": "kube-system",
   132        "podName": "kube-proxy-tcbn4",
   133        "containerName": "kube-proxy",
   134        "podUID": "87c52d60-fefd-45a9-a420-895256fc03b5"
   135      },
   136      "pid": 454674,
   137      "mntns": 4026532232,
   138      "netns": 4026531840,
   139      "hostNetwork": true,
   140      "cgroupPath": "/sys/fs/cgroup/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod87c52d60_fefd_45a9_a420_895256fc03b5.slice/cri-containerd-a126df15fba5713f57f1abad9c484cb75569e9f48f1169bd9710f63bb8af0e46.scope",
   141      "cgroupID": 41286,
   142      "cgroupV2": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod87c52d60_fefd_45a9_a420_895256fc03b5.slice/cri-containerd-a126df15fba5713f57f1abad9c484cb75569e9f48f1169bd9710f63bb8af0e46.scope"
   143    }
   144  ]
   145  ```
   146  
   147  For example, with `--host`, you can get the following output:
   148  
   149  ```bash
   150  $ sudo ig trace exec --host
   151  RUNTIME.CONTAINERNAME    PID        PPID       COMM             RET ARGS
   152  
   153  # Open another terminal.
   154  $ cat /dev/null
   155  $ docker run --name test-host --rm -t debian sh -c 'ls > /dev/null'
   156  # Go back to first terminal.
   157  RUNTIME.CONTAINERNAME    PID        PPID       COMM             RET ARGS
   158                           3326022    308789     cat              0   /usr/bin/cat /dev/null
   159  test-host                3326093    3326070    sh               0   /usr/bin/sh -c ls > /dev/null
   160  test-host                3326123    3326093    ls               0   /usr/bin/ls
   161  ```
   162  
   163  Events generated from containers have their container field set, while events which are generated from the host do not.
   164  
   165  ### Using ig with "kubectl debug node"
   166  
   167  The "kubectl debug node" command is documented in
   168  [Debugging Kubernetes Nodes With Kubectl](https://kubernetes.io/docs/tasks/debug/debug-cluster/kubectl-node-debug/).
   169  
   170  Examples of commands:
   171  
   172  ```bash
   173  $ kubectl debug node/minikube-docker -ti --image=ghcr.io/inspektor-gadget/ig -- ig --auto-sd-unit-restart trace exec
   174  Creating debugging pod node-debugger-minikube-docker-c2wfw with container debugger on node minikube-docker.
   175  If you don't see a command prompt, try pressing enter.
   176  RUNTIME.CONTAINERNAME          PID              PPID             COMM             RET ARGS
   177  k8s_shell_shell_default_b4ebb… 3186934          3186270          cat              0   /bin/cat file
   178  ```
   179  
   180  ```bash
   181  $ kubectl debug node/minikube-docker -ti --image=ghcr.io/inspektor-gadget/ig -- ig --auto-sd-unit-restart list-containers -o json
   182  ```
   183  
   184  As of today, the `kubectl debug` command does not have a way to give enough privileges to the debugging pod to be able
   185  to use `ig`.
   186  This might change in the future: the Kubernetes Enhancement Proposal 1441
   187  ([KEP-1441](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/1441-kubectl-debug))
   188  suggests to implement Debugging Profiles (`--profile=`) to be able to give the necessary privileges.
   189  kubectl v1.27 implements some of those profiles but not yet the "sysadmin" profile, so it is not possible to use
   190  `--profile=` yet.
   191  
   192  Meanwhile, `ig` provides the `--auto-sd-unit-restart` flag. The flag is `false` by default. When it is set to `true`,
   193  `ig` will detect if it does not have enough privileges and it can transparently
   194  re-execute itself in a privileged systemd unit if necessary.
   195  This is possible because the "kubectl debug node" gives access to the systemd socket (`/run/systemd/private`) via the
   196  /host volume.
   197  
   198  ### Using ig as a daemon
   199  
   200  `ig` can also be run as a daemon. You can then use `gadgetctl` to connect to it as an unprivileged user.
   201  We will be using a new group called `ig` to allow controlling `ig` in this example.
   202  
   203  #### Create new group "ig" and add yourself to it
   204  
   205  ```bash
   206  $ sudo addgroup ig
   207  $ sudo adduser $USER ig
   208  ```
   209  
   210  Logout and login to make sure the new group membership is applied to your session.
   211  
   212  #### Create systemd service
   213  
   214  This assumes you installed `ig` in `/usr/local/bin` and are using systemd.
   215  Create a new service file at `/etc/systemd/system/ig.service` with the following content:
   216  
   217  ```ini
   218  [Unit]
   219  Description=Inspektor Gadget
   220  
   221  [Service]
   222  User=root
   223  Restart=on-failure
   224  RestartSec=30
   225  WorkingDirectory=/usr/local/bin
   226  ExecStart=/usr/local/bin/ig daemon --group ig
   227  
   228  [Install]
   229  WantedBy=multi-user.target
   230  ```
   231  
   232  > If you want to use another group than `ig`, make sure to adjust the `--group` parameter on the "ExecStart" line.
   233  
   234  Enable and start the new service:
   235  
   236  ```bash
   237  $ sudo systemctl enable ig.service
   238  $ sudo systemctl start ig.service
   239  ```
   240  
   241  #### Run gadgetctl
   242  
   243  If all went well, you can now run `gadgetctl` with your favorite gadgets!
   244  
   245  ```bash
   246  $ gadgetctl trace open
   247  RUNTIME.CONTAINERNAME                                          PID        COMM             FD     ERR PATH
   248  minikube-docker                                                3293       cri-dockerd      11     0   /etc/cni/net.d
   249  minikube-docker                                                3293       cri-dockerd      11     0   /etc/cni/net.d/1-k8s.conflist
   250  minikube-docker                                                2180730    bridge           3      0   /etc/ld.so.cache
   251  ...
   252  ```
   253  
   254  #### Using over the network
   255  
   256  > This is not yet a recommended way of working with ig, as the connection is __not secure__. Please only use it on otherwise
   257  > secured and/or trusted networks. We will be adding secure connections later on.
   258  
   259  Modify the `ig.service` file to something like this:
   260  
   261  ```
   262  ...
   263  ExecStart=/usr/local/bin/ig daemon -H tcp://127.0.0.1:9999
   264  ...
   265  ```
   266  
   267  Restart the service:
   268  
   269  ```bash
   270  $ sudo systemctl restart ig.service
   271  ```
   272  
   273  Use `gadgetctl` like this:
   274  
   275  ```bash
   276  $ gadgetctl trace open --remote-address tcp://127.0.0.1:9999
   277  ```
   278  
   279  #### Debugging
   280  
   281  In case anything is not working, you can look at the logs:
   282  
   283  ```bash
   284  $ journalctl -u ig.service
   285  ```
   286  
   287  To increase the verbosity of `ig`, you can edit the service file and add
   288  the verbose flag (-v) like so:
   289  
   290  ```ini
   291  ...
   292  ExecStart=/usr/local/bin/ig daemon -v --group ig
   293  ...
   294  ```
   295  
   296  The flag can also be used with `gadgetctl` like so:
   297  
   298  ```bash
   299  $ gadgetctl trace open -v
   300  ```
   301  
   302  ### Using ig in a container
   303  
   304  Example of command:
   305  
   306  ```bash
   307  $ docker run -ti --rm \
   308      --privileged \
   309      -v /run:/run \
   310      -v /:/host \
   311      --pid=host \
   312      ghcr.io/inspektor-gadget/ig \
   313      trace exec
   314  RUNTIME.CONTAINERNAME    PID        PPID       COMM             RET ARGS
   315  heuristic_yonath         3329233    3329211    ls               0   /bin/ls
   316  ```
   317  
   318  List of flags:
   319  - `--privileged` gives all capabilities such as `CAP_SYS_ADMIN`. It is required to run eBPF programs.
   320  - `-v /run:/run` gives access to the container runtimes sockets (docker, containerd, CRI-O).
   321  - `-v /:/host` gives access to the host filesystem. This is used to access the host processes via /host/proc, and access
   322    container runtime hooks (rootfs and config.json).
   323  - `--pid=host` runs in the host PID namespace. Optional on Linux. This is necessary on Docker Desktop on Windows because
   324    /host/proc does not give access to the host processes.
   325  
   326  ### Using ig in a Kubernetes pod
   327  
   328  In order to run `ig` in a Kubernetes pod use [examples/pod-ig.yaml](examples/pod-ig.yaml).
   329  
   330  ```bash
   331  $ kubectl apply -f docs/examples/pod-ig.yaml
   332  $ kubectl logs ig
   333  RUNTIME.CONTAINERNAME          RUNTIME.CONTAIN… PID              PPID             COMM             RET ARGS
   334  kube-proxy                     k8s.gcr.io/kube… 3985376          3024961          ip6tables        0   /usr/sbin/ip6tables -w 5 -W 100000 -S K…
   335  ```
   336  
   337  ### Adding ig in your own container image
   338  
   339  In order to add `ig` in your own container image, you can take example on the following Dockerfile:
   340  
   341  ```Dockerfile
   342  # In production, you should use a specific version of ig instead of latest:
   343  # --build-arg BASE_IMAGE=ghcr.io/inspektor-gadget/ig:v0.18.1
   344  ARG BASE_IMAGE=ghcr.io/inspektor-gadget/ig:latest
   345  FROM ${BASE_IMAGE} as ig
   346  
   347  # Your own image
   348  FROM alpine:3.17
   349  COPY --from=ig /usr/bin/ig /usr/bin/ig
   350  ENV HOST_ROOT=/host
   351  # The rest of your Dockerfile
   352  ```
   353  
   354  The `ghcr.io/inspektor-gadget/ig` image supports amd64 and arm64. Your own image can also support both architectures if
   355  you use the appropriate `--platforms` flag of `docker buildx build` (see
   356  [Docker documentation about multi-platform images](https://docs.docker.com/build/building/multi-platform/#example)).
   357  
   358  You can then run your image locally or in a Kubernetes pod.
   359  Here is an example using a Kubernetes DaemonSet: [examples/ds-ig.yaml](examples/ds-ig.yaml):
   360  
   361  ```bash
   362  $ kubectl apply -f docs/examples/ds-ig.yaml
   363  $ kubectl exec -ti $(kubectl get pod -o name -l name=example-ig | head -1) -- sh
   364  / # ig trace exec
   365  ```