Open39

Docker&Kubernetes学習メモ

jnuankjnuank

1章

jnuankjnuank

コンテナ技術は、1つの共有されたOS上(ホストOS)で複数の独立したアプリケーションの実行環境を作成する技術

コンテナ内で実行されるプロセスからは、OS環境を専有しているかのように見え、
アクセスできるシステム上のリソースの多くも、他のコンテナやホストOSとは隔離されている。
-> 必ずしも全部が隔離されているわけではなさそう?

コンテナの中に入ったら、ホストや他のコンテナのプロセスは見れない

docker run -it centos /bin/bash
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
[root@bbbd77021b9a /]# ls /
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@bbbd77021b9a /]# ps ax
  PID TTY      STAT   TIME COMMAND
    1 pts/0    Ss     0:00 /bin/bash
   17 pts/0    R+     0:00 ps ax
jnuankjnuank

仮想マシンとコンテナ技術の違い

  • 仮想マシン:Linux KVMなどを用いた、ハイパーバイザ型の完全仮想技術
    • ハイパーバイザ上で、OSが別途立ち上がっている?
  • コンテナ:Linux上でnamespaceなどの隔離機能により実装されるアプリケーションコンテナ

コンテナ自体には、OSカーネルは含まれていない。
ホスト上のカーネルが提供する環境隔離機能を用いて、独立した実行環境を作り出して実行している。

コンテナ=プロセス

コンテナもイメージも軽量

jnuankjnuank

エコシステム

  • Open Container Initiative(OCI)

    • Linux Foundation傘下プロジェクト
    • コンテナイメージ、コンテナレジストリ、コンテナランタイムの標準仕様を策定
  • Computing Foundation(CNCF)

    • Linux Foundation傘下プロジェクト
    • 様々なOSSプロジェクトがホストされている
      • Kubernetesも含む
jnuankjnuank

DockerとKubernetes

Docker

コンテナにまつわる基本的なワークフロー(Build Ship Run)をサポート
Docker Swarmというオーケストレーション機能あり
-> これについては初めて知った。オーケストレーション機能はKubernetesだけなのかと。

Kubernetes

複数マシンで構成される環境でコンテナの実行を管理する
-> 【疑問】ホストが別でも管理ができると言っている?

コンテナ群がどのような状態で動いて欲しいという理想を「マニフェスト」という設定ファイルに記述して、Kubernetesに「宣言」する
-> 宣言型。TerraFormとか。EC2とかでも数を指定できるから、そういうものかな?

jnuankjnuank

コンテナランタイム、というのもあるらしい。(Dockerのことかな?)

コンテナを直接作成・管理する?

Kubernetesは直接コンテナを作成、操作する機能は持たないらしい。
Kubernetes環境を構成する各マシン(ノード)でコンテナランタイムがその役割を果たす。
-> 処理を委譲している感じかな?

jnuankjnuank

コンテナイメージのBuild

コンテナイメージのビルドするには、コンテキストとDockerFileが必要

コンテキストは、ビルドの材料として用いるファイル群を1つのディレクトリにまとめたもの

-t オプションで名前指定。
コロンより前がimage名。コロン後がタグ

$ docker build -t myimage:v1 .
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM ubuntu:20.04
20.04: Pulling from library/ubuntu
5d3b2c2d21bb: Pull complete
3fc2062ea667: Pull complete
75adf526d75b: Pull complete
Digest: sha256:b4f9e18267eb98998f6130342baacaeb9553f136142d40959a1b46d6401f0f2b
Status: Downloaded newer image for ubuntu:20.04
 ---> 4dd97cefde62
Step 2/3 : COPY ./hello.sh /hello.sh
 ---> 762d128b03bd
Step 3/3 : ENTRYPOINT [ "/hello.sh" ]
 ---> Running in aa28abebbee3
Removing intermediate container aa28abebbee3
 ---> a212d90ab198
Successfully built a212d90ab198
Successfully tagged myimage:v1

build後、 image ls で確認。

$ docker image ls myimage
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
myimage      v1        a212d90ab198   About a minute ago   72.9MB
jnuankjnuank

起動

$ docker run --name mycontainer myimage:v1
Hello, World!


別端末でプロセス確認
ps -o pid,cmd で表示するカラム指定が出来たのが初めて知った

$ docker exec -it mycontainer /bin/bash
root@b5aab760828a:/# ps -Ao pid,cmd
  PID CMD
    1 sleep infinity
   18 /bin/bash
   31 ps -Ao pid,cmd

