うなすけとあれこれ

2022年11月29日

RubyKaigi 2022の会場ネットワークリポジトリを読み解く

機材

私がこれを書く動機

私はKaigi on Railsのオーガナイザーのひとりです。Kaigi on Rails 2023は物理会場にて開催されることが公開されました。そうなるともちろん、会場でのインターネットについてはどうなる、どうする、という問題が出てきます。それに備えて、先輩イベントであるRubyKaigiを参考にしようというわけで、自分の理解のために書くことにしました。

おことわり

私はRubyKaigi 2022のネットワークをお手伝いしましたが、ケーブルの巻き直し、APの設営、撤収時の諸々を手伝ったのみです。よってこれから言及する内容については、一般参加者に毛が生えた程度の事前知識しかありません。

またこれから読み解くコードにおいて、コメントする内容の正確性は一切ないものと思って読んでください。

RubyKaigiのネットワークについて

RubyKaigiのネットワークにおけるL3(OSI参照モデルで言うネットワーク層以上)より上の構成(多分)については、このリポジトリで公開されています。

何とは言わんが現場絶賛公開中なんだよな、宿題を放置した自分が全部悪いといいながらやってます https://t.co/J6SoHxBd4P https://t.co/GcPJLU69Rn

— そらは (@sora_h) September 3, 2022

今回は、2022年の会場ネットワークの構築が始まったあたりからのcommitを順を追う形で読み解いていきます。

e419d86 destroy itamae/ and start from scratch

今回のネットワークの準備はここから開始したと見られます。これ以前にもcommitsはあるのですが、それらは2019年以前のものをimportしたもののようなので、今年には関係ないとして無視します。 実際、このcommitでもitamaeのrecipeを削除してscratchからやりなおす、という意図を感じられます。

073c8e71 onpremises subnet

subnetを3つ、route_tableをひとつ定義しています

260fc96f dxg

AWS Direct Connect ゲートウェイを定義しています。AWS Direct Connectとは……

AWS Direct Connect は、お客様の内部ネットワークを AWS Direct Connect ロケーションに、標準のイーサネット光ファイバケーブルを介して接続するサービスです。 https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/Welcome.html

とのことです。(今知った)

3c07751 rubykaigi.net route53 zones

Route 53に rubykaigi.net のZoneを定義しています。ネットワーク関係の色々は *.rubykaigi.net で提供されました。

6e1f798da setup bastion instance

踏み台インスタンスを定義しています。関連するIAM roleであったり、SSH loginできるユーザーの公開鍵の設定などもあります。

b29183d awsroute53zone.ptr-10 => 10.in-addr.arpa.

DNSの逆引きを設定しているんだと思います。この記載で 10.0.0.0 になるってこと……?

https://manual.iij.jp/dpf/help/19004700.html

c3a8f29c1 mv terraform/ => tf/core/ in order to have multiple tfstates

これは単純にTerraformのdirectory構成の変更ですね。

4dd4bae2 create hosts DNS records with terraform

様々な機器のDatacenter、Network、CIDR、IP等を定義したhosts.txtを作成(というより更新)し、その内容から aws_route53_record を作成するRuby scriptを経由してRoute 53にTerraformからrecordを登録するようにしています。まあこれは手では書いていられないですね……最終的なhosts.tfは1400行弱になっています。

8fcc2cf remove route53/ (roadworker)

Roadworkerを削除しています。RoadworkerはRubyによるRoute 53をDSLによって管理できるgemです。Terraformによる管理に乗り換えたから、ということなんでしょう。

awsroute53record 大量に発生すると一瞬で terraform apply 遅すぎてやってられん状態になるし roadworker はなんだかんだ捨てられないなぁ

— そらは (@sora_h) August 22, 2022

01b95c6 enable nat gateway

NAT Gatewayが有効になりました。

687e37b initialize k8s cluster

EKSによるKubernetes clusterが爆誕しました。というか、Cookpad org以下にterraform moduleが公開されているんですね。

https://github.com/cookpad/terraform-aws-eks

注目すべきは、このクラスタは全部ARM instanceで稼動するような設定になっているところです。

a8b808f6 aws_vpn_gateway_route_propagation (import)

VPN間でのrouteのpropagationを設定しています。

dd6967e provision node groups

K8s clusterに属するnodeの設定です。

14e22a3 deploy node-termination-handler

https://github.com/aws/aws-node-termination-handler をHelm経由でdeployしています。こんなのがあるんですね。

