Pages

Tuesday, September 18, 2018

Containers with out Docker


Containers are not new but what made people go for Docker?. Though we have  many container technologies people preferred docker for one reason. Docker made great leaps in simplification of containers. It is always hard implementing the containers in a organisation before docker.

Is Docker the only container technology?. Can we create a container without docker?. This article talks about the how we can create containers with out docker

Docker is not a container technology, if is a company that promotes creating of containers in a simplest way. They have their own library called “libcontainer” that helps in creating the containers. Below are few other tools that helps in creating containers with out docker.

RunC - RunC is a command line tool for spawning and running containers according to the OCI specification. This is a docker container format and runtime that is being donated to the Oci.

How to use RunC to run Containers?
1. Download the runC library based on the platform from here using,
wget https://github.com/opencontainers/runc/releases/download/v1.0.0-rc5/runc.amd64

2. Create a directory structure
mkdir runC
cd runC
mkdir test-container
cd test-container

3. Download a busybox docker container image and export the image to the rootfs filesystem like,  docker export $(docker create busybox) | tar -C rootfs -xvf -

Now we will see a directory by the name rootfs with multiple files and directories inside

4. Run the runC spec command from the download library using,
[root@manja17-I13330 test-container]# /root/runc/runc.amd64 spec
[root@manja17-I13330 test-container]# ll
total 4
-rw-r--r--  1 root root 2614 Jul 26 07:27 config.json
drwxr-xr-x 12 root root  137 Jul 26 07:09 rootfs

A spec file is created by the name config.json. Check the file to see the configurations details for the image.