停止

$ docker stop mycontainer
mycontainer

停止したのを確認

$ docker container ls -a | grep mycontainer
b5aab760828a   myimage:v1                             "/hello.sh"              5 minutes ago   Exited (137) 53 seconds ago                                  mycontainer

削除

$ docker rm mycontainer
mycontainer
jnuankjnuank

Unixコマンド叩きながら理解できそう

https://eh-career.com/engineerhub/entry/2019/02/05/103000

jnuankjnuank
  • 仮想マシンは、アプリケーションやライブラリの他にOS実行の為のリソースが必要で、起動時間も数分掛かる場合がある
  • コンテナの場合は、アプリケーションやライブラリの実行に必要なリソースだけを準備すればよくて、起動時間は通常のアプリケーション実行と遜色ないレベル
    • これはコンテナの実態が隔離、制限されたプロセスであることから、わかる
    • コンテナはホストOSのプロセスの1つであるため、隔離や制限が不十分な場合には、ホストOSや他のコンテナに影響を与える可能性がある
jnuankjnuank

cgroupってのがよくわからん…。

cgroups(Control Groups)とは、「プロセスをグループ化して、
リソースの利用をコントロール」するカーネル機能で、
Linux 2.6.24からマージされています。

具体的には、グループ単位でリソースの割り当て、
優先度、管理、モニタリングなどが設定できます。

https://qiita.com/legitwhiz/items/72ead813f5be784534e5

jnuankjnuank

cgroupを使うことによってリソース制限ができる。

-> おそらくこれらを利用して、コンテナのリソースを制限している

jnuankjnuank

Namespaceはすべてのプロセスに関連付けられていて、指定がない限り親プロセスと同じNamespaceを参照します。新しくNamespaceが作成されていない環境において、全てのプロセスはPID1と同じNamespaceを参照し、プロセス間で共通のカーネルリソースを扱います。

PID1 = 親プロセス?

jnuankjnuank

Namespaceはシステムコールではなくて、機能の概要っぽい。

unshareシステムコールで、現在のプロセスを新しいNamespaceに紐付けができるっぽい

jnuankjnuank
$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 vagrant vagrant 0 Mar  8 01:56 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 vagrant vagrant 0 Mar  8 01:56 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 vagrant vagrant 0 Mar  8 01:56 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 vagrant vagrant 0 Mar  8 01:56 net -> 'net:[4026531993]'
lrwxrwxrwx 1 vagrant vagrant 0 Mar  8 01:56 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 vagrant vagrant 0 Mar  8 01:56 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 vagrant vagrant 0 Mar  8 01:56 user -> 'user:[4026531837]'
lrwxrwxrwx 1 vagrant vagrant 0 Mar  8 01:56 uts -> 'uts:[4026531838]'

シンボリックリンクは、Namespaceの種別とinode番号で構成されている文字列とのこと。
この文字列が同じプロセス同士は、Namespaceを共有している。

ファイルじゃなくて、文字列なんだな。 'cgroup:[4026531835]' って

jnuankjnuank

Namespaceとは

Namespaceはプロセスが参照するPID(プロセスID)番号空間やマウントポイントなど、カーネルリソースを他のプロセスと隔離し、独立したOS環境のように見せる機能です。

jnuankjnuank

Namespaceの隔離

unshareコマンドで、新しいNamespaceを作成し、指定コマンド(/bin/sh)を実行

vagrant@ubuntu-bionic:~$ unshare --mount-proc -uipr --fork /bin/sh
# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   4636   780 pts/0    S    02:01   0:00 /bin/sh
root         2  0.0  0.3  37804  3252 pts/0    R+   02:01   0:00 ps aux
# id
uid=0(root) gid=0(root) groups=0(root)
#
/bin/sh: 2: Cannot set tty process group (No such process)

vagrant@ubuntu-bionic:~$ id
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant)
jnuankjnuank

Namespaceに接続する

unshareコマンドをバックグラウンドで実行。
UTS Namespaceを隔離したプロセスで、ホスト名を foobar に変更している

$ unshare -ur /bin/sh -c 'hostname foobar; sleep 15' &

バックグラウンドで実行中のPIDに対して、nsenter で接続

これがDockerの docker exec コマンドに相当

$ PID=$(jobs -p)
$ sudo nsenter -u -t $PID hostname
foobar
jnuankjnuank

Namespaceを維持する

Namespaceは関連するすべてのプロセスが終了すると消える、らいし。

