- 投稿日:2019-05-29T23:43:40+09:00
一足遅れて Kubernetes を学び始める - 12. リソース制限 -
ストーリー
- 一足遅れて Kubernetes を学び始める - 01. 環境選択編 -
- 一足遅れて Kubernetes を学び始める - 02. Docker For Mac -
- 一足遅れて Kubernetes を学び始める - 03. Raspberry Pi -
- 一足遅れて Kubernetes を学び始める - 04. kubectl -
- 一足遅れて Kubernetes を学び始める - 05. workloads その1 -
- 一足遅れて Kubernetes を学び始める - 06. workloads その2 -
- 一足遅れて Kubernetes を学び始める - 07. workloads その3 -
- 一足遅れて Kubernetes を学び始める - 08. discovery&LB その1 -
- 一足遅れて Kubernetes を学び始める - 09. discovery&LB その2 -
- 一足遅れて Kubernetes を学び始める - 10. config&storage その1 -
- 一足遅れて Kubernetes を学び始める - 11. config&storage その2 -
- 一足遅れて Kubernetes を学び始める - 12. リソース制限 -
- 一足遅れて Kubernetes を学び始める - 13. ヘルスチェックとコンテナライフサイクル -
前回
一足遅れて Kubernetes を学び始める - 10. config&storage その2 -では、storageについて学習しました。
今回は、リソース制限について学習します。※ リソースの種類から、次は「Metadata」だったのですが、kubernetes完全ガイドによると直接説明するのではなく、内容ベースで説明されていましたので、それに準拠します。
リソース制限
kubernetesで管理するコンテナに対して、リソース制限をかけることができます。主にCPUやメモリに対して制限をかけることができますが、Device Pluginsを使うことでGPUにも制限をかけることもできます。
※ CPUの指定方法は、1vCPUを1000millicores(m)とする単位となります。
requestsとlimits
requestは、使用するリソースの下限値です。
limitsは、使用するリソースの上限値です。requestは、空きノードに指定するリソースがなければスケジューリングされませんが、limitsは、関係なくスケジューリングされます。
とにもかくにも、試してみましょう。
まず、現状確認です。
pi@raspi001:~/tmp $ k get node NAME STATUS ROLES AGE VERSION raspi001 Ready master 31d v1.14.1 raspi002 Ready worker 31d v1.14.1 raspi003 Ready worker 30d v1.14.1 pi@raspi001:~/tmp $ k get nodes -o jsonpath='{.items[?(@.metadata.name!="raspi001")].status.allocatable.memory}' 847048Ki 847048Ki pi@raspi001:~/tmp $ k get nodes -o jsonpath='{.items[?(@.metadata.name!="raspi001")].status.allocatable.cpu}' 4 4 pi@raspi001:~/tmp $ k get nodes -o jsonpath='{.items[?(@.metadata.name!="raspi001")].status.capacity.memory}' 949448Ki 949448Ki pi@raspi001:~/tmp $ k get nodes -o jsonpath='{.items[?(@.metadata.name!="raspi001")].status.capacity.cpu}' 4 4jsonpathの使い方は、こちらにあります。
allocatableがPodに配置できるリソース量で、capacityはNode全体での配置できるリソース量です。
これだけだと、現在使っているリソース量が不明なので個別に調べます。pi@raspi001:~/tmp $ k describe node raspi002 ... Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 200m (5%) 200m (5%) memory 150Mi (18%) 150Mi (18%) ephemeral-storage 0 (0%) 0 (0%) ... pi@raspi001:~/tmp $ k describe node raspi003 ... Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 400m (10%) 300m (7%) memory 320Mi (38%) 420Mi (50%) ephemeral-storage 0 (0%) 0 (0%) ...現状のリソース状況を表にすると下記のとおりです。
node allocatable
(memory/cpu)capacity
(memory/cpu)used
(memory/cpu)remain
(memory/cpu)raspi002 847,048Ki/4000m 949,448Ki/4000m 150,000Ki/200m 697,048Ki/3800m raspi003 847,048Ki/4000m 949,448Ki/4000m 320,000Ki/400m 527,048Ki/3600m では、リソース制限を試してみましょう。
sample-resource.yamlapiVersion: apps/v1 kind: Deployment metadata: name: sample-resource spec: replicas: 3 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 resources: requests: memory: "128Mi" cpu: "300m" limits: memory: "256Mi" cpu: "600m"applyするpodで要求するmemoryの下限合計は384Mi(128Mi×3),cpuは900m(300m×3)です。
これだと、podがrunするはずです。pi@raspi001:~/tmp $ k apply -f sample-resource.yaml pi@raspi001:~/tmp $ k get pods NAME READY STATUS RESTARTS AGE sample-resource-785cd54844-7n89t 1/1 Running 0 108s sample-resource-785cd54844-9b5f9 1/1 Running 0 108s sample-resource-785cd54844-whj7x 1/1 Running 0 108s期待通りですね。
今度はリソース制限になる状態を試してみます。全WorkerNodeのmemory下限合計は1,224Mi(697,048Ki+527,048Ki)です。
これを超えるように先程のマニフェストを更新します。
replica数を3にしましたが、10にすれば良いですね(1,280Mi)期待動作として、9個(128Mi*9=1,152Mi)はRunningで、1個(128Mi)はPendingになるはずです。
sample-resource.yamlのreplicaを10に変更したあと↓
pi@raspi001:~/tmp $ k apply -f sample-resource.yaml pi@raspi001:~/tmp $ k get pods NAME READY STATUS RESTARTS AGE sample-resource-785cd54844-7n89t 1/1 Running 0 6m19s sample-resource-785cd54844-9b5f9 1/1 Running 0 6m19s sample-resource-785cd54844-dffsd 1/1 Running 0 61s sample-resource-785cd54844-jmkv6 1/1 Running 0 61s sample-resource-785cd54844-k9vcb 1/1 Running 0 61s sample-resource-785cd54844-l4smf 0/1 Pending 0 60s sample-resource-785cd54844-n4hl7 1/1 Running 0 60s sample-resource-785cd54844-th4bp 0/1 Pending 0 60s sample-resource-785cd54844-whj7x 1/1 Running 0 6m19s sample-resource-785cd54844-xclsk 1/1 Running 0 60sあれ、2つPendingになっていますね。もしかして、Nodeの空きリソースが中途半端にないからですかね。
確認してみましょう。pi@raspi001:~/tmp $ k describe node raspi002 ... Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 1700m (42%) 3200m (80%) memory 790Mi (95%) 1430Mi (172%) ephemeral-storage 0 (0%) 0 (0%) ... pi@raspi001:~/tmp $ k describe node raspi003 ... Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 1300m (32%) 2100m (52%) memory 704Mi (85%) 1188Mi (143%) ephemeral-storage 0 (0%) 0 (0%) ...raspi002は、847Mi中790Mi使っています。1つのPodを追加するためのリソース(128Mi)はないですね。
raspi003は、847Mi中704Mi使っています。こちらは空いている気がするのですが、なぜでしょうか。ここで、memoryの
704Mi (85%)
というところに着目すると、100%だった場合は828Miということになります。
確かに、それだと704Mi+128Mi=832Miでオーバーしています。では、allocatableで表示されていた847Miとの違いは何でしょうか。
allocatableというのは、全てのnamespaceにあるpodも込みのリソース配置可能量だからです。
defaultだけでなく、kube-systemなど他のnamespaceにあるpodも、もちろんリソースを消費しています。
828Miというのは、defaultで使えるリソース配置可能量ではないでしょうか。(現在のnamespaceはdefault)ちなみに、Limitsは、100%を超えていますね...。ひぇ〜...。
Cluster Autoscaler
需要に応じてKubernetes Nodeを自動的に追加されていく機能です。
これが動作するタイミングは、PodがPendingになったときに動作します。
つまり、先程の例であったように、requestsの下限によってスケールします。そのため、requestsが高すぎるために、実際はロードアベレージが低くてもスケールしてしまったり、
requestsが低すぎるために、実際は高負荷でもスケールしなくなったりします。
requestsは、パフォーマンステストをしつつ最適化していきましょう。LimitRange
さっきの例でもあったように、それぞれに対してrequests,limitを設定しても良いのですが、
もっと便利なものがあります。それがLimitRangeです。
これは、Namespaceに対してCPUやメモリのリソースの最小値や最大値を設定できます。
設定可能な制限項目として、下記があります。
- default
- デフォルトのLimits
- defaultRequest
- デフォルトのRequests
- max
- 最大リソース
- min
- 最小リソース
- maxLimitRequestRatio
- Limits/Requestsの割合
また、制限する対象は、Container,Pod,PersistentVolumeClaimがあります。
実運用する際は、きちんと定義しておきましょう。(プロバイダーによってはデフォルトで設定されているものもあるそうです)ResourceQuota
ResourceQuotaを使うことで、Namespaceごとに「作成可能なリソース数の制限」と「リソース使用量の制限」ができます。
「作成可能なリソース数の制限」を試そうと思います。sample-resourcequota.yamlapiVersion: v1 kind: ResourceQuota metadata: name: sample-resourcequota namespace: default spec: hard: # 作成可能なリソースの数 count/pods: 5pi@raspi001:~/tmp $ k delete -f sample-resource.yaml pi@raspi001:~/tmp $ k apply -f sample-resourcequota.yaml pi@raspi001:~/tmp $ k apply -f sample-resource.yaml pi@raspi001:~/tmp $ k get pods NAME READY STATUS RESTARTS AGE sample-resource-785cd54844-dll8t 1/1 Running 0 38s sample-resource-785cd54844-ljr7q 1/1 Running 0 39s sample-resource-785cd54844-r6txh 1/1 Running 0 38s sample-resource-785cd54844-sb6sq 1/1 Running 0 38s sample-resource-785cd54844-3ffeg 1/1 Running 0 38sこうすると、podsが5個までしか作成できないので、sample-resource.yamlを適用しても5個までしか作成されません。
replicaのような場合は、特に警告がなく単純に作られませんでした。
configmapを5個までに制限して、1つずつconfigmapをapplyすると、警告がでるそうです。HorizontalPodAutoscaler(HPA)
HPAは、Deployment,ReplicaSetで管理するPodのCPU負荷などに応じて自動的にスケールするリソースです。
30秒に1回の頻度でスケールするかチェックしています。必要なレプリカ数は、下記の数式で表します。
- 必要なレプリカ数 = ceil(sum(Podの現在のCPU使用率)/targetAverageUtilization)
KubernetesのPodとNodeのAuto Scalingについてで、
auto scalingはtarget valueに近づくようにpod数が調整されるということ。
という文がわかりやすかったです。つまり、targetAverageUtilizationが50なら、全体のCPU使用率が50%になるよう調整されます。
今回、試そうと考えたのですが、metrics-serverをinstallしていないため、動作確認できませんでした。
また今度installして試してみようと思います。VerticalPodAutoscaler(VPA)
VPAは、コンテナに割り当てるCPUやメモリのリソース割当をスケールさせるリソースです。
これは、HPAのスケールアウトではなく、Podのスケールアップを行うものです。お片付け
pi@raspi001:~/tmp $ k delete -f sample-resource.yaml -f sample-resourcequota.yaml最後に
今回は、RequestsやLimitsを操作してリソース制限をしてみました。
どれがいくらリソースを消費しているのか確認する術を学び、
ついでにjsonpathの使い方も知りました。
次回は、こちらです。
- 投稿日:2019-05-29T23:40:54+09:00
Rspecで突然謎のエラーが
circleCIで通常通り動いていたテストコードが突然動かなくなりましたが解決したのでその方法を書いていきます。
開発環境
Ruby 2.6.2
Rails 5.2.3
Docker 18.09.2
docker-compose 1.23.2今回発生したエラー
Selenium::WebDriver::Error::UnknownError: unknown error: session deleted because of page crash from unknown error: cannot determine loading status from tab crashed原因
エラーを調べたところ日本語での記事が少なく詳しくはわからなかったのですが、メモリ不足によってクラッシュしてしまうとのこと。
ブラウザのサイズを小さくすれば解決するとの記事を見て試してみたのですが、僕の場合小さくしても解決しませんでした。解決方法
rails_helperのchromeOptionsのところに
--no-sandbox
と--disable-dev-shm-usage
というargumentsを追加してください。--disable-dev-shm-usage
と書くことでChromeは/tmpディレクトリを代わりに使用するようになるみたいです。メモリの代わりにディスクが使用されるので、実行が遅くなる場合があるみたいですがそんなに変わってない気がします。spec/rails_helper.rbCapybara.register_driver :selenium_remote do |app| driver = Capybara::Selenium::Driver.new( app, browser: :remote, desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome( chromeOptions: { args: [ 'window-size=500,500', #念の為サイズも小さく 'headless', '--no-sandbox', # crush回避 '--disable-dev-shm-usage' # crush回避 ] } ), url: 'http://chrome:4444/wd/hub', ) endこれで解決すると思います。
もし間違いがあれば訂正お願いいたします。
参考サイト
https://qiita.com/jb-vasseur/items/d3aa33e08ebba3b9231e
https://stackoverflow.com/questions/53902507/unknown-error-session-deleted-because-of-page-crash-from-unknown-error-cannot
- 投稿日:2019-05-29T22:53:44+09:00
Ruby/Ruby on rails/MysqlをDockerで環境構築
DockerでRuby/Ruby on rails/mysqlの環境構築からデプロイまでできたのでメモしておきます。
(1)Dockerfile作成
DockerfileFROM ruby:2.5.3 RUN apt-get update -qq && \ apt-get install -y build-essential \ libpq-dev \ nodejs RUN mkdir /app_name ENV APP_ROOT /app_name WORKDIR $APP_ROOT ADD ./Gemfile $APP_ROOT/Gemfile ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock RUN bundle install ADD . $APP_ROOT(2)docker-compose.yml作成
docker-compose.ymlversion: '3' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: root ports: - "3306:3306" web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/app_name ports: - "3000:3000" links: - db(3)Gemfile作成
Gemfilesource 'https://rubygems.org' gem 'rails', '5.2.2'Gemfile.lockも作成
$ touch Gemfile.lock(4)新しいアプリを作成
$ docker-compose run web rails new アプリ名 . --force --database=mysql --skip-bundledatabese.ymlを編集
database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password host: dbGemfileをbundle install
$ docker-compose run web bundle install(5)コンテナをビルドと起動
$ docker-compose build # コンテナをビルド $ docker-compose up # コンテナの一斉起動※bundle installの後にbuildする
(6)DB作成
$ docker-compose run web rails db:createDBを作らないとエラーが出る
DBを作成後localhost:3000で初期画面が表示される!
()Herokuでデプロイ
herokuの登録,heroku cliはインストール済みとする
Herokuにアプリ作成
$ heroku createデータベースをMySQLに変更
$ heroku addons:add cleardbClearDBアドオンとは,ClearDBというデータベースサービスが提供している,MySQLを使うためのもの。
$ heroku config | grep CLEARDB_DATABASE_URL
mysql:// 〜 reconnect=true
がデータベース情報
mysql
の部分をmysql2
に変更環境変数を変更
$ heroku config:set DATABASE_URL=mysql2:// 〜 reconnect=true //先ほどのデータベース情報全部$ git add . $ git commit -m "update for upload to heroku"アプリをデプロイ
$ git push heroku masterマイグレーションファイル作成
$ heroku run rake db:migrate参考
- 投稿日:2019-05-29T20:45:49+09:00
【Docker】よく使うコマンドまとめ
最近Dockerの履修を始めたので自分用めも。
確認系
# dockerの色々を確認 $ docker info # 動いているコンテナを見る $ docker ps # 動いていないコンテナも見る $ docker ps -a # イメージの確認 $ docker imagesコンテナ起動関係
CONTAINER IDは特定ができる所まで入力すれば省略が可能。
# コンテナを起動 $ docker start [CONTAINER ID] # コンテナを終了 $ docker stop [CONTAINER ID] # コンテナに入る $ docker attach [CONTAINER ID] # コンテナを終了 $ exit # コンテナを抜ける $ Ctrl + p + q削除系
イメージが使っているコンテナが存在する場合エラーを投げてくれるので、不要なイメージを削除する場合は不要なコンテナを先に削除する。
# コンテナの削除。複数指定可能 $ docker rm [CONTAINER ID] [CONTAINER ID] ...... # コンテナを全て削除。注意 $ docker rm `docker ps -a -q` # イメージの削除 $ docker rmi [IMAGE ID]その他
# イメージのリネーム $ docker tag [SRC REPOSITORY]:[SRC TAG] [DST REPOSITORY]:[DST TAG] $ docker rmi [SRC IMAGE ID] # コンテナをファイル出力 $ docker export [CONTAINER ID] > [DST].tar # ファイルからコンテナを作成 $ cat [SRC].tar | docker import - [REPOSITORY]:[TAG]
- 投稿日:2019-05-29T18:04:18+09:00
docker runコマンドでhoge && tail -f hoge.logでゾンビコンテナになる
概要
dockerコンテナを永続化する方法としてRUNコマンドに
hoge & tail -f hoge.log
のようにしているならば要注意です!
場合によってはゾンビコンテナになります!
なぜそうなるのかというと、メインプロセス(フォアグラウンドプロセスでも)が異常終了してもtail
コマンドが正常である限り、そのまま稼働し続けるからです!
restart policyが定義されていても期待した動作にならないでしょう!検証方法
例として、RUNコマンドで
hoge && tail -f hoge.log
が定義されているとする。
hogeプロセスをkillしてみてください!
tail -f hoge.log
だけを実行するゾンビコンテナの出来上がりです!対策法
監視システムが導入されているならば、メインプロセスの状態を監視して異常時に自動起動するような仕組みを導入する。
他にいい方法があればご教授ください!
- 投稿日:2019-05-29T18:04:18+09:00
docker runコマンドでhoge && tail -f hoge.logでゾンビになる
概要
dockerコンテナを永続化する方法としてRUNコマンドに
hoge & tail -f hoge.log
のようにしているならば要注意です!
場合によってはゾンビコンテナになります!
なぜそうなるのかというと、メインプロセスが異常終了してもtail
コマンドが正常である限り、そのまま稼働し続けるからです!
restart policyが定義されていても期待した動作にならないでしょう!検証方法
例として、RUNコマンドで
hoge && tail -f hoge.log
が定義されているとする。
hogeプロセスをkillしてみてください!
tail -f hoge.log
だけを実行するゾンビコンテナの出来上がりです!対策法
監視システムが導入されているならば、メインプロセスの状態を監視して異常時に自動起動するような仕組みを導入する。
他にいい方法があればご教授ください!
- 投稿日:2019-05-29T17:41:35+09:00
Dockerfileを楽に作りたい
この記事には修正版があります.そちらをご覧ください. -> https://qiita.com/RyodoTanaka/items/c7e4889a1b9383291799
2019.05.29時点で下記手順でうまく行かない事を確認しました...orz -> 修正しました(2019.05.30)
修正版を作りました.
https://qiita.com/RyodoTanaka/items/c7e4889a1b9383291799
表題のとおりです.
Dockerfileを楽に作りたいなぁと思った時,どうやりますか?
私は下のような手順で出来るといいなと思ってます.
- Docker image の実行
- 環境構築
- imageからDockerfileを作成
1. Docker image の実行
例えば,
Ubuntu 16.04
をベースにしたいなと思ったとき,まずはimageを引っ張ってきますよね.$ docker pull <image repository name>
でもってPullが完了したら,そいつを実行します.
$ docker run -it <image name>2. 環境構築
実行してるcontainer内で色々環境構築します.
具体的に何をするかは皆様お好きに!
環境構築が終わったらexit
コマンドとか使って終了します.3. containerからimageを作成する
まずはcontainer 情報を下記コマンドで確認します.
ここからDockerfileを作りたいcontainer IDか名前を取得します.$ docker ps -aそしたら,下記コマンドで希望のcontainerを任意の名前のimageにします.
$ docker container commit <container ID> <image name>
一応作成し終わったら,下記コマンドでimageがちゃんと作られてるか確認します.
$ docker images
4. imageからDockerfileを作成
はい.やっと本記事のミソですね.
適当にぐぐったところ,海外の方が神bashをアップしてくださってました.
やっぱりStack Overflow なしでは生きていけません.
https://stackoverflow.com/a/50926503$ docker history --no-trunc <image name> | tac | tr -s ' ' | cut -d " " -f 5- | sed 's,^/bin/sh -c #(nop) ,,g' | sed 's,^/bin/sh -c,RUN,g' | sed 's, && ,\n & ,g' | sed 's,\s*[0-9]*[\.]*[0-9]*[kMG]*B\s*$,,g' | head -n -1ただ,こいつ長いですよね.
なので,dfimage
というコマンドを作りました.
https://github.com/RyodoTanaka/.bash_extend/blob/master/dfimage.bash
こいつを.bashrc
で読み込んでやれば,$ dfimage <image name>
とするだけで,Dockerfileを標準出力に出力してくれます.
なのでUNIX系使いの方であれば$ dfimage <image name> > Dockerfileとすれば自動でDockerfileが出来上がります!
まとめ
というわけで,
dfimage
コマンドを作って簡単にDockerfileが作成できるようにしました.
これでDocker Hubにイメージをアップしまくれますね!!!
- 投稿日:2019-05-29T17:41:35+09:00
Dockerfileを楽に作りたい(imageから自動生成したい)
この記事には修正版があります.そちらをご覧ください. -> https://qiita.com/RyodoTanaka/items/c7e4889a1b9383291799
2019.05.29時点で下記手順でうまく行かない事を確認しました...orz -> 修正しました(2019.05.30)
修正版を作りました.
https://qiita.com/RyodoTanaka/items/c7e4889a1b9383291799
表題のとおりです.
Dockerfileを楽に作りたいなぁと思った時,どうやりますか?
私は下のような手順で出来るといいなと思ってます.
- Docker image の実行
- 環境構築
- imageからDockerfileを作成
1. Docker image の実行
例えば,
Ubuntu 16.04
をベースにしたいなと思ったとき,まずはimageを引っ張ってきますよね.$ docker pull <image repository name>
でもってPullが完了したら,そいつを実行します.
$ docker run -it <image name>2. 環境構築
実行してるcontainer内で色々環境構築します.
具体的に何をするかは皆様お好きに!
環境構築が終わったらexit
コマンドとか使って終了します.3. containerからimageを作成する
まずはcontainer 情報を下記コマンドで確認します.
ここからDockerfileを作りたいcontainer IDか名前を取得します.$ docker ps -aそしたら,下記コマンドで希望のcontainerを任意の名前のimageにします.
$ docker container commit <container ID> <image name>
一応作成し終わったら,下記コマンドでimageがちゃんと作られてるか確認します.
$ docker images
4. imageからDockerfileを作成
はい.やっと本記事のミソですね.
適当にぐぐったところ,海外の方が神bashをアップしてくださってました.
やっぱりStack Overflow なしでは生きていけません.
https://stackoverflow.com/a/50926503$ docker history --no-trunc <image name> | tac | tr -s ' ' | cut -d " " -f 5- | sed 's,^/bin/sh -c #(nop) ,,g' | sed 's,^/bin/sh -c,RUN,g' | sed 's, && ,\n & ,g' | sed 's,\s*[0-9]*[\.]*[0-9]*[kMG]*B\s*$,,g' | head -n -1ただ,こいつ長いですよね.
なので,dfimage
というコマンドを作りました.
https://github.com/RyodoTanaka/.bash_extend/blob/master/dfimage.bash
こいつを.bashrc
で読み込んでやれば,$ dfimage <image name>
とするだけで,Dockerfileを標準出力に出力してくれます.
なのでUNIX系使いの方であれば$ dfimage <image name> > Dockerfileとすれば自動でDockerfileが出来上がります!
まとめ
というわけで,
dfimage
コマンドを作って簡単にDockerfileが作成できるようにしました.
これでDocker Hubにイメージをアップしまくれますね!!!
- 投稿日:2019-05-29T16:35:15+09:00
Docker on Storybook@Vueを最小構成で動かす
何時もの備忘録として
- docker-compose runの仕様にはまった
まずはチュートリアル通りに動かす
こちらを参照に進める
docker-compose.ymlの準備
version: '3' services: node: image: node:12.3.1-alpine volumes: - ./:/app working_dir: /app ports: - 9001:9001モジュールをインストール
docker-compose run node npm init docker-compose run node npm install @storybook/vue --save-dev docker-compose run node npm install vue --save docker-compose run node npm install vue-loader vue-template-compiler @babel/core babel-loader babel-preset-vue --save-devpackeage.jsonの編集
以下を追加
packeage.json{ "scripts": { "storybook": "start-storybook --ci -p 9001 -c .storybook", } }設定ファイルを作成
.storybook/config.jsを作成 .storybookディレクトリに注意
storybook/config.jsimport { configure } from '@storybook/vue'; function loadStories() { require('../stories/index.js'); } configure(loadStories, module);./stories/index.jsを作成
index.jsimport Vue from 'vue'; import { storiesOf } from '@storybook/vue'; import MyButton from '../components/Button'; storiesOf('Button', module) .add('with text', () => '<my-button>with text</my-button>') .add('with emoji', () => '<my-button>? ? ? ?</my-button>') .add('as a component', () => ({ components: { MyButton }, template: '<my-button :rounded="true">rounded</my-button>' }));./components/Button.vueを作成
Button.vue//何でもいいので作る <template> <button @click="hello">hello</button> </template> <script> export default { methods: { hello: e => { alert('hello'); } } } </script>そして
docker-compose run run node run storybookでブラウザが開かない。。。
docker-compose runの仕様でそのままだとportsのマッピングが効かない。知らなかった。。。
気を取り直して
docker-compose run --service-ports node npm run storybooklocalhost:9001でStorybookが確認できる
参考
- 投稿日:2019-05-29T14:56:57+09:00
Spring Boot� / Thymeleafの基礎を学ぶ【初心者向け】
はじめに
この記事は社内でSpring Boot(実質的にはSpring?)の勉強会を行うにあたり作成した資料となります。
1時間程度で済む簡単なものになっています。
「Spring Bootってこんな感じなんだ」ということが少しでも伝われば幸いです。
なお、私自身Spring並びにSpring Boot初心者なため、記事に誤っている点があるかもしれません。
その際はご指摘いただけますと幸いです。環境
- Mac
- Spring 2.0.2
- Dokcer for Mac
- Gradle 5.2.1
- VSCode
※Eclipseでええやん!って人はDockerじゃなくても○。
※Gradleについては以下の記事が分かり易かったです。
→ 多分わかりやすいGradle入門
Gradle入門Springについて
強み
- 変更に強い
- DI(Dependency Injection)という仕組みが導入されている。
- それぞれが独立しているため依存度が低く、変更に強い。
- 拡張性が高い
- 基本的な機能の大部分が
インターフェース
として提供されている。- 必要な部分は簡単に追加できる。
- 保守性が高い
AOP(アスペクト指向プログラミング)
を用いることができる。
- 共通のプログラムを再利用することでコーディング量減・修正も簡単
- テストが簡単
Spring MVC Test
という専用のテストプログラムで結合テストが簡単にできる。- 大規模データベース
NoSQL
に対応弱み
- フレームワークの規模が大きく、全体を把握するのが難しい。
- DIコンテナの正しい使い方が難しい
- 日本語のドキュメントが乏しい
じゃあSpring Bootって何?
WEBアプリケーションに特化した「Spring MVC」というフレームワークの完成形として、Spring MVCやその他のSpring Frameworkのライブラリ類をいい感じに組み合わせたWebアプリケーション環境を簡単に構築するライブラリです。
【参考: [Java] Spring BootでHello World!(入門編)】
その特徴を簡単にまとめると、
1.アノテーションを記述するだけで実装できる機能が多数あり、コード量を削減できる
2.Webコンテナをjarに内蔵することで、jar単体でWebアプリケーションが実行できる
3.今までのSpringフレームワークでは必須だった、XML設定ファイルが不要になった
4.Spring Initializrというプロジェクト雛形生成サービスがあり、一から開発する必要がないなどなど様々な高速システム開発のための機能が提供されています。
【[Java] Spring Bootで簡単・高速にWebAPI開発】
下準備
- Docker for Macをインストールし、
docker
コマンドが打てることを確認する。- 以下のコマンドを実行する。
$ git clone https://github.com/miwa0519/spring-boot.git $ cd spring-boot/spring_boot_docker/
- 以下のコマンドを実行。
- Tomcatが8080ポートで動く。
- 3000番ポートは人気者だから別ポートがいい、という場合は
docker-compose.yml
内の3000部分を別の番号に変えるといい。- Springが上手く動いていればコンソールに
Spring>>>
みたいな例のAAが出る。出ると少しテンションが上がる。$ docker build -t spring-docker ./ $ docker run -p 3000:8080 spring-docker
- http://localhost:3000 にアクセスする。(3000は任意のポートに変えていい)
今回のサンプルだと、ソースコードを編集する度に上記コマンドを実行する必要があります。
今後改善予定です。面倒臭くてすみません
- ※こちらは必要な人のみ
- こちらの記事 でVSCode向けのプラグインを取り纏めてくださっています。
import
とか手入力してられるかよ!という人にはオススメです。とりあえずHello Worldしてみる
src/main/java/com/example/demo
直下にHelloController.java
を作成します。
HelloController.java
内に以下のソースを記述します。src/main/java/com/example/demo/HelloController.javapackage com.example.demo; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello") public String hello() { return "Hello World!"; } }http://localhost:3000/hello
にアクセスするとHello World!
と表示されていると思います。アノテーションが二つ出てきました。これらが何をしているかを簡単に説明します。
@RestController
:RestControllerアノテーションをつけると、このコントローラーがWebアプリケーション
のリクエストを受け付けるRestコントローラー
になる。@RequestMapping
:RequestMappingアノテーションをつけると、ルーティングを行なってくれる。今回でいうと、http://localhost:3000/hello
にアクセスするとHello
メソッドを実行する、という紐付けが行われる。これらが使えるように、それぞれのクラスをインポートしてます。インポート出来ていないとコンパイルエラーになるので気をつけてください。
もう少しWebアプリらしく
Hello World!
したいので、今度はテンプレートを作ってみたいと思います。Viewの部分を実装する
Spring Bootでは1.2以降はJSPが非推奨とされています。
なので今回はThymeleaf
というテンプレートエンジンを使います。
Spring BootではThymeleaf
を使うのが無難らしいです。Thymeleafを使えるように設定する
設定をしないとThymeleafは使えません。
build.gradle
を以下のように書き換えてください。build.gradle// 中略 dependencies { + compile('org.springframework.boot:spring-boot-starter-thymeleaf') implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' }
実際にHTMLを書いてみる
Thymeleafの設定ができたので、実際にHTMLを書いてViewを実装していきます。
src/resources
直下にtemplates
ディレクトリを用意し、hello.html
ファイルを作成します。src/main/resources/templates/hello.html<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Thymeleaf</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p th:text="'Hello Wonderful World!'" /> </body> </html>※
th:text
はThymeleaf
の属性。Thymeleafの記述については以下が分かりやすかったです。
[Java] Spring BootでThymeleafを使ってみよう!(応用編)HelloControllerを修正する
テンプレートを用意したので、今度はコントローラーがそのテンプレートを呼び出してくれるように修正します。
HelloController.javapackage com.example.demo; import org.springframework.web.bind.annotation.RequestMapping; - import org.springframework.web.bind.annotation.RestController; + import org.springframework.stereotype.Controller; + import org.springframework.web.bind.annotation.RequestMethod; - @RestController + @Controller public class HelloController { @RequestMapping("/hello") public String hello() { - return "Hello World!" + return "hello"; } }
@RestController
を@Controller
に変更しました。
これにより、WebAPIとして機能していたHelloController
がMVC
のC
として振る舞うようになります。
それにより、return
の部分に記載したhello
をViewResolver
がView名として認識し、実際のファイル名に変換し、クライアントに返却します。最初のコマンドを再度実行した後に
http://localhost:3000/hello
をリロードします。テンプレートが呼び出されて、表示される文言が変わっていることが確認できると思います。簡単な計算アプリを作ってみる
MVCのVとCについてはここまでで学ぶことが出来ました。
最後にModelについての説明を加えながら、与えた数字を元に足し算を行ってくれる簡単なアプリを作成したいと思います。Model作ってみる
まず、フォームの値を受け取って計算するためのモデルを作成します。
Controllerを作成したディレクトリの中にmodel
ディレクトリを作成し、その中にForm.java
を作成します。src/main/java/com/example/demo/model/Form.javapackage com.example.demo.model; public class Form { private int num1 = 0; private int num2 = 0; private int total = 0; public int getNum1(){ return num1; } public void setNum1(int num){ this.num1 = num; } public int getNum2(){ return num2; } public void setNum2(int num){ this.num2 = num; } public int getTotal(){ return total; } public void setTotal(int total){ this.total = total; } public void sumTotal(){ total = this.num1 + this.num2; setTotal(total); } }入力値を保持する
num1
、num2
と合計値を保持するtotal
フィールドを作成し、それぞれにgetter
とsetter
を定義します。
また、num1
とnum2
の合計を算出するsumTotal
メソッドを定義しておきます。入力フォームを表示する
modelを定義したので、次は入力フォームを表示してみます。
まず、入力フォームを表示するためのコントローラーを定義します。src/main/java/com/example/demo/CalculateController.javapackage com.example.demo; import com.example.demo.model.Form; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @Controller public class CalculateController { @RequestMapping("/calculate") public String form(Model model){ model.addAttribute("form", new Form()); return "index"; } }今までの
Controller
と違うところは、メソッドにModel
型のオブジェクトを引数に取っているところです。
このModel
に値をセットすることでHTMLに値を渡す事が出来ます。(Springが用意してくれているクラス)
model.addAttribute("form", new Form())
の部分で、model
に対し、Formインスタンスを渡しています。model.addAttribute("変数名", オブジェクト)※ちなみに、第2引数に
Form form
と記述しても同じ意味になります。(裏で
addAttribute
と同じことが実行されるイメージ)【参考:【Spring Boot】ModelクラスとModel And Viewクラス】
form
メソッドではindex
というテンプレートを最後に返しています。
今度はindex
テンプレートを作成し、入力画面を作成します。入力画面を作る
src/main/resources/templates/index.html<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Index</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <h1>Form</h1> <form action="#" th:action="@{/result}" th:object="${form}" method="post"> <p>first number: <input type="number" th:field="*{num1}" /></p> <p>Second number: <input type="number" th:field="*{num2}" /></p> <p><input type="submit" value="calculate" /></p> </form> </body> </html>最初に作った
hello.html
と異なるところは、th:action
、th:object
、th:field
という属性が出てきている点です。
なんとなく見た目で伝わるかと思いますが、簡単に使い方だけご紹介します。
th:action th:object th:field="*{フィールド名}" フォームのアクションを指定する ${}で指定したオブジェクトにフォームで入力した値が入る。 th:objectで指定しているオブジェクトのフィールドに対して入力された値を入れる。 【参考: [Spring Boot でフォームの値を取得して操作] 】(https://qiita.com/NariseT/items/172ca093364aa9391989)
各テキストエリアに入力された値は、先ほどコントローラーで
Model
オブジェクトに追加したForm
インスタンスの各フィールドに値がセットされます。http://localhost:3000/calculate
にアクセスすると入力フォームが表示されるはずです。Controllerを修正する
今度はフォームで入力した値を受け取り、計算を行い、その結果を画面に表示できるようにします。
まずはコントローラーに新しいメソッドを追加します。src/main/java/com/example/demo/CalculateController.javapackage com.example.demo; import com.example.demo.model.Form; // 中略 import org.springframework.ui.Model; + import org.springframework.web.bind.annotation.RequestMethod; + import org.springframework.web.bind.annotation.ModelAttribute; @Controller public class CalculateController { @RequestMapping("/calculate") public String form(Model model){ model.addAttribute("form", new Form()); return "index"; } + @RequestMapping(value="/result", method = RequestMethod.POST) + public String result(@ModelAttribute Form form, Model model){ + form.sumTotal(); + model.addAttribute("form", form); + return "result"; + } }
@RequsetMapping
は今回パラメータを受け取るので、HTTPメソッドを指定します。
method = RequestMethod.post
と記載することでこれはPOSTだよ!と指定できます。
また今回はメソッドの引数に@ModelAttribute
というアノテーションがついています。このアノテーションをつけるとinput
の値を受け取ることが出来ます。
form
の各フィールドには入力フォームで入力された値がセットされている状態なので、Form
クラスで定義したsumTotal
メソッドを呼び出し、form
のtotal
フィールドに合計値を保持させます。その結果を
result
テンプレートに表示させたいので、今度はresult
テンプレートを作成します。計算結果を画面に表示する
templates
ディレクトリ直下に以下のファイルを作成してください。src/main/resources/templates/result.html<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Result</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <h1>Result</h1> <p th:text="'Answer: ' + ${form.getTotal()}" /> <a href="/calculate">Calculate Another number</a> </body> </html>
${}
で式展開を行なってくれるので、getterを使っての合計値を取得し、表示します。計算実行結果は以下です。
最後に
私自身がSpring Bootについて初歩的な部分を学んで感じたのは以下の三点です。
- 面倒な設定が少なく、すぐに開発に取りかかれた。(Dockerで動かすのが大変だったくらい)
- ソースコードが割と直感的に書ける
- 自分の求めているドキュメントに辿り着くまでの時間が壮大(自分の調べ方が下手なだけかも)
とはいえ私自身、初歩的な部分しかまだ分からない状況なので、今後も少しずつ学んでいけたらと思っております。
この記事がSpring Boot、Spring初心者の何かの皆さんの役に立てば幸いです。参考
- Docker+Spring-boot事始め 環境構築でお世話になりました。プロジェクトを作るところからやってみたい方におすすめ
- エンジニア志望者必見のSpring Frameworkとは
- Spring Boot でフォームの値を取得して操作 フォームってどうやって書くんだ?という時に凄く助かりました。
- 多様化するJavaのフレームワーク問題を解決する、「Spring Boot」とは?
- 投稿日:2019-05-29T14:31:40+09:00
オフラインUbuntuで機械学習やKaggle用環境構築(Docker)
オフライン環境で辛い中、頑張ってUbuntuの環境構築をしましょうシリーズの続き。今回はdockerで機械学習用の基礎環境を構築する。
前回はこちら(オフライン環境でapt install:Dockerをインストール)
https://qiita.com/tetrar124/items/40fd9b1ff5f0b015a6da各ステップ
1. オンライン環境でビルドして必要なパッケージを追加したkaggleイメージを作成
2. イメージをアーカイブ化後、オフライン環境へコピー
3. docker-compseで必要な設定を追加して完成※注意点
kaggle-pythonコンテナは現時点でGPU非対応。
https://github.com/Kaggle/docker-python
GPUを使う際はtensorflowコンテナなど、別なコンテナを選ぶ必要がある。1. オンライン環境でkaggleコンテナに必要なパッケージを追加
下記のDockerfileを作成する。
Dockerfile
# kaggleのpythonコンテナを使用 FROM gcr.io/kaggle-images/python:latest # パッケージの追加 RUN pip install -U pip && \ pip install fastprogress japanize-matplotlib今回はオフライン環境なのでlatestに指定したが、オンラインの場合はバージョンを指定するのが好ましい。
バージョンは下記サイトで調査可能(2019/5/29現在はv56が最新)。Google container Registryのkaggle pythonレポジトリ
https://console.cloud.google.com/gcr/images/kaggle-images/GLOBAL/python$sudo docker load < pythonLocal.tar $docker-compose up --buildDockerfileを用いてビルドし、local/kaggleイメージを作成する。Dockerfileのあるフォルダで下記を実行。
$ sudo docker build ./ -t local/kaggle2. 作成したイメージをアーカイブ化後、オフライン環境へコピー
$ sudo docker save local/kaggle > kaggle.tarkaggle.tarファイル(15G!)をオフライン環境へ頑張ってコピーする。
(NIC二枚刺しにしてオフライン装置へ接続、scpが楽)オフラインUbuntuのコピーしたファイルのあるフォルダで下記を実行し、イメージをロードする。
$ sudo docker load < kaggle.tar3. docker-compseで必要な設定を追加して完成
Dockerfile
FROM local/kaggledocker-compose.yaml
version: "2" services: jupyter: build: . volumes: - ~/tmp:/tmp/working working_dir: /tmp/working ports: - 1234:8888 command: jupyter notebook --ip=0.0.0.0 --allow-root --no-browser --NotebookApp.token=''※ Ubuntuのdocker-composeはvesion: "2" にしないとエラーが出る
- portsの項目は、コンテナのポート8888をlocalhostの1234に転送する設定。
- volumesの
- ~/tmp:/tmp/working
は、Dockerのホストマシン(今回はオフライン環境Ubuntu)の~/tmpフォルダをコンテナの/tmp/workingとして共有する設定。今回は~/tmpファイルのセーブ先、必要なファイルを入れる共有フォルダとして使用する。- ローカルネットを想定しているため
--NotebookApp.token=''
のオプションで認証を回避した。下記コマンドでコンテナが起動する。
$ docker-compose up buildブラウザに
localhost:1234
と入れる事でJupyter notebookにアクセスできる。ネットワーク内の場合は、ブラウザに
dockerを動かすホストマシンIPのアドレス:1234
と入れる事でリモートアクセスできる。※事前にdockerを動かすマシンを下記コマンドでポート開放すること。
(fromオプションでローカルのみにした方が安全)$ sudo ufw allow from 192.168.0.0/24 to any port 12344. GPU用の設定インストール
参考
- 投稿日:2019-05-29T12:10:23+09:00
Docker Scratch
scratchのDocker
前の記事では、「FROM scratch」からDockerfileを書き、それに「alpine-minirootfs」を追加して始めました。
では、「FROM scratch」の状態でどんな感じなんでしょう。まず、busyboxを用意します。以下の内容としました。
6c82cf6b59b1:/tmp$ tar tvf busybox-1.30.1.tar.gz drwxr-sr-x build/build 0 2019-05-29 00:52 bin/ -rwxr-xr-x build/build 833104 2019-05-29 00:37 bin/busybox drwxr-sr-x build/build 0 2019-05-29 00:44 lib/ -rwxr-xr-x build/build 584304 2019-05-29 00:44 lib/ld-musl-x86_64.so.1これを用いて、Dockerfileを作ります。
FROM scratch ADD busybox-1.30.1.tar.gz / CMD ["/bin/busybox","sh"]では、動かしてsys/proc以外をリストしてみましょう。
/ # /bin/busybox ls -l bin dev etc lib bin: total 816 -rwxr-xr-x 1 1000 1000 833104 May 29 00:37 busybox dev: total 0 crw--w---- 1 0 5 136, 0 May 29 01:04 console lrwxrwxrwx 1 0 0 11 May 29 01:00 core -> /proc/kcore lrwxrwxrwx 1 0 0 13 May 29 01:00 fd -> /proc/self/fd crw-rw-rw- 1 0 0 1, 7 May 29 01:00 full drwxrwxrwt 2 0 0 40 May 29 01:00 mqueue crw-rw-rw- 1 0 0 1, 3 May 29 01:00 null lrwxrwxrwx 1 0 0 8 May 29 01:00 ptmx -> pts/ptmx drwxr-xr-x 2 0 0 0 May 29 01:00 pts crw-rw-rw- 1 0 0 1, 8 May 29 01:00 random drwxrwxrwt 2 0 0 40 May 29 01:00 shm lrwxrwxrwx 1 0 0 15 May 29 01:00 stderr -> /proc/self/fd/2 lrwxrwxrwx 1 0 0 15 May 29 01:00 stdin -> /proc/self/fd/0 lrwxrwxrwx 1 0 0 15 May 29 01:00 stdout -> /proc/self/fd/1 crw-rw-rw- 1 0 0 5, 0 May 29 01:00 tty crw-rw-rw- 1 0 0 1, 9 May 29 01:00 urandom crw-rw-rw- 1 0 0 1, 5 May 29 01:00 zero etc: total 12 -rw-r--r-- 1 0 0 13 May 29 01:00 hostname -rw-r--r-- 1 0 0 174 May 29 01:00 hosts lrwxrwxrwx 1 0 0 12 May 29 01:00 mtab -> /proc/mounts -rw-r--r-- 1 0 0 101 May 29 01:00 resolv.conf lib: total 572 -rwxr-xr-x 1 1000 1000 584304 May 29 00:44 ld-musl-x86_64.so.1 / #最低限のデバイスのみですね。
busybox:muslのmusl/Dockerfileも見てみます。FROM scratch ADD busybox.tar.xz / CMD ["sh"]上に書いたのと同じようなことをやっていますね。
変更履歴
(2019/5/30) shのリンクを削除し、busyboxを使用する変更
- 投稿日:2019-05-29T11:46:33+09:00
docker unity
dockerでunityを動かしたく調べ始める。
UnityEditorのバージョン管理をしたい
https://qiita.com/Sashimimochi/items/06c136487b8150e35ed0最近流行りのDockerを使ってUnityを動かせないかと思いました。結論から言うとおすすめしません。それでも、供養の意味も込めて検討記録ということで長くはなりますが、それでもいいよという心優しい方はお付き合いください。
nenadg/docker-unity3d
https://github.com/nenadg/docker-unity3d条件
Unityをhostに導入するのは嫌。
dockerの外でcompileするのは嫌。
dockerの中でcompileするのはOK.例
gableroux/unity3d
https://hub.docker.com/r/gableroux/unity3d/unity3d
https://gitlab.com/gableroux/unity3d$ docker run -it --rm -v "$(pwd):/root/project" gableroux/unity3d:latest xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' /opt/Unity/Editor/Unity -projectPath /root/project Unable to find image 'gableroux/unity3d:latest' locally latest: Pulling from gableroux/unity3d 6abc03819f3e: Pulling fs layer 05731e63f211: Pulling fs layer 0bd67c50d6be: Pulling fs layer e59bcdf9f569: Waiting b71d75459548: Waiting ea0a10bb716a: Waiting docker: error pulling image configuration: Get https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/44/44cfb41a0d6ce87f3bf9019a7ed4b40aa20c23d390f0515756c8d07200623b5a/data?verify=1559100714-PcoiRlJ4gKyKppTu7hxHitXjGqs%3D: Service Unavailable. See 'docker run --help'.「-v "$(pwd):/root/project"」 を外すと作業を始めた。意味があるかどうかは後で検討。
$ docker run -it --rm gableroux/unity3d:latest xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' /opt/Unity/Editor/Unity -projectPath /root/project Unable to find image 'gableroux/unity3d:latest' locally latest: Pulling from gableroux/unity3d 6abc03819f3e: Pull complete 05731e63f211: Pull complete 0bd67c50d6be: Pull complete e59bcdf9f569: Pull complete b71d75459548: Pull complete ea0a10bb716a: Pull complete Digest: sha256:b84f59091450b89314591dd9e1f51f6aceaf34994b82a7f282b32612b4c36837 Status: Downloaded newer image for gableroux/unity3d:latestここでプロンプトが出ずに止まった。
/bin/bashの指定がないため当たり前かも。-vの意味を調べる。
やる前に調べろって? ごめんなさい。 DoCAP。
Dockerのすべてが5分でわかるまとめ!(コマンド一覧付き)
https://paiza.hatenablog.com/entry/docker_introhttps://docs.docker.com/engine/reference/commandline/run/
--volume , -v Bind mount a volume
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1f80fb69bfa2 gableroux/unity3d:latest "xvfb-run --auto-ser…" 7 minutes ago Up 7 minutes priceless_ramanujan 2e7d55f97935 kaizenjapan/100pon "/usr/bin/tini -- /b…" 4 months ago Up 4 months mystifying_roentgen KM-S10:~ administrator$ docker stop 1f80fb69bfa2 1f80fb69bfa2$ docker run -it --rm -v "/root/project" gableroux/unity3d:latest xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' /opt/Unity/Editor/Unity -projectPath /root/project$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 54aa8c924989 gableroux/unity3d:latest "xvfb-run --auto-ser…" About a minute ago Up About a minute sleepy_rosalind 2e7d55f97935 kaizenjapan/100pon "/usr/bin/tini -- /b…" 4 months ago Up 4 months mystifying_roentgen
- 投稿日:2019-05-29T11:46:05+09:00
Pleromaのユーザ管理コマンドが変わってた
環境
HostPC Win10
- VirtualBoxのCentOS7の中にDockerを入れて
- angristan/docker-pleroma を使ってDockerで建てました
README.mdのままで動きますので、立てる手順は端折ります。
User management
コンテナの中に入って
docker-compose exec web /bin/shmix なんとかかんとかシリーズがcould not be found
** (Mix) The task "register_user" could not be found ** (Mix) The task "set_moderator" could not be found ** (Mix) The task "generate_password_reset" could not be foundAdmin tasksを参照
- mix help pleroma.user で一覧表示されました。
## Create a new user. mix pleroma.user new NICKNAME EMAIL [OPTION...] Options: • --name NAME - the user's name (i.e., "Lain Iwakura") • --bio BIO - the user's bio • --password PASSWORD - the user's password • --moderator/--no-moderator - whether the user is a moderator • --admin/--no-admin - whether the user is an admin • -y, --assume-yes/--no-assume-yes - whether to assume yes to all questions ## Generate an invite link. mix pleroma.user invite [OPTION...] Options: • --expires_at DATE - last day on which token is active (e.g. "2019-04-05") • --max_use NUMBER - maximum numbers of token uses ## List generated invites mix pleroma.user invites ## Revoke invite mix pleroma.user revoke_invite TOKEN OR TOKEN_ID ## Delete the user's account. mix pleroma.user rm NICKNAME ## Delete the user's activities. mix pleroma.user delete_activities NICKNAME ## Deactivate or activate the user's account. mix pleroma.user toggle_activated NICKNAME ## Unsubscribe local users from user's account and deactivate it mix pleroma.user unsubscribe NICKNAME ## Create a password reset link. mix pleroma.user reset_password NICKNAME ## Set the value of the given user's settings. mix pleroma.user set NICKNAME [OPTION...] Options: • --locked/--no-locked - whether the user's account is locked • --moderator/--no-moderator - whether the user is a moderator • --admin/--no-admin - whether the user is an admin ## Add tags to a user. mix pleroma.user tag NICKNAME TAGS ## Delete tags from a user. mix pleroma.user untag NICKNAME TAGS ## Toggle confirmation of the user's account. mix pleroma.user toggle_confirmed NICKNAME Location: _build/prod/lib/pleroma/ebin
- 投稿日:2019-05-29T02:13:10+09:00
docker-composeでpythonを立ち上げてみた(Dockerfile)
概要
いろいろとpythonの環境を考えた結果macではdockerを使ったらいいのでは無いかと思い最初から勉強してみた。
参考
dockerで簡易にpython3の環境を作ってみる
docker-compose コマンドまとめ
あと、公式のリファレンスとか
Compose CLI リファレンス
コンテナで Hello worldファイル構成
ファイル一覧├ Dockerfile └ docker-compose.ymlDockerfile
基本的にはpipでインストールするものは最小限のほうが良いとされる。
つまり、何であれ最小構成を心がける。DockerfileFROM python:3.7.3 USER root SHELL ["/bin/bash", "-c"] ENV DEBCONF_NOWARNINGS yes RUN apt-get update && apt-get -y install locales && \ localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 ENV LANG ja_JP.UTF-8 ENV LANGUAGE ja_JP:ja ENV LC_ALL ja_JP.UTF-8 ENV TZ JST-9 ENV TERM xterm RUN apt-get install -y vim less RUN pip install --upgrade pip RUN pip install --upgrade setuptools RUN pip install numpy \ matplotlib \ pandas \docker-compose.yml
docker-compose.ymlversion: '3' services: python3: restart: always build: . container_name: 'python3' working_dir: '/root/dev/' tty: true volumes: - /Users/hoge/dev/python3/:/root/dev/起動
terminal$docker-compose up -d --build停止
terminaldocker-compose down --rmi all
--rmi all
でイメージも含めて削除
dockerは短命であるべきらしい接続
attach
もあるみたいだけど、exit
すると完全にコンテナが停止するらしいので、基本的にはexec
らしいterminal$ docker exec -it python3 bashps
一番上の参考記事を踏襲した感じになっているので、そちらとの差異を見ていただけたらと思います。
基本的にはDockerfileのみが変わっていると思っていただいて。。。。。
あとは、dockerの基本的な考え方が載っているDockerfile を書くベスト・プラクティスを読むと
コンテナはエフェメラルであるべき
Dockerfile で定義されたイメージを使って作成するコンテナは、可能ならばエフェメラル(短命;ephemeral)にすべきです。私たちの「エフェメラル」とは、停止・破棄可能であり、明らかに最小のセットアップで構築して使えることを意味します。
のようにいろいろな指針が載っています。
- 投稿日:2019-05-29T01:36:25+09:00
個人メモ docker
#イメージにリポジトリを追加する
tag
イメージにタグを追加する。
docker tag 元のイメージ名 変えたいイメージ名inspect
コンテナやイメージの詳細を確認できる。
docker inspect イメージ名history
イメージに対してしてきた変更を確認できる。
docker history イメージ名commit
コンテナからイメージを作成できる。
docker commit コンテナ名build
dockerfileからイメージを作成する。
よくわからなかったので加筆します。save
イメージをtarアーカイブとして出力。
よくわからなかったので加筆します。load
saveの出力を復元
よくわからなかったので加筆します。import
コンテナをtarアーカイブとして出力。
よくわからなかったので加筆します。login, logout
自分のdockerアカウントにログイン、ログアウト
pull run
レポジトリからのイメージ取得。
docker pull イメージ名push
レポジトリにイメージを送る。
よくわからなかったので加筆します。search
レポジトリを探す。
docker イメージ名
- 投稿日:2019-05-29T01:09:59+09:00
Docker イメージを ECR に保存して実行する
docker コマンドと aws コマンド (CLI) を使って、手元の Docker イメージを Elastic Container Registry (ECR) に保存して、とりあえずローカルで実行してみます。(2019年5月現在)
- docker コマンド → https://qiita.com/kawanet/items/30c1acd4bc90ee0e535d
- awscli コマンド → Mac なら
brew install awscli
でインストールできる。リポジトリの準備
先に AmazonEC2ContainerRegistryFullAccess 権限のついた IAM ユーザのアクセスキー ID・シークレットアクセスキーを取得しておきます。
# アクセスキー ID export AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxxxxx" # シークレットアクセスキー export AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 東京リージョン export AWS_DEFAULT_REGION="ap-northeast-1" # Docker を認証する → 「Login Succeeded」と表示されれば成功 aws ecr get-login --no-include-email | sh -v # ECR 上にリポジトリを作る aws ecr create-repository --repository-name myalpine # ECR 上にリポジトリを消す aws ecr delete-repository --repository-name myalpineDocker イメージをアップロードする
# 適当なイメージを Docker Hub からダウンロードする docker pull alpine:latest # ローカルのイメージの一覧を確認する docker images # リポジトリにプッシュするイメージにタグを付ける # `xxxxxxxxxxx` の部分は、AWS のアカウント ID です。 # `ap-northeast-1` の部分は、リージョン(東京)です。 docker tag alpine:latest xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myalpine:latest # 間違えたら、タグを消す(リージョンの指定を間違えた等) docker image list docker image rm xxxxxxxxxxx.dkr.ecr.wrong-region.amazonaws.com/myalpine:latest # ECR にイメージをプッシュする。 # 「no basic auth credentials」が出たら認証の問題。リージョンが違うとか。 docker push xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myalpine:latest # プッシュした ECR のイメージを確認する aws ecr list-images --repository-name myalpine # ローカル側のタグをいちど消しておく docker image rm -f xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myalpine:latest # ローカル側のタグが削除されたのを確認 docker image listECR からイメージをダウンロードして実行する
# ECR 上のイメージをそのまま実行してみる docker run -it xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myalpine:latest sh # ECR からイメージをプルする docker image pull xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myalpine:latest # ローカルのイメージが復活したことを確認する docker image list # ECR 上のイメージの削除 aws ecr batch-delete-image --repository-name myalpine --image-ids imageTag=latest # ECR 上のリポジトリの削除 aws ecr delete-repository --repository-name myalpine参考 → https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/ECR_AWSCLI.html
- 投稿日:2019-05-29T00:32:38+09:00
docker-compose でコンテナを起動する
docker-compose を使ってミニマムのコンテナを作って起動してみます。(2019年5月現在)
まず最初に、ディレクトリ名が docker-compose におけるプロジェクト名(Docker コンテナ等の接頭辞)になるので、ディレクトリを作ります。
mkdir myproj cd myprojDockerfile を作ります。
ドキュメント → http://docs.docker.jp/engine/reference/builder.html# 軽量な Alpine Linux をベースにする FROM alpine # ログインしたときに便利なように bash・ps・curl を入れておく。 RUN apk add bash procps curl # 1秒ごとに時刻を STDERR に書き出す CMD sh -c "(while :; do date; sleep 1; done) >&2"docker-compose.yml を作ります。
ドキュメント → https://docs.docker.com/compose/compose-file/compose-file-v2/
なお、tty などのオプションについては、docker 側のドキュメント http://docs.docker.jp/engine/reference/run.html を参照します。docker-compose.ymlversion: "3" services: myalpine: build: "." tty: trueイメージを作ります。
イメージ名は、サービス名の前に、プロジェクト名(ディレクトリ名)が自動で付きます。
プロジェクト名を指定する場合は-p
オプションを指定します。$ docker-compose build Building myalpine Successfully built e4215b22f7c8 Successfully tagged myproj_myalpine:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE myproj_myalpine latest e4215b22f7c8 2 minutes ago 13MBdetach モードで起動します。
$ docker-compose up -d Creating network "myproj_default" with the default driver Creating myproj_myalpine_1 ... doneコンテナ名は、イメージ名の末尾に
_1
が付きます。
起動中のコンテナ・プロセスを確認します。$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cc95a9d44519 myproj_myalpine "/bin/sh -c 'sh -c \"…" 23 seconds ago Up 22 seconds myproj_myalpine_1 $ docker-compose ps Name Command State Ports ------------------------------------------------------------------ myproj_myalpine_1 /bin/sh -c sh -c "(while : ... UpSTDERR 標準エラー出力を確認します。
docker logs
だとコンテナ単位のログを、
docker-compose logs
だとプロジェクト単位のログを確認できます。
-f
はtail -f
と同じ--follow
の意味です。$ docker logs -f myproj_myalpine_1 Tue May 28 15:13:50 UTC 2019 Tue May 28 15:13:51 UTC 2019 Tue May 28 15:13:52 UTC 2019 Tue May 28 15:13:53 UTC 2019 $ docker-compose logs -f myalpine_1 | Tue May 28 15:13:50 UTC 2019 myalpine_1 | Tue May 28 15:13:51 UTC 2019 myalpine_1 | Tue May 28 15:13:52 UTC 2019 myalpine_1 | Tue May 28 15:13:53 UTC 2019稼働中のコンテナにログイン(bash を起動)してみます。
$ docker exec -it myproj_myalpine_1 bash bash-4.4# uname -a Linux cc95a9d44519 4.14.114-105.126.amzn2.x86_64 #1 SMP Tue May 7 02:26:40 UTC 2019 x86_64 Linux bash-4.4# grep PRETTY /etc/os-release PRETTY_NAME="Alpine Linux v3.9" bash-4.4# exitコンテナを
stop
で停止してみます。$ docker-compose stop Stopping myproj_myalpine_1 ... done $ docker ps不要なコンテナを削除して後片付けします。
$ docker image prune -f Total reclaimed space: 0B $ docker image list $ docker image rm myproj_myalpine今回は1サービスのみでしたが、docker-compose を使うと
1プロジェクトで複数のサービスを束ねられます。