#コンテナを理解するためにコンテナを自分で"造る"
今回はこちらを参考にして自作コンテナを作ってみる。
#コンテナとは
詳しくは他の方の説明を受けてください。
#Goでコンテナを"造る"
##環境
今回はVMware
でUbuntu
を稼働させ、VM
上で造りました。
Ubuntu 20.04 LTS 64-bit
go version go1.13.8 linux/amd64
##まずはコンテナのルートディレクトリとなるFile Systemを作る
/home/rootfs
ディレクトリ下に今回のルートディレクトリとなるFile System(fs)
を作成します。
/home/rootfs/
├── bin
├── lib
├── lib32
├── lib64
├── proc \\空のディレクトリ
└── sbin
bin
,lib
,lib32
,lib64
,sbin
ディレクトリは/usr
ディレクトリ下と同じものをコピーしました。
proc
ディレクトリは空の状態で作成しておきます。
※今回はただコンテナとして動くことだけを目的としているので最小のfs
にしています。
##コンテナを稼働させるsrc
【Go】
src
は次のようにしました。
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
)
func main() {
switch os.Args[1] {
case "run":
run()
case "child":
child()
default:
panic("what??")
}
}
func run() {
cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID,
}
must(cmd.Run())
}
func child() {
fmt.Printf("running %v as PID %d\n", os.Args[2:], os.Getpid())
cmd := exec.Command(os.Args[2], os.Args[3:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
must(syscall.Chroot("/home/rootfs"))
must(os.Chdir("/"))
must(syscall.Mount("proc", "proc", "proc", 0, ""))
must(cmd.Run())
}
func must(err error) {
if err != nil {
panic(err)
}
}
##実際にコンテナを起動してみる
###まずはホストのfs
とProcess
の確認
Terminal
でホストのfs
を確認しましょう。
~$ cd /
~$ ls
bin dev lib libx32 mnt root snap sys var
boot etc lib32 lost+found opt run srv tmp
cdrom home lib64 media proc sbin swapfile usr
次に、ホストのProcess
を確認
~$ ps
PID TTY TIME CMD
1927 pts/0 00:00:00 bash
2950 pts/0 00:00:00 ps
PID(Process ID)
が大きい値であるのが確認できます。
###コンテナを起動
満を持してコンテナを起動しましょう。
先ほどのsrc
があるディレクトリに移動し、Terminal
で次のようにコマンドを入力します。
~:/home/{username}/{directoryname}$ sudo go run main.go run /bin/bash
running [/bin/bash] as PID 1
bash-5.0#
おめでとうございます!
コンテナが起動しました!
##コンテナがコンテナであるか確認する
ホストの時と同じようにfs
とProcess
を確認してみましょう。
bash-5.0# cd /
bash-5.0# ls
bin lib lib32 lib64 proc sbin
コンテナ内で/
ディレクトリに移動してもホストの/home/rootfs
ディレクトリに移動しますね。
bash-5.0# ps
PID TTY TIME CMD
1 ? 00:00:00 exe
6 ? 00:00:00 bash
8 ? 00:00:00 ps
PID
ちゃんと小さい値です。
ついでにhistory
も確認しておきましょう。
bash-5.0# history
1 cd /
2 ls
3 ps
4 history
history
もコンテナ内の記録しか表示されません。
###最後にコンテナを停止するには
コンテナ内でexit
と入力すればOK
bash-5.0# exit
~:/home/{username}/{directoryname}$