/proc/PID/ns 以下のファイルをbind mount することで維持が可能。

【疑問】unshare、nsneterコマンドのオプションがまだよくわからん

$ touch ns_uts
$ sudo unshare --uts=ns_uts /bin/sh -c 'hostname foobar'

先程みたいにバックグラウンド実行しないで、すでに終了してしまっている。
が、UTS Namespaceは、 ns_uts ファイルに bind mountされて維持されている

【疑問】mountコマンドの結果の見方もよくわかっていない。以下の結果でなぜbindされていることがわかっている?

$ mount | grep ns_uts
nsfs on /home/vagrant/ns_uts type nsfs (rw)

saveポイントみたいなものだろうか? ns_utsにマウントしたものというのは。

$ sudo nsenter --uts=ns_uts hostname
foobar
vagrant@ubuntu-bionic:~$ sudo nsenter --uts=ns_uts
root@foobar:~# hostname
jnuankjnuank

cgroup

コンテナはホストOSのCPUやメモリなどのリソースを共有している。
そのため制限を掛けないと、コンテナ側の処理が重くなったときに、他のプロセスを落としてしまうことがありうる。

そのため、cgroupを使って、プロセスが使用できるリソースを制限することができる。

  • CPU時間の制限、割り当てCPUの指定
  • メモリ使用量の制限、OOM killerの有効化/無効化
  • プロセス数の確認と制限
  • デバイスのアクセス制御
  • ネットワーク優先度設定
  • タスクの一時停止/再開
  • CPU使用量、メモリ使用量のレポート
  • ネットワークパケットをタグ付け(tcで利用)

これらの機能とNamespaceを組み合わせることにより、プロセスを仮想マシンのように扱うことができる(つまり、コンテナ)

jnuankjnuank

cgroupfsというVFS(Virtual File System)をマウントしている

$ mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
jnuankjnuank

cgroupはnamespaceとは異なり、システムコールでは操作しない

jnuankjnuank
$ UUID=$(uuidgen)
$ sudo cgcreate -g cpu,memory:$UUID

# 差分確認用
$ sudo apt-get install colordiff

# root用と新しく作ったサブグループを指定して、プロセスのcgroupがどう変わるか確認
$ colordiff -y  <(cat /proc/$$/cgroup ) <(sudo cgexec -g cpu,memory:$UUID cat /proc/self/cgroup)

jnuankjnuank

cgroupsのグループに所属するプロセスは、 mount -t cgroup で見た、<SUBSYSTEM>/[<SUBGROUP>]/cgroup.procs で確認が可能。

【疑問】/sys/fs/cgroup/ がサブシステム? cpu/がサブグループ?

以下の例は、cgroupを指定して sleep 10 をバックグラウンド実施。
その後、/sys/fs/cgroup/cpu/$UUID/cgroup.procs をcatして、どのPIDが動いているか確認。
11355は、psコマンドで見ていると、sleep 10のコマンドとなっている。

【疑問】なんでUUIDなんだろ??

vagrant@ubuntu-bionic:~$ sudo cgexec -g cpu:$UUID sleep 10 &
[1] 11354
vagrant@ubuntu-bionic:~$ cat /sys/fs/cgroup/cpu/$UUID/cgroup.procs
11355
vagrant@ubuntu-bionic:~$ ps fau
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
vagrant  10283  0.0  0.5  23220  5216 pts/1    Ss+  03:17   0:00 -bash
vagrant   9614  0.0  0.5  23612  5692 pts/0    Ss   02:23   0:00 -bash
root     11354  0.0  0.4  63976  4228 pts/0    S    08:23   0:00  \_ sudo cgexec -g cpu:42ac367c-48f4-4
root     11355  0.0  0.0   7932   776 pts/0    S    08:23   0:00  |   \_ sleep 10
vagrant  11357  0.0  0.3  37804  3272 pts/0    R+   08:23   0:00  \_ ps fau
jnuankjnuank

いろんなサブグループが見れるっぽい。
さらに、UUIDのフォルダが存在していて、そのUUIDに属しているプロセスも見れるっぽい

【疑問】なぜUUID? たまたま?

