2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GCE上でContainer-Optimized OSを使ってコンテナバッチ処理する方法

Last updated at Posted at 2020-01-09

Container-Optimized OSを使ってGCE上でコンテナバッチ処理する方法のメモ。
コンテナバッチ処理後はコンテナ内でVMを削除するため、VM稼働分のコストで済みます。
コードはGithubにあげています。
https://github.com/yolo-kiyoshi/gce_docker_cli

フォルダ構成
root/
 ├ .env
 ├ .param
 ├ Dockerfile
 ├ Pipfile
 ├ Pipfile.lock
 ├ *********.json(credentialファイル)
 ├ scripts/
 │ └ build_and_push.sh
 │ └ deploy_container.sh
 └ src/
   └ delete_vm.py
   └ main.py

準備

VM起動パラメータ

VM起動パラメータを .param に記載します。

SERVICE_ACCOUNT=*********
PROJECT_ID=*********
MACHINE_TYPE=n1-standard-1

Credentialファイル

Dockerfile と同一ディレクトリにCredentialファイル(json)を配置します。

コンテナ環境変数

コンテナ環境変数を .env に記載します。
Credentialファイル(json)pathを必ず GOOGLE_APPLICATION_CREDENTIALS に記載します。

GOOGLE_APPLICATION_CREDENTIALS=/app/************.json

概要

  1. GCRにDockerイメージをプッシュ
  2. GCRのイメージからGCE上のVMにコンテナをデプロイ。コンテナ処理終了後、VMを削除

GCRにDockerイメージをプッシュ

Dockerイメージをビルドし、GCRにイメージをプッシュするスクリプトです。

scripts/build_and_push.sh
# !/usr/bin/env bash

set -eu

image=${1:-}
tag=${2:-latest}

# read param
. .param

fullname="gcr.io/${PROJECT_ID}/${image}:${tag}"

# read setting file
docker build -t ${image}:${tag} .
docker tag ${image}:${tag} ${fullname}
docker push ${fullname}
echo "image successfully pushed to: ${fullname}"

Dockerfile と同一ディレクトリで以下を実行すると、GCRにDockerイメージをプッシュできます。

Dockerビルド&GCRへのプッシュ
sh scripts/build_and_push.sh <イメージ名> <タグ>

GCRのイメージからGCE上のVMにコンテナをデプロイ。コンテナ処理終了後、VMを削除

GCRのイメージからGCE上のVMにコンテナをデプロイするスクリプトです。

deploy_container.sh
# !/usr/bin/env bash

set -eu

service=${1:-}
image=${2:-}
tag=${3:-latest}

# read param
. .param

fullname="gcr.io/${PROJECT_ID}/${image}:${tag}"

gcloud compute instances create-with-container ${service} \
    --container-image=${fullname} \
    --container-env-file=.env \
    --container-restart-policy=never \
    --machine-type=${MACHINE_TYPE} \
    --service-account=${SERVICE_ACCOUNT}

VMを削除するモジュールです。

src/delete_vm.py
from googleapiclient import discovery

from oauth2client.client import GoogleCredentials

import requests


def delete_vm():
    # credentialオブジェクト取得
    credentials = GoogleCredentials.get_application_default()
    service = discovery.build('compute', 'v1', credentials=credentials)
    # メタデータサーバからプロジェクトID, インスタンンス名, ゾーンを取得する
    project_id = requests.get(
        "http://metadata.google.internal/computeMetadata/v1/project/project-id",
        headers={"Metadata-Flavor": "Google"}
    ).text
    name = requests.get(
        "http://metadata.google.internal/computeMetadata/v1/instance/name",
        headers={"Metadata-Flavor": "Google"}
    ).text
    zone_long = requests.get(
        "http://metadata.google.internal/computeMetadata/v1/instance/zone",
        headers={"Metadata-Flavor": "Google"}
    ).text
    zone = zone_long.split("/")[-1]

    print(f'[delete target] project_id:{project_id},name:{name},zone:{zone}')
    # VMインスタンス削除
    request = service.instances().delete(
        project=project_id,
        zone=zone,
        instance=name
    )
    request.execute()

main の最後(finally)でVM削除処理を行います。

src/main.py
from delete_vm import delete_vm


try:
    print('process start.')
    ######################
    # process
    ######################
    print('process end.')
finally:
    delete_vm()

Dockerfile と同一ディレクトリで以下を実行すると、GCRのDockerイメージをもとにVMにコンテナをデプロイします。
コンテナ内での処理終了後はVMを削除します。

sh scripts/deploy_container.sh <サービス名> <イメージ名> <タグ>

参考

How to make GCE instance stop when its deployed container finishes?
Google公式ドキュメント

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?