Skip to content

3-2. UTS Namespace

さあ次はいよいよ、Namespaceで遊んでみましょう!

【前提】この節で扱うsyscall

unshare

独立したNamespaceを作り今いるプロセスをそのNamespaceに所属させます。

go
func Unshare(flags int) (err error)

どのNamespaceを分けるかflagsで指定できます。
使えるflagsunixパッケージでconstとして定義されています。

go
const (
  CLONE_NEWCGROUP = 0x2000000
  CLONE_NEWIPC    = 0x8000000
  CLONE_NEWNET    = 0x40000000
  CLONE_NEWNS     = 0x20000
  CLONE_NEWPID    = 0x20000000
  CLONE_NEWTIME   = 0x80
  CLONE_NEWUSER   = 0x10000000
  CLONE_NEWUTS    = 0x4000000
)

UTS Namespaceを分けてみる

UTS Namespaceは、hostnameの設定を分けることができるNamespaceです。
Namespace同士が異なるホスト名を持つことができますし、ホスト名の変更が互いに影響を及ぼしません

早速unix.Unshareを使ってNamespaceを分離してみましょう!

ヒント

UTC Namespaceのflagsunix.CLONE_NEWUTSです!

想定解答

想定解答
go
// runサブコマンド
func runCommand(c Config) error {
  // Namespaceを分離
  if err := unix.Unshare(unix.CLONE_NEWUTS); err != nil { 
    return errors.WithStack(err) 
  } 

  // cgroupの設定
  if err := SetupCgroup(c.Name, os.Getpid(), c.Cgroup); err != nil {
    return errors.WithStack(err)
  }

  // rootfsの設定
  _ = unix.Unshare(unix.CLONE_NEWNS) // rootfsで使うので、Namespace系の処理だが仮置き
  if err := SetupRootfs(c.Rootfs); err != nil {
    return errors.WithStack(err)
  }

  // 作成した簡易コンテナ内でエントリーポイントを実行
  path, err := exec.LookPath(c.EntryPoint[0])
  if err != nil {
    return errors.WithStack(err)
  }
  if err := unix.Exec(path, c.EntryPoint, os.Environ()); err != nil {
    return errors.WithStack(err)
  }

  return nil
}

Namespaceが分かれたことを確かめる

hostnameをNamespace内で設定しても元のシェルに影響を及ぼさないことを確かめましょう。
Namespaceの分離にはroot権限が必要なので、sudo suを実行してrootになってからプログラムを実行して下さい。

  • hostname: ホスト名表示
  • hostname {文字列}: ホスト名を変更
console
$ sudo su
# make run
go build -o main *.go
./main run bash
# hostname
HOST-MACHINE
# hostname container1
# hostname
container1
# exit
exit
# hostname
HOST-MACHINE
#