ddb5c69 deploy aws-load-balancer-controller

AWS Load Balancer Controllerをclusterにdeployしています。

AWS Load Balancer Controller アドオンのインストール - Amazon EKS

ff3f013 addcreate shared ALB (ops-lb.rubykaigi.net)

証明書とALBを作成して *.rubykaigi.net ないくつかのhostを定義しています。こんなの生えてたのか。

144b3b6 deploy dex at idp.rubykaigi.net

dexをdeployしています。dexというのは https://dexidp.io/ です。 これで何をしたいかというと、 *.rubykaigi.net でhostされているいくつかのresources(例えば grafana.rubykaigi.net )へのアクセス権限を絞るためです。今回はGitHubの特定teamに所属しているメンバーに対しての許可を与えるような設定が書かれています。

また主にこのcommit以降からだと思いますが、K8sで使用するYAMLをJsonnetから生成するようになっています。

f5d628c test.rubykaigi.net with authenticate_oidc action through dex

で、そのテスト用のendpointを作成しています。ちゃんとAuthrorizeされていれば画像が見れるはず、というやつ。

9cb14e1 add wgbridger

wgbridgerを導入しています。wgbridgerというのは、

build L2 bridge using Wireguard to bring NGN to behind IPv4 NAPT only environment…

というもの(?) これはあれかな、準備作業中に見せてくれた、どこでもNGNに繋がる便利Raspberry Piの実体かな?

43c0b1a amc: to gain access to AWS through dexidp

dexをOIDC準拠IdPとして使用した認証を利用し、AWS Management Consoleへのアクセス権限を特定のIAM Roleによって行えるような機構、AMCを用意しています。つまりどういうことかというと、あるGitHub teamに所属している場合、その認証情報を用いてAWSのConsoleに入れる仕組みです。 tf/amc/src/app.rb がキモだと思うんですが、難しいよぉ……

5d66255 amc: enhance readme

AMCのREADMEに追記が行われています。

1db6e03 amc(ca_thumbprint): validate certificate chain

AMCに関連する処理のなかで、curlによる証明書チェーンが正当かどうかの検証を追加しています。

dc4ec4d build kea Docker image

ここからKeaのための準備が始まります。Keaが何者かというと、DHCP serverです。このcommitでは、Docker imageのbuildやKeaを起動するためのscriptなどの準備をしています。

https://www.isc.org/kea/

cd4d420 create kea backend rds

これはKeaのためのAuroraを準備しています。

bf917ef gen-k8s: use rsync instead of rm -rf & cp

JsonnetをYAMLにするscript内部で、生成したファイルの扱いがちょっと変更されています。rsyncにしたのは更新日時とかそのあたりの都合?

857d625 deploy kea-dhcp4

Keaが運用され始めました。

f64e1a1 dhcp: add health check server for NLB

Keaに対するhealthcheck用のendpointを用意しています、Rustで。Healthcheckそうやってやるんだ……なるほど……?

36c0f97 NocAdmin: allow elasticloadbalancing:*

NocAdmin roleに対してロードバランサーへの権限を解放しています。

04171ac dhcp: roll c866cff

Kea関連のdeploymentで参照しているcommit hashを更新しています。

7a7a1c3 nocadmin: grant rds:*

NocAdmin roleに対してRDSへの権限を解放しています。

cc0d6cb employ permission boundary on NocAdminBase policy

これはちょっとわからない……NocAdminBaseとNocAdminに権限を分離して、権限昇格を防いでいるんだと思いますが多分。

権限の昇格を防ぎ、アクセス許可の境界で IAM ユーザー範囲を限定する

cf56dd4 copypasta

🍝

4756245 NocAdmin: grant more iam permissions

NocAdminに対して許可するiamへの権限をいっぱい追加しています。

2c09e19 tf/k8s: arm64 support has been merged but not yet released

687e37bで導入されたterraform moduleをfork先のものからfork元のものを使うよう修正しています。ARM対応がmergeされたのがこのタイミングだったのかな。

d5c2a75 tf: No YAML!

Terraformのexternal data sourceとして、Jsonnetを指定してJSONを吐くときに使うためのRuby scriptを定義しています。

9743d8f tf/core: ALB rules for prometheus/alertmanager

このあたりからPrometheusの設定が始まります。ここではALBのための設定を作成しています。これらのendpointもdexを経由して認証されるようにしていますね。

6cf6189 tf/k8s-prom: install kube-prometheus-stack

