Customize Packages for Atomic Host : Ansible Automation

My earlier post automate-building-your-own-atomic-host describes how to Automate building Atomic Host with Ansible. But it is not capable of customizing packages for OSTree and build Atomic host based on it.

This post includes Ansible Automation for customizing packages of OSTree and build Atomic Host. Below are the improvements on this updated post :

  • Add packages to OSTree (It is suggested not to delete any pre-existing packages from the OSTree, that might break your Atomic host).
  • No need to create VM from the QCOW2 image will shell script anymore, It will be now all-in-one playbook.

If you do not know about Atomic host, please refer to http://www.projectatomic.io.

Requirements:

The requirements remain the same just like the earlier post. I will use Fedora distribution for the demo, but the same will be applicable for CentOS as well.

  • Make sure Ansible is installed on your system. If you are using Fedora workstation/any other platform, do not forget to install python2-dnf as well.
  • Download Atomic QCOW2 image: Fedora-Atomic.

Procedure:

Clone:

$ git clone https://github.com/trishnaguha/build-atomic-host.git
$ cd build-atomic-host/

Environment Setup:

The following will install requirements on your system, initializes OSTree and starts HTTP server as daemon service. The OSTree is made available via web server at TCP port 35000. After running the playbook you may use ip addr to check the IP Address of your HTTP server.

$ ansible-playbook setup.yml --ask-sudo-pass

Variables:

I am going to use variables applicable for Fedora. If you are using CentOS please modify the variables based on it.

  • Primary Variables.
    vars/atomic.yml
---
# Variables for Atomic host
atomicname: my-atomic                          # OSTree name
basehost: fedora-atomic/25/x86_64/docker-host  # Basehost
httpserver: 192.168.122.1                      # IP Address of HTTP Server
  • Additional packages you would like to have in your OSTree.
    vars/buildrepo.yml
# Variables for OSTree packages
repo: https://pagure.io/fedora-atomic.git
branch: f25
repodir: fedora-atomic
abs_path: /workspace                                # The absolute path to the git repo.
custommanifest: customized-atomic-docker-host.json  # The manifest that goes into the custom host(ostree) content that we are going to build.
sourcemanifest: fedora-atomic-docker-host.json      # The manifest that goes into the actual Base Fedora host(ostree) content.
packages: '"vim-enhanced", "git"'                   # Packages you want to have in your Atomic host.

Add packages like above separate by comma.

  • Variables for the VM
    vars/guests.yml
# Variables for Creating VM
domain: atomic-node                        # Domain name
image: Fedora-Atomic-25-20170228.0.x86_64  # Image name
cpu: 1
mem: 1536
os:
  variant: fedora23
path: /tmp                                 # Path to QCOW2 Image

Main Playbook:

Run the main Playbook which will create VM from QCOW2 image, compose OSTree and perform SSH-Setup and Rebase on OSTree:

$ ansible-playbook main.yml --ask-sudo-pass

Note: user-name: atomic-user, password: atomic are the credentials for the instance.
If you wish to change it, modify the cloud-init user-data.
We will have the credentials as variables/vault later.

To Check the IP Address of the VM running:

$ sudo virsh domifaddr atomic-node

Now SSH to the Atomic host and perform Reboot so that it will reboot in to custom OSTree.

$ ssh atomic-user@IP-ADDRESS-OF-VM
$ sudo systemctl reboot

SSH again and You will have your own OSTRee.

[atomic-user@atomic-node ~]$ sudo rpm-ostree status
State: idle
Deployments:
● my-atomic:fedora-atomic/25/x86_64/docker-host
       Version: 25.1 (2017-02-07 05:34:46)
        Commit: 15b70198b8ec7fd54271f9672578544ff03d1f61df8d7f0fa262ff7519438eb6
        OSName: fedora-atomic

  fedora-atomic:fedora-atomic/25/x86_64/docker-host
       Version: 25.51 (2017-01-30 20:09:59)
        Commit: f294635a1dc62d9ae52151a5fa897085cac8eaa601c52e9a4bc376e9ecee11dd
        OSName: fedora-atomic
