映画「トップガン」見た

今週のハンガリー🇭🇺GPが終わるとF1も夏休みに入り土日に少し時間の余裕ができる。
この機会にこれまで追いかけて来れなかったコンテンツを追いかけることにした。
要するに夏休みの宿題。

媒体に問わずおすすめコンテンツを教えてもらった中で最初に見たのは映画「トップガン」。

もちろん初見で作品に対する知識はトム・クルーズが主演ということと戦闘機がテーマというくらい。

最新作「トップガン・マーヴェリック」が公開中だが、最新作を楽しむ為には「トップガン」の履修が必要とのこと。
「トップガン・マーヴェリック」の評判を目にすると好評のものが多かったし、なにより皆のトム・クルーズへの解像度の高い反応に驚いていた。

「トップガン」は現在プライム・ビデオで配信中。

感想など

トム・クルーズ演じるマーヴェリック。
結果は出すがルールは守らない。成績はクーガー、アイスマンに首位を譲り2位。
この2位というのがすごいいい味出している感じ。
グースとのコンビはとても好きだったのでグースの死については非常に悲しい。

父の死の真相がかなり重要な伏線だと思っていたら割とあっさり明かされる。

チャーリーとの恋愛については、言ってしまえば教師と生徒の恋愛なんで
戦闘機が主テーマのこの作品でそんなことするなんて思ってなかった。
チャーリーが惚れるまでのところもちょっと行間読まないと納得できないけど
細かいことはいいんだよ。という感じがする。

この作品憎たらしいやつが全然いない。有望株だったアイスマンも最後に寝返りやがって...

物語はマーヴェリックがトップガンの教官を目指すことを告げるところで幕を閉じる。

ここからはこの作品外の話になるが、
「トップガン・マーヴェリック」は36年振りの続編でトム・クルーズが続編制作権を持っていて
トム・クルーズが納得できる続編出せるタイミングで出した続編。

トム・クルーズがスターダムにのし上がったこの作品の制作権を
ずっと譲らなかったその事実だけでもうエモい。

そして教官になったマーヴェリックを主役にした物語。こんなの絶対面白いに決まってる!

ご時世を鑑みて今すぐ映画館に行って見ようとは思わないけどいずれは絶対「トップガン・マーヴェリック」見る!

その他

視聴したのは吹替版だったが吹替版が不評なことについてはある程度は同意するが見るのをやめようとまでは思わなかった。
ただ、明らかに浮いているのは事実だと思う。


Amazon CloudFrontでクライアントIPを確認する

Amazon CloudFront(以下CloudFront)を挟んだリクエストを行った場合は、
デフォルトの状態ではオリジンから見たクライアントの情報はCloudFrontの物になってしまいます。

オリジンが、クライアントの情報知るための方法としてCloudFrontはいくつか解決策を用意しています。

X-Forwarded-For(XFF)

XFFに関して詳しい説明は省きますが、基本的にはXFFヘッダに複数のIPアドレスが列挙されていて
そのうち先頭のIPアドレスがクライアントのものである可能性が高いです。

ただ、XFFはリクエストヘッダで任意の値を設定することが可能なので安易に信用することはできません。
信頼できるIPリストと照合するなどして精査を行わなければなりません。

CloudFront-Viewer-Address ヘッダ

CloudFrontのアップデートによって実装され、XFFヘッダの解析を行わなくてもクライアントIP及びポートがわかるようになりました。
IPアドレスとポートが連結した情報になるのでIPアドレスだけ利用する場合は前処理は必要になります。

CloudFront Functions

リクエストに True-Client-IP ヘッダーを追加する - Amazon CloudFront
CloudFront Functionsを使用することで独自ヘッダを追加し値としてクライアントIPをセットすることができます。

docker logsとPID 1問題

1サービス1コンテナという言葉がある通り、Dockerコンテナでは1つのアプリケーションをパッケージングすることが推奨されています。
これを遵守していれば、docker logsの仕組みについてあまり理解せずともサービスのログの出力先を標準出力、標準エラー出力に向ければdocker logsでログを見ることができました。

docker docsでは例としてnginxとhttpdのコンテナでの設定を紹介しています。

nginx

The official nginx image creates a symbolic link from /var/log/nginx/access.log to /dev/stdout, and creates another symbolic link from /var/log/nginx/error.log to /dev/stderr, overwriting the log files and causing logs to be sent to the relevant special device instead.

View logs for a container or service | Docker Documentation

ログの出力先をシンボリックリンクにしておき標準出力、標準エラー出力にログを流しています。

ここで登場する「/dev/stdout」「/dev/stderr」に関してはそれぞれ下記のようにシンボリックリンクが設定されています。

  • /dev/stdout -> /proc/self/fd/1
  • /dev/stderr -> /proc/self/fd/2

httpd

The official httpd driver changes the httpd application’s configuration to write its normal output directly to /proc/self/fd/1 (which is STDOUT) and its errors to /proc/self/fd/2 (which is STDERR).

View logs for a container or service | Docker Documentation

「/proc/self/fd/1」「/proc/self/fd/2」については上述のnginxの項で出ましたね。
つまり最終的にはここにログを流せば良さそうということになります。

self?

selfというのは自分自身を表す言葉ですが、ここでself示してるのはPIDです。
例に上がっていたnginx,httpの場合selfは何になるのか?ということになりますが
DockerfileのCMDで起動したプロセスのPIDは1になります。つまりselfは1です。

となるとそれぞれ下記にログを転送すればdocker logsにログが出てくれることになります。

  • /proc/1/fd/1
  • /proc/1/fd/2

1というのがPIDであることがわかったので、/proc配下をみてみるとPID毎にディレクトリが切られていることがわかります。
つまりPID毎に標準出力、標準エラー出力を管理していることがわかります。
考えてみれば当然ですね。同じサーバーに複数のクライアントが接続していたとして全てのクライアントに同じ標準出力がでるわけではないので。

複数サービスのログを出したい

ここで最初に触れた1サービス1コンテナの話に戻ります。
1サービス1コンテナがいいことは重々承知ですが、どうしても2サービス動かしたい場合がありました。
その時docker logsに2サービスのログを流すにはどうすればいいかがわかりませんでした。

上述のPID1用の標準出力、標準エラー出力にログを流してあげれば実現できます。

  • /proc/1/fd/1
  • /proc/1/fd/2

PID1問題

ログの問題が解決できたので、複数サービスを起動するシェルスクリプトを作成してDockerコンテナを起動するようにしました。
すると、Dockerコンテナを正常に終了することができなくなりました。

下記事象が原因で発生していると推測できます。

参考

ざっくり理解したのは下記を認識していれば良さそうです。

  • PID1のプロセスがSIGTERMをハンドリングしていなければ正常終了することができない
  • Dockerの場合はTiniを使用すれば回避できる