気軽に楽しくプログラムと遊ぶ

自分が興味があってためになるかもって思う情報を提供しています。

AWSのサブネット、セキュリティグループ、ネットワークACL

AWSで扱う概念について理解を深めるために記載してみる。

サブネット

  • VPC内のアドレスレンジのこと
  • ネットワーク内の小さな、サブのネット
  • VPCに設定したCIDRブロック範囲に収まる小さなCIDRブロックを割り当てることができる
  • 個々のサブネットは、仮想ルーターを保持、これはサブネット内のデフォルトゲートウェイとなっている
  • 仮想ルーターは、ルートテーブルとネットワークACLの設定を保持している

セキュリティグループ

  • VPC内のEC2などのインスタンス単位に割当てられる通信制御設定
  • インスタンスは少なくとも1つのセキュリティグループを割り当てる必要がある
  • セキュリティグループの設定
    • 通信制御:インバウンド(入ってくる通信の許可IP指定)、アウトバウンド(出ていく通信の許可IP設定)
    • TCP/UDPとポート番号(インスタンス自体の固有番号の位置づけ)、送受信先のCIDR or セキュリティグループ

ネットワークACL

  • VPC内のサブネットに割当てられる通信制御設定
  • ACLの設定
    • 通信制御:インバウンド(入ってくる通信の許可IP指定)、アウトバウンド(出ていく通信の許可IP設定)
    • TCP/UDPとポート番号(インスタンス自体の固有番号の位置づけ)、送受信先のCIDR。(セキュリティグループは指定できない)

インターネットゲートウェイとNATゲートウェイの違いと使い方

インターネットゲートウェイとNATゲートウェイは、AWSでセキュリティを担保したいAPIサーバーなどを立てる際に使うオブジェクトです。それぞれの大雑把な違いと使い方について参考URLの内容を引用しつつ、説明します。

インターネットゲートウェイとNATゲートウェイの違い

インターネットゲートウェイ NATゲートウェイ
用途 インターネットへの相互アクセスの窓口 外部アクセス禁止としたいサーバーの踏み台
配置場所 VPC(サブネットには紐付かない?) public サブネット
NATの種類 static NAT(1対1変換) Dynamic NAT(多対1変換)

f:id:tamata78:20220209175452p:plain

インターネットゲートウェイ

インターネットゲートウェイは、static NAT(1対1変換)を行います。
具体的に言うと、VPC内に配置されたEC2インスタンスに割り当てられたprivate IPを public IPへ1対1変換することを指します。

またその変換を伴う通信は、EC2からでもインターネット外からでも可能となります。
通信がなくてもインターネットゲーなくてもにNATエントリが存在し、このエントリに登録されたIPを元に変換が行われます。

インターネットゲートウェイを使う際の設定

  • インターネットゲートウェイVPCに配置
  • public サブネット上にEC2を配置
  • public サブネットにルーティングテーブルを紐付ける(「デフォルトルート 0.0.0.0/0 」のターゲットをインターネットゲートウェイとする)

この場合のEC2は、外部から自由にアクセスされてしまうため、セキュリティを担保したい場合は、この構成は不適切。 外部からのアクセスを點せたくない場合、NATゲートウェイを用います。

NATゲートウェイ

NATゲートウェイは、dynamic NAT(多対1変換)を行います。
具体的に言うと、VPC内のprivateサブネットが紐付けられた複数のEC2インスタンスに割り当てられたprivate IPを NATゲートウェイにおいてpublic IPへ多対1変換することを指します。

またその変換を伴う通信は、EC2からのみで可能となります。
インターネット経由のアクセスにおいては、public IPからどの private IPに変換すべきか判別できないため、アクセス不可とすることができ、これによってprivateサブネットに紐付けられたEC2インスタンスのセキュリティを担保することが可能となります。

f:id:tamata78:20220209183600p:plain

EC2からインターネットへのアクセス

EC2からインターネットへのアクセスにおけるレスポンスは、どうやって各EC2インスタンスに戻すのでしょうか。 EC2インスタンスがNATゲートウェイを通る際に「NATエントリ」を生成します。このエントリには、EC2インスタンスTCP/UDPポート番号が登録されており、このポート番号を用いて、レスポンスを指定のEC2インスタンスに返却することができます。

NATゲートウェイを使う際の設定

  • インターネットゲートウェイVPCに配置
  • NATゲートウェイをpublic サブネットに紐付けて配置
  • public サブネットにルーティングテーブルを紐付ける(「デフォルトルート 0.0.0.0/0 」のターゲットをインターネットゲートウェイとする)
  • EC2インスタンスをprivateサブネットに紐付けて配置
  • privateサブネットにルーティングテーブルを紐付ける(「デフォルトルート 0.0.0.0/0 」のターゲットをNATゲートウェイとする)

参考URL

ネットワーク用語_ACL、CIDR

ネットワーク関連で知らなかった用語をまとめておく

ACLAccess Control List)

