🔍

探検!Cloud Run 第1世代 vs 第2世代

2023/12/23に公開

この記事は Google Cloud Japan Advent Calender 2023 23日目の記事です。

Cloud Run の中、気になりませんか?

Cloud Run はサーバーレスの特性そのままに、インフラを一切意識せずにコンテナを運用できる大人気のプラットフォームとなっています。

しかし、ときどき気になりませんか?その中身。
コンテナの中は誰でも見ることができますが、あえて覗いている人は少ないのではないでしょうか? そこで今回はユーザーとして探索できる範囲で、Cloud Run のコンテナを通して透けて見える OS や基盤を眺めてみたいと思います。

ご存知のとおり、Cloud Run の実行環境には第1世代と第2世代がありますので、比較しながら楽しみたいと思います。gVisor ベースの第1世代と、Linux の互換性を重視した第2世代は結構違っているので、事前にチェックしていただければと思います。
https://cloud.google.com/run/docs/about-execution-environments?hl=ja

大事な注意点

本記事は、2023年後半に東京リージョンで実施したスナップショットです。実行する日時、条件、リージョンなどで結果が大きく変わる可能性があるので、あくまでも参考程度に見てください。
また、こちらの内容を Google Cloud にお問い合わせすることはお控えください。

探検ツール

探検するためにちょっとしたツールを作りました。
https://github.com/shin5ok/cloud-run-shell
ローカルの疑似シェルから、Cloud Run の中のシェルでコマンドを実行するだけです。

セットアップ方法は README をご確認ください。

こんな感じで Linux マシンっぽく、Cloud Run のコンテナ(Ingress コンテナ)内で連続してシェルを叩けます。

$ xargs -L1 ./client/shell

ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ssl    0:01 /shell/.venv/bin/python main.py
   43 ?        S      0:00 /bin/sh -c ps ax
   44 ?        R      0:00 ps ax

hostname
localhost

id
uid=0(root) gid=0(root) groups=0(root)

いろいろ見るために、あえて root で動かしてますので注意してください。

探検先の Cloud Run のスペック

Cloud Run サービスのスペックは第1世代、第2世代とも以下の通り。

  • CPU 2, メモリ 2Gi
  • マルチコンテナ
    • シェル用(メイン)
    • ログ収集(サイドカー)
  • Direct VPC egress(プレビュー)

見えたこと

見えているアウトプットをベースにコメントは控えめにしています。ご了承ください。

カーネルの比較

  • 第1世代
Linux localhost 4.4.0 #1 SMP Sun Jan 10 15:06:54 PST 2016 x86_64 GNU/Linux
  • 第2世代
Linux localhost 5.15.60 #1 SMP Fri Sep 8 16:08:58 UTC 2023 x86_64 GNU/Linux

世代間で、かなりバージョンに差があるようです。

CPU 型番

  • 第1世代
processor       : N
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : unknown
stepping        : unknown
cpu MHz         : 2000.120
fpu             : yes
fpu_exception   : yes
  • 第2世代
processor       : N
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) CPU @ 2.00GHz
stepping        : 3
microcode       : 0xffffffff
cpu MHz         : 2000.142
cache size      : 39424 KB

第1世代は unknown とでているのに対して、第2世代は Xeon とでています。
第2世代は CPU パフォーマンスが高速化されている、とのことでしたね。

CPU 数比較

コンテナインスタンスの CPU は2と指定しています。

  • 第1世代
grep ^processor /proc/cpuinfo
processor       : 0
processor       : 1
processor       : 2
processor       : 3
  • 第2世代
grep ^processor /proc/cpuinfo
processor       : 0
processor       : 1
processor       : 2
processor       : 3

どちらも 4つ見えますね。Docker でいうと、これは通常ホストの CPU が見えている部分です。なんらかの方法で利用できるCPUリソースを制限してると予想されます。

ここで CPU ブーストを ON にしてみます
  • 第1世代
grep ^processor /proc/cpuinfo
processor       : 0
processor       : 1
processor       : 2
processor       : 3
processor       : 4
processor       : 5
  • 第2世代
grep ^processor /proc/cpuinfo
processor       : 0
processor       : 1
processor       : 2
processor       : 3
processor       : 4
processor       : 5
processor       : 6
processor       : 7

増えてます・・・!

