All Projects → Mic92 → Cntr

Mic92 / Cntr

Licence: mit
A container debugging tool based on FUSE

Programming Languages

rust
11053 projects

Labels

Projects that are alternatives of or similar to Cntr

cv4pve-api-php
Proxmox VE Client API for PHP
Stars: ✭ 45 (-84.75%)
Mutual labels:  lxc
ProxmoxVE PHP API
ProxmoxVE PHP API
Stars: ✭ 78 (-73.56%)
Mutual labels:  lxc
python2-lxc
Python 2.7 binding for liblxc (similar to the better supported python3-lxc)
Stars: ✭ 49 (-83.39%)
Mutual labels:  lxc
emrah-buster-templates
The templates of the emrah-buster installer.
Stars: ✭ 57 (-80.68%)
Mutual labels:  lxc
softwarecontainer
Framework to manage and contain applications in an automotive setting
Stars: ✭ 19 (-93.56%)
Mutual labels:  lxc
ansible virtualization
Ansible Collection: Virtualization roles
Stars: ✭ 31 (-89.49%)
Mutual labels:  lxc
vps host server
VPS Hosting Server Daemon for provisioning, monitoring, and communications with the central system.
Stars: ✭ 12 (-95.93%)
Mutual labels:  lxc
Lxd
Powerful system container and virtual machine manager
Stars: ✭ 3,115 (+955.93%)
Mutual labels:  lxc
DockerAndKubernetes
Docker and Kubernetes cheat sheets and examples for familiarization. Also contains some documentation on LXC.
Stars: ✭ 31 (-89.49%)
Mutual labels:  lxc
cv4pve-api-dotnet
Proxmox VE Client API .Net C#
Stars: ✭ 25 (-91.53%)
Mutual labels:  lxc
saltstack-lxc-vagrant
Vagrantfile for setting up a SaltStack test/dev environment.
Stars: ✭ 13 (-95.59%)
Mutual labels:  lxc
edi-raspbian
edi configuration for emulated raspbian and raspbian cross compilation.
Stars: ✭ 16 (-94.58%)
Mutual labels:  lxc
bakery
Simple tool to backup and restore ChromeOS Crostini containers
Stars: ✭ 18 (-93.9%)
Mutual labels:  lxc
icp-ce-on-linux-containers
Multi node IBM Cloud Private Community Edition 3.2.x w/ Kubernetes 1.13.5 in a Box. Terraform, Packer and BASH based Infrastructure as Code script sets up a multi node LXD cluster, installs ICP-CE and clis on a metal or VM Ubuntu 18.04 host.
Stars: ✭ 52 (-82.37%)
Mutual labels:  lxc
cv4pve-botgram
Telegram Bot for Proxmox VE
Stars: ✭ 26 (-91.19%)
Mutual labels:  lxc
awesome-lxc-lxd
A curated list of awesome LXC and LXD tools, libraries and related projects.
Stars: ✭ 34 (-88.47%)
Mutual labels:  lxc
harbour-containers
A Linux containers manager for SailfishOS
Stars: ✭ 30 (-89.83%)
Mutual labels:  lxc
Lxdmosaic
Web interface to manage multiple instance of lxd
Stars: ✭ 270 (-8.47%)
Mutual labels:  lxc
cbtool
Cloud Rapid Experimentation and Analysis Toolkit
Stars: ✭ 65 (-77.97%)
Mutual labels:  lxc
demo-container-runtime
Simple demonstration codebase for how containers work
Stars: ✭ 37 (-87.46%)
Mutual labels:  lxc

cntr

Say no to $ apt install vim in containers! cntr is a replacement for docker exec that brings all your developers tools with you. This is done by mounting the file system from one container or the host into the target container by creating a nested container with the help of a FUSE filesystem. This allows to ship minimal runtime image in production and limit the surface for exploits.

Cntr was also published in Usenix ATC 2018. See bibtex for citation.

Demo

In this two minute recording you learn all the basics of cntr:

