20200729のdockerに関する記事は11件です。

古のエンジニアがlaravelを初めて触って習熟していく流れで、とても参考になった記事まとめ

経緯

普段はフロントエンド、vueやnuxtの開発を中心にやっています。今回はバックエンドも含めて開発する案件を受注したことをきっかけに、最近流行ってるlaravelでバックエンドを作ってみるか、ということになりました。

もともと、LAMP環境の構築やphp,mysqlは経験がある古のエンジニアです。
以前は素のphp+mysqlでフレームワークを使わずゴリゴリ書いていました。

開発環境はlinux(CentOS)をベアメタルサーバーにインストールして、phpやmysqlをソースからインストールしたりして使う、そういう時代のエンジニアです。HTTPサーバーといえばapacheでしょ?という時代から、最近のAWSは便利だよね〜という時代を生きてきた人です。

ちなみにデータセンターにオンプレミス環境を構築して月間数億PVのアクセスがあるソシャゲの開発運用とかを一人でやったりしていました。AWSに移行してからはRDSの負荷分散のためmemcachedサーバーにキャッシュレイヤーを作ったり、懐かしい。

話はそれてしまいましたが、最近はフロントエンド中心の開発案件をやっています。
バックエンドとのやり取りはAPIでやることが主流の時代になってきました。

久しぶりにバックエンド作るので、最新のモダンで人気なフレームワークをいっちょやってやるか!と思い人気のlaravelに目をつけたわけです。

laravelを選んだ理由

  1. 日本語で書かれたドキュメントやサンプルが多い
  2. AWSとの連携が組み込み済み
  3. API用のレイヤーが標準装備
  4. Model経由でのDBとの密な連携

この辺です。テーブル作成はphpmyadminで、PHPの中にSQLを直書きしていた私からすると、アプリケーション内からModelでDBと密接に結合しているのは新鮮です。

フロントエンドとはAPIで連携するので、その辺の機能も標準装備していることに魅力を感じました。

開発環境構築

https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4

