20200727のdockerに関する記事は9件です。

Node.jsとMySQLをDockerComposeで組んでみた

初めてのDockerネットワーク
これから先僕が環境構築する際、思い出せるようにするための、です。

事前準備

まずDockerHubから二つのイメージをpullするところから
それぞれ12系と5.7系を使うのでバージョン指定

$ docker run -it node:12
$ docker run -it mysql:5.7

runはpull,create,startを一気に行ってくれる

control+p+qでコンテナから出る

その後$ docker ps -aで一度止めて、
コンテナが作成されているかを確認する(Upなら一度stopしてExitedにしておく)
これからは$docker start [コンテナID]で起動できる

$ docker rename [古いコンテナ名] [新しいコンテナ名]
しておいた方がわかりやすい

正しいバージョンのものが入っているかの確認は起動後
$ docker exec -it [コンテナ名] bash
attachと違うのはコンテナを起動したまま抜けることができるのかできないのかが違うexecは起動したまま抜けることができる
でコンテナに入り、バージョン確認...

MySQLが起動しない...

先人様がいらっしゃいました。ありがとうございます。↓
https://qiita.com/takepan/items/0cbf13af3a0bb2c243ab

よしこれで確認できた

...でどうやってつなげるん??

Docker Composeとは

複数のコンテナを組み合わせてシステムを構成するための仕組みに用いるのがDocker Composeと呼ばれるもので、予めコンテナの起動方法やボリューム、ネットワークの構成などが書かれている

こんなものがあるのか、今まで一つのコンテナを独立させて動かしていたので、全く知りませんでした...

事前知識でDockerネットワークやマウントのことを知らなければならないとのことで書籍を借りて軽く頭に入れておきました。
全然知らないままDockerを使っていたのだなと反省

そしてこれを書いていく...docker-compose.ymlを作ってバージョン決めて、サービスの中身にnode.jsとmysql使いますよってこととかそれぞれの設定など、先人のymlファイルを参考にゴリゴリ書いていく...

書き方を丁寧に載せてる先人様の記事はこちらです。ありがとうございます。↓
https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa

かけたら、docker-compose up で起動
しばし待つ

...しばし待つ

終わらねえ

db  | Version: '5.7.31'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

ここで止まって一向に動かない...

仕方ないので、control+cで一度抜けました

docker-compose psで確認すると動いといて欲しいdb(mysql)が動いてない...

一か八かでdocker start dbを試すと...

stateがExitからUpに
一件落着

ていうかこのやり方だと最初にコンテナは立ち上げなくても、なんならimageもpullしてこなくて急にdocker compose書いてあげた方がよかったのね...

じゃあ他のコンテナもたてます
今回はフロント、バック、dbの三つのコンテナを用意します。

docker-compose start

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

Node.jsとMySQLをDockerComposeで組みつつ、React,Express,MySQLの環境構築を躓きながらやっていく

初めてのDockerネットワーク
これから先僕が環境構築する際、思い出せるようにするための、です。

事前準備

まずDockerHubから二つのイメージをpullするところから
それぞれ12系と5.7系を使うのでバージョン指定

$ docker run -it node:12
$ docker run -it mysql:5.7

runはpull,create,startを一気に行ってくれる

control+p+qでコンテナから出る

その後$ docker ps -aで一度止めて、
コンテナが作成されているかを確認する(Upなら一度stopしてExitedにしておく)
これからは$docker start [コンテナID]で起動できる

$ docker rename [古いコンテナ名] [新しいコンテナ名]
しておいた方がわかりやすい

正しいバージョンのものが入っているかの確認は起動後
$ docker exec -it [コンテナ名] bash
attachと違うのはコンテナを起動したまま抜けることができるのかできないのかが違うexecは起動したまま抜けることができる
でコンテナに入り、バージョン確認...

MySQLが起動しない...

先人様がいらっしゃいました。ありがとうございます。↓
https://qiita.com/takepan/items/0cbf13af3a0bb2c243ab

よしこれで確認できた

...でどうやってつなげるん??

Docker Composeとは

複数のコンテナを組み合わせてシステムを構成するための仕組みに用いるのがDocker Composeと呼ばれるもので、予めコンテナの起動方法やボリューム、ネットワークの構成などが書かれている

こんなものがあるのか、今まで一つのコンテナを独立させて動かしていたので、全く知りませんでした...

事前知識でDockerネットワークやマウントのことを知らなければならないとのことで書籍を借りて軽く頭に入れておきました。
全然知らないままDockerを使っていたのだなと反省

そしてこれを書いていく...docker-compose.ymlを作ってバージョン決めて、サービスの中身にnode.jsとmysql使いますよってこととかそれぞれの設定など、先人のymlファイルを参考にゴリゴリ書いていく...

書き方を丁寧に載せてる先人様の記事はこちらです。ありがとうございます。↓
https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa

かけたら、docker-compose up で起動
しばし待つ

...しばし待つ

終わらねえ

db  | Version: '5.7.31'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

ここで止まって一向に動かない...

仕方ないので、control+cで一度抜けました

docker-compose psで確認すると動いといて欲しいdb(mysql)が動いてない...

一か八かでdocker start dbを試すと...

stateがExitからUpに
一件落着

ていうかこのやり方だと最初にコンテナは立ち上げなくても、なんならimageもpullしてこなくて急にdocker compose書いてあげた方がよかったのね...

じゃあ他のコンテナもたてます
今回はフロント、バック、dbの三つのコンテナを用意します。

docker-compose start

動かない...

それもそのはず、docker-composeに必要なコマンドを書いてなかったからなんですね
いやymlファイルに書くコマンド全然わからん...ってなった僕はとりあえずdocker-compose run [コンテナ名] bashで中に潜り込んで、reactの環境を作ることに...

