Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Docker±³ºóµÄÄÚºË֪ʶ¡ªNamespace×ÊÔ´¸ôÀë
 
×÷ÕߣºË。²¨ À´Ô´£ºInfoQ ·¢²¼ÓÚ 2015-04-13
  2197  次浏览      27
 

DockerÕâô»ð£¬Ï²»¶¼¼ÊõµÄÅóÓÑ¿ÉÄÜÒ²»áÏ룬Èç¹ûÒª×Ô¼ºÊµÏÖÒ»¸ö×ÊÔ´¸ôÀëµÄÈÝÆ÷£¬Ó¦¸Ã´ÓÄÄЩ·½ÃæÏÂÊÖÄØ£¿Ò²ÐíÄãµÚÒ»·´Ó¦¿ÉÄܾÍÊÇchrootÃüÁÕâÌõÃüÁî¸øÓû§×îÖ±¹ÛµÄ¸Ð¾õ¾ÍÊÇʹÓúó¸ùĿ¼/µÄ¹ÒÔØµãÇл»ÁË£¬¼´Îļþϵͳ±»¸ôÀëÁË¡£È»ºó£¬ÎªÁËÔÚ·Ö²¼Ê½µÄ»·¾³Ï½øÐÐͨÐźͶ¨Î»£¬ÈÝÆ÷±ØÈ»ÐèÒªÒ»¸ö¶ÀÁ¢µÄIP¡¢¶Ë¿Ú¡¢Â·Óɵȵȣ¬×ÔÈ»¾ÍÏëµ½ÁËÍøÂçµÄ¸ôÀ롣ͬʱ£¬ÄãµÄÈÝÆ÷»¹ÐèÒªÒ»¸ö¶ÀÁ¢µÄÖ÷»úÃûÒÔ±ãÔÚÍøÂçÖбêʶ×Ô¼º¡£Ïëµ½ÍøÂ磬˳Æä×ÔÈ»¾ÍÏ뵽ͨÐÅ£¬Ò²¾ÍÏëµ½Á˽ø³Ì¼äͨÐŵĸôÀë¡£¿ÉÄÜÄãÒ²Ïëµ½ÁËȨÏÞµÄÎÊÌ⣬¶ÔÓû§ºÍÓû§×éµÄ¸ôÀë¾ÍʵÏÖÁËÓû§È¨Ï޵ĸôÀë¡£×îºó£¬ÔËÐÐÔÚÈÝÆ÷ÖеÄÓ¦ÓÃÐèÒªÓÐ×Ô¼ºµÄPID,×ÔȻҲÐèÒªÓëËÞÖ÷»úÖеÄPID½øÐиôÀë¡£

ÓÉ´Ë£¬ÎÒÃÇ»ù±¾ÉÏÍê³ÉÁËÒ»¸öÈÝÆ÷ËùÐèÒª×öµÄÁùÏî¸ôÀ룬LinuxÄÚºËÖоÍÌṩÁËÕâÁùÖÖnamespace¸ôÀëµÄϵͳµ÷Óã¬ÈçϱíËùʾ¡£

±í namespaceÁùÏî¸ôÀë

ʵ¼ÊÉÏ£¬LinuxÄÚºËʵÏÖnamespaceµÄÖ÷ҪĿµÄ¾ÍÊÇΪÁËʵÏÖÇáÁ¿¼¶ÐéÄ⻯£¨ÈÝÆ÷£©·þÎñ¡£ÔÚͬһ¸önamespaceϵĽø³Ì¿ÉÒÔ¸ÐÖª±Ë´ËµÄ±ä»¯£¬¶ø¶ÔÍâ½çµÄ½ø³ÌÒ»ÎÞËùÖª¡£ÕâÑù¾Í¿ÉÒÔÈÃÈÝÆ÷ÖеĽø³Ì²úÉú´í¾õ£¬·Â·ð×Ô¼ºÖÃÉíÓÚÒ»¸ö¶ÀÁ¢µÄϵͳ»·¾³ÖУ¬ÒÔ´Ë´ïµ½¶ÀÁ¢ºÍ¸ôÀëµÄÄ¿µÄ¡£

ÐèҪ˵Ã÷µÄÊÇ£¬±¾ÎÄËùÌÖÂÛµÄnamespaceʵÏÖÕë¶ÔµÄ¾ùÊÇLinuxÄÚºË3.8¼°ÆäÒÔºóµÄ°æ±¾¡£½ÓÏÂÀ´£¬ÎÒÃǽ«Ê×ÏȽéÉÜʹÓÃnamespaceµÄAPI£¬È»ºóÕë¶ÔÕâÁùÖÖnamespace½øÐÐÖðÒ»½²½â£¬²¢Í¨¹ý³ÌÐòÈÃÄãÇ×Éí¸ÐÊÜÒ»ÏÂÕâЩ¸ôÀëЧ¹û£¨²Î¿¼×Ôhttp://lwn.net/Articles/531114/£©¡£

1. µ÷ÓÃnamespaceµÄAPI

namespaceµÄAPI°üÀ¨clone()¡¢setns()ÒÔ¼°unshare()£¬»¹ÓÐ/procϵIJ¿·ÖÎļþ¡£ÎªÁËÈ·¶¨¸ôÀëµÄµ½µ×ÊÇÄÄÖÖnamespace£¬ÔÚʹÓÃÕâЩAPIʱ£¬Í¨³£ÐèÒªÖ¸¶¨ÒÔÏÂÁù¸ö³£ÊýµÄÒ»¸ö»ò¶à¸ö£¬Í¨¹ý|£¨Î»»ò£©²Ù×÷À´ÊµÏÖ¡£Äã¿ÉÄÜÒѾ­ÔÚÉÏÃæµÄ±í¸ñÖÐ×¢Òâµ½£¬ÕâÁù¸ö²ÎÊý·Ö±ðÊÇCLONE_NEWIPC¡¢CLONE_NEWNS¡¢CLONE_NEWNET¡¢CLONE_NEWPID¡¢CLONE_NEWUSERºÍCLONE_NEWUTS¡£

£¨1£©Í¨¹ýclone()´´½¨Ð½ø³ÌµÄͬʱ´´½¨namespace

ʹÓÃclone()À´´´½¨Ò»¸ö¶ÀÁ¢namespaceµÄ½ø³ÌÊÇ×î³£¼û×ö·¨£¬ËüµÄµ÷Ó÷½Ê½ÈçÏ¡£

int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg);

clone()ʵ¼ÊÉÏÊÇ´«Í³UNIXϵͳµ÷ÓÃfork()µÄÒ»ÖÖ¸üͨÓõÄʵÏÖ·½Ê½£¬Ëü¿ÉÒÔͨ¹ýflagsÀ´¿ØÖÆÊ¹ÓöàÉÙ¹¦ÄÜ¡£Ò»¹²ÓжþÊ®¶àÖÖCLONE_*µÄflag£¨±ê־룩²ÎÊýÓÃÀ´¿ØÖÆclone½ø³ÌµÄ·½·½ÃæÃ棨ÈçÊÇ·ñÓ븸½ø³Ì¹²ÏíÐéÄâÄÚ´æµÈµÈ£©£¬ÏÂÃæÍâÃæÖðÒ»½²½âcloneº¯Êý´«ÈëµÄ²ÎÊý¡£

²ÎÊýchild_func´«Èë×Ó½ø³ÌÔËÐеijÌÐòÖ÷º¯Êý¡£

²ÎÊýchild_stack´«Èë×Ó½ø³ÌʹÓõÄÕ»¿Õ¼ä

²ÎÊýflags±íʾʹÓÃÄÄЩCLONE_*±ê־λ

²ÎÊýargsÔò¿ÉÓÃÓÚ´«ÈëÓû§²ÎÊý

ÔÚºóÐøµÄÄÚÈÝÖн«»áÓÐʹÓÃclone()µÄʵ¼Ê³ÌÐò¿É¹©´ó¼Ò²Î¿¼¡£

£¨2£©²é¿´/proc/[pid]/nsÎļþ

´Ó3.8°æ±¾µÄÄں˿ªÊ¼£¬Óû§¾Í¿ÉÒÔÔÚ/proc/[pid]/nsÎļþÏ¿´µ½Ö¸Ïò²»Í¬namespaceºÅµÄÎļþ£¬Ð§¹ûÈçÏÂËùʾ£¬ÐÎÈç[4026531839]Õß¼´ÎªnamespaceºÅ¡£

$ ls -l /proc/$$/ns         <<-- $$ ±íʾӦÓõÄPID
total 0
lrwxrwxrwx. 1 mtk mtk 0 Jan 8 04:12 ipc -> ipc:[4026531839]
lrwxrwxrwx. 1 mtk mtk 0 Jan 8 04:12 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 mtk mtk 0 Jan 8 04:12 net -> net:[4026531956]
lrwxrwxrwx. 1 mtk mtk 0 Jan 8 04:12 pid -> pid:[4026531836]
lrwxrwxrwx. 1 mtk mtk 0 Jan 8 04:12 user->user:[4026531837]
lrwxrwxrwx. 1 mtk mtk 0 Jan 8 04:12 uts -> uts:[4026531838]

Èç¹ûÁ½¸ö½ø³ÌÖ¸ÏòµÄnamespace±àºÅÏàͬ£¬¾Í˵Ã÷ËûÃÇÔÚͬһ¸önamespaceÏ£¬·ñÔòÔòÔÚ²»Í¬namespaceÀïÃæ¡£/proc/[pid]/nsµÄÁíÍâÒ»¸ö×÷ÓÃÊÇ£¬Ò»µ©Îļþ±»´ò¿ª£¬Ö»Òª´ò¿ªµÄÎļþÃèÊö·û£¨fd£©´æÔÚ£¬ÄÇô¾ÍËãPIDËùÊôµÄËùÓнø³Ì¶¼ÒѾ­½áÊø£¬´´½¨µÄnamespace¾Í»áÒ»Ö±´æÔÚ¡£ÄÇÈçºÎ´ò¿ªÎļþÃèÊö·ûÄØ£¿°Ñ/proc/[pid]/nsĿ¼¹ÒÔØÆðÀ´¾Í¿ÉÒÔ´ïµ½Õâ¸öЧ¹û£¬ÃüÁîÈçÏ¡£

# touch ~/uts
# mount --bind /proc/27514/ns/uts ~/uts

Èç¹ûÄã¿´µ½µÄÄÚÈÝÓë±¾ÎÄËùÃèÊöµÄ²»·û£¬ÄÇô˵Ã÷ÄãʹÓõÄÄÚºËÔÚ3.8°æ±¾ÒÔǰ¡£¸ÃĿ¼Ï´æÔÚµÄÖ»ÓÐipc¡¢netºÍuts£¬²¢ÇÒÒÔÓ²Á´½Ó´æÔÚ¡£

£¨3£©Í¨¹ýsetns()¼ÓÈëÒ»¸öÒѾ­´æÔÚµÄnamespace