Laravel環境構築はこちらの神リポジトリをcloneしてdockerで一発です。すごい便利な時代になったものですなぁ、昔はLinuxのインスト(ry

laravelのtableを作ってみて、表示させてみる

えっ!DBのテーブルってphpmyadminでチマチマ作るんじゃないんですか?

なるほど、作成、変更履歴も残せるマイグレーションと言うのがあるのか…

https://noumenon-th.net/programming/2020/01/15/laravel-mysql/

larvel passportでAPI認証のバックエンド側基本を作る→やめた

シンプルなjwtに切り替えました。

https://www.whizz-tech.co.jp/1442/

composer dumpautoloadってなんだ?

おかしくなったときはこれ。でもあまり使わない。

https://qiita.com/WebSysRider/items/e41f211f8c913e008d03

laravel上でvueベースの認証画面を作る

基本のapiのやりとり。

https://www.whizz-tech.co.jp/1453/

nodeが無いと言われたのでこちらでDockerを再構築

https://zukucode.com/2019/06/docker-laravel-nodejs.html

http://127.0.0.1/register
にアクセスしてみる

npm run devが抜けていたため、以下のファイルが見つからんかった

/css/app.css 178 KiB /js/app [emitted] /js/app
/js/app.js 1.4 MiB /js/app [emitted] /js/app

再度アクセスするとうまくいった

Personal access client not found. Please create one. エラーがでる

php artisan passport:client --personal

上記コマンドならうまくいく、

その後webで再度やるとうまく行った。なんでや?

これが回答かな?
https://stackoverflow.com/questions/56249565/why-we-have-to-create-personal-access-client-in-passport-again-and-again

makefileのinitに以下のコマンドを追加した→削除

docker-compose exec app php artisan passport:install

laravelのアクセスがやったら重いんですけど

Docker for Mac限定の問題。
色々試しましたけど、最終的には直接php artisan serveすることで解決。

dockerのvolumeのマウントが原因。 :delegatedをつけたら少し軽くなった。

https://wonwon-eater.com/mac-docker-performance/

/api/userにアクセスしてもなにも起こらない

忘れがち

なお、JSONが返されるのはLaravel5.3のデフォルトではヘッダーにX-Requested-With: XMLHttpRequestがある、またはAcceptヘッダーでjsonが指定されている場合です。(fetchにネイティブ対応しているブラウザではそれを使用した場合明示的にAcceptを指定してやらないと前者の対象にはならずにリダイレクトが発生し200になります。宇宙。)
https://blog.hinaloe.net/2016/09/15/try-passport-laravel-5-3/

Acceptヘッダとauth Bearerヘッダを追加して再確認、うまくいった。

よく考えたら、backendフォルダ内で直接laravel動かしたらいいんじゃね?

→動いた。ローカルなので応答も早い。
DBの接続情報を変更する必要がある。Dockerコンテナは環境変数を変更しているため。

DB_DATABASE=laravel_local
DB_USERNAME=phper
DB_PASSWORD=secret

.envの更新を反映させるにはコマンドが必要

php artisan cache:clear
php artisan config:cache

passportやめたい

composer.jsonを編集して composer update

https://ja.coder.work/so/laravel/545565

認証APIをjwtで作り直し

参考
https://re-engines.com/2019/06/03/laravelで認証apiを作る/
うごかないなんでや
https://github.com/tymondesigns/jwt-auth/issues/1484

replace
'expires_in' => auth()->factory()->getTTL() * 60
by
'expires_in' => auth('api')->factory()->getTTL() * 60

うごいた。ここでtokenの有効期限も設定できるっぽい

認証APIにregisterを移植した

バリデーションも合わせて実装した

userのcrudをAPIで実装する

参考
https://qiita.com/sutara79/items/cd4371b246b44a2cf87f

putのrequestが空っぽなんなんでや??

postmanの設定だった

https://qiita.com/wjtnk/items/eb2ddcc0642dc3197671

PUT時にuserが見つからない場合に出るModelNotFoundExceptionエラーをカスタマイズする

abortの第一引数にresponceを渡さないとstach traceが出るみたいだぞ?

https://laraveldaily.com/laravel-api-404-response-return-json-instead-of-webpage-error/

その他、細かく設定する場合
https://qiita.com/sakuraya/items/af38c4cf84459a8b5967

基本形

Handler.php
    public function render($request, Throwable $exception)
    {
        if ($exception instanceof ModelNotFoundException) 
        {
          abort(response()->json(['message' => 'not found'], 404));
        }
        return parent::render($request, $exception);
    }

コードフォーマッタとリンターがないので入れる

https://www.ritolab.com/entry/188#aj_3

開発用のメールサーバー

ブラックホールメールサーバーのDockerコンテナを開発用に立てる
http://127.0.0.1:1080 で送信したメールが全部見れる。なんて便利な世の中や・・

https://qiita.com/kanemu/items/1f2da063c7e5b5477502

seederでダミーデータを適当に作る。マスタデータも作れる。

https://qiita.com/shosho/items/b69db263a494edfe3b21

Route::resources で全部使わないよ!って場合

https://qiita.com/sympe/items/9297f41d5f7a9d91aa11

もはや個別にmodel,controllerとか作らなくても良くない?全部まとめて作れるで

https://qiita.com/niisan-tokyo/items/9c799989cb535489f201

管理画面をlaravel-adminで作る

https://laravel-admin.org/docs/#/
https://tac-blog.tech/index.php/2018/09/29/laravel-admin-add-crud/

管理設定をmigrationできるようにseederに追加する

https://qiita.com/ntm718/items/5ea29ee70b50320352c4

基本のDBクエリビルド

https://www.ritolab.com/entry/93#aj_11_1

Laravel debaggerを入れる

https://qiita.com/sutara79/items/9fd442a81001842aeba1

apiResource

https://www.webopixel.net/php/1526.html

純粋なAPIで使用するCRUDの場合はapiResourceを使用します。
Route::apiResource('users', 'UsersController');
これで、index,store,show,update,destroyが使用できるようになります。
複数のコントローラーをまとめて指定する場合はapiResourcesを使用します。
Route::apiResources([
'tasks' => 'Api\TaskController',
'users' => 'Api\UserController'
]);

api用のデータ整形、リレーションデータの追加。

https://yuhodev.hatenablog.com/entry/2019/11/27/121500

apiCollectionの作成

php artisan make:resource UserCollection
php artisan make:resource User

JsonResouseに追加したい

    public function toArray($request)
    {
        $data = parent::toArray($request);

        $data["staff"] = StaffResource::collection($this->staff);
        $data["doctor"] = DoctorResource::collection($this->doctor);

        return $data;

    }

apiのセキュリティ 自分のデータ以外は編集できてはいけない

Policyの設定を行う。

https://nakka-k.hatenablog.com/entry/2019/06/07/140758

$this->authorize('update', $user);

APIで返却するJSONを共通フォーマットにしたい

https://waterfalls.hatenablog.com/entry/2019/08/24/012913

Modelでバリデーションをする

https://qiita.com/kd9951/items/c06d107aa4018295aa25

中間テーブルを通した多対多リレーション

https://php-junkie.net/framework/laravel/many_to_many/

Tips: primarykeyを使わない場合
https://www.yuulinux.tokyo/15552/#i-5

多対多リレーション時のデータ修正・追加

例えばusers-> user_role -> roles というふうに
中間テーブルを経由してroleを管理している場合、roleを変更したい場合は

roleテーブルのidを配列で渡すだけで良い
roles = [1,2,3]

$user->roles()->sync($request->roles);

神か!!!

https://nextat.co.jp/staff/archives/200

この辺から自力で調べつつ、公式リファレンスを読めば大体構築イメージがつかめるようになってきました。

概ね3日でLaravelの基本は理解できたと言えます。
素晴らしいフレームワークですが、レイヤーも多いため、基本のSQLの知識も必要、PHPの基礎も。

やっぱ基礎って大事だな、と思いました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerでAPIサーバー(Flask)を立てる

Dockerのお勉強シリーズその2

https://www.nogawanogawa.work/entry/backend_api

を参考にやってみたことのメモ。

前回の続き

実行環境

  • Windows 10
  • DockerDesktop for Windows

ディレクトリ構成

├── backend
│   ├── Dockerfile
│   ├── app.py
│   └── requirements.txt
├── docker-compose.yml
└── mysql
    ├── conf.d
    │   └── my.cnf
    ├── initdb.d
    │   ├── schema.sql
    │   └── testdata.sql
    └── log
        └── ysql

docker-compose.yml

flaskの定義を追加。

docker-compose.yml
version: '3.3'
services:
  db:
    image: mysql:latest
    restart: always
    volumes:
      - .\mysql\initdb.d:/docker-entrypoint-initdb.d
      - .\mysql\conf.d:/etc/mysql/conf.d
      - .\mysql\log\ysql:/var/log/mysql
    environment:
      MYSQL_DATABASE: sample_db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: rootpassword
    command: --default-authentication-plugin=mysql_native_password
    expose:
      - 3306

  flask:
    build: backend/
    volumes:
      - ./backend:/code
    environment:
      MYSQL_DATABASE: sample_db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: rootpassword
    ports:
      - "5000:5000"
    command: flask run --host 0.0.0.0 --port 5000
    links:
      - db
    depends_on:
      - db

Flask

Dockerfile

python3のイメージにrequirements.txtのパッケージをインストールするだけ。

FROM python:3
ENV PTYHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt

requirements.txt

なんとなくPyMySQLにしてみた。

flask
flask-cors
PyMySQL
cryptography

app.py

app.py
import os
import pymysql.cursors
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

conn = pymysql.connect(
    host='db',
    port=3306,
    user=os.environ.get('MYSQL_USER'),
    password=os.environ.get('MYSQL_PASSWORD'),
    db=os.environ.get('MYSQL_DATABASE'),
    charset='utf8mb4',
    cursorclass=pymysql.cursors.DictCursor
)


@app.route('/', methods=['GET'])
def select_all():
    with conn.cursor() as cur:
        sql = "SELECT * FROM Comment"
        cur.execute(sql)
        results = cur.fetchall()
    return jsonify(results)

コンテナ起動&確認

$ docker-compose build
$ docker-compose up -d
Starting webapp_db_1 ... done
Creating webapp_flask_1 ... done

curlでgetしてデータをとれることを確認。そのままだと見づらいのでjqに食わせると見やすくなる。

$ curl 'localhost:5000' | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   256  100   256    0     0   6400      0 --:--:-- --:--:-- --:--:--  6400
[
  {
    "category": "food",
    "content": "good",
    "id": 1,
    "title": "curry"
  },
  {
    "category": "vegitable",
    "content": "good",
    "id": 2,
    "title": "poteto"
  },
  {
    "category": "vegitable",
    "content": "bad",
    "id": 3,
    "title": "onion"
  },
  {
    "category": "meat",
    "content": "very good",
    "id": 4,
    "title": "poak"
  }
]

途中で発生した問題

$ docker-compose up -d
Starting webapp_db_1 ... done
Starting webapp_flask_1 ... done
$ docker-compose ps
     Name                   Command               State                  Ports
--------------------------------------------------------------------------------------------
webapp_db_1      docker-entrypoint.sh mysqld      Up       0.0.0.0:3306->3306/tcp, 33060/tcp
webapp_flask_1   flask run --host 0.0.0.0 - ...   Exit 1
$ docker-compose logs -t flask
Attaching to webapp_flask_1
 flask_1  | 2020-07-29T07:00:20.975201259Z RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods

ここらへんを参考に

-> 【MySQL・Docker】cryptography is required for sha256_password or caching_sha2_passwordを参考にmy.cnfを作成
-> docker-compose python: RuntimeError: cryptography is required for sha256_password or caching_sha2_password

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-machine active 切り替え

Machine がアクティブにならない・・・。

$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER      ERRORS
default   -        virtualbox   Running   tcp://192.168.99.102:2376           v19.03.12

入力コマンド

$ DOCKER_HOST=tcp://192.168.99.103:2376

結果

$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER      ERRORS
default   *        virtualbox   Running   tcp://192.168.99.102:2376           v19.03.12

おっけい!
ほかにやり方あった気がする。教えて。

参考文献
https://stackoverflow.com/questions/33211767/how-is-a-docker-machine-marked-as-active

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerでMySQLコンテナを立ち上げ~実行確認

Dockerのお勉強シリーズその1(続く予定)

https://www.nogawanogawa.work/entry/backend_api

を参考にやってみたことのメモ。

最終的には
frontend + backend + db
の構成を作りたいの第一歩

実行環境

  • Windows 10
  • DockerDesktop for Windows

ディレクトリ構成

.
├── docker-compose.yml
└── mysql
    ├── conf.d
    ├── initdb.d
    │   ├── schema.sql
    │   └── testdata.sql
    └── log

docker-compose.yml

version: '3.3'
services:
  db:
    image: mysql:latest
    restart: always
    volumes:
      - .\mysql\initdb.d:/docker-entrypoint-initdb.d
      - .\mysql\conf.d:/etc/mysql/conf.d
      - .\mysql\log\ysql:/var/log/mysql
    environment:
      MYSQL_DATABASE: sample_db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: rootpassword
    ports:
      - 3306:3306

テーブル定義&初期データ

mysql/init.dにテーブル定義と投入する初期データのファイルを作成する

schema.sql
CREATE TABLE Comment
(
        id int NOT NULL AUTO_INCREMENT,
        title varchar(32) NOT NULL,
        category varchar(32) NOT NULL,
        content varchar(256) NOT NULL,
        PRIMARY KEY(id)
);
testdata.sql
INSERT INTO Comment (title, category, content) VALUES ('curry', 'food', 'good');
INSERT INTO Comment (title, category, content) VALUES ('poteto', 'vegitable', 'good');
INSERT INTO Comment (title, category, content) VALUES ('onion', 'vegitable', 'bad');
INSERT INTO Comment (title, category, content) VALUES ('poak', 'meat', 'very good');

コンテナ起動&確認

docker-compose upでコンテナ起動

$ docker-compose up -d

docker execで起動したコンテナに入り、mysqlに接続。
テストデータが入っていることまで確認。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
f225c6620b90        mysql:latest        "docker-entrypoint.s…"   11 minutes ago      Up 11 minutes       0.0.0.0:3306->3306/tcp, 33060/tcp   webapp_db_1
$ docker exec -it f225c6620b90 bash
# mysql --user=user --password=password
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| sample_db          |
+--------------------+
mysql> show tables;
+---------------------+
| Tables_in_sample_db |
+---------------------+
| Comment             |
+---------------------+
1 row in set (0.00 sec)

mysql> select * from Comment;
+----+--------+-----------+-----------+
| id | title  | category  | content   |
+----+--------+-----------+-----------+
|  1 | curry  | food      | good      |
|  2 | poteto | vegitable | good      |
|  3 | onion  | vegitable | bad       |
|  4 | poak   | meat      | very good |
+----+--------+-----------+-----------+
4 rows in set (0.01 sec)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

アリババクラウドコンテナサービスを利用したKubernetesクラスタの展開戦略

本記事シリーズでは、Alibaba Cloud Container Serviceを利用したCI/CD(Continuous Integration and Deployment:継続的インテグレーションとデプロイメント)のライフサイクルを実装するための実践的なアプローチを紹介しています。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

1 前提条件

ステップバイステップのガイドを通過する前に、ユーザーは以下の前提条件を持っている必要があります。

  • まともなコンピュータまたはラップトップ。
  • ウェブブラウザ、Google Chromeをお勧めします。
  • 安定したインターネット接続
  • Alibaba Cloudアカウント
  • Linuxオペレーティングシステムの操作に関する基本的な知識。
  • DockerコンテナとDockerfileの使い方についての理解と基礎知識。
  • Kubernetesの基礎知識。
  • GitHubのアカウント。

2つのリソース

このチュートリアルでは、サンプルアプリケーションのソースコードを含む多くのサードパーティのリソースを使用しています。GitHub のアプリケーションソースコードを提供してくれた Satya Depareddy さんに感謝します。
https://github.com/depareddy/java-webapp-docker

3 はじめに

本連載の前回は、クラウド上での継続的なデプロイの流れを自動化するための手順を解説しました。今回は、Alibaba Cloud Container Serviceを利用したKubernetesクラスタ上でのデプロイ戦略を中心としたDevOpsシリーズの第3回目、最終回です。

4 ローリングアップデート

これは、Kubernetesクラスタ上でのデフォルトのデプロイ戦略です。ローリングアップデートでは、Podsインスタンスを新しいものでインクリメンタルに更新することで、デプロイメントの更新をダウンタイムゼロで行うことができます。新しいPodsは、利用可能なリソースを持つノード上でスケジュールされます。

この戦略は、更新を実行している間、どの時点でも少なくともいくつかのインスタンスを稼働させておくことで、アプリケーションのダウンタイムを防ぐことを目的としています。古いポッドがシャットダウンされるのは、新しいデプロイメントバージョンの新しいポッドが起動してトラフィックを処理できるようになってからです。

5 カナリアリリース

カナリアデプロイメントは、新しいソフトウェアのバージョンをリリースする際のリスクを軽減するためのパターンです。しかし、ソフトウェアでは、継続的なデリバリを採用しているチームにとって、カナリアをリリースすることは戦略的な戦術となります。このアイデアは、新しいリリースを、安定版と並んで小さなサブセットのサーバに少しずつロールアウトするというものです。一旦テストを行った後、インフラストラクチャの残りの部分に変更をロールアウトすることができます。これにより、効果的に新しいバージョンを少数のユーザに公開することができ、障害が発生する可能性がある場合の早期の指標として機能します。カナリアは問題のあるデプロイやユーザーの怒りを避けるために非常に便利です。カナリアのデプロイに失敗しても、他のサーバには影響がないので、単にそれを捨てて根本的な原因を修正することができます。

Alibaba Cloudでカナリアリリースプロセスを体験するには、ソースコードの異なるバージョンに基づいて新しいイメージを作成することになります。

5.1 新しいブランチを作成する

タグから新しいブランチを作成する場合

$git branch release-v2.0-branch release-v2.0

5.2 ブランチからのコーデをチェックする

新しいブランチのソースコードをチェックアウト

$git checkout release-v2.0-branch

5.3 既存のソースコードを変更する

プロジェクトのソースコードのホームディレクトリ - java-webapp-docker に移動します。ディレクトリを src/main/webapp に変更します。vi や vim などのエディタで index.jsp を開きます。ヘッダー <h2>を "Welcome to Alibaba Cloud DevOps v2.0" に変更し、ヘッダーのフォントを赤に変更します。

<html>
<body>
<h2><font color="red">Welcome to Alibaba Cloud DevOps v1.0</font></h2>
</body>
</html>

5.4 変更のコミットと新しいタグの作成

次のように入力して、コミットするファイルをGitに追加します。

$git add index.jsp

そして、リポジトリにコードをコミットします。

$git commit -m "changed header text”

5.5 新しいタグの作成

前のタグを削除するには次のように入力します。

$git tag -d release-v2.0

新しいタグを作成するには、次のように入力します。

$git tag release-v2.0

5.6 リモートリポジトリへのプッシュタグ

リモートでタグを削除して再作成します。

$git push origin :release-v2.0

新しいタグを作成するには次のように入力します。

$git push origin release-v2.0

Container Registry->Build ページに戻って、イメージの最新のビルドを確認します。ビルドが成功した場合、タグ 2.0 の最新のイメージがリストに表示されるはずです。

image.png

次に、Kubernetesクラスタへのイメージの新しいデプロイメントを作成する必要があります。

5.7 新規デプロイメントの作成

「コンテナサービス」→「デプロイ」ページに移動します。テンプレートで作成」ボタンをクリックします。

image.png

YAMLスクリプトを参照して、プライベートレジストリのイメージURLを元にイメージURLを修正します。

イメージレジストリのURLを覚えていない場合は、コンテナレジストリの詳細ページに移動し、VPCのリンクからコピーしてください。

image.png

以下のYAMLスクリプトをテンプレートに貼り付け、デプロイをクリックします。

image.png

5.7.1 YAML デプロイメントスクリプト

apiVersion: apps/v1beta2 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
  name: simplewebapp-v2
  labels:
    app: simplewebapp-default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: simplewebapp-default
  template:
    metadata:
      labels:
        app: simplewebapp-default
    spec:
    #  nodeSelector:
    #    env: test-team
      containers:
      - name: simplewebapp-default
        imagePullPolicy: Always
        image: registry-intl-vpc.ap-southeast-3.aliyuncs.com/evanwong/simplewebapp:2.0
        ports:
        - containerPort: 8080

デプロイに成功すると、新しいバージョンのデプロイメントが[デプロイメント]リストに表示されます。

image.png

Pods セクションに行くと、新しいポッドが起動しています。この新しいポッドはバージョン2.0の最新のイメージをベースにしています。

image.png

5.8 テストカナリアのリリース

ターミナルを使用して、以下のコマンドを入力し、エンドポイントの URL をロードバランサー外部エンドポイントの IP アドレスに置き換えます。URL は Container Service->Discovery と Load Balancing->Service で確認できます。

image.png

$for x in {1..10}; do curl <URL of the LB endpoint>/simplewebapp; done

結果は以下のように表示されます。レスポンスは、コードのバージョンが異なるPodsからの出力になるでしょう。これはロードバランサーが平均的にPodsにリクエストを分散させているためです。

image.png

新しいイメージ (2.0) に負荷を分散させるために、デプロイメント上のレプリカの数を増やすことができます。more->YAMLをクリックしてYAMLスクリプトファイルを開きます。replicas属性を1以上、例えば10に変更します。更新をクリックします。

image.png

Podsの数を確認すると、バージョン2.0をベースにした新しいPodsは1よりも多く表示されます。

image.png

ターミナルに行って、CURLコマンドをもう一回実行してみてください。新しいPodsからは、より多くのレスポンスが出力されるでしょう。

$for x in {1..10}; do curl <URL of the LB endpoint>/simplewebapp; done

image.png

6 グレーのリリースとBlue-Greenデプロイメント

ここでは、Alibaba Cloud Container Service for Kubernetesが提供するIngress機能を利用して、グレーリリースやBlue-Greenデプロイメントを実装する方法を説明します。

グレーリリースまたはBlue-Greenデプロイメントでは、ターゲットソフトウェアの最新バージョンとそれ以前のバージョンの2つの同一の本番環境を作成することができます。そして、特定のルールを適用して、以前のバージョンのソフトウェアに影響を与えることなく、以前のバージョンから最新バージョンへのトラフィックをリルートすることができます。最新版のソフトウェアが一定期間例外なく動作した後、以前のバージョンから最新版へのトラフィックをすべてリルートすることができます。

A/Bテストは、比較・増分グレーリリースの一種です。具体的には、A/Bテストでは、一部のユーザーには以前のバージョンのサービスを利用させておき、他のユーザーのトラフィックを最新バージョンのサービスにリルートすることができます。最新版のサービスが指定された期間、例外なく動作していれば、すべてのユーザのトラフィックを徐々に最新版のサービスに迂回させることができます。

6.1 シナリオ

6.1.1 シナリオ1

例えば、サービスAが既にオンラインで動作し、外部からアクセス可能なレイヤ7サービスを提供しており、このサービスの新機能を備えた新バージョン、すなわちサービスA'が開発されているとします。サービスA'をリリースしたいが、サービスAを直接直接置き換えたくない場合。さらに、リクエストヘッダーにfoo = barが含まれている、またはCookieにfoo = barが含まれているクライアントリクエストをサービスA 'に転送したい場合。サービスA'が特定の期間、例外なく実行された場合、すべてのトラフィックをサービスAからサービスA 'に再ルーティングし、サービスAをスムーズにオフラインにする必要があります。

image.png

6.1.2 シナリオ2

例えば、サービスBという名前の以前のバージョンのサービスが、外部からアクセス可能なレイヤ7サービスを提供するためにオンラインで実行されているとします。ただし、それには既知の問題があります。新しいバージョンのService B 'は、問題が修正されて開発されています。この最新バージョンをリリースする必要がありますが最初はすべてのクライアントトラフィックの20%のみをサービスB 'に再ルーティングする必要があります。そして次に、サービスB'が例外なく一定期間実行された後、すべてのトラフィックをサービスから再ルーティングする必要があります。 BをサービスB 'に接続し、サービスBをスムーズにオフラインにします。

image.png

先行アプリケーションのリリース要件を満たすために、Alibaba Cloud Container Service for KubernetesではIngress機能を利用して、以下の4つの方法でトラフィックを分散させています。

A/Bテストでは

  • リクエストヘッダに応じてトラフィックを分散させる
  • クッキーに応じてトラフィックを分散させる
  • クエリパラムに応じてトラフィックを分散させる

blue/green deploymentでは

  • サービスウェイトに応じてトラフィックを分配

6.2 サービスの作成

イングレスを作成する前に、まず最初にv1用とv2用の2つのNodePortサービスを作成する必要があります。Container Service->Serviceページに移動し、Createボタンをクリックします。

サービス名を入力し、NodePortを選択し、ドロップダウンボックスからsimplewebapp-defaultを選択します。サービスポートには80、コンテナポートには8080を入力し、NodePortは残してプロトコルとしてTCPを選択します。

image.png

バージョン2の別サービスを作成します。

image.png

6.3 イングレスの作成

Container Service] > [Ingress]に移動します。Createボタンをクリックして新しい入口を作成します。