カーネルパラメータを比較

  • 第1世代
sysctl -a | grep somaxconn
net.core.somaxconn = 128

sysctl -a | grep net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 16000 65535

sysctl -a | grep fs.file-max
(空)

sysctl -a | wc -l
52
  • 第2世代
sysctl -a | grep somaxconn
net.core.somaxconn = 4096

sysctl -a | grep net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768    60999

sysctl -a | grep fs.file-max
fs.file-max = 813775

sysctl -a | wc -l
1192

世代間の差が大きく、興味深いですね。

ファイルシステム対応状況

  • 第1世代
cat /proc/filesystems
nodev   overlay
nodev   proc
nodev   tmpfs
nodev   devpts
nodev   devtmpfs
nodev   fuse
nodev   9p
nodev   mqueue
nodev   cgroup
nodev   ramdiskfs
nodev   sysfs
  • 第2世代
(多いので省略)

nodev   devpts
        ext3
        ext4
        squashfs
nodev   nfs
nodev   nfs4
nodev   cifs
nodev   smb3
        fuseblk
nodev   fuse
nodev   fusectl
nodev   overlay
nodev   9p
nodev   ceph
nodev   mqueue
nodev   selinuxfs
nodev   pstore

第2世代は NFS、Windows ファイル共有、Fuse などに対応していますね。

マウントしてみる
  • 第1世代
# Cloud Storage
gcsfuse --debug_gcs --debug_fuse $STORAGE_NAME /gcs
# mount 成功!
# でもファイルの内容が書き込めない

# NFS
mount -o nolock -t nfs  10.79.97.2:/share /nfs
mount.nfs: No such device # エラー
  • 第2世代
# Cloud Storage
gcsfuse --debug_gcs --debug_fuse $STORAGE_NAME /gcs
# 成功

# NFS
mount -o nolock -t nfs 10.79.97.2:/share /nfs
# 成功
df -h --type=nfs
Filesystem         Size  Used Avail Use% Mounted on
10.79.97.2:/share 1007G     0  956G   0% /mnt

ディスクの状況

  • 第1世代
df -h
df: /var/log: Function not implemented

Filesystem      Size  Used Avail Use% Mounted on
none            8.0E  3.2M  8.0E   1% /
none            8.0E     0  8.0E   0% /dev
none            8.0E     0  8.0E   0% /dev/shm
none            8.0E     0  8.0E   0% /tmp
none            8.0E     0  8.0E   0% /tmp/cloudsql-proxy-tmp
none            8.0M     0  8.0M   0% /var/share


df -i
df: /var/log: Function not implemented

Filesystem     Inodes IUsed IFree IUse% Mounted on
none                0     0     0     - /
none                0     0     0     - /dev
none                0     0     0     - /dev/shm
none                0     0     0     - /tmp
none                0     0     0     - /tmp/cloudsql-proxy-tmp
none                0     0     0     - /var/share
  • 第2世代
df -h
Filesystem      Size  Used Avail Use% Mounted on
none            2.0G  3.2M  2.0G   1% /
none            2.0G     0  2.0G   0% /tmp
none            2.0G     0  2.0G   0% /tmp/cloudsql-proxy-tmp
none            2.0G     0  2.0G   0% /sys/fs/cgroup
none            2.0G     0  2.0G   0% /dev
none            2.0G     0  2.0G   0% /dev/shm
tmpfs           8.0M     0  8.0M   0% /var/share


df -i
Filesystem      Inodes IUsed   IFree IUse% Mounted on
none           1018298   312 1017986    1% /
none           1018298     2 1018296    1% /tmp
none           1018298     6 1018292    1% /tmp/cloudsql-proxy-tmp
none           1018298    14 1018284    1% /sys/fs/cgroup
none           1018298    18 1018280    1% /dev
none           1018298     1 1018297    1% /dev/shm
tmpfs          1018298     1 1018297    1% /var/share

Cloud Run はメモリをディスクとして利用します。第2世代はまさにそういう見え方になっていますね。

ネットワークインタフェースの状況

  • 第1世代
ifconfig | grep -A 1 ^[a-z]
eth0: flags=65<UP,RUNNING>  mtu 65000
        inet 192.168.1.1  netmask 255.255.255.255