node -v,npm -vでバージョンを確認
npm install -g create-react-appでcreate-react-appをインストール

create-react-app [プロジェクトを入れるディレクトリ名]
しばしまつ...

Happy hacking!これで完了

(docker-compose run [コンテナ名] bashで中に潜り込んで作ったせいで、docker-compose upでローカルに作られたディレクトリの中に[プロジェクトを入れるディレクトリ名]のディレクトリができてしまったので削除しておく)

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

EC2,Docker,Github,Codedeploy,Codepipeline まわり個人的メモ

EC2とGithubの接続に関するエラー解消

https://qiita.com/hisayuki/items/1f608f70a212982b23d5

dockerで作成したRailsをデプロイする手順

https://qiita.com/at-946/items/1e8acea19cc0b9f31b98

EC2上でコンテナの起動

gitlabの場合
[myuser@xxx.xxx.xxx.xxx ~]$ exit
$ scp -i ~/.ssh/myapp.pem ~/myapp/config/master.key myuser@xxx.xxx.xxx.xxx:./myapp/config/
[myuser@xxx.xxx.xxx.xxx ~]$ cd myapp
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose build
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose run web rails db:create
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose run web rails db:migrate
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose run web rails assets:precompile
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ mkdir tmp/sockets
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ touch tmp/sockets/puma.sock
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose up
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GitHub ActionsでSpringBootアプリをさくらVPSにSSHしてデプロイする

概要

  • GitHub ActionsでさくらVPSにデプロイしようとしていろいろハマったのでその結果を残しておきます。
  • GitHub ActionsからAWSとかAzureにデプロイは色々記事がありますが、それ以外のサーバーにログインしてごにょごにょしたいときはどうすればいいのかがあまり書かれていなかったので、似たようなことがしたい人の参考になればさいわいです。
  • 間違っている点、こうすればもっと楽だよなどあればご指摘ください!

環境

  • GitHub Actions実行環境:ubuntu-latest
  • Java8
  • SpringBoot
  • さくらVPS CentOS Linux release 7.8.2003 (Core)

この記事でやること

  • GitHub Actionsでmasterブランチにマージされたら、さくらVPSにデプロイする

この記事では書かないこと

  • GitHub Actionsそのものについての解説は公式や書籍などをご参照ください。
  • CIの設定は他の記事でもサンプルが多くあるのでそちらを参照ください。

手順

  1. /.github/workflows配下にdeploy.ymlを用意する(名前はなんでもOK)
  2. デプロイ用のシェルスクリプトを用意する
  3. ローカルでGitHub ActionsがさくらVPSにアクセスするための秘密鍵・公開鍵のセットを作成する
  4. GitHubのSecretsに作成した秘密鍵と公開鍵、known_hostsを登録する
  5. さくらVPSのOpenSSHのバージョンをアップデートする
  6. さくらVPSのSSH設定を確認する
  7. ローカルで作成した(GitHubに登録した)公開鍵をさくらVPSに登録する
  8. masterブランチにプルリク出してマージする

1. /.github/workflows配下にdeploy.ymlを用意する(名前はなんでもOK)

  • GitHub Actions用の設定ファイルを用意します。
  • GitHub ActionsでSSHするためにInstall SSH Keyを利用しました。 日本の方が作成されたアクションで、こちらの本人が執筆された記事を参考にしました。ありがとうございます。
deploy.yml
name: sample-deploy
on:
  push:
    branches:
      - master

jobs:
  deploy:
    name: sample
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: install SSH key
        uses: shimataro/ssh-key-action@v2 # こちらのアクションがキモ
        with:
          key: ${{ secrets.SSH_KEY }} # 必須
          public-key: ${{ secrets.SSH_KEY_PUBLIC }} # 必須
          name: id_rsa # optional
          known_hosts: ${{ secrets.KNOWN_HOSTS }} # 省略可だが、セキュリティ上設定したほうがよい
      - name: deploy
        run: bash deploy.sh

こちらをプロジェクトのルートディレクリ直下に/.github/workflowsを作成して配置します。

Project Root
└── .github/
 └── workflows
    └── deploy.yml

2. デプロイ用のシェルスクリプトを用意する

  • ご自身のプロジェクトに応じたデプロイ用のシェルスクリプトを用意します。今回私はDockerを利用していたので以下のようにしています。こちらもinstall SSH keyの作者様の記事を参考にしました。
deploy.sh
#!/bin/bash
# srcファイルをrsync over SSHで転送
rsync -acvz --delete ./src test@your.ip.addres:project/
# サービスを再起動
ssh test@your.ip.address "cd project/; docker-compose build; docker-compose down; docker-compose -f docker-compose.yml -f docker-compose-prod.yml up -d"

3. ローカルでGitHub ActionsがさくらVPSにアクセスするための秘密鍵・公開鍵のセットを作成する

# 認証鍵を生成する
ssh-keygen -t rsa -b 4096 -C "your@email"

# 作成した認証鍵を確認する
ls -la ~/.ssh/

# PEM形式に変換。OpenSSHのバージョンによってはPEM形式じゃないと駄目な場合があるらしい・・・
ssh-keygen -p -m PEM -f ~/.ssh/id_rsa

# known_hostsを確認する。次でGitHubに登録します。
ssh-keyscan <server-hostname>