image.png

ポップアップ画面で、以下の詳細を入力して「作成」をクリックします。

注意事項:
- ドメイン名については、コンテナサービスが提供するデフォルトのドメイン名は *.ca58e4d5834804a40b0723004c3c11370.ap-southeast-3.alicontainer.com/simplewebapp/ です。独自のカスタムドメインを使用することもできます。
- パス: simplewebapp
- サービス上で、既存の NodePort サービス - simplewebapp-v1 と simplewebapp-v2 - を選択します。

image.png

イングレスが作成された後、新しいイングレスは以下のようにランディングページに表示されるはずです。

image.png

ウェブサイトを表示するには、ルール上のリンクをコピーし、*を以前にサービスを有効化するために使用したユーザー名に置き換えるだけです。

image.png

この段階では、この流入用に2つのサービスが作成されているにもかかわらず、Webサイトがリフレッシュされると、バージョン1.0のアプリケーションにしかリクエストを送信してくれませんでした。これは、サービスの重みが有効になっていないためです。

両方のバージョンに負荷を分散させるためには、サービスウェイトを有効にする必要があります。そのためには、ingressでupdateをクリックします。ポップアップダイアログで、サービスウェイトを有効にするチェックボックスにチェックを入れます。負荷を均等に分散させるには、各サービスのウェイトを50に設定します。

image.png

これで、リクエストはランダムに両バージョンに転送されるようになりました。ingress では、特定のサービスにマッチするルールを指定することもできます。例えば、クエリパラメータが条件にマッチした場合、そのサービスにリクエストを転送します。

ingressページに戻り、Updateをクリックします。ポップアップダイアログで、グレーのルールセットを追加し、サービスとして simplewebapp-v2 を選択し、タイプとして Query を選択し、マッチングルールとして Value match を選択し、マッチする値として key in 2 を選択します。

image.png