ÉÏÎĸÕÌáµ½£¬ÔÚ½ø³Ì¶¼½áÊøµÄÇé¿öÏ£¬Ò²¿ÉÒÔͨ¹ý¹ÒÔØµÄÐÎʽ°Ñnamespace±£ÁôÏÂÀ´£¬±£ÁônamespaceµÄÄ¿µÄ×ÔÈ»ÊÇΪÒÔºóÓнø³Ì¼ÓÈë×ö×¼±¸¡£Í¨¹ýsetns()ϵͳµ÷Óã¬ÄãµÄ½ø³Ì´ÓÔ­ÏȵÄnamespace¼ÓÈëÎÒÃÇ×¼±¸ºÃµÄÐÂnamespace£¬Ê¹Ó÷½·¨ÈçÏ¡£

int setns(int fd, int nstype);

²ÎÊýfd±íʾÎÒÃÇÒª¼ÓÈëµÄnamespaceµÄÎļþÃèÊö·û¡£ÉÏÎÄÒѾ­Ìáµ½£¬ËüÊÇÒ»¸öÖ¸Ïò/proc/[pid]/nsĿ¼µÄÎļþÃèÊö·û£¬¿ÉÒÔͨ¹ýÖ±½Ó´ò¿ª¸ÃĿ¼ÏµÄÁ´½Ó»òÕß´ò¿ªÒ»¸ö¹ÒÔØÁ˸ÃĿ¼ÏÂÁ´½ÓµÄÎļþµÃµ½¡£

²ÎÊýnstypeÈõ÷ÓÃÕß¿ÉÒÔÈ¥¼ì²éfdÖ¸ÏòµÄnamespaceÀàÐÍÊÇ·ñ·ûºÏÎÒÃÇʵ¼ÊµÄÒªÇó¡£Èç¹ûÌî0±íʾ²»¼ì²é¡£

ΪÁ˰ÑÎÒÃÇ´´½¨µÄnamespaceÀûÓÃÆðÀ´£¬ÎÒÃÇÐèÒªÒýÈëexecve()ϵÁк¯Êý£¬Õâ¸öº¯Êý¿ÉÒÔÖ´ÐÐÓû§ÃüÁ×î³£ÓõľÍÊǵ÷ÓÃ/bin/bash²¢½ÓÊܲÎÊý£¬ÔËÐÐÆðÒ»¸öshell£¬Ó÷¨ÈçÏ¡£

fd = open(argv[1], O_RDONLY);   /* »ñÈ¡namespaceÎļþÃèÊö·û */
setns(fd, 0); /* ¼ÓÈëеÄnamespace */
execvp(argv[2], &argv[2]); /* Ö´ÐгÌÐò */

¼ÙÉè±àÒëºóµÄ³ÌÐòÃû³ÆÎªsetns¡£

# ./setns ~/uts /bin/bash   # ~/uts Êǰ󶨵Ä/proc/27514/ns/uts

ÖÁ´Ë£¬Äã¾Í¿ÉÒÔÔÚеÄÃüÃû¿Õ¼äÖÐÖ´ÐÐshellÃüÁîÁË£¬ÔÚÏÂÎÄÖлá¶à´ÎʹÓÃÕâÖÖ·½Ê½À´ÑÝʾ¸ôÀëµÄЧ¹û¡£

£¨4£©Í¨¹ýunshare()ÔÚÔ­ÏȽø³ÌÉϽøÐÐnamespace¸ôÀë

×îºóÒªÌáµÄϵͳµ÷ÓÃÊÇunshare()£¬Ëü¸úclone()ºÜÏñ£¬²»Í¬µÄÊÇ£¬unshare()ÔËÐÐÔÚÔ­ÏȵĽø³ÌÉÏ£¬²»ÐèÒªÆô¶¯Ò»¸öнø³Ì£¬Ê¹Ó÷½·¨ÈçÏ¡£

int unshare(int flags);

µ÷ÓÃunshare()µÄÖ÷Òª×÷ÓþÍÊDz»Æô¶¯Ò»¸öнø³Ì¾Í¿ÉÒÔÆðµ½¸ôÀëµÄЧ¹û£¬Ï൱ÓÚÌø³öÔ­ÏȵÄnamespace½øÐвÙ×÷¡£ÕâÑù£¬Äã¾Í¿ÉÒÔÔÚÔ­½ø³Ì½øÐÐһЩÐèÒª¸ôÀëµÄ²Ù×÷¡£LinuxÖÐ×Ô´øµÄunshareÃüÁ¾ÍÊÇͨ¹ýunshare()ϵͳµ÷ÓÃʵÏֵģ¬ÓÐÐËȤµÄ¶ÁÕß¿ÉÒÔÔÚÍøÉÏËÑË÷Ò»ÏÂÕâ¸öÃüÁîµÄ×÷Óá£

£¨5£©ÑÓÉìÔĶÁ£ºfork£¨£©ÏµÍ³µ÷ÓÃ

ϵͳµ÷Óú¯Êýfork()²¢²»ÊôÓÚnamespaceµÄAPI£¬ËùÒÔÕⲿ·ÖÄÚÈÝÊôÓÚÑÓÉìÔĶÁ£¬Èç¹û¶ÁÕßÒѾ­¶Ôfork()ÓÐ×ã¹»µÄÁ˽⣬ÄÇ´ó¿ÉÌø¹ý¡£

µ±³ÌÐòµ÷ÓÃfork£¨£©º¯Êýʱ£¬ÏµÍ³»á´´½¨ÐµĽø³Ì£¬ÎªÆä·ÖÅä×ÊÔ´£¬ÀýÈç´æ´¢Êý¾ÝºÍ´úÂëµÄ¿Õ¼ä¡£È»ºó°ÑÔ­À´µÄ½ø³ÌµÄËùÓÐÖµ¶¼¸´ÖƵ½ÐµĽø³ÌÖУ¬Ö»ÓÐÉÙÁ¿ÊýÖµÓëÔ­À´µÄ½ø³ÌÖµ²»Í¬£¬Ï൱ÓÚ¿Ë¡ÁËÒ»¸ö×Ô¼º¡£ÄÇô³ÌÐòµÄºóÐø´úÂëÂß¼­ÒªÈçºÎÇø·Ö×Ô¼ºÊÇнø³Ì»¹ÊǸ¸½ø³ÌÄØ£¿

fork()µÄÉñÆæÖ®´¦ÔÚÓÚËü½ö½ö±»µ÷ÓÃÒ»´Î£¬È´Äܹ»·µ»ØÁ½´Î£¨¸¸½ø³ÌÓë×Ó½ø³Ì¸÷·µ»ØÒ»´Î£©£¬Í¨¹ý·µ»ØÖµµÄ²»Í¬¾Í¿ÉÒÔ½øÐÐÇø·Ö¸¸½ø³ÌÓë×Ó½ø³Ì¡£Ëü¿ÉÄÜÓÐÈýÖÖ²»Í¬µÄ·µ»ØÖµ£º

ÔÚ¸¸½ø³ÌÖУ¬fork·µ»ØÐ´´½¨×Ó½ø³ÌµÄ½ø³ÌID

ÔÚ×Ó½ø³ÌÖУ¬fork·µ»Ø0

Èç¹û³öÏÖ´íÎó£¬fork·µ»ØÒ»¸ö¸ºÖµ

ÏÂÃæ¸ø³öÒ»¶ÎʵÀý´úÂ룬ÃüÃûΪfork_example.c¡£

#include <unistd.h>
#include <stdio.h>
int main (){
pid_t fpid; //fpid±íʾforkº¯Êý·µ»ØµÄÖµ
int count=0;
fpid=fork();
if (fpid < 0)printf("error in fork!");
else if (fpid == 0) {
printf("I am child. Process id is %d/n",getpid());
}
else {
printf("i am parent. Process id is %d/n",getpid());
}
return 0;
}

±àÒë²¢Ö´ÐУ¬½á¹ûÈçÏ¡£

root@local:~# gcc -Wall fork_example.c && ./a.out
I am parent. Process id is 28365
I am child. Process id is 28366

ʹÓÃfork()ºó£¬¸¸½ø³ÌÓÐÒåÎñ¼à¿Ø×Ó½ø³ÌµÄÔËÐÐ״̬£¬²¢ÔÚ×Ó½ø³ÌÍ˳öºó×Ô¼º²ÅÄÜÕý³£Í˳ö£¬·ñÔò×Ó½ø³Ì¾Í»á³ÉΪ¡°¹Â¶ù¡±½ø³Ì¡£

ÏÂÃæÎÒÃǽ«·Ö±ð¶ÔÁùÖÖnamespace½øÐÐÏêϸ½âÎö¡£

2. UTS£¨UNIX Time-sharing System£©namespace

UTS namespaceÌṩÁËÖ÷»úÃûºÍÓòÃûµÄ¸ôÀ룬ÕâÑùÿ¸öÈÝÆ÷¾Í¿ÉÒÔÓµÓÐÁ˶ÀÁ¢µÄÖ÷»úÃûºÍÓòÃû£¬ÔÚÍøÂçÉÏ¿ÉÒÔ±»ÊÓ×÷Ò»¸ö¶ÀÁ¢µÄ½Úµã¶ø·ÇËÞÖ÷»úÉϵÄÒ»¸ö½ø³Ì¡£

ÏÂÃæÎÒÃÇͨ¹ý´úÂëÀ´¸ÐÊÜÒ»ÏÂUTS¸ôÀëµÄЧ¹û£¬Ê×ÏÈÐèÒªÒ»¸ö³ÌÐòµÄ¹Ç¼Ü£¬ÈçÏÂËùʾ¡£´ò¿ª±à¼­Æ÷´´½¨uts.cÎļþ£¬ÊäÈëÈçÏ´úÂë¡£

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 
#include 

#define STACK_SIZE (1024 * 1024)

static char child_stack[STACK_SIZE];
char* const child_args[] = {
  "/bin/bash",
  NULL
};

int child_main(void* args) {
  printf("ÔÚ×Ó½ø³ÌÖÐ!\n");
  execv(child_args[0], child_args);
  return 1;
}

int main() {
  printf("³ÌÐò¿ªÊ¼: \n");
  int child_pid = clone(child_main, child_stack + STACK_SIZE, SIGCHLD, NULL);
  waitpid(child_pid, NULL, 0);
  printf("ÒÑÍ˳ö\n");
  return 0;
}

±àÒë²¢ÔËÐÐÉÏÊö´úÂ룬ִÐÐÈçÏÂÃüÁЧ¹ûÈçÏ¡£

root@local:~# gcc -Wall uts.c -o uts.o && ./uts.o
³ÌÐò¿ªÊ¼:
ÔÚ×Ó½ø³ÌÖÐ!
root@local:~# exit
exit
ÒÑÍ˳ö
root@local:~#

ÏÂÃæ£¬ÎÒÃǽ«Ð޸ĴúÂ룬¼ÓÈëUTS¸ôÀë¡£ÔËÐдúÂëÐèÒªrootȨÏÞ£¬ÎªÁË·ÀÖ¹ÆÕͨÓû§ÈÎÒâÐÞ¸ÄϵͳÖ÷»úÃûµ¼ÖÂset-user-IDÏà¹ØµÄÓ¦ÓÃÔËÐгö´í¡£

//[...]
int child_main(void* arg) {
printf("ÔÚ×Ó½ø³ÌÖÐ!\n");
sethostname("Changed Namespace", 12);
execv(child_args[0], child_args);
return 1;
} int main() {
//[...]
int child_pid = clone(child_main, child_stack+STACK_SIZE,
CLONE_NEWUTS | SIGCHLD, NULL);
//[...]
}

