Centos 7 Docker Image with Systemd and Docker

Topic created · 1 Posts · 7 Views
  • Purpose

    It's possible that due to some requirement in our environment, we might need to run a Docker image which has Docker running inside of it.

    An example would be the need of creating a custom Jenkins slave image with specific libraries or packages for our builds in Kubernetes.

    If there are no needs for specific libraries or packages, we recommend to use Kaniko

    In this build we are including:

    • Python 3.6
    • wget
    • unzip
    • curl

    Build Process

    We need an environment with Docker installed (could be a linux server, our workstation or laptop).
    Then, we need to create a Dockerfile with the following content:

    The following dockerfile is an example with several dependencies.

    FROM centos:7
    RUN yum -y install curl systemd yum-utils
    ENV container docker
    RUN rm -f /lib/systemd/system/multi-user.target.wants/* && rm -f /etc/systemd/system/*.wants/* && rm -f /lib/systemd/system/local-fs.target.wants/* && \
        rm -f /lib/systemd/system/sockets.target.wants/*udev* && rm -f /lib/systemd/system/sockets.target.wants/*initctl* && rm -f /lib/systemd/system/basic.target.wants/* && \
        rm -f /lib/systemd/system/anaconda.target.wants/*
    RUN yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && \
        yum clean all && rm -Rf /var/cache/yum/
    RUN yum install https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm -y
    RUN yum install docker-ce initscripts epel-release openssh openssh-server openssh-clients openssl-libs wget unzip git python36 -y && \
        yum clean all; systemctl enable docker.service && systemctl enable sshd.service
    RUN sed -i s/^SELINUX=.*$/SELINUX=disabled/ /etc/selinux/config && rm -f /etc/nologin /run/nologin && mkdir /jenkins && chmod -R 777 /jenkins && \
        mkdir -p /etc/docker/ && chmod -R 777 /etc/docker/
    WORKDIR /jenkins
    COPY ./start.sh /jenkins/start.sh
    COPY ./slave.sh  /jenkins/slave.sh
    COPY ./daemon.json /etc/docker/daemon.json
    
    EXPOSE 80
    EXPOSE 8080
    EXPOSE 50000
    
    CMD ["/jenkins/start.sh"]
    

    We need to create to additional files. The first file would be slave.sh:

    #!/bin/bash
    for (( ; ; ))
    do
       echo "Pres CTRL+C to stop..."
       sleep 1
    done
    

    And the second file would be start.sh

    #!/bin/bash
    setsid /jenkins/slave.sh > output.txt &
    exec /usr/sbin/init && service docker start 
    

    Don't forget to give execution permissions to our scripts:

    chmod a+x slave.sh start.sh
    

    Finally, create a file named daemon.json
    As we will be running docker inside a container, we will be using the vfs storage driver

    {
     "storage-driver": "vfs",
     "data-root": "/tmp"
    }
    

    Then we can build our docker image with the command:

    docker build . -t mycustomimage
    

    Testing the image

    Now if you run the following command, you'll see your new build

    docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    mycustomimage       latest              f2a59057bc67        23 seconds ago      1.16GB
    

    Try and run it by typing:

    docker run -d --privileged=true -it mycustomimage
    

    Then check that it's running:

    docker ps
    CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS                         NAMES
    f8f27c1cb50e        mycustomimage       "/jenkins/start.sh"   13 seconds ago      Up 11 seconds       80/tcp, 8080/tcp, 50000/tcp   sad_goodall
    

    Then, connect to our running container (remember to change for your container id) by using:

     docker exec -it f8f27c1cb50e /bin/bash
    

    Once inside the container, try to run

    docker ps
    docker pull nginx
    

    Tweaking the image

    As you might have noticed, the image grew up more than 500mb. This is because we are installing several packages.
    You can remove the packages that you're not going to use and customize your docker builds inside the container properly.

    Build cleanup

    Once you've finished building your images and you've pushed them to your container registry, you can clean up all the images and cached information.

    Warning

    If you run the following command it will delete all your images in the system.
    Execute it wisely

    docker system prune -a