ブラウザでURLを更新すると、ヘッダテキストはアプリケーションv2から来ているはずです。 サービスウェイトが50/50で有効になっているため、レスポンスはアプリケーションv1から出力される可能性があります。新しいバージョン(v2)へのリクエストのみを転送する必要がある場合、simplewebapp-v1 のウェイトを 0 に減らすべきです。

image.png

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

クラウド上での継続的なデプロイの流れを自動化する方法

本記事シリーズでは、Alibaba Cloud Container Serviceを利用したCI/CD(Continuous Integration and Deployment:継続的インテグレーションとデプロイメント)のライフサイクルを実装するための実践的なアプローチを紹介しています。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

1. 前提条件

ステップバイステップのガイドを通過する前に、ユーザーは以下の前提条件を持っている必要があります。

  • まともなコンピュータまたはラップトップ。
  • ウェブブラウザ、Google Chrome
  • 安定したインターネット接続
  • Alibaba Cloudアカウント
  • Linuxオペレーティングシステムの操作に関する基本的な知識。
  • DockerコンテナとDockerfileの使い方についての理解と基礎知識。
  • Kubernetesの基礎知識。
  • GitHubのアカウント。

2. リソース

このチュートリアルでは、サンプルアプリケーションのソースコードを含む多くのサードパーティのリソースを使用しています。GitHub のアプリケーションソースコードを提供してくれた Satya Depareddy さんに感謝します。

https://github.com/depareddy/java-webapp-docker

3. 序章

DevOpsシリーズの後編です。前回は、コンテナサービスとコンテナレジストリの自動化機能を利用したCI/CDパイプラインの設定について見てきました。本パートでは、Alibaba Cloud Container ServiceへのDockerイメージのデプロイと、クラウド上での継続的なデプロイの流れを自動化する手順を中心に紹介します。

4. コンテナサービスのセットアップ

コンテナクラスタを作成する前に、初めて利用する人のためにアクティベートしておく必要があるサービスがあります。クラウドリソースが有効化されていない場合は、Kubernetesクラスタの作成に進む前に有効化する必要があります。

4.1 Kubernetesクラスタを作成する

image.png

コンテナサービスコンソールに移動し、Kubernetesを選択して、Create Kubernetes Clusterボタンをクリックします。

Alibaba Cloud上で作成できるKubernetesクラスタには、4つの異なるエディションがあります。

  • Kubernetes - このエディションは、基盤となるインフラストラクチャを完全に制御できる標準のKubernetesクラスタです。マスターノードとワーカーノードを直接管理できます。
  • Managed Kubernetes - これは、マスターノードがAlibaba Cloudによって管理されているManaged Kubernetesで、マスターノードの健全性やスケーラビリティを心配する必要はありません。あなたが集中する必要があるのは、ワーカーノードを制御することだけです。
  • Multi-AZ Kubernetes - これは、異なるアベイラビリティゾーンにまたがるクラスタです。このオプションを選択すると、物理的なデータセンターの可用性に耐障害性が向上します。
  • Serverless Kubernetes (beta) - この記事を書いている時点で、このエディションは現在ベータ版です。このエディションでは、基盤となるインフラストラクチャリソースの最高レベルの抽象化を実現しています。開発者はアプリケーションのデプロイメントにのみ焦点を当て、インフラストラクチャの管理はクラウドサービスプロバイダに任せる必要があります。 このラボでは、標準のKubernetesクラスタを選択します。

image.png

Kubernetes Clusterの設定ページに移動し、Cluster Nameに名前を指定してから、任意のRegionとZoneを選択し、VPCは「Use Existing」を選択します。VPCにはvpc-devops、VSwitchにはvswitch-devopsを選択します。

VPCとVSwitchが作成されていない場合は、「Auto Create for VPC」を選択します。

image.png

マスタノードとワーカーノードの構成、インスタンスタイプ(推奨2コア、4G RAM、40GBウルトラディスク)を選択します。

マスターノードの場合、デフォルトではマスターノードは3台に固定されており、ワーカーノードの数は2台に設定する必要があります。

image.png

マスタークラスタのログオンパスワードを「Kubernetes@2019」または任意のパスワードに設定し、SSHでクラスタにログオンできるログオン方法を選択します。CloudMonitorのオプションをクリアすることで、クラスタ作成にかかる時間を短縮することができます。すべてデフォルトのままにしておきます。

image.png

作成ボタンをクリックして、Kubernetesクラスタを作成します。

image.png

クラスタ作成中であることが画面に表示されます。クラスタ作成中は大量のサービスが作成されますので、15分~20分程度は気長にお待ちください。作成状況はコンテナサービスコンソールで確認できます。以下に正常に作成されたサービスを示します。

image.png

上記のような画面が表示されれば正常にクラスタが作成されました。クラスタ一覧に戻るをクリックします。クラスタが起動している場合は、クラスタの状態を確認してください。

image.png

クラスタ名をクリックすると詳細情報が表示されます。

image.png

API サーバー インターネットのエンドポイント。Kubernetes APIサーバがインターネット向けのサービスを提供するために使用するサービスアドレスとポート。このサービスを経由してユーザー端末でkubectlなどのツールを利用してクラスタを管理することができます。

API Server イントラネットのエンドポイント。Kubernetes APIサーバーがイントラネット向けのサービスを提供するために使用するサービスアドレスとポートです。このIPアドレスは、バックエンドの3つのマスターノードがサービスを提供するServer Load Balancerのアドレスです。

マスターノードのSSH IPアドレスです。マスターノードにSSHで直接ログオンすることができ、クラスタの日常的なメンテナンスを容易にします。

サービスアクセスドメイン。クラスタ内のサービスをテストするために使用するドメイン名です。

5. コンテナレジストリの設定

5.1 GitHub アカウントの作成 (オプション)

GitHub のアカウントをお持ちでない場合は、www.github.com にアクセスして新しいアカウントを作成してください。ユーザー名、メールアドレス、パスワードを入力します。そして、確認後、無料アカウントを選択します。

image.png

登録が完了すると、メインのランディングページに移動します。

image.png

5.2 アプリケーションのソースコードをフォークする

この研究室では、GitHub をソースコードのリポジトリとして使用します。まず、既存の Git リポジトリからソースコードをフォークする必要があります: https://github.com/echoesian/java-webapp-docker これを行うには、自分の GitHub にログインし、このリポジトリに移動します https://github.com/echoesian/java-webapp-docker 画面右上のフォークをクリックします。

image.png

フォークが成功したら、自分のリポジトリにソースコードがあるはずです。

5.3 GitHubアカウントをコンテナレジストリにバインドする

Alibaba Cloudコンソールに移動し、ページ左上の「Home」をクリックし、「Container Registry」を選択します。

image.png

最初のログオン時に下図のようなプロンプトが表示されます。左上隅でマレーシア(クアラルンプール)またはその他の地域を選択し、OKをクリックします。

コードソースに移動し、アカウントのバインドをクリックします。

image.png

ポップアップダイアログで右矢印をクリックします。GitHub アカウントにサインインするための新しいリンクが開きます。

image.png

GitHubのサインインページで、ログイン情報を入力してサインインをクリックします。

image.png

Authrizationページで、"Authroize Aliyun Developer "をクリックします。

image.png

承認されると、通知メールが送られてくるはずです。コンテナ レジストリのページに戻ります。Account Bound ボタンをクリックします。

image.png

これで、GitHub のコードソースに "Bound" と表示されるようになったはずです。

image.png

5.4 ネームスペース

ネームスペースページに戻ります。defaut プロンプトで、[OK] をクリックします。

image.png

初めての場合は、Reset Docker Login Passwordをクリックします。

image.png

Dockerのログオンパスワードを[Aliyun-test]または[お好みのパスワード]に設定します。

image.png

ネームスペースとは、リポジトリの集合体です。企業や組織のリポジトリを1つのネームスペースにグループ化することをお勧めします。

  • ネームスペースとして会社名を使用します。
  • ネームスペースとしてチームや組織を使用する: misaka-team 次の図は、ネームスペースの一覧です。このラボでは、既存のネームスペース devops-workshop を使用します。

image.png

5.5 新規リポジトリの作成

下図のようにリポジトリを作成します。リージョンをマレーシア(クアラルンプール)など任意のリージョンに設定します。

image.png

次の図に従ってパラメータを設定し、[次へ] をクリックします。先ほど作成したネームスペースを選択します。

image.png

GitHubを選択し、アカウントユーザー名とプロジェクトを入力します。リポジトリの作成をクリックします。

image.png

下図は、リポジトリが作成されたことを示しています。

image.png

管理をクリックしてリポジトリを開きます。

このリポジトリに画像をプッシュするための詳細なコマンドが表示されます。

image.png

次の図に示す最初のコマンドをECSターミナルにコピーし、リポジトリのログオンパスワードを入力します。

image.png

5.6 Dockerイメージをコンテナレジストリにプッシュする

ターミナルのルートレベルで、アプリケーションのソースコードディレクトリに移動します。

$ cd java-webapp-docker

利用可能なdockerイメージを一覧表示します。

$ docker images

image.png

下図の 2 番目のコマンドを ECS 端末にコピーする(「ImageId」を実際のものに置き換え、「tag」を v1 に設定)。

image.png

image.png

下図の 3 番目のコマンドを ECS 端末にコピーします([tag]を v1 に設定)。

image.png

下図は画像をアップロードしているところです。

image.png

下図は、画像がアップロードされたことを示しています。

image.png

Alibaba Cloudコンソールに移動し、タグを選択します。アップロードされた画像が表示されます。

image.png

5.7 自動画像ビルドの設定

ビルドセクションに移動し、イメージを自動的にビルドするオプションを有効にします。

image.png

他の環境でのダウンロード方法については、リポジトリガイドを参照してください。

image.png

6. アプリケーションをコンテナサービスにデプロイする