ÔÙ´ÎÔËÐпÉÒÔ¿´µ½hostnameÒѾ­±ä»¯¡£

root@local:~# gcc -Wall namespace.c -o main.o && ./main.o
³ÌÐò¿ªÊ¼:
ÔÚ×Ó½ø³ÌÖÐ!
root@NewNamespace:~# exit
exit
ÒÑÍ˳ö
root@local:~# <- »Øµ½Ô­À´µÄhostname

Ò²ÐíÓжÁÕßÊÔ×Ų»¼ÓCLONE_NEWUTS²ÎÊýÔËÐÐÉÏÊö´úÂ룬·¢ÏÖÖ÷»úÃûÒ²±äÁË£¬ÊäÈëexitÒÔºóÖ÷»úÃûÒ²»á±ä»ØÀ´£¬ËƺõÃ»Ê²Ã´Çø±ð¡£Êµ¼ÊÉϲ»¼ÓCLONE_NEWUTS²ÎÊý½øÐиôÀë¶øÊ¹ÓÃsethostnameÒѾ­°ÑËÞÖ÷»úµÄÖ÷»úÃû¸ÄµôÁË¡£Äã¿´µ½exitÍ˳öºó»¹Ô­Ö»ÊÇÒòΪbashÖ»ÔڸյǼµÄʱºò¶Áȡһ´ÎUTS£¬µ±ÄãÖØÐµÇ½»òÕßʹÓÃunameÃüÁî½øÐв鿴ʱ£¬¾Í»á·¢ÏÖ²úÉúÁ˱仯¡£

DockerÖУ¬Ã¿¸ö¾µÏñ»ù±¾¶¼ÒÔ×Ô¼ºËùÌṩµÄ·þÎñÃüÃûÁË×Ô¼ºµÄhostname¶øÃ»ÓжÔËÞÖ÷»ú²úÉúÈκÎÓ°Ï죬ÓõľÍÊÇÕâ¸öÔ­Àí¡£

3. IPC£¨Interprocess Communication£©namespace

ÈÝÆ÷Öнø³Ì¼äͨÐŲÉÓõķ½·¨°üÀ¨³£¼ûµÄÐźÅÁ¿¡¢ÏûÏ¢¶ÓÁк͹²ÏíÄڴ档Ȼ¶øÓëÐéÄâ»ú²»Í¬µÄÊÇ£¬ÈÝÆ÷ÄÚ²¿½ø³Ì¼äͨÐŶÔËÞÖ÷»úÀ´Ëµ£¬Êµ¼ÊÉÏÊǾßÓÐÏàͬPID namespaceÖеĽø³Ì¼äͨÐÅ£¬Òò´ËÐèÒªÒ»¸öΨһµÄ±êʶ·ûÀ´½øÐÐÇø±ð¡£ÉêÇëIPC×ÊÔ´¾ÍÉêÇëÁËÕâÑùÒ»¸öÈ«¾ÖΨһµÄ32λID£¬ËùÒÔIPC namespaceÖÐʵ¼ÊÉϰüº¬ÁËϵͳIPC±êʶ·ûÒÔ¼°ÊµÏÖPOSIXÏûÏ¢¶ÓÁеÄÎļþϵͳ¡£ÔÚͬһ¸öIPC namespaceϵĽø³Ì±Ë´Ë¿É¼û£¬¶øÓëÆäËûµÄIPC namespaceϵĽø³ÌÔò»¥Ï಻¿É¼û¡£

IPC namespaceÔÚ´úÂëÉϵı仯ÓëUTS namespaceÏàËÆ£¬Ö»ÊDZêʶλÓÐËù±ä»¯£¬ÐèÒª¼ÓÉÏCLONE_NEWIPC²ÎÊý¡£Ö÷Òª¸Ä¶¯ÈçÏ£¬ÆäËû²¿Î»²»±ä£¬³ÌÐòÃû³Æ¸ÄΪipc.c¡££¨²âÊÔ·½·¨²Î¿¼×Ô£ºhttp://crosbymichael.com/creating-containers-part-1.html£©

//[...]
int child_pid = clone(child_main, child_stack+STACK_SIZE,
CLONE_NEWIPC | CLONE_NEWUTS | SIGCHLD, NULL);
//[...]

ÎÒÃÇÊ×ÏÈÔÚshellÖÐʹÓÃipcmk -QÃüÁî´´½¨Ò»¸ömessage queue¡£

root@local:~# ipcmk -Q
Message queue id: 32769

ͨ¹ýipcs -q¿ÉÒԲ鿴µ½ÒѾ­¿ªÆôµÄmessage queue£¬ÐòºÅΪ32769¡£

root@local:~# ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x4cf5e29f 32769 root 644 0 0

È»ºóÎÒÃÇ¿ÉÒÔ±àÒëÔËÐмÓÈëÁËIPC namespace¸ôÀëµÄipc.c£¬ÔÚн¨µÄ×Ó½ø³ÌÖе÷ÓõÄshellÖÐÖ´ÐÐipcs -q²é¿´message queue¡£

root@local:~# gcc -Wall ipc.c -o ipc.o && ./ipc.o
³ÌÐò¿ªÊ¼:
ÔÚ×Ó½ø³ÌÖÐ!
root@NewNamespace:~# ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
root@NewNamespace:~# exit
exit
ÒÑÍ˳ö

ÉÏÃæµÄ½á¹ûÏÔʾÖпÉÒÔ·¢ÏÖ£¬ÒѾ­ÕÒ²»µ½Ô­ÏÈÉùÃ÷µÄmessage queue£¬ÊµÏÖÁËIPCµÄ¸ôÀë¡£

ĿǰʹÓÃIPC namespace»úÖÆµÄϵͳ²»¶à£¬ÆäÖбȽÏÓÐÃûµÄÓÐPostgreSQL¡£Docker±¾Éíͨ¹ýsocket»òtcp½øÐÐͨÐÅ¡£

4. PID namespace

PID namespace¸ôÀë·Ç³£ÊµÓã¬Ëü¶Ô½ø³ÌPIDÖØÐ±êºÅ£¬¼´Á½¸ö²»Í¬namespaceϵĽø³Ì¿ÉÒÔÓÐͬһ¸öPID¡£Ã¿¸öPID namespace¶¼ÓÐ×Ô¼ºµÄ¼ÆÊý³ÌÐò¡£ÄÚºËΪËùÓеÄPID namespaceά»¤ÁËÒ»¸öÊ÷×´½á¹¹£¬×î¶¥²ãµÄÊÇϵͳ³õʼʱ´´½¨µÄ£¬ÎÒÃdzÆÖ®Îªroot namespace¡£Ëû´´½¨µÄÐÂPID namespace¾Í³ÆÖ®Îªchild namespace£¨Ê÷µÄ×ӽڵ㣩£¬¶øÔ­ÏȵÄPID namespace¾ÍÊÇд´½¨µÄPID namespaceµÄparent namespace£¨Ê÷µÄ¸¸½Úµã£©¡£Í¨¹ýÕâÖÖ·½Ê½£¬²»Í¬µÄPID namespaces»áÐγÉÒ»¸öµÈ¼¶Ìåϵ¡£ËùÊôµÄ¸¸½Úµã¿ÉÒÔ¿´µ½×Ó½ÚµãÖеĽø³Ì£¬²¢¿ÉÒÔͨ¹ýÐźŵȷ½Ê½¶Ô×Ó½ÚµãÖеĽø³Ì²úÉúÓ°Ïì¡£·´¹ýÀ´£¬×ӽڵ㲻ÄÜ¿´µ½¸¸½ÚµãPID namespaceÖеÄÈκÎÄÚÈÝ¡£Óɴ˲úÉúÈçϽáÂÛ£¨²¿·ÖÄÚÈÝÒý×Ô£ºhttp://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-part£©¡£

ÿ¸öPID namespaceÖеĵÚÒ»¸ö½ø³Ì¡°PID 1¡°£¬¶¼»áÏñ´«Í³LinuxÖеÄinit½ø³ÌÒ»ÑùÓµÓÐÌØÈ¨£¬ÆðÌØÊâ×÷Óá£

Ò»¸önamespaceÖеĽø³Ì£¬²»¿ÉÄÜͨ¹ýkill»òptraceÓ°Ï츸½Úµã»òÕßÐֵܽڵãÖеĽø³Ì£¬ÒòΪÆäËû½ÚµãµÄPIDÔÚÕâ¸önamespaceÖÐûÓÐÈκÎÒâÒå¡£
Èç¹ûÄãÔÚеÄPID namespaceÖÐÖØÐ¹ÒÔØ/procÎļþϵͳ£¬»á·¢ÏÖÆäÏÂÖ»ÏÔʾͬÊôÒ»¸öPID namespaceÖÐµÄÆäËû½ø³Ì¡£

ÔÚroot namespaceÖпÉÒÔ¿´µ½ËùÓеĽø³Ì£¬²¢Çҵݹé°üº¬ËùÓÐ×Ó½ÚµãÖеĽø³Ì¡£

µ½ÕâÀ¿ÉÄÜÄãÒѾ­ÁªÏëµ½Ò»ÖÖÔÚÍⲿ¼à¿ØDockerÖÐÔËÐгÌÐòµÄ·½·¨ÁË£¬¾ÍÊÇ¼à¿ØDocker DaemonËùÔÚµÄPID namespaceϵÄËùÓнø³Ì¼´Æä×Ó½ø³Ì£¬ÔÙ½øÐÐɾѡ¼´¿É¡£

ÏÂÃæÎÒÃÇͨ¹ýÔËÐдúÂëÀ´¸ÐÊÜÒ»ÏÂPID namespaceµÄ¸ôÀëЧ¹û¡£ÐÞ¸ÄÉÏÎĵĴúÂ룬¼ÓÈëPID namespaceµÄ±êʶ룬²¢°Ñ³ÌÐòÃüÃûΪpid.c¡£

//[...]
int child_pid = clone(child_main, child_stack+STACK_SIZE,
CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWUTS
| SIGCHLD, NULL);
//[...]

±àÒëÔËÐпÉÒÔ¿´µ½ÈçϽá¹û¡£

root@local:~# gcc -Wall pid.c -o pid.o && ./pid.o
³ÌÐò¿ªÊ¼:
ÔÚ×Ó½ø³ÌÖÐ!
root@NewNamespace:~# echo $$
1 <<--×¢Òâ´Ë´¦¿´µ½shellµÄPID±ä³ÉÁË1
root@NewNamespace:~# exit
exit
ÒÑÍ˳ö

´òÓ¡$$¿ÉÒÔ¿´µ½shellµÄPID£¬Í˳öºóÈç¹ûÔÙ´ÎÖ´ÐпÉÒÔ¿´µ½Ð§¹ûÈçÏ¡£

root@local:~# echo $$
17542