4. GitHubのSecretsに作成した秘密鍵と公開鍵、known_hostsを登録する

  • GitHub Actionsを利用したいリポジトリの「settings」を押下
    image.png

  • Secretsを押下
    image.png

  • New Secretを押下
    image.png

  • 作成しておいた認証鍵をそれぞれNameとValueを以下のように登録

    • 秘密鍵
      • Name:SSH_KEY
      • Value:~/.ssh/id_rsaの中身をコピペ
    • 公開鍵
      • Name:SSH_KEY_PUBLIC
      • Value:~/.ssh/id_rsa.pubの中身をコピペ
    • known_hosts
      • Name:KNOWN_HOSTS
      • Value:ssh-keyscanで出力された値をコピペ image.png

5. さくらVPSのOpenSSHのバージョンをアップデートする

6. さくらVPSのSSH設定を確認する

  • SSHの設定ファイル(/etc/ssh/sshd_config)で以下の設定になっているかを確認します。
  • PubkeyAuthentication yes
    • 公開鍵認証がyesになっているかどうか
  • PasswordAuthentication no
    • パスワード認証がnoになっているかどうか
  • 設定を変更した場合はsudo systemctl sshd restartで反映します。

7. ローカルで作成した(GitHubに登録した)公開鍵をさくらVPSに登録する

  • ローカルで下記を実施して、サーバーに公開鍵を登録します。
ssh-copy-id ${USER}@${target_host}

8. masterブランチにプルリク出してマージする

  • これでGitHub Actions内からSSHする準備ができたので、実際に動かしてみます。
  • masterブランチに適当にプルリクしてマージしてみてください。
  • Actionsで確認してエラーになっていなければOKです。念の為、サーバーに反映されたか確認して完了です。

参考

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

MacでホストからDockerコンテナにlocalhostでアクセスできなかった話

事象

Macでdockerの公式ドキュメントに従ってもnginxのコンテナにlocalhostでアクセスできない :sob:

公式ドキュメント
Networking features in Docker Desktop for Mac

環境

  • macOS Catalina 10.15.6
  • docker desktop community
    • Version 2.3.0.3(45519)
    • Channel stable
    • Engine 19.03.8
  • eset CYBER SECURITY PRO
    • Version 6.8.300.0

原因・解決方法 :relaxed:

こちらの回答の通り、セキュリティソフトのファイアウォールが原因でした
teratail: docker desktop for macでホストからコンテナに接続できない

所感 :rolling_eyes:

この答えに行き着くまでに様々なことを疑いました

  • コンテナに対するポートフォーワーディング
  • コンテナのポート公開設定
  • コンテナのOS上のファイアウォール設定
  • コンテナに割り当てられたIPアドレスでのアクセス

などなど。
しかし、どれもこれも解決に至らず。。。

セキュリティソフトが原因なのは盲点でした。
これまでの経験でも同じようなことはあったのですが、最近はなかったことだったので。

セキュリティソフト以外に原因が考えられる場合は下記サイトが参考になると思います。
Dockerコンテナで起動したサーバにアクセスできないときの確認と対処方法

#なんか今回は他所のサイト紹介みたいになっている。。。

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

docker-compose: マルチステージビルドの中間イメージにタグ付けするベストプラクティス

はじめに

自分のメモ用に殴り書き。この記事では、docker-compose を使って、マルチステージビルドで中間生成される Docker イメージにタグ付けするためのベストプラクティスを紹介します。

TL;DR

  • Dockerfile の各ステージには名前を付けましょう。
  • 各ステージの中間イメージビルド用の docker-compose.build.yml を作りましょう。
  • 以上
  • なお、docker-compose は、バージョン 3.4 以上である必要があります。
    • V3.4 でサポートされた buildtarget という機能を利用します。

Dockerfile マルチステージビルドのムカつくところ

  • Dockerfile のマルチステージビルドは中間イメージにタグを付けてくれません。
  • 結果として、<none>:<none> という無名の Docker イメージが残存し続けます。
  • たまに掃除して上げないと、docker images に大量の無名イメージがリストされます。
  • 不要なイメージでサーバーストレージも無駄に消費します。
# image:latest は Dockerfile で生成された最終成果物となる Docker イメージ
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
image                   latest              439521aeed0d        1 hours ago         1.48GB
<none>                  <none>              f683a5456003        1 hours ago         1.33GB
<none>                  <none>              a92a033bf4e7        1 hours ago         1.03GB
<none>                  <none>              7fa2a4097f16        2 hours ago         1.33GB
<none>                  <none>              20acbe3cae6c        2 hours ago         1.03GB
<none>                  <none>              dee5b549543c        3 hours ago         1.33GB
<none>                  <none>              8679ced16d20        3 hours ago         1.03GB
<none>                  <none>              f683a5456003        4 hours ago         1.33GB
<none>                  <none>              a92a033bf4e7        4 hours ago         1.03GB
<none>                  <none>              7fa2a4097f16        5 hours ago         1.33GB
<none>                  <none>              20acbe3cae6c        5 hours ago         1.03GB
<none>                  <none>              dee5b549543c        6 hours ago         1.33GB
<none>                  <none>              8679ced16d20        6 hours ago         1.03GB
...延々と続く

マルチステージビルドって何?

  • 公式ドキュメント(英語)
  • Docker イメージのビルド工程を複数ステージに分割して最終イメージを生成する、Dockerfile の機能です。
  • 複雑になりがちだった Docker イメージ生成プロセスを効率よくするために導入された機能です。
  • 例えば、Webアプリケーションサーバーの Docker イメージの場合、フロントエンドのパッケージ生成は、node:latest イメージを使い、バックエンドのパッケージ生成は、python:latest イメージを用いて、最終的にフロントエンドとバックエンドの生成物を alpine:latest イメージにデプロイするといった感じになるでしょう。(図とか欲しいけど、そんな時間ない、殴り書き)

擬似サンプル: シンプルなマルチステージビルド

  • この記事では次のような Dockerfiledocker-compose.yml を利用して、手順を説明します。
