nsenter
root@pc-01:~# docker ps | grep busybox 807e1730775a busybox "sh" 5 hours ago Up 5 hours optimistic_hermann root@pcl-01:~# docker inspect 807e1730775a -f '{{.State.Pid}}' 2781180 root@pc-01:~# nsenter --target 2781180 --mount --uts --ipc --net --pid root@pc-01:/# ls bin boot dev etc home lib lost+found media mnt opt proc root run sbin snap srv sys tmp usr var root@pcl-01:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: tap0_kata: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UNKNOWN group default qlen 1000 link/ether c2:03:51:46:a8:8b brd ff:ff:ff:ff:ff:ff 136: eth0@if137: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever root@pc-01:/# exit logout root@pc-01:~# docker exec -it 807e1730775a sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000 link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe11:2/64 scope link valid_lft forever preferred_lft forever / #
Linux containers and namespaces
To demonstrate the namespaces managing a container, I'll use Podman to create a container from the UBI8:8.2 image from Red Hat Container Catalog. The container resides on a Red Hat Enterprise Linux (RHEL) 8.2 host. For the purpose of this article, the procps-ng package is installed inside the container, which provides top and ps commands.
[root@workshop ~]# podman run --name namespace-demo -it registry.access.redhat.com/ubi8/ubi /bin/bash
In another terminal, use the runc command to determine the process id associated with the new container.
[root@workshop ~]# runc list
ID PID STATUS BUNDLE CREATED OWNER
92585ccfd2d20c4bc7f03863d9b0a999eea18c91fb76f6333ef21171138beb83 7172 running /var/lib/containers/storage/overlay-containers/92585ccfd2d20c4bc7f03863d9b0a999eea18c91fb76f6333ef21171138beb83/userdata 2020-06-24T14:56:37.895046979Z root
The process id is 7172.
Use the lsns command to list the namespaces associated with a given process.
[root@workshop ~]# lsns -p 7172
NS TYPE NPROCS PID USER COMMAND
4026531835 cgroup 137 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 16
4026531837 user 137 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 16
4026532438 net 1 7172 root /bin/bash
4026532516 mnt 1 7172 root /bin/bash
4026532517 uts 1 7172 root /bin/bash
4026532518 ipc 1 7172 root /bin/bash
4026532519 pid 1 7172 root /bin/bash
Inspect the namespaces with nsenter
The nsenter command expands to namespace enter. It accepts different options to only enter the specified namespace.
Let's enter the network namespace to check the IP address and route table.
[root@workshop ~]# nsenter -t 7172 -n ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether ea:95:99:52:13:56 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.88.0.6/16 brd 10.88.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::e895:99ff:fe52:1356/64 scope link
valid_lft forever preferred_lft forever
Here, -t is the target process id, and -n refers to the network namespace.
[root@workshop ~]# nsenter -t 7172 -n ip route
default via 10.88.0.1 dev eth0
10.88.0.0/16 dev eth0 proto kernel scope link src 10.88.0.6
Next, I enter the process namespace to check the process details.
[root@workshop ~]# nsenter -t 7172 -p -r ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 14:56 pts/0 00:00:00 /bin/bash
root 135 0 0 16:55 ? 00:00:00 ps -ef
The -r option sets the root directory to the top-level directory within the namespace so that the commands run in the context of the namespace.
[root@workshop ~]# nsenter -t 7172 -p -r top
The bash command, which executes during podman run, is the first process inside the namespace.
Enter the UTC namespace to check the hostname.
[root@workshop ~]# nsenter -t 7172 -u hostname
92585ccfd2d2
Modify the hostname within the namespace and verify the new name.
[root@workshop ~]# nsenter -t 7172 -u hostname namespace.enable.sysadmin
[root@workshop ~]# nsenter -t 7172 -u hostname
namespace.enable.sysadmin
Finally, enter all namespaces by using the -a option.
[root@workshop ~]# nsenter -t 7172 -a
[root@namespace /]# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 7.9G 6.3G 1.6G 80% /
tmpfs 64M 0 64M 0% /dev
tmpfs 1.9G 1.4M 1.9G 1% /etc/hosts
shm 63M 0 63M 0% /dev/shm
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
tmpfs 1.9G 0 1.9G 0% /proc/acpi
tmpfs 1.9G 0 1.9G 0% /proc/scsi
tmpfs 1.9G 0 1.9G 0% /sys/firmware
tmpfs 1.9G 0 1.9G 0% /sys/fs/selinux
Summary
Linux containers help with rapid application delivery and the use of DevOps practices. It is essential to make sure that those applications are secure, isolated, and resource-restricted. The nsenter tool helps you understand the low-level details of a container. It also helps with troubleshooting issues with container orchestration and deployment.

浙公网安备 33010602011771号