0% found this document useful (0 votes)
63 views65 pages

Lab Manual

Uploaded by

midhulasrikj3053
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
63 views65 pages

Lab Manual

Uploaded by

midhulasrikj3053
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

DOCKER:

What is Docker?

Docker is a tool that helps you:

●​ Package your applications with all dependencies (like libraries, frameworks, etc.) into a
container.
●​ Run your applications consistently across different environments (your PC, cloud, servers).
●​ Make deployment faster and more reliable.

Why Use Docker?

Imagine you're building an app, and it works perfectly on your PC. But when you run it on another PC or
server, it fails because of different software versions or missing libraries.

Docker solves this problem by packaging your app with everything it needs into a container, ensuring it
works anywhere.

Types of Docker Components We'll Use:

1.​ Docker Engine – Core part of Docker that runs containers.


2.​ Docker CLI (Command-Line Interface) – Used to manage containers and images.
3.​ Docker Compose – Helps manage multi-container applications.

Step-by-Step Docker Installation

Here’s exactly what to do in your Ubuntu environment.

I'll explain each command so you know why it's needed.

Step 1: Update Your Ubuntu

This ensures your package list is up to date.


bash
sudo apt update​
sudo apt upgrade -y

Explanation:

●​ sudo apt update – Refreshes the list of available packages.


●​ sudo apt upgrade -y – Updates all installed packages to the latest versions.

Step 2: Install Required Dependencies

Run this to install tools Docker needs.

bash
sudo apt-get install -y \​
ca-certificates \​
curl \​
gnupg \​
lsb-release

Explanation:

●​ ca-certificates – Ensures your system trusts secure websites.


●​ curl – A tool to download files from the internet.
●​ gnupg – Adds support for verifying digital signatures.
●​ lsb-release – Helps your system identify your Linux distribution.

Step 3: Add Docker’s GPG Key and Repository

The GPG key ensures you download the official Docker packages securely.

bash
sudo mkdir -p /etc/apt/keyrings​
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o
/etc/apt/keyrings/docker.gpg​

Explanation:

●​ mkdir -p /etc/apt/keyrings – Creates a directory to store the Docker key.


●​ curl -fsSL – Downloads Docker’s GPG key.
●​ gpg --dearmor – Converts the key into a readable format.

Next, add the Docker repository:

bash
echo \​
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg]
https://download.docker.com/linux/ubuntu \​
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null​

Explanation:​
This command tells your system where to download Docker from.

Step 4: Install Docker Engine

Now, install Docker.

bash
sudo apt update​
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin
docker-compose-plugin

Explanation:

●​ docker-ce – Docker Engine Community Edition.


●​ docker-ce-cli – Command-line tool to manage Docker.
●​ containerd.io – Core component to manage containers.
●​ docker-buildx-plugin – Allows building images efficiently.
●​ docker-compose-plugin – Helps manage multi-container apps.
Step 5: Start Docker Service

Start the Docker service to make it ready to use.

bash
sudo service docker start​

What is a Docker Image?

A Docker image is like a blueprint for your app. It contains:

●​ Your app’s code


●​ System libraries (e.g., Python, Java)
●​ Configuration files
●​ Operating system files

An image is used to create a container, which is a running instance of your app.

Think of an image as a template and a container as a running app.

Example to Understand Docker Image and Container

Imagine you have a game (app). To play it:

1.​ Docker Image = Game DVD (the blueprint)


2.​ Docker Container = Game running on your PC (a running instance)

You can make multiple containers from one image, like playing the same game on different PCs.

Why Use Docker Images?

Without Docker:

●​ You must manually install everything (Python, libraries, dependencies) on every system where
your app runs.
With Docker:

●​ You package everything into one image and run it anywhere without installing extra stuff.

How a Docker Image Works

1.​ You create a Dockerfile – A text file that tells Docker how to build the image

2.​ Docker builds the image from the Dockerfile.

3.​ You run a container from the image to use your app.

Simple Analogy:

Term Example
Dockerfile Recipe (instructions)
Docker Image Cake (template)
Docker Container Slice of cake (running app)

Objective: Build a Simple Docker Image for a Blockchain Concept

We'll use a very basic blockchain concept in Python, package it in a Docker image, and run it inside a
Docker container. This will help participants learn:

1.​ What a Docker image is


2.​ How to build and run a Docker container
3.​ How a simple blockchain works (without complex theory)
Step 1: Create a Simple Blockchain App (No Prior Knowledge Needed)