asciicast

Features

  • For convenience cntr supports container names/identifier for the following container engines natively:
    • docker
    • podman
    • LXC
    • LXD
    • rkt
    • systemd-nspawn
    • containerd
  • For other container engines cntr also takes process ids (PIDs) instead of container names.

Installation

Pre-build static-linked binary

For linux x86_64 we build static binaries for every release. More platforms can added on request. See the release tab for pre-build tarballs. At runtime only commandline utils of the container engine in questions are required.

Build from source

All you need for compilation is rust + cargo. Checkout rustup.rs on how to get a working rust toolchain. Then run:

Either:

$ cargo install cntr

Or the latest master:

$ cargo install --git https://github.com/Mic92/cntr

For offline builds we also provided a tarball with all dependencies bundled here for compilation with cargo-vendor.

Usage

At a high-level cntr provides two subcommands: attach and exec:

  • attach: Allows you to attach to a container with your own native shell/commands. Cntr will mount the container at /var/lib/cntr. The container itself will run unaffected as the mount changes are not visible to container processes.
    • Example: cntr attach <container_id> where container_id can be a container identifier or process id (see examples below).
  • exec: Once you are in the container, you can also run commands from the container filesystem itself. Since those might need their native mount layout at / instead of /var/lib/cntr, cntr provides exec subcommand to chroot to container again and also resets the environment variables that might have been changed by the shell.
    • Example: cntr exec <command> where command is an executable in the container

Note: Cntr needs to run on the same host as the container. It does not work if the container is running in a virtual machine while cntr is running on the hypervisor.

$ cntr --help
Cntr 1.5.1
Jörg Thalheim <[email protected]>
Enter or executed in container

USAGE:
    cntr <SUBCOMMAND>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    attach    Enter container
    exec      Execute command in container filesystem
    help      Prints this message or the help of the given subcommand(s)
$ cntr attach --help
cntr-attach 1.5.1
Jörg Thalheim <[email protected]>
Enter container

USAGE:
    cntr attach [OPTIONS] <id> [command]...

FLAGS:
    -h, --help    Prints help information

OPTIONS:
        --effective-user <EFFECTIVE_USER>    effective username that should be owner of new created files on the host
    -t, --type <TYPE>                        Container types to try (sperated by ','). [default: all but command]
                                             [possible values: process_id, rkt, podman, docker, nspawn, lxc, lxd,
                                             containerd, command]

ARGS:
    <id>            container id, container name or process id
    <command>...    Command and its arguments to execute after attach. Consider prepending it with '-- ' to prevent
                    parsing of '-x'-like flags. [default: $SHELL]
$ cntr exec --help
cntr-exec 1.5.1
Jörg Thalheim <[email protected]>
Execute command in container filesystem

USAGE:
    cntr exec [command]...

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

ARGS:
    <command>...    Command and its arguments to execute after attach. Consider prepending it with '-- ' to prevent
                    parsing of '-x'-like flags. [default: $SHELL]

Docker

1: Find out the container name/container id:

$ docker run --name boxbusy -ti busybox
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
55a93d71b53b        busybox             "sh"                22 seconds ago      Up 20 seconds                           boxbusy

Either provide a container id...