Dockerfile
# 第1ステージビルド: node:latest を用いて、フロントエンドパッケージをビルドする
FROM node:latest
RUN build_frontend_package
# 第2ステージビルド: python:latest を用いて、バックエンドパッケージをビルドする
FROM python:latest
RUN build_backend_package
# 最終ステージビルド: alpine:latest をベースイメージとし、フロントエンドとバックエンドのパッケージを組み込んだ Web アプリケーションサーバを構築する
FROM alpine:latest
COPY --from 0 frontend_package
COPY --from 1 backend_package
RUN build_production frontend_package backend_package
docker-compose.yml
version: "3.4"
services:
    web:
        build: .
        image: image:latest

ポイント1: 各ステージには名前をつけましょう

  • FROM イメージ名 AS ステージ名 を使って、それぞれのステージに名前をつけてください。
  • そうすると、Dockerfile 内や、docker-compose から、その名前でステージを参照できます。
  • docker-compose でステージ名を指定してビルドするために、ステージに名前を付けるんです。
Dockerfile
# 第1ステージビルド: node:latest を用いて、フロントエンドパッケージをビルドする
FROM node:latest AS frontend_stage
RUN build_frontend_package
# 第2ステージビルド: python:latest を用いて、バックエンドパッケージをビルドする
FROM python:latest AS backend_stage
RUN build_backend_package
# 最終ステージビルド: alpine:latest をベースイメージとし、フロントエンドとバックエンドのパッケージを組み込んだ Web アプリケーションサーバを構築する
FROM alpine:latest AS final_stage
COPY --from frontend_stage frontend_package
COPY --from backend_stage backend_package
RUN build_production frontend_package backend_package

ポイント2: docker-compose.build.yml というファイルでビルドしましょう

  • 執筆段階では、docker-compose を使うなら、docker-compose.yml のみで実現するのは無理だと思います。
  • docker-compose.build.yml では、buildcontexttarget という設定を入れます。
  • context には、カレントディレクトリとか Docker のビルドコンテキストのパスを入れておきます。
  • target には、(先ほど名前をつけた) マルチステージビルドのステージ名を入れて上げます。
  • ファイル名は任意です。docker-compose.build.yml である必要はありません。
docker-compose.build.yml
version: "3.4"
services:
    frontend:
        build:
            context: .
            target: frontend_stage
        image: frontend:latest
    backend:
        build:
            context: .
            target: backend_stage
        image: backend:latest
    final:
        build:
            context: .
            target: final_stage
        image: image:latest
  • docker-compose.yml からは、build 設定を抜いておきましょう。(残しておいてもOK。使わないだけ。)
docker-compose.yml
version: "3.4"
services:
    web:
        image: image:latest

ビルドしてサービスを起動する方法

  • docker-compose build に、-f オプションで docker-compose.build.yml を指定してビルドします。
$ docker-compose -f docker-compose.build.yml build
  • ビルドが完了したら、docker-compose.yml を用いて、サービスを起動して上げます。
    • 注意: docker-compose.build.yml ではありません
$ docker-compose up -d
  • Docker イメージの一覧を表示すると、中間イメージがタグ付けされています。
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
image                   latest              439521aeed0d        1 hours ago         1.48GB
frontend                latest              f683a5456003        1 hours ago         1.33GB
backend                 latest              a92a033bf4e7        1 hours ago         1.03GB

まとめ

  • Dockerfile の各ステージには名前を付けましょう。
  • 各ステージの中間イメージビルド用の docker-compose.build.yml を作りましょう。
  • 細かな修正とかして、何度も docker-compose ビルドし直したりしても、タグ付けされます。(当たり前)
  • 知らず知らずのうちに、手元ビルドで大量に残存していた無名イメージがなくなります。
  • マルチステージビルドの中間イメージにタグ付けする方法は他にもありますが、私の試行錯誤したかぎりでは、これがベストプラクティスだと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker Compose Limitsを実行する際の生産性のヒントとベストプラクティス - Docker Composeのための実践的なエクササイズ その4

このチュートリアルでは、Alibaba Cloud上でコンテナを扱う際にDocker Composeを使用して実践的な経験を積むことに焦点を当てています。

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

生産性のヒント

私はよく使うDockerコマンド用にいくつかのbash aliasesを定義しています。ここではそのうちの2つを紹介します。

    alias nnc='nano docker-compose.yml'
    alias psa='docker ps -a'

シェルで psa を入力すると、チュートリアルで docker ps -a をハイライトしてからコピーし、alt-tab でコンソールウィンドウに移動してからペーストするよりも速いです。

docker-compose.yml の編集が速くなりました。

1、Chromeを使用している場合は、オートコピー拡張機能をインストールしてください。ブラウザでハイライトしたテキストを自動的にコピーしてくれます。
2、チュートリアルでdocker-compose.ymlのテキストをハイライト表示します。
3、AltタブでLinuxコンソールへ
4、type nnc ( editorで docker-compose.yml ファイルを開きます )
5、右クリックして貼り付けます(これは使用しているコンソールソフトウェア固有のものです)。
6、保存
拡張子とエイリアスを使用しない場合、このプロセスには上記の6つのステップの代わりに12のステップが必要になります。

シェルで psa を入力するのは、チュートリアルで docker ps -a をハイライトしてからコピーし、alt-tab でコンソールウィンドウに移動してからペーストするよりも速いです。

docker-compose.yml の編集が速くなりました。

1、Chromeを使っている場合は、オートコピー拡張機能をインストールしてください。ブラウザでハイライトしたテキストを自動的にコピーします。
2、チュートリアルでdocker-compose.ymlのテキストをハイライト表示します。
3、AltタブでLinuxコンソールへ
4、type nnc ( エディタが docker-compose.yml ファイルを開く )
5、右クリックして貼り付けます(これは使用しているコンソールソフトウェアに固有のものです)。
6、保存
拡張子とエイリアスを使用しない場合、このプロセスには上記の6つのステップの代わりに12のステップが必要になります。

