namespace
user namespace
映射当前用户用户成子进程的root,用来隔离user namespace
子user namespace 在父 user namespace中是普通用户,在子user namespace中是超级用户(超级用户只相对于子user namespace所拥有的资源,无法访问其他user namespace中需要超级用户才能访问资源)。
通过id查看
package main
import (
"log"
"os"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command("/bin/bash")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWUSER
cmd.SysProcAttr.UidMappings = []syscall.SysProcIDMap{
{ContainerID: 0, HostID: syscall.Getuid(), Size: 1},
}
cmd.SysProcAttr.GidMappings = []syscall.SysProcIDMap{
{ContainerID: 0, HostID: syscall.Getgid(), Size: 1},
}
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}
uts namespace
提供主机名和域名的隔离
通过hostname -b xxx 修改hostname来看是否隔离
package main
import (
"log"
"os"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command("/bin/bash")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWUTS
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}
ipc namespace
用来隔离system v ipc 和posix message queues
通过ipcmk -Q创建
ipcs -q 查看是否隔离
ipcrm -Q xxx 来删除
package main
import (
"log"
"os"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command("/bin/bash")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWIPC
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}
pid namespace
隔离进程id
运行后通过echo $$ 查看当前的pid
package main
import (
"log"
"os"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command("/bin/bash")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWPID
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}
mount namespace
隔离各个进程的挂载点视图.
mount namespace中进行的mount,umount不会影响全局
运行后mount -t proc proc /proc
通过ps -ef 确认
package main
import (
"log"
"os"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command("/bin/bash")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWNS | syscall.CLONE_NEWPID
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}
network namespace
隔离网络栈
通过ifconfig来确认
package main
import (
"log"
"os"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command("/bin/bash")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWNET
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}
cgroups
安装stress来测试资源限制
创建目录 /sys/fs/cgroup/memory/stress
package main
import (
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"strconv"
"syscall"
)
const root = "/sys/fs/cgroup/memory/stress"
const self = "/proc/self/exe"
func main() {
if os.Args[0] == self {
cmd := exec.Command("sh", "-c", "stress --vm-bytes 400m --vm-keep -m 1")
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
os.Exit(0)
}
cmd := exec.Command(self)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
log.Fatal(err)
} else {
file := path.Join(root, "cgroup.procs")
if err := ioutil.WriteFile(file, []byte(strconv.Itoa(cmd.Process.Pid)), 0644); err != nil {
log.Fatal(err)
}
file = path.Join(root, "memory.limit_in_bytes")
if err := ioutil.WriteFile(file, []byte("400M"), 0644); err != nil {
log.Fatal(err)
}
}
cmd.Process.Wait()
}
aufs
union file system
把不同文件系统文件和目录形成一个文件系统
aufs
mount -t aufs -o dirs=./dir1:dir2:dir3 none ./mntdir
对./mnt里的写入会反应到./dir1里,不会影响到dir2,dir3