$ cntr attach 55a93d71b53b
[echo "I am in a container!"
[[email protected]:/var/lib/cntr]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
40: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[[email protected]:/var/lib/cntr]# vim etc/resolv.conf

...or the container name. Use cntr exec to execute container native commands (while running in the cntr shell).

$ cntr attach boxbusy
[exec -- sh -c 'busybox | head -1'

You can also use Dockerfile.example from this repo to build a docker container with cntr:

$ docker build -f Dockerfile.example . -t cntr
# boxbusy here is the name of the target container to attach to
$ docker run --pid=host --privileged=true -v /var/run/docker.sock:/var/run/docker.sock -ti --rm cntr attach boxbusy /bin/sh

Podman

See docker usage, just replace docker with the podman command.

LXD

1: Create a container and start it

$ lxc image import images:/alpine/edge
$ lxc launch images:alpine/edge
$ lxc list
+-----------------+---------+------+------+------------+-----------+
|      NAME       |  STATE  | IPV4 | IPV6 |    TYPE    | SNAPSHOTS |
+-----------------+---------+------+------+------------+-----------+
| amazed-sailfish | RUNNING |      |      | PERSISTENT | 0         |
+-----------------+---------+------+------+------------+-----------+

2: Attach to the container with cntr

$ cntr attach amazed-sailfish
$ cat etc/hostname
amazed-sailfish

LXC

1: Create a container and start it

$ lxc-create --name ubuntu -t download -- -d ubuntu -r xenial -a amd64
$ lxc-start --name ubuntu -F
...
Ubuntu 16.04.4 LTS ubuntu console
ubuntu login:
$ lxc-ls
ubuntu

2: Attach to container with cntr:

$ cntr attach ubuntu
[cat etc/os-release
NAME="Ubuntu"
VERSION="16.04.4 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.4 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

rkt

1: Find out the container uuid:

$ rkt run --interactive=true docker://busybox
$ rkt list
UUID            APP     IMAGE NAME                                      STATE   CREATED         STARTED         NETWORKS
c2d2e87e        busybox registry-1.docker.io/library/busybox:latest     running 6 minutes ago   6 minutes ago   default:ip4=172.16.28.3

2: Attach with cntr

# make sure your container is still running!
$ cntr attach c2d2e87e
# Finally not the old ugly top!
[[email protected]:/var/lib/cntr]# htop
...

With cntr you can also debug stage1 of rkt - even there is no support from rkt itself.

$ ps aux | grep stage1
joerg    13546  0.0  0.0 120808  1608 pts/12   S+   11:10   0:00 grep --binary-files=without-match --directories=skip --color=auto stage1
root     22232  0.0  0.0  54208  2656 pts/7    S+   10:54   0:00 stage1/rootfs/usr/lib/ld-linux-x86-64.so.2 stage1/rootfs/usr/bin/systemd-nspawn --boot --notify-ready=yes --register=true --link-journal=try-guest --quiet --uuid=c2d2e87e-e798-4341-ae93-26f6cbb7c017 --machine=rkt-c2d2e87e-e798-4341-ae93-26f6cbb7c017 --directory=stage1/rootfs --capability=CAP_AUDIT_WRITE,CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FSETID,CAP_FOWNER,CAP_KILL,CAP_MKNOD,CAP_NET_RAW,CAP_NET_BIND_SERVICE,CAP_SETUID,CAP_SETGID,CAP_SETPCAP,CAP_SETFCAP,CAP_SYS_CHROOT -- --default-standard-output=tty --log-target=null --show-status=0

Therefore we use the process id instead of the container uuid:

$ cntr attach 22232
# new and exiting territory!
[grep pods
sysfs on /var/lib/cntr/var/lib/rkt/pods/run/c2d2e87e-e798-4341-ae93-26f6cbb7c017/stage1/rootfs/sys type sysfs (ro,nosuid,nodev,noexec,relatime)
tmpfs on /var/lib/cntr/var/lib/rkt/pods/run/c2d2e87e-e798-4341-ae93-26f6cbb7c017/stage1/rootfs/sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /var/lib/cntr/var/lib/rkt/pods/run/c2d2e87e-e798-4341-ae93-26f6cbb7c017/stage1/rootfs/sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory)

systemd-nspawn

1: Start container

$ wget https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-amd64-root.tar.xz
$ mkdir /var/lib/machines/ubuntu
$ tar -xf ubuntu-16.04-server-cloudimg-amd64-root.tar.xz -C /var/lib/machines/ubuntu
$ systemd-nspawn -b -M ubuntu
$ machinectl list
MACHINE CLASS     SERVICE        OS     VERSION ADDRESSES
ubuntu  container systemd-nspawn ubuntu 16.04   -

2: Attach

$ cntr attach ubuntu

Generic process id

The minimal information needed by cntr is the process id of a container process you want to attach to.

# Did you now chromium uses namespaces too?
$ ps aux | grep 'chromium --type=renderer'
joerg    17498 11.7  1.0 1394504 174256 ?      Sl   15:16   0:08 /usr/bin/chromium

In this case 17498 is the pid we are looking for.

$ cntr attach 17498
# looks quite similar to our system, but with less users
[[email protected] cntr]$ ls -la /
total 240
drwxr-xr-x   23 nobody nogroup    23 Mar 13 15:05 .
drwxr-xr-x   23 nobody nogroup    23 Mar 13 15:05 ..
drwxr-xr-x    2 nobody nogroup     3 Mar 13 15:14 bin
drwxr-xr-x    4 nobody nogroup 16384 Jan  1  1970 boot
drwxr-xr-x   24 nobody nogroup  4120 Mar 13 14:56 dev
drwxr-xr-x   52 nobody nogroup   125 Mar 13 15:14 etc
drwxr-xr-x    3 nobody nogroup     3 Jan  8 16:17 home
drwxr-xr-x    8 nobody nogroup     8 Feb  9 22:10 mnt
dr-xr-xr-x  306 nobody nogroup     0 Mar 13 09:38 proc
drwx------   22 nobody nogroup    43 Mar 13 15:09 root
...

Containerd

For containerd integration the ctr binary is required. You can get a binary by running:

$ GOPATH=$(mktemp -d)
$ go get github.com/containerd/containerd/cmd/ctr
$ $GOPATH/bin/ctr --help

Put the resulting ctr binary in your $PATH

1: Start container

$ ctr images pull docker.io/library/busybox:latest
$ ctr run docker.io/library/busybox:latest boxbusy
$ ctr tasks lists
TASK        PID      STATUS
boxbusy    24310    RUNNING

2: Attach

$ cntr attach boxbusy

It's also possible to run cntr from a container itself. This repository contains a example Dockerfile for that:

$ docker build -f Dockerfile.example . -t cntr
$ docker save cntr > cntr.tar
$ ctr images import --base-name cntr ./cntr.tar

In this example we attach to containerd by process id. The proccess id of a task is given in ctr tasks list.

$ ctr run --privileged --with-ns pid:/proc/1/ns/pid --tty docker.io/library/cntr:latest cntr /usr/bin/cntr attach 31523 /bin/sh

To resolve containerd names one also would need to add the ctr binary (~12mb) to the Dockerfile.

How it works

Cntr is container-agnostic: Instead of interfacing with container engines, it implements the underlying operating system API. It treats every container as a group of processes, that it can inherit properties from.

Cntr inherits the following container properties:

  • Namespaces (mount, uts, pid, net, cgroup, ipc)
  • Cgroups
  • Apparamor/selinux
  • Capabilities
  • User/group ids
  • Environment variables
  • The following files: /etc/passwd, /etc/hostname, /etc/hosts, /etc/resolv.conf

Under the hood it spawns a shell or user defined program that inherits the full context of the container and mount itself as a fuse filesystem.

We extensively evaluated the correctness and performance of cntr's filesystem using xfstests and a wide range of filesystem performance benchmarks (iozone, pgbench, dbench, fio, fs-mark, postmark, ...)

Related projects

  • nsenter
    • Only covers linux namespaces and the user is limited to tools installed in the containers
  • toolbox
    • Does attach from a container to the host, this is the opposite of what Cntr is doing

Bibtex

We published a paper with all technical details about Cntr in Usenix ATC 2018.

@inproceedings{cntr-atc18,
  author = {J{\"o}rg Thalheim and Pramod Bhatotia and Pedro Fonseca and Baris Kasikci},
  title = {Cntr: Lightweight {OS} Containers},
  booktitle = {2018 {USENIX} Annual Technical Conference ({USENIX} {ATC} 18)},
  year = {2018},
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].