6.1 Kubernetesクラスタへのアプリケーションの初期展開

Container Registryのページに移動し、先ほど作成したリポジトリの管理リンクをクリックします。

image.png

「アプリケーションのデプロイ」をクリックします。

image.png

プロンプトアップページで、「デプロイ」ボタンをクリックします。

image.png

コンテナサービスのページで、すべてのデフォルトのままにして、[次へ] をクリックします。

image.png

最新の画像バージョン(1.0)を選択し、「Always pull image」を有効にして「次へ」をクリックします。

image.png

[作成]をクリックします。

image.png

次のページでは「Create Success」と表示されるはずです。デプロイが成功したかどうかを確認します。

image.png

6.2 サービスの作成

ディスカバリー->ロードバランシングページ->サービスに移動します。作成をクリックして、アプリケーションのポートを公開する新しいサーバーロードバランサーを作成します。

image.png

image.png

サービス名を入力し、タイプは Service Load balancer と public を選択し、関連するコンテナアプリケーションを選択します。ポートマッピングでは、サービスポートとコンテナポートにそれぞれ 8080 を入力します。プロトコルはデフォルトでTCPにしておきます。

6.3 トリガーの作成

コンテナサービス→デプロイ

image.png

新しいトリガーを作成するには、トリガーセクションに移動し、「トリガーの作成」ボタンをクリックします。

image.png

ポップアップダイアログで、アクションとして「Redeploy」を選択します。確認をクリックします。

image.png

トリガーが作成されると、以下のようにURLリンクが表示されるはずです。このリンクをクリップボードにコピーして、後のセクションで使用できるようにしてください。

image.png

コンテナレジストリのページに戻り、トリガーセクションに移動します。右上の「作成」ボタンをクリックします。

image.png

ポップアップダイアログで、以下の詳細を入力し、先にコピーしたコンテナサービスのトリガーページからURLリンクを貼り付けます。

image.png

7. コンテナサービス上での継続的インテグレーションとデプロイメント

このラボでは、ソースコードリポジトリとしてGitHubを使用しています。ここでは、既存のタグにコード変更をコミットし、その変更をリモートのGitにプッシュします。

一般的に、コードコミットのワークフローは以下の通りです。

1) タグでブランチを作成する

    git branch {tagname}-branch {tagname}
    git checkout {tagname}-branch

2) 変更のみの場合は、修正を手動で行います。

    git add .
    git ci -m "Fix included"

3) ローカルでタグを削除して再作成

    git tag -d {tagname}
    git tag {tagname}

4) リモートでタグを削除して作り直します。

    git push origin :{tagname} // deletes original remote tag
    git push origin {tagname} // creates new remote tag

7.1 Gitをインストールする

$yum install -y git

image.png

7.2 ソースコードをローカルコンピュータにクローンする

次に、コードをローカルコンピュータにクローンする必要があります。それを行うには、ターミナルまたはコマンドプロンプトを開きます。以下のように入力してください。

$git clone https://github.com/echoesian/java-webapp-docker

image.png

コードが正常にクローン化された後。

7.3 新しいタグの作成

新しいタグを作成するには

$git tag release-v1.0

image.png

7.4 新規ブランチの作成

タグから新しいブランチを作成するには

$git branch release-v1.0-branch release-v1.0

image.png

7.5 ブランチからのコーデをチェックする

新しいブランチのソースコードをチェックアウト

$git checkout release-v1.0-branch

image.png

7.6 既存のソースコードの変更

プロジェクトのソースコードのホームディレクトリ - java-webapp-docker に移動します。ディレクトリを src/main/webapp に変更します。vi や vim などのエディタで index.jsp を開きます。ヘッダを変更します。

"Welcome to Alibaba Cloud DevOps v1.0"へ

<html>
<body>
<h1>Welcome to Alibaba Cloud DevOps v1.0</h1>
</body>
</html>

7.7 変更のコミットと新しいタグの作成

次のように入力して、コミットするファイルをGitに追加します。

$git add .

image.png

そして、コードをリポジトリにコミットします。

$git commit -m "changed header text"

image.png

タグの削除と再作成をリモートで行います。

$git push origin :release-v1.0

image.png

新しいタグを作成するには、以下のようにします。

$git push origin release-v1.0

image.png

リモートの GitHub 関数のクレデンシャルキャッシュを有効にします。

$ git config credential.helper store
$ git remote -v

Username for 'https://github.com': <USERNAME>
Password for 'https://USERNAME@github.com': <PASSWORD>

7.8 自動ビルド

変更がGitHubのリモートリポジトリにプッシュされると、Alibaba Cloud Container Registryがトリガーされ、新しいイメージが自動的にビルドされているはずです。コンテナレジストリのページに移動してビルドし、ビルドのステータスを確認します。ステータスには「Successful」と表示されているはずです。

image.png

ビルドタスクのログを見ることができます。

image.png

ポップアップページ右上の更新をクリックすると、最新のログが表示されます。

image.png

コンテナ サービスに戻り、デプロイメント セクションに移動します。simplewebapp-default をクリックし、イベントセクションに移動します。デプロイメントジョブが以前のポッドをスケールダウンしていることに気づくでしょう、最新のイメージを引っ張り出し、新しいイメージをポッドにデプロイします。

image.png

履歴バージョンのセクションに行くと、最新バージョンがリストの一番上に表示されます。以前のバージョンにロールバックする必要がある場合は、バージョンの「ロールバック」リンクをクリックしてください。

image.png

ブラウザを開き、コンテキストパス/simplewebappでサービスアドレスをキー入力します。新しいサイトには「Welcome to Alibaba Cloud DevOps v1.0」と表示されているはずです。

image.png

URLアドレスはContainer Service -> Serviceページで確認できます。ExternalEndpointのラベルに外部IPアドレスが表示されます。

image.png

シリーズの次のパートでは、このチュートリアルではKubernetesのデプロイ戦略であるローリングアップデート、ブルーグリーンリリース、カナリアリリースを実行するように拡張していきます。ご期待ください。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンテナサービスとコンテナレジストリの自動化機能を使用したCI/CDパイプラインの設定

本記事では、Alibaba Cloud Container Serviceを利用したCI/CD(Continuous Integration and Deployment:継続的インテグレーションとデプロイメント)のライフサイクルを実装するための実践的なアプローチを紹介しています。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

1、 前提条件

ステップバイステップのガイドを実行する前に、ユーザーは以下の前提条件を持っている必要があります。

  • まともなコンピュータまたはラップトップ。
  • ウェブブラウザ、Google Chrome
  • 安定したインターネット接続
  • Alibaba Cloudアカウント
  • Linuxオペレーティングシステムの操作に関する基本的な知識。
  • DockerコンテナとDockerfileの使い方についての理解と基礎知識。
  • Kubernetesの基礎知識。
  • GitHubのアカウント。

2、 リソース

このチュートリアルでは、サンプルアプリケーションのソースコードを含む多くのサードパーティのリソースを使用しています。GitHub のアプリケーションソースコードを提供してくれた Satya Depareddy さんに感謝します。
https://github.com/depareddy/java-webapp-docker

3、序章

このドキュメントでは、Alibaba Cloud上でのDevOpsの基本的なベストプラクティスガイドを提供します。このガイドでは、Alibaba Cloud上のクラウドサービスを利用した継続的インテグレーションと継続的デプロイメント(CI/CD)をどのように実装するかについてのベストプラクティスを理解する。

本書では、CI/CDのライフサイクルを実際のシナリオに即して実装するための実践的なアプローチを説明します。ソフトウェア業界では、アプリケーション開発者の開発、デプロイ、環境オーケストレーションを容易にする方法として、コンテナを使用することの価値が急速に高まっています。それは、コンテナが環境の違いを効果的に管理し、スケーラビリティの向上を可能にし、新機能の継続的デリバリー(CD)をサポートする予測可能性を提供するからです。技術的な利点に加えて、コンテナは複雑な環境のコストモデルを劇的に削減することが示されています。

コンテナで構築された大規模かつ高弾性なアプリケーションには間違いなくメリットがありますが、環境の管理は大変なものになります。そこで、Kubernetesのようなオーケストレーションツールが本当に輝くのです。

Alibaba Cloud Container Serviceは、Googleが作成したプラットフォームに依存しないコンテナオーケストレーションツールであるKubernetesをベースにしており、Cloud Native Computing Foundation(CNCF)のプロジェクトとしてオープンソースコミュニティから多大なサポートを受けています。Alibaba CloudはCNCFのプラチナメンバーです。Alibaba Cloud Container Serviceでは、コンテナインスタンスの数をスピンアップし、スケーリングやフォールトトレランスのための管理を行うことができます。また、リクエストルーティング、コンテナディスカバリー、ヘルスチェック、ローリングアップデートなど、別のソリューションやカスタムコードが必要になるような幅広い管理活動も処理します。

Alibaba Cloud Container Serviceは、ほとんどのCI/CDツールと互換性があり、開発者はダウンタイムなしでテストの実行、Kubernetesでのビルドのデプロイ、アプリケーションのアップデートを行うことができます。Alibaba Cloud Container Serviceは、他のオープンソースツールとの互換性はあるが、CIとCDの自動化機能を備えています。

このシリーズの最初の記事では、Alibaba Cloud Container Serviceコンテナレジストリの自動化機能を使用してCI/CDパイプラインを構成することに焦点を当てています。

4. シナリオ

投資家がポートフォリオを閲覧したり、新しいファンドに投資したり、追加ファンドを購入したり、ファンドのパフォーマンスや統計情報を閲覧したりすることができるカスタマー・フェイシング・ウェブサイト・ポータルを導入している金融機関。現時点では、顧客は、ECS、SLBと自動スケーリングを使用してアプリケーションのワークロードをホストしています。顧客はデプロイを行うために伝統的な方法を使用しているが、開発者がソースコードリポジトリからソースコードを変更すると、それはユニットテストのために継続されます。テストが成功した後、開発者は手動で顧客イメージにパッケージ化し、クラウド上に保存します。その後、イメージに基づいてECSを作成するために使用されます。

