zoukankan      html  css  js  c++  java
  • linux(centos8):使用namespace做资源隔离

    一,namespace是什么?

    namespace 是 Linux 内核用来隔离内核资源的方式。
    它是对全局系统资源的封装隔离,
    处于不同 namespace 的进程拥有独立的全局系统资源,
    改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程,
    对其他 namespace 中的进程没有影响
     
    每个namespace下的资源对于其他namespace下的资源是透明的,不可见的。
    从操作系统角度看,可以出现多个相同pid的进程,
    由于它们属于不同的namespace,所以进程之间并不冲突。
    从用户角度看,只能看到属于用户自己namespace下的资源,
    例如:ps命令只能列出自己namespace下的进程。
     

    说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

             对应的源码可以访问这里获取: https://github.com/liuhongdi/

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,namespace的用途?

    当前linux内核中提供了7类namespace,分别用于:
     
    Cgroup   :Cgroup 根目录 
    IPC        :System V IPC/POSIX 消息队列 
    Network :网络设备/协议栈/端口
    Mount    :挂载点 
    PID        :进程ID 
    User      :用户和group ID 
    UTS       :Hostname和NIS域名
     

    三,查看一个进程所属的namespace

    1,得到一个nginx进程的id
    [root@blog ~]# ps auxfww | grep nginx:
    root       491  0.0  0.0  71028  3368 ?        Ss   May18   0:00 nginx: master process /usr/local/openresty/nginx/sbin/nginx
    nginx      492  0.0  0.0 102496  7036 ?        S    May18   0:00  \_ nginx: worker process
    nginx      493  0.0  0.0 102764  7496 ?        S    May18   0:00  \_ nginx: worker process
    nginx      494  0.0  0.0 102496  5856 ?        S    May18   0:00  \_ nginx: worker process
    …
    我们选择492这个进程
     
    2,查看492这个进程的namespace
    [root@blog ~]# ls /proc/492/ns/
    cgroup  ipc  mnt  net  pid  pid_for_children  user  uts
     
    3,这些namespace文件的类型是符号链接
    [root@blog ns]# ll /proc/492/ns/
    total 0
    lrwxrwxrwx 1 nginx nginx 0 Jun 15 13:32 cgroup -> 'cgroup:[4026531835]'
    lrwxrwxrwx 1 nginx nginx 0 Jun 15 13:32 ipc -> 'ipc:[4026531839]'
    lrwxrwxrwx 1 nginx nginx 0 Jun 15 13:32 mnt -> 'mnt:[4026532277]'
    lrwxrwxrwx 1 nginx nginx 0 Jun 15 13:32 net -> 'net:[4026531992]'
    lrwxrwxrwx 1 nginx nginx 0 Jun 15 13:32 pid -> 'pid:[4026531836]'
    lrwxrwxrwx 1 nginx nginx 0 Jun 15 13:32 pid_for_children -> 'pid:[4026531836]'
    lrwxrwxrwx 1 nginx nginx 0 Jun 15 13:32 user -> 'user:[4026531837]'
    lrwxrwxrwx 1 nginx nginx 0 Jun 15 13:32 uts -> 'uts:[4026531838]’
    链接文件的内容的格式为 xxx:[inode number]。
     xxx 是 namespace 的类型,
    inode number 用来标识一个 namespace,
     

    四,查看一个进程的mnt namespace信息 

    1,mnt namespace的挂载点信息,记录在下面的3个文件中
    [root@blog ns]# ll /proc/492/mount*
    -r--r--r-- 1 nginx nginx 0 Jun 13 23:23 /proc/492/mountinfo
    -r--r--r-- 1 nginx nginx 0 Jun 13 23:23 /proc/492/mounts
    -r-------- 1 nginx nginx 0 Jun 13 23:23 /proc/492/mountstats
    mnt namespace的作用:隔离mount point,
    每个mnt namespace内的文件结构可以单独进行修改,互不影响
     
    2,我们做一个试验验证mnt namespace:
    先创建两个目录,下面各创建一个文件:
    [root@localhost ~]# mkdir /root/hosta
    [root@localhost ~]# touch /root/hosta/a.txt
    [root@localhost ~]# mkdir /root/hostb
    [root@localhost ~]# touch /root/hostb/b.txt 
    查看当前的mnt目录:
    [root@localhost ~]# ls /mnt
    hgfs
    新开启两个终端:
    在终端a中进行如下操作:
    创建新的mount namespace和uts namespace,并运行bash
    [root@localhost ~]# unshare --mount --uts bash
    修改主机名为hosta
    [root@localhost ~]# hostname hosta && exec bash
    查看当前进程中mnt和uts两个namespace的inode number
    #$$:当前的进程id
    [root@hosta ~]# readlink /proc/$$/ns/{mnt,uts}
    mnt:[4026532774]
    uts:[4026532775]
    挂载hosta目录到mnt下
    [root@hosta ~]# mount --bind hosta/ /mnt/
    [root@hosta ~]# ls /mnt
    a.txt
    3,回到最早的localhost终端中查看:
    [root@localhost ~]# ls /mnt
    hgfs
    /mnt目录下的内容没有变,说明localhost终端与 hosta终端的mount namespace是成功隔离的
     
    在终端b中进行以下操作:
    创建新的mount namespace和uts namespace,并运行bash
    [root@localhost ~]# unshare --mount --uts bash
    修改主机名为hostb
    [root@localhost ~]# hostname hostb && exec bash
    查看当前进程中mnt和uts两个namespace的inode number
    #$$:当前的进程id
    [root@hostb ~]# readlink /proc/$$/ns/{mnt,uts}
    mnt:[4026532706]
    uts:[4026532707]
    挂载hostb目录到mnt下
    [root@hostb ~]# mount --bind hostb/ /mnt/
    [root@hostb ~]# ls /mnt
    b.txt

    五,测试pid namespace

    #—fork:以unshare的子进程来启动bash
    [root@localhost ~]# unshare --pid --uts --mount --fork bash
    修改hostname,作为标识
    [root@localhost ~]# hostname hosta && exec bash
    [root@hosta ~]# echo $$
    1
    当前的进程id是1
    #-p:显示pid
    #-l: 显示长的行(不按COLUMNS这个环境变量去截取宽度)
    [root@hosta ~]# pstree -pl
    systemd(1)─┬─ModemManager(871)─┬─{ModemManager}(911)
               │                   └─{ModemManager}(924)
               ├─NetworkManager(867)─┬─dhclient(993)
               │                     ├─{NetworkManager}(915)
               │                     └─{NetworkManager}(925)
    …
    用pstree可以看到:pid为1的进程是systemd
    这是因为这里的proc是unshare给带来的mount namespace的/proc
    包括查看ns下的inode number也是如此,
    [root@hosta ~]# readlink /proc/$$/ns/{pid,uts,mnt}
    pid:[4026531836]
    uts:[4026531838]
    mnt:[4026531840]
    需要重新挂载/proc
    [root@hosta liuhongdi]# mount --types proc proc /proc/
    [root@hosta liuhongdi]# pstree -pl
    bash(1)───pstree(70)
    说明:如果用unshare启动bash时,加 --mount-proc 参数,则不需要重新挂载/proc
     
    再次查看ns下的inode number,也可以正确显示了
    [root@hosta liuhongdi]# readlink /proc/$$/ns/{pid,uts,mnt}
    pid:[4026532779]
    uts:[4026532778]
    mnt:[4026532777]
     

    六,查看linux的版本:

    [root@node1 ~]# more /etc/redhat-release
    CentOS Linux release 8.1.1911 (Core)
    [root@node1 ~]# uname -r
    4.18.0-147.el8.x86_64 
  • 相关阅读:
    网页 js 获取DPI pxTomm
    利用自定义属性实现js点击事件 委托
    鼠标移动div时禁止选中div中的文字的方法
    关于if简写语句优化的方法
    .clearfix::after(清除浮动)
    js 事件委托
    清空共享池
    oracle中scott用户权限不足
    安装完Oracle 12C数据库,scott账户过期,解锁方法
    Vulnhub靶场-Me Tomcat Host 学习笔记
  • 原文地址:https://www.cnblogs.com/architectforest/p/13131307.html
Copyright © 2011-2022 走看看