[atomic-user@atomic-node ~]$ rpm -q git vim-enhanced
git-2.9.3-2.fc25.x86_64
vim-enhanced-8.0.386-1.fc25.x86_64

If you find any bug/idea please open up issues here. Thanks.

Atomic-Host

Contribute to Atomic Host Documentation

The post describes how you can contribute to Atomic Host Documentation. If you do not know what Atomic Host is, please refer to: http://www.projectatomic.io.

Atomic Host Documentation focuses on covering Docs required for Atomic Host Introduction, Installation, Cluster set up with Kuberenetes/Openshift etc to how to compose, manage and deploy Atomic Host and its various application.

Atomic Host Documentation will also support Fedora Atomic Documentation and CentOS Atomic Documentation within the same repository in near future as AsciiBinder has ability to build Docs with multiple distros and versions.

Requirements:

  • AsciiDoc markup language to write Docs.
  • Asciidoctor that acts as text processor to convert AsciiDoc content to HTML5, DocBook and others.
  • AsciiBinder that helps to build, maintain documentation in easier way.

Set up Development Environment:

The following creates development environment and installs required libraries/packages on your local system which are required in order to write/build Doc for Atomic Host.

$ sudo dnf install ansible
$ git clone https://github.com/projectatomic/atomic-host-docs.git
$ cd atomic-host-docs/
$ git checkout -b branchname
$ ansible-playbook setup.yml --ask-sudo-pass

How to Write Doc:

Atomic Host Documentation uses AsciiDoc markup language. You can have a look at the Reference for AsciiDoc Syntax.

The following procedure demonstrates how you can write and build Doc.

$ mkdir container
$ touch container/overview.adoc

 

container/overview.adoc

[[container-overview]]
= Container Overview
{product-author}
{product-version}
:data-uri:
:icons:

Container contains applications in a way to keep itself isolated from the host system that it runs on and
container allows developer to package an application with all of it parts, such as libraries and other packages
it needs to run and ship it all as one package.
I love Containers!!!

 

After the Doc is ready, we need to make entry in topic_map.yml file. This file tells AsciiBinder which topic groups and topics to generate.

_topic_map.yml

---
Name: Tools
Dir: container
Topics:
  - Name: Overview
    File: overview

 

Now go to the root directory of the repo. The following command will build the Documentation.

$ asciibinder

Verify:

A new directory will be created named _preview. You will be able to browse Documentation from there that you just build.

This is how it will look like after the Doc is build:

contribution-guide-demo

Join and Help:

If you are looking forward to contribute to Atomic Host Docs, this URL contains the issues based on the topics that is required to be documented: https://github.com/projectatomic/atomic-host-docs/issues.

Mailing list:

IRC: #atomic on Freenode server.

Automate Building your Own Atomic Host

Project Atomic hosts are built from standard RPM packages which have been composed into filesystem trees using rpm-ostree. This post provides method for automation of Building Atomic host (Creating new trees).

Requirements

Process

Clone the Git repo on your working machine Build-Atomic-Host.

$ git clone https://github.com/trishnaguha/build-atomic-host.git
$ cd build-atomic-host

Create VM from the QCOW2 Image

The following creates VM from QCOW2 Image where username is atomic-user and password is atomic. Here atomic-nodein the instance name.

$ sudo sh create-vm.sh atomic-node /path/to/fedora-atomic25.qcow2
# For example: /var/lib/libvirt/images/Fedora-Atomic-25-20170131.0.x86_64.qcow2

Start HTTP Server

The tree is made available via web server. The following playbook creates directory structure, initializes OSTree repository and starts the HTTP server.

$ ansible-playbook httpserver.yml --ask-sudo-pass

Use ip addr to check IP Address of the HTTP server.

Give OSTree a name and add HTTP Server IP Address

Replace the variables given in vars/atomic.yml with OSTree name and HTTP Server IP Address.

For Instance:

# Variables for Atomic host
atomicname: my-atomic
httpserver: 192.168.122.1

Here my-atomic is OSTree name and 192.168.122.1 is HTTP Server IP Address.

Run Main Playbook

The following playbook installs requirements, starts HTTP Server, composes OSTree, performs SSH-setup and rebases on created Tree.