現実世界のシナリオでは、アプリケーションは頻繁に変更される傾向があり、この場合、顧客はほぼ毎日ソースを変更します。アプリケーションチームはまた、テストとリリースを可能な限り迅速に行う必要があります。従来は、変更、テスト、アプリケーションサーバへの再デプロイのサイクルを経て、失敗した場合、前のバージョンにロールバックする面倒な方法が必要でした。開発者はすでにDockerコンテナの研究開発を行っています。この場合、このガイドでは、先ほどのCI/CDを継続するための手順を提供しますが、今回はアプリケーションをDockerコンテナにパッケージ化し、Kubernetes技術をベースにしたAlibaba Cloud Containerサービスにデプロイします。コンテナサービス上で稼働しているアプリケーションの複数バージョンを切り替える機能は、開発者にとって非常にシームレスで便利です。

チュートリアルを詳しく見ていきましょう。このチュートリアルでは、アリババクラウドコンテナサービスコンテナレジストリを使用します。

image.png

5. 継続的インテグレーション&継続的デプロイメント(CI/CD

5.1 CI/CDステップ

CI/CDプロセスは、一般的に以下のスキームに従います。

  • ソースコードのブランチを作成する
  • ソースコードをチェックアウト
  • ユニットテストの構築と実行
  • アプリケーションをDocker化する
  • Docker化されたアプリケーションをDockerレジストリにプッシュする
  • イメージをKubernetesクラスタにデプロイする

6. CI/CDサーバの作成

ここでは、開発/CIサーバとして動作する新しいサーバを作成します。サーバーにdockerをインストールし、サンプルアプリケーションをサーバーにクローンします。その後、docker buildを実行し、コンテナにパッケージ化します。最後に、サーバ上でアプリケーションを実行します。

6.1 仮想プライベートクラウドを作成する

ホームメニューの「製品」→「ネットワーク」→「仮想プライベートクラウド」と進みます。

image.png

VPC の名前(例:vpc-devops)と説明を入力します。

image.png

次に、VSwitch の詳細を入力します。VSwitch-devops に名前を入力し、デフォルトの CIDR ブロックを使用して、送信ボタンをクリックします。

image.png

6.2 ECS(Elastic Compute Service)の購入

ホーム -> 製品 -> Elastic Computing -> Elastic Compute Service に移動します。

image.png

ECSのランディングページで、左の「インスタンス」メニューをクリックします。

image.png

インスタンスページで「インスタンスの作成」ボタンをクリックします。

image.png

課金方法はPay-As-You-Goを選択します。ご希望の地域を選択します。サーバーの仕様としては、vCPU2台、RAM4GBを推奨しています。

image.png

公開イメージとしてCentOSを選択し、ストレージとしてデフォルトの40GBを使用します。「次へ」をクリックします。「ネットワーキング」をクリックします。

ネットワークのページで、VPC: "vpc-devops "とVSwitchを選択します。先ほど作成した "vswitch-devops "を選択します。実際のシナリオでは、ECSにパブリックIPを割り当てず、代わりにSLB、ジャンプホスト、またはSSL-VPN経由でのアクセスのみを許可することをお勧めします。このラボの目的のために、ホストに直接 ssh します。パブリックIPの割り当てチェックボックスにチェックを入れます。最大帯域幅を選択します。

image.png

セキュリティグループセクションでは、デフォルトのセキュリティグループを使用します。使用できない場合は、「セキュリティグループの作成」をクリックして、新しいセキュリティグループを作成することができます。

image.png

セキュリティグループページで、[セキュリティグループの作成]ボタンをクリックします。

image.png

テンプレートとしてWeb Server Linuxを選択し、セキュリティグループの名前と説明を与えます。ネットワークタイプとしてVPCを選択し、先に作成したVPCを選択します。入口と出口のデフォルトのルールのままにしておきます。

ssh 22 のデフォルトポートがすでに追加されているので、新しいルールを追加する要求に対してこれが表示された場合は、プロンプトを無視します。

image.png

image.png

[Add Security Group Rule] をクリックします。

image.png

ポップアップ画面で、ポート範囲に8080/8080を、認証オブジェクトに0.0.0.0.0/0を入力します。OK]をクリックします。

image.png

セキュリティグループのショーは今、次のルールを持っています。

image.png

ECS->ネットワーク画面に戻り、先ほど作成したセキュリティグループを選択します。

image.png

[次へ]をクリックします。[システム構成] ボタンをクリックします。

Logon CredentialsでPasswordを選択し、ルートユーザー名のパスワードを入力します。ECS サーバの名前を付けてプレビューをクリックします。

image.png

プレビューページで、情報が正しく表示されたら、「利用規約」チェックボックスをチェックして、「インスタンスの作成」をクリックします。

image.png

ECSが作成されたら、ランディングページで、新しいECSが作成されているのを観察してください。ECSが正常に作成された後、関連付けられたパブリックインターネットIPアドレスがあるでしょう。後の演習で使用するために、このIPアドレスを削除してください。

image.png

6.3 セットアップ開発/CIサーバ

先ほどのラボで作成したCIサーバにログオンします。PCまたはラップトップで、ターミナルまたはコマンドプロンプト、またはPuttyを開きます。ECSにログオンするには、sshコマンドを使用します。

$ ssh root@x.x.x.x

パスワードは、先ほどの ECS のセットアップ時に root で入力したパスワードを使用してください。ログインに成功すると、以下のような画面が表示されるはずです。

image.png

6.3.1 古いDockersのアンインストール
古いバージョンのDockerは、dockerまたはdocker-engineと呼ばれていました。これらがインストールされている場合は、関連する依存関係と一緒にアンインストールしてください。

$ sudo yum remove docker docker-common docker-selinux docker-engine

yum がこれらのパッケージがどれもインストールされていないと報告してくれればOKです。

イメージ、コンテナ、ボリューム、ネットワークを含む/var/lib/docker/の内容は保持されます。Docker CEパッケージはdocker-ceと呼ばれるようになりました。

6.3.2 Docker CEのインストール
yum-utilsはyum-config-managerユーティリティを提供し、devicemapperストレージドライバではdevice-mapper-persistent-dataとlvm2が必要です。

$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2

以下のコマンドを使用して安定版リポジトリを設定します。エッジやテストリポジトリからもビルドをインストールしたい場合でも、安定版リポジトリは常に必要です。

$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

最新バージョンのDocker CEをインストールするか、次のステップで特定のバージョンをインストールします。

$ sudo yum install docker-ce -y

警告:複数のDockerリポジトリを有効にしている場合、yum installやyum updateコマンドでバージョンを指定せずにインストールやアップデートを行うと、常に可能な限り高いバージョンがインストールされます。

最近追加されたリポジトリからパッケージをインストールするのが初めての場合は、GPG キーを受け入れるように促され、キーのフィンガープリントが表示されます。フィンガープリントが正しいかどうかを確認し、正しい場合はキーを受け入れてください。フィンガープリントは 060a 61c5 1b55 8a7f 742b 77aa c52f eb6b 621e 9f35 と一致しているはずです。

Dockerはインストールされていますが、起動されていません。dockerグループは作成されていますが、グループにユーザーが追加されていません。

Dockerを起動します。

$ sudo systemctl start docker

hello-worldイメージを実行して、dockerが正しくインストールされていることを確認します。

$ sudo docker run hello-world

このコマンドは、テストイメージをダウンロードし、コンテナ内で実行します。コンテナが実行されると、情報メッセージを表示して終了します。

Docker CEがインストールされ、実行されています。Dockerコマンドを実行するにはsudoを使用する必要があります。非特権ユーザーがDockerコマンドを実行できるようにするため、およびその他のオプションの設定手順については、Linux postinstallに進みます。

6.4 Dockerイメージのビルド

最新版のgitをインストールします。

$ sudo yum install git -y

6.4.1 ソースコードをCIサーバにクローンする
次に、ローカルコンピュータにコードをクローンする必要があります。

$ git clone https://github.com/echoesian/java-webapp-docker

image.png

6.4.2 Dockerビルド
dockerをビルドするには、まずローカルにクローンしたソースコードのディレクトリに変更します。

$ cd java-webapp-docker

以下のコマンドを入力して、dockerイメージをビルドします。

$ docker build -t simplewebapp .

image.png

6.4.3 dockerイメージの検証
docker イメージが正常にビルドされているかどうかを確認します。

$ docker images

image.png

6.5 Dockerイメージをローカルで実行する

KubernetestにpushされるDockerの前に、ローカルで実行してみて、すべてが正常に動作していることを確認してみましょう。

$ docker run -p 8080:8080 simplewebapp

6.5.1 ブラウザ上でWebアプリケーションを表示する
ブラウザを開き、WebアプリケーションのURLを入力します。例えば、CIサーバのIPアドレスが47.254.192.185の場合:http://47.254.192.185:8080/simplewebapp/

対応は以下のようにしてください。

image.png

7. コンテナレジストリの設定

7.1 GitHub アカウントの作成 (オプション)

GitHub のアカウントをお持ちでない場合は、www.github.com にアクセスして新しいアカウントを作成してください。ユーザー名、メールアドレス、パスワードを入力します。そして、確認後、無料アカウントを選択します。

image.png

登録が完了すると、メインのランディングページに移動します。

image.png

7.2 アプリケーションのソースコードをフォークする

この研究室では、ソースコードリポジトリとしてGitHubを使用しています。まず、既存の Git リポジトリhttps://github.com/echoesian/java-webapp-dockerからソースコードをフォークする必要があります。これを行うには、自分のGitHubにログインして、このリポジトリ https://github.com/echoesian/java-webapp-docker に移動します。画面右上のForkをクリックします。

