- 投稿日:2020-07-27T23:39:40+09:00
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
- 投稿日:2020-07-27T23:39:40+09:00
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でローカルに作られたディレクトリの中に[プロジェクトを入れるディレクトリ名]のディレクトリができてしまったので削除しておく)
- 投稿日:2020-07-27T23:17:39+09:00
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
- 投稿日:2020-07-27T21:44:53+09:00
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の設定は他の記事でもサンプルが多くあるのでそちらを参照ください。
手順
/.github/workflows
配下にdeploy.ymlを用意する(名前はなんでもOK)- デプロイ用のシェルスクリプトを用意する
- ローカルでGitHub ActionsがさくらVPSにアクセスするための秘密鍵・公開鍵のセットを作成する
- GitHubのSecretsに作成した秘密鍵と公開鍵、known_hostsを登録する
- さくらVPSのOpenSSHのバージョンをアップデートする
- さくらVPSのSSH設定を確認する
- ローカルで作成した(GitHubに登録した)公開鍵をさくらVPSに登録する
- masterブランチにプルリク出してマージする
1.
/.github/workflows
配下にdeploy.ymlを用意する(名前はなんでもOK)
- GitHub Actions用の設定ファイルを用意します。
- GitHub ActionsでSSHするためにInstall SSH Keyを利用しました。 日本の方が作成されたアクションで、こちらの本人が執筆された記事を参考にしました。ありがとうございます。
deploy.ymlname: 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.yml2. デプロイ用のシェルスクリプトを用意する
- ご自身のプロジェクトに応じたデプロイ用のシェルスクリプトを用意します。今回私は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を登録する
作成しておいた認証鍵をそれぞれNameとValueを以下のように登録
5. さくらVPSのOpenSSHのバージョンをアップデートする
- こちらの記事を参考に進めました。(けっこう長いので以下のブログを参照してみてください)
- CentOS7の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です。念の為、サーバーに反映されたか確認して完了です。
参考
- 投稿日:2020-07-27T21:16:21+09:00
MacでホストからDockerコンテナにlocalhostでアクセスできなかった話
事象
Macでdockerの公式ドキュメントに従ってもnginxのコンテナにlocalhostでアクセスできない
公式ドキュメント
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
原因・解決方法
こちらの回答の通り、セキュリティソフトのファイアウォールが原因でした
teratail: docker desktop for macでホストからコンテナに接続できない所感
この答えに行き着くまでに様々なことを疑いました
- コンテナに対するポートフォーワーディング
- コンテナのポート公開設定
- コンテナのOS上のファイアウォール設定
- コンテナに割り当てられたIPアドレスでのアクセス
などなど。
しかし、どれもこれも解決に至らず。。。セキュリティソフトが原因なのは盲点でした。
これまでの経験でも同じようなことはあったのですが、最近はなかったことだったので。セキュリティソフト以外に原因が考えられる場合は下記サイトが参考になると思います。
Dockerコンテナで起動したサーバにアクセスできないときの確認と対処方法
#なんか今回は他所のサイト紹介みたいになっている。。。
- 投稿日:2020-07-27T19:35:33+09:00
docker-compose: マルチステージビルドの中間イメージにタグ付けするベストプラクティス
はじめに
自分のメモ用に殴り書き。この記事では、docker-compose を使って、マルチステージビルドで中間生成される Docker イメージにタグ付けするためのベストプラクティスを紹介します。
TL;DR
- Dockerfile の各ステージには名前を付けましょう。
- 各ステージの中間イメージビルド用の
docker-compose.build.yml
を作りましょう。- 以上
- なお、docker-compose は、バージョン 3.4 以上である必要があります。
- V3.4 でサポートされた
build
のtarget
という機能を利用します。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
イメージにデプロイするといった感じになるでしょう。(図とか欲しいけど、そんな時間ない、殴り書き)擬似サンプル: シンプルなマルチステージビルド
- この記事では次のような
Dockerfile
とdocker-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_packagedocker-compose.ymlversion: "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
では、build
でcontext
とtarget
という設定を入れます。context
には、カレントディレクトリとか Docker のビルドコンテキストのパスを入れておきます。target
には、(先ほど名前をつけた) マルチステージビルドのステージ名を入れて上げます。- ファイル名は任意です。
docker-compose.build.yml
である必要はありません。docker-compose.build.ymlversion: "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.ymlversion: "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 ビルドし直したりしても、タグ付けされます。(当たり前)
- 知らず知らずのうちに、手元ビルドで大量に残存していた無名イメージがなくなります。
- マルチステージビルドの中間イメージにタグ付けする方法は他にもありますが、私の試行錯誤したかぎりでは、これがベストプラクティスだと思います。
- 投稿日:2020-07-27T19:31:54+09:00
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.ymlversion: "3.7" services: alpine: image: alpine:3.8 command: sleep 600 deploy: placement: constraints: - node.labels.has-ssd == yes - node.labels.tuts-allowed == yesstack deployコマンドは、両方の制約に一致するノードにのみサービススタックを配置します。
両方の制約が私たちのノードと一致しているので、デプロイは成功します。
docker stack deploy -c docker-compose.yml mystack実行中のコンテナをリストアップしてみましょう。
docker ps -aCONTAINER 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.ymlversion: "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 mystackmystackのサービスを一覧にしてみましょう。
docker stack services mystackID 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.ymlversion: "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 -aCONTAINER 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-containe3つの小さなコンテナはそれぞれ約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.ymlversion: "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 -aCONTAINER 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.mr5ktkei9pn1dzhkggq2e48o94つのコンテナがリストアップされています。4 * .5 = 2CPUを使用していることになります。
mystackにある全てのサービスをリストアップする。
docker stack services mystackID NAME MODE REPLICAS IMAGE PORTS 7030g8ila28h mystack_alpine replicated 4/6 alpine:3.86つのコンテナのうち4つだけがプロビジョニングされました。Dockerはプロビジョニングするcpusを使い果たしました。
重要: これは存在するものだけをreservationすることができます。
Deploy: resources: reservations: RAM( オーバープロビジョニング )
RAMをオーバープロビジョニングしてみましょう。(この機能はこのチュートリアルの後半で正しく使用します。)
docker-compose.yml に以下を追加します。
nano docker-compose.ymlversion: "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.ymlversion: "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.ymlVersion: "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ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ
- 投稿日:2020-07-27T14:27:27+09:00
Dockerの環境をリセットしたい コンテナ・イメージ ・ボリュームを全削除
- 投稿日:2020-07-27T06:12:25+09:00
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)