[root@manja17-I13330 test-container]# cat config.json
{
        "ociVersion": "1.0.0",
        "process": {
                "terminal": true,
                "user": {
                        "uid": 0,
                        "gid": 0
                },
                "args": [
                        "sh"
                ],
                "env": [
                        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                        "TERM=xterm"
                ],
                "cwd": "/",
                "capabilities": {
                        "bounding": [
                                "CAP_AUDIT_WRITE",
                                "CAP_KILL",
                                "CAP_NET_BIND_SERVICE"
                        ],
                        "effective": [
                                "CAP_AUDIT_WRITE",
                                "CAP_KILL",
                                "CAP_NET_BIND_SERVICE"
                        ],
                       *********
If you check the config.json, we can see what this container does and how it will run etc.Run the container using the runC command as,
[root@manja17-I13330 test-container]# /root/runc/runc.amd64 run container1
/ # ps ux
PID   USER     TIME  COMMAND
    1 root      0:00 sh
    6 root      0:00 ps ux
/ # exit

Run the container background using,
[root@manja17-I13330 test-container]# /root/runc/runc.amd64 run container1 &
[root@manja17-I13330 test-container]# /root/runc/runc.amd64 list
We will see the containers running listed

All commands that we run is based on the Container ID. lets run some more commands as
[root@manja17-I13330 runc]# ./runc.amd64 ps container1
UID        PID     PPID   C STIME TTY          TIME    CMD
root     21033 21025  0 00:20 ?         00:00:00 sh

[root@manja17-I13330 runc]# ./runc.amd64 exec container1 free
                total          used           free        shared    buffers     cached
Mem:       8175444    8013024     162420          0       2776    5760124
-/+ buffers/cache:     2250124     5925320
Swap:       0             0                 0

Podman - Podman is a tool designed for managing pods and containers without requiring a container daemon.  Unlike Docker , we will not be having any Container Runtime over here. Podman takes care of creating containers, managing etc.

Podman CLI is based on Docker Cli. This is intended to be user friendly interface and is capable of providing summaries of containers, images etc.

Podman manages pods as well as Containers outside of Pod. So when said podman does not have a Container Runtime , how can we build images , start containers etc.

Podman creates the containerised processes and makes the necessary changes on the disk itself. This is based on the library called “container/images” for pulling images from registry. The same library is used to manage images on the disk even 

Installing podman is quite easy. Just enable the epel-release repo on the centos and run the “yum install godman.x86_64” or you can download the repo from here.

Podman Cli is based on the Docker Cli. So the podman commands will be pretty much similar to the docker commands.  

[root@rkt-machine vagrant]# podman run -d --name testing docker.io/jagadesh1982/testing-service
Trying to pull docker.io/jagadesh1982/testing-service...Getting image source signatures
*********
Copying config sha256:60c1b93cd9f4920aba848d5d457a5f9d24bd1bc4afd0cb4bbcf510a9528c43d2
 9.06 KB / 9.06 KB [========================================================] 0s
Writing manifest to image destination
Storing signatures
bb7893663146fad1f0c344b1b6670e56e08cf428cbe97088f511f9adc771805f

Check the Running Container using “podman ps”,

If we check with docker command as “docker ps” , we will not be able to see any running containers since the containers started by podman are subprocess of the podman process.

Gather the Container details - to get the container details like Ip address etc, podman provides us with a inspect command which is similar to docker. We can use that using “podman inspect <container ID> 

List Images - Podman Provides us with same commands as docker to list the images as below,
[root@rkt-machine vagrant]# podman images
REPOSITORY                                                   TAG      IMAGE ID.           CREATED        SIZE
docker.io/jagadesh1982/testing-service   latest   60c1b93cd9f4   4 months ago   705MB

Run the Container in Foreground - Similar to Docker, podman provides us with a way to run a container in a foreground way using,

[root@rkt-machine vagrant]# podman run -it --name testingService docker.io/jagadesh1982/testing-service /bin/bash
root@7972e841af05:/usr/src/app# hostname -I
10.88.0.4 
root@7972e841af05:/usr/src/app# exit
exit

Systemd-nspawn - systems-spawn is a system tool to run containers like a virtual machine. The isolation environments created by nspawn are called machines and are managed by the tool called “machinectl”. This is the same tool that will interface with the nspawn machines and also containers created by rkt, docker etc.

Install the minimal packages necessary for starting the container using,
[root@rkt-machine install]# sudo yum -y --nogpg --releasever=7 --installroot=/srv/mycontainer   install systemd passwd yum vim-minimal

Start our container using
[root@rkt-machine install]# sudo systemd-nspawn -D /srv/mycontainer
Spawning container mycontainer on /srv/mycontainer.
Press ^] three times within 1s to kill container.
-bash-4.2# hostname -I
-bash: hostname: command not found
-bash-4.2# ls         
-bash-4.2# pwd
/root
-bash-4.2# exit
logout
Container mycontainer exited successfully.

List the container using,
[root@rkt-machine install]# machinectl 
MACHINE     CLASS     SERVICE
mycontainer container nspawn 

1 machines listed.

Rkt - Another container technology that is gaining up along with docker is Rocket. A CoreOS Container Runtime built as docker is no locker according to the open standards.   Docker runs with a daemon that manages all components. If the process disappears the containers disappear. Rkt tries to solve these problems.

Download and install the latest rkt rpm using
Wget https://github.com/rkt/rkt/releases/download/v1.30.0/rkt-1.30.0-1.x86_64.rpm

Yum install rkt*

[root@manja17-I13330 ~]# rkt fetch --insecure-options=image docker://jagadesh1982/testing-service
Downloading sha256:74eaa8be722 [=============================] 43.3 MB / 43.3 MB
Downloading sha256:f2b6b4884fc [=============================] 52.6 MB / 52.6 MB
Downloading sha256:bb0bcc8d7f6 [=============================] 14.8 MB / 14.8 MB
Downloading sha256:727d0f4e04b [=============================]     133 B / 133 B
Downloading sha256:4fb899b4df2 [=============================] 19.3 MB / 19.3 MB
Downloading sha256:da74659b918 [=============================] 4.33 MB / 4.33 MB
Downloading sha256:2d6e98fe404 [=============================]   131 MB / 131 MB
Downloading sha256:414666f7554 [=============================] 3.17 MB / 3.17 MB
Downloading sha256:ace2d3087f5 [=============================] 1.78 MB / 1.78 MB
Downloading sha256:17c4133ca61 [=============================]     667 B / 667 B
Downloading sha256:9940cbd4fb3 [=============================]     206 B / 206 B
Downloading sha256:b6477608bbd [=============================]     864 B / 864 B
Downloading sha256:fb20ef6fe17 [=============================] 1.35 MB / 1.35 MB
sha512-d5628ec41849f9c65c8be020921c61a8

Check for the downloaded images using,
[root@manja17-I13330 ~]# rkt image list
ID                                            NAME                               
sha512-d5628ec41849     registry-1.docker.io/jagadesh1982/testing-service:latest

Run a Container as,
[root@manja17-I13330 ~]# 
rkt run sha512-d5628ec41849
In the another command line, check the list of containers running using
[root@manja17-I13330 ~]# rkt list | grep testing-service3e42fb73        testing-service registry-1.docker.io/jagadesh1982/testing-service:latest        running 3 minutes ago   3 minutes ago default:ip4=172.16.28.6
Access the application using ,
[root@manja17-I13330 ~]# curl 172.16.28.6:9876/info{"host": "172.16.28.6:9876", "version": "0.5.0", "from": "172.16.28.1"}
Enter into the Container using,

[root@manja17-I13330 ~]# rkt enter 3e42fb73 /bin/bash
root@rkt-3e42fb73-ef08-4876-b996-759c7849aa99:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  testing_service.py  tmp  usr  var
root@rkt-3e42fb73-ef08-4876-b996-759c7849aa99:/# exit
Exit

CRI-O - Kubernetes is an orchestration engine that uses a container run time to run a container or a Pod. So kubernetes was built on top of docker as the container runtime. Soon as CoreOS announced the rkt container runtime, kubernetes was asked to support it. So finally kubernetes ended up supporting both container runtime.

The problem here is docker was growing in a faster pace. In order to upgrade our existing kubernetes cluster runtime with newer versions, it is always complex. More over the runtime now are enhancing by adding more features like swarm etc which are not necessary to kubernetes. 

The Container Runtime Interface ( CRI ) was introduced to solve these problems.The idea is to build a container runtime that will decouple the kubernetes kubelet service ( which is responsible for sending requests to container runtime on a machine to start a container ) from the container run time.

The CRI-O was started to create a minimal maintainable runtime dedicated for kubernetes. CRI-O is an implementation of Kubernetes CRI that allows kubernetes to use any OCI-compliant runtime as container runtime for creating and running pods. The Runtime will be part of the kubernetes library it self so that we don’t need to install a separate runtime like docker or rkt for starting containers.

CRI-O supports OCI container images and can pull from any compliant container registry. It is a lightweight alternative to using Docker as the runtime for Kubernetes.

No comments :

Post a Comment