image.png

フォークが成功したら、自分のリポジトリにソースコードがあるはずです。

7.3 GitHub アカウントをコンテナレジストリにバインドする

Alibaba Cloudコンソールに移動し、ページ左上の「Home」をクリックし、「Container Registry」を選択します。

image.png

最初のログオン時に下図のようなプロンプトが表示されます。左上隅でマレーシア(クアラルンプール)またはその他の地域を選択し、OKをクリックします。

コードソースに移動し、アカウントのバインドをクリックします。

image.png

ポップアップダイアログで右矢印をクリックします。GitHub アカウントにサインインするための新しいリンクが開きます。

image.png

GitHubのサインインページで、ログイン情報を入力してサインインをクリックします。

image.png

認証ページで「Aliyun Developerを認証する」をクリックします。

image.png

承認されると、通知メールが送られてくるはずです。コンテナ レジストリのページに戻ります。Account Bound ボタンをクリックします。

image.png

これで、GitHub のコードソースに "Bound" と表示されるようになったはずです。

image.png

7.4 名前空間

名前空間] ページに戻ります。デフォルトのプロンプトで、[OK] をクリックします。

image.png

初めての場合は、Reset Docker Login Passwordをクリックします。

image.png

Dockerのログオンパスワードを[Aliyun-test]または[お好みのパスワード]に設定します。

image.png

ネームスペースとは、リポジトリの集合体です。企業や組織のリポジトリを1つのネームスペースにグループ化することをお勧めします。

  • ネームスペースとして会社名を使用します。
  • チームや組織を名前空間として使用する: misaka-team 次の図のようにネームスペースを作成します。新しいネームスペースは、既存のネームスペースと同じにすることはできません。入力したネームスペースが既に存在する場合は、別のネームスペースを入力します。

image.png

次の図は、ネームスペースが作成されたことを示しています。

image.png

7.5 新規リポジトリの作成

下図のようにリポジトリを作成します。リージョンをマレーシア(クアラルンプール)など任意のリージョンに設定します。

image.png

次の図に従ってパラメータを設定し、[次へ] をクリックします。先ほど作成したネームスペースを選択します。

image.png

GitHubを選択し、アカウントユーザー名とプロジェクトを入力します。リポジトリの作成をクリックします。

image.png

下図は、リポジトリが作成されたことを示しています。

image.png

管理をクリックしてリポジトリを開きます。

このリポジトリに画像をプッシュするための詳細なコマンドが表示されます。

image.png

次の図に示す最初のコマンドをECSターミナルにコピーし、リポジトリのログオンパスワードを入力します。

image.png

7.6 Dockerイメージをコンテナレジストリにプッシュする

ルートディレクトリ上で、ローカルにクローンしたソースコードのディレクトリに変更します。

$cd java-webapp-docker

7.6.1 Dockerfile
dockerfileを開いてファイルを確認します。以下、dockerfileですが、簡単に言うと

1、ベースイメージとしてのmavenをダウンロード
2、作業ディレクトリの設定
3、ソースコードをターゲット画像ディレクトリにコピー
4、mavenビルドの実行
5、Tomcatイメージをダウンロードして、tomcatコンテナにデプロイ
6、port 8080を公開
7、Tomcatサーバーを実行

# setup working directory
FROM maven AS build
RUN mkdir /app
WORKDIR /app

# maven build
COPY src /app/src
COPY pom.xml /app
RUN mvn -f /app/pom.xml clean package

# deploy to tomcat server
FROM tomcat 
COPY --from=build app/target/simplewebapp.war /usr/local/tomcat/webapps
EXPOSE 8080
CMD ["catalina.sh", "run"]

以下のコマンドを実行して、simplewebapp画像のIDを取得します。

docker images

image.png

下図の 2 番目のコマンドを ECS 端末にコピーします(「ImageId」を実際のものに置き換え、「tag」を v1 に設定)。

image.png

image.png

下図の 3 番目のコマンドを ECS 端末にコピーします([tag]を v1 に設定)。

image.png

下図は画像をアップロードしているところです。

image.png

下図は、画像がアップロードされたことを示しています。

image.png

Alibaba Cloudコンソールに移動し、タグを選択します。アップロードされた画像が表示されます。

image.png

7.7 自動画像ビルドの設定
ビルドセクションに移動し、イメージを自動的にビルドするオプションを有効にします。

image.png

他の環境でのダウンロード方法については、リポジトリガイドを参照してください。

image.png

シリーズの次のパートでは、このDockerイメージをAlibaba Cloud Container Serviceにデプロイする方法と、Kubernetesのデプロイ戦略の概念をContinuous Deploymentワークフローに適用する方法を学びます。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.jsのDockerイメージのマルチコア対応をがんばってみた

いろいろ頑張ってみたものの、Docker本家とかその他の情報によると、Dockerfile内部でマルチコア対応は頑張らない方が良いらしい。せっかくがんばったので供養のためにまとめておきます。

マルチコア対応したい!

Node.jsはシングルコアで動くのでマルチコア対応したいですよね?コア数が生かせないのはかっこ悪いですよね?サーバーにそのままデプロイする場合はpm2とかのプロセスマネージャを使います。pm2のウェブサイトをみると、Docker用のpm2があるじゃないですね。

というわけでそれを使うようにしてみました。

  • package.jsonのdependenciesにはpm2のみ
  • package.jsonのその他の依存はdevDependenciesに
  • npm run buildでサーバーコードはdist/index.jsというシングルjsファイルになる(@zeit/ncc 利用)

package.jsonは以下の通り(ESLintとかビルドに不要なものは省いた)。

package.json
{
  "name": "webserver",
  "version": "1.0.0",
  "scripts": {
    "build": "ncc build src/main.ts"
  },
  "dependencies": {
    "pm2": "^4.4.0"
  },
  "devDependencies": {
    "@types/body-parser": "^1.19.0",
    "@types/compression": "^1.7.0",
    "@types/express": "^4.17.7",
    "@zeit/ncc": "^0.22.3",
    "body-parser": "^1.19.0",
    "compression": "^1.7.4",
    "express": "^4.17.1",
    "http-graceful-shutdown": "^2.3.2",
    "typescript": "^3.9.7"
  }
}

サンプルのウェブアプリはこんな感じで作ってみました。大事なのはシグナルを受け取って終了するということです。

src/main.ts
import express, { Request, Response } from "express";
import compression from "compression";
import bodyParser from "body-parser";
import gracefulShutdown from "http-graceful-shutdown";

const app = express();
app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.get("/", (req: Request, res: Response) => {
    res.json({
        message: `hello ${req.headers["user-agent"]}`,
    });
});

const host = process.env.HOST || "0.0.0.0";
const port = process.env.PORT || 3000;

const server = app.listen(port, () => {
    console.log("Server is running at http://%s:%d", host, port);
    console.log("  Press CTRL-C to stop\n");
});

gracefulShutdown(server, {
    signals: "SIGINT SIGTERM",
    timeout: 30000,
    development: false,
    onShutdown: async (signal: string) => {
        console.log("... called signal: " + signal);
        console.log("... in cleanup");
        // shutdown DB or something
    },
    finally: () => {
        console.log("Server gracefulls shutted down.....");
    },
});

こちらがDockerfileです。pm2とpm2-runtimeはだけはパスを通すようにしています。

Dockerfile
# ここから下がビルド用イメージ

FROM node:12-buster AS builder

WORKDIR app
COPY package.json package-lock.json ./
RUN npm ci
COPY tsconfig.json ./
COPY src ./src
RUN npm run build

# ここから下が実行用イメージ

FROM node:12-buster-slim AS runner
WORKDIR /opt/app
COPY package.json package-lock.json ./
RUN npm ci --prod
RUN ln -s /opt/app/node_modules/.bin/pm2 /usr/local/bin/pm2
RUN ln -s /opt/app/node_modules/.bin/pm2-runtime /usr/local/bin/pm2-runtime
COPY ecosystem.config.js ecosystem.config.js
COPY --from=builder /app/dist ./
USER node
EXPOSE 3000
CMD ["pm2-runtime", "start", "ecosystem.config.js"]

PM2の設定ファイルは次の通り。instances: "max"が勇者の証。

ecosystem.config.js
module.exports = {
    apps: [
        {
            name: "greeting-server",
            script: "/opt/app/index.js",
            env: {
                NODE_ENV: "development",
            },
            env_production: {
                NODE_ENV: "production",
            },
            instances: "max",
            exec_mode: "cluster",
        },
    ],
};

これでビルドして実行すると、コア数分プロセスが立ち上がっていることがわかります(Dockerは4コア使うように設定してあります)。

$ docker build -t webserver .
$ docker --name webserver --rm -it webserver
$ docker exec webserver pm2 list
┌─────┬────────────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id  │ name               │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├─────┼────────────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0   │ greeting-server    │ default     │ 1.0.0   │ cluster │ 18       │ 55s    │ 0    │ online    │ 0%       │ 40.8mb   │ node     │ disabled │
│ 1   │ greeting-server    │ default     │ 1.0.0   │ cluster │ 25       │ 55s    │ 0    │ online    │ 0%       │ 41.3mb   │ node     │ disabled │
│ 2   │ greeting-server    │ default     │ 1.0.0   │ cluster │ 32       │ 55s    │ 0    │ online    │ 0%       │ 41.2mb   │ node     │ disabled │
│ 3   │ greeting-server    │ default     │ 1.0.0   │ cluster │ 39       │ 55s    │ 0    │ online    │ 0%       │ 41.2mb   │ node     │ disabled │
└─────┴────────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

pm2-runtimeはpm2 --no-daemon相当のツールで、フォアグラウンドで動作し、シグナルなどはDockerの作法に従ってきちんと動作するように作られています。

めでたしめでたし・・・ではなかった