$ ansible-playbook main.yml --ask-sudo-pass

Check IP Address of the Atomic instance

The following command returns the IP Address of the running Atomic instance

$ sudo virsh domifaddr atomic-node

Reboot

Now SSH to the Atomic Host and reboot it so that it can reboot in to the created OSTree:

$ ssh atomic-user@<atomic-hostIP>
$ sudo systemctl reboot

Verify: SSH to the Atomic Host

Wait for 10 minutes, You may want to go for a Coffee now.

$ ssh atomic-user@192.168.122.221
[atomic-user@atomic-node ~]$ sudo rpm-ostree status
State: idle
Deployments:
● my-atomic:fedora-atomic/25/x86_64/docker-host
       Version: 25.1 (2017-02-07 05:34:46)
        Commit: 15b70198b8ec7fd54271f9672578544ff03d1f61df8d7f0fa262ff7519438eb6
        OSName: fedora-atomic

  fedora-atomic:fedora-atomic/25/x86_64/docker-host
       Version: 25.51 (2017-01-30 20:09:59)
        Commit: f294635a1dc62d9ae52151a5fa897085cac8eaa601c52e9a4bc376e9ecee11dd
        OSName: fedora-atomic

Now you have the Updated Tree.

Shout-Out for the following folks:

My future post will have customizing packages (includes addition/deletion) for OSTree.

Talking to Docker daemon of Fedora Atomic Host

This post is now deprecated, Please follow the more enhanced one: http://www.projectatomic.io/blog/2017/01/remote-access-docker-daemon

This post will describe how to use Docker daemon of Fedora Atomic host remotely.  Note that we are also going to secure the Docker daemon since we are connecting via Network which we will be doing with TLS.

TLS (Transport Layer Security) provides communication security over computer network. We will create client cert and server cert to secure our Docker daemon. OpenSSL will be used to to create the cert keys for establishing TLS connection.

I am using Fedora Atomic host as remote and workstation as my present host.

Thanks to Chris Houseknecht for writing an Ansible role which creates all the certs required automatically, so that there is no need to issue openssl commands manually. Here is the Ansible role repository: https://github.com/ansible/role-secure-docker-daemon. Clone it to your present working host.

$ mkdir secure-docker-daemon
$ cd secure-docker-daemon
$ git clone https://github.com/ansible/role-secure-docker-daemon.git
$ touch ansible.cfg inventory secure-docker-daemon.yml
$ ls 
ansible.cfg  inventory  role-secure-docker-daemon  secure-docker-daemon.yml

$ vim ansible.cfg
[defaults]
inventory=inventory
remote_user='USER_OF_ATOMIC_HOST'

$ vim inventory 
[serveratomic]
'IP_OF_ATOMIC_HOST' ansible_ssh_private_key_file='PRIVATE_KEY_FILE'

$ vim secure-docker-daemon.yml
---
- name: Secure Docker daemon for Atomic host
  hosts: serveratomic
  gather_facts: no
  become: yes
  roles:
    - role: role-secure-docker-daemon
      dds_host: 'IP_OF_ATOMIC_HOST'
      dds_server_cert_path: /etc/docker
      dds_restart_docker: no

Replace ‘USER_OF_ATOMIC_HOST’ with the user of your Atomic host, ‘IP_OF_ATOMIC_HOST’ with the IP of your Atomic host, ‘PRIVATE_KEY_FILE’ with the ssh private key file of your workstation.

Now we will run the ansible playbook. This will create client and server certs on the Atomic host.

$ ansible-playbook secure-docker-daemon.yml

Now ssh to your Atomic host.

We will copy the client certs created on the Atomic host to the workstation. You will find the client certs file in ~/.docker directory as root user. Now create ~/.docker directory on your workstation for regular user and copy the client certs there. You can use scp to copy the cert files from Atomic host to Workstation or do it manually ;-).

We are going to append some Environment variables in the ~/.bashrc file of the workstation for regular user.

$ vim ~/.bashrc
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=~/.docker/
export DOCKER_HOST=tcp://IP_OF_ATOMIC_HOST:2376

Docker’s port is 2376 for TLS (secured port).

Now go your Atomic host. We will add tls options to docker command on atomic host.

