Slide 1

Slide 1 text

openSUSE® MicroOS Managing Pods & Containers Ish Sookun [email protected]

Slide 2

Slide 2 text

$ whoami Systems Architect I work for La Sentinelle Ltd (Mauritius). Linux & OSS Advocate I hangout during local meetups to talk about Linux (mostly). I blog at hacklog.in. I am currently in the Election Committee. I install openSUSE on as many machines as I can.

Slide 3

Slide 3 text

What is openSUSE MicroOS? openSUSE MicroOS is a modern single service Linux operating system, designed for container hosts and optimized for large deployments. It inherits the openSUSE Tumbleweed and SUSE Linux Enterprise knowledge while redefining the operating system into a small, efficient and reliable distribution. It is available as a separate distribution from: http://download.opensuse.org/tumbleweed/iso/

Slide 4

Slide 4 text

MicroOS Container Host System Role During installation select the “container host” system role. MicroOS comes with a minimal set of packages by default. The container host system role installs Podman as container runtime. A complete installation of the MicroOS Container host is about 1.3GiB. Note: Container tools such as Skopeo & Buildah are not installed. Those are not intended for server use.

Slide 5

Slide 5 text

Why not use Tumbleweed server directly?

Slide 6

Slide 6 text

MicroOS Highlights Read-only root file system Automated transactional-updates Podman/runc as default container runtime Rolling release

Slide 7

Slide 7 text

What are containers? Shared Linux kernel Resource and process isolation Lighter than virtual machines Portable across different environments

Slide 8

Slide 8 text

Linux namespaces

Slide 9

Slide 9 text

Overview of Linux namespaces A namespace wraps a global system resource in an abstraction that makes it appear to the processes within the namespace that they have their own isolated instance of the global resource. Changes to the global resource are visible to other processes that are members of the namespace, but are invisible to other processes. One use of namespaces is to implement containers. $ man namespaces Demo: $ sudo unshare -u /bin/bash Namespace Isolates Cgroup Cgroup root directory IPC System V IPC, Posix Message queues Network Network devices, stacks, ports, etc. Mount Mount points PID Process IDs User User and group IDs UTS Hostname and NIS domain name

Slide 10

Slide 10 text

Container runtimes Container runtimes can be categorized as being low-level or high-level. Low-level container runtimes would usually focus on just running containers, e.g runc. High-level container runtimes provide additional features, e.g manage images and containers. Nevertheless, running a container is often all that is required to call “something” a container runtime. ● containerd ● Docker ● Kata Containers ● LXD ● rkt ● runc ● Others… (Mentioned in alphabetical order)

Slide 11

Slide 11 text

Listing Linux namespaces The command lsns lists information about all the currently accessible namespaces or about the given namespace. Column Description NS Namespace identifier (inode number) TYPE Kind of namespace PATH Path to the namespace NPROCS Number of processes in the namespace PID Process ID PPID Parent Process ID USER Username of the PID COMMAND Command line of the PID

Slide 12

Slide 12 text

What is a container composed of?

Slide 13

Slide 13 text

Skopeo Skopeo is a command line utility used to interact with local and remote container images and container image registries. Skopeo can copy container images between various containers image stores, converting them as necessary. $ skopeo inspect docker://opensuse/leap $ mkdir nginx $ skopeo copy docker://nginx:latest dir:nginx $ tree nginx

Slide 14

Slide 14 text

Peeking further into the container image The container image contains several files among which are compressed layers containing files that provide the necessary environment for a running container. Not clear enough? Okay, fine. Let’s decompress one layer to see what it contains. $ mkdir b8f2 $ tar -C b8f2 -xf b8f262c62ec67f02536f49654de586c022043652bbb6bbf76a8dab1542627a8d $ ls -lh b8f2

Slide 15

Slide 15 text

Container Image Registries Before we experiment further with containers we need to understand a few basic things about registries. What happened when we ran the below command earlier? $ podman run --rm -d -p 8080:80 nginx Podman first checks whether there is a local image tagged “nginx” to spin a container from. If it is not present on the system it will look for it in some “remote location”, pull the image and then run the container. The action of pulling a container can be independent of running a container, e.g: $ podman pull nextcloud The remote location which we referred to is called a container registry. Local images can be listed by executing: $ podman images

Slide 16

Slide 16 text

Podman Podman (Pod Manager) is a fully featured container engine that is a simple daemonless tool. Podman provides a Docker-CLI comparable command line that eases the transition from other container engines and allows the management of pods, containers and images. Podman uses Buildah internally to create container images. Both tools share image (not container) storage, hence each can use or manipulate images (but not containers) created by the other. Simple demo: $ podman run --rm -d -p 8080:80 nginx $ curl localhost:8080

Slide 17

Slide 17 text

Where does Podman store container information? When running Podman as root, the default location for storage is /var/lib/containers/storage. Users cannot use this directory when running as non root, so Podman creates the storage by default in $HOME/.local/share/containers. $ podman info Running the above command produces an output displaying some key information about Podman configuration including the path to container storage.

Slide 18

Slide 18 text

Container Image Registries Information about image registries is stored in /etc/containers/registries.conf. It is a system-wide configuration file for container image registries. The file format is TOML. More information about the configuration can be found in the man page. $ man containers-registries.conf The most important thing about this config file is the specification of registry urls. [registries.search] registries = ["docker.io"] The above list contains urls of container registries where images will be searched and downloaded from. If the list contains more that one url they should be comma separated.