vagrant@ubuntu-bionic:~$ ll /sys/fs/cgroup/cpu/
total 0
dr-xr-xr-x  6 root    root      0 Mar  8 08:19 ./
drwxr-xr-x 15 root    root    380 Mar  8 00:49 ../
drwxr-xr-x  2 root    root      0 Mar  8 08:04 42ac367c-48f4-4f9c-ae76-c2c73d5a39d8/
drwxr-xr-x  2 vagrant vagrant   0 Mar  8 01:46 9564c204-ec1b-4be5-b61c-5ed3ee1ba6ad/
-rw-r--r--  1 root    root      0 Mar  8 08:19 cgroup.clone_children
-rw-r--r--  1 root    root      0 Mar  8 08:19 cgroup.procs
-r--r--r--  1 root    root      0 Mar  8 08:19 cgroup.sane_behavior
-rw-r--r--  1 root    root      0 Mar  8 08:19 cpu.cfs_period_us
-rw-r--r--  1 root    root      0 Mar  8 08:19 cpu.cfs_quota_us
-rw-r--r--  1 root    root      0 Mar  8 08:19 cpu.shares
-r--r--r--  1 root    root      0 Mar  8 08:19 cpu.stat
-r--r--r--  1 root    root      0 Mar  8 08:19 cpuacct.stat
-rw-r--r--  1 root    root      0 Mar  8 08:19 cpuacct.usage
-r--r--r--  1 root    root      0 Mar  8 08:19 cpuacct.usage_all
-r--r--r--  1 root    root      0 Mar  8 08:19 cpuacct.usage_percpu
-r--r--r--  1 root    root      0 Mar  8 08:19 cpuacct.usage_percpu_sys
-r--r--r--  1 root    root      0 Mar  8 08:19 cpuacct.usage_percpu_user
-r--r--r--  1 root    root      0 Mar  8 08:19 cpuacct.usage_sys
-r--r--r--  1 root    root      0 Mar  8 08:19 cpuacct.usage_user
-rw-r--r--  1 root    root      0 Mar  8 08:19 notify_on_release
-rw-r--r--  1 root    root      0 Mar  8 08:19 release_agent
drwxr-xr-x 63 root    root      0 Mar  8 08:19 system.slice/
-rw-r--r--  1 root    root      0 Mar  8 01:20 tasks
drwxr-xr-x  2 root    root      0 Mar  8 08:19 user.slice/
jnuankjnuank
# cgroup-tools経由ではなく、cgroupfsに対して直接フォルダを作る
$ sudo mkdir /sys/fs/cgroup/cpu/$UUID
# cpuの制限値を50%にする
$ sudo echo 50000 | sudo tee /sys/fs/cgroup/cpu/$UUID/cpu.cfs_quota_us
# 端末のPIDを、今回作ったcgroupfs内のcgroup.procsに所属
$ echo $$ | sudo tee /sys/fs/cgroup/cpu/$UUID/cgroup.procs
# timeout付きのyesコマンドをバックグラウンド実行
$ timeout 15s yes > /dev/null &
# topで確認する。端末のPID自体がCPU50%制限のcgroupに所属(cgroup.procsに書いてる)しているので、50%で頭打ちになる
$ top

結果

jnuankjnuank

unshareを実行後、straceをしてみる

$ strace -o unshare.log cgexec -g cpu,memory:$UUID unshare -muinpfr /bin/sh -c "
mount -t proc proc $ROOTFS/proc &&
touch $ROOTFS$(tty); mount --bind $(tty) $ROOTFS$(tty) &&
touch $ROOTFS/dev/pts/ptmx; mount --bind /dev/pts/ptmx $ROOTFS/dev/pts/ptmx &&
ln -sf /dev/pts/ptmx $ROOTFS/dev/ptmx &&
touch $ROOTFS/dev/null && mount --bind /dev/null $ROOTFS/dev/null &&
/bin/hostname $UUID &&
exec capsh --chroot=$ROOTFS --drop=cap_sys_chroot -- -c 'exec $CMD'
"

別ターミナルで、unshare.logを確認