Add –tlsverify –tlscacert=/etc/docker/ca.pem –tlscert=/etc/docker/server-cert.pem –tlskey=/etc/docker/server-key.pem -H=0.0.0.0:2376 -H=unix:///var/run/docker.sock in the /etc/sysconfig/docker file.

$ vi /etc/sysconfig/docker
OPTIONS='--selinux-enabled --log-driver=journald --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem -H=0.0.0.0:2376 -H=unix:///var/run/docker.sock'

We will need to reload and restart the docker daemon.

$ sudo systemctl docker-reload
$ sudo systemctl restart docker.service

Reboot both of your Atomic host and Workstation.

So now if you try running any docker command as regular user on your workstation it will talk to the docker daemon of the Atomic host and execute the command there. You do not need to manually ssh and issue docker command on your Atomic host :-).

Here are some screenshots for demonstration:

Atomic Host:

screenshot-from-2016-12-09-10-27-47

screenshot-from-2016-12-09-10-29-46

screenshot-from-2016-12-09-10-26-31

Workstation:

fotoflexer_photo

screenshot-from-2016-12-09-10-26-35

 

Containerization and Deployment of Application on Atomic Host using Ansible Playbook

This article describes how to build Docker image and deploy containerized application on Atomic host (any Remote host) using Ansible Playbook.

Building Docker image for an application and run container/cluster of containers is nothing new. But the idea is to automate the whole process and this is where Ansible playbooks come in to play.

Note that you can use Cloud/Workstation based Image to execute the following task. Here I am issuing the commands on Fedora Workstation.

Let’s see How to automate the containerization and deployment process for a simple Flask application:

We are going to deploy container on Fedora Atomic host.

First, Let’s Create a simple Flask Hello-World Application.

This is the Directory structure of the entire Application:

flask-helloworld/
├── ansible
│   ├── ansible.cfg
│   ├── inventory
│   └── main.yml
├── Dockerfile
└── flask-helloworld
    ├── hello_world.py
    ├── static
    │   └── style.css
    └── templates
        ├── index.html
        └── master.html

hello_world.py

from flask import Flask, render_template

APP = Flask(__name__)

@APP.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    APP.run(debug=True, host='0.0.0.0')

static/style.css

body {
  background: #F8A434;
  font-family: 'Lato', sans-serif;
  color: #FDFCFB;
  text-align: center;
  position: relative;
  bottom: 35px;
  top: 65px;
}
.description {
  position: relative;
  top: 55px;
  font-size: 50px;
  letter-spacing: 1.5px;
  line-height: 1.3em;
  margin: -2px 0 45px;
}

templates/master.html

<!doctype html>
<html>
<head>
    {% block head %}
    <title>{% block title %}{% endblock %}</title>
    {% endblock %}
    												<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    												<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
    												<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
    												<link href='http://fonts.googleapis.com/css?family=Lato:400,700' rel='stylesheet' type='text/css'>

</head>
<body>
<div id="container">
    {% block content %}
    {% endblock %}</div>
</body>
</html>

templates/index.html

{% extends "master.html" %}

{% block title %}Welcome to Flask App{% endblock %}

{% block content %}
<div class="description">

Hello World</div>
{% endblock %}

Let’s write the Dockerfile.

FROM fedora
MAINTAINER Trishna Guha<tguha@redhat.com>

RUN dnf -y update && dnf -y install python-flask python-jinja2 && dnf clean all
RUN mkdir -p /app

COPY files/ /app/
WORKDIR /app

ENTRYPOINT ["python"]
CMD ["hello_world.py"]

Now we will work on Ansible playbook for our application that deals with the automation part:

Create inventory file:

[atomic]
IP_ADDRESS_OF_HOST ansible_ssh_private_key_file=<'PRIVATE_KEY_FILE'>

Replace IP_ADDRESS_OF_HOST with the IP address of the atomic/remote host and ‘PRIVATE_KEY_FILE’ with your private key file.

Create ansible.cfg file:

[defaults]
inventory=inventory
remote_user=USER

[privilege_escalation]
become_method=sudo
become_user=root

Replace USER with the user of your remote host.