1.​ Create a project folder:

bash
mkdir simple-blockchain​
cd simple-blockchain

2.​ Create a Python file (blockchain.py):

bash
nano blockchain.py

Add this simple blockchain code:

Python

import hashlib​
import time​

class Block:​
def __init__(self, index, previous_hash, timestamp, data):​
self.index = index​
self.previous_hash = previous_hash​
self.timestamp = timestamp​
self.data = data​
self.hash = self.calculate_hash()​
def calculate_hash(self):​
return
hashlib.sha256(f"{self.index}{self.previous_hash}{self.timestamp}{self.data}".encode()).hexdigest()​

def create_genesis_block():​
return Block(0, "0", time.time(), "Genesis Block")​

def create_new_block(previous_block, data):​
return Block(previous_block.index + 1, previous_block.hash, time.time(), data)​

# Create the blockchain​
blockchain = [create_genesis_block()]​
print("Genesis Block created!")​

# Add a new block​
new_block = create_new_block(blockchain[-1], "This is the second block")​
blockchain.append(new_block)​
print(f"New Block Added: {new_block.index} with Hash: {new_block.hash}")​

Step 2: Create a Dockerfile

The Dockerfile tells Docker how to package your app.

1.​ Create a Dockerfile:

bash
nano Dockerfile​

2.​ Add the following content:

Dockerfile
# Use the official Python image​
FROM python:3.9​

# Set the working directory​
WORKDIR /app​

# Copy the current directory contents into the container​
COPY . .​

# Run the Python app​
CMD ["python", "blockchain.py"]
Step 3: Build the Docker Image

Run this command to build your Docker image:

bash
docker build -t simple-blockchain . →include space and dot at end of command

If you face the error , Fix: Grant Docker Permissions:and if you get error like unab

1.​ Add your user to the Docker group:


bash
sudo usermod -aG docker $USER

This command adds your user to the docker group, which has the necessary permissions to interact with
Docker.

2.​ Restart your session:


a.​ Log out and log back in, or you can use the following to refresh your group membership:
bash
newgrp docker​

3.​ Test Docker Access:

After doing this, try running the Docker command again:

bash
docker build -t simple-blockchain .

If you still encounter issues:

1.​ Check Docker Service:

Ensure that the Docker service is running:

bash
sudo systemctl start docker​

2.​ Verify Permissions:


Check the permissions of /var/run/docker.sock:

bash
ls -l /var/run/docker.sock

The permissions should show the docker group having read/write access. If not, you may need to adjust
the socket's permissions.

sudo chmod 777 /var/run/docker.sock

Using Buildx Specifically If you're using docker buildx build, ensure you specify the context:

bash

docker buildx build -t simple-blockchain .→include space and dot at end of command
Step 4: Run the Docker Container

Run your Docker container:

bash
docker run simple-blockchain

You’ll see output like this:

mathematical
Genesis Block created!​
New Block Added: 1 with Hash: a3f8e24f3f6a...

✅ To create a private Docker registry and push your blockchain image into it, follow these steps:
Step 1: Set Up Your Private Docker Registry

Step 1: Pull the registry Image

Manually pull the Docker Registry image from Docker Hub:

bash
docker pull registry:2​

Step 2: Start a Docker Registry Container

You can run a local Docker registry by using the official registry image:

bash
docker run -d -p 5000:5000 --name registry registry:2

if you see the, "Unable to find image 'registry:2' locally", means that Docker can't find the registry:2
image on your local machine, and it's trying to pull it from Docker Hub but is unable to.

Follow below steps:

Step 1: Pull the registry Image

Manually pull the Docker Registry image from Docker Hub:

bash
docker pull registry:2

This will download the latest version (2.x) of the Docker Registry image.

You should see the registry container listed.

If you face the error "Conflict. The container name '/registry' is already in use", which means that a
container with the name registry already exists.

To resolve this, you have two options:

Option 1: Remove the Existing Container

If you no longer need the existing container, you can remove it and then run the new one:

1.​ Stop the existing container:


bash
docker stop registry​

2.​ Remove the existing container:


bash
docker rm registry​

3.​ Now, start a new registry container:


bash
docker run -d -p 5000:5000 --name registry registry:2
Option 2: Use a Different Name for the New Container

If you want to keep the existing container and just start a new one with a different name, use a different
container name like my-registry:

bash
docker run -d -p 5000:5000 --name my-registry registry:2​

This will start the new registry container with the name my-registry instead of registry.

Step 2: Run the Registry

Once the image is pulled, you can run the Docker registry container:

bash

This starts a Docker registry that listens on port 5000 of your local machine.

2.​ Verify the Registry is Running

Check that the registry is running:

bash
docker ps

You should see a container named registry running.


Step 2: Tag the Image for Your Private Registry

Before you push your image to the private registry, you need to tag it with your registry's address.

1.​ Tag the Image

Assuming your image name is simple-blockchain, tag it like this:

bash
docker tag simple-blockchain localhost:5000/simple-blockchain

Here, localhost:5000 is your private registry (running on port 5000), and simple-blockchain is your image
name.

Step 3: Push the Image to Your Private Registry

Push the tagged image to the private registry:

bash
docker push localhost:5000/simple-blockchain​
This will upload the image to your local registry running at localhost:5000.

Step 4: Verify the Image is Pushed

You can verify that the image is in your registry by checking the registry API:

bash
curl http://localhost:5000/v2/simple-blockchain/tags/list​
This will show the tags associated with the simple-blockchain image.

Step 5: Pull the Image from Your Private Registry

On any machine that has access to your private registry, you can pull the image like this:

bash
docker pull localhost:5000/simple-blockchain

This will start the registry on port 5000 on your local machine.

Step 3: Verify the Registry

Make sure the registry container is running:


bash
docker ps​

You should see the registry container listed.

Command:

docker run -i -t ubuntu /bin/bash

This command is used to run an interactive Ubuntu container with a Bash shell.

Explanation of Flags:

●​ docker run creates and starts a new container.


●​ -i keeps the standard input (STDIN) open for interactive mode.
●​ -t allocates a pseudo-TTY (terminal) for the container.
●​ ubuntu specifies the Ubuntu image (Docker pulls it if not available locally).
●​ /bin/bash runs the Bash shell inside the container.
Steps to be followed:

