编程技术分享平台

网站首页 > 技术教程 正文

Docker系列06—如何理解Docker的NameSpace机制

xnh888 2024-10-16 17:40:15 技术教程 26 ℃ 0 评论

1 NameSpace技术概述

Linux NameSpace是一种Linux Kernel提供的资源隔离方案,系统可以为进程分配不同的NameSpace,并保证不同的NameSpace资源独立分配、进程间彼此隔离,即不同的NameSpace下的进程互不干扰。

Linux内核提供了6种namespace隔离的系统调用,不提NameSpace隔离的对象不同,下边列出了NameSpace隔离的资源以及引入该NameSpace的Kernel版本。

1)Pid NameSpace:不同用户的进程就是通过Pid NameSpace隔离开的,并且不同的NameSpace中可以有相同的Pid,每个NameSpace中的Pid实现了相互隔离。

2)Network NameSpace:其实现了网络隔离,每个Network NameSpace有独立的Network device,IP address,IP routing tables和/proc/net目录。

3)IPC NameSpace:容器中进程交互还是采用Linux常见的进程间交互方法IPC,包括常见的信号量、消息队列和共享内存,容器的进程间交互实际上还是主机上具有相同Pid NameSpace中的进程间交互,因此需要在IPC资源申请时加入NameSpace信息,每个IPC资源有一个唯一的32位ID。

4)MNT NameSpace:允许不同NameSpace的进程看到的文件结构不同,这样每个NameSpace中的进程所看到的文件目录就被隔离开了,每个MNT NameSpace都有自己的根挂载点。

5)UTS NameSpace:允许每个容器拥有独立的hostname和domain name,使其在网络上可以被视作一个独立的节点,而非主机的的进程。

6)User NameSpace:每个容器可以有不同的user和group ID,也就是说可以在容器中用容器内部用户执行程序,而非主机上的用户。

那么如何理解主机上不同NameSpace之间的关系呢?主机的NameSpace是进程号为1的那个进程所在的NameSpace,也就是systemd,一般用户的进程都是运行在主机的NameSpace中,当systemd这个1号进程fork一个新的进程时,可以将这个新进程放到一个新的NameSpace中,这样不同NameSpace中的进程就实现了互相隔离,如下图所示。

比如在同一主机上的不同的NameSpace进程,通过Network NameSpace隔离机制,可以拥有自己独立的IP地址、网卡等网络信息。

NameSpace的常用操作

启动一个Nginx的测试容器

# docker run --name nginx-test1 -p 8080:80 -d nginx

查看容器的ID

# docker ps |grep nginx

6244dcfd3a40 nginx "nginx -g 'daemon of…"

查看容器的进程ID

# docker inspect 6244dcfd3a40 |grep -i pid

"Pid": 17602,
"PidMode": "",
"PidsLimit": 0,

通过进程ID查看容器的NameSpace

# ls -la /proc/17602/ns

total 0
dr-x--x--x 2 root root 0 Feb 27 07:56 .
dr-xr-xr-x 9 root root 0 Feb 27 07:56 ..
lrwxrwxrwx 1 root root 0 Feb 27 07:57 ipc -> ipc:[4026532491]
lrwxrwxrwx 1 root root 0 Feb 27 07:57 mnt -> mnt:[4026532489]
lrwxrwxrwx 1 root root 0 Feb 27 07:56 net -> net:[4026532494]
lrwxrwxrwx 1 root root 0 Feb 27 07:57 pid -> pid:[4026532492]
lrwxrwxrwx 1 root root 0 Feb 27 07:57 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Feb 27 07:57 uts -> uts:[4026532490]

通过进程ID,进入容器Network NameSpace,查看其网络信息。

# nsenter -t 17602 -n ip add

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
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
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

NameSpace的练习

在一个shell窗口中fork一个新的namespace,并在这个namespace中运行sleep 60。

# unshare -fn sleep 60

打开另一个shell窗口,查看进程信息

# ps -ef|grep sleep

root 17789 17739 0 08:14 pts/0 00:00:00 unshare -fn sleep 60
root 17790 17789 0 08:14 pts/0 00:00:00 sleep 60
root 17795 17761 0 08:15 pts/1 00:00:00 grep --color=auto sleep

查看网络NameSpace,找到unshare隶属的NameSpace

# lsns -t net

NS TYPE NPROCS PID USER COMMAND
4026532494 net 3 17602 root nginx: master process nginx -g daemon off
4026532557 net 2 17789 root unshare -fn sleep 60

进入该进程所在 Namespace 查看网络配置,与主机是不一致的

# nsenter -t 17789 -n ip a

1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

NameSpace机制小结

namespace其实很简单,它在fork进程的时候或者系统调用时,可以把进程的namespace改掉,比如上边的例子,就是在fork一个新进程的时候创建了一个新的网络namespace,这样就把这个新的进程放到了一个新的环境,实现了通过namespace隔离进程的效果。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表