Helm経由でPrometheusをK8s clusterにdeployしています。

9020ef2 tf/k8s-prom: Install prometheus-blackbox-exporter chart

blackbox exporter を用意しています。ICMP (ping)でどこかを監視する用かな。

6e086c7 k8s/prom: Probes

8.8.8.8 に対して60秒ごとにICMPを投げるように設定しています。これはインターネットへの疎通確認かな?

287eba2 tf/k8s-prom: Set retention to 30 days

Prometheusのdata retensionを1分から30日に変更しています。

f86fb99 tf/k8s: Export cluster config

clusterへの設定を他のtfから参照できるようにoutputしています。

7c1f56c tf/k8s-prom: Import cluster config via terraform_remote_state

ハードコードしていた設定値を、先ほどoutputしたclusterの設定を用いた形に書き換えています。

025d95 update hosts.txt

hosts.txtが更新されました

f52e1bc tf/k8s: snmp-exporter

snmp-exporterを設定しています。SNMPはSimple Network Management Protocolのこと。CiscoのWireless LAN ControllerやNECのIX Routerの監視に用いていたのかな。

22b1104 k8s/prom: Example config for blackbox/snmp probes

先のcommitで作成した設定値をprometheus側に反映されるようにK8sのmanifestを設定している、という理解でいいのかな

743b14b tf/k8s-prom: Grafana

Grafanaです。

218ec5 k8s/dhcp: Monitor kea4

Keaの監視もPrometheusで行うようになりました

99cb633 wgbridger: increase wg0 mtu

wgbridgerのためにMTU値を上げています

034fe8f wlc.rubykaigi.net

Wireless LAN Controllerにアクセスできるようになりました。

42df8b0 k8s-prom: Slack alert

PrometheusからのアラートがSlackに送られるようにしています。

c89d220 jsonnetfmt -i */.jsonnet

Jsonnetに対してformatterをかけています。

dd79016 prom: scrape-interval 20s

Prometheusがmetricsをscrapeする間隔を60秒から20秒に変更しています。

d397d5a tf/k8s: Export cluser OIDC config

clusterでのOIDC configを別tfから参照できるようにexportしています

0344245 nocadmin: dynamodb:*

NocAdmin roleに対してDynamoDBに関する権限を解放しています。なんかで使うんでしょう。

68781de tf: state lock

なるほど、State lockでDynamoDBを使うためだったんですね。

Backend Type: s3 | Terraform | HashiCorp Developer

3fa3622 noadmin: Allow iam:UpdateAssumeRolePolicy

NocAdmin roleに対して iam:UpdateAssumeRolePolicy を許可するよう変更しています。

a5268cf prom: cloudwatch_exporter

cloudwatch_exporterを有効にしています。AWSのresourceもPrometheusでモニタリングするためでしょうね

d36e815 update hosts.txt

hosts.txtを更新しています。IPv6の指定が増えてますね。

18af871 update hosts.txt

さらにhosts.txtの更新。もりっとhostが追加されています。

3902ba6 hosts_to_tf: fix error that single name allowed only single rrtype

hosts.txtからtfに変換するscriptを修正しています。IPv6の取り扱いとかに修正が入ってますね。

fd15430 update hosts.txt (typo)

typo

e21aec7 script to generate tunnel iface configurations…

これは……なんだろう、多分何かの機器用の設定を生成するためのscript。NECのルーターだと思うけど。

マニュアル : UNIVERGE IXシリーズ | NEC

6febb97 nocadmin: Allow s3:* on rk-syslog bucket

Syslogを置くためのS3 bucketへの権限をNocAdmin roleに付けています

335669f tf/syslog: init

Syslog関連のterraformのための場所を作っています。

8440359 tf/syslog: ECR repo for custom fluentd image

Syslogのためのfluentdを置くECR repositopryを定義しています

dbc46d8 docker: custom fluentd image

Syslogのためのfluentd containerを作成しています。GitHub Actionsでdocker buildをしていますね。

9eef1d4 Use https transport for cnw submodule to allow unauthenticated checkout

git submoduleのrepository URLをssh形式からhttps形式に変更しています。鍵がない環境でcloneできないから、でしたっけ。たぶんGitHub Actionsで不都合になったのか……?

d89649d docker/syslog: fluend plugins

fluentd pluginを作成しています。これはまずhealthcheckだけやってる感じ?

c690a8f tf/core: Allow GHA to push fluentd images