Create main.yml file:

---
- name: Deploy Flask App
  hosts: atomic
  become: yes

  vars:
    src_dir: [Source Directory]
    dest_dir: [Destination Directory]

  tasks:
    - name: Create Destination Directory
      file:
       path: "{{ dest_dir }}/files"
       state: directory
       recurse: yes

    - name: Copy Dockerfile to host
      copy:
       src: "{{ src_dir }}/Dockerfile"
       dest: "{{ dest_dir }}"

    - name: Copy Application to host
      copy:
       src: "{{ src_dir }}/flask-helloworld/"
       dest: "{{ dest_dir }}/files/"

    - name: Make sure that the current directory is {{ dest_dir }}
      command: cd {{ dest_dir }}

    - name: Build Docker Image
      command: docker build --rm -t fedora/flask-app:test -f "{{ dest_dir }}/Dockerfile" "{{ dest_dir }}"

    - name: Run Docker Container
      command: docker run -d --name helloworld -p 5000:5000 fedora/flask-app:test
...

Replace [Source Directory] in src_dir field in main.yml with your /path/to/src_dir of your current host.

Replace [Destination Directory] in dest_dir field in main.yml with your /path/to/dest_dir of your remote atomic host.

Now simply run $ ansible-playbook main.yml :).  To verify if the application is running issue this command $ curl http://localhost:5000 on your atomic/remote host.

You can also manage your containers running on remote host using Cockpit. Check this article to know how to use Cockpit to manage your containers: https://fedoramagazine.org/deploy-containers-atomic-host-ansible-cockpit

fotoflexer_photo

screenshot-from-2016-10-21-18-52-45

Here is the repository of the above example:  https://github.com/trishnaguha/fedora-cloud-ansible/tree/master/examples/flask-helloworld

My future post will be related to ansible-container where I will describe how we can build Docker image and orchestrate container without writing any Dockerfile :).

Run commands on Fedora Atomic host from Remote host using Ansible

This post will show how to run commands on your atomic host from remote.

I am using Fedora Atomic host. Boot up your atomic instance. Make your you have Ansible installed on your control host.

The user of fedora instance is “fedora” by default and there is no password authentication. So first we will need to create password on the atomic for user “fedora”.

For that type the following command. It will ask for new password.

$ passwd

Now we will need to change PasswordAuthentication to YES . Open /etc/ssh/sshd_config on atomic host and change PasswordAuthentication to YES. Now The atomic host is all set :).

Go to your Remote host/Control host. I am using Fedora Workstation.

Now we need to generate ssh key on our control host.

Type the following command. This will create ssh key(private and public) on your host. The default location is of public key is ~/.ssh/id_rsa.pub.

$ ssh-keygen

It is time to add the ssh key to the Atomic host.
Type the following command. This will add your ssh public key to .ssh/authorized_keys on atomic host.

$ ssh-copy-id username@IPofAtomicHost

Now we will create inventory and config file for Ansible.

$ mkdir test && cd test
$ touch inventory
$ touch ansible.cfg

Inside the inventory file add the following:

[atomic]
IP-of-Atomic-Host

Inside the ansible.cfg file add the following:

[default]
inventory=inventory

Now let’s ping the atomic host :).

$ ansible atomic -i inventory -m ping

If the above returns Success we will try to run command on atomic host from our remote host :).
Type the following to run command on your atomic host.

$ ansible atomic -i inventory -m command -a "sudo atomic host upgrade"

 

NOTE: If you have you atomic instance running on Openstack make sure to add icmp to the security groups of the instance.

fotoflexer_photo1

fotoflexer_photo

IRC Client: Irssi On Atomic Host

If you are a terminal geek you will always want to do things using terminal ;). And when it comes to Atomic host, YES you will have to do stuffs using terminal.

If you don’t know about Atomic, you must visit http://www.projectatomic.io 🙂

This post will describe how to setup and use IRC client on Atomic host. This will be applicable for any Cloud host also.

Irssi is a terminal based IRC client for Unix/Linux systems. And the best part is we will not need to setup things manually because we have containers :).

Let’s Get Stared:

