Level 1: アプリケーションをコンテナ化する

目的・ゴール: アプリケーションをコンテナ化する

今回はコンテナに適したアーキテクチャへ変更するまえの段階として、 オンプレミスで仮想マシンで動いているアプリケーションについてコンテナ化をしていきます。

コンテナ技術のDockerを使うことでクラウド、オンプレミス、PCなどどのような環境でもアプリケーションを稼働させることができます。

具体的にはコンテナイメージをpullし、実行します。 その結果、アプリケーションがコンテナとして起動します。

このレベルではこのあとのラボで使用するKubernetes上で稼働させるアプリケーションのコンテナイメージを作成するのがの目標です。

流れ

  1. Dockerfileを作成する。
  2. ビルドを行いDockerイメージを作成
  3. 作成したDockerイメージをDocker Registryに登録
  4. どこからでもpull可能に(デプロイが可能に)

コンテナ化の準備

本ラボでは以下のミドルウェアやスタックを使ったアプリケーションを想定しています。 基本的にはアプリケーションをコンテナ化する際にはDockerHubで作成済みのイメージを使用することで効率よくコンテナ化することができます。

Web/AP レイヤー

  • nginx
  • apache
  • tomcat

Databaseレイヤー

  • mySQL
  • Postgress
  • Oracle
  • MongoDB

コンテナイメージの作成

このステップはアプリケーションを持ち込みの場合や複雑なスタックをコンテナ化する際に行うステップです。
選択したアプリケーションによっては不要なステップになるのでやるべきかどうかを確認してください。

その場合、 アプリケーションのマニフェストファイルを作成してデプロイ からはじめてください。

想定するアプリケーションのコンテナイメージを作成します。

Dockerfile のリファレンス Dockerfile Reference ファイル

留意点としては以下の通りです。

  • アプリケーションの配置をDockerfile内に配置

  • 基本となるコンテナイメージについてはDockerHubで探してベースイメージとする

  • 静的な構成となっていないか(IPパスワードのべた書きなど)

    • 環境変数で設定出来るよう設計する。のちほどk8sのSecretなどでパスワードを保存
  • 冪等性はコンテナイメージ側で対応する。責任範囲を明確にしてイメージを作成

  • ステートフルなものについてはコンテナに適したものにする

ヒント

記述例を提示します。このままビルドしてもイメージは作成されませんのであくまで記述例としてみてください。 どうしても進まない場合は サンプル: Dockerfile記述例 をクリックしてください。

コンテナイメージのビルド

作成した Dockerfileをビルドしてイメージを作成します。

バージョニングを意識してコンテナイメージを作成します、コンテナイメージに明示的にバージョンを指定します。

$ docker build -t 生成するコンテナイメージ名:タグ名 Dockerファイルのパス

Dockerイメージの生成方法は複数の手法があります。 例えば、普通のOSイメージを起動して、ログインしパッケージなどのインストールを行っていく手法があります。 メリットとしてはオペレーションで作成したものをイメージとして登録できるため、Dockerfileを作成しなくても良いといメリットがある一方で、 コンテナイメージの作成方法が不透明となる可能性もあります。

イメージレポジトリに登録

今回はイメージレポジトリにDockerHubを使用します。

DockerHub へログイン

DockerHubにアカウントがあることが前提です。

$ docker login

  ユーザ名、パスワードを入力

$ docker image push アカウント名/コンテナイメージ名:タグ名

アプリケーションのマニフェストファイルを作成してデプロイ

Level 0: 環境の確認・基本操作 ではコマンドラインで作成してきましたがYAMLファイルで1サービスをまとめてデプロイ出来るようにします。

ファイルのセクション構成としては以下の通りです。

  • Service
  • PersistentVolumeClaim
  • Deployment

サンプルファイルを準備しましたのでそれぞれの項目の意味を考え作成してみましょう。

(https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/ を参考としています。)

アプリケーションをデプロイするマニフェストファイルの例 deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: サービス名
  labels:
    app: 任意のラベル名
spec:
  ports:
    - port: ポート番号
  selector:
    app: アプリケーション名
    tier: ティア名
  clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: デプロイメント名
  labels:
    app: アプリケーション名
spec:
  selector:
    matchLabels:
      app: アプリケーション名
      tier: ティア名
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: アプリケーション名
        tier: ティア名
    spec:
      containers:
      - image: イメージ名:タグ
        name: アプリケーション名
        env:
        - name: PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-pass
              key: password
        ports:
        - containerPort: ポート番号
          name: アプリケーション名

kubectlの操作を容易にする

kubectlのオペレーションの簡易化のためlabelをつけることをおすすめします。

kubectl get pods -l app=nginx などのようにlabelがついているPod一覧を取得といったことが簡単にできます。 ほかにも以下の様なことが可能となります。

  • kubectl delete deployment -l app=app_label
  • kubectl delete service -l app=app_label
  • kubectl delete pvc -l app=wordpress

kubectlを使ってアプリケーションをデプロイ

以下のコマンドを実行してデプロイしましょう。

$ kubectl create -f deployment.yaml

アプリケーションの稼働確認

デプロイしたアプリケーションにアクセスし正常稼働しているか確認します。

アクセスするIPについてはサービスを取得して確認します。

$ kubectl get svc

結果として以下のような出力が得られます。

今回はServiceのtypeをNodePortで指定しているため、PORT(S)の」:」で区切られた右側のポート(以下の例だと32048)にアクセスしてみましょう。

NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP   10.96.0.1      <none>        443/TCP        6d
wordpress         NodePort    10.98.247.58   <none>        80:32048/TCP   2h
wordpress-mysql   ClusterIP   None           <none>        3306/TCP       2h

注釈

kubectl引数の省略系について

今回はServiceの確認をする際に svc という省略形でコマンドを実行しました。 他のオブジェクトも同様に省略形があります。コマンド入力を省力化したい場合は省略形も使ってみましょう。

kubectl --helpkubectl XX --help コマンドで確認できます。

まとめ

kubectlやYAMLで記載するマニフェストファイルを使ってk8sへのデプロイが体感できたかと思います。 実運用になるとこのYAMLをたくさん書くことは負荷になることもあるかもしれません.

その解決のためにパッケージマネージャーHelm 等を使ってデプロイすることが多いかと思います。 このラボでは仕組みを理解していただき、応用出来ることを目的としています。

ここまでで Level1 は終了です。