システムやファイル、ネットワーク上のリソースなどへのアクセス可否の設定をリストとして列挙したもの。

ネットワークの場合

  • 宛先と送信元のIPアドレスおよびポート番号を条件とした上で、その条件に合致した通信の可否をACLとして設定する。
  • このACLを使ってネットワークアクセスを制御することにより、特定のサーバーのIPアドレス宛のパケットのみを許可する
  • あるいは特定の送信元IPアドレスからのパケットはすべて破棄するなどといった設定が可能になる。

CIDR (サイダー)

  • 「Classless Inter-Domain Routing」の略。
  • CIDRは、クラスを使わないIPアドレス割当、経路集約を行う技術。

クラス

  • IPアドレスをネットワーク部とホスト部といった決められたブロック単位に区切る方法
  • 簡単だが、アドレス空間が無駄になりやすい
  • クラスA、クラスB・・・の何れかになり、いずれにしても必要なアドレスにピッタリなクラスがないため、アドレスが無駄になる
    • f:id:tamata78:20220113155644p:plain
    • クラスA 16,777,214台、クラスB 65,534台、クラスC 256台
  • ネットワーク部とホスト部の区別は、サブネットマスクで確認する

CIDR

NAT64とは

特殊なIPv6アドレスを利用することでIPv6アドレスを持つ端末から、IPv4アドレスのみを持つサイトへアクセスを可能とする技術です。 この技術により、混雑している従来のIPv4/PPPoE接続方式を使わず、IPv6/IPoE方式で大容量化されたネットワークに接続でき、快適に通信できます。

スクラム勉強会

どうしたら、効率的に作業を進められるか?

見積もり

  • 相対見積もり。ざっくりでもストーリーポイントを出すことが望ましい
  • チームの目的によって取りうる選択が変わる
    • ベロシティ(チームが作業を進める速度。開発効率)を上げたいのであれば、ストリートポイントを振り返って改善していく

納得感のあるプロダクトを作るには?

  • プロダクトオーナーが近い場所にいるといい

タスク作成

  • 開発目線でのタスク作成ではなく、ユーザーストーリーベースで切るのが望ましい

ブラウザ操作でもvimっぽく扱う vimvim ショートカット

以下のChrome拡張のショートカットで使いそうなものを記載しておきます。 chrome.google.com

これ以外にもありますので、知りたい方はvimiumを追加した状態で?を入力してください。helpが表示されます。

