AWS(などのIaaS/PaaS)とOSの類似性

またポエムです。

OSとAWSって似ていますよね

 最近OSの勉強を始め、勉強記録をこのブログでまとめています(OSの役割とコンピュータの典型構成)。その中で印象に残ったのが「OSはユーザーやプログラムのリソース要求に対して、リソースを割り当てるリソース管理者」であるという点です。OSがCPUの処理時間・メモリ・ファイルシステムを管理してくれるお陰で、プログラムの開発者は自分のプロセスが他のプロセスのメモリを触らないようにする、CPUを占領して他のプロセスが動かなくならないようにする、ディスクの断片化を考慮してファイルを書き込む、といったことを全く考えずに済んでいます。

 これってAWSに似ていませんか?AWSは物理的なネットワーク構成やどんなスペックのコンピュータが使われていて、ベースとしてどんなOSが動いているかなどはユーザーから隠蔽されています。ユーザーは自分が使いたいネットワーク構成や仮想マシンを単にAPIでリクエストするだけで、AWSはリソースを割り当ててくれます。EC2にしても本当は自分が作った仮想マシンと同じハードウェア上で同居する別のユーザーの仮想マシンがあるはずなんですが、人の仮想マシンに配慮する必要は全くありません(なお、ハードウェアを専有するオプションもあるそうです。参考:Dedicated Instance と Dedicated Hosts の違い)。この動作はまさにOSにおけるプロセスに類似しています。S3なんかはファイルシステムですよね。ユーザー管理はIAMでしょう。

 たまたま似ているというよりは、そもそもAWSを作ってるのはコンピュータサイエンスをよく理解したエンジニアなので、OSとのアナロジーが成り立つように設計しているということなんだと思います。コーディングではパーツごとに違う書き方をするのではなく、可能なら同じように書くほうが望ましいとよく聞きます。一箇所のコードを理解すれば他の部分を読むときに類推が働くので、理解のハードルが下がり保守性が上がるからです。同様に、OS上で動くプログラムを作ってきたエンジニアが類推で理解できるようにクラウドサービスを作ったほうが、わかりやすいということなんでしょう。

 こういう話は語り尽くされているはずだと思うんですが、似たような議論がググってもあまり見つからなかったのが本記事執筆の動機です。「AWS OS 類似」「AWS 設計思想」「AWS アーキテクチャ」「AWS 裏側」「AWS 裏側」みたいなのでググってもAWS上でのサービス構築の話が出てきてAWS自体の話が出てきませんでした。多分こういう話はブログやWiki、qiitaのようなまとまった形式ではなく、SNSや講演とかの会話的な形式もしくは本でシェアされているんでしょうね。

OSの役割とAWSの比較表

 色々OSとAWSをマッピング・比較してみました。1

OSAWSコメント
システムコールAPI呼び出しなお、APIとシステムコールの違いは参考リンク:APIとかABIとかシステムコールとか 参照
ファイルシステムEBS
S3
メモリElastiCacheOSは仮想記憶とか難しいことしてるんだと思いますが(未勉強)、揮発性の記憶域というくらいの意味合いです。
プロセスEC2
Lambda
ECS
プロセス間通信SNS
SQS
ユーザー・プロセスの権限管理IAM
経路制御
ファイアウォール
VPCやや無理やり感がありますね
TCP/IPソケットAPI GatewayポートをListenしているプロセスは、API Gatewayで呼ばれるLambdaに当たるでしょう。
RDS
Aurora
DynamoDB
Redshift
データベースに対応するOS機能ってなんだろう?
ALB
NLB
マルチプロセッサ対応のスケジューリング?
CloudFront
Cognitoユーザー認証画面を出す機能?
標準出力CloudWatch Logs
イベントスケジューラEventBridgeイベントスケジューラはOS機能と言っていいのかという問題

AWSやOSの勉強が進んだら修正するかもしれません。