Slide 19

Slide 19 text

Podman flags $ podman run --rm -d --name webserver -h web \ -v /home/ish/summit2019:/usr/share/nginx/html \ -p 8080:80 nginx We are running a container based on the nginx image, having name as webserver and hostname set to web. It will map its port 80 to the host’s port 8080 and mount a volume to the path of the Nginx virtual host root directory. We can enter the container by executing the following. $ podman exec -it webserver bash The -it flags specify that STDIN should be kept open and a pseudo-TTY attached. You can experiment further with the different flags. $ podman run --help

Slide 20

Slide 20 text

Printing information about containers $ podman ps -a Displays all containers, default shows only running containers. $ podman ps -a -s Displays the total file size. $ podman ps --ns -a Displays namespace information. $ podman ps -a -p Displays the pods the containers are associated with.

Slide 21

Slide 21 text

Display a container or image's configuration $ podman inspect container_name This displays the low-level information on containers and images identified by name or ID. By default, this will render all results in a JSON array. $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/nginx latest f949e7d76d63 2 days ago 130 MB $ podman inspect f949e7d76d63

Slide 22

Slide 22 text

Podman as a Systemd service Podman wasn’t designed to manage containers start-up order or failed containers recovery. A Systemd unit file on the host can have the host automatically start, stop, check the status, and manage a container as a regular systemd service. We create a Systemd unit file in: /etc/systemd/system/webserver.service We then enable the service as follows: $ sudo systemctl enable webserver $ sudo systemctl start webserver [Unit] Description=Podman webserver After=network.target [Service] Type=simple Restart=always ExecStart=/usr/bin/podman run --rm -d --name webserver -h web -v /home/ish/summit2019:/usr/share/nginx/html -p 8080:80 nginx ExecStop=/usr/bin/podman stop webserver [Install] WantedBy=multi-user.target

Slide 23

Slide 23 text

Photo by Febiyan on Unsplash Break time! ☕

Slide 24

Slide 24 text

Understanding Pods The term pod originates from the Kubernetes project where a pod relates to a unit of deployment, i.e an instance of an application. A pod may contain a single or multiple containers. In a multi-container pod all the containers can communicate with each other over localhost since they share the same network namespace. An empty pod will contain one container by default which is called the “infra container”. $ podman pod create --name small-pod $ podman pod ps POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID 0173c61afadd small-pod Created About a minute ago 1 613f59088260 An infra container is a lightweight container used to coordinate the shared kernel namespace of a pod.

Slide 25

Slide 25 text

A quick note about conmon Conmon is a monitoring program and communication tool between podman and runc for a single container. $ podman ps -a --pod $ ps -ef `pidof conmon` Compare the output of the above commands to relate one conmon process for every running container.

Slide 26

Slide 26 text

Dockerfile A Dockerfile is a text file that contains instructions to build a container image. As the name suggests it was introduced by Docker. Podman supports Dockerfile. $ podman build --tag myapp:1.0 -f ./Dockerfile $ podman images The image will be available from the local images repository. Dockerfile Reference: https://docs.docker.com/engine/reference/builder/ FROM golang:latest COPY . /app RUN make /app CMD /app/hello_word Each instruction creates one layer: ● FROM creates a layer from the golang:latest Docker image. ● COPY adds files from your Docker client’s current directory. ● RUN builds your application with make. ● CMD specifies what command to run within the container.

Slide 27

Slide 27 text

Kubernetes YAML YAML is a reverse acronym for “YAML Ain’t Markup Language”. It is a human-readable text-based format for specifying configuration-type information. Kubernetes uses YAML configuration files to create resources such as pods, services and deployments. Create a YAML config from an existing pod: $ podman generate kube osas2019-pod > osas2019-pod.yml Create a pods from a YAML config file: $ podman play kube osas2019-pod.yml More about YAML configuration sets for Kubernetes Pod resources can be found at: https://kubernetes.io/docs/tasks/configure-pod-container apiVersion: v1 kind: Pod metadata: labels: app: osas2019 name: osas2019-pod spec: containers: - command: - nginx - -g - daemon off; image: docker.io/library/nginx:latest name: nginx ports: - containerPort: 80 hostPort: 8080 protocol: TCP resources: {} securityContext: allowPrivilegeEscalation: true capabilities: {} privileges: false readOnlyRootFilesystem: false workingDir: / status: {}

Slide 28

Slide 28 text

Buildah Buildah is a command line tool that facilitates building OCI container images. What can we do with Buildah? ● Create a working container, either from scratch or using an image as a starting point. ● Mount a working container's root filesystem for manipulation. ● Unmount a working container's root filesystem. ● Use the updated contents of a container's root filesystem as a filesystem layer to create a new image. ● Delete a working container or an image. ● Rename a local container.

Slide 29

Slide 29 text

Buildah Create a working container for your project $ buildah from opensuse Copy your files and set an entrypoint. $ buildah copy opensuse-working-container app /app $ buildah copy opensuse-working-container entrypoint.sh /opt/entrypoint.sh $ buildah config --entrypoint “/app/entrypoint.sh” opensuse-working-container Finally, commit your work and the container image should be available in your local image repo. $ buildah commit opensuse-working-container myapp:1.0 $ buildah images

Slide 30

Slide 30 text

Terima kasih Thank you Merci धन्यवाद Feel free to send your questions to [email protected].