アプリケーションデプロイまでの流れを理解する

はじめに

三菱総研DCS クラウドテクノロジー部の神保です。
今回はアプリケーションの動作環境内でアプリ部分とインフラ部分がどのように連携しているかをご説明します。アプリケーションが動作するまでについてはCI/CD環境でのケースついても触れていますので、CI/CD環境に興味がある方にもぜひ読んでいただきたいです。


記載する範囲について

今回は、Javaのアプリケーションを例として動作させる各種ミドルウェアとアプリケーションデプロイまでの流れについて記載します。デプロイパターンとしては、手動でデプロイするパターンとCI/CD構成(GitLab Runner)によるデプロイパターンとし、それぞれのパターンにおける各ミドルウェアの連携を解説します。
そのため、実行プログラムの作成や各ミドルウェアの連携以外の設定(ログなど)については対象外としています。

アプリケーションデプロイの流れ(手動)

以下はJavaのWebアプリケーションを動作させる構成の1例です。
アプリケーション利用ユーザと、開発者の観点でそれぞれ開発されたアプリケーションがどのように連携されているかを記載しています。

アプリケーション利用ユーザからWebサーバへの連携

Webアプリケーションの場合、ユーザはブラウザからhttp(s)通信でWebサーバにアクセスをします。ミドルウェアとしてはApache,nginx,IISなどを用いることでユーザからのhttp通信を受けられる状態になります。Webサーバ用のミドルウェアとしてnginxを採用した場合、以下のようにサーバに対してブラウザアクセスが可能になります。

Webサーバからアプリケーションサーバへの連携

ユーザが通信を行う受け口はWebサーバですが、実際のアプリケーションはアプリケーション動作用のサーバで行われます。(Webサーバとアプリケーションサーバを同居させる場合もあります) JavaのWebアプリケーションの場合、tomcat,JBossなどを用いてアプリケーションを動作させる事が多く、tomcatを利用した場合アプリケーション利用ユーザはWebサーバにアクセスし、Webサーバのリダイレクト設定によりtomcatを見に行きます。
リダイレクトの設定は/etc/nginx/nginx.confに以下のような指定で可能です。これはWebサーバに通信が来たらアプリサーバの8080ポート(tomcatのデフォルトポート)にリダイレクトしなさいという設定です。

~
location / {
        proxy_pass http://<アプリサーバのIP>:8080/;
}
~

この設定により、Webサーバへブラウザアクセスした場合でもtomcat画面が見られるようになります。

また、tomcatの場合、Webappsディレクトリ内にビルドされたwarファイル(Java Webアプリケーションのアーカイブファイル)を置き、tomcatを再起動することでwarファイルが展開されアプリケーションとして動作可能状態になります。以下はtomcat再起動後の/opt/tomcat/webapps/ディレクトリとなります。mytest-app.warがwarファイルで、mytest-appはデプロイされたアプリケーション(ディレクトリ)です。

# ls /opt/tomcat/webapps/
docs  examples  host-manager  manager  mytest-app  mytest-app.war  ROOT

http://webサーバのIP/mytest-app/のようにアクセスすると作成したアプリケーションの画面が見られます。今回は「Hello World!!」の文言が表示されていればデプロイ成功となります。

開発者からアプリケーションサーバへの連携

開発者はJDK(Java用のSDK)などのプログラム開発ツール(コンパイラやデバッガなどが含まれたツール)を用いて開発し、 その後ビルダーを用いてwarファイルを作成します。その後、作成したwarファイルをtomcat内のwebappsディレクトリに配置します。 Java Webアプリケーションにおけるビルダーとは、すごくざっくり書くと開発者が作成したアプリケーション内に javaファイル,htmlファイル,cssファイル,画像ファイルなどをまとめてwar(Web Application Archive)という1つのファイルにしてくれるものです。 ビルダーにはant,maven,gradleなどがあり、mavenでmaven-archtype-webappというWebアプリ用のプロジェクトを作った場合、以下の構成のフォルダができます。

maven-archtype-webappの初期ディレクトリ構成。任意のディレクトリに作成可能。

├── pom.xml
└── src
    └── main
        ├── resources
        └── webapp
            ├── index.jsp
            └── WEB-INF
                └── web.xml

ビルド後のディレクトリ構成(targetディレクトリ配下にwarファイルが生成)

├── pom.xml
└── target
    ├── classes
    ├── maven-archiver
    │   └── pom.properties
    ├── mytest-app
    │   ├── index.jsp
    │   ├── META-INF
    │   └── WEB-INF
    │       ├── classes
    │       └── web.xml
    └── mytest-app.war

アプリケーションデプロイの流れ(CI/CD環境)