Deploy: placement constraints

docker-composeの配置制約は、制約を定義することで、タスクをスケジューリング/実行できるノード/サーバを制限するために使用されます。

まず、ノード/サーバのラベルを定義する必要があります。次に、これらのラベルに基づいて配置制約を定義します。

ノードにラベルを追加する構文

docker node update --label-add label-name=label-value hostnam-of-node

このためにはサーバのホスト名が必要です。シェルでホスト名を入力して、あなたのホスト名を取得します。

以下、自分のホスト名を使ってください。( localhost.localdomain = 私のホスト名)

docker node update --label-add tuts-allowed=yes localhost.localdomain

docker node update --label-add has-ssd=yes localhost.localdomain

ノードを検査してラベルが存在することを確認することができます。

head -n 13 は先頭のみを表示します。 / head 13行の長いinspectの出力。

docker node inspect self | head -n 13

期待される出力 .

[
    {
        "ID": "wpk3r9ypjd8f0p3koh1dikvie",
        "Version": {
            "Index": 443
        },
        "CreatedAt": "2018-11-06T09:29:29.644400514Z",
        "UpdatedAt": "2018-11-07T09:55:18.065758325Z",
        "Spec": {
            "Labels": {
                "has-ssd": "yes",
                "tuts-allowed": "yes"
            },

ここで、docker-compose.yml の一番下に配置規則を追加します。

docker-compose.yml に次のように追加します。

nano docker-compose.yml
version: "3.7"
services:
  alpine:
    image: alpine:3.8
    command: sleep 600

    deploy:
      placement:
        constraints:
          - node.labels.has-ssd == yes
          - node.labels.tuts-allowed == yes

stack deployコマンドは、両方の制約に一致するノードにのみサービススタックを配置します。

両方の制約が私たちのノードと一致しているので、デプロイは成功します。

docker stack deploy -c docker-compose.yml  mystack

実行中のコンテナをリストアップしてみましょう。

docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
42f8a9b43faf        alpine:3.8          "sleep 600"         12 seconds ago      Up 11 seconds                           mystack_alpine.1.ezwejfbrmhbk0k5yd9a53ei85

成功しました。mystackにある全てのサービスをリストアップしてみましょう。

docker stack services mystack

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
ji5dnn9klinx        mystack_alpine      replicated          1/1                 alpine:3.8  

成功しました。REPLICAS欄を参照してください。リクエストされた1つのサービスのうち、1つのサービスが実行されています。

それでは、デプロイができないように制約テストを変更してみましょう。

docker-compose.ymlに以下を追加します。

nano docker-compose.yml
version: "3.7"
services:
  alpine:
    image: alpine:3.8
    command: sleep 600

    deploy:
      placement:
        constraints:
          - node.labels.has-ssd == yeszzz
          - node.labels.tuts-allowed == yeszzz

以前に展開したスタックを削除します。

docker stack rm mystack
docker stack deploy -c docker-compose.yml  mystack

mystackのサービスを一覧にしてみましょう。

docker stack services mystack
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
jdg2bgxx5nfa        mystack_alpine      replicated          0/1                 alpine:3.8   

デプロイは適切なノードを見つけることに成功しませんでした。REPLICAS カラムを参照してください。要求された 1 つのサービスのうち 0 つのサービスが実行されています。

ノードラベルの使用方法の例。

1、ssds を必要とする特定のアプリがそのようなノードでのみ実行できるように ssds でノードをラベル付けします。
2、アプリケーションがそのようなノードを見つけることができるように、グラフィックカードでノードをラベル付けします。
3、必要に応じて国名、州名、都市名をノードにラベル付けします。
4、バッチとリアルタイムのアプリケーションを分離します。
5、開発ジョブは開発用マシンでのみ実行してください。
6、開発中のアプリケーションを物理的なコンピュータ上でのみ実行してください - CPUやRAMを浪費するコードが同僚に悪影響を与えないようにしてください。
Placementeについての詳しい情報はこちらをご覧ください: https://docs.docker.com/compose/compose-file/#placement

制約についてはこちらをご覧ください: https://docs.docker.com/engine/reference/commandline/service_create/#specify-service-constraints-constraint

Deploy: replicas

任意の時間に実行するコンテナの数を指定します。

これまではデフォルトのreplicasを1つだけ使用していました。

ここでは3つのreplicasを実行するデモをしてみましょう。

docker-compose.ymlに以下のように追加します。

nano docker-compose.yml
version: "3.7"
services:
  alpine:
    image: alpine:3.8
    command: sleep 600

    deploy:
      replicas: 3

以前に実行していたmystackの削除

docker stack rm mystack

期待される出力 .

Removing service mystack_alpine
Removing network mystack_default

新しいスタックを展開します。

docker stack deploy -c docker-compose.yml  mystack

期待される出力 .

Creating network mystack_default
Creating service mystack_alpine

出力は期待できそうにありません - 3つのreplicasについては言及されていません。mystackのサービスをリストアップしてみましょう

docker stack services mystack

期待される出力 .

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
pv2ebn95au9j        mystack_alpine      replicated          3/3                 alpine:3.8   

要求された3つのレプリカが不足しています。成功しました。

実行中のコンテナをリストアップしてみましょう。

docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
80de65e6e0d3        alpine:3.8          "sleep 600"         9 seconds ago       Up 6 seconds                            mystack_alpine.2.51hlsv3s7ky5zr02fprjaxi59
440548cfcc7d        alpine:3.8          "sleep 600"         9 seconds ago       Up 6 seconds                            mystack_alpine.1.za68nt6704xobu2cxbz7x7p3l
19564317375f        alpine:3.8          "sleep 600"         9 seconds ago       Up 7 seconds                            mystack_alpine.3.1ut387z38e2hrlmahalp7hfsa

予想通りです。3つのコンテナが稼働しています。

サーバの作業負荷を調査してみました。

top - 09:45:33 up  2:02,  2 users,  load average: 0.00, 0.01, 0.05
Tasks: 133 total,   1 running, 132 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.2 sy,  0.0 ni, 99.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  985.219 total,  472.004 free,  171.848 used,  341.367 buff/cache
MiB Swap: 1499.996 total, 1499.996 free,    0.000 used.  639.379 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
  939 root      20   0  950.7m 105.9m  29.2m S   0.7 10.8   1:19.36 dockerd
  946 root      20   0  424.8m  29.1m  12.1m S        2.9   0:14.14 docker-containe
 5082 root      20   0    7.2m   2.7m   2.0m S        0.3           docker-containe
 4950 root      20   0    7.2m   2.6m   2.0m S        0.3           docker-containe
 5075 root      20   0    7.2m   2.4m   1.9m S        0.2           docker-containe

3つの小さなコンテナはそれぞれ約2.5MBのRAMを使用しています。

これで、隔離された環境で動作する3つのフルAlpine Linuxディストロが、それぞれ2.5MBのRAMサイズで動作するようになりました。これは素晴らしいことです。

これを3つの独立した仮想マシンと比較してみてください。それぞれの仮想マシンは、存在するだけで50MBのオーバーヘッドを必要とします。さらに、それぞれに数百 MB のディスクスペースが必要になります。

各コンテナは約300msで起動しますが、これはVMでは不可能です。

Deploy: resources: reservations cpu ( オーバープロビジョニング )

reservations: cpu config settingsを使ってCPU容量を確保しています。

cpuをオーバープロビジョニングして、Dockerが指示に従うかどうかを確認してみましょう。

docker-compose.ymlに以下を追加します。

nano docker-compose.yml
version: "3.7"
services:
  alpine:
    image: alpine:3.8
    command: sleep 600

    deploy:
      replicas: 6

      resources:
        reservations:
          cpus: '0.5'

私のサーバには 2 つのコアがあるので、2 つの CPU が利用可能です。

この設定では、6 * .5 = 3CPUをプロビジョニングしようとしています。

この設定を編集して、あなたの小さなノートパソコンや、あなたの雇い主であるスーパーサーバーで失敗するようにしなければなりません。

既存のスタックを削除してみましょう。

docker stack rm mystack

展開してみましょう。

docker stack deploy -c docker-compose.yml  mystack

期待されない出力 .

Creating service mystack_alpine
failed to create service mystack_alpine: Error response from daemon: network mystack_default not found

時々上記のようなことが起こりますが、エラーが出なくなるまでデプロイを再実行してください。

デプロイの結果を調査してください。

docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a8861c79e3e8        alpine:3.8          "sleep 600"         40 seconds ago      Up 37 seconds                           mystack_alpine.6.pgtvnbpxpy4ony26pmp8ekdv1
3d2a0b8e52e9        alpine:3.8          "sleep 600"         40 seconds ago      Up 37 seconds                           mystack_alpine.5.j52dwbe7qqx0nn5nhanp742n4
5c2674b7fa36        alpine:3.8          "sleep 600"         40 seconds ago      Up 37 seconds                           mystack_alpine.1.bb1ocs3zkz730rp9bpf6s9jux
f984a8d52393        alpine:3.8          "sleep 600"         40 seconds ago      Up 38 seconds                           mystack_alpine.4.mr5ktkei9pn1dzhkggq2e48o9

4つのコンテナがリストアップされています。4 * .5 = 2CPUを使用していることになります。

mystackにある全てのサービスをリストアップする。

docker stack services mystack
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
7030g8ila28h        mystack_alpine      replicated          4/6                 alpine:3.8   

6つのコンテナのうち4つだけがプロビジョニングされました。Dockerはプロビジョニングするcpusを使い果たしました。

重要: これは存在するものだけをreservationすることができます。

Deploy: resources: reservations: RAM( オーバープロビジョニング )

RAMをオーバープロビジョニングしてみましょう。(この機能はこのチュートリアルの後半で正しく使用します。)

docker-compose.yml に以下を追加します。

nano docker-compose.yml
version: "3.7"
services:
  alpine:
    image: alpine:3.8
    command: sleep 600

    deploy:
      replicas: 6

      resources:
          memory: 2000M

私のサーバーには1GBのラムがあります。

この設定では、私は6 * 2 = 12 MBをプロビジョニングしようとしています。

前と同じように: この設定を編集して、あなたの小さなノートパソコンやモンスターの雇用主のスーパーサーバーで失敗するようにする必要があります。

既存のスタックを削除してみましょう。

docker stack rm mystack

展開してみましょう。

docker stack deploy -c docker-compose.yml  mystack

実行中のstack servicesを一覧表示します。

docker stack services mystack

期待される出力 .

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
l7yr2m5k6edf        mystack_alpine      replicated          0/6                 alpine:3.8   

デプロイされたサービスはゼロ。Dockerは、指定された予約RAMの50%を使用して1つのコンテナをデプロイすることさえしません。これは正しく想定しています - RAMの予約を指定した場合、コンテナが正常に動作するためにはその最小値を必要とします。したがって、予約が不可能な場合、コンテナは起動しません。

ここまでで、リソースの制限が守られることを見てきました。

どのように動作するかを確認するために、妥当な制限を定義してみましょう。

Deploy: resources: limits: cpu

以下のアルパインサービスは、20M以下のメモリと0.50(50%)以下の利用可能な処理時間(CPU)に制約されています。

docker-compose.ymlに以下を追加します。

nano docker-compose.yml  
version: "3.7"
services:
  alpine:
    image: alpine:3.8
    command: sleep 600

    deploy:
      replicas: 1

      resources:
        limits:
          cpus: '0.5'
          memory: 20M

ここから先はreplicasが1つしか必要ないことに注意してください。

docker stack rm mystack

スタックを展開します。

docker stack deploy -c docker-compose.yml  mystack
docker ps -a

期待される出力 .

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
11b8e8c2838b        alpine:3.8          "sleep 600"         3 seconds ago       Up 1 second                                      mystack_alpine.1.qsamffjd1vg0137off9xinyzg

コンテナが動いています。これを入力して、CPU速度をベンチマークしてみましょう。

docker exec -it mystack_alpine.1.qsamffjd1vg0137off9xinyzg /bin/sh

コンテナ / # プロンプトに表示されているコマンドを入力します。

/ #  time dd if=/dev/urandom bs=1M count=2 | md5sum
2+0 records in
2+0 records out
real    0m 0.57s
user    0m 0.00s
sys     0m 0.28s
064be3476682daf856bb32fa00d29e2e  -
/ # exit

ベンチマークの説明:

1、time: 経過時間を測定します。
2、dd if=/dev/urandom bs=1M count=2: 1 MB のランダム性を bs (ブロックサイズ) を 2 回コピーする。
3、md5sum: md5ハッシュを計算する (CPUに負荷を与える)
CPU 制限値 0.5 のベンチタイムがありますが、これを比較できなければ何の意味もありません。

そこで、docker-compose.yml で cpu limit を 0.25 に変更してみましょう。

cpus: '0.25'

その後、シェルで実行します。

docker stack rm mystack
docker stack deploy -c docker-compose.yml  mystack
docker ps -a # to get our container name 
docker exec -it mystack_alpine.1.cbaakbi027ue0c1rtj0z463qz /bin/sh

ベンマークを再実行します。

/ # time dd if=/dev/urandom bs=1M count=2 | md5sum
2+0 records in
2+0 records out
real    0m 1.27s
user    0m 0.00s6d9b25e860ebef038daa165ae491c965  -
sys     0m 0.30s
/ # time dd if=/dev/urandom bs=1M count=2 | md5sum
2+0 records in
2+0 records out
real    0m 1.33s
ed29ebf0ef70923f9b980c65495767eb  -
user    0m 0.00s
sys     0m 0.33s
/ # exit

結果は理にかなっています。 - 約50%の速度低下 - 利用可能なCPUパワーが50%減少しています。

そこで、docker-compose.ymlでCPU制限を1.00に変更してみましょう。

     cpus: '1.00'

シェルで実行します。

docker stack rm mystack

docker stack deploy -c docker-compose.yml  mystack

docker ps -a

docker exec -it your-container-name /bin/sh

表示されているコマンドを入力します。

/ # time dd if=/dev/urandom bs=1M count=2 | md5sum
2+0 records in
2+0 records out
real    0m 0.25s
user    0m 0.00s
sys     0m 0.24s
facbf070f7328db3321ddffca3c4239e  -
/ # time dd if=/dev/urandom bs=1M count=2 | md5sum
2+0 records in
2+0 records out
616ba74d54b8a176f559f41b224bc3a3  -real 0m 0.29s
user    0m 0.00s
sys     0m 0.28s
/ # exit

非常に高速なランタイム:100%のCPU制限は25%のCPUパワーよりも4倍速い

これで、コンテナごとのCPUパワーを制限することが期待通りに動作することを体験していただけたと思います。

本番用のサーバーが 1 台しかない場合、この知識を使って、CPU を消費するバッチプロセスを他の作業と同じサーバーで実行することができます - バッチプロセスの CPU を厳しく制限するだけです。

Resources: limits: memory

この設定オプションは、コンテナの最大 RAM 使用量を制限します。

docker-compose.yml に次のように追加します。

nano docker-compose.yml 
Version: "3.7"
services:
  alpine:
    image: alpine:3.8
    command: sleep 600

    deploy:
      replicas: 1

      resources:
        limits:
          cpus: '1.00'
          memory: 4M

実行します。

docker stack rm mystack

docker stack deploy -c docker-compose.yml  mystack

docker ps -a

期待される出力 .

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
2e0105ce94fd        alpine:3.8          "sleep 600"         3 seconds ago       Up 1 second                             mystack_alpine.1.ykn9fdmeaudp4ezar7ev19111

これで、メモリ制限が4MBのコンテナが稼働していることになります。

典型的な好奇心旺盛なDocker管理者になって、8MBの/dev/shm RAMを使用した場合にどうなるか見てみましょう。

docker exec -it mystack_alpine.1.ykn9fdmeaudp4ezar7ev19111 /bin/sh

表示されているようにコマンドを入力します。

/ # df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/mapper/docker-253:1-388628-c88293aae6b79e197118527c00d64fee14aec2acfb49e5f1ec95bc6af6bd874b
                         10.0G     37.3M     10.0G   0% /
tmpfs                    64.0M         0     64.0M   0% /dev
tmpfs                   492.6M         0    492.6M   0% /sys/fs/cgroup
/dev/mapper/centos00-root
                         12.6G      5.5G      7.2G  43% /etc/resolv.conf
/dev/mapper/centos00-root
                         12.6G      5.5G      7.2G  43% /etc/hostname
/dev/mapper/centos00-root
                         12.6G      5.5G      7.2G  43% /etc/hosts
shm                      64.0M         0     64.0M   0% /dev/shm
tmpfs                   492.6M         0    492.6M   0% /proc/acpi
tmpfs                    64.0M         0     64.0M   0% /proc/kcore
tmpfs                    64.0M         0     64.0M   0% /proc/keys
tmpfs                    64.0M         0     64.0M   0% /proc/timer_list
tmpfs                    64.0M         0     64.0M   0% /proc/timer_stats
tmpfs                    64.0M         0     64.0M   0% /proc/sched_debug
tmpfs                   492.6M         0    492.6M   0% /proc/scsi
tmpfs                   492.6M         0    492.6M   0% /sys/firmware
/ # dd if=/dev/zero of=/dev/shm/fill bs=1M count=4
4+0 records in
4+0 records out
/ # df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/mapper/docker-253:1-388628-c88293aae6b79e197118527c00d64fee14aec2acfb49e5f1ec95bc6af6bd874b
                         10.0G     37.3M     10.0G   0% /
tmpfs                    64.0M         0     64.0M   0% /dev
tmpfs                   492.6M         0    492.6M   0% /sys/fs/cgroup
/dev/mapper/centos00-root
                         12.6G      5.5G      7.2G  43% /etc/resolv.conf
/dev/mapper/centos00-root
                         12.6G      5.5G      7.2G  43% /etc/hostname
/dev/mapper/centos00-root
                         12.6G      5.5G      7.2G  43% /etc/hosts
shm                      64.0M      4.0M     60.0M   6% /dev/shm
tmpfs                   492.6M         0    492.6M   0% /proc/acpi
tmpfs                    64.0M         0     64.0M   0% /proc/kcore
tmpfs                    64.0M         0     64.0M   0% /proc/keys
tmpfs                    64.0M         0     64.0M   0% /proc/timer_list
tmpfs                    64.0M         0     64.0M   0% /proc/timer_stats
tmpfs                    64.0M         0     64.0M   0% /proc/sched_debug
tmpfs                   492.6M         0    492.6M   0% /proc/scsi
tmpfs                   492.6M         0    492.6M   0% /sys/firmware


/ # dd if=/dev/zero of=/dev/shm/fill bs=1M count=8
Killed


/ # df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/mapper/docker-253:1-388628-c88293aae6b79e197118527c00d64fee14aec2acfb49e5f1ec95bc6af6bd874b
                         10.0G     37.3M     10.0G   0% /
tmpfs                    64.0M         0     64.0M   0% /dev
tmpfs                   492.6M         0    492.6M   0% /sys/fs/cgroup
/dev/mapper/centos00-root
                         12.6G      5.5G      7.2G  43% /etc/resolv.conf
/dev/mapper/centos00-root
                         12.6G      5.5G      7.2G  43% /etc/hostname
/dev/mapper/centos00-root
                         12.6G      5.5G      7.2G  43% /etc/hosts
shm                      64.0M      5.4M     58.6M   9% /dev/shm
tmpfs                   492.6M         0    492.6M   0% /proc/acpi
tmpfs                    64.0M         0     64.0M   0% /proc/kcore
tmpfs                    64.0M         0     64.0M   0% /proc/keys
tmpfs                    64.0M         0     64.0M   0% /proc/timer_list
tmpfs                    64.0M         0     64.0M   0% /proc/timer_stats
tmpfs                    64.0M         0     64.0M   0% /proc/sched_debug
tmpfs                   492.6M         0    492.6M   0% /proc/scsi
tmpfs                   492.6M         0    492.6M   0% /sys/firmware
/ # exit

上で起こったことの説明。

最初に df -h を実行して /dev/shm のサイズと使用量を調べます。

shm                      64.0M         0     64.0M   0% /dev/shm

そして、/dev/shmに4MBを追加します。

dd if=/dev/zero of=/dev/shm/fill bs=1M count=4

使用方法を再確認してください - 4Mを参照してください。

shm                      64.0M      4.0M     60.0M   6% /dev/shm

そして、/dev/shm に 8MB を追加して、以前の内容を上書きします。

dd if=/dev/zero of=/dev/shm/fill bs=1M count=8
Killed

で、このコマンドは強制終了されます。

dev/shm の使用状況を再度確認してください。

shm                      64.0M      5.4M     58.6M   9% /dev/shm

コンテナがRAMを使い果たす前に4MBを少し使いました。

結論:Dockerのdocker-composeのメモリ制限が適用されます。

デフォルトではコンテナはRAMの使用量が制限されていません。そのため、このリソース制限を利用して、暴走したコンテナによってRAMが完全に消費されるのを防ぎましょう。

20MB、50MB、100MBのいずれも240GBを消費させるよりは良いでしょう。

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

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

Dockerの環境をリセットしたい コンテナ・イメージ ・ボリュームを全削除

コンテナを全削除

docker ps -aq | xargs docker rm

イメージ全削除

docker images -aq | xargs docker rmi

ボリューム全削除

docker volume rm $(docker volume ls -qf dangling=true)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UbuntuのOfficial Docker image内でlsb_release -cs相当のことを実現する

Ubuntuのdocker iamgeにはlsb_releaseが入っていないため、Dockerfile中にlsb_release相当のことをするにはちょっと工夫が必要になります。lsb_coreをインストールすれば使えるようにはなりますが、わざわざインストールするのもためらうときに使えるtipsです。

例えば、lsb_release -csはOSのコードネームを取得するコマンドですが、これと同様のことをしたければ、下記の様に書くことができます。。要はlsb_releaseが参照している情報は/etc/lsb-releaseに格納されているので、そこから必要な文字列を取り出せばいいわけです。

RUN export ubuntu_codename=$(cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d = -f 2)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む