namespace介紹:
linux namespace 是kernel 的一個功能重慢,他可以隔離一系列的資源饥臂,比如PID ,UsrID,Network
當(dāng)前l(fā)inux 一共實現(xiàn)了6種不同類型的NameSpace
接下來我們看看怎么用go語言來調(diào)用namespace來實現(xiàn)環(huán)境隔離。
(1)UTS NameSpace 主要用來隔離nodename和domainname
package main
import (
"os/exec"
"syscall"
"os"
"log"
)
/**
因為要使用linux 內(nèi)核似踱,所以不能在其他平臺上運行
*/
func main() {
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS,
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err!=nil{
log.Fatal(err)
}
}
驗證
執(zhí)行代碼隅熙,查看進程信息
go run utsnamespace.go
pstree -pl
很明顯可以看到 父進程和 子進程不在一個uts中
(2)IPC NameSpace用來隔離System v IPC 和 POSIX message queues
package main
import (
"os/exec"
"syscall"
"os"
"log"
)
/**
因為要使用linux 內(nèi)核,所以不能在其他平臺上運行
*/
func main() {
//sh 為被fork 出的新進場的初始命令
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS |syscall.CLONE_NEWIPC,
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err!=nil{
log.Fatal(err)
}
}
驗證
在宿主機上開個終端
ipcs -q 無queue
ipcmk -Q 創(chuàng)建queue
ipcs -q 查看發(fā)現(xiàn)有一個queue
此時運行ipcnamespace.go
gor run ipcnamespace.go
ipcs -q 無queue
說明 該環(huán)境和外部是隔離的
(3)PID Namespace ,用來隔離進程ID. 例如某個進程在容器里面 的進程pid 和在宿主機上查看是不一樣的核芽。
package main
import (
"os/exec"
"syscall"
"os"
"log"
)
/**
因為要使用linux 內(nèi)核囚戚,所以不能在其他平臺上運行
*/
func main() {
//sh 為被fork 出的新進場的初始命令
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS |syscall.CLONE_NEWIPC|syscall.CLONE_NEWPID,
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err!=nil{
log.Fatal(err)
}
}
驗證
運行pidnamespace.go ,查看pid 為1
其在宿主機的pid為15814
(4)Mount Namespace 用來隔離各個進程看到的掛載點試圖
package main
import (
"os/exec"
"syscall"
"os"
"log"
)
/**
因為要使用linux 內(nèi)核轧简,所以不能在其他平臺上運行
*/
func main() {
//sh 為被fork 出的新進場的初始命令
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS |syscall.CLONE_NEWIPC|syscall.CLONE_NEWPID|syscall.CLONE_NEWNS,
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err!=nil{
log.Fatal(err)
}
}
驗證:
go mountnamespace.go
ls /proc 查看(此時文件還比較多)
mount -t proc proc /proc 將proc 掛載到我們自己的namespace下
ls /proc 查看(少了許多)
(5)User Namespace 主要用來隔離用戶的用戶組ID 比較常用的是 在宿主機上以一個非root用戶運行創(chuàng)建一個User Namespace 然后在User Namespace映射成root
package main
import (
"os/exec"
"syscall"
"os"
"log"
)
/**
因為要使用linux 內(nèi)核驰坊,所以不能在其他平臺上運行
*/
func main() {
//sh 為被fork 出的新進場的初始命令
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS |syscall.CLONE_NEWIPC|syscall.CLONE_NEWPID|syscall.CLONE_NEWNS|syscall.CLONE_NEWUSER,
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err!=nil{
log.Fatal(err)
}
}
驗證 (內(nèi)核版本要3.8以上,我一開始使用的是2.6.32的就無法創(chuàng)建User Namespace)
(6)Network NameSpace 主要用來隔離網(wǎng)絡(luò)設(shè)備哮独、IP地址端口等網(wǎng)絡(luò)棧
package main
import (
"os/exec"
"syscall"
"os"
"log"
)
/**
因為要使用linux 內(nèi)核拳芙,所以不能在其他平臺上運行
*/
func main() {
//sh 為被fork 出的新進場的初始命令
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS |syscall.CLONE_NEWIPC|syscall.CLONE_NEWPID|syscall.CLONE_NEWNS|syscall.CLONE_NEWUSER|syscall.CLONE_NEWNET,
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err!=nil{
log.Fatal(err)
}
}
驗證
在宿主機上執(zhí)行ifconfig 可以看到有eth0 和 lo 網(wǎng)絡(luò)設(shè)備
運行networknamespace.go,在此環(huán)境下無網(wǎng)絡(luò)設(shè)備