ÒѾ­»Øµ½ÁËÕý³£×´Ì¬¡£¿ÉÄÜÓеĶÁÕßÔÚ×Ó½ø³ÌµÄshellÖÐÖ´ÐÐÁËps aux/topÖ®ÀàµÄÃüÁ·¢ÏÖ»¹ÊÇ¿ÉÒÔ¿´µ½ËùÓи¸½ø³ÌµÄPID£¬ÄÇÊÇÒòΪÎÒÃÇ»¹Ã»ÓжÔÎļþϵͳ½øÐиôÀ룬ps/topÖ®ÀàµÄÃüÁîµ÷ÓõÄÊÇÕæÊµÏµÍ³ÏµÄ/procÎļþÄÚÈÝ£¬¿´µ½µÄ×ÔÈ»ÊÇËùÓеĽø³Ì¡£

´ËÍ⣬ÓëÆäËûµÄnamespace²»Í¬µÄÊÇ£¬ÎªÁËʵÏÖÒ»¸öÎȶ¨°²È«µÄÈÝÆ÷£¬PID namespace»¹ÐèÒª½øÐÐһЩ¶îÍâµÄ¹¤×÷²ÅÄÜÈ·±£ÆäÖеĽø³ÌÔËÐÐ˳Àû¡£

£¨1£©PID namespaceÖеÄinit½ø³Ì

µ±ÎÒÃÇн¨Ò»¸öPID namespaceʱ£¬Ä¬ÈÏÆô¶¯µÄ½ø³ÌPIDΪ1¡£ÎÒÃÇÖªµÀ£¬ÔÚ´«Í³µÄUNIXϵͳÖУ¬PIDΪ1µÄ½ø³ÌÊÇinit£¬µØÎ»·Ç³£ÌØÊâ¡£Ëû×÷ΪËùÓнø³ÌµÄ¸¸½ø³Ì£¬Î¬»¤Ò»ÕŽø³Ì±í£¬²»¶Ï¼ì²é½ø³ÌµÄ״̬£¬Ò»µ©ÓÐij¸ö×Ó½ø³ÌÒòΪ³ÌÐò´íÎó³ÉΪÁË¡°¹Â¶ù¡±½ø³Ì£¬init¾Í»á¸ºÔð»ØÊÕ×ÊÔ´²¢½áÊøÕâ¸ö×Ó½ø³Ì¡£ËùÒÔÔÚÄãҪʵÏÖµÄÈÝÆ÷ÖУ¬Æô¶¯µÄµÚÒ»¸ö½ø³ÌÒ²ÐèҪʵÏÖÀàËÆinitµÄ¹¦ÄÜ£¬Î¬»¤ËùÓкóÐøÆô¶¯½ø³ÌµÄÔËÐÐ״̬¡£

¿´µ½ÕâÀ¿ÉÄܶÁÕßÒѾ­Ã÷°×ÁËÄÚºËÉè¼ÆµÄÁ¼¿àÓÃÐÄ¡£PID namespaceά»¤ÕâÑùÒ»¸öÊ÷×´½á¹¹£¬·Ç³£ÓÐÀûÓÚϵͳµÄ×ÊÔ´¼à¿ØÓë»ØÊÕ¡£DockerÆô¶¯Ê±£¬µÚÒ»¸ö½ø³ÌÒ²ÊÇÕâÑù£¬ÊµÏÖÁ˽ø³Ì¼à¿ØºÍ×ÊÔ´»ØÊÕ£¬Ëü¾ÍÊÇdockerinit¡£

£¨2£©ÐźÅÓëinit½ø³Ì

PID namespaceÖеÄinit½ø³ÌÈç´ËÌØÊ⣬×ÔÈ»ÄÚºËҲΪËû¸³ÓèÁËÌØÈ¨¡ª¡ªÐÅºÅÆÁ±Î¡£Èç¹ûinitÖÐûÓÐд´¦Àíij¸öÐźŵĴúÂëÂß¼­£¬ÄÇôÓëinitÔÚͬһ¸öPID namespaceϵĽø³Ì£¨¼´Ê¹Óг¬¼¶È¨ÏÞ£©·¢Ë͸øËüµÄ¸ÃÐźŶ¼»á±»ÆÁ±Î¡£Õâ¸ö¹¦ÄܵÄÖ÷Òª×÷ÓÃÊÇ·ÀÖ¹init½ø³Ì±»Îóɱ¡£

ÄÇôÆä¸¸½ÚµãPID namespaceÖеĽø³Ì·¢ËÍͬÑùµÄÐźŻᱻºöÂÔÂ𣿸¸½ÚµãÖеĽø³Ì·¢Ë͵ÄÐźţ¬Èç¹û²»ÊÇSIGKILL£¨Ïú»Ù½ø³Ì£©»òSIGSTOP£¨ÔÝÍ£½ø³Ì£©Ò²»á±»ºöÂÔ¡£µ«Èç¹û·¢ËÍSIGKILL»òSIGSTOP£¬×Ó½ÚµãµÄinit»áÇ¿ÖÆÖ´ÐУ¨ÎÞ·¨Í¨¹ý´úÂë²¶×½½øÐÐÌØÊâ´¦Àí£©£¬Ò²¾ÍÊÇ˵¸¸½ÚµãÖеĽø³ÌÓÐȨÖÕÖ¹×Ó½ÚµãÖеĽø³Ì¡£

Ò»µ©init½ø³Ì±»Ïú»Ù£¬Í¬Ò»PID namespaceÖÐµÄÆäËû½ø³ÌÒ²»áËæÖ®½ÓÊÕµ½SIGKILLÐźŶø±»Ïú»Ù¡£ÀíÂÛÉÏ£¬¸ÃPID namespace×ÔȻҲ¾Í²»¸´´æÔÚÁË¡£µ«ÊÇÈç¹û/proc/[pid]/ns/pid´¦ÓÚ±»¹ÒÔØ»òÕß´ò¿ª×´Ì¬£¬namespace¾Í»á±»±£ÁôÏÂÀ´¡£È»¶ø£¬±£ÁôÏÂÀ´µÄnamespaceÎÞ·¨Í¨¹ýsetns()»òÕßfork()´´½¨½ø³Ì£¬ËùÒÔʵ¼ÊÉϲ¢Ã»ÓÐʲô×÷Óá£

ÎÒÃdz£Ëµ£¬DockerÒ»µ©Æô¶¯¾ÍÓнø³ÌÔÚÔËÐУ¬²»´æÔÚ²»°üº¬Èκνø³ÌµÄDocker£¬Ò²¾ÍÊÇÕâ¸öµÀÀí¡£

£¨3£©¹ÒÔØprocÎļþϵͳ

ǰÎÄÖÐÒѾ­Ìáµ½£¬Èç¹ûÄãÔÚеÄPID namespaceÖÐʹÓÃpsÃüÁî²é¿´£¬¿´µ½µÄ»¹ÊÇËùÓеĽø³Ì£¬ÒòΪÓëPIDÖ±½ÓÏà¹ØµÄ/procÎļþϵͳ£¨procfs£©Ã»ÓйÒÔØµ½ÓëÔ­/proc²»Í¬µÄλÖá£ËùÒÔÈç¹ûÄãÖ»Ïë¿´µ½PID namespace±¾ÉíÓ¦¸Ã¿´µ½µÄ½ø³Ì£¬ÐèÒªÖØÐ¹ÒÔØ/proc£¬ÃüÁîÈçÏ¡£

root@NewNamespace:~# mount -t proc proc /proc
root@NewNamespace:~# ps a
PID TTY STAT TIME COMMAND
1 pts/1 S 0:00 /bin/bash
12 pts/1 R+ 0:00 ps a

¿ÉÒÔ¿´µ½Êµ¼ÊµÄPID namespace¾ÍÖ»ÓÐÁ½¸ö½ø³ÌÔÚÔËÐС£

×¢Ò⣺ÒòΪ´ËʱÎÒÃÇûÓнøÐÐmount namespaceµÄ¸ôÀ룬ËùÒÔÕâÒ»²½²Ù×÷ʵ¼ÊÉÏÒѾ­Ó°ÏìÁË root namespaceµÄÎļþϵͳ£¬µ±ÄãÍ˳öн¨µÄPID namespaceÒÔºóÔÙÖ´ÐÐps a¾Í»á·¢ÏÖ³ö´í£¬ÔÙ´ÎÖ´ÐÐmount -t proc proc /proc¿ÉÒÔÐÞ¸´´íÎó¡£

£¨4£©unshare()ºÍsetns()

ÔÚ¿ªÆªÎÒÃǾͽ²µ½ÁËunshare()ºÍsetns()ÕâÁ½¸öAPI£¬¶øÕâÁ½¸öAPIÔÚPID namespaceÖÐʹÓÃʱ£¬Ò²ÓÐÒ»Ð©ÌØ±ðÖ®´¦ÐèҪעÒâ¡£

unshare()ÔÊÐíÓû§ÔÚÔ­Óнø³ÌÖн¨Á¢namespace½øÐиôÀë¡£µ«ÊÇ´´½¨ÁËPID namespaceºó£¬Ô­ÏÈunshare()µ÷ÓÃÕß½ø³Ì²¢²»½øÈëеÄPID namespace£¬½ÓÏÂÀ´´´½¨µÄ×Ó½ø³Ì²Å»á½øÈëеÄnamespace£¬Õâ¸ö×Ó½ø³ÌÒ²¾ÍËæÖ®³ÉΪÐÂnamespaceÖеÄinit½ø³Ì¡£

ÀàËÆµÄ£¬µ÷ÓÃsetns()´´½¨ÐÂPID namespaceʱ£¬µ÷ÓÃÕß½ø³ÌÒ²²»½øÈëеÄPID namespace£¬¶øÊÇËæºó´´½¨µÄ×Ó½ø³Ì½øÈë¡£

Ϊʲô´´½¨ÆäËûnamespaceʱunshare()ºÍsetns()»áÖ±½Ó½øÈëеÄnamespace¶øÎ¨¶ÀPID namespace²»ÊÇÈç´ËÄØ£¿ÒòΪµ÷ÓÃgetpid()º¯ÊýµÃµ½µÄPIDÊǸù¾Ýµ÷ÓÃÕßËùÔÚµÄPID namespace¶ø¾ö¶¨·µ»ØÄĸöPID£¬½øÈëеÄPID namespace»áµ¼ÖÂPID²úÉú±ä»¯¡£¶ø¶ÔÓû§Ì¬µÄ³ÌÐòºÍ¿âº¯ÊýÀ´Ëµ£¬ËûÃǶ¼ÈÏΪ½ø³ÌµÄPIDÊÇÒ»¸ö³£Á¿£¬PIDµÄ±ä»¯»áÒýÆðÕâЩ½ø³Ì±¼À£¡£

»»¾ä»°Ëµ£¬Ò»µ©³ÌÐò½ø³Ì´´½¨ÒÔºó£¬ÄÇôËüµÄPID namespaceµÄ¹ØÏµ¾ÍÈ·¶¨ÏÂÀ´ÁË£¬½ø³Ì²»»á±ä¸üËûÃǶÔÓ¦µÄPID namespace¡£

5. Mount namespaces

