LXC容器有许多HOOK,通过指定这些HOOK对应的脚本,可以在容器的各个阶段做一些处理。
但是有些小伙伴不知道如何正确使用这些HOOK。
下面是官方对这些HOOK的解释:
- lxc.hook.pre-start (called before any initialization is done)
- lxc.hook.pre-mount (called after creating the mount namespace but before mounting anything)
- lxc.hook.mount (called after the mounts but before pivot_root)
- lxc.hook.autodev (identical to mount but only called if using autodev)
- lxc.hook.start (called in the container right before /sbin/init)
- lxc.hook.post-stop (run after the container has been shutdown)
- lxc.hook.clone (called when cloning a container into a new one)
但是这些解释还是有些难以理解,比方说pre_start指定的脚本到底在哪个名字空间运行呢?下面我们来验证一下:
首先我们写几个脚本pre_start.sh, pre_mount.sh
pre_mount.sh
#!/bin/sh set -e ls -la /proc/self/ns > /var/pre-mount-ns.txt
pre_start.sh
#!/bin/sh ls -la /proc/self/ns > /var/pre-start-ns.txt
然后我们将这些脚本链接到lxc configure文件的HOOK上:
lxc.hook.pre-start = /var/lib/lxc/ns1/pre_start.sh lxc.hook.pre-mount = /var/lib/lxc/ns1/pre_mount.sh
然后我们启动这个容器,之后我们再检查下/var/pre-mount-ns.txt和/var/pre-start-ns.txt的内容:
[router] # cat /var/pre-mount-ns.txt dr-x--x--x 2 root root 0 Mar 30 21:48 . dr-xr-xr-x 8 root root 0 Mar 30 21:48 .. lrwxrwxrwx 1 root root 0 Mar 30 21:48 ipc -> ipc:[4026532790] lrwxrwxrwx 1 root root 0 Mar 30 21:48 mnt -> mnt:[4026532788] lrwxrwxrwx 1 root root 0 Mar 30 21:48 net -> net:[4026532793] lrwxrwxrwx 1 root root 0 Mar 30 21:48 pid -> pid:[4026532791] lrwxrwxrwx 1 root root 0 Mar 30 21:48 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 Mar 30 21:48 uts -> uts:[4026532789] [router] # cat /var/pre-start-ns.txt dr-x--x--x 2 root root 0 Mar 30 21:48 . dr-xr-xr-x 8 root root 0 Mar 30 21:48 .. lrwxrwxrwx 1 root root 0 Mar 30 21:48 ipc -> ipc:[4026531839] lrwxrwxrwx 1 root root 0 Mar 30 21:48 mnt -> mnt:[4026531840] lrwxrwxrwx 1 root root 0 Mar 30 21:48 net -> net:[4026531885] lrwxrwxrwx 1 root root 0 Mar 30 21:48 pid -> pid:[4026531836] lrwxrwxrwx 1 root root 0 Mar 30 21:48 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 Mar 30 21:48 uts -> uts:[4026531838]
我们可以看到pre-start和pre-mount的脚本是在不同的名字空间执行的。我们检查一下容器中的某个进程的名字空间:
[router] # ls -la /proc/12440/ns/ dr-x--x--x 2 root root 0 Mar 30 21:52 . dr-xr-xr-x 8 root root 0 Mar 30 21:48 .. lrwxrwxrwx 1 root root 0 Mar 30 21:52 ipc -> ipc:[4026532790] lrwxrwxrwx 1 root root 0 Mar 30 21:52 mnt -> mnt:[4026532788] lrwxrwxrwx 1 root root 0 Mar 30 21:52 net -> net:[4026532793] lrwxrwxrwx 1 root root 0 Mar 30 21:52 pid -> pid:[4026532791] lrwxrwxrwx 1 root root 0 Mar 30 21:52 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 Mar 30 21:52 uts -> uts:[4026532789]
可以看到容器中进程所在的名字空间跟pre-mount脚本所在的名字空间是一样的。
我们再看看host里面的进程所在的名字空间:
[router] # ls -la /proc/1/ns dr-x--x--x 2 root root 0 Mar 30 22:10 . dr-xr-xr-x 8 root root 0 Mar 30 03:47 .. lrwxrwxrwx 1 root root 0 Mar 30 22:10 ipc -> ipc:[4026531839] lrwxrwxrwx 1 root root 0 Mar 30 22:10 mnt -> mnt:[4026531840] lrwxrwxrwx 1 root root 0 Mar 30 22:10 net -> net:[4026531885] lrwxrwxrwx 1 root root 0 Mar 30 22:10 pid -> pid:[4026531836] lrwxrwxrwx 1 root root 0 Mar 30 22:10 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 Mar 30 22:10 uts -> uts:[4026531838] [router] #
可以看到host里面的进程所在的名字空间跟pre-start脚本所在的名字空间是一样的。
这也就说明了pre-start脚本是在host的名字空间里执行的,而pre-mount脚本则是在容器的名字空间里执行的。
理解了上面的区别之后,我们就知道如果是针对host上面的一些操作,需要放在pre-start脚本里执行,如果是针对容器本身的操作,需要放在pre-mount脚本或者start脚本中执行。
比方说我们想在容器中创建一些iptables的规则,则必须放在pre-mount或start脚本里。
 
                     
                    
                 
                    
                 
                
            
         
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号