GitHub ActionsからECRにpushできるような権限を付与しています

71ae2b9 tf/syslog: k8s service account for fluentd

Syslog用のIAM role、K8sのservice accountを作成しています。EKSでIAM roleとの連携ってこうやってやるんだ。

2ab09ff k8s/syslog: deploy fluentd

fluentdの設定、k8sのdeployment諸々が作成されています。これでEKS clusterにfluentd containerが稼動し始めたのかな。

eb9d2bd tf/syslog: SGs

SyslogのためのSecurity groupを作成しています。fluentdに向かう通信を許可しているはず。

06cafcf k8s/syslog: use monitor_agent plugin for healthcheck

fluentdのhealthcheckのために、pluginを作ってやっていたものからmonitor_agentを使う方式に変更しています。

https://docs.fluentd.org/input/monitor_agent

850181c workflow: correct path

GitHub Actions内で参照していたpathの修正です

8c44f4d k8s/syslog: Inject fluentd hostname in records and object keys

S3に置くlog fileにhostnameを付与するようにしています

c72628c k8s/syslog: Use default chunk_limit_size as timekey is enough short

fluentdが終了するときにbuffer(?)をflushするようにしています。これないと書き出し切らずに終了してしまう?

7160fc0 k8s/syslog: No separete chunks by tag

tagでchunkが分離されてしまうのを防いでいる?

73d7542 bastion: ignore ami id change

terraformでbastion instanceに対してはAMIの変更を無視するようにしています。

51869fc configure private NAT gateway for onpremises

use static NAT on onpremises router devices so they don’t need to handle dynamic NAPT table and allow redundancy

「オンプレミスのルーターデバイスで静的NATを使用することにより、動的NAPTテーブルを処理する必要がなく、冗長性を確保できる。」 あ~はいはいなるほど完全に理解した

b0c0737 tf/core: Allog GHA to push unbound image

unboundがアップを始めている

dafaaeb tf/dns-cache: ECR repo and SG

unboundをCache DNS serverとして運用するみたいで、そのためのECRとsecurity groupを定義しています。

9d4ead6 docker/unbound: unbound with modified unbound_exporter

独自のunbound exporterによる監視を有効にしたunboundのcontainerをbuildしています。Jsonnet大活躍。

ac08623 tf/dns-cache: typo

フィックスタイポ

bbd2f10 k8s/dns-cache: unbound

unboundの設定です。

68c205f k8s/dns-cache: forward reverse lookup zones and rubykaigi.{net,org} to VPC resolver

特定の逆引きに対しては特定のIPに送るようにしてい……る?このIPがVPC resolverを指している?

c15afdf k8s/dns-cache: Update image

deployされるunboundを更新しています。

831f13 k8s/dns-cache: fixup 68c205f

68c205fで設定したlocal-zoneに対してnodefaultを付けています。unboundなにもわからない。

nodefault AS112ゾーン(※)のデフォルトの設定をオフにする ※ AS112ゾーンはプライベートアドレスやリンクローカルアドレスの逆引きのゾーンのことです。Unboundではデフォルトでこのゾーンに対する問い合わせにはNXDOMAIN(情報なし)を返します。 第4回 Unboundサーバ運用Tips | gihyo.jp

NXDOMAIN を返さないようにした、ということなんでしょうか。

9dc8b6c k8s/dns-cache: https://nlnetlabs.nl/documentation/unbound/howto-optimise/

unboundの設定を変更して性能を調整しています。

48cead4 k8s/dns-cache: setuid

unboundが unbound userで動作するようにしています。

83645b1 update hosts.txt, generate ptr for public IPs

グオオオ

477f8a1 add kea4 config for all venue subnets

venue下のsubnetに対してKaeで払い出すIP rangeを指定している……でいいのか?

ceca0e4 dns-cache: Expose TCP port

unbound containerに対してTCPでも通信できるようにしています。heathcheckとかでも使うから。

ae37486 Enable pod-readiness-gate-inject

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/deploy/pod_readiness_gate/

なる、ほど、ね……?

42bc251 kopipe

😜

ae96cb9 tf/dns-cache: Restrict access to healthcheck port from NLB subnets

NLBのsubnetからunboundへのhealthcheck accessをできないようにしています。metricも同じportで提供するから、というのはmetricに影響が出る?

9d02422 Use loop over map value

これはterraformのfor loopの設定。

a4e3dd3 ./gen-workflows.rb

./gen-workflows.rbを実行した結果をcommitしたんだと思います。