1.​ Pull the Ubuntu image if not available using the command docker pull ubuntu.
2.​ Run the container with an interactive shell using docker run -i -t ubuntu /bin/bash.
3.​ After running the command, a shell prompt appears (root@container-id:/#), allowing Linux
commands to be executed inside the container.
4.​ To exit the container, type exit or press Ctrl + D.

Docker Basic Commands

1. Display Docker Version and Information

Command:

docker --version


Description: This command checks the installed Docker version. It confirms whether Docker is installed
and shows the currently installed version.

bash

docker info or docker version

Description: These commands provide system-wide information about Docker, including details such as
the number of running and stopped containers, total images, storage details, and system configurations.

2. List Docker Images

bash

docker image ls or docker images



Description: Displays a list of all Docker images available on the system. The output includes the
repository name, tag, image ID, creation date, and size.

3. Execute a Docker Image


bash

docker run <docker-image-name>


Description: This command creates and starts a container from the specified Docker image. If the image
is not available locally, Docker automatically pulls it from the default registry (Docker Hub) before
running the container.

4. List Running Docker Containers


To view only active containers:
bash
docker container ls
# OR
docker ps
5. List All Containers (Including Exited Containers)

To display both running and stopped containers:

bash

docker container ls --all

6. List Available Docker CLI Commands

To get a list of Docker commands:

bash

docker
For container-specific commands:

bash

docker container --help


7. Stop a Running Container

To stop a container, use its Container ID or Name:

bash

docker container stop <container_id>

# OR

docker stop <container_id>


8. Restarting a Docker Container

Docker provides a simple command to restart a running or stopped container.

i. Restart a Running or Stopped Container

To restart a container, use:

bash

docker restart <container_id>

or

bash

docker restart <container_name>


ii. Example

If you have a container named peer0.org2.example.com, restart it using:

bash

docker restart peer0.org2.example.com

or by its container ID:

bash

docker restart 787335fb6d9e

9. View Logs of a Docker Container

To check the logs of a running or stopped container:

bash

docker logs <container_id>


Running an Nginx Container and Port Mapping

1. Running an Nginx Container

To start an Nginx container in detached mode, use the following command:

bash

docker run -d --name web1 nginx

●​ -d → Runs the container in the background.


●​ --name web1 → Assigns the container a custom name web1.
●​ nginx → Uses the official Nginx image from Docker Hub.
2. Checking if Nginx is Running on the Host Machine

Even though the Nginx container is running, it does not expose its ports to the host by default. To check
if nginx is running inside the container:

bash

ps aux | grep nginx

This lists processes related to nginx.

3. Testing Nginx Without Port Mapping


Try accessing the Nginx default page:

bash

curl localhost:80

This will fail because port 80 is not exposed to the host.

4. Running an Nginx Container with Port Mapping

To make Nginx accessible from the host machine, use port mapping:

bash

docker run -d --name web2 -p 8080:80 nginx

●​ -p 8080:80 → Maps port 80 of the container to port 8080 on the host.


●​ Now, Nginx will be accessible at localhost:8080.

5. Checking Connectivity

Verify if Nginx is reachable after running web2:

bash

curl localhost:8080

This should return the Nginx Welcome Page HTML.


Creating a Docker Image

This section outlines the standard method for creating a Docker image, following best practices.

1. Create a Working Directory

First, create a directory to store the Dockerfile:

bash

mkdir mydockerimage

cd mydockerimage

2. Create a Dockerfile
A Dockerfile defines the structure of the image. Create it using:

bash

nano Dockerfile

Insert the following content:

dockerfile

# Use an official Ubuntu base image

FROM ubuntu:latest

# Set image metadata

LABEL maintainer="[email protected]"

# Update system packages and install curl

RUN apt-get update && apt-get install -y curl

# Set a default command for the container

CMD ["echo", "Hello, this is a standardized Docker image."]

Save and exit.

3. Build the Docker Image

Execute the following command:

bash

docker build -t myimage .

●​ -t myimage → Assigns the image name as myimage.


●​ . → Uses the current directory as the build context.
4. Verify the Image

To confirm the image was created successfully:

bash

docker images
5. Run a Container from the Image

Execute a container based on the image:

bash

docker run myimage

To run in detached mode:

bash

docker run -d --name mycontainer myimage

To check running containers:


bash

docker ps

6. Stopping and Removing Containers

To stop a running container:

bash

docker stop mycontainer

To remove a stopped container:

bash

docker rm mycontainer
7. Removing the Docker Image (Optional)

To delete the image if no longer needed:

bash

docker rmi myimage

Ensure no containers are using it:

bash

docker ps -a

Summary of commands:

Step Command Description

1 mkdir mydockerimage && cd mydockerimage Creates a working directory.

2 nano Dockerfile Creates and edits the Dockerfile.


3 docker build -t myimage . Builds a new Docker image.

4 docker images Lists available images.

5 docker run myimage Runs a container from the image.

6 docker ps -a Lists all containers (running and


stopped).

7 docker stop mycontainer Stops a running container.

8 docker rm mycontainer Removes a stopped container.

9 docker rmi myimage Deletes the Docker image.

Running a Container with Automatic Removal and Monitoring Docker Events

1. Running a Container with the --rm Flag

The --rm flag ensures that a container is automatically removed after it stops.

Command:

bash

docker run -d --rm --name webhello myimage


Explanation:

●​ -d → Runs the container in detached mode (background).


●​ --rm → Automatically removes the container after it stops.
●​ --name webhello → Assigns a name to the container.
●​ myimage → Uses the custom image you created (myimage).

2. Checking Container Persistence With and Without --rm

i. Run a container without --rm:

bash

docker run -d --name webhello myimage

ii. List all containers (including stopped ones):

bash

docker ps -a
The container remains in the list even after stopping it.

iii. Run the same container with --rm:

Bash

Fix: Remove the Existing Container

Stop and Remove the Container Manually

bash

docker stop webhello

docker rm webhello

Then, run the command again:

bash
docker run -d --rm --name webhello myimage

iv. Check again with:

bash

docker ps -a

Since --rm is used, the container disappears after stopping because it gets automatically removed.

3. Monitoring Docker System Events


Docker provides a command to track system-level events in real time.

Command:

bash

docker system events

This continuously displays events such as:

●​ Container start/stop
●​ Image pulls/removals
●​ Network changes
●​ Volume actions

The docker system events command runs in real time and only shows new events as they happen. If
nothing is happening in Docker, the command will appear unresponsive.

Let's test it:

Open two terminal windows:

1.​ In Terminal 1, start monitoring Docker events:

bash

docker system events

2.​ In Terminal 2, trigger some Docker actions, such as:

bash

docker run -d --rm --name testcontainer nginx

docker stop testcontainer

docker rmi myimage

After running these commands in Terminal 2, you'll start seeing real-time events in Terminal 1.
If docker system events still shows nothing:

Make sure Docker is running:​


bash​
systemctl status docker

●​ Try restarting the Docker daemon:​


bash​
sudo systemctl restart docker

Terminal 1: system events


Terminal 2: Operation of commands

Namespaces in Docker

1. Introduction to Namespaces

Namespaces are a fundamental Linux kernel feature used by Docker to isolate processes. They ensure that
containers operate independently by providing a unique execution environment.

2. Types of Namespaces in Docker

Docker uses multiple namespaces to isolate containers from the host system:
Namespace Description

PID (Process ID) Isolates process IDs so that each container has its own process
space.

Network Provides each container with its own network stack (IP, routes,
etc.).

Mount Manages file system mount points, ensuring container-specific


mounts.

UTS (Unix Timesharing Allows containers to have independent hostnames and domain
System) names.

IPC (Inter-Process Enables process communication within the same container but
Communication) isolates it from other containers.

User Assigns different user IDs and group IDs inside the container,
enhancing security.

3. How Docker Uses Namespaces

●​ When a container starts, Docker automatically assigns it a new set of namespaces.


●​ This ensures isolation between the host and other containers.
●​ Docker allows limited sharing of namespaces for specific use cases (e.g., --pid=host for sharing
the host’s PID namespace).

4. Checking Namespaces in Docker

You can inspect namespaces using Linux commands:

List namespaces in the host system:​


sh​
lsns
●​ Check a container’s PID namespace:​
sh​
docker inspect --format '{{ .State.Pid }}' <container_id>

●​ View network namespaces:​


sh​
ls /var/run/netns/

5. Practical Example
You can test namespace isolation by running two containers and observing their process and network
isolation.

sh
docker run -d --name container1 alpine sleep 1000
docker run -d --name container2 alpine sleep 1000

Now, check if processes are isolated:

sh
docker exec container1 ps aux
docker exec container2 ps aux

Each container only sees its own processes.

6. Namespace Sharing in Docker

In some cases, containers may share namespaces:


●​ --network=host: Shares the host's network stack.
●​ --pid=host: Shares the host’s process space.
●​ --ipc=container:<id>: Shares IPC between two containers.

7.Check Namespace IDs of Each Container

Find the PID of a container and inspect its namespaces:

sh

CONTAINER_PID=$(docker inspect --format '{{ .State.Pid }}' container1)

ls -l /proc/$CONTAINER_PID/ns

These are Linux namespaces used by Docker to isolate containers. Each namespace provides a separate
execution environment for specific system resources.

1.​PID Namespace (Process Isolation)


●​ What it does:
○​ Isolates process IDs inside the container.
○​ A container sees only its own processes, not the host’s.
●​ Example:
○​ Run ps aux inside a container → You’ll see only container processes.
○​ On the host, use docker inspect --format '{{ .State.Pid }}' <container_id> to see the
container’s process mapped to the host.

2.​NET Namespace (Network Isolation)


●​ What it does:
○​ Provides each container with a separate network stack.
○​ Containers get their own IP address, routes, and interfaces.
●​ Example:
○​ docker exec <container> ip a shows container’s isolated network interfaces.
○​ Containers can have separate or shared networks (--network=host removes isolation).
❖​ Run an interactive shell inside the container:

sh

docker exec -it be46a6735c69 bash

❖​ Run a specific command inside the container:

sh

docker exec be46a6735c69 ls /

i. Check if You're Inside the Container

Run:

sh

hostname
This should return a different hostname than your host machine, confirming you’re inside the container.

ii. List Filesystem

Run:

sh

ls -l /
This lists the container’s root directory, separate from your host.

iii. Check Running Processes

Run:

sh

ps aux

You will see only the processes running inside the container, not the host’s processes.

iv. Install Packages (If Needed)

For Ubuntu containers, you may need to update first:

sh

apt update && apt install -y nano curl


This installs nano and curl inside the container.

v. Exit the Container

Simply type:

sh

exit

3.​IPC Namespace (Interprocess Communication Isolation)


●​ What it does:
○​ Isolates shared memory (SHM), message queues, and semaphores.
○​ Prevents one container from accessing IPC resources of another.
●​ Example:
○​ Inside a container, run ipcs → Shows only container’s IPC resources.
Check IPC resources inside a container:

sh

docker run -it --name ipc_test --ipc=private ubuntu bash

apt update && apt install -y iputils-ping

ipcs

Expected output: Only IPC resources within the container are listed.

Check IPC namespace of the container from the host:

sh

docker inspect --format '{{ .State.Pid }}' ipc_test

sudo ls -l /proc/<PID>/ns/ipc
Summary of Commands

Namespace Command Inside Command on Host


Container

IPC ipcs ls -l /proc/$(docker inspect --format '{{ .State.Pid }}'


ipc_test)/ns/ipc

MNT `mount grep root`

UTS hostname hostname

USER id id

4.​MNT Namespace (Filesystem Isolation)


●​ What it does:
○​ Gives each container a separate filesystem view.
○​ Changes in one container’s mount points don’t affect others.
●​ Example:
○​ mount | grep root inside a container → Shows isolated filesystem.

Each Docker container has its own filesystem using the MNT (mount) namespace, meaning
changes inside one container do not affect the host or other containers.

i. Check Mount Points Inside a Container

Run a container and check its mount points:

sh

docker run -it --name mnt_test ubuntu bash

mount | grep root

This shows the root filesystem mount inside the container.


Compare with the host:​
Run this outside the container (on the host):

sh

mount | grep root

➔​ The output should be different from the container's output.

ii. Check Container’s Mount Namespace from Host

Find the PID of the running container:

sh

docker inspect --format '{{ .State.Pid }}' mnt_test

➔​ Suppose it returns 26513, then check its mount namespace:

sh

sudo ls -l /proc/26513/ns/mnt
➔​ Expected output: A symlink showing the mount namespace.

iii. Verify Mount Namespace Isolation

Find all mount namespaces on the system:

sh

lsns | grep mnt

➔​ This lists all processes with separate mount namespaces.

Compare with the host’s mount namespace:

sh

readlink /proc/self/ns/mnt

readlink /proc/26513/ns/mnt
Summary of Commands

Command Where to Purpose


Run

`mount grep root` Inside the container

`mount grep root` On the host

docker inspect --format '{{ .State.Pid }}' mnt_test On the host Get container's process ID
(PID)

ls -l /proc/<PID>/ns/mnt On the host Check container's mount


namespace

`lsns grep mnt` On the host

readlink /proc/self/ns/mnt On the host Get the host’s mount namespace

readlink /proc/<PID>/ns/mnt On the host Get the container’s mount


namespace
5.​UTS Namespace (Hostname & Domain Isolation)
●​ What it does:
○​ Allows containers to have a different hostname from the host.
●​ Example:
○​ Run hostname inside a container → Shows a different name than hostname on the host.

i. Check Hostname Inside a Container

Run a container with a custom hostname:

sh

docker run -it --name uts_test --hostname=mycontainer ubuntu bash

Inside the container, check the hostname:

sh

hostname

➔​ Expected output: mycontainer (not the host’s hostname).

ii. Compare with the Host

Run this outside the container (on the host):

sh

hostname
➔​ Expected output: Host’s actual hostname, which should be different from the container.

iii. Check UTS Namespace from Host

Find the PID of the running container:

sh

docker inspect --format '{{ .State.Pid }}' uts_test

➔​ Suppose it returns 22410, then check the UTS namespace symlink:

sh

sudo ls -l /proc/26769/ns/uts

➔​ This confirms the container has its own UTS namespace.

Compare with the host’s UTS namespace:

sh

readlink /proc/self/ns/uts

readlink /proc/26769/ns/uts
Summary of Commands

Command Where to Run Purpose

hostname Inside the Shows container’s hostname


container

hostname On the host Shows the host’s hostname

docker inspect --format '{{ .State.Pid }}' uts_test On the host Get container’s PID

ls -l /proc/<PID>/ns/uts On the host Check container’s UTS


namespace

readlink /proc/self/ns/uts On the host Get host’s UTS namespace

readlink /proc/<PID>/ns/uts On the host Get container’s UTS


namespace

6.​USER Namespace (User ID Isolation)


●​ What it does:
○​ Allows containers to have different user/group IDs than the host.
○​ Improves security by mapping container root user to a non-root user on the host.
●​ Example:
○​ Inside a container, id shows different UID/GID values than on the host.

The USER namespace allows a container to have different user and group IDs from the host. This
improves security by preventing container root access from affecting the host system.

i. Check User ID Inside a Container

Run a new container and check UID/GID:

sh

docker run -it --rm --name user_test ubuntu bash


Inside the container, run:

sh

id

➔​ Expected output: Shows uid=0(root) gid=0(root), meaning the container has root privileges
inside itself but not on the host.

ii. Compare with the Host

Run the same command on the host:

sh

id

➔​ Expected output: Your actual host user ID, which is different from the container’s root.

Summary of Commands

Command Where to Run Purpose

id Inside the Shows container’s UID/GID


container

id On the host Shows host’s UID/GID

docker run --rm -it --user 1000:1000 ubuntu bash On the host Runs container as a non-root
user

docker inspect --format '{{ .State.Pid }}' user_test On the host Get container’s PID
ls -l /proc/<PID>/ns/user On the host Check container’s USER
namespace

readlink /proc/self/ns/user On the host Get host’s user namespace

readlink /proc/<PID>/ns/user On the host Get container’s user


namespace

iii. Check User Namespace Mapping

To run a user-mapped container, create one with a mapped UID/GID:

sh

docker run --rm -it --user 1000:1000 ubuntu bash

Inside the container, check:

sh

id
➔​ Expected output: uid=1000 gid=1000, meaning it runs as a non-root user inside the container.

iv. Check User Namespace on the Host

Find the container’s PID:

sh

docker inspect --format '{{ .State.Pid }}' user_test

➔​ Suppose it returns 27261, then check its USER namespace:

sh

sudo ls -l /proc/27261/ns/user

Compare with the host’s user namespace:

sh

readlink /proc/self/ns/user

readlink /proc/27261/ns/user
➔​ If different, the container has its own user namespace.
Summary of Commands

Command Where to Run Purpose

id Inside the Shows container’s UID/GID


container

id On the host Shows host’s UID/GID

docker run --rm -it --user 1000:1000 ubuntu bash On the host Runs container as a non-root
user

docker inspect --format '{{ .State.Pid }}' user_test On the host Get container’s PID

ls -l /proc/<PID>/ns/user On the host Check container’s USER


namespace

readlink /proc/self/ns/user On the host Get host’s user namespace

readlink /proc/<PID>/ns/user On the host Get container’s user


namespace
Namespace Purpose

PID Isolates process IDs

NET Provides a separate network stack

IPC Isolates shared memory & message queues

MNT Isolates the filesystem

UTS Separates hostnames & domain names

USER Separates user IDs & permissions

Control Groups (cgroups)

control groups cgroups limit and allocate resources cpu memory io etc for docker containers

i. Check cgroups on the host

list cgroups available on your system

sh
sudo ls /sys/fs/cgroup
expected output → displays different resource controllers cpu memory blkio etc

ii. Run a container with cpu limit

limit the container to 50 percent of a single cpu core

sh
docker run -it --rm --cpus="0.5" ubuntu bash

inside the container run

sh
cat /sys/fs/cgroup/cpu.max

expected output → 50000 half a cpu core

iii. Run a container with memory limit

limit the container to 256mb ram


sh
docker run -it --rm --memory="256m" ubuntu bash

inside the container check memory limits

sh
cat /sys/fs/cgroup/memory/memory.limit_in_bytes

expected output → 268435456 256mb in bytes

v. Verify cgroup configuration from the host

find the container pid

sh
docker inspect --format '{{ .State.Pid }}' container_id

suppose it returns 27261 check cgroup settings


sh
cat /proc/27261/cgroup

expected output → shows container’s cgroup assignments

vi. Run a container with cpu and memory limits together

limit to one cpu and 512mb ram

sh
docker run -it --rm --cpus="1" --memory="512m" ubuntu bash

verify inside the container

sh
cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
cat /sys/fs/cgroup/memory/memory.limit_in_bytes
Summary of commands

command where to run purpose

ls /sys/fs/cgroup on the host list available cgroups

docker run -it --rm --cpus="0.5" ubuntu bash on the host run a container with 50
percent cpu

cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us inside the show cpu limit


container

docker run -it --rm --memory="256m" ubuntu bash on the host run a container with
256mb ram

cat /sys/fs/cgroup/memory/memory.limit_in_bytes inside the show memory limit


container

docker inspect --format '{{ .State.Pid }}' container_id on the host get container pid

cat /proc/pid/cgroup on the host check cgroup settings

docker run -it --rm --cpus="1" --memory="512m" ubuntu on the host run a container with
bash both limits

You might also like