Dockerのベストプラクティスを諸々調べると、どれもnode スクリプトで起動せよ、プロセスマネージャとかランチャーは挟むな、と書かれています。ランチャー(npm run)はシグナルを適切に伝達しないということで、pm2-runtimeはそこはきちんとしているので、停止できないとかクリティカル無問題はないです。とはいえ、オーケストレーションツール側でオートスケール、みたいな話とちょっと喧嘩する可能性があるので、そこはもっと深く検証が必要なのかもしれません。

便利なところといえば、ロードバランサー的なものをおかなくても手っ取り早くパフォーマンスはあげられる・・・ぐらいですかね。

pm2はSaaSでObservabilityなサービスをしているようですね。pm2-runtimeはそこにつなげるためのエージェントという色合いが強いのかも・・・という気もしました。npm install pm2すると30MBぐらいどかっとイメージが大きくなってしまうのもいまいちだし、とりあえずこの努力はこのエントリーで供養します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Minecraft PE統合版サーバをDocker for Macで起動、バックアップ、レストア

Docker for Mac で Minecraft 統合版のサーバを立てます。
あわせてデータ領域のバックアップとレストアする手順も記載します。

logo.png

Minecraft 統合版(PE版、iPad・iPhone・Android 等)のサーバは、
Windows 版と Ubuntu 版の alpha バージョンが公開されています。
https://www.minecraft.net/en-us/download/server/bedrock/
そのままでは Mac で実行できないので、Docker for Mac を使います。

Docker イメージは下記を使いました。
https://hub.docker.com/r/itzg/minecraft-bedrock-server

mkdir minecraft-bedrock-server

curl -o docker-compose.yml https://raw.githubusercontent.com/itzg/docker-minecraft-bedrock-server/master/examples/docker-compose.yml

docker-compose up --build --no-start
docker-compose start
docker-compose logs -f

docker-compose.yml の中身 → github 参照

version: '3.4'

services:
  bds:
    image: itzg/minecraft-bedrock-server:latest
    environment:
      EULA: "TRUE"
      GAMEMODE: survival
      DIFFICULTY: normal
    ports:
      - 19132:19132/udp
    volumes:
      - bds:/data
    stdin_open: true
    tty: true

volumes:
  bds: {}

起動すると、こんなログが表示されて、統合版から接続できるようになります。

bds_1  | Starting Bedrock server...
bds_1  | NO LOG FILE! - setting up server logging...
bds_1  | [2020-07-28 11:50:24 INFO] Starting Server
bds_1  | [2020-07-28 11:50:24 INFO] Version 1.16.1.2
bds_1  | [2020-07-28 11:50:24 INFO] Session ID f130158c-xxxx-xxxx-xxxx-199a89746d3e
bds_1  | [2020-07-28 11:50:24 INFO] Level Name: Bedrock level
bds_1  | [2020-07-28 11:50:24 INFO] Game mode: 0 Survival
bds_1  | [2020-07-28 11:50:24 INFO] Difficulty: 2 NORMAL
bds_1  | [2020-07-28 11:50:24 INFO] opening worlds/Bedrock level/db
bds_1  | [2020-07-28 11:50:28 INFO] IPv4 supported, port: 19132
bds_1  | [2020-07-28 11:50:28 INFO] IPv6 not supported
bds_1  | [2020-07-28 11:50:28 INFO] IPv4 supported, port: 33126
bds_1  | [2020-07-28 11:50:28 INFO] IPv6 not supported
bds_1  | [2020-07-28 11:50:29 INFO] Server started.

設定ファイル server.properties の編集

docker-compose exec bds apt update 
docker-compose exec bds apt install vim 
docker-compose exec bds vi server.properties
docker-compose restart

データ領域のバックアップ手順

docker-compose stop

docker run -it --rm -v minecraft-bedrock-server_bds:/data -v ${PWD}:/dump debian \
tar zcvf /dump/bds.tar.gz -C /data .

データ領域のレストア手順

docker-compose stop

docker run -it --rm -v minecraft-bedrock-server_bds:/data -v ${PWD}:/dump debian \
tar zxvf /dump/bds.tar.gz

上記手順で使用中のワールドのデータを別ホストに移動することもできます。

なお、上記で debian イメージを使っているのは、itzg/minecraft-bedrock-server が FROM debian のためです。→ Dockerfile

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-composeで超簡単にNuxt.jsで静的サイトの開発環境を構築する方法

はじめに

今回用意するコンテナは4つです
必要なタイミングに応じてdocker-compose upコマンドで1つずつコンテナを起動します

  1. nodeコンテナ
    create-nuxt-appするために使用

  2. devコンテナ
    yarn devを実行し、サーバーを起動する
    アプリ開発中に使用します

  3. generateコンテナ
    静的ファイルを出力するために使用します

  4. dev_staticコンテナ
    出力した静的ファイルをApatchサーバーを立ててローカルで確認するために使用します
    出力結果はdevコンテナで起動中のものと同じ結果なはずなので、必要に応じて使用してください

環境

  • Windows10 Pro バージョン2004
  • WSL2
  • Docker For Windows

1. docker-composeファイル準備

指定するimageのタグはこちらから最新版を取得
おすすめはalpineの最新です
https://hub.docker.com/_/node/

docker-compose.yml
version: '3'

services:
  node: &app_base
    image: node:14.5.0-alpine3.10
    tty: true
    working_dir: /var/www
    volumes:
      - ./src:/var/www # ./srcをコンテナ内の/var/wwwにマウントする
    environment:
      PORT: 3000
      HOST: 0.0.0.0
    restart: always # エラーなどでコンテナが落ちた際に自動で再起動してくれる
  dev:
    <<: *app_base
    ports:
      - "3000:3000"
    command: yarn dev # upする際に実行されるコマンド
  generate:
    <<: *app_base
    command: yarn generate # upする際に実行されるコマンド
  dev_static:
    image: httpd
    volumes:
      - ./src/dist:/usr/local/apache2/htdocs/
    ports:
      - "8080:80"

2. Nuxt.jsのプロジェクト作成

  1. こちらでコンテナ内に入ります
    docker-compose run --rm node sh

  2. 必要なパッケージをインストール
    yarn global add create-nuxt-app

    ※Nuxt.js modulesでVuetify.jsを選択する場合
    apk add python make g++

  3. プロジェクトの作成

create-nuxt-app ./コマンドを実行し、対話形式でアプリのベースを作成

```
$ create-nuxt-app ./
? Project name: test
> test
? Programming language: JavaScript 
> JavaScript
? Package manager: Yarn
> Yarn
? UI framework: None
> None
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
> 未選択でEnter
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
> 未選択でEnter
? Testing framework: None
> None
? Rendering mode: Universal (SSR / SSG)
> Universal (SSR / SSG)
? Deployment target: Static (Static/JAMStack hosting)
> Static (Static/JAMStack hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
> 未選択でEnter
```
  1. コンテナから出る
exit

3. 実行

  1. 下記コマンドで起動します

    docker-compose up dev
    
  2. アクセス

http://localhost:3000

4. 静的ファイル出力

  1. 下記コマンドを実行すると/distに出力される
docker-compose up generate

5. 出力した静的ファイルをApacheサーバーで確認

  1. 下記コマンドで起動します

    docker-compose up dev_static
    
  2. アクセス

http://localhost:8080/

6.参考

以上です、お疲れさまでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Jupyter 公式の DockerHub に関するメモ

自身の理解のためにある程度調べたことをナレッジになればと思い記載

リポジトリ毎の関係性

Jupyter 公式の Read the Docs に記載がある。

Image Relationships

派生関係としては以下の通り。

  • base-notebook
    • minimal-notebook
      • scipy-notebook
        • tensorflow-notebook
        • datascience-notebook
        • pyspark-notebook
          • all-spark-notebook
      • r-notebook

イメージ名からは分かりづらいが、minimal-notebookの方がbase-notebookよりもイメージサイズが大きい。

scipy-notebook、datascience-notebook の違い

よく使われる(であろう)やつ

  • scipy-notebook
    • データ分析で使われるライブラリセット(pandas, scikit-learn など)を追加したもの
  • datascience-notebook
    • scipy-notebook にさらに R や Julia を追加したもの

したがって、Python しか使わないならscipy-notebookで十分(勘違いしていた)

イメージ Tag について

各リポジトリ内には多くのイメージ Tag が存在し、どれを利用すれば良いか一見分かりづらい。
イメージ Tag の規則はリポジトリ毎に細かい癖はありそうだが、例えばbase-notebookは2020/7/29時点で以下のようになっている

image.png

  • 黄色の強調部分(b5abe43c6d31)はコンテナイメージのSHAダイジェスト。同一ダイジェストに対して6つの Tag が存在している。
    • つまり、この6つは全て同一コンテナイメージを指すエイリアス。
  • 最後のイメージ Tag (b90cce83f37b)もSHAダイジェスト。これは GitHub 側のコミットハッシュ。
    • このイメージ Tag に対応する Git コミットがこちら

これらから分かることは、base-notebookのイメージ Tag は Python バージョンや Jupyter コンポーネント(Jupyter Notebook、JupyterLab、JupyterHub)毎にバージョンアップデートしたものが登録されている。

分かっていないこと

base-notebookは様々なエイリアスが1つのコンテナイメージを指しており、過去の Python バージョンに対応したイメージ Tag を見つけることができる。

ここで、最も実利用する(であろう)scipy-notebookのイメージ Tag はコミットハッシュばかりとなっており、目的の Python バージョンに対応するイメージ Tag が見つけづらい。
※逆にいうと、scipy-notebookの各イメージ Tag に対してベースイメージとなっているbase-notebookminimal-notebookのイメージ Tag をどのようにして見つけるのかが分からない。

image.png

いくつかのイメージを試してみたところ、Python のマイナーバージョン(3.6.6, 3.6.7, 3.8.0, ...)毎にイメージ Tag が作成されているっぽい?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む