2c84d6c tf/k8s: node_onpremises min_size=2

Availability Zoneごとに配置されるよう、nodeのmin_sizeを2にしています

3bacade update hosts

hosts.txtが更新されました。tmpに対して名前が付きましたね。

137ce90 Probe dns-cache

unboundに対するPrometheusからの監視を設定しています。internalなhostnameとexternalなhostnameに対する名前解決もするようにしていそう。

017aca1 k8s/dns-cache: topologySpreadConstraints

unboundに対してtopologySpreadConstraintsを設定しています。Zoneごとにちゃんとばらけてくれるようにしています。

ef6d2bb k8s/dhcp: nameserver IPs

KeaがDNS resolverとして使うものを 8.8.8.8 からunboundに変更しています。

d9d2a64 air: more dynamic ips

IP addr足りなかった?

5788b2e scrape snmp

PrometheusがSNMPで監視する対象のhostを増やしています。

3551e94 snmp_exporter cisco wlc

CiscoのWLCに対してSNMPで取得するmetricを追加しています。

473d956 fixup 5788b2e

5788b2eで指定したWLCのhostnameを修正しています

306e534 prom: wlc uses public2 community

これちょっとよくわからない……WLCの居場所に関する設定?

345596c snmp-exporter: damerashii

ダメらしい。 f52e1bc で追加した一部の設定をコメントアウトしています。

b7c40c9 update hosts

hosts.txtを更新しています。順番が上に移動しただけ?

4124beb add am-i-at-rubykaigi s3 bucket

さて、会場でRubyKaigiのライブ配信を見ようとした場合には見られなくなっていたと思いますが、これがそれです。特定のS3 bucketに対し、会場内ネットワークからのアクセスであればDenyするような設定をしています。

ライプ配信視聴アプリ側ではここでその制御を行っています。

https://github.com/ruby-no-kai/takeout-app/blob/2657a8f46ac3068954c8ef46aaffeb2caac01eb2/app/javascript/Api.ts#L680-L699

d6f4953 cloudwatch: DX

AWS Direct Connectのmetricもcloudwatch-exporterで収集するようにしています。

fac7459 cloudwatch: MediaLive

AWS Elemental MediaLiveのmetricもcloudwatch-exporterで収集するようにしています。

RubyKaigiのライブ配信がどのようにAWSのサービスを使用して実現されているかはこの記事に詳しいです。まあ作者が書いてるので……

f758267 printer

プリンター?

44518e6 dns-cache: temporarily set to permissive mode

一時的に val-permissive-mode: yes にしています。これなに?

DNSSECを無効にする方法 – 日本Unboundユーザー会

なるほどね。

a6affeb dns-cache: Reverse IPv4/6 zones

先の変更を削除し、zoneの逆引きの設定を変更しています。

836e010 dns-cache: trust reverse IP zones

privateなzoneは信頼するように設定しています……というかDNS周りのこれらの設定を日本語に起こすときの言葉の選択が正しいのか全然自信がない。

0f0f71b dns-cache: Only forward private IP reverse zones

private IPのみ逆引きをforwardするよう変更しています。

2d76c39 rules

EC2やEBSなどへの監視設定をPrometheusに対して行っています。

9ef4827 Copy prometheus rules from cnw

sorah/cnwからPrometheusの設定を拝借しています。


ここからは設営日 (9/9)になります。

58ab522 prom: SNMP target down

SNMPで監視する対象がDOWNしている場合のアラートを設定しています。

f1dd400 prom: IXSystemUtilization

NECのルーターに対してのアラートを設定しています。CPU使用率かな?

8a48bd7 snmp-exporter: scrape sysinfo from wlc

WLCに対してSNMPで取得する項目を追加しています。

e618b04 printer oops!

プリンターの居場所(というよりはhosts.txtから生成される定義?)が間違っていたっぽく、それを修正しています。

今思い出したけど、これテプラのラベルプリンター?

3307051 prom: alert on sysUpTime resets

SNMPで監視している対象の機器が再起動したときのアラートを設定しています。

4e85ec7 nocadmin: moooar bucket

NocAdmin roleに対してtakeout-app(配信視聴アプリ)関連のS3 bucketへの権限を付与しています。

9b5dfe8 86400 nagai; to 3600

自分が会場ネットワークにいるかどうかの判定に使用するBucketのresponse cacheが長いので1時間に変更しています。

いかがでしたか?

いかがでしたか?

2022年11月29日