unshare(CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|CLONE_NEWUSER|CLONE_NEWPID) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f7b0f4517d0) = 10310
wait4(10310,

別プロセス内でbash/shを起動しているので、いまwait4コールが呼ばれてそのままの状態?
cloneシステムコールによって、作られたのが、10310

ps f で確認すると、unshareした子プロセスでの/bin/shがそれに当たる。

vagrant@ubuntu-bionic:~$ ps f
  PID TTY      STAT   TIME COMMAND
10283 pts/1    Ss     0:00 -bash
10321 pts/1    R+     0:00  \_ ps f
 9614 pts/0    Ss     0:00 -bash
10307 pts/0    S      0:00  \_ strace -o unshare.log cgexec -g cpu,memory:9564c204-ec1b-4be5-b61c-5ed3ee1ba6ad unshare -muinpfr /bin/sh -c  mount -t proc pro
10309 pts/0    S      0:00      \_ unshare -muinpfr /bin/sh -c  mount -t proc proc /tmp/tmp.yhqaNrafyQ/proc &&  touch /tmp/tmp.yhqaNrafyQ/dev/pts/0; mount --
10310 pts/0    S+     0:00          \_ /bin/sh

https://kazmax.zpp.jp/cmd/c/clone.2.html

jnuankjnuank

2.2 コンテナのレイヤ構造

  • 2021/03/19(金)
jnuankjnuank

コンテナイメージはレイヤの集まり

$ sudo docker save myimage:v1 | tar -xC ./dumpimage
$ cd dumpimage
$ tree
.
├── 07d67c3173ab032b5395d7e292f9c78e669af58c220b94e432784fba43c11adf
│   ├── VERSION
│   ├── json
│   └── layer.tar
├── 2186c6fa4d9b22226fe8572f55ae2cdda5336ff9abd46a2b5e0c40a1bcff5317
│   ├── VERSION
│   ├── json
│   └── layer.tar
├── 2a5607ba8f2cb67dc80649869c9ca3990ff35a65a64308a516dd635eee8e8104.json
├── 5367b0805440d84bce8b0c815a92c29f2c74b0de13f5b82ec524837f496d96dd
│   ├── VERSION
│   ├── json
│   └── layer.tar
├── 9677226adbb823011a9b00fccba48935af627e2f1c3c8ffd4c033319f8fc07ef
│   ├── VERSION
│   ├── json
│   └── layer.tar
├── manifest.json
└── repositories

4 directories, 15 files
jnuankjnuank

イメージ構成に関する情報がmanifest.json に含まれている。

Layersの一番目から順に適用していくといった意味になるだろうか?

$ cat manifest.json | jq
[
  {
    "Config": "2a5607ba8f2cb67dc80649869c9ca3990ff35a65a64308a516dd635eee8e8104.json",
    "RepoTags": [
      "myimage:v1"
    ],
    "Layers": [
      "9677226adbb823011a9b00fccba48935af627e2f1c3c8ffd4c033319f8fc07ef/layer.tar",
      "07d67c3173ab032b5395d7e292f9c78e669af58c220b94e432784fba43c11adf/layer.tar",
      "5367b0805440d84bce8b0c815a92c29f2c74b0de13f5b82ec524837f496d96dd/layer.tar",
      "2186c6fa4d9b22226fe8572f55ae2cdda5336ff9abd46a2b5e0c40a1bcff5317/layer.tar"
    ]
  }
]

$ tar --list -f 2186c6fa4d9b22226fe8572f55ae2cdda5336ff9abd46a2b5e0c40a1bcff5317/layer.tar
hello.sh
jnuankjnuank

Dockerはコンテナの実行時、これらtarに格納されているレイヤを重ね合わせることでルートファイルシステムを構築し、その上で実行しています

変更差分であるtarファイルデータを順番に積み重ねていくのかな。

jnuankjnuank

Vagrant up でエラー

vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'base' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Box file was not detected as metadata. Adding it directly...
==> default: Adding box 'base' (v0) for provider: virtualbox
    default: Downloading: base
An error occurred while downloading the remote file. The error
message, if any, is reproduced below. Please fix this error and try
again.

Couldn't open file /xxx/xxx/xxx/base

どうやら一度Vagrantfileを消して、box名を指定してからinitしないといけないらしい。(なぜ?

https://unity-yuji.xyz/vagrant-up-an-error-occurred-while-downloading-the-remote-file/

$ vagrant box list
ubuntu/bionic64 (virtualbox, 20210305.0.0)
$ vagrant init ubuntu/bionic64
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

$  vagrant up
wBringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'ubuntu/bionic64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'ubuntu/bionic64' version '20210305.0.0' is up to date...
==> default: A newer version of the box 'ubuntu/bionic64' for provider 'virtualbox' is
==> default: available! You currently have version '20210305.0.0'. The latest is version
==> default: '20210315.1.0'. Run `vagrant box update` to update.
==> default: Setting the name of the VM: linux_gcc_default_1616139626822_69012
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default:
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default:
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Mounting shared folders...

$ vagrant ssh

さっきBox 'base' could not be found. となっていたから、指定をすればもしかしたらいけた?