hostname在docker中是使用UTS namespace進行隔離的。docker中主要有兩種ns的用法,
- 一種是
docker run --uts="" busybox
。這種會新創建一個新的uts ns。 - 一種是
docekr run --uts="host" busybox
。這種創建的容器將會使用物理機的uts ns。
在k8s中,是這樣處理的uts的ns的:
func modifyHostNetworkOptionForContainer(hostNetwork bool, sandboxID string, hc *dockercontainer.HostConfig) {
sandboxNSMode := fmt.Sprintf("container:%v", sandboxID)
hc.NetworkMode = dockercontainer.NetworkMode(sandboxNSMode)
hc.IpcMode = dockercontainer.IpcMode(sandboxNSMode)
hc.UTSMode = ""
if hostNetwork {
hc.UTSMode = namespaceModeHost
}
}
這里我們可以關注幾個事情:
-
pause容器和應用容器都是使用獨自的uts namespace。應用容器之間也都是使用獨立的namespace,因此任何一個容器啟動后修改hostname並不會影響到其他的容器。
-
如果判斷是使用物理機網絡就是hostNetwork,則會將uts的mode設置為"host",也就是使用物理機的uts ns。
因此這時候容器修改hostname,也會影響到物理機。
當然,容器如果想要修改hostname(通過hostname命令),需要privileged權限才可以。
修改后容器直接重啟會導致恢復原來的hostname。這個的主要原因是重啟會導致重新創建新的uts namespace。
當然,如果容器重建了,比如exit后又被kubelet創建了一個新的容器,則hostname會再次恢復。
一個pod內有兩個容器,兩個容器修改hostname並不會彼此影響,因為他們的uts namespace是各自獨立的。
通過修改/etc/hostname的方式動態修改運行容器的hostname無效。
以下是完整實驗過程:
//容器啟動時hostname為busyboxtest
[root@node ~]# docker exec 6f5 hostname
busyboxtest
//修改/etc/hostname文件
[root@node ~]# docker exec 6f5 cat /etc/hostname
busyboxtest123
[root@node ~]# docker exec 6f5 hostname test123
//修改后查看hostname為test123
[root@node ~]# docker exec 6f5 hostname
test123
[root@node ~]# docker inspect 6f5|grep Pid
"Pid": 15818,
[root@node ~]# ll /proc/15818/ns/
total 0
lrwxrwxrwx 1 root root 0 Jan 10 16:16 ipc -> ipc:[4026535715]
lrwxrwxrwx 1 root root 0 Jan 10 16:16 mnt -> mnt:[4026535789]
lrwxrwxrwx 1 root root 0 Jan 10 16:16 net -> net:[4026535718]
lrwxrwxrwx 1 root root 0 Jan 10 16:16 pid -> pid:[4026535791]
lrwxrwxrwx 1 root root 0 Jan 10 16:18 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Jan 10 16:16 uts -> uts:[4026535790]
//重啟容器
[root@node ~]# docker restart 6f5
6f5
[root@node ~]# docker inspect 6f5|grep Pid
"Pid": 17553,
//可以看到uts的namespace變化了
[root@node ~]# ll /proc/17553/ns/
total 0
lrwxrwxrwx 1 root root 0 Jan 10 16:19 ipc -> ipc:[4026535715]
lrwxrwxrwx 1 root root 0 Jan 10 16:19 mnt -> mnt:[4026535341]
lrwxrwxrwx 1 root root 0 Jan 10 16:19 net -> net:[4026535718]
lrwxrwxrwx 1 root root 0 Jan 10 16:19 pid -> pid:[4026535714]
lrwxrwxrwx 1 root root 0 Jan 10 16:19 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Jan 10 16:19 uts -> uts:[4026535713]
//hostname恢復
[root@node ~]# docker exec 6f5 hostname
busyboxtest
[root@node ~]# docker exec 6f5 cat /etc/hostname
busyboxtest123