上一篇文章我们分享了容器网络命名空间,Netwrok Namespace虽然解决网络协议栈的隔离,但主机名还没有实现隔离,所以,今天我们一起看一下UTS Namespace。UTS Namespace主要用来隔离主机名和主机域名。每个UTS namespace中都允许有自己的主机名。
虽然有了独立的UTS命名空间,但由于还是共享内核模式,操作系统和版本信息还是无法改变的,只能修改主机名和主机域名。
引入Namespace概念以后,无论是sethostname还是gethostname 都引入了UTS命名空间这个维度。这两个系统调用代码如下,都调用了utsname这个方法:
SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
{
. . .
u = utsname();
. . .
}
SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
{
. . .
u = utsname();
. . .
}
utsname方法实现如下,就是通过nsproxy获取本Namespace下的UTS。关于nsproxy之前关于Namespace概述这篇文章的时候已经介绍过了,有兴趣的童鞋可以回顾一下。
static inline struct new_utsname *utsname(void)
{
return ¤t->nsproxy->uts_ns->name;
}
在前面的文章都分享了一个简单的Demo,创建一个新的命名空间。按照惯例,下面将通过一个Go程序创建一个新的UTS Namespace。后续其他新的Namespace的创建读者可以自行调整参数。
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command("/bin/sh")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = []string{"PS1=-[ns-process]- # "}
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS,
}
if err := cmd.Run(); err != nil {
fmt.Printf("Error running the /bin/sh command - %s
", err)
os.Exit(1)
}
}
通过go build编译后便可以直接“./”运行,此时会启动一个新的UTS Namespace。如下操作:
-[ns-process]- # hostname -b testhost
-[ns-process]- # hostname
testhost
可以看到新的UTS空间内我们重置了主机名,但此并没有修改宿主机的主机名,如果通过exit退出后,发现宿主机的主机名没有发生改变。Docker设置主机名可以通过”-h“参数指定。
[root@test ~]# docker run -it -h testhost busybox sh
/ # hostname
testhost
/ #
如果是k8s中,需要通过hostname指定Pod的主机名,这个主机名k8s是通过只读文件挂载的方式设置到Pause容器上面的,由于Pod直接是共享UTS Namespace的,所以Pod里面每个容器的UTS都是相同的。
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
name: busybox
spec:
hostname: busybox-1
subdomain: default-subdomain
containers:
- image: busybox:1.28
command:
- sleep
- "3600"
name: busybox
页面更新:2024-06-10
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号