OS上のコーディングとAWS上のコーディング

 AWS上のコーディングとPC上のコーディングの大きな違いの一つはリソース割り当ての仕方だと感じます。例えば、あるサービスからLambdaを実行したいとします。Python3ではboto3というライブラリを使って、リンク先のようなコードを書くことになります。Lambdaで実行する関数はクラウド上で呼び出し側とは別に予め定義されており、その関数名を指定して実行することになります。1PC上であれば、プログラムが関数オブジェクトを別プロセスとして実行するようOSに依頼します。プロセス間通信をキューで行いたいときはどうするでしょうか?SQSをAWS上で別に作っておいて、プログラム上でARNやURLを指定して読み書きする必要があります。一方でOS上ではプログラムが実行時にキューオブジェクトを作るようOSに依頼し、putしたりgetしたりすることで通信します。プログラム実行前にキューを作っておいてそれをプログラム上から参照するなどはしません。

 AWS上でのアプリ作成では、プログラムがリソースを割り当てるのではなく、人手で別定義したリソースをプログラム上から参照して利用することが普通です。それではプログラム上でリソースを割り当てをAWSにリクエストする(ように見える)コーディングは不可能なのでしょうか?例えば、下のようなPythonプログラムを考えます。

from aws_os import EC2,Lambda,SQS,build_infrastructure
def lambda_func():
    data=sqs.get()
    print(data)
def ec2_main():
    sqs.put("hello world")
    lmd.start()
    lmd.join()
if __name__=='__main__':
    #グローバルスコープで変数としてリソースを定義
    ec2=EC2(main=ec2_main)
    lmd=Lambda(target=lambda_func)
    sqs=SQS()
    build_infrastructure(ec2,lmd,sqs)

このコードをローカルで実行するとグローバルスコープが実行され、Terraformのように構成がAWSに反映されます。動的に変数を生成するようなノリでAWS構成を変更するという感じですね。実行の結果、EC2とLambdaが適当なオプションで作成されます。2このときEC2とLambdaに構成情報が渡ります。EC2上では一回だけ上記と同じソースコードが実行されます。構成情報を見てEC2で実行されていることを認識し、build_infrastructure関数の振る舞いがローカル時と変わり、ec2_main関数を呼び出します。ec2_main関数ではlmdというグローバル変数のstartとjoinというメソッドを呼び出しています。lmdはLambdaを意味している変数なので、Lambdaが実行されます。Lambdaは呼び出されるとSQSからデータをポップしてprintして終了します。EC2はjoinでLambdaが終わるまで待っており、Lambdaが終わったらEC2上のプログラム実行も終わり、EC2の実行が停止されます。3

Infrastructure as Codeはどうなのか?

 TerraformではAWSのリソース構成をtfファイルで定義してリソースの一元管理や一括適用などができます。ただし、リソースの配置のみに特化しており、処理を書いたり、処理からリソースを参照したりといったことはサポートされていないようです。リソースオブジェクトを各言語で吐かせられるだけでも便利だと思うのですが。

 いろんな言語で構成を書けるPulumiもやはり構成定義に特化していそうです。変数割当の構文でリソースを作れ、Lambdaの処理をその場で書けるなどはありそうです。ただ、EC2やLambdaで動くコードからリソースを参照できるというような記述は見当たりませんでした。

こういうものが無いとしたらなぜ無いのか

  • リソースとロジックを別で管理しても特に弊害が無い
    • 自分自身あまり別管理であることで大きな負担を感じたことがありません
  • 同じソースコードで構成からロジックまで管理すると密結合になりやすい
  • ロジックをいじっているつもりだったら構成が変わる等を防ぎたい
    • よく触る部分が近くにあると間違ってデータ消去したりセキュリティが低下したなどが起きるかもしれません
  • 構成をいじるのはロジックを触るエンジニアと別なことが多い
    • 自分は小規模開発しか経験したことがないのでわかりませんが
  • デバッグ・テストどうするのか問題

などがあるのかもしれません。

いかがでしたか?

 OSとAWSの類似性から、1PC・1OS上のコーディングのようにAWS上でコーディングできたらどうなるかみたいな話まで徒然と書いてきました。今後誰かがこういうものを作ってくれると面白いので使わせてもらうと思います。

  1. ただし、自分が使ったことがある・聞いたことがあるサービスだけです。
  2. 何かしらカスタマイズしたいならオプション引数で指定する
  3. 書いていて思いましたがECSのほうが良かったかもしれませんね。

コメント

タイトルとURLをコピーしました