- 投稿日:2021-01-22T22:17:31+09:00
【2】Docker-compose + Django の環境で管理画面からアプリのでデータベース管理をする
概要
- Docker-composoe + Django環境で作業環境を整えます。
- Djangoは専用の管理画面からデータベースの操作(作成や編集など)が行えます。
- つまりPHPMyAdminなどが不要!!
環境
- Docker + Docker-compose が利用できること。
- Python3.6
- Django3.1(最新)
前提
- Docker-compose + Django + MySQL + Nginx + uwsgi を使った環境の初期設定 が完了していること
- djangoが起動中である
- データベースへアクセスできる
- 管理画面へアクセスできる
- または、同等の環境であること
手順
アプリケーションの作成
- アプリケーションの作成
$ docker-compose exec django manage.py sampleコンフィグの修正
src/app/settings.py
を編集する
- INSTALLED_APPS に作成したアプリケーションを追加する
- sample: フォルダ名
- SampleConfig:
src/app/sample/apps.py
に書いてあるclass
名src/app/settings.pyINSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'sample.apps.SampleConfig', # 追加 ]モデルの作成
src/app/sample/models.py
を編集するsrc/app/sample/models.pyfrom django.db import models class Test1(models.Model): class Meta: verbose_name_plural = "テスト1" test1_name = models.CharField("テスト名",max_length=25) test1_value = models.CharField("テスト値",max_length=25) def __str__(self): return self.test1_name class Test2(models.Model): class Meta: verbose_name_plural = "テスト2" test1= models.ForeignKey(Test1, on_delete=models.PROTECT) test2_name = models.CharField("テスト名",max_length=25) test2_value = models.CharField("テスト値",max_length=25) def __str__(self): return self.test2_name管理画面の設定
src/app/sample/admin.py
を編集するfrom django.contrib import admin # Register your models here. from order.models import Test1, Test2 admin.site.register(Test1) admin.site.register(Test2)マイグレーション
- マイグレーションファイルを作成して実行
$ docker-compose exec django ./manage.py makemigrations $ docker-compose exec django ./manage.py migrate確認
- 下記へログインするとモデルで作成したデータベースが操作できる
http://<IP>:8000/admin
- 投稿日:2021-01-22T22:17:31+09:00
【2】Django の管理画面からアプリケーションのデータベース管理をする
概要
- Docker-composoe + Django環境で作業環境を整えます。
- Djangoは専用の管理画面からデータベースの操作(作成や編集など)が行えます。
- つまりPHPMyAdminなどが不要!!
環境
- Docker + Docker-compose が利用できること。
- Python3.6
- Django3.1(最新)
前提
- Docker-compose + Django + MySQL + Nginx + uwsgi を使った環境の初期設定 が完了していること
- djangoが起動中である
- データベースへアクセスできる
- 管理画面へアクセスできる
- または、同等の環境であること
手順
アプリケーションの作成
- アプリケーションの作成
$ docker-compose exec django manage.py sampleコンフィグの修正
src/app/settings.py
を編集する
- INSTALLED_APPS に作成したアプリケーションを追加する
- sample: フォルダ名
- SampleConfig:
src/app/sample/apps.py
に書いてあるclass
名src/app/settings.pyINSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'sample.apps.SampleConfig', # 追加 ]モデルの作成
src/app/sample/models.py
を編集するsrc/app/sample/models.pyfrom django.db import models class Test1(models.Model): class Meta: verbose_name_plural = "テスト1" test1_name = models.CharField("テスト名",max_length=25) test1_value = models.CharField("テスト値",max_length=25) def __str__(self): return self.test1_name class Test2(models.Model): class Meta: verbose_name_plural = "テスト2" test1= models.ForeignKey(Test1, on_delete=models.PROTECT) test2_name = models.CharField("テスト名",max_length=25) test2_value = models.CharField("テスト値",max_length=25) def __str__(self): return self.test2_name管理画面の設定
src/app/sample/admin.py
を編集するsrc/app/sample/admin.pyfrom django.contrib import admin # Register your models here. from order.models import Test1, Test2 admin.site.register(Test1) admin.site.register(Test2)マイグレーション
- マイグレーションファイルを作成して実行
$ docker-compose exec django ./manage.py makemigrations $ docker-compose exec django ./manage.py migrate確認
- 下記へログインするとモデルで作成したデータベースが操作できる
http://<IP>:8000/admin
- 投稿日:2021-01-22T22:01:04+09:00
DjangoとSvelteを使ってSPAを作るためのテンプレートの紹介
DjangoとSvelteを使ってSPAを作るためのテンプレートの紹介
github https://github.com/muzin00/django_svelte_starter_on_docker
dockerを使用しての環境構築です。
databaseはpostgresqlです。
環境構築の手順はgithubに乗せてあります。
自分はdjangoもsvelteも学習しだしたばかりなので何か間違いがあったり動かなかったりしたら
すいません。コメントで教えていただけると助かります。vscodeを使っている人は公式からでているsvelteの拡張機能をインストールすることをおすすめします。いれないとつらいと思います。
- 投稿日:2021-01-22T20:04:10+09:00
コンテナでDBを作る【mysql】
悩んだ末に絞り出したコンテナ設定の備忘録です。
条件
下記の設定が記載されたテンプレートを元に必要な機能を追記する
・mysql5.7公式dockerイメージを元に、その他必要な設定をcomposeファイルで行う
・データ用のボリュームを用意しコンテナ起動時にマウント
・Mysqlの環境変数の設定がなければDB名等をダミーで作成するシェルが、コンテナ起動時にDBのボリュームが存在しない場合に実行されるこれに加え
・初回コンテナ起動時にテーブル定義〜ダミーデータのインポートまで自動で行えるようにしたい辿り着いた設定
実際のファイルはここに載せると長くなる為載せないけど、こんなイメージのものを作成
composeファイルでイメージがビルド
↓
下記のディレクトリがマウント
・データ用ディレクトリ
・mysql設定ファイル配置ディレクトリ
・エントリーポイント用ディレクトリ
↓
エントリーポイント用ディレクトリに下記を配置
・init.sh(テンプレート)
・テーブル定義用sqlファイル
・データインポート用シェル(インポートするデータサイズが大きい為シェル内で圧縮されたファイルの解凍等も行っている)テーブル定義とデータ部分のインポートを分けたので何かエラーがあったときに箇所が明確になる
また、テーブル定義かデータのどちらかを差し替えたい場合も分けて対応できる
あと、データインポート用シェルには必要な処理を色々追記できるというメリットがある
(インポートが終わったらdumpファイルを削除するとか)若干はまったこと
composeファイルに記載した下記の変数について
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'この設定によりcomposeファイルで
environment: MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' DB_NAME: test DB_USER: root上記のように設定すると、testDBのrootユーザーにはパスワードが存在しないはずなのに、なぜかパスワードが生成された状態でDBが起動する為不思議に思っていたけど、テンプレートのシェルをよく見たら「パスワードが空または定義されていない場合、これを代入」的な処理になっていたので、これが原因とわかった。
dbName="${DB_NAME:-aaa}" dbUser="${DB_USER:-bbb}" dbPassword="${DB_PASSWORD:-ccc}" sql="create database if not exists ${dbName}" echo "${sql}" | ${cmd} mysql sql="grant all on ${dbName}.* to ${dbUser}@'%' identified by '${dbPassword}'" echo "${sql}" | ${cmd} mysql細かく検証していないけど、デフォルト(localhostからのアクセスのみ受け付ける)rootユーザーのパスワードが無くなるという設定のための専用変数ということはさすがにないはず。
どこかで配布されているテンプレートなんだろうか、、出どころ不明だけど、今回はこれを元に作業している為仕方ない、これに手を加えない手段だと、手っ取り早いのはcomposeファイルでパスワードを設定してしまう方法なのでそれで対応。
もしシェルを改修して良ければ、こんな感じでやるかも
if [DB_PASSWORDが値関係なく(nullでも)定義が存在すれば]; then 定義されているものを優先(nullでも) else xxxxxxxxを使用する
- 投稿日:2021-01-22T19:54:12+09:00
Dockerを使って爆速でGPUを設定する方法
はじめに
機械学習をやろうと思ったら、まずやってくるのが GPUの設定 ですよね。ドライバインストールしてCUDAとcudnnインストールして、、、。これが本当にめんどくさい!そんな方には Dockerを用いた設定をオススメします。マジで爆速です。しかも、PyTorchやTFによって環境を別で設定できますし、使わなくなったらその環境をすぐに削除できます。ひと通りカバーした記事があまりなかったので残しておきます。困っている方の参考になればと思います。
*ミスがありましたら、ぜひご指摘お願いします
手順
1. NVIDIA driver のインストール
2. Docker のインストール
3. NVIDIA container toolkit のインストール
1. NVIDIA Driverのインストール
$ nvidia-smi$ sudo apt-get --purge remove nvidia-* $ sudo apt autoremove$ sudo add-apt-repository ppa:graphics-drivers/ppa $ ubuntu-drivers devices$ sudo apt-get install nvidia-driver-4502. Dockerのインストール
- aptのindex更新
$ sudo apt-get update
- 前提ソフトウェアをインストール
$ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
- Dockerの公式GPG公開鍵のインストール
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - OK
- 公開鍵のフィンガープリントを確認
$ sudo apt-key fingerprint 0EBFCD88 pub rsa4096 2017-02-22 [SCEA] 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid [ unknown] Docker Release (CE deb) <docker@docker.com> sub rsa4096 2017-02-22 [S]*「0EBFCD88」は鍵ID
- repositoryの追加
$ sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"$ sudo apt-get update
- Docker CE のインストール
$ sudo apt-get install -y docker-ce
- この状態だと、
$ sudo docker ps
のようにsudo
を付加しないと実行できないので変更# dockerグループの情報表示 $ getent group docker # Dockerグループにユーザ追加 $ sudo gpasswd -a [username] docker # 権限を付与 $ sudo chgrp docker /var/run/docker.sock # 追加されているか確認 $ id [username] # 再起動 $ sudo reboot
- エラーが消えているか確認
$ docker ps
- これでエラーが出なかったらOK
$ sudo docker run hello-world3. NVIDIA container toolkit
- インストール
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) $ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - $ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list $ sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit $ sudo systemctl restart docker
- 確認
$ nvidia-container-cli info4. DockerでGPUを使う
- イメージをpull
$ docker pull nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04
- docker上でNVIDIAドライバが認識されていればOK
$ docker run --gpus all nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04 nvidia-smi
- イメージを元にコンテナを作成する
- 以下は、CUDA:10.0、cudnn:7を使用する場合
$ docker run -it -d --gpus all --name gpu_env nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04 bash$ docker ps
- コンテナに入る
$ docker exec -it gpu_env bash5. コンテナで作業
root@cf3868e92ebf:/# nvidia-smi root@cf3868e92ebf:/# nvcc -Vroot@cf3868e92ebf:/# apt-get updateroot@cf3868e92ebf:/# apt-get install -y python3 python3-piproot@cf3868e92ebf:/# pip3 install torch torchvisionroot@cf3868e92ebf:/# python3 Python 3.6.9 (default, Oct 8 2020, 12:12:24) [GCC 8.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> import torch >>> print(torch.cuda.is_available()) True >>>
- コンテナを抜ける
root@cf3868e92ebf:/# exitその他(dockerコマンド)
- ローカルにあるイメージの一覧表示
$ docker images
- 起動中のコンテナ表示
$ docker ps
- コンテナの起動
$ docker start CONTAINER
- コンテナの停止
$ docker stop CONTAINER
- 起動中のコンテナに入る
$ docker exec -it CONTAINER bash
- コンテナの名前変更
$ docker rename OLD_CONTAINER_NAME NEW_ONTAINER_NAME
- コンテナの削除
$ docker rm CONTAINER参考文献
- 投稿日:2021-01-22T18:49:13+09:00
Docker有償プラン(Pro)の申込方法
はじめに
昨年(2020年)に一部を騒がせたDockerのフリープランでの各種制限の導入ですが、みなさんもイメージをプルする前にDockerにログインしておくなど、以前とは開発体験に変化があったのではないでしょうか?
ここでは、FreeプランからProプランへの移行申込方法についてご紹介します。入力等、画面を見ればあまりに自明だからなのか、Qiitaでも類似した記事を見つけられなかったので、書いてみました。
FreeプランとProプランの違い
移行手続きに入る前に、FreeプランとProプランでできることにどの程度違いがあるのでしょうか? 詳しくは、Pricing & Subscriptionsのページをご覧いただくのが早いのですが、今日(2021/01/22)現在では、こういった違いがあるようです。
Freeプラン(無料)
- パブリックなリポジトリをいくつでも作成可能
- プライベートなリポジトリは1つのみ作成可能
- ロールベースのアクセス制限が可能なユーザ管理
- 1チーム、3チームメンバーまで登録可能
- コンテナイメージのプルリクエストは6時間200回まで(未ログインだとIPアドレスごとに6時間で100回まで)
- 2要素認証の設定可能
Proプラン(7ドル/月, または60ドル/年)
- Freeプランでの提供内容(上述)プラス
- プライベートなリポジトリもいくつでも作成可能
- コンテナイメージのプルリクエスト回数は無制限
- 2パラレルビルド
- 1サービスアカウント
- Slack通知
- 300イメージ/月まで脆弱性スキャン
- プレミアムカスタマーサポート(メールベース)
得られる「開発者体験」が毎月7ドル(年払いなら5ドル)に見合うのであれば、Proプランを申し込みましょう!
Proプラン申込手順
自アカウントにログイン、加入中プランを確認
dockerhubにアクセスし、自分のアカウントにログインします。
右上の指紋マークの左側にある自分のIDをクリックし、Billingをクリックすると、現在加入中のプランが表示されます。
上の画面では、現在加入中のプランが Free Repository Plan である旨、表示されています。では、右側にある
Change Plan
ボタンをクリックします。アップグレードプランの内容・費用確認
先にご紹介したようなFreeプランとProプランの比較、ならびに費用が表示されていますので、確認の上、
Upgrade now
ボタンをクリックします。なお、Learn moreリンクをクリックすると、Pricing & Subscriptionsのページが表示され、FreeとProの他に、Teamプラン、Largeプランについての情報も提供されています。
支払方法の入力
さて、
Upgrade now
ボタンをクリックすると、Payment Method(支払方法)の入力画面になります。年払い(pay annually)か月払い(pay monthly)を選択の上、氏名、クレジットカード番号、有効期限、CNN、住所(CountryにJapanを指定すると郵便番号入力欄が表示されます)を入力し、Purchase
(購入)ボタンをクリックします。アップグレード完了
Purchase
ボタンをクリックすると、現在加入中のプランが改めて表示されます。先ほどはFree Repository Planだったのが、Pro Planに更新されているのがわかります。おわりに
さて、Proプランであれば、Slack通知、および脆弱性プランの設定方法が気になるところです。別途、記事を起こして紹介させていただきます。
- 投稿日:2021-01-22T17:27:01+09:00
docker-composeの面白い挙動を発見した。
問題
docker-composeで定義されたコンテナ名と別のコンテナのサービス名が同じだと、Dockerネットワーク内での名前解決がコンテナ名でできなくなる
本家には報告ずみです。
https://github.com/docker/compose/issues/8056検証
docker-compose.yml
version: "3" services: rest-client: container_name: curl image: tutum/curl command: sleep infinity web1: container_name: api1 build: ./api1 command: ruby main.rb -o 0.0.0.0 api1: container_name: api2 build: ./api2 command: ruby main.rb -o 0.0.0.0 networks: default: name: net1以上のようなケース、”api1”が異なるコンテナでそれぞれコンテナ名、サービス名で使われている場合だと、net1ネットワーク内だと名前解決の結果が混ざる。
嘘だろって思いますが、本当に混ざります。api1コンテナ
require 'sinatra' get '/' do 'This is app1 container!' endapi2コンテナ
require 'sinatra' get '/' do 'This is app2 container!' endこれらをnet1内でアクセスするにはドメインにコンテナ名を使うことでURLアクセスできます。
つまり、以下の結果が期待できます。#net1ネットワークに接続して、 $ curl "http://api1:4567/" This is app1 container! $ curl "http://api2:4567/" This is app2 container!ですが、
curl "http://api1:4567/"
の結果がランダムに変わります。テスト
$ docker-compose up -d $ docker exec -it curl bash # curl "http://api1:4567/"こうしてやると、半分ぐらいの確率で、
This is app2 container!
の結果が混ざって帰ってきます。。。謎の404エラーなどで困っている方がいれば、それが別のコンテナに運ばれている可能性があります。お気をつけて。。。
手軽に試したい方へ
https://github.com/akihirof0005/Verification-defects
上記のリポジトリにテストケースを作成しました。
そして、協力してくれる方は、再現できたら教えてください。再現できなくても教えてください。。。。
- 投稿日:2021-01-22T17:05:52+09:00
EC-CUBE 4 の環境を、Windows + WSL2 + Docker で構築する
Windows 10 Pro 上に、新規に EC-CUBE の開発環境を構築する機会があったのでその手順メモです。
WSL2 + Docker を使って EC-CUBE 4.0 が起動するところまでをまとめます。
試した環境・バージョンは
- Windows 10 Pro (バージョン 1909)
- WSL 2 + Ubuntu 20.04LTS
- Docker v20.10.2
- EC-CUBE 4.0.5
1. Windows に WSL2 をインストール
まずは WSL2 (Windows Subsystem for Linux) のインストールから。
Microsoft の公式サイトに詳しいガイドがありますので、その手順どおりに進めていきます。(途中、再起動が必要な箇所もありました)
Linuxディストリビューションを選択してインストールする箇所では、今回は Ubuntu 20.04LTS を選んでいます。
2. Docker Desktop をインストール
以下から Docker Desktop をダウンロード、からのインストール。
3. EC-CUBE をダウンロード
今回は GitHub の EC-CUBE のリポジトリからクローンしてきます。
Ubuntu のターミナルを開き、適当なフォルダにて以下コマンドで。
git clone https://github.com/EC-CUBE/ec-cube.git4. Docker のビルド
EC-CUBE のフォルダに移動して、docker build します。
cd path/to/ec-cube docker build -t eccube4-php-apache .5. Docker の初回起動
ローカルの EC-CUBE のディレクトリをマウントしつつ、Docker を起動します。
docker run --name ec-cube -p "8080:80" -p "4430:443" -v "$PWD/html:/var/www/html/html:cached" -v "$PWD/src:/var/www/html/src:cached" -v "$PWD/app:/var/www/html/app:cached" eccube4-php-apacheこれで EC-CUBE が起動しました。
ブラウザで http://localhost:8080/ にアクセスして、ストアの画面が表示されていれば成功です。
管理画面へのログインは http://localhost:8080/admin/ にて、初期ID/パスワードは
admin
password
です。Docker の終了は
ctrl + c
で。6. 2回目以降の起動
2回目以降の起動は、以下のコマンドでOKです。
docker start --attach ec-cube参考
- 投稿日:2021-01-22T16:19:22+09:00
gem wheneverをdockerで使う
環境
Docker Engine 20.10.2
Ruby 2.7.0
Bundler 2.1.4手順
wheneverをGemfileへ
# Gemfile source 'https://rubygems.org' git_source(:github) do |repo| "https://github.com/#{repo}.git" end gem 'whenever'コンテナにcronをインストール
# Dockerfile FROM ruby:2.7.0 RUN apt-get update && apt-get install -y cron && apt-get install -y vim WORKDIR /usr/src/app COPY Gemfile . COPY Gemfile.lock . RUN bundle installコンテナのsetupとwheneverの設定
$ docker build -t test_image . $ docker create --name="test_container" -it -v "$PWD":/var/src/app test_image $ docker start test_container $ docker exec -it test_container /bin/bash /usr/src/app# bundle exec wheneverize .以下の設定ファイルができるのでカスタマイズする
# schedule.rb # # Use this file to easily define all of your cron jobs. # # It's helpful, but not entirely necessary to understand cron before proceeding. # http://en.wikipedia.org/wiki/Cron # Example: # set :output, "log/cron_log.log" # every 1.hours do # command end # # every 4.days do # runner "AnotherModel.prune_old_records" # end # Learn more: http://github.com/javan/wheneverもう一度コンテナに入りコマンドを実行
$ docker exec -it test_container /bin/bash /usr/src/app# bundle exec whenever # => # 0 0,2,4,6,8,10,12,14,16,18,20,22 * * * /bin/bash -l -c '/usr/bin/some_great_command >> /path/to/my/cron_log.log 2>&1' # 0 0,2,4,6,8,10,12,14,16,18,20,22 * * * /bin/bash -l -c 'cd /usr/src/app && bundle exec script/runner -e production '\''MyModel.some_method'\'' >> /path/to/my/cron_log.log 2>&1' # 0 0,2,4,6,8,10,12,14,16,18,20,22 * * * /bin/bash -l -c 'cd /usr/src/app && RAILS_ENV=production bundle exec rake some:great:rake:task --silent >> /path/to/my/cron_log.log 2>&1' # 0 0 1,5,9,13,17,21,25,29 * * /bin/bash -l -c 'cd /usr/src/app && bundle exec script/runner -e production '\''AnotherModel.prune_old_records'\'' >> /path/to/my/cron_log.log 2>&1'cronを起動
/usr/src/app# service cron start #=> [ ok ] Starting periodic command scheduler: cron.
cronが動いているか確認
/usr/src/app# service cron status #=> [ ok ] cron is running.
参考
- 投稿日:2021-01-22T16:10:32+09:00
dockerコンテナ作った(Dockerfileから)
イメージの作成
*コンテナ起動時にapacheが自動起動しない・・・なぜだ
Dockerfileを準備
mkdir -p /usr/local/etc/docker_files/test/ vi /usr/local/etc/docker_files/test/DockerfileFROM ubuntu RUN apt-get update RUN apt-get -y upgrade RUN apt-get install -y sudo RUN sudo apt-get install -y vim RUN sudo apt-get install -y curl RUN sudo apt-get install -y tzdata RUN sudo apt-get install -y php7.4 ADD ./home /home/ ADD ./php.ini /usr/local/etc/php/ ADD ./apache2 /usr/local/etc/ COPY ./startup.sh /usr/local/etc/ RUN chmod 744 /usr/local/etc/startup.sh RUN ["sudo", "/bin/bash", "-c", "echo \"ServerName $HOSTNAME\" > /etc/apache2/conf-available/fqdn.conf"] RUN a2enconf fqdn #RUN apachectl start EXPOSE 80 CMD ["/usr/local/etc/startup.sh"] #ENV APACHE_RUN_USER www-data #ENV APACHE_RUN_GROUP www-data #ENV APACHE_PID_FILE /var/run/apache2.pid #ENV APACHE_RUN_DIR /var/run/apache2 #ENV APACHE_LOG_DIR /var/log/apache2 #ENV APACHE_LOCK_DIR /var/lock/apache2 #CMD ["apachectl", "-D", "FOREGROUND"] #RUN ["sudo", "/bin/bash", "-c", "/etc/init.d/apache2 start"] #RUN ["sudo", "/bin/bash", "-c", "/usr/sbin/apachectl -D FOREGROUND"]Dockerfileからイメージを作成
イメージあるかどうか確認
docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE
ビルド(イメージを作成)
docker build -t test /usr/local/etc/docker_files/test/できたかどうか確認
docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE php74test latest b5f7bfd05352 58 seconds ago 297MB ubuntu latest f63181f19b2f 24 hours ago 72.9MB
コンテナ作成
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESdocker run --name container01 -it php74test:latest /bin/bash Ctrl + P + Q でコンテナから出るdocker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a3270221bbd8 php74test:latest "/bin/bash" 54 seconds ago Up 53 seconds container01
docker attach container01
- 投稿日:2021-01-22T15:14:11+09:00
docker, docker-composeを ubuntu18にワンライナーインストール
概要
これを実行すること。
sudo apt-get update &&\ sudo apt-get -y install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common &&\ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - &&\ sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" &&\ sudo apt-get update &&\ sudo apt-get install -y docker-ce docker-ce-cli containerd.io &&\ sudo apt-get install -y docker-compose備考
この後
docker login
で謎のgoのpanicエラー(sigfault的な)が出た時は
https://qiita.com/kenmaro/items/1adc71b42088f12d1b95
これを実行する。また、
ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running? If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable. Makefile:5: recipe for target 'config' failed make: *** [config] Error 1が発生した場合、
https://qiita.com/dnnnn_yu/items/14a31721a2870b735938
ここをフォローすること。(記事ありがとうございます。)
- 投稿日:2021-01-22T14:48:58+09:00
dockerをubuntuにインストール後、docker login できない問題解決備忘録
概要
$ docker login registry.gitlab.com
等のコマンドで、SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x5647add8ed76] goroutine 1 [running]: github.com/docker/cli/cli/command.ConfigureAuth(0x5647af9cfce0, 0xc00050d6c0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5647af93f100, 0xc000414eb0, 0xc00059b968) /go/src/github.com/docker/cli/cli/command/registry.go:128 +0x46 github.com/docker/cli/cli/command/registry.runLogin(0x5647af9cfce0, 0xc00050d6c0, 0x7ffdf63d38a5, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...) /go/src/github.com/docker/cli/cli/command/registry/login.go:123 +0x223 github.com/docker/cli/cli/command/registry.NewLoginCommand.func1(0xc000138dc0, 0xc0005e37f0, 0x1, 0x1, 0x0, 0x0) /go/src/github.com/docker/cli/cli/command/registry/login.go:45 +0xcc github.com/docker/cli/vendor/github.com/spf13/cobra.(*Command).execute(0xc000138dc0, 0xc000364410, 0x1, 0x1, 0xc000138dc0, 0xc000364410) /go/src/github.com/docker/cli/vendor/github.com/spf13/cobra/command.go:850 +0x462 github.com/docker/cli/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0xc000139b80, 0xc000364400, 0x2, 0x2) /go/src/github.com/docker/cli/vendor/github.com/spf13/cobra/command.go:958 +0x34b github.com/docker/cli/vendor/github.com/spf13/cobra.(*Command).Execute(...) /go/src/github.com/docker/cli/vendor/github.com/spf13/cobra/command.go:895 main.runDocker(0xc00050d6c0, 0x5647af941de0, 0xc000010020) /go/src/github.com/docker/cli/cmd/docker/docker.go:287 +0x1d3 main.main() /go/src/github.com/docker/cli/cmd/docker/docker.go:298 +0xf3となる。。
解決方法
sudo apt remove golang-docker-credential-helpersとりあえずこれで大丈夫になる。。
- 投稿日:2021-01-22T14:05:57+09:00
M1 MacでDocker Preview版が起動しなくなった。
事象
ある日突然Docker Preview版が起動しなくなりました。
何もしてないのに...解決方法
以下のIssueを参考にしました。
https://github.com/docker/for-mac/issues/5276
まず以下を試しました
Kubernetesを無効化(効果なしでした)
k8s is known not to work, I had to edit ~/Library/Group\ Containers/group.com.docker/settings.json ("kubernetesEnabled": false, "kubernetesInitialInstallPerformed": false) to get the dashboard to respect that I wanted to back out that change
that said, the perpetual starting state problem happened to me long after I tried to enable k8s
edit: when docker was working, I was using k3d successfullyで、以下を試したところ起動しました(FireWallをOFFにする)
ちなみにファイアーウォールオプションから、Docker Previewを外部アクセス許可してもだめだったので、ファイアーウォール自体をオフにしないとダメっぽいです。
Try to close the firewall on mac m1 and then restart the docker.
結論
原因はわかりませんが、Mac側のファイアウォールが起動を妨げていた模様。セキュリティ的に問題ありそうですが、一応は動くようになったので解決です。
- 投稿日:2021-01-22T14:05:57+09:00
M1 MacでDockerが起動しなくなった。
事象
ある日突然Docker Preview版が起動しなくなりました。
何もしてないのに...解決方法
以下のIssueを参考にしました。
https://github.com/docker/for-mac/issues/5276
まず以下を試しました
Kubernetesを無効化(効果なしでした)
k8s is known not to work, I had to edit ~/Library/Group\ Containers/group.com.docker/settings.json ("kubernetesEnabled": false, "kubernetesInitialInstallPerformed": false) to get the dashboard to respect that I wanted to back out that change
that said, the perpetual starting state problem happened to me long after I tried to enable k8s
edit: when docker was working, I was using k3d successfullyで、以下を試したところ起動しました(FireWallをOFFにする)
ちなみにファイアーウォールオプションから、Docker Previewを外部アクセス許可してもだめだったので、ファイアーウォール自体をオフにしないとダメっぽいです。
Try to close the firewall on mac m1 and then restart the docker.
結論
原因はわかりませんが、Mac側のファイアウォールが起動を妨げていた模様。セキュリティ的に問題ありそうですが、一応は動くようになったので解決です。
- 投稿日:2021-01-22T11:59:58+09:00
Dockerいれてみた
サーバの用意
まずはさくらにログインして最小構成でUbuntu選んで適当にサーバ作る
ユーザの作成
作成完了したら、デフォルトのユーザでログイン後、
adduser USER
を実行してユーザを作成する。dockerインストール
参考)公式
https://docs.docker.com/engine/install/ubuntu/apt-get update sudo apt-get install -y \ apt-transport-https \ ca-certificates \ curl \ software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo apt-key fingerprint 0EBFCD88 sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" sudo apt-get install docker-ce docker-ce-cli containerd.ioここまでやればdocker使えるようになる
ちなみにdockerコマンドをsudoしないで使いたいなら
dockerグループにユーザ追加すればOK
- 投稿日:2021-01-22T11:13:24+09:00
OpenJDKコンテナにDockerを追加
FROM openjdk:8-jdk RUN apt-get update -qq && apt-get install -qqy \ apt-transport-https \ ca-certificates \ curl \ lxc \ iptables RUN curl -sSL https://get.docker.com/ | sh CMD service docker start && /bin/bash
- 投稿日:2021-01-22T10:54:53+09:00
コンテナの話をはじめから 〜Kubernetesを本番運用して5年目の所感まで〜
この記事は、ベルフェイスの有志メンバーでつなぐ 新年ベルリレー 20日目のコンテンツです。
はじめに
ベルフェイスでは、本番サービス運営のためにコンテナ技術 (Kubernetes = クーバネティス) を利用しています。
本項の執筆者 @numa-numa は転職して日が浅いのですが、以前からKubernetes (これより先は、主にK8sと記載します) を本番で運用してきました。
私にとってコンテナで商用サービスを扱うようになってもうすぐちょうど5年…という節目の年でもあるので、コンテナのことを基本からまとめながら、K8sの何が良いのか/悪いのかという経験に基づいた概観についてまでご紹介する内容にしていきたいと思います。【歴史】 2000年代半ばくらいから一気に隆盛を極めた仮想技術
いわゆる、コンピュータの仮想化と言われる技術が多用されるようになったのは、2000年代半ば (2005年前後?) が黎明期であり、それから数年の間に一気に多用されるようになりました。
コンピュータを仮想化するようになった背景要因として、ハードウェアの高性能化が挙げられます。
WEBサービスを提供する時に、フロント系サーバ群にはWEBサーバ (Apacheなど) や開発言語 (主にPHPを利用したものやRailsなどの各種フレームワーク) などをインストールして多数台の冗長構成で利用することが一般的です。ただ、徹底したチューニングを施したとしても、OSの制約などでサーバ1台で捌けるアクセス量もある程度上限が決まってきます。
サーバリソースは使えるだけ有効に使いたいものですが、台数を増やす前にサーバ1台の性能が大きすぎて非効率…という状況も往々にして発生していました。そこで、物理ベースのサーバには仮想化のソフトウェアをインストールすることで、1台の物理サーバのリソースを分割し何台かのサーバを内部に収容するタイプの仮想技術が使われるようになりました。
イメージ的には以下の図のような構成概念になります。
これは、細分化すると、
- ホストOS型 (VMware Fusion, Vagrant, VirtualBox など)
=> OSはWindow/Linuxなどを利用し、仮想化用ツールをインストール- ハイパーバイザ型 (Esxi, KVM, Xen など)
=> OS自体が仮想化専用のものの2通りがあります。
ホストOS型は主にPCで使われる技術で本項の主旨とも外れるので、ここではサーバ用途に限定しハイパーバイザ型だけを図示しています。【歴史+α】 コンテナとは何か?
さて、私が使ってきたK8sをはじめとしたコンテナ技術は仮想化技術です。
これがいわゆるハイパーバイザ型と何が違うのかというと、Linuxのコンテナ層というOSのカーネルの機能を利用して仮想化を行っている点です。
具体的には、 namespaces と cgroup という機能を利用しています。詳細は割愛しますが、これらはK8sの動作についても重要な役割を持っています。
- namespaces … 実行環境を名前空間として切り分けることで、コンテナ間の分離・独立性を確保する
- cgroup … CPU・メモリ・Disk I/Oなどにリソース制限を設ける
これらの特性を利用することで、Linuxという1つのOSでも実行空間分離やリソースへの制限を設けることで、仮想的に複数環境を動作することができる仕組みです。
コンテナ型の仮想化は、下の図のような構成概念となります。
Linuxにおけるコンテナ技術というのは比較的歴史があり、cgroupの元になるカーネル技術は2008年頃に開発されていて、当時からカーネル機能を利用したLXCという技術も開発されています。
その他、初期から独自のコンテナを展開してきたものとしてOpenVZというのがありますし、libvirt, systemd-nspawn, FreeBSD Jail など、実はいろいろなコンテナ技術があります…しかしながら、2021年初現在では、コンテナ ≒ Docker と言って差し支えない昨今です。
https://www.docker.com/companyDockerは2013年3月に急遽出てきた技術といえるでしょう。
それなのに、これが現在世界のコンテナの標準技術となっているのです。Dockerがデファクトスタンダードになった理由は実際判然としないのですが、
- 単純に、市場のニーズに対するリリースタイミングがよかった
- 軽量さとシンプルさ、手軽な利用性
- 結果的に多くのLinuxディストリビューションに加え、Microsoft/Googleなどでも導入された
などではないかと、個人的には考えています。
- Control groupsの参考 (RHEL7)
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/kernel_administration_guide/kernel_features- LXCの参考 (技術評論社のベージ)
https://gihyo.jp/admin/serial/01/linux_containers/0001- OpenVZの参考 (公式)
https://openvz.org/Kubernetesとは何か?
K8sはDockerを運用するためのオーケストレーションツールです。
Dockerはそれだけを使っても、スポットでだけ生存する単純な仮想環境 (コンテナ) を作成し検証作業などに利用することしかできません。
WEBサーバ・DBサーバ・ストレージサーバ・KVS……
WEBサービスを商用展開する場合には、単一のコンテナがあれば良い訳ではなく、複数種のコンテナを立てそれらを相互連携できるスキームが必要です。
それを提供するのがオーケストレーションツールということになります。K8sはコンテナオーケストレーションツールのデファクトスタンダードです。
Dockerの世界と違い、ことコンテナオーケストレーションに関しては、ここ数年はレッドオーシャンの状態が続いていました。
しかし、今はその戦いにひとまず決着がつき "K8sがデファクトだ!" と言い切ってほぼ問題ない状況だと考えています。
(ITのことなので、今後これがひっくり返らない保証もないのですが…)コンテナ (Docker) を使うと何がいいの?
結論からいうと、開発/運用における下記の5つの課題が解決されます。
- 開発環境をすぐに立てることも、消すこともできる (環境の自由)
- アプリケーションの実行環境 (多くはインフラ的な領域) の構成方法をコードとして定義することで、結果的に運用負荷が低減される
- 本番/ステージング/開発 各環境の差異がなくなり、アプリケーションリリースに対する心理的安全性が高まる
- パッチ適用やカーネルアップデートが容易になる (それらがすぐ行えるかどうかの確認も含め)
- CIを整備することで、安定的なデリバリーが確保される
これらについて、単純な例でかんたんに説明します。
ここでは、WEBプログラムを用いない単純なWEBサーバをローンチすることを考えます。
Apacheをインストールし、テストページが見えればOKです一般的なサーバの場合
当たり前ですが、もし物理サーバを用いるとすると、まずはハードウェアを用意し、そこにOSをインストールするキッティングから始まります
ただ、今はクラウドがありますので、私の方ではAWSを利用して Ubuntu がインストールされた VM(EC2) を立ててrootログインし、以下のようなコマンドを実行しました。apt-get install -y apache2 systemctl start apache2ブラウザを表示した結果は、以下の通りです。
OS標準のApacheテストページが見えるようになっています。Dockerの場合
Dockerではインフラ構成をコードにします。
このコード (Dockerfile) をもとにインフラ/アプリケーションをデプロイします。通常、商用で利用するときは何らかのCIツールを使用することになりますが、ここではPC(Mac)でDockerfileを記載し、コマンドでコンテナを実行することにします。
Dockerfileは以下のような内容です。
FROM alpine:3.10 # Package Install RUN apk update && apk add --no-cache apache2 # Run apache2 CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]Dockerfileが書けたら、以下のようにコマンドを実行しDockerをビルド/実行します。
docker build -t test-apache ./ docker run --name test-apache -d -p 80:80 test-apacheこちらのブラウザ表示結果は、以下の通りです。
ここでは Alpine というOSを利用しています。Alpine は非常に軽量なため、一般にコンテナでの使用が推奨されます。
OSなどが違っているので、テストページの見た目は全く異なっていますが、WEBサービスが構築できるという本質は同じです。どういい所につながる?
Dockerは "定義(宣言)型インフラストラクチャ" と言われます。
対して、ログインしコマンドコントロールするものは "命令型インフラストラクチャ" と言います。命令型は、エンジニア (あるいはオペレータ) がコマンド操作を行うことで、自由に状態や構成を変化させることができます。
対して定義型は、コードによって定義された一定の状態を保ち続けることになります。一見、前者の方が良いように感じますが、実は定義型を採用するだけで先に挙げた5つの課題解決に結びつくのです。
一つ一つ見ていくことにしましょう。
- 開発環境をすぐに立てることも、消すこともできる (環境の自由)
もし物理サーバでも構築しようものなら、破棄するときにはデータ消去とサーバ回収の業者まで呼ぶことになります。
クラウドを利用する場合も、手動で立てたサーバを消し忘れれば、どんどんお金はかかります。
Dockerコンテナは、以下のようなコマンド1つで揮発します。
(K8sの場合は別のコマンド体系を利用することになります。)docker stop e3d51562fb72
アプリケーションの実行環境 (多くはインフラ的な領域) の構成方法をコードとして定義することで、結果的に運用負荷が低減される
人がコンピュータに命令を行う=運用作業…です。つまり、コンテナの利用範囲が広がれば広がるほど運用作業は少なくなります。本番/ステージング/開発 各環境の差異がなくなり、アプリケーションリリースに対する心理的安全性が高まる
開発だけインストールされているモジュールのバージョンが異なる…
ステージングだけサービス止まってた…
などは、WEBベンチャー企業を中心によくある話です。
コンテナを使うことで、こうしたことは起きなくなるか、相当起こりにくくなります。
どの環境も、同じDockerfileをもとに構成されるためです。パッチ適用やカーネルアップデートが容易になる (それらがすぐ行えるかどうかの確認も含め)
OSのカーネルアップデート。命令型のインフラでこれを行おうとすると、サービスの停止やサーバの切り離しを伴う数時間の作業が必要です。
そして、それら(本番)の作業に至るまでの検証作業も…
コンテナの場合。ここでは Alpine の3.10に特有の脆弱性があると仮定し、それが3.12で修正されたとします。
3.12でサービスが稼働するかの確認は、Dockerfileの先頭行を以下のように直してコンテナを作り直せばすぐにできます。FROM alpine:3.12
- CIを整備することで、安定的なデリバリーが確保される
先ほど実行したように、手動オペレーションでDockerイメージを実行するやり方はPCのみに通用するものです。 商用サービスへの適用検討すると、
・ビルド
・テスト
・デプロイのフローを厳密化する必要が生じ、それを機にフローを設計(改善)することとなり、結果的に安定したデリバリー確保につながります。
Kubernetesを使うと何がいいの?
まず、K8sはDockerのオーケストレーションツールですので、Dockerで享受できるいいことは同様に全て当てはまります。
K8sは非常に多機能であり多くのメリットがあるのですが、本項の内容に即した3点に絞ってご紹介します。
複数のDockerホストの管理
Dockerを1台のホスト(サーバ)で構成すると、故障などでホストが停止した時に全サービスが停止することになります。
ハイパーバイザ型の仮想化では、こうしたことがしばしば問題になってきました。
K8sでは複数のDockerホストを一元管理することによって、冗長性・高可用性を確保することが可能です。スケーリング/オートスケーリング
K8sでは、サーバ1台が Pod と呼ばれる単位で構成されます。
Podの数や性能は自由に定義できます。Podの性能を変更したいときは、コードを変更し再リリースを行うだけです。
アクセス量によってPod数が調整される、オートスケーリングも簡単に実装できます。オートヒーリング
Dockerではオペレーションを行うことでコンテナの内容が変わってしまった時に、再生成することで定義された状態に戻すことができます。
K8sではこれを一歩進め、コンテナに異常 (過大なアクセスによるリソース枯渇など) が起こりダウンしてしまった時にPodは自動で復旧されます。Kubernetesの構成概念
WEBにおいては、以下のようなものが基本となります。
K8sではさまざまな種類のコンテナをデプロイすることができるのですが、下図は Deployment と言われる種類のものを例に取っています。
Deployment はWEBのフロントアクセス系に最も適したリソースで、リリースを行うことで継続的にコンテナの更新を行うことが可能です。
Pod
実際にデプロイされるコンテナです。サーバ1台と同様のものと考えて差し支えありません。
Podはオートスケールで数を変更することもできますし、固定の数を指定しておくこともできます。
デプロイされるアプリケーションに応じて、CPU/メモリの割当て量を調整して構成します。Namespace
仮想のクラスタ空間であり、それぞれは分離されていて独立しています。
Namespaceをいくつか用意することで、複数のチームで利用したり、複数のアプリケーションを同じ(物理)K8sクラスタにデプロイすることが可能です。このように概念を見ていくと、K8sで使われる技術はLinuxコンテナの技術の応用であることにも気づかれるでしょう。
Kubernetesを運用するうえで出てくる問題点
私のこれまでの経験でも、またベルフェイスでもそうなのですが、K8sをツールとしてインストール/運用したりDockerホストを構築したりすることは行っていません。
AmazonやGoogleのクラウドサービスで提供されるマネージドサービスでK8sを利用しています。
マネージドサービスを利用するとK8s自体の複雑な管理/運用は不要 (クラウド任せ) になるので、エンジニアはより開発に注力できることになります。
ただし、運用面で何もしなくて良いわけでは当然なく、私がこの5年間で実感した K8sのマネージドサービスを使う上での問題点 に絞って2点ご紹介します。バージョンアップのつらみ
K8sは仕様こそある程度落ち着いてきましたが、現在も活発に開発が進んでいます。
2021年1月現在の最新は、v1.20.0ですがこれもすぐに過去のバージョンとなってしまうことでしょう。
https://kubernetes.io/docs/setup/release/notes/#downloads-for-v1-20-0K8sはOSSであり、ベンダーニュートラルなツールです。
ただ、マネージドサービスはベンダーディペンドなので、この間の差はユーザが埋めることになります。具体的には、クラウド側ではある時点で新規インストールできるバージョンとサポートするバージョンが決められているということになります。
ユーザは定期的にマネージドのK8sクラスタのバージョンを上げる運用が必要になります。
バージョンアップにより、K8sとして仕様が変わり最悪デプロイされたアプリケーションが動作しなくなる可能性もあるので注意が必要です。慣れてしまえば、ポイントは決まっているのでバージョンアップは恐怖の作業ではないですが、それでもつらみの運用とはいえるでしょう。
キャパシティプランニングは慎重に
先述の通り、K8sはPodのオートスケーリングが可能ですので、本番運用ではぜひ採用/設定すべきです。
しかし、Pod単体のキャパシティプランニング (利用リソース量調整) まで自動で行ってくれるわけではありません。
たとえば、アプリケーションの動作のために、
- 2vCPU
- 2GBメモリ
という要件のところ、たとえばこれを下回る以下のような設定を行ったとすると記載のような不具合を生じます。
- 1vCPU … CPU使用率が張り付いてパフォーマンスが相当に悪化
- 1GBメモリ … コンテナ内部でOOM (Out Of Memory) が引き起こされ、Podが上がってもすぐに落ちる
とくに、私はメモリ不足による一大インシデントを経験しています。
キャパシティプランニングほどITインフラにとって重要なものはないので、十分に余裕を見た設計が肝要です。おわりに
ここ15年くらいの仮想の歴史を繙きながら、コンテナのことをいろいろ書いてきましたが、結局のところシステムにおける運用負荷を完全に0にすることはできません。
ただし、コンテナを活用することで可能な限りの運用効率化・可視化・負荷低減施策など継続的なプロセス改善を行い、限りなく0に近い運用負荷水準にすることは可能だと考えています。
ベルフェイスでは、AWSを利用したコンテナ活用を推進しておりまして、今後も安定性の高いシステム基盤作りに取り組んでいきます。
ベルフェイスは,現在積極採用中です
一緒にOpslessに取り組みたい人いませんか
https://recruit.bell-face.com/
- 投稿日:2021-01-22T04:29:13+09:00
golangでFargate運用を想定したDockerfile作成(Alpineベース)
概要
個人アプリにて、Fargateでのコンテナ運用を行うため、golang環境のDockerfileを作成しました。
当環境の特徴として、
- DockerイメージをAlpine Linuxベースを使用し、軽量化。
- マルチステージビルド機能を使用し、ビルド環境でgolangアプリやその他バイナリを作成し、軽量化。
- Fargateで運用するコンテナの中に入ってシェル操作するため、ssm-agentを導入。
です。
各種ファイル
Dockerfile
FROM golang:1.14.4-alpine3.12 as builder ARG SSM_AGENT_VERSION=2.3.1205.0 RUN apk add --no-cache \ 'make~=4.3-r0' \ 'git~=2.26.2-r0' \ 'gcc~=9.3.0-r2' \ 'libc-dev~=0.7.2-r3' \ 'bash~=5.0.17-r0' RUN wget -q https://github.com/aws/amazon-ssm-agent/archive/${SSM_AGENT_VERSION}.tar.gz && \ mkdir -p /go/src/github.com && \ tar xzf ${SSM_AGENT_VERSION}.tar.gz && \ mv amazon-ssm-agent-${SSM_AGENT_VERSION} /go/src/github.com/amazon-ssm-agent && \ echo ${SSM_AGENT_VERSION} > /go/src/github.com/amazon-ssm-agent/VERSION WORKDIR /go/src/github.com/amazon-ssm-agent RUN gofmt -w agent && make checkstyle || ./Tools/bin/goimports -w agent && \ make build-linux WORKDIR /go/src/server COPY go.mod go.sum ./ RUN go mod download RUN go get bitbucket.org/liamstask/goose/cmd/goose COPY . . RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /go/bin/server FROM alpine:3.12 as prod RUN apk add --no-cache \ 'aws-cli~=1.18.55-r0' \ 'sudo~=1.9.0-r0' \ 'mysql-client~=10.4.15-r0' RUN adduser -D ssm-user && \ echo "Set disable_coredump false" >> /etc/sudo.conf && \ echo "ssm-user ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ssm-agent-users && \ mkdir -p /etc/amazon/ssm COPY --from=builder /go/src/github.com/amazon-ssm-agent/bin/linux_amd64/ /usr/bin COPY --from=builder /go/src/github.com/amazon-ssm-agent/bin/amazon-ssm-agent.json.template /etc/amazon/ssm/amazon-ssm-agent.json COPY --from=builder /go/src/github.com/amazon-ssm-agent/bin/seelog_unix.xml /etc/amazon/ssm/seelog.xml COPY --from=builder /go/bin/server /go/bin/server COPY --from=builder /go/bin/goose /go/bin/goose RUN mkdir -p /go/bin/db COPY ./db/dbconf.yml /go/bin/db/dbconf.yml COPY ./db/migrations /go/bin/db/migrations COPY ./db/mysql/init /docker-entrypoint-initdb.d EXPOSE 8080 COPY ./aws/docker-entrypoint.sh / CMD ["sh", "/docker-entrypoint.sh"]docker-entrypoint.sh
#!/bin/sh set -e amazon-ssm-agent -register -code $SSM_ACTIVATE_CODE -id $SSM_ACTIVATE_ID -region "ap-northeast-1" amazon-ssm-agent & /go/bin/server要点
Alpineはssmエージェント未対応
※一部抜粋 RUN wget -q https://github.com/aws/amazon-ssm-agent/archive/${SSM_AGENT_VERSION}.tar.gz && \ mkdir -p /go/src/github.com && \ tar xzf ${SSM_AGENT_VERSION}.tar.gz && \ mv amazon-ssm-agent-${SSM_AGENT_VERSION} /go/src/github.com/amazon-ssm-agent && \ echo ${SSM_AGENT_VERSION} > /go/src/github.com/amazon-ssm-agent/VERSIONAlpineではssmエージェントのパッケージがないので、ソースから拾いビルドして設置する必要があります。
https://github.com/aws/amazon-ssm-agent/issues/140ECRスキャンはscratchベース非対応
FROM alpine:3.12 as prodDockerイメージ軽量化のため、最初はscratchベースで実行環境を構築しようとしましたが、ECRはイメージスキャン未対応のことなので、実行環境もAlpineを採用しました。
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/image-scanning-troubleshooting.htmlマイグレーションツールのgooseを採用
RUN mkdir -p /go/bin/db COPY ./db/dbconf.yml /go/bin/db/dbconf.yml COPY ./db/migrations /go/bin/db/migrations開発環境でもお世話になった
goose
を本番環境でも採用しました。ビルド環境でバイナリ作成、実行環境にバイナリと必要なファイルをコピーして準備完了。ファイルの置き場所によって設定ファイルdbconf.yml
が読み込まれなくなってしまうので、注意が必要です。シェルスプリクトで起動コマンド設定
amazon-ssm-agent -register -code $SSM_ACTIVATE_CODE -id $SSM_ACTIVATE_ID -region "ap-northeast-1" amazon-ssm-agent &コンテナ内で実行するため、シェルスクリプトでコマンドを投げてあげます。この時アクチベーションキーも設定しないといけないので、コンテナ内の環境変数に設定します。
参考資料
Go 1.12 の開発環境と本番環境の Dockerfile を考える
Alpine Linux に amazon-ssm-agent をインストールする
AWS Fargateで動かしてるコンテナの中に入る方法
- 投稿日:2021-01-22T00:13:55+09:00
Myリポジトリの利用とDocker Registoryの構築。
はじめに
普段Dockerを利用する際は、初めに登録したDockerHUBのリポジトリからイメージ取得がされている。
これに特別困っていることはないのだが、DockerHUBにMyリポジトリを作ったり、ローカルでDocker Registoryを構築したりもせっかくなので試してみようと思った。実行環境
・VMインスタンス2台(GCP上)
【VM#1(リージョン:東京)】
・Ubuntu 20.04 LTS
・docker 19.03【VM#2(リージョン:US)】
・Ubuntu 20.04 LTS
・docker 19.03
・docker-registory今回の手順
1.VM環境準備
2.DockerHUBにMyリポジトリ作成
3.Docker Registoryの構築1.VM環境の構築
VM#1、VM#2にdockerのインストール
【Dockerコンテナ内のUbuntuではsystemctlは使えない】の手順1を参考に。2.DockerHUBにMyリポジトリ作成
DockerHUBへのアカウント登録
DockerHUBの公式ページに飛び、サインアップ。
https://hub.docker.com/VM#1にPush用のイメージを用意
$ docker container run -it -d --name con1 ubuntu:18.04コンテナに入り適当なソフトをインストール
※今回もApache2をインストールコンテナに入る$ docker attach con1
コンテナ内のコマンドapt update apt -y upgrade apt install -y apache2コンテナ内のコマンド(コンテナから出る)exit
変更を加えたコンテナをイメージ化する
$ docker commit con1 test-myrepo:ver1
イメージの確認
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE test-myrepo ver1 754107070068 54 seconds ago 213MB ubuntu 18.04 2c047404e52d 3 weeks ago 63.3MBMyリポジトリにイメージをPush
まずはDockerHUBにログインする
$ sudo docker login Username: ****** Password: ****** Login Succeeded
tag
コマンドでレジストリ先・リポジトリを変更したものを用意。$ docker image tag 【イメージID】 【アカウント名(Myリポジトリ)】/【イメージ名】:【タグ】試しにイメージを確認してみる。
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE test-myrepo ver1 754107070068 19 hours ago 213MB ******/new-img ver1 754107070068 19 hours ago 213MB ubuntu 18.04 2c047404e52d 3 weeks ago 63.3MBDockerHUBにイメージを
Push
$ docker image push 【上記で作成されたイメージ名(アカウント含む)】:【タグ】DockerHUBのページでリポジトリが作成されていれば、Pushは上手くいっている。
※普段
docker image pull
より、【イメージ名】:【タグ】のみでダウンロードできるのは、最初の設定時にデフォルトのレジストリ先を DockerHUB 、リポジトリ先をどこかに設定しているから。(上記のPush
はリポジトリ先をMyリポジトリに変えている。)
例えば、プライベートレジストリにイメージをPush
やPull
する時は、docker image pull 【レジストリ名】:【リポジトリ名】:【イメージ名】:【タグ】
となる。VM#2でMyリポジトリからイメージをPull
Push
の時と同じくCUIからDockerHUBにログインする$ sudo docker login Username: ****** Password: ****** Login Succeeded実際の
Pull
コマンドを実行$ docker image pull 【アカウント名(Myリポジトリ)】/【イメージ名】:【タグ】
docker image ls
コマンドなどで確認できれば成功!ここまでできたら一旦VM#2のイメージは消す。
3.Docker Registoryの構築(プライベート用)
VM#2にDockerRegistory 取得
Registoryのイメージ取得
$ docker image pull registry
Registoryコンテナの起動
$ docker container run -d -p 5000:5000 registryVM#1からDockerRegistoryに
Push
&Pull
レジストリ情報を付与したイメージを用意
$ docker image tag 【イメージID】 【DockerRegistoryの内部IP:5000】/【リポジトリ名】:【タグ】
プライベートRegistoryに
Push
$ docker image push 【DockerRegistoryの内部IP:5000】/【リポジトリ名】:【タグ】 The push refers to repository [xxx.xxx.xxx.xxx:5000/******] Get https://xxx.xxx.xxx.xxx:5000/v2/: http: server gave HTTP response to HTTPS clientしかし上記の様なエラーが出て上手く行かない。
別のdockerクライアントの端末から
Push
やPull
を行いたい場合、基本的にはSSLを使った暗号化通信が必要となる。
これはdockerクライアント側で、信頼関係がなく暗号化通信できないサーバーとは通信不可の設定になっているから。今回は、Registryコンテナが入っているサーバーを限定的にhttp通信ができる様にする。
VM#1で以下を実行
daemon.json
を作成$ sudo nano /etc/docker/daemon.jsondaemon.json{"insecure-registries":["DockerRegistoryの内部IP:5000"]}docker再起動
$ sudo systemctl restart docker
Inseure Registoryes
に追加されているか確認$ docker info ・・・ ・・・ Experimental: false Insecure Registries: xxx.xxx.xxx.xxx:5000 127.0.0.0/8 Live Restore Enabled: false ・・・ ・・・この状態で再度プライベートRegistoryにPush
$ sudo docker push 【DockerRegistoryの内部IP:5000】/【リポジトリ名】:【タグ】 The push refers to repository [xxx.xxx.xxx.xxx:5000/*******] 2a42637bbd9b: Pushing [====================> ] 62.14MB/149.7MB fe6d8881187d: Pushed 23135df75b44: Pushed b43408d5f11b: Pushing [========================================> ] 51.5MB/63.25MBちゃんとPushできる事を確認!
※ちなみにPullも試したけど問題なくできた。