I am using Fedora Atomic host here. Get Fedora atomic host from herehttps://getfedora.org/en/cloud/download/atomic.html

Make Sure you have Docker installed.

Copy the Dockerfile from here: https://github.com/trishnaguha/Fedora-Dockerfiles/blob/irssi/irssi/Dockerfile

Now run docker build -t username/irssi .This will build image.

There after you just need to run the container 🙂  docker run -it username/irssi.

Later on sometime you will be able to do the whole set up only docker run -it fedora/irssi once Fedora adds Irssi to its Docker hub :).

After you start the container you will see something like this:

Screenshot from 2016-08-19 14-12-05

Let’s join a channel

Screenshot from 2016-08-19 14-14-16

You will find the Irssi Commands here: Irssi Commands.

Cockpit Container on Atomic Host

Screenshot from 2016-08-16 17-42-05

Cockpit is a remote manager for GNU/Linux servers.

  • Cockpit is a server manager that makes it easy to administer your GNU/Linux servers via a web browser.
  • Cockpit makes it easy for any sysadmin to perform simple tasks, such as administering storage, inspecting journals and starting and stopping services.
  • Jumping between the terminal and the web tool is no problem. A service started via Cockpit can be stopped via the terminal. Likewise, if an error occurs in the terminal, it can be seen in the Cockpit journal interface.
  • You can monitor and administer several servers at the same time. Just add them with a single click and your machines will look after its buddies.

The Cockpit team is currently uploading the cockpit container to the Fedora repo on the Docker Hub, but Fedora Release Engineering is working on publishing layered images. We now have a super-privileged container (SPC) for the web service (cockpit-ws) with the bridge, shell, and docker components installed by default on the Atomic host.

This means you can simply run atomic run fedora/cockpitws as root or with sudo and cockpit will be running on port 9090. Try it :).

Getting Started

Boot up Fedora Atomic instance.

Install the Container

Install cockpitws container using atomic.

# atomic install fedora/cockpitws
/usr/bin/docker run -ti --rm --privileged -v /:/host fedora/cockpitws /container/atomic-install
+ sed -e /pam_selinux/d -e /pam_sepermit/d /etc/pam.d/cockpit
+ mkdir -p /host/etc/cockpit/ws-certs.d
+ chmod 755 /host/etc/cockpit/ws-certs.d
+ chown root:root /host/etc/cockpit/ws-certs.d
+ mkdir -p /host/var/lib/cockpit
+ chmod 775 /host/var/lib/cockpit
+ chown root:wheel /host/var/lib/cockpit
+ /bin/mount --bind /host/etc/cockpit /etc/cockpit
+ /usr/sbin/remotectl certificate --ensure

There’s a few things going on here in the install method.

Note that we’re exposing the Atomic host root directory to the container at /host. As a SPC (Super Privileged Container), this allows the container to access the host filesystem and make changes. The install method creates a set of directories in /etc and /var to persist configs. This means that we don’t need any particular cockpitws container to stick around, any cockpitws container will be able to read the appropriate state from the host. We can upgrade the cockpit image and not worry about losing data. Since/etc and /var are writable on an Atomic host, and /etc content will be appropriately merged on a tree change, cockpit data will also survive an atomic host upgrade as well.

Set up the systemd unit

# vi /etc/systemd/system/cockpitws.service

[Unit]
Description=Cockpit Web Interface
Requires=docker.service
After=docker.service

[Service]
Restart=on-failure
RestartSec=10
ExecStart=/usr/bin/docker run --rm --privileged --pid host -v /:/host --name %p fedora/cockpitws /container/atomic-run --local-ssh
ExecStop=-/usr/bin/docker stop -t 2 %p

[Install]
WantedBy=multi-user.target

With the container available to docker, we’ll build the systemd unit file next. For local systemd unit files, we want them to reside in /etc/systemd/system.

The ExecStart line in the unit file looks nearly identical to the RUN label, with one change. When running containers from systemd, we don’t want to use docker -d, instead we want either docker -a or docker --rm. We’re using docker --rm here since we don’t need this particular container instance to survice a restart. We are going to name container using the %p tag to pick up the systemd service name, just to make it easier to find in docker ps.

Start the Service

