Introduction
I'm starting a new series of posts about container and VM specific API's and tools in the Linux operating system. These posts reflect some of the work I'm doing systematically exploring the containerization and virtualization options natively available in the Linux kernel. I will also explore some APIs and tools built on top of these functionalities.
In the first post here we look at creating a simple namespace and then using that namespace to modify some resource in that namespace.
Namespaces
Namespaces are one of the fundamental concepts available in new Linux kernels which support isolation of resources. A namespace wraps a global system resource, and provides isolated access to it.
Each namespace (NS) type is linked to a specific resource type. There are several NS types available in the linux kernel, and more might be added in the future.
For further reading on namespaces refer to the namespaces(7) manpage
UTS Namespace
UTS stands for "Unix Time Sharing". It is a legacy name from the early days of Unix. The UTS resource contains two items node/host name and domain name. Thus the UTS namespace which isolates this resource is one of the simplest namespaces available. A process in a UTS namespace can change the host name and domain name in that namespace without changing these values in the parent namespace or any other namespace in the system.
Example
The two scripts below demonstrate creating a new UTS namespace and changing hostname inside the newly created namespace. The namespace in the "initial" or "parent" namespace remains unchanged.
exp.sh
- This is the main script for this demo
- It just creates a new UTS namespace using
unshare -u
where-u
is for UTS. - And executes another script called
change_hostname_in_ns.sh
in the new NS. - After executing the change hostname script, it prints out the hostname in the current namespace - demonstrating that the script in the separate namespace did not change the parent/initial namespace.
#!/bin/bash
echo "--------------------------------------"
echo "NOTE: this script uses sudo"
echo "--------------------------------------"
echo -e "readlink of UTS namespace of this process, prints inode of UTS NS"
readlink /proc/$$/ns/uts
echo "--------------------------------------"
echo "change UTS NS of newly created process"
echo "--------------------------------------"
sudo unshare -u bash ./change_hostname_in_ns.sh
echo "--------------------------------------"
echo "hostname unchanged in initial UTS NS"
hostname
echo "--------------------------------------"
change_hostname_in_ns.sh
- This script shows the PID of the current process.
- Then shows the uts ns of the current process showing it is different from the parent.
- It then prints the hostname, changes it and prints it again.
- The script demonstrates that it is able to set a new hostname.
#!/bin/bash
echo -e "\t> hint: \$\$ expands to PID of current shell"
echo -e "\t> current shell PID = $$"
echo -e "\t> list namespaces of current shell process"
ls /proc/$$/ns
echo -e "\t> readlink of UTS namespace of this process, prints inode of UTS NS"
readlink /proc/$$/ns/uts
echo -e "\t> hostname unchanged, but namespace changed"
hostname
echo -e "\t> change hostname now..."
hostname exp001
echo -e "\t> now hostname is changed..."
hostname
Sample run
Here's a sample run from the above script...
$ ./exp.sh
--------------------------------------
NOTE: this script uses sudo
--------------------------------------
readlink of UTS namespace of this process, prints inode of UTS NS
uts:[4026531838]
--------------------------------------
change UTS NS of newly created process
--------------------------------------
[sudo] password for abhishek:
> hint: $$ expands to PID of current shell
> current shell PID = 2096
> list namespaces of current shell process
cgroup mnt pid time user
ipc net pid_for_children time_for_children uts
> readlink of UTS namespace of this process, prints inode of UTS NS
uts:[4026532187]
> hostname unchanged, but namespace changed
localhost
> change hostname now...
> now hostname is changed...
exp001
--------------------------------------
hostname unchanged in initial UTS NS
localhost
--------------------------------------
Usage
There are several scripts which do useful things based on the hostname or domain name of the host. It is possible with namespaces to isolate those programs and run them with a different hostname/domainname pair without having any impact on the other parts of the running system.