--
eth2: flags=65<UP,RUNNING>  mtu 1280
        inet 169.254.8.1  netmask 255.255.255.255
--
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65522
        inet 127.0.0.1  netmask 255.0.0.0


netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
169.254.1.1     0.0.0.0         255.255.255.255 U         0 0          0 eth0
  • 第2世代
ifconfig | grep -A 1 ^[a-z] 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 65000
        inet 169.254.8.1  netmask 255.255.0.0  broadcast 169.254.255.255
--
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0


netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         169.254.1.254   0.0.0.0         UG        0 0          0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 eth0
169.254.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0

loopback アドレスを除くと、第1世代はネットワークインタフェースが2つ、第2世代は1つ、見えています。

Direct VPC egress(プレビュー)を有効化

Direct VPC egress は、リージョンリソースである Cloud Run から、Compute Engine や Cloud SQL など VPC 内のリソースに直接アクセスできる機能です。今回は、プライベートトラフィックのみルーティングする設定を選択しております。

  • 第1世代
ifconfig | grep -A 1 ^[a-z]
eth0: flags=65<UP,RUNNING>  mtu 65000
        inet 192.168.1.1  netmask 255.255.255.255
--
eth2: flags=65<UP,RUNNING>  mtu 1280
        inet 169.254.8.1  netmask 255.255.255.255
--
eth3: flags=65<UP,RUNNING>  mtu 1500
        inet 169.254.9.1  netmask 255.255.255.255
--
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65522
        inet 127.0.0.1  netmask 255.0.0.0

netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
169.254.1.1     0.0.0.0         255.255.255.255 U         0 0          0 eth0
199.36.153.0    0.0.0.0         255.255.255.0   U         0 0          0 eth3
192.168.0.0     0.0.0.0         255.255.0.0     U         0 0          0 eth3
172.16.0.0      0.0.0.0         255.15.0.0      U         0 0          0 eth3
100.64.0.0      0.0.0.0         255.3.0.0       U         0 0          0 eth3
10.0.0.0        0.0.0.0         255.0.0.0       U         0 0          0 eth3
240.0.0.0       0.0.0.0         15.0.0.0        U         0 0          0 eth3
0.0.0.0         0.0.0.0         0.0.0.0         U         0 0          0 eth2

  • 第2世代
ifconfig | grep -A 1 ^[a-z]
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 65000
        inet 169.254.8.1  netmask 255.255.0.0  broadcast 169.254.255.255
--
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.9.1  netmask 255.255.255.0  broadcast 169.254.9.255
--
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0


netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         169.254.1.254   0.0.0.0         UG        0 0          0 eth0
10.0.0.0        0.0.0.0         255.0.0.0       U         0 0          0 eth1
100.64.0.0      0.0.0.0         255.192.0.0     U         0 0          0 eth1
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 eth0
169.254.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0
169.254.9.0     0.0.0.0         255.255.255.0   U         0 0          0 eth1
172.16.0.0      0.0.0.0         255.240.0.0     U         0 0          0 eth1
192.168.0.0     0.0.0.0         255.255.0.0     U         0 0          0 eth1
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0
199.36.153.0    0.0.0.0         255.255.255.0   U         0 0          0 eth1
240.0.0.0       0.0.0.0         240.0.0.0       U         0 0          0 eth1

それぞれ、ネットワークインタフェースが1つずつ増えています。割り当てられている IPアドレスは VPC のものとは違うようですね。またそれに伴い、ルーティングテーブルも変化しています。

なお第2世代はネットワークパフォーマンスが高速化されている、とのことでしたね。計測したところ確かに帯域幅は大きくなっており、ファイルのリモートコピーなど違いを体感できました。

探検おわり

今回は控えめの探検でしたが、インフラを好きな方はいろいろ仕組みを想像して楽しんでいただけたかもしれません。この記事を読んで、みなさんがさらに Cloud Run に興味を持ってくれることを期待してます。

しかし、やはり Cloud Run はサーバーレス。インフラを気にせずに運用できることが一番の特徴です。実践的な Cloud Run の活用には、同僚の Swacchi さんの Cloud Run Advent Calendar 2023 をおすすめします。
https://qiita.com/advent-calendar/2023/cloud-run

探検のことは忘れて(笑)、すてきなサーバーレスライフをお送りください。

Discussion