Vimiumはコマンドの繰り返しをサポートしているため、たとえば、「5t」を押すと、5つのタブが連続して開きます。ESC(または<c-[>)は、キュー内の部分的なコマンドをすべてクリアし、挿入モードと検索モードも終了します。

ページ移動

ショートカット 説明
j 下スクロール
k 上スクロール
h 左スクロール
l 右スクロール
d 下へ半ページ移動
u 上へ半ページ移動
gg ページ最上部へ移動
G ページ最下部へ移動
f ページ内のリンクをマッピング(そのキーを入力するとジャンプ)
F ページ内のリンクをマッピング(そのキーを入力すると新タブで開く)
H 戻る(back)
L 進む(forward)
ページの再読込
/ ページ内検索

URL関連

ショートカット 説明
yy 現在のURLをコピー
p コピーしてあるURLをカレントタブで開く
P コピーしてあるURLを新タブで開く

検索など

ショートカット 説明
n 検索結果次へ
N 検索結果前へ
i インサートモード

タブ操作

ショートカット 説明
t 新タブを開く
gi 一番上の入力ウィンドウに入力
o 新しいタブで検索
J タブを左へ移動
K タブを右へ移動
x タブを閉じる
X 消したタブをもとに戻す
g0 最初のタブに移動
g $ 最後のタブに移動

ブックマーク関連

ショートカット 説明
o URL、ブックマーク、または履歴エントリを開く
O URL、ブックマーク、履歴エントリを新しいタブで開く
b ブックマークを開く
B ブックマークを新しいタブで開く

Kotlin Coroutineの概念を理解する

以下でCoroutinの使い方をざっくり理解しました。
https://tamata78.hatenablog.com/entry/2021/09/06/174235

上記で理解を進める中でわからなかった概念を補足する情報を記載していきます。

CoroutineScope

  • CoroutineScopeは、コルーチンビルダー関数であるlaunchまたはasyncを使用して作成したコルーチンを全て追跡します。
  • 実行中のコルーチンはscope.cancel()を呼び出してキャンセル可能
  • キャンセルされたスコープは、コルーチンをそれ以上作成できません。
class ExampleClass {

    // Job and Dispatcher are combined into a CoroutineContext which
    // will be discussed shortly
    val scope = CoroutineScope(Job() + Dispatchers.Main)

    fun exampleMethod() {
        // Starts a new coroutine within the scope
        scope.launch {
            // New coroutine that can call suspend functions
            fetchDocs()
        }
    }

    fun cleanUp() {
        // Cancel the scope to cancel ongoing coroutines work
        scope.cancel()
    }
}

CoroutineScopeの生成時には、ジョブとスレッドプールであるディスパッチャを結合した値を設定する必要があります。

ジョブ

  • ジョブはコルーチンのハンドル(管理側)です。
  • 各コルーチンは、コルーチンのライフサイクルを管理するJobインスタンスを返却します。
  • Jobを用いてコルーチンをキャンセルするなどのライフサイクル管理ができます。
class ExampleClass {
    ...
    fun exampleMethod() {
        // Handle to the coroutine, you can control its lifecycle
        val job = scope.launch {
            // New coroutine
        }

        if (...) {
            // Cancel the coroutine started above, this doesn't affect the scope
            // this coroutine was launched in
            job.cancel()
        }
    }
}

CoroutineContext

コルーチンの設定のようなもの。 以下のCoroutineContext要素(設定項目)があります。

  • Job: コルーチンのライフサイクルを制御
  • CoroutineDispatcher: 適切なスレッドに処理を送信
  • CoroutineName: コルーチンの名前。デバッグに用いる
  • CoroutineExceptionHandler: キャッチされない例外を処理

上記の要素は以下のように割り当てられます。

  • 新規コルーチン作成時にJobインスタンスが割り当てられます。
  • Job以外のCoroutineContext要素は、コルーチンを含むスコープから継承されます。
  • 継承された要素を変更するには、launchasyncに変更対象要素を渡す必要があります。
class ExampleClass {
    val scope = CoroutineScope(Job() + Dispatchers.Main)

    fun exampleMethod() {
        // 新しいコルーチンの開始。ディスパッチャとコルーチン名をlanchの引数に設定すると変更できる
        val job = scope.launch(Dispatchers.Default + "BackgroundCoroutine") {
            // New coroutine with CoroutineName = "BackgroundCoroutine" (overridden)
        }
    }
}

+演算子は文字列結合とは違う処理なんでしょうか。引数二つ指定ではないのが少し疑問。。

ディスパッチャ

  • コルーチンは、ディスパッチャでコルーチンの実行スレッドを決定します。
  • DBアクセス、外部API実行などメインスレッドの外部で実行する場合は、デフォルト or IOディスパッチャを指定します。

開発者が指定できるディスパッチャは以下の3つになります。

  • Dispatchers.Main:UI を操作して処理を手早く作業する場合にのみ使用(suspend 関数の呼び出しなど)
  • Dispatchers.IO:メインスレッドの外部でディスクまたはネットワークの I/O を実行する場合に使用(ファイルの読み書き、ネットワーク オペレーションの実行など)
  • Dispatchers.Default :メインスレッドの外部で CPU 負荷の高い作業を実行する場合に使用(リストの並べ替えや JSON の解析など)

withContext()におけるディスパッチャ切り替え

  • withContext(Dispatchers.IO)を呼び出すことで、IOスレッドプールで実行するブロックを生成します。
  • get関数内は、IOディスパッチャ経由で実行されるようになります。
  • withContext自体が中断関数であるため、ディスパッチャのメインスレッドを中断して、get関数内の処理を実行します。
suspend fun fetchDocs() {                      // Dispatchers.Main
    val result = get("developer.android.com")  // Dispatchers.Main
    show(result)                               // Dispatchers.Main
}

suspend fun get(url: String) =                 // Dispatchers.Main
    withContext(Dispatchers.IO) {              // Dispatchers.IO (main-safety block)
        /* perform network IO here */          // Dispatchers.IO (main-safety block)
    }                                          // Dispatchers.Main
}

withContext()コルーチンを作成せず、ディスパッチャの切り替えのみを行うため、パフォーマンスに優れている。
withContextブロックの処理が完了するとget以降の処理が再開されて処理が継続されます。

実装のポイント

コールーチンの使いどころ

  • ループ処理内でのDBアクセスなど
  • 外部APIに後続処理を任せる場合。API実行を行った場合に、後処理を先にやらせておいて、レスポンスをその後、受け取るような実装。

実装時の注意点

実装していて、気づいた実装上の注意点を少し記載しておきます。

  • コルーチン生成を乱立すると逆にスレッド切り替えで遅くなる可能性があります
  • asyncのネストなどはできるだけ避ける。コルーチンが作られすぎでしまう
  • launch、runblockなどのコルーチンビルダー関数は、ループ内で入れず、外に記載。これもコルーチンを大量に作ってしまい、逆に性能劣化を招く

コルーチン内での例外

scope.launch内でのasyncをすると例外をキャッチできずにクラッシュするということが発生したりする。
この場合は、「coroutineScopeをtry catchで囲む」という方法で対処すると良い。

コルーチンがネストしていると親コルーチンに例外が伝播してしまうが、asyncをscope.launchと別のコルーチンで囲むことでscope.launchのコルーチンへ例外を伝播させるのを止めることができ、クラッシュを防ぐことができるようだ。

以下の記事の説明がわかりやすかった。
Coroutines asyncとException - Kenji Abe - Medium

参考URL