次にアプリケーションのデプロイをCI/CD環境で実行した場合について解説します。まずCI/CDとはContinuous Integration/Continuous Delivery(Deployment)」の略で、継続的インティグレーション/継続的デリバリー言われます。これは端的に言うと、ビルド、テスト、デプロイを自動的に実行してくれる手法や機能を指します。
CI/CDを利用するメリットとしてはバグを素早く検知できたり、変更を自動でリリースできるので属人化を低減できます。一方、デメリットとしては、環境の開発コストがかかるのでデプロイされる頻度が少ない環境では費用対効果が期待できない場合があります。
また、CI/CDはオンプレミス型とクラウドサービス型があり、以下の表はそれぞれの製品とメリット/デメリットをまとめたものです。

タイプ製品メリットデメリット
オンプレミス型 ・Jenkins
・Concourse CI
・GitLab Runner(クラウドサービスもあり)
・拡張性が高い
・ビルドするマシンの性能を調整できる
・サーバを用意する必要がありコストがかかる
・製品のアップデートが必要になる
クラウドサービス型 ・AWS CodeBuild
・CircleCI
・Travis CI
・製品のアップデートをしなくてよい
・サーバを自前で持たなくて良い
・サービス自体の利用料がかかる


以下の図はGitLab Runner内にリポジトリがあり、この中にソースコードがpushされると、それを契機にビルド、デプロイが自動で実行されることを表した図です。

GitLab Runnerでは以下のようなyamlファイル(gitlab-ci.yaml)をリポジトリ内に設定することで指定した操作を自動的に行ってくれます。これはリポジトリ内のファイルをビルドし、生成されたwarファイルをデプロイ対象のサーバに配置、さらにtomcatの再起動までを行うことを設定したファイルです。

image: maven:3.6-jdk-11
stages: #今回はビルドデプロイのみなのでビルドとデプロイのそれぞれのステージを宣言
  - build
  - deploy

build: #ビルドを実行しwarファイルを生成
  stage: build
  tags:
    - test
  script:
    - mvn package
  artifacts:
    paths:
      - target/mytest-app.war

deploy: #warファイルをデプロイ対象サーバに配置しtomcatを再起動
  stage: deploy
  tags:
    - test
  script:
  - eval $(ssh-agent -s)
  - mkdir -p ~/.ssh
  - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa  
  - mkdir -p ~/.ssh
  - chmod 600 ~/.ssh/id_rsa
  - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  - scp target/mytest-app.war <デプロイ対象サーバのログインユーザ>@<デプロイ対象サーバのIP>:/tmp
  - ssh <デプロイ対象サーバのログインユーザ>@<デプロイ対象サーバのIP> sudo cp /tmp/mytest-app.war /opt/tomcat/webapps/
  - ssh <デプロイ対象サーバのログインユーザ>@<デプロイ対象サーバのIP> sudo systemctl restart tomcat.service


こちらのgitlab-ci.yamlは以下の環境で動作検証を実施しました。 ※AWS Cloud9とはAWSが提供するオンライン統合開発環境です。

操作と画面からの確認は以下の順で行っております。
①リポジトリ内のファイルを変更
 今回は動作連携の確認を目的としているため、index.jspの変更のみとしています。  

~
$ sudo vi src/main/webapp/index.jsp
Hello World!!
↓以下に変更
Hello DCS!!
$ sudo git add src/main/webapp/index.jsp
$ sudo git commit -m "gitlab runner test"
$ sudo git push -u origin master
~

②リポジトリへのpushを契機にGitLab Runnerのジョブが実行
 gitlab-ci.yaml内のstage: buildの内容が自動的に実行開始(running状態)されます。

③全てのジョブがpassedになっていることを確認
 gitlab-ci.yaml内のstage: build,stage: deployの内容が正しく完了すると、
 全てのStatusがpassedになります。

※また、Statusのpassedをクリックするとジョブの実行内容(ログ)を確認できます。
 これは、stage: deployのStatusをクリックした際の画面で、
 gitlab-ci.yaml内のstage: deployで記載したscriptが順次実行されていることが分かります。

④ブラウザアクセスした際に、変更が反映されていることを確認
 ①で変更した内容が反映されていることが確認できます。

おわりに

今回はアプリケーションを手動でデプロイする場合とCI/CD環境を用いてデプロイする場合の流れを理解することをゴールとしました。CI/CD環境ではアプリケーションだけでは無く、サーバ内のconfigファイルなども管理し、デプロイすることも可能です。また、コンテナイメージによって様々な動作を実行させることも可能となるため、今後も様々な用途に応じて必要な機能の動作検証を行っていきたいと思います。

参考

CI/CDのエキスパートが解説:CI/CDとは何か? なぜ今、必要とされるのか?
https://codezine.jp/article/detail/11083
DevOps CI/CD とは
https://www.redhat.com/ja/topics/devops/what-is-ci-cd