$30 off During Our Annual Pro Sale. View Details »

第4回 AWSとGitHub勉強会 - GitHub Actionsを使ったCD環境の構築 -

荻原利雄
September 18, 2023

第4回 AWSとGitHub勉強会 - GitHub Actionsを使ったCD環境の構築 -

荻原利雄

September 18, 2023
Tweet

More Decks by 荻原利雄

Other Decks in Programming

Transcript

  1. ワークフローの全体像 – 各論に行く前に 5 name: image-publish on: workflow_dispatch: jobs: build:

    runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' server-id: ghcr.io settings-path: ${{ github.workspace }} - name: Publish to GitHub Packages Apache Maven run: mvn -B package docker:build docker:push -Dimage.tag=`date +%Y%m%dT%H%M%S-%3N` --file pom.xml -s $GITHUB_WORKSPACE/settings.xml env: # 自分のリポジトリへのアクセスなのでPATではなく GITHUB_TOKENの権限で登録もできる GITHUB_TOKEN: ${{ github.token }} ※見やすいように改行しています <image-publish.yml> このワークフローの目的 ✓ コンパイルしてjarを作って、 ✓ 動作させるコンテナイメージをビルドし ✓ GitHub Container Registry(ghcr.io)にpushする チェックアウト Javaのsetup Mavenコマンド実行
  2. 実行しているMavenコマンドの詳細 6 mvn -B → ① package → ② docker:build

    → ③ docker:push → ④ -Dimage.tag=`date +%Y%m%dT%H%M%S-%3N` → ⑤ --file pom.xml → ⑥ -s $GITHUB_WORKSPACE/settings.xml → ⑦ ① Mavenのバッチモードオプション(コンソールログ出力を少なめにする) ② packagフェーズの実行。これによりJavaのコンパイルとclassファイルのjarファイル化が行われ、結果が./target以下に出力される ③ dockerプラグインのbuildゴールの実行。これによりdockerプライグインの定義に従い、コンテナのビルドが行われる ④ dockerプラグインのpushゴールの実行。これによりdockerプライグインの定義に従い、コンテナレジストリへのpushが行われる ⑤ pomに定義したimage.tagプロパティの上書き指定。``(バッククオォート)によるdataコマンドがシェルで即時実行され、その結果がimage.tagプロパティに設定さ れる(例:20230726T055802-719)。 dockerプラグインではビルドしたイメージのタグ名とpushするイメージの対象に使われる ⑥ 実行するpomファイルを指定するオプション。この場合プロジェクト直下のpomが使用される(デフォルトと同じなのでこの場合は省略化) ⑦ setup-javaアクションにより生成されたghcr.ioへの接続情報が設定されたsettings.xmlを指定する
  3. Mavenコマンドの実行の流れ – 1/2 7 $ mvn package target ├─hello-app.jar ├─libs

    │ ├─aopalliance-repackaged-3.0.3.jar │ ├─helidon-common-3.2.1.jar │ ├─helidon-common-configurable-3.2.1.jar │ ... $ mvn docker:build <plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.40.2</version> <configuration> <registry>ghcr.io</registry> <images> <image> <name>ssi-mz-studygroup/hello-app</name> <build> <tags> <tag>${image.tag}</tag> </tags> <contextDir>${project.basedir}</contextDir> <cleanup>try</cleanup> </build> </image> </images> </configuration> </plugin> # ベースイメージはeclipse-temurin(旧OpenJDK)のJava17を使用 FROM docker.io/eclipse-temurin:17-jre-alpine # 作業ディレクトリを/(root)にする WORKDIR / # Mavenのビルド成果物(sample-app.jar)をコンテナイメージにCOPY COPY ./target/hello-app.jar ./ # Mavenのビルド成果物(libs以下を)をコンテナイメージにCOPY COPY ./target/libs ./libs # ExecutableJarをjavaコマンドで起動 CMD ["java", "-jar", "./hello-app.jar"] ビルド成果物をイメージにCOPY ./Dockerfile dockerプラグインの設定 contextDir直下(プロジェクト直下)のDockerfileを使ってイメージをビルドする buildした イメージを 登録 nameタグの値をイメージ名しタグにtagタグに設定されている値を付ける
  4. Mavenコマンドの実行の流れ – 2/2 8 $ mvn docker:push <plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId>

    <version>0.40.2</version> <configuration> <registry>ghcr.io</registry> <images> <image> <name>ssi-mz-studygroup/hello-app</name> <build> <tags> <tag>${image.tag}</tag> </tags> <contextDir>${project.basedir}</contextDir> <cleanup>try</cleanup> </build> </image> </images> </configuration> </plugin> dockerプラグインの設定 [nameタグ]:[tagタグ]がpush対象 pushする先 イメージを push <servers> <server> <id>ghcr.io</id> <username>${env.GITHUB_ACTOR}</username> <password>${env.GITHUB_TOKEN}</password> </server> </servers> dockerプラグインの設定 setup-javaアクションで生成されたsettings.xml ghcr.ioに対する認 証を情報を参照 ✓ ${env.ENV_VAL}はENV_VALの環境変数を参照する設定 ✓ GITHUB_ACTORとGITHUB_TOKENはGitHubActionにより環境変数に設定される ✓ GITHUB_TOKENはそのワークフロー限り有効なアクセストークン
  5. GitHub Actions中のコンテナ操作 • dockerプラグインが行っている操作はコマンドレベルでは以下と同じになる • 今回はDockerコマンドの実行をプラグインで行ってくれるdockerプラグインを使ったが、 run: で直接dockerコマンドを実行する形式でも同じことができる(通称:ランラン♪して実 行するパターン) •

    ただし、run:でdockerコマンドを実行する場合はghcr.ioへの認証(docker login) が必要となるため、そのIDとパスワードの管理が必要となる。どこに保存してどうやって 参照するかは少し工夫が必要 9 # タグの値を取得 IMAGE_TAG=`date +%Y%m%dT%H%M%S-%3N` # ./Dockerfileを使ってコンテナイメージをビルド docker build -t ssi-mz-studygroup/hello-app:${IMAGE_TAG} . # ghcr.ioへpushするためにコンテナ名にprefixを付ける docker tag ssi-mz-studygroup/hello-app:${IMAGE_TAG} ghcr.io/ssi-mz-studygroup/hello-app:${IMAGE_TAG} # ghcr.ioへのpushの実行 docker push ghcr.io/ssi-mz-studygroup/hello-app:${IMAGE_TAG}
  6. 参考情報 • 今さら聞けないMaven – コンテナも一緒にビルドしたい。テスト実行前にコンテナを起動したい | 豆蔵デ ベロッパーサイト • https://developer.mamezou-tech.com/blogs/2022/08/31/docker_with_maven/

    • 「テスト実行前にコンテナを起動したい」の章は関係なし • GitHub Packages Container Registryをモデリングしてみた – UMLを理解の道具として | 豆蔵デ ベロッパーサイト • https://developer.mamezou-tech.com/blogs/2023/03/09/ghcr-modeling/ • 今さら聞けないMaven – コンテナのビルドと一緒にpushもMavenでしたい。 | 豆蔵デベロッパーサイト • https://developer.mamezou-tech.com/blogs/2023/03/02/docker-push-with-maven/
  7. 次回までの課題 • テーマ • GitHub Packgesで公開したコンテナイメージをAWSのEC2で動かす • お題 • AWSアカウントを作成する(まだない人)

    • EC2インスタンスを作成する • SSHでEC2に接続する • EC2環境を構築する(Dockerエンジンのインストールなど) • GitHub Packageで公開したコンテナイメージを起動する • ゴール • AWS上のコンテナアプリをローカルから呼び出せること 12
  8. 演習アドバイス • 困ったことがあったら • 今回の演習対象のAWSのアカウント作成とEC2に関することはネットに沢山あります • 困ったな?これなんだ?と疑問に思ったことはグーグル先生かChat GPTに聞くと大抵答えを教えてくれます • ただし、検索結果の上位にAWSのドキュメントが掛かりますが、これを最初に見るのは避けましょう

    • 対象を分かっている状態でマニュアル的に参照するに分にはよいですが「どうやればいいのだろ?」な状態でAWSのドキュメントをみると 余計?が増えます。まずはクラスメソッドさんのブログやQiitaなど平易に書かれてそうな記事を見るのがお勧めです • 演習手順でこれは気をつけましょう(先に言っておきます) • ルートユーザとは別にIAMユーザを作成し、普段の作業はIAMユーザで行うようにする • ルートユーザもIAMユーザも認証はMFAを有効化する、絶対 • EC2のソフトウェアイメージ(AIM)はAmazon Linux 2023 AIMではなく Amazon Linux 2 AMI(HVM)を使う • EC2のインスタンスタイプはt2.microを使う • EC2は使い終わったら課金がもったいないので停止する • なお「インスタンスの終了」はインスタンスの削除なので間違いないこと。停止は「インスタンスの停止」 14
  9. Step1. AWSアカウントを作成する(まだない人)- ルートアカウントの作成 • AWSのアカウントを作成する • ここはキャプチャを採れないので「AWSアカウント 作成」で検索すると情報が沢山でるのでネットの 情報を見ながら作成 •

    ルートアカウントの作成だけは以下のAmazonの公式が分かりやすい https://aws.amazon.com/jp/register-flow/ • アカウントを作成したら必ずMFA認証を有効化すること • MFA認証の有効化はIAMユーザと同じなので、21-22スライドを参考にする 15
  10. Step1. AWSアカウントを作成する(まだない人)- IAMユーザの作成(7/8) 22 ①デバイスを識別する任意の名称を入力 ②こちらになってることを確認 (デフォルトのまま) ③クリック ④スマフォのAuthenticator アプリで

    このQRコードを読み取る ⑤QRコードを読み取ったアプリで 表示されているワンタイムパスワー ドを入力する ⑥MFAコード1で入力したパスワードの次に表示されたパ スワードを入力する ⑦クリック *** ***
  11. Step2. EC2インスタンスを作成する(4/9) ①任意のインスタンス名を入力 ②Amazon Linuxを選択(デフォルト) ③Amazon Linux 2 AMI(HVM)を必ず選択 ④デフォルトのt2.microでOK

    ⑤クリックして作成へ ⑥任意のキー名を入力 ⑦あとはデフォルトのままで 作成をクリック ⑧ダウンロードダイアログがでるのでロー カルの任意の場所に保存 ***
  12. Step2. EC2インスタンスを作成する(9/9) ▪ SSHクライアントの接続方法の確認 ①確認するインスタン スにチェック 32 (一覧に戻って行う) 下線部は後で実施するSSHクラ イアントからの接続で使うコマンド

    なので控えておく ③確認が終わったらク リックして元の画面へ 戻る これでEC2インスタン スの作成は完了です ②インスタンスにチェックしたら クリック
  13. Step3. SSHでEC2に接続する(1/1) ▪ ローカルのSSHクライアントからEC2に接続する (Windowsは標準でSSHクライアントは入っていないため、ネットなどで調べて各自で好きなものをインストールしてくだ さい) • SSHクライアントを起動しpemファイルを保存したディレクトリに移動する • AWSコンソールの「接続」画面で確認した下線部のコマンドを実行する

    • 2つ目のSSHコマンドの引数は個人ごとに異なります これがでれば接続OK • EC2インスタンスに割り当てられるパブリックIPアドレスは EC2の起動ごとに変わる • なので、EC2を再起動した場合はAWSコンソールの前 スライドの「接続」で再度接続に必要なコマンドを確認し、 それを利用すること
  14. Step6. AWS上のコンテナアプリをローカルから呼び出す ▪別のコントールを立ち上げてローカル環境からAWS上のREST APIを呼び出す • 接続IPアドレスは個人ごとに異なります • 接続IPアドレスはEC2インスタンスのIPアドレスで、EC2インスタンスを作成したときに確認して控えてお いたアドレスになります。 ↑

    Helloが返ってくれば成功です! 今回の課題はこれで終了です。お疲れさまでしたmm 39 • EC2インスタンスに割り当てられるパブリックIPアドレスは EC2の起動ごとに変わる • なので、EC2を再起動した場合はAWSコンソールから 再度パブリックIPアドレスを確認すること(IPアドレスの確 認方法は30スライドを参照)