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 ```