Now we can reload systemd to read the new unit file, enable the service to start on reboot, and then start the new cockpitws service.

  # systemctl daemon-reload
  # systemctl enable cockpitws.service
  Created symlink from /etc/systemd/system/multi-user.target.wants/cockpitws.service to /etc/systemd/system/cockpitws.service.
  # systemctl start cockpitws.service
  # systemctl status cockpitws.service

  ● cockpitws.service - Cockpit Web Interface
  Loaded: loaded (/etc/systemd/system/cockpitws.service; enabled; vendor preset: disabled)
  Active: active (running) since Tue 2016-08-16 12:42:23 UTC; 10s ago
Main PID: 2047 (docker)
   Tasks: 6 (limit: 512)
  Memory: 0B
     CPU: 1ms
  CGroup: /system.slice/cockpitws.service
          └─2047 /usr/bin/docker run --rm --privileged --pid host -v /:/host --name cockpitws fedora/cockpitws /container/atomic-run --local-ssh

  Aug 16 12:42:25 atomic.novalocal docker[2047]: + sed -e /pam_selinux/d -e /pam_sepermit/d /etc/pam.d/cockpit
  Aug 16 12:42:25 atomic.novalocal docker[2047]: + mkdir -p /host/etc/cockpit/ws-certs.d
  Aug 16 12:42:25 atomic.novalocal docker[2047]: + chmod 755 /host/etc/cockpit/ws-certs.d
  Aug 16 12:42:25 atomic.novalocal docker[2047]: + chown root:root /host/etc/cockpit/ws-certs.d
  Aug 16 12:42:25 atomic.novalocal docker[2047]: + mkdir -p /host/var/lib/cockpit
  Aug 16 12:42:25 atomic.novalocal docker[2047]: + chmod 775 /host/var/lib/cockpit
  Aug 16 12:42:25 atomic.novalocal docker[2047]: + chown root:wheel /host/var/lib/cockpit
  Aug 16 12:42:25 atomic.novalocal docker[2047]: + /bin/mount --bind /host/etc/cockpit /etc/cockpit
  Aug 16 12:42:25 atomic.novalocal docker[2047]: + /usr/sbin/remotectl certificate --ensure
  Aug 16 12:42:25 atomic.novalocal docker[2047]: INFO: cockpit-ws: Using certificate: /etc/cockpit/ws-certs.d/0-self-signed.cert

Now that the service is up and running, point your web browser at port 9090 on the Atomic host and you should see the Cockpit login page. You’ll need to log in with a user in the wheel group in order to administrate the system, but you can log in as any user to view the local host. For the published Fedora Atomic cloud image, log in with the fedora credentials and you should be ready to go. You can login as root user. For that You need to setup password for root user in your atomic instance. After that you need to change PasswordAuthentication to yes in /etc/ssh/sshd_config and you are ready to go.

You can add other hosts to this Cockpit instance, with the knowledge that reboots and upgrades to the host or the container won’t affect the configuration.

Note that if you are using Openstack you need to add Port 9090 in your security group.

I just started Cockpit container on atomic host yesterday.

Here is the screenshot of the containers running.

Screenshot from 2016-08-17 11-30-22

Getting Started with Atomic Commands

Project Atomic is a framework to create OS from RHEL, CentOS, Fedora and the aim of Project Atomic is to create better OS for containers.

Why Atomic?

  • For running containers we don’t need full fledged distribution.
  • Less number of packages to maintain

rpm-ostree is a software management tool that combines the features of both traditional RPMs and OSTree. we can be way more confident on updating system if we know that we can have reliable rollback even after updating system. It provides clear transaction for updates. Since the whole process is atomic there is almost no chance o half way update of the system hence less chance of breaking system.

The atomic command defines the entrypoint for Project Atomic hosts.

On Atomic hosts there are two software delivery vehicles:

  • rpm-ostree for managing deployment and updates of host system.
  • Docker to provide containers running services and applications.

RPM-OSTree makes the file-system immutable i.e, read only except var and etc. Docker uses /var/lib/docker where all the docker related files, images are stored. /etc has all the configuration files.

Atomic Command: Let’s get Started!

We will first need to have an atomic host running.

  • atomic host upgrade will upgrade to a newer version.
  • atomic host rollback will rollback to the previous version.
  • atomic host status displays the status of the atomic host installed.
  • atomic run <name> allows an image provider how a container image expects to be run.
  • atomic install <name> installs a container on atomic host with systemd unit file to run it as service.
  • atomic uninstall <name> uninstalls the container from atomic host.
  • atomic info <name> displays LABEL information of the image.
  • atomic images lists the container images on your Atomic host.

When we ship an application you need to run an install script. Using Atomic tool management system we can embed install and uninstall script within our application itself. In the Dockerfile of our application we need to have LABEL INSTALL that points to the docker command for the application with executable install script. When we execute atomic install it will specifically run LABEL INSTALL command from the Dockerfile to install the application on atomic host.
Same way to uninstall an application we need to run atomic uninstall that will specifically run LABEL UNINSTALL from Dockerfile which specifically points to the uninstall script for the application.

For further reading regarding Install and Uninstall: http://www.projectatomic.io/docs/usr-bin-atomic

Atomic Command Cheat Sheet is now available.

BeFunky Collage

Further Reading:

 

How to Convert NetworkManager to networkd

This post will describe how to convert NetworkManager to networkd.

I am using Fedora Workstation 24 image. If you are using fedora or projectatomic cloud images you can use networkd there.

Switching from NetworkManager to networkd:

We need to make sure that NetworkManager and networkd don’t start on reboot.

# systemctl disable NetworkManager
# systemctl disable network

Now Ensure that systemd-networkd starts on the next boot:

# systemctl enable systemd-networkd

Enable the resolver and make a symlink:

# systemctl enable systemd-resolved
# systemctl start systemd-resolved
# rm -f /etc/resolv.conf
# ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

Configure your network interfaces in /etc/systemd/network and then reboot.

Some sample use cases for systemd-networkd and example configurations are below:

Simple DHCP on single interface

For an interface eth0, a single .network file is needed

# cat /etc/systemd/network/eth0.network
[Match]
Name=eth0

[Network]
DHCP=yes

Bridging

Here we have eth0 and we want to add it to a bridge. This could be handy for servers where you want to build containers or virtual machines and attach them to the network bridge.

We will start with setting up bridge interface br0.

# cat /etc/systemd/network/br0.netdev
[NetDev]
Name=br0
Kind=bridge

Let’s configure the network for the bridge

# cat /etc/systemd/network/br0.network
[Match]
Name=br0

[Network]
IPForward=yes
DHCP=yes

The IPForward=yes will take care of the systemctl forwarding setting for us (net.ipv4.conf.br0.forwarding = 1) automatically when the interface comes up.
Now take ethernet adapter and add it to bridge

# cat /etc/systemd/network/eth0.network
[Match]
Name=eth0

[Network]
Bridge=br0

Now reboot the system and it will come up with eth0 as a port on br0.

Bonding

Let’s configure a bonding interface which is similar to that of a bridge. Start by setting up individual network adapters.

# cat /etc/systemd/network/ens9f0.network
[Match]
Name=ens9f0
 
[Network]
Bond=bond1
# cat /etc/systemd/network/ens9f1.network
[Match]
Name=ens9f1

[Network]
Bond=bond1

Create network device for the bond

# /etc/systemd/network/bond1.netdev
[NetDev]
Name=bond1
Kind=bond

[Bond]
Mode=802.3ad
TransmitHashPolicy=layer3+4
MIIMonitorSec=1s
LACPTransmitRate=fast

Add networking to the device

# /etc/systemd/network/bond1.network
[Match]
Name=bond1
 
[Network]
DHCP=yes
BindCarrier=ens9f0 ens9f1

The BindCarrier is optional but recommended. It gives systemd-networkd the hint that if both bonded interfaces are offline, it should remove the bond configuration until one of the interfaces comes up again.

Check Status

Output from systemd-netword will appear in system journal. The networkctl command allows to check your network devices at a glance.

Here’s an example of the network setup we just created:

Screenshot from 2016-08-09 14-31-17

Further Reading: http://fedoracloud.readthedocs.io/en/latest/networkd.html