Mount namespaceͨ¹ý¸ôÀëÎļþϵͳ¹ÒÔØµã¶Ô¸ôÀëÎļþϵͳÌṩ֧³Ö£¬ËüÊÇÀúÊ·ÉϵÚÒ»¸öLinux namespace£¬ËùÒÔËüµÄ±êʶλ±È½ÏÌØÊ⣬¾ÍÊÇCLONE_NEWNS¡£¸ôÀëºó£¬²»Í¬mount namespaceÖеÄÎļþ½á¹¹·¢Éú±ä»¯Ò²»¥²»Ó°Ïì¡£Äã¿ÉÒÔͨ¹ý/proc/[pid]/mounts²é¿´µ½ËùÓйÒÔØÔÚµ±Ç°namespaceÖеÄÎļþϵͳ£¬»¹¿ÉÒÔͨ¹ý/proc/[pid]/mountstats¿´µ½mount namespaceÖÐÎļþÉ豸µÄͳ¼ÆÐÅÏ¢£¬°üÀ¨¹ÒÔØÎļþµÄÃû×Ö¡¢ÎļþϵͳÀàÐÍ¡¢¹ÒÔØÎ»Öõȵȡ£

½ø³ÌÔÚ´´½¨mount namespaceʱ£¬»á°Ñµ±Ç°µÄÎļþ½á¹¹¸´ÖƸøÐµÄnamespace¡£ÐÂnamespaceÖеÄËùÓÐmount²Ù×÷¶¼Ö»Ó°Ïì×ÔÉíµÄÎļþϵͳ£¬¶ø¶ÔÍâ½ç²»»á²úÉúÈκÎÓ°Ïì¡£ÕâÑù×ö·Ç³£ÑϸñµØÊµÏÖÁ˸ôÀ룬µ«ÊÇijЩÇé¿ö¿ÉÄܲ¢²»ÊÊÓᣱÈÈ縸½ÚµãnamespaceÖеĽø³Ì¹ÒÔØÁËÒ»ÕÅCD-ROM£¬Õâʱ×Ó½Úµãnamespace¿½±´µÄĿ¼½á¹¹¾ÍÎÞ·¨×Ô¶¯¹ÒÔØÉÏÕâÕÅCD-ROM£¬ÒòΪÕâÖÖ²Ù×÷»áÓ°Ïìµ½¸¸½ÚµãµÄÎļþϵͳ¡£

2006 ÄêÒýÈëµÄ¹ÒÔØ´«²¥£¨mount propagation£©½â¾öÁËÕâ¸öÎÊÌ⣬¹ÒÔØ´«²¥¶¨ÒåÁ˹ÒÔØ¶ÔÏó£¨mount object£©Ö®¼äµÄ¹ØÏµ£¬ÏµÍ³ÓÃÕâЩ¹ØÏµ¾ö¶¨ÈκιÒÔØ¶ÔÏóÖеĹÒÔØÊ¼þÈçºÎ´«²¥µ½ÆäËû¹ÒÔØ¶ÔÏ󣨲ο¼×Ô£ºhttp://www.ibm.com/developerworks/library/l-mount-namespaces/£©¡£Ëùν´«²¥Ê¼þ£¬ÊÇÖ¸ÓÉÒ»¸ö¹ÒÔØ¶ÔÏóµÄ״̬±ä»¯µ¼ÖÂµÄÆäËü¹ÒÔØ¶ÔÏóµÄ¹ÒÔØÓë½â³ý¹ÒÔØ¶¯×÷µÄʼþ¡£

¹²Ïí¹ØÏµ£¨share relationship£©¡£Èç¹ûÁ½¸ö¹ÒÔØ¶ÔÏó¾ßÓй²Ïí¹ØÏµ£¬ÄÇôһ¸ö¹ÒÔØ¶ÔÏóÖеĹÒÔØÊ¼þ»á´«²¥µ½ÁíÒ»¸ö¹ÒÔØ¶ÔÏ󣬷´Ö®ÒàÈ»¡£

´ÓÊô¹ØÏµ£¨slave relationship£©¡£Èç¹ûÁ½¸ö¹ÒÔØ¶ÔÏóÐγɴÓÊô¹ØÏµ£¬ÄÇôһ¸ö¹ÒÔØ¶ÔÏóÖеĹÒÔØÊ¼þ»á´«²¥µ½ÁíÒ»¸ö¹ÒÔØ¶ÔÏ󣬵«ÊÇ·´¹ýÀ´²»ÐУ»ÔÚÕâÖÖ¹ØÏµÖУ¬´ÓÊô¶ÔÏóÊÇʼþµÄ½ÓÊÕÕß¡£

Ò»¸ö¹ÒÔØ×´Ì¬¿ÉÄÜΪÈçÏÂµÄÆäÖÐÒ»ÖÖ£º

¹²Ïí¹ÒÔØ£¨shared£©

´ÓÊô¹ÒÔØ£¨slave£©

¹²Ïí/´ÓÊô¹ÒÔØ£¨shared and slave£©

˽ÓйÒÔØ£¨private£©

²»¿É°ó¶¨¹ÒÔØ£¨unbindable£©

´«²¥Ê¼þµÄ¹ÒÔØ¶ÔÏó³ÆÎª¹²Ïí¹ÒÔØ£¨shared mount£©£»½ÓÊÕ´«²¥Ê¼þµÄ¹ÒÔØ¶ÔÏó³ÆÎª´ÓÊô¹ÒÔØ£¨slave mount£©¡£¼È²»´«²¥Ò²²»½ÓÊÕ´«²¥Ê¼þµÄ¹ÒÔØ¶ÔÏó³ÆÎªË½ÓйÒÔØ£¨private mount£©¡£ÁíÒ»ÖÖÌØÊâµÄ¹ÒÔØ¶ÔÏó³ÆÎª²»¿É°ó¶¨µÄ¹ÒÔØ£¨unbindable mount£©£¬ËüÃÇÓë˽ÓйÒÔØÏàËÆ£¬µ«ÊDz»ÔÊÐíÖ´Ðа󶨹ÒÔØ£¬¼´´´½¨mount namespaceʱÕâ¿éÎļþ¶ÔÏ󲻿ɱ»¸´ÖÆ¡£

ͼ1 mount¸÷Àà¹ÒÔØ×´Ì¬Ê¾Òâͼ

¹²Ïí¹ÒÔØµÄÓ¦Óó¡¾°·Ç³£Ã÷ÏÔ£¬¾ÍÊÇΪÁËÎļþÊý¾ÝµÄ¹²ÏíËù±ØÐë´æÔÚµÄÒ»ÖÖ¹ÒÔØ·½Ê½£»´ÓÊô¹ÒÔØ¸ü´óµÄÒâÒåÔÚÓÚijЩ¡°Ö»¶Á¡±³¡¾°£»Ë½ÓйÒÔØÆäʵ¾ÍÊÇ´¿´âµÄ¸ôÀ룬×÷Ϊһ¸ö¶ÀÁ¢µÄ¸öÌå¶ø´æÔÚ£»²»¿É°ó¶¨¹ÒÔØÔòÓÐÖúÓÚ·ÀֹûÓбØÒªµÄÎļþ¿½±´£¬Èçij¸öÓû§Êý¾ÝĿ¼£¬µ±¸ùĿ¼±»µÝ¹éʽµÄ¸´ÖÆÊ±£¬Óû§Ä¿Â¼ÎÞÂÛ´ÓÒþ˽»¹ÊÇʵ¼ÊÓÃ;¿¼ÂǶ¼ÐèÒªÓÐÒ»¸ö²»¿É±»¸´ÖƵÄÑ¡Ïî¡£

ĬÈÏÇé¿öÏ£¬ËùÓйÒÔØ¶¼ÊÇ˽Óеġ£ÉèÖÃΪ¹²Ïí¹ÒÔØµÄÃüÁîÈçÏ¡£

mount --make-shared <mount-object>

´Ó¹²Ïí¹ÒÔØ¿Ë¡µÄ¹ÒÔØ¶ÔÏóÒ²Êǹ²ÏíµÄ¹ÒÔØ£»ËüÃÇÏ໥´«²¥¹ÒÔØÊ¼þ¡£

ÉèÖÃΪ´ÓÊô¹ÒÔØµÄÃüÁîÈçÏ¡£

mount --make-slave <shared-mount-object>

´Ó´ÓÊô¹ÒÔØ¿Ë¡µÄ¹ÒÔØ¶ÔÏóÒ²ÊÇ´ÓÊôµÄ¹ÒÔØ£¬ËüÒ²´ÓÊôÓÚÔ­À´µÄ´ÓÊô¹ÒÔØµÄÖ÷¹ÒÔØ¶ÔÏó¡£

½«Ò»¸ö´ÓÊô¹ÒÔØ¶ÔÏóÉèÖÃΪ¹²Ïí/´ÓÊô¹ÒÔØ£¬¿ÉÒÔÖ´ÐÐÈçÏÂÃüÁî»òÕß½«ÆäÒÆ¶¯µ½Ò»¸ö¹²Ïí¹ÒÔØ¶ÔÏóÏ¡£

mount --make-shared <slave-mount-object>

Èç¹ûÄãÏë°ÑÐ޸ĹýµÄ¹ÒÔØ¶ÔÏóÖØÐ±ê¼ÇΪ˽Óеģ¬¿ÉÒÔÖ´ÐÐÈçÏÂÃüÁî¡£

mount --make-private <mount-object>

ͨ¹ýÖ´ÐÐÒÔÏÂÃüÁ¿ÉÒÔ½«¹ÒÔØ¶ÔÏó±ê¼ÇΪ²»¿É°ó¶¨µÄ¡£

mount --make-unbindable <mount-object>

ÕâЩÉèÖö¼¿ÉÒԵݹéʽµØÓ¦Óõ½ËùÓÐ×ÓĿ¼ÖУ¬Èç¹û¶ÁÕ߸ÐÐËȤ¿ÉÒÔËÑË÷µ½Ïà¹ØµÄÃüÁî¡£

ÔÚ´úÂëÖÐʵÏÖmount namespace¸ôÀëÓëÆäËûnamespaceÀàËÆ£¬¼ÓÉÏCLONE_NEWNS±êʶλ¼´¿É¡£ÈÃÎÒÃÇÔÙ´ÎÐ޸ĴúÂ룬²¢ÇÒÁí´æÎªmount.c½øÐбàÒëÔËÐС£

//[...]
int child_pid = clone(child_main, child_stack+STACK_SIZE,
CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWIPC
| CLONE_NEWUTS | SIGCHLD, NULL);
//[...]

Ö´ÐеÄЧ¹û¾ÍÈçͬPID namespaceÒ»½ÚÖС°¹ÒÔØprocÎļþϵͳ¡±µÄÖ´Ðнá¹û£¬Çø±ð¾ÍÊÇÍ˳ömount namespaceÒÔºó£¬root namespaceµÄÎļþϵͳ²»»á±»ÆÆ»µ£¬´Ë´¦¾Í²»ÔÙÑÝʾÁË¡£

6. Network namespace

ͨ¹ýÉϽڣ¬ÎÒÃÇÁ˽âÁËPID namespace£¬µ±ÎÒÃÇÐËÖ²ª²ªµØÔÚн¨µÄnamespaceÖÐÆô¶¯Ò»¸ö¡°Apache¡±½ø³Ìʱ£¬È´³öÏÖÁË¡°80¶Ë¿ÚÒѱ»Õ¼ÓᱵĴíÎó£¬Ô­À´Ö÷»úÉÏÒѾ­ÔËÐÐÁËÒ»¸ö¡°Apache¡±½ø³Ì¡£Ôõô°ì£¿Õâ¾ÍÐèÒªÓõ½network namespace¼¼Êõ½øÐÐÍøÂç¸ôÀëÀ²¡£

Network namespaceÖ÷ÒªÌṩÁ˹ØÓÚÍøÂç×ÊÔ´µÄ¸ôÀ룬°üÀ¨ÍøÂçÉ豸¡¢IPv4ºÍIPv6ЭÒéÕ»¡¢IP·ÓÉ±í¡¢·À»ðǽ¡¢/proc/netĿ¼¡¢/sys/class/netĿ¼¡¢¶Ë¿Ú£¨socket£©µÈµÈ¡£Ò»¸öÎïÀíµÄÍøÂçÉ豸×î¶à´æÔÚÔÚÒ»¸önetwork namespaceÖУ¬Äã¿ÉÒÔͨ¹ý´´½¨veth pair£¨ÐéÄâÍøÂçÉ豸¶Ô£ºÓÐÁ½¶Ë£¬ÀàËÆ¹ÜµÀ£¬Èç¹ûÊý¾Ý´ÓÒ»¶Ë´«ÈëÁíÒ»¶ËÒ²ÄܽÓÊÕµ½£¬·´Ö®ÒàÈ»£©ÔÚ²»Í¬µÄnetwork namespace¼ä´´½¨Í¨µÀ£¬ÒԴ˴ﵽͨÐŵÄÄ¿µÄ¡£

Ò»°ãÇé¿öÏ£¬ÎïÀíÍøÂçÉ豸¶¼·ÖÅäÔÚ×î³õµÄroot namespace£¨±íʾϵͳĬÈϵÄnamespace£¬ÔÚPID namespaceÖÐÒѾ­Ìá¼°£©ÖС£µ«ÊÇÈç¹ûÄãÓжà¿éÎïÀíÍø¿¨£¬Ò²¿ÉÒÔ°ÑÆäÖÐÒ»¿é»ò¶à¿é·ÖÅ䏸д´½¨µÄnetwork namespace¡£ÐèҪעÒâµÄÊÇ£¬µ±Ð´´½¨µÄnetwork namespace±»ÊÍ·Åʱ£¨ËùÓÐÄÚ²¿µÄ½ø³Ì¶¼ÖÕÖ¹²¢ÇÒnamespaceÎļþûÓб»¹ÒÔØ»ò´ò¿ª£©£¬ÔÚÕâ¸önamespaceÖеÄÎïÀíÍø¿¨»á·µ»Øµ½root namespace¶ø·Ç´´½¨¸Ã½ø³ÌµÄ¸¸½ø³ÌËùÔÚµÄnetwork namespace¡£

µ±ÎÒÃÇ˵µ½network namespaceʱ£¬ÆäʵÎÒÃÇÖ¸µÄδ±ØÊÇÕæÕýµÄÍøÂç¸ôÀ룬¶øÊǰÑÍøÂç¶ÀÁ¢³öÀ´£¬¸øÍⲿÓû§Ò»ÖÖ͸Ã÷µÄ¸Ð¾õ£¬·Â·ð¸úÁíÍâÒ»¸öÍøÂçʵÌåÔÚ½øÐÐͨÐÅ¡£ÎªÁË´ïµ½Õâ¸öÄ¿µÄ£¬ÈÝÆ÷µÄ¾­µä×ö·¨¾ÍÊÇ´´½¨Ò»¸öveth pair£¬Ò»¶Ë·ÅÖÃÔÚеÄnamespaceÖУ¬Í¨³£ÃüÃûΪeth0£¬Ò»¶Ë·ÅÔÚÔ­ÏȵÄnamespaceÖÐÁ¬½ÓÎïÀíÍøÂçÉ豸£¬ÔÙͨ¹ýÍøÇŰѱðµÄÉ豸Á¬½Ó½øÀ´»òÕß½øÐзÓÉת·¢£¬ÒÔ´ËÍøÂçʵÏÖͨÐŵÄÄ¿µÄ¡£

Ò²ÐíÓжÁÕß»áºÃÆæ£¬ÔÚ½¨Á¢Æðveth pair֮ǰ£¬Ð¾Énamespace¸ÃÈçºÎͨÐÅÄØ£¿´ð°¸ÊÇpipe£¨¹ÜµÀ£©¡£ÎÒÃÇÒÔDocker DaemonÔÚÆô¶¯ÈÝÆ÷dockerinitµÄ¹ý³ÌΪÀý¡£Docker DaemonÔÚËÞÖ÷»úÉϸºÔð´´½¨Õâ¸öveth pair£¬Í¨¹ýnetlinkµ÷Ó㬰ÑÒ»¶Ë°ó¶¨µ½docker0ÍøÇÅÉÏ£¬Ò»¶ËÁ¬½øÐ½¨µÄnetwork namespace½ø³ÌÖС£½¨Á¢µÄ¹ý³ÌÖУ¬Docker DaemonºÍdockerinit¾Íͨ¹ýpipe½øÐÐͨÐÅ£¬µ±Docker DaemonÍê³Éveth-pairµÄ´´½¨Ö®Ç°£¬dockerinitÔڹܵÀµÄÁíÒ»¶ËÑ­»·µÈ´ý£¬Ö±µ½¹ÜµÀÁíÒ»¶Ë´«À´Docker Daemon¹ØÓÚvethÉ豸µÄÐÅÏ¢£¬²¢¹Ø±Õ¹ÜµÀ¡£dockerinit²Å½áÊøµÈ´ýµÄ¹ý³Ì£¬²¢°ÑËüµÄ¡°eth0¡±Æô¶¯ÆðÀ´¡£Õû¸öЧ¹ûÀàËÆÏÂͼËùʾ¡£

ͼ2 DockerÍøÂçʾÒâͼ

¸úÆäËûnamespaceÀàËÆ£¬¶Ônetwork namespaceµÄʹÓÃÆäʵ¾ÍÊÇÔÚ´´½¨µÄʱºòÌí¼ÓCLONE_NEWNET±êʶλ¡£Ò²¿ÉÒÔͨ¹ýÃüÁîÐй¤¾ßip´´½¨network namespace¡£ÔÚ´úÂëÖн¨Á¢ºÍ²âÊÔnetwork namespace½ÏΪ¸´ÔÓ£¬ËùÒÔÏÂÎÄÖ÷Ҫͨ¹ýipÃüÁîÖ±¹ÛµÄ¸ÐÊÜÕû¸önetwork namespaceÍøÂ罨Á¢ºÍÅäÖõĹý³Ì¡£

Ê×ÏÈÎÒÃÇ¿ÉÒÔ´´½¨Ò»¸öÃüÃûΪtest_nsµÄnetwork namespace¡£

# ip netns add test_ns

µ±ipÃüÁ¾ß´´½¨Ò»¸önetwork namespaceʱ£¬»áĬÈÏ´´½¨Ò»¸ö»Ø»·É豸£¨loopback interface£ºlo£©£¬²¢ÔÚ/var/run/netnsĿ¼Ï°ó¶¨Ò»¸ö¹ÒÔØµã£¬Õâ¾Í±£Ö¤Á˾ÍËãnetwork namespaceÖÐûÓнø³ÌÔÚÔËÐÐÒ²²»»á±»ÊÍ·Å£¬Ò²¸øÏµÍ³¹ÜÀíÔ±¶Ôд´½¨µÄnetwork namespace½øÐÐÅäÖÃÌṩÁ˳ä×ãµÄʱ¼ä¡£

ͨ¹ýip netns execÃüÁî¿ÉÒÔÔÚд´½¨µÄnetwork namespaceÏÂÔËÐÐÍøÂç¹ÜÀíÃüÁî¡£

# ip netns exec test_ns ip link list
3: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

ÉÏÃæµÄÃüÁîΪÎÒÃÇչʾÁËн¨µÄnamespaceÏ¿ɼûµÄÍøÂçÁ´½Ó£¬¿ÉÒÔ¿´µ½×´Ì¬ÊÇDOWN,ÐèÒªÔÙͨ¹ýÃüÁîÈ¥Æô¶¯¡£¿ÉÒÔ¿´µ½£¬´ËʱִÐÐpingÃüÁîÊÇÎÞЧµÄ¡£

# ip netns exec test_ns ping 127.0.0.1
connect: Network is unreachable

Æô¶¯ÃüÁîÈçÏ£¬¿ÉÒÔ¿´µ½Æô¶¯ºóÔÙ²âÊԾͿÉÒÔpingͨ¡£

# ip netns exec test_ns ip link set dev lo up
# ip netns exec test_ns ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_req=1 ttl=64 time=0.050 ms
...

ÕâÑùÖ»ÊÇÆô¶¯Á˱¾µØµÄ»Ø»·£¬ÒªÊµÏÖÓëÍⲿnamespace½øÐÐͨÐÅ»¹ÐèÒªÔÙ½¨Ò»¸öÍøÂçÉ豸¶Ô£¬ÃüÁîÈçÏ¡£

# ip link add veth0 type veth peer name veth1
# ip link set veth1 netns test_ns
# ip netns exec test_ns ifconfig veth1 10.1.1.1/24 up
# ifconfig veth0 10.1.1.2/24 up

µÚÒ»ÌõÃüÁî´´½¨ÁËÒ»¸öÍøÂçÉ豸¶Ô£¬ËùÓз¢Ë͵½veth0µÄ°üveth1Ò²ÄܽÓÊÕµ½£¬·´Ö®ÒàÈ»¡£

µÚ¶þÌõÃüÁîÔòÊǰÑveth1ÕâÒ»¶Ë·ÖÅäµ½test_nsÕâ¸önetwork namespace¡£

µÚÈý¡¢µÚËÄÌõÃüÁî·Ö±ð¸øtest_nsÄÚ²¿ºÍÍⲿµÄÍøÂçÉ豸ÅäÖÃIP£¬veth1µÄIPΪ10.1.1.1£¬veth0µÄIPΪ10.1.1.2¡£

´ËʱÁ½±ß¾Í¿ÉÒÔ»¥ÏàÁ¬Í¨ÁË£¬Ð§¹ûÈçÏ¡£

# ping 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_req=1 ttl=64 time=0.095 ms
...
# ip netns exec test_ns ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_req=1 ttl=64 time=0.049 ms
...

¶ÁÕßÓÐÐËȤ¿ÉÒÔͨ¹ýÏÂÃæµÄÃüÁî²é¿´£¬ÐµÄtest_nsÓÐ×Å×Ô¼º¶ÀÁ¢µÄ·ÓɺÍiptables¡£

ip netns exec test_ns route
ip netns exec test_ns iptables -L

·ÓɱíÖÐÖ»ÓÐÒ»ÌõͨÏò10.1.1.2µÄ¹æÔò£¬´ËʱÈç¹ûÒªÁ¬½ÓÍâÍø¿Ï¶¨ÊDz»¿ÉÄܵģ¬Äã¿ÉÒÔͨ¹ý½¨Á¢ÍøÇÅ»òÕßNATÓ³ÉäÀ´¾ö¶¨Õâ¸öÎÊÌâ¡£Èç¹ûÄã¶Ô´Ë·Ç³£¸ÐÐËȤ£¬¿ÉÒÔÔĶÁDockerÍøÂçÏà¹ØÎÄÕ½øÐиüÉîÈëµÄ½²½â¡£

×öÍêÕâЩʵÑ飬Ä㻹¿ÉÒÔͨ¹ýÏÂÃæµÄÃüÁîɾ³ýÕâ¸önetwork namespace¡£

# ip netns delete netns1

ÕâÌõÃüÁî»áÒÆ³ý֮ǰµÄ¹ÒÔØ£¬µ«ÊÇÈç¹ûnamespace±¾Éí»¹Óнø³ÌÔËÐУ¬namespace»¹»á´æÔÚÏÂÈ¥£¬Ö±µ½½ø³ÌÔËÐнáÊø¡£

ͨ¹ýnetwork namespaceÎÒÃÇ¿ÉÒÔÁ˽⵽£¬Êµ¼ÊÉÏÄں˴´½¨ÁËnetwork namespaceÒÔºó£¬ÕæµÄÊǵõ½ÁËÒ»¸ö±»¸ôÀëµÄÍøÂç¡£µ«ÊÇÎÒÃÇʵ¼ÊÉÏÐèÒªµÄ²»ÊÇÕâÖÖÍêÈ«µÄ¸ôÀ룬¶øÊÇÒ»¸ö¶ÔÓû§À´ËµÍ¸Ã÷¶ÀÁ¢µÄÍøÂçʵÌ壬ÎÒÃÇÐèÒªÓëÕâ¸öʵÌåͨÐÅ¡£ËùÒÔDockerµÄÍøÂçÔÚÆð²½½×¶Î¸øÈËÒ»Öַdz£ÄÑÓõĸоõ£¬ÒòΪһÇж¼Òª×Ô¼ºÈ¥ÊµÏÖ¡¢È¥ÅäÖá£ÄãÐèÒªÒ»¸öÍøÇÅ»òÕßNATÁ¬½Ó¹ãÓòÍø£¬ÄãÐèÒªÅäÖ÷ÓɹæÔòÓëËÞÖ÷»úÖÐÆäËûÈÝÆ÷½øÐбØÒªµÄ¸ôÀ룬ÄãÉõÖÁ»¹ÐèÒªÅäÖ÷À»ðǽÒÔ±£Ö¤°²È«µÈµÈ¡£ËùÐÒÕâÒ»ÇÐÒѾ­ÓÐÁ˽ÏΪ³ÉÊìµÄ·½°¸£¬ÎÒÃÇ»áÔÚDockerÍøÂ粿·Ö½øÐÐÏêϸµÄ½²½â¡£

7. User namespaces

User namespaceÖ÷Òª¸ôÀëÁ˰²È«Ïà¹ØµÄ±êʶ·û£¨identifiers£©ºÍÊôÐÔ£¨attributes£©£¬°üÀ¨Óû§ID¡¢Óû§×éID¡¢rootĿ¼¡¢key£¨Ö¸ÃÜÔ¿£©ÒÔ¼°ÌØÊâȨÏÞ¡£ËµµÃͨË×Ò»µã£¬Ò»¸öÆÕͨÓû§µÄ½ø³Ìͨ¹ýclone()´´½¨µÄнø³ÌÔÚÐÂuser namespaceÖпÉÒÔÓµÓв»Í¬µÄÓû§ºÍÓû§×é¡£ÕâÒâζ×ÅÒ»¸ö½ø³ÌÔÚÈÝÆ÷ÍâÊôÓÚÒ»¸öûÓÐÌØÈ¨µÄÆÕͨÓû§£¬µ«ÊÇËû´´½¨µÄÈÝÆ÷½ø³ÌÈ´ÊôÓÚÓµÓÐËùÓÐȨÏ޵ij¬¼¶Óû§£¬Õâ¸ö¼¼ÊõΪÈÝÆ÷ÌṩÁ˼«´óµÄ×ÔÓÉ¡£

User namespaceÊÇĿǰµÄÁù¸önamespaceÖÐ×îºóÒ»¸öÖ§³ÖµÄ£¬²¢ÇÒÖ±µ½LinuxÄÚºË3.8°æ±¾µÄʱºò»¹Î´ÍêȫʵÏÖ£¨»¹Óв¿·ÖÎļþϵͳ²»Ö§³Ö£©¡£ÒòΪuser namespaceʵ¼ÊÉϲ¢²»ËãÍêÈ«³ÉÊ죬ºÜ¶à·¢Ðа浣ÐݲȫÎÊÌ⣬ÔÚ±àÒëÄں˵Äʱºò²¢Î´¿ªÆôUSER_NS¡£Êµ¼ÊÉÏĿǰDockerÒ²»¹²»Ö§³Öuser namespace£¬µ«ÊÇÔ¤ÁôÁËÏàÓ¦½Ó¿Ú£¬ÏàÐÅÔÚ²»¾Ãºó¾Í»áÖ§³ÖÕâÒ»ÌØÐÔ¡£ËùÒÔÔÚ½øÐнÓÏÂÀ´µÄ´úÂëʵÑéʱ£¬ÇëÈ·±£ÄãϵͳµÄLinuxÄں˰汾¸ßÓÚ3.8²¢ÇÒÄں˱àÒëʱ¿ªÆôÁËUSER_NS£¨Èç¹ûÄã²»»áÑ¡Ôñ£¬¿ÉÒÔʹÓÃUbuntu14.04£©¡£

LinuxÖУ¬ÌØÈ¨Óû§µÄuser ID¾ÍÊÇ0£¬ÑÝʾµÄ×îÖÕÎÒÃǽ«¿´µ½user ID·Ç0µÄ½ø³ÌÆô¶¯user namespaceºóuser ID¿ÉÒÔ±äΪ0¡£Ê¹ÓÃuser namespaceµÄ·½·¨¸ú±ðµÄnamespaceÏàͬ£¬¼´µ÷ÓÃclone()»òunshare()ʱ¼ÓÈëCLONE_NEWUSER±êʶλ¡£ÀÏÑù×Ó£¬Ð޸ĴúÂë²¢Áí´æÎªuserns.c£¬ÎªÁË¿´µ½Óû§È¨ÏÞ(Capabilities)£¬¿ÉÄÜÄ㻹ÐèÒª°²×°Ò»ÏÂlibcap-dev°ü¡£

Ê×ÏȰüº¬ÒÔÏÂÍ·ÎļþÒÔµ÷ÓÃCapabilities°ü¡£

#include <sys/capability.h>

Æä´ÎÔÚ×Ó½ø³Ìº¯ÊýÖмÓÈëgeteuid()ºÍgetegid()µÃµ½namespaceÄÚ²¿µÄuser ID£¬Æä´Îͨ¹ýcap_get_proc()µÃµ½µ±Ç°½ø³ÌµÄÓû§ÓµÓеÄȨÏÞ£¬²¢Í¨¹ýcap_to_text£¨£©Êä³ö¡£

int child_main(void* args) {
printf("ÔÚ×Ó½ø³ÌÖÐ!\n");
cap_t caps;
printf("eUID = %ld; eGID = %ld; ",
(long) geteuid(), (long) getegid());
caps = cap_get_proc();
printf("capabilities: %s\n", cap_to_text(caps, NULL));
execv(child_args[0], child_args);
return 1;
}

ÔÚÖ÷º¯ÊýµÄclone()µ÷ÓÃÖмÓÈëÎÒÃÇÊìϤµÄ±êʶ·û¡£

//[...]
int child_pid = clone(child_main, child_stack+STACK_SIZE,
CLONE_NEWUSER | SIGCHLD, NULL);
//[...]

ÖÁ´Ë£¬µÚÒ»²¿·ÖµÄ´úÂëÐ޸ľͽáÊøÁË¡£ÔÚ±àÒë֮ǰÎÒÃÇÏȲ鿴һϵ±Ç°Óû§µÄuidºÍguid£¬Çë×¢Òâ´ËʱÎÒÃÇÊÇÆÕͨÓû§¡£

$ id -u
1000
$ id -g
1000

È»ºóÎÒÃÇ¿ªÊ¼±àÒëÔËÐУ¬²¢½øÐÐн¨µÄuser namespace£¬Äã»á·¢ÏÖshellÌáʾ·ûǰµÄÓû§ÃûÒѾ­±äΪnobody¡£

sun@ubuntu$ gcc userns.c -Wall -lcap -o userns.o && ./userns.o
³ÌÐò¿ªÊ¼:
ÔÚ×Ó½ø³ÌÖÐ!
eUID = 65534; eGID = 65534; capabilities: = cap_chown,cap_dac_override,[...]37+ep <<--´Ë´¦Ê¡ÂÔ²¿·ÖÊä³ö£¬ÒÑÓµÓÐÈ«²¿È¨ÏÞ
nobody@ubuntu$

ͨ¹ýÑéÖ¤ÎÒÃÇ¿ÉÒԵõ½ÒÔÏÂÐÅÏ¢¡£

user namespace±»´´½¨ºó£¬µÚÒ»¸ö½ø³Ì±»¸³ÓèÁ˸ÃnamespaceÖеÄÈ«²¿È¨ÏÞ£¬ÕâÑùÕâ¸öinit½ø³Ì¾Í¿ÉÒÔÍê³ÉËùÓбØÒªµÄ³õʼ»¯¹¤×÷£¬¶ø²»»áÒòȨÏÞ²»×ã¶ø³öÏÖ´íÎó¡£

ÎÒÃÇ¿´µ½namespaceÄÚ²¿¿´µ½µÄUIDºÍGIDÒѾ­ÓëÍⲿ²»Í¬ÁË£¬Ä¬ÈÏÏÔʾΪ65534£¬±íʾÉÐδÓëÍⲿnamespaceÓû§Ó³Éä¡£ÎÒÃÇÐèÒª¶Ôuser namespaceÄÚ²¿µÄÕâ¸ö³õʼuserºÍÆäÍⲿnamespaceij¸öÓû§½¨Á¢Ó³É䣬ÕâÑù¿ÉÒÔ±£Ö¤µ±Éæ¼°µ½Ò»Ð©¶ÔÍⲿnamespaceµÄ²Ù×÷ʱ£¬ÏµÍ³¿ÉÒÔ¼ìÑéÆäȨÏÞ£¨±ÈÈç·¢ËÍÒ»¸öÐźŻò²Ù×÷ij¸öÎļþ£©¡£Í¬ÑùÓû§×éÒ²Òª½¨Á¢Ó³Éä¡£

»¹ÓÐÒ»µãËäÈ»²»ÄÜ´ÓÊä³öÖп´³öÀ´£¬µ«ÊÇÖµµÃ×¢Òâ¡£Óû§ÔÚÐÂnamespaceÖÐÓÐÈ«²¿È¨ÏÞ£¬µ«ÊÇËûÔÚ´´½¨ËûµÄ¸¸namespaceÖв»º¬ÈκÎȨÏÞ¡£¾ÍËãµ÷Óúʹ´½¨ËûµÄ½ø³ÌÓÐÈ«²¿È¨ÏÞÒ²ÊÇÈç´Ë¡£ËùÒÔÄÄÅÂÊÇrootÓû§µ÷ÓÃÁËclone()ÔÚuser namespaceÖд´½¨³öµÄÐÂÓû§ÔÚÍⲿҲûÓÐÈκÎȨÏÞ¡£

×îºó£¬user namespaceµÄ´´½¨ÆäʵÊÇÒ»¸ö²ã²ãǶÌ×µÄÊ÷×´½á¹¹¡£×îÉϲãµÄ¸ù½Úµã¾ÍÊÇroot namespace£¬Ð´´½¨µÄÿ¸öuser namespace¶¼ÓÐÒ»¸ö¸¸½Úµãuser namespaceÒÔ¼°Áã¸ö»ò¶à¸ö×Ó½Úµãuser namespace£¬ÕâÒ»µãÓëPID namespace·Ç³£ÏàËÆ¡£

½ÓÏÂÀ´ÎÒÃǾÍÒª½øÐÐÓû§°ó¶¨²Ù×÷£¬Í¨¹ýÔÚ/proc/[pid]/uid_mapºÍ/proc/[pid]/gid_mapÁ½¸öÎļþÖÐдÈë¶ÔÓ¦µÄ°ó¶¨ÐÅÏ¢¿ÉÒÔʵÏÖÕâÒ»µã£¬¸ñʽÈçÏ¡£

ID-inside-ns   ID-outside-ns   length

дÕâÁ½¸öÎļþÐèҪעÒâÒÔϼ¸µã¡£

ÕâÁ½¸öÎļþÖ»ÔÊÐíÓÉÓµÓиÃuser namespaceÖÐCAP_SETUIDȨÏ޵Ľø³ÌдÈëÒ»´Î£¬²»ÔÊÐíÐ޸ġ£

дÈëµÄ½ø³Ì±ØÐëÊǸÃuser namespaceµÄ¸¸namespace»òÕß×Ónamespace¡£

µÚÒ»¸ö×Ö¶ÎID-inside-ns±íʾн¨µÄuser namespaceÖжÔÓ¦µÄuser/group ID£¬µÚ¶þ¸ö×Ö¶ÎID-outside-ns±íʾnamespaceÍⲿӳÉäµÄuser/group ID¡£×îºóÒ»¸ö×ֶαíʾӳÉ䷶Χ£¬Í¨³£Ìî1£¬±íʾֻӳÉäÒ»¸ö£¬Èç¹ûÌî´óÓÚ1µÄÖµ£¬Ôò°´Ë³Ðò½¨Á¢Ò»Ò»Ó³Éä¡£

Ã÷°×ÁËÉÏÊöÔ­Àí£¬ÎÒÃÇÔÙ´ÎÐ޸ĴúÂ룬Ìí¼ÓÉèÖÃuidºÍguidµÄº¯Êý¡£

//[...]
void set_uid_map(pid_t pid, int inside_id, int outside_id, int length) {
char path[256];
sprintf(path, "/proc/%d/uid_map", getpid());
FILE* uid_map = fopen(path, "w");
fprintf(uid_map, "%d %d %d", inside_id, outside_id, length);
fclose(uid_map);
}
void set_gid_map(pid_t pid, int inside_id, int outside_id, int length) {
char path[256];
sprintf(path, "/proc/%d/gid_map", getpid());
FILE* gid_map = fopen(path, "w");
fprintf(gid_map, "%d %d %d", inside_id, outside_id, length);
fclose(gid_map);
}
int child_main(void* args) {
cap_t caps;
printf("ÔÚ×Ó½ø³ÌÖÐ!\n");
set_uid_map(getpid(), 0, 1000, 1);
set_gid_map(getpid(), 0, 1000, 1);
printf("eUID = %ld; eGID = %ld; ",
(long) geteuid(), (long) getegid());
caps = cap_get_proc();
printf("capabilities: %s\n", cap_to_text(caps, NULL));
execv(child_args[0], child_args);
return 1;
}
//[...]

±àÒëºó¼´¿É¿´µ½userÒѾ­±ä³ÉÁËroot¡£

$ gcc userns.c -Wall -lcap -o usernc.o && ./usernc.o
³ÌÐò¿ªÊ¼:
ÔÚ×Ó½ø³ÌÖÐ!
eUID = 0; eGID = 0; capabilities: = [...],37+ep
root@ubuntu:~#

ÖÁ´Ë£¬Äã¾ÍÒѾ­Íê³ÉÁ˰󶨵Ť×÷£¬¿ÉÒÔ¿´µ½ÑÝʾȫ³Ì¶¼ÊÇÔÚÆÕͨÓû§ÏÂÖ´Ðеġ£×îÖÕʵÏÖÁËÔÚuser namespaceÖгÉΪÁËroot¶ø¶ÔÓ¦µ½ÍâÃæµÄÊÇÒ»¸öuidΪ1000µÄÆÕͨÓû§¡£

Èç¹ûÄãÒª°Ñuser namespaceÓëÆäËûnamespace»ìºÏʹÓã¬ÄÇôÒÀ¾ÉÐèÒªrootȨÏÞ¡£½â¾ö·½°¸¿ÉÒÔÊÇÏÈÒÔÆÕͨÓû§Éí·Ý´´½¨user namespace£¬È»ºóÔÚн¨µÄnamespaceÖÐ×÷ΪrootÔÙclone()½ø³Ì¼ÓÈëÆäËûÀàÐ͵Änamespace¸ôÀë¡£

½²ÍêÁËuser namespace£¬ÎÒÃÇÔÙÀ´Ì¸Ì¸Docker¡£ËäÈ»DockerĿǰÉÐδʹÓÃuser namespace£¬µ«ÊÇËûÓõ½ÁËÎÒÃÇÔÚuser namespaceÖÐÌá¼°µÄCapabilities»úÖÆ¡£´ÓÄÚºË2.2°æ±¾¿ªÊ¼£¬Linux°ÑÔ­À´ºÍ³¬¼¶Óû§Ïà¹ØµÄ¸ß¼¶È¨ÏÞ»®·Ö³ÉΪ²»Í¬µÄµ¥Ôª£¬³ÆÎªCapability¡£ÕâÑù¹ÜÀíÔ±¾Í¿ÉÒÔ¶ÀÁ¢¶ÔÌØ¶¨µÄCapability½øÐÐʹÄÜ»ò½ûÖ¹¡£DockerËäȻûÓÐʹÓÃuser namespace£¬µ«ÊÇËû¿ÉÒÔ½ûÓÃÈÝÆ÷Öв»ÐèÒªµÄCapability£¬Ò»´ÎÔÚÒ»¶¨³Ì¶ÈÉϼÓÇ¿ÈÝÆ÷°²È«ÐÔ¡£

µ±È»£¬Ëµµ½°²È«£¬namespaceµÄÁùÏî¸ôÀë¿´ËÆÈ«Ãæ£¬Êµ¼ÊÉÏÒÀ¾ÉûÓÐÍêÈ«¸ôÀëLinuxµÄ×ÊÔ´£¬±ÈÈçSELinux¡¢ CgroupsÒÔ¼°/sys¡¢/proc/sys¡¢/dev/sd*µÈĿ¼ÏµÄ×ÊÔ´¡£¹ØÓÚ°²È«µÄ¸ü¶àÌÖÂۺͽ²½â£¬ÎÒÃÇ»áÔÚºóÎÄÖнÓ×Å̽ÌÖ¡£

8. ×ܽá

±¾ÎÄ´ÓnamespaceʹÓõÄAPI¿ªÊ¼£¬½áºÏDockerÖð²½¶ÔÁù¸önamespace½øÐн²½â¡£ÏàÐŰѽ²½â¹ý³ÌÖÐËùÓеĴúÂëÕûºÏÆðÀ´£¬ÄãÒ²ÄÜʵÏÖÒ»¸öÊôÓÚ×Ô¼ºµÄ¡°shell¡±ÈÝÆ÷ÁË¡£ËäÈ»namespace¼¼ÊõʹÓÃÆðÀ´·Ç³£¼òµ¥£¬µ«ÊÇÒªÕæÕý°ÑÈÝÆ÷×öµ½°²È«Ò×ÓÃÈ´²¢·ÇÒ×Ê¡£PID namespaceÖУ¬ÎÒÃÇҪʵÏÖÒ»¸öÍêÉÆµÄinit½ø³ÌÀ´Î¬»¤ºÃËùÓнø³Ì£»network namespaceÖУ¬ÎÒÃÇ»¹Óи´ÔӵķÓɱíºÍiptables¹æÔòûÓÐÅäÖã»user namespaceÖл¹ÓкܶàȨÏÞÉϵÄÎÊÌâÐèÒª¿¼Âǵȵȡ£ÆäÖÐÓÐЩ·½ÃæDockerÒѾ­×öµÄºÜºÃ£¬ÓÐЩ·½ÃæÒ²²Å¸Õ¸Õ¿ªÊ¼¡£Ï£Íûͨ¹ý±¾ÎÄ£¬ÄÜΪ´ó¼Ò¸üºÃµÄÀí½âDocker±³ºóÔËÐеÄÔ­ÀíÌṩ°ïÖú¡£

   
2197 ´Îä¯ÀÀ       27
 
Ïà¹ØÎÄÕÂ

ÔÆ¼ÆËãµÄ¼Ü¹¹
¶ÔÔÆ¼ÆËã·þÎñÄ£ÐÍ
ÔÆ¼ÆËãºËÐļ¼ÊõÆÊÎö
Á˽âÔÆ¼ÆËãµÄ©¶´
 
Ïà¹ØÎĵµ

ÔÆ¼ÆËã¼ò½é
ÔÆ¼ÆËã¼ò½éÓëÔÆ°²È«
ÏÂÒ»´úÍøÂç¼ÆËã--ÔÆ¼ÆËã
ÈídzÎöÔÆ¼ÆËã
 
Ïà¹Ø¿Î³Ì

ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ
ÔÆ¼ÆËãÓ¦ÓÃÓ뿪·¢
CMMIÌåϵÓëʵ¼ù
»ùÓÚCMMI±ê×¼µÄÈí¼þÖÊÁ¿±£Ö¤
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

ר¼ÒÊӽǿ´ITÓë¼Ü¹¹
Èí¼þ¼Ü¹¹Éè¼Æ
ÃæÏò·þÎñÌåϵ¼Ü¹¹ºÍÒµÎñ×é¼þµÄ˼¿¼
ÈËÈËÍøÒÆ¶¯¿ª·¢¼Ü¹¹
¼Ü¹¹¸¯»¯Ö®ÃÕ
̸ƽ̨¼´·þÎñPaaS
Ïà¹ØÅàѵ¿Î³Ì

ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ
Windows Azure ÔÆ¼ÆËãÓ¦ÓÃ

ĦÍÐÂÞÀ­ ÔÆÆ½Ì¨µÄ¹¹½¨ÓëÓ¦ÓÃ
ͨÓù«Ë¾GE DockerÔ­ÀíÓëʵ¼ù
ijÑз¢ÖÐÐÄ Openstackʵ¼ù
ÖªÃûµç×Ó¹«Ë¾ ÔÆÆ½Ì¨¼Ü¹¹ÓëÓ¦ÓÃ
ijµçÁ¦ÐÐÒµ »ùÓÚÔÆÆ½Ì¨¹¹½¨ÔÆ·þÎñ
ÔÆ¼ÆËãÓëWindows AzureÅàѵ
±±¾© ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