- 投稿日:2020-04-26T23:44:14+09:00
OpenProject に Metabase をドッキングしたら最強のダッシュボードが作れるかも
なぜ書いた?
- 趣味で調べたことを職場で参照したい
- もしかすると参考になる人がいるかもしれない
- OpenProject と Metabase の可能性に震えたから
OpenProject の準備
OpenProjectは、場所に依存しないチームコラボレーションのためのWebベースのプロジェクト管理システムです。
まず OpenProject のインストール方法は下記の3つであると公式にあります。
docker(-compose) を使うのが手軽そうなのでこれでやってみます。
- DEB/RPM packages
- 既存のマシンなどへ直接インストール(推奨)
- docker
- docker-compose で起動
- Installation with Univention Corporate Server
- VMイメージを入手
Installing OpenProject | OpenProject Help & Documentation
https://docs.openproject.org/installation-and-operations/installation/docker を使ったインストール方法は下記の2つであると公式にあります。
推奨されている前者の方法でやってみます。
- One container per process
- WebやDBなどの機能ごとにコンテナを分けます(推奨)
- All-in-one container
- 1つのコンテナで全ての機能を賄います
Install OpenProject with Docker | OpenProject Help & Documentation
https://docs.openproject.org/installation-and-operations/installation/docker/とりあえずローカルで試運転する分には上記のページに従って下記のコマンドを打つだけで起動します(簡単!)。ですが Metabase と組み合わせたいので起動の前に
docker-compose.yml
を編集します。# docker-compose.yml などを取得する git clone --depth=1 --branch=stable/10 https://github.com/opf/openproject # docker-compose.yml のあるディレクトリへ移動する cd openproject # デタッチモードで起動 docker-compose up -d
docker-compose.yml
を読み解くと主な要素は下記のように配置されると分かります。
ここへ Metabase を追加してみます。Metabase の準備
メタベースは、社内の誰もが質問したり、データから学んだりするための簡単でオープンソースな方法です。
Metabase を加えて下記の構成となるよう
docker-compose.yml
を編集します。そして出来上がった
docker-compose.yml
がこちら。
docker-compose up -d
で起動させると http://localhost:8080/ に OpenProject が、 http://localhost:3000/ に Metabase が起動します。Metabase の起動が完了するまではしばらく待つかもしれません。version: "3.7" networks: frontend: backend: metabase-backend: volumes: pgdata: opdata: metabase-pgdata: x-op-restart-policy: &restart_policy restart: unless-stopped x-op-image: &image image: openproject/community:${TAG:-10} x-op-app: &app <<: *image <<: *restart_policy environment: - "RAILS_CACHE_STORE=memcache" - "OPENPROJECT_CACHE__MEMCACHE__SERVER=cache:11211" - "OPENPROJECT_RAILS__RELATIVE__URL__ROOT=${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}" - "DATABASE_URL=postgres://postgres:p4ssw0rd@db/openproject" - "USE_PUMA=true" # set to true to enable the email receiving feature. See ./docker/cron for more options - "IMAP_ENABLED=false" volumes: - "opdata:/var/openproject/assets" depends_on: - db - cache x-mb-app: &mb-app image: metabase/metabase <<: *restart_policy environment: - "MB_DB_TYPE=postgres" - "MB_DB_DBNAME=metabase" - "MB_DB_PORT=5432" - "MB_DB_USER=postgres" - "MB_DB_PASS=p4ssw0rd" - "MB_DB_HOST=metabase-db" depends_on: - db - metabase-db services: db: image: postgres:10 <<: *restart_policy stop_grace_period: "3s" volumes: - "pgdata:/var/lib/postgresql/data" environment: - POSTGRES_PASSWORD=p4ssw0rd - POSTGRES_DB=openproject networks: - backend cache: image: memcached <<: *restart_policy networks: - backend proxy: <<: *image <<: *restart_policy command: "./docker/proxy" ports: - "8080:80" environment: - APP_HOST=web - "OPENPROJECT_RAILS__RELATIVE__URL__ROOT=${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}" depends_on: - web networks: - frontend web: <<: *app command: "./docker/web" networks: - frontend - backend worker: <<: *app command: "./docker/worker" networks: - backend cron: <<: *app command: "./docker/cron" networks: - backend seeder: <<: *app command: "./docker/seeder" restart: on-failure networks: - backend metabase-app: <<: *mb-app ports: - "3000:3000" networks: - backend - metabase-backend metabase-db: image: postgres:10 <<: *restart_policy stop_grace_period: "3s" volumes: - "metabase-pgdata:/var/lib/postgresql/data" environment: - POSTGRES_PASSWORD=p4ssw0rd - POSTGRES_DB=metabase networks: - metabase-backendMetabase が起動したら初期設定時に OpenProject の DB を登録してしまいましょう。
「名前」は任意、「データベースユーザー名」と「ポート」は postgres のデフォルトですが、「ホスト」から「データベースパスワード」のその他の項目はdocker-compose.yml
の db サービスの設定から読み取れる内容で埋めます。OpenProject の DB スキーマを紐解く
※ まだあまり紐解けていないので随時更新予定
OpenOroject の Work packages(Redmine におけるチケットに相当する概念) を格納しているテーブルは、Metabase からは Work Packages という名前で見えるようになります(生のSQLで参照する場合は work_packages)。このテーブルには多数の列がありますが下記の列に注目してみます。
- Story Points
- 相対見積もり
- Derived Estimated Hours
- 配下のタスクの見積もりの合計(時間単位)
まず一例としてプロダクトバックログ項目に対して割り当てた相対見積もりと、いざ項目を実行しようとしてタスクへブレークダウンした後の時間見積もりが相関しているかウォッチできる散布図を作ってみました(データが少ないので見栄えしない)。
最終的には99%の確率で納期を守るにはの考え方を使ってプロジェクトの成功率を表示したいと思っています。OpenOroject のタイムトラッキング機能を有効にするとタスクの実行にかかった時間を入力できるようになりますが Work Packages テーブルに直接は反映されないので器用に抽出する必要がありそうです。
- 投稿日:2020-04-26T23:35:40+09:00
Dockerの存在意義とは何か調べてみた(個人的見解も含みます)
この記事の目的
技術的にDockerが使えるようになりたくて先日環境構築をして、「この作業いるのだろうか...というか逆にコンテナ消したり作ったりするから通信量ばかになってなくないか...なんか重いし...」とふと疑問が湧いてきたので調べてみました。
Dockerとは結局何者なのか
非常に軽い仮想環境(バーチャルマシン)です。似たようなものとしてVMware,VirtialBox,bootcampなどがあります。
用途は環境構築(OS)からプロジェクト完成までの変化を記録してくれる、Gitの亜種だと理解するといいそうです。(筆者の感覚だとGitHubの亜種です)
環境構築を多人数で行う時、途中までをpushしておいて、途中から別な人がpullして付け加えていく使い方になります。
docker pull
はgit pull
と同じで差分だけダウンロードされます。Dockerの良さは?
バージョン管理の容易さと環境の準備の容易さ
ローカルの開発環境から独立し、OSの階層からアップロードされたものだけを使うため、gemのバージョンやOSの統一などを一切気にしなくて良くなります。MojaveとCatarinaという違いどころか、Windowsで同じプロジェクトをやっても大丈夫です。
コンテナ化のシステムではダントツ軽い
通常コンテナを使う際にはOSを入れなければいけないのですがdockerだとOSにubuntuを使用すればストレージの使用量が123MBで済むためVMwareやbootcampなどと比べた時圧倒的に仮想環境で使用するストレージ容量が小さいです。bootcampでwindowsを快適に使うには50GBは必要です。
デプロイがわかりやすい
AWSのEC2(Elastic Cloud Container)を使わずdockerで作成し、仮想環境で作ったものをそのままpullすればwebに公開できるのでわかりやすい、らしいです。(未実施なので今後確認します。ただ確かにEC2で作業していた時はコンパイルの問題とアプリケーションの起動の問題で悩まされており、それがDockerfileにRun ~ と書いてあるだけで動くならとても楽だと思います。ちなみに前回はcapistranoという自動デプロイ機能のgemのおかげでなんとか乗り切りました。)
参考
- 投稿日:2020-04-26T23:32:55+09:00
【Docker】基本をざっくりメモ
Dockerとは、、
サーバ環境をパッケージングできる仕組み。
osのバージョンから使用するライブラリ・ミドルウェアの構成等の実行環境をパッケージングすることで固定する。
そうしてDockerで作成された開発環境は配布しやすく、そのパッケージがあれば、環境を作ったり捨てたり(消したり)が簡単にできる。アプリケーション起動・実行までの流れ
1.アプリケーションの環境を Dockerfile ファイルで定義する。このファイルは、どこでも再利用可能。
2.アプリケーションを構成する各サービスを docker-compose.yml ファイルで定義する。そうすることで、独立した環境を一斉に実行できるようにしている。
3.最後に、
docker-compose up
を実行すると、Composeがアプリケーション全体を起動・実行する。Dockerfileで行うこと
(例)FROM ruby:2.5.1-stretch ENV ENTRYKIT_VERSION 0.4.0 WORKDIR /path RUN apt-get update 〜(後略)
- FROMで元にするOS(ベースイメージ)の指定
- ENVで環境変数の指定( の形式)
- WORKDIRでRUN等の命令実行時の作業場所の明示
- RUN apt-getで必要になるライブラリのインストール
などなど、、
docker-compose.ymlで行うこと
(例)version: "3" volumes: mysql_8_0-data: redis-data: vendor_bundle_2_5_1: vendor_assets_2_7: node_modules: services: mysql: image: mysql:8.0 environment: networks: - default ports: - '33306:3306' redis: image: redis:alpine networks: - default app_name: build: context: . dockerfile: Dockerfile.dev depends_on: - mysql - redis networks: - default command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails server -b 0.0.0.0
- versionでdocker-composeの使用バージョンの指定
- servicesでアプリケーションを動かす為の各要素(railsとmysqlとredisと…)を定義。更にそれぞれの設定をその下に記述。
などなど、、docker-compose.ymlの考え方
上述したservicesに記載のある各要素もそれぞれコンテナであり、docker-compose upを行うことで、docker-compose.ymlの内容を元に別々に分かれているコンテナが一つの環境としてまとめられる。
実際のサーバ構築で例えるとすると、rails、mysql、redisがそれぞれ動くサーバを立てる、更にそれぞれがネットワークで繋げるという状況を記述しているイメージ。
参考
終わりに。
転職の為、未経験の状態からRailsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございます。
- 投稿日:2020-04-26T20:42:16+09:00
Docker volume の公式ドキュメントが分かりやすかった話
はじめに
最近、くろかわこうへいさんや、KENTAさんの動画をよく見る中で「あれ、Docker できないのやばくね?」と、ふと思いDocker の学習を始めました。参考書やネットでちょっと調べていくと「あれ、思ってたよりも難しくないじゃん」と思っていた矢先に、volume が出てきて一気につまづきまいした。記事などもいろいろ読んで調べてみたものの、よくわからず挫折しかけていた時に、公式ドキュメントに出会い読んでみると「何これわかりやすいじゃん!」ってなりました(笑)。
ということで、公式ドキュメントを読んで自分なりに理解したことをまとめます。
実行環境
- Windows Home 10
- Docker Toolbox v19.03.1
この記事を読むとわかること
- volume とは
- Dockerをデータの永続化の具体的な方法
- データのマウントの具体的な挙動及び実装方法
- bind mount
- volume
- tmpfs mount
Volume には 2 つの意味がある
後述するが、データを永続化させる方法は
bind mount
とvolume
の2 種類ある。ただ、どちらも-v
や--volume
を使う。つまり、volume という単語には 2 つの意味があることになる。
- データをマウントするための機能(-v, --volume)
- Dockerのリソース内にあるコンテナの実行データを保管する場所
この記事では前者の機能を示す
volume
を データのマウントと定義する。なぜデータのマウントが必要か
そもそもなぜ、データのマウントが必要なのか?
それは、コンテナ内部にデータを保存しても、コンテナ破棄すると消えてしまうため、データを永続化する際は、コンテナの外にデータを置く必要があるため。
データをマウント方法は 3 つ
概要
データのマウント方法は 3 つある。データを永続化させる場合は
Bind mount
かVolume
を使う。
- Bind mount
- Volume
- Tmpfs mount
種類 データの保管場所 永続化 Bind mount ホストディレクトリ ○ Volume Docker のリソース ○ Tmpfs mount メモリ ×
出典:docker docsBind mount
特徴
- ホストディレクトリやファイルがコンテナにマウントされる
- コンテナ内のデータの変更に応じてホスト側のファイルも変更される
用途
- データを永続化させたい
開発環境でホスト側のソースコードの修正を反映させたい
※ 本番環境のイメージではマウントでデータをコンテナに反映させるのではなく、
copy
を使うことが推奨されている。実装方法
-v
または--volume
を使うオプションの設定が 1 つのフィールドに固まっており、コンテナにデータのマウント先のディレクトリがなければ自動的に作成される。
--mount
を使うオプションの設定が複数のフィールドに分かれているコンテナにマウント先のディレクトリが無ければ、エラーを返す。(※筆者の環境ではディレクトリが自動作成された)
例
volume_testディレクトリをマウントしてみる。ディレクトリの中は text.txt のみ。volume_test test.txtテキストファイルの内容。
test.txttestvolume_testディレクトリに移動する。
まずは、
-v
(--volume
)コマンドでカレントディレクトリをubuntu
コンテナ内のすでに存在する/usr/src/var/tmp
にマウントしてみる。> docker run -it --name bindmount -v $(pwd):/usr/src/var/tmp ubuntu bash root@eab26b27a693:/# cd usr/src/var/tmp root@eab26b27a693:/usr/src/var/tmp# ls test.txtきちんと ディレクトリのデータがマウントされていることが分かる。ファイルの内容も
test
からmount success!
に変更してみる。root@eab26b27a693:/usr/src/var/tmp# cat test.txt test root@eab26b27a693:/usr/src/var/tmp# echo mount success! > test.txt root@eab26b27a693:/usr/src/var/tmp# cat test.txt mount success!実際にホスト側のファイルを確認してみると変更が反映されている!
次に、
ubuntu
コンテナ内に存在しない/volume_test
にマウントしてみる。> docker run -it --name bindmount -v $(pwd):/volume_test ubuntu bash root@b3e9bf711b7e:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var volume_test root@b3e9bf711b7e:/# cd volume_test root@b3e9bf711b7e:/volume_test# ls test.txt存在しないディレクトリにマウントした際には新しくディレクトリが作られている。先程と同様にファイルの内容も
test
からmount success!
に変更してみる。root@b3e9bf711b7e:/volume_test# cat test.txt test root@b3e9bf711b7e:/volume_test# echo mount success! > test.txt root@b3e9bf711b7e:/volume_test# cat test.txt mount success!こちらでもホスト側のファイルを確認してみると変更が反映されている!
次に
--mount
コマンドでカレントディレクトリをubuntu
内のすでに存在する/usr/src/var/tmp
にマウントしてみる。-v
とは違いマウントの仕方やホスト側のディレクトリ、マウントのディレクトリといった複数のオプションをカンマつなぎで記述する。> docker run -it --name bindmount --mount type=bind,source="$(pwd)",target=/usr/src/var/tmp ubuntu bash root@f77d388c204e:/# cd usr/src/var/tmp root@f77d388c204e:/usr/src/var/tmp# ls test.txt
--mount
を使った場合でも同様にマウントできた。実際にコンテナ内のファイルを編集した際は上記の内容と同様に、ホスト側のファイルも編集された。次に、
ubuntu
コンテナに存在しないディレクトリ(volume_test
)にマウントしてみる。docker run -it --rm --name bindmount --mount type=bind,source="$(pwd)",target=/volume_test ubuntu bash root@a738ae0ebbd0:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var volume_test
volume_test
が存在している!!! マウントできた!?公式ドキュメントによると、
If you use --mount to bind-mount a file or directory that does not yet exist on the Docker host, Docker does not automatically create it for you, but generates an error.
出典:docker docsつまり、
--mount
を使ってコンテナにバインドマウントする際は、コンテナ内にすでに存在するディレクトリにマウントしないとエラーが出る。なぜできたのだろう??バインドマウントできているか確かめてみる。
root@a738ae0ebbd0:/# cd volume_test/ root@a738ae0ebbd0:/volume_test# cat test.txt test root@a738ae0ebbd0:/volume_test# echo mount sucess! > test.txt root@a738ae0ebbd0:/volume_test# cat test.txt mount sucess!ホスト側のファイルも変更されているので、バインドマウントができている。なぜだろう??
ちなみに
-v
,--mmount
どちらを使ってもマルチコンテナ間でもデータの共有は可能。Volume
特徴
- docker リソース内のデータがコンテナにマウントされる
- ホストディレクトリに依存しない
用途
- データを永続化させたい
- 開発環境でソースコードの修正を反映させる以外の目的
実装方法
bind mount
と同じ。-v
または--mount
を使う。例
まずはvolume_test
という名前のボリュームを作る。$ docker volume create volume_test volume_test $ docker volume ls local volume_testまずは、
-v
(--volume
)コマンドでカレントディレクトリをubuntu
コンテナ内のすでに存在する/usr/src/var/tmp
にマウントしてみる。また、ボリュームが存在しない場合は自動でボリュームが作成される。test.txt
に mount success! と入力してコンテナを閉じる。$ docker run -it --name volume_mount -v volume_test:/usr/src/var/tmp ubuntu bash root@fe23da2e739c:/# cd /usr/src/var/tmp root@fe23da2e739c:/usr/src/var/tmp# ls root@fe23da2e739c:/usr/src/var/tmp# touch test.txt root@fe23da2e739c:/usr/src/var/tmp# echo mount success! > test.txt root@fe23da2e739c:/usr/src/var/tmp# cat test.txt mount success! root@fe23da2e739c:/usr/src/var/tmp# exitコンテナを再度立ち上げて、test.txtが存在するか確認してみる。
$ docker container rm volume_mount volume_mount $ docker run -it --name volume_mount -v volume_test:/usr/src/var/tmp ubuntu bash root@e54d18741135:/# cat usr/src/var/tmp/test.txt mount success!マウントできている!
ubuntu
コンテナに存在しないディレクトリにマウントしても同様の結果が得られる。次に、次に
--mount
コマンドでカレントディレクトリをubuntu
内のすでに存在する/usr/src/var/tmp
にマウントしてみる。先程と同様に、test.txt
に mount success! と入力してコンテナを閉じる。$ docker run -it --name volume_mount --mount source="volume_test",target=/usr/src/var/tmp ubuntu bash root@03074d3166a9:/# echo > usr/src/var/tmp/test.txt root@03074d3166a9:/# cat usr/src/var/tmp/test.txt root@03074d3166a9:/# echo mount success! > usr/src/var/tmp/test.txt root@03074d3166a9:/# cat usr/src/var/tmp/test.txt mount success! root@03074d3166a9:/# exit再度、
volume_test
をマウントしてコンテナを立ち上げる。$ docker run -it --name volume_mount --mount source="volume_test",target=/usr/src/var/tmp ubuntu bash root@9fe26cd9575f:/# cat usr/src/var/tmp/test.txt mount success!マウントできている!
ubuntu
コンテナに存在しないディレクトリにマウントしても同様の結果が得られる。ちなみに
-v
,--mmount
どちらを使ってもマルチコンテナ間でもデータの共有は可能。Tmpfs mount
特徴
- マルチコンテナ間でデータの共有はできない
- コンテナが止まるとホストメモリ上に保存されたファイルは消える
- Docker on Linux でのみ動作する
用途
- 一時的にデータを退避させたい
- セキュリティ的な理由で、ホストディレクトリやDocker リソース内の書き込み可能な領域にファイルを保管したくない
実装方法
-tmpfs
を使うマウントディレクトリ以外のオプションの設定が不可、コンテナにデータのマウント先のディレクトリがなければ自動的に作成される。
--mount
を使うオプションの設定が複数のフィールドに分かれているコンテナにマウント先のディレクトリが無ければ、エラーを返す。
まとめ
- データの永続化の種類は二つ
- bind mount
- volume
それぞれの違いは、永続化データの保存領域。使い分けは、開発においてソースコードの修正をコンテナにも反映させたいといったホストOSのファイルに依存することなら bind mount そうでなければ、volume を使う。
- 一時的にデータを退避させるなら tmpfs mount を使う。
初心者なので、至らぬところはあるかと思いますがご指摘いただいたけると幸いです
参考
- 投稿日:2020-04-26T20:21:55+09:00
AWS X-RayをJavaで色々動かして試してみる
前提条件
X-Ray初心者向け。なんとなくは知ってるけど、具体的に何がどこまでできて、どうやって実装するかを色々試してみながら確認した記事。
環境としては、Spring Boot+MavenでWebアプリを実装している。依存関係の解決方法以外はGradleも同じはず。
X-RayのDockerコンテナイメージを作る。
まずは、適当なEC2とかでコンテナイメージを作る。
今回は、AWSのサンプルをベースに作ってみよう。$ git clone https://github.com/aws-samples/aws-xray-fargatebuildspec.yml に書いてあるコマンドを、実行していってみる。
$ aws ecr get-login --no-include-email --region ap-northeast-1でログイン情報を取得後、実行。
ap-northeast-1
は利用しているリージョンを指定する。$ docker build -t xray:latest .作ったコンテナイメージは正常性確認をしてみよう。以下を参考にする。
それぞれのdocker runのオプションの意味も記載されているので読んでみると良い。$ docker run \ --attach STDOUT \ -v ~/.aws/:/root/.aws/:ro \ --net=host \ -e AWS_REGION=ap-northeast-1 \ --name xray \ -p 2000:2000/udp \ xray -oあと、EC2のロールに
AWSXRayDaemonWriteAccess
のIAMポリシをつけておく。アプリケーションのX-Ray対応
受信リクエスト対応
以下の開発者ガイドを参考にしながら、アプリケーション側でX-Rayのログをデーモンに送るようにする。
受信リクエストの対応をするだけなら簡単なようだ。
WebConfig.java
なクラスを以下の様に実装する。ApigwTest
は、サンプルで作ったWebアプリの名前。WebConfig.javapackage com.example; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import javax.servlet.Filter; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter("ApigwTest"); } }X-RayはAWSのSDKを使う必要があるため、pom.xmlに以下を記述して依存関係を解決する。
pom.xml<dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-bom</artifactId> <version>2.4.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-core</artifactId> </dependency> </dependencies>さて、このアプリを起動してアクセスすると、↓こんな感じでトレースができるようになる。
詳細情報の取得
さらに、受信リクエストを受けたノードの情報を取得できるように、↑で作った
WebConfig
クラスに以下のコードを入れてみる。import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorderBuilder; import com.amazonaws.xray.plugins.EC2Plugin; import com.amazonaws.xray.plugins.ECSPlugin; static { AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()).withPlugin(new ECSPlugin()); AWSXRay.setGlobalRecorder(builder.build()); }これをEC2上で実行した場合は、以下のように、サービスマップにEC2インスタンスであることが表示されるようになる。
ダウンストリームのトレース対応
さらに、HTTPクライアントとして、ダウンストリームのWebサービスの情報も取得する場合は、コントローラの中に↓こんなのを入れてみる。
import com.amazonaws.xray.proxies.apache.http.HttpClientBuilder; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.impl.client.CloseableHttpClient; import java.io.IOException; (中略) public int HttpClient(String URL) throws IOException { int statusCode = 500; CloseableHttpClient httpclient = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet(URL); CloseableHttpResponse clientResponse = httpclient.execute(httpGet); try { statusCode = clientResponse.getStatusLine().getStatusCode(); } finally { clientResponse.close(); } return statusCode; }また、
com.amazonaws.xray.proxies.apache.http.HttpClientBuilder
をインポートするために、pom.xmlにも以下の依存関係を追記する。pom.xml<dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-apache-http</artifactId> </dependency> </dependencies>すると、以下のようにダウンストリームの情報も取得できるようになる。
ちなみに、このダウンストリームのサービスはLambda関数で実装していたので、ふと気になってLambda関数側でX-Rayの設定を有効化すると、↓こんな感じで、重複した要素は取得しなくなった。賢い。
ECS on Fargateで動かす
まずは、ここまでで動作確認したX-RayのコンテナをECRにPUSHする。
事前にxrayのリポジトリを作っておくのを忘れないように。$ docker tag xray:latest [AWSのアカウントID].dkr.ecr.[リージョン].amazonaws.com/xray:latest $ docker push [AWSのアカウントID].dkr.ecr.[リージョン].amazonaws.com/xray:latestまた、ここでもECSのタスクロールとタスク実行ロールに
AWSXRayDaemonWriteAccess
を付与しておく。コンテナのタスク定義に、↑でPUSHしたxrayのイメージを入れる。
CloudFormationテンプレートで言えば、ContainerDefinitions
内で、既存のコンテナ定義に並べて以下の定義を書く。awsvpcを使わないECS on EC2の場合は他にも設定が必要だが、Fargateの場合は、awsvpcで動くので、簡単に加えられるようだ。- Name: X-Ray-Daemon Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/xray:latest Cpu: 32 MemoryReservation: 256 PortMappings: - ContainerPort: 2000 Protocol: udpLambda側のアクティブトレースを有効化すると、EC2と同様に取得することができた。
ただし、Lambda側のアクティブトレースを無効にすると、リクエストに対するトレースは取得できたが、ダウンストリームのトレースが取得できなかった。何かまだ足りていない設定があるのかもしれない。
- 投稿日:2020-04-26T19:36:02+09:00
初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)公開編パート1(NodePort)
背景
個人的にインフラの知識以上にこれからのアプリケーションが動く環境を作ってデプロイしたりしてこれからの知識を身に着けたい。そしてより一層、自分の知識のアップデートをしたいと思いました。
その中でこの本に出会い、これから少しずつやったことを残し、未来の自分への手紙としてもあり、見つめ直せればと思いました。
引用や参考と今回の自分の勉強用の書籍の紹介
技術評論社『Kubernetes実践入門』のサンプルコード
Kubernetes実践入門 プロダクションレディなコンテナ&アプリケーションの作り方
実際の学びについて
書籍を読みながら、章ごとに少しずつ進めていきたいと思います。
GitHub のソースコードも使いながら学んで行きたいと思います。
この章の勉強は本当に書籍の写経が主になるかもしれません・・・勉強開始
- アプリケーションを外部に公開する方法を学びます
- NodePort を使って公開する
- 外部 LoadBalancer を使って公開する
- Ingress を使って公開する
今回は「NodePort を使って公開する」をやっていこうと思います
NodePort を使って公開する
- すべてのノードに同じポートが開放される
- ポートは 3000-32767 までが指定できる
- expose コマンドでも実施できる
範囲外だと下記のようにエラーが出るし、Service でもできることを一旦確認
$ kubectl create service nodeport invalid-nodeport --tcp 8086 --node-port 32768 The Service "invalid-nodeport" is invalid: spec.ports[0].nodePort: Invalid value: 32768: provided port is not in the valid range. The range of valid ports is 30000-32767マニュフェスト作成
Serviceのマニュフェストを作る$ kubectl expose --type NodePort --port 8065 deployment mattermost --dry-run -o yaml > mattermost-service.yamlgitと自分で作成したマニュフェストの差分--- a/ch3.6.1/manifests/mattermost/mattermost-service.yaml +++ b/ch3.6.1/manifests/mattermost/mattermost-service.yaml @@ -3,7 +3,7 @@ kind: Service metadata: creationTimestamp: null labels: - app: mattermost + run: mattermost # コマンドで作成すると run となる name: mattermost spec: ports: @@ -11,7 +11,7 @@ spec: protocol: TCP targetPort: 8065 selector: - app: mattermost + run: mattermost # コマンドで作成すると run となる type: NodePort status: loadBalancer: {}ここは、
app
で実施するように修正するマニュフェストを適用する
マニュフェスト適用$ kubectl apply -f mattermost-service.yaml service/mattermost createdマニュフェストの適用を確認
適用されたマニュフェストの確認$ kubectl get svc mattermost -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR mattermost NodePort 10.108.64.60 <none> 8065:32020/TCP 2m10s app=mattermostアクセス確認
以前は
localhost
で接続していたけど、名前で接続してみたいと思ったので、名前を確認/etc/hosts## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost # Added by Docker Desktop # To allow the same kube context to work on the host and the container: 127.0.0.1 kubernetes.docker.internal # End of section動作確認
次は 3.6.2 章をやっていきます。
写経しながら「外部 LoadBalancer を使って公開する」をやっていきます
最後に
https://github.com/kubernetes-practical-guide/examples/tree/master/ch3.6.1/manifests/mattermost
今回は GitHub のマニュフェストを確認しながら行ったのですが・・・
自分のちから不足からかうまく動かなかったので、mattermost-preview のコンテナを使って
やってみました。ここらへんのデバッグも自分でできるようになりたいと思いました。
今までの投稿
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Pod編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)NameSpace 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Label 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)ReplicaSet 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Deployment 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Service 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)ConfigMap 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Secret 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)操作編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編パート2
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編パート3(Label操作)
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編パート3(OwnerReference 操作)
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)マニュフェスト編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)マニュフェスト(ConfigMap)編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編 パート2
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編 パート3
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編 パート4
- 投稿日:2020-04-26T19:15:59+09:00
初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編 パート4
背景
個人的にインフラの知識以上にこれからのアプリケーションが動く環境を作ってデプロイしたりしてこれからの知識を身に着けたい。そしてより一層、自分の知識のアップデートをしたいと思いました。
その中でこの本に出会い、これから少しずつやったことを残し、未来の自分への手紙としてもあり、見つめ直せればと思いました。
引用や参考と今回の自分の勉強用の書籍の紹介
技術評論社『Kubernetes実践入門』のサンプルコード
Kubernetes実践入門 プロダクションレディなコンテナ&アプリケーションの作り方
実際の学びについて
書籍を読みながら、章ごとに少しずつ進めていきたいと思います。
GitHub のソースコードも使いながら学んで行きたいと思います。
この章の勉強は本当に書籍の写経が主になるかもしれません・・・勉強開始
- ClusterIP を使わない Headless Service を学びます
- 外部アプリケーションに接続する Service
- Service 名から各 Pod の IP アドレスを直接名前解決する Service
\2. は
StatefulSet
で学べるっぽい$ cat <<EOF | kubectl create -f - apiVersion: v1 kind: Service metadata: name: headless-test spec: clusterIP: None ports: - name: http port: 8086 protocol: TCP targetPort: 8086 selector: app: mattermost EOF service/headless-test created$ kubectl run -i --rm test4 --image=k8spracticalguide/busybox:1.28 --restart=Never -- nslookup headless-test If you don't see a command prompt, try pressing enter. Error attaching, falling back to logs: nslookup: can't resolve 'headless-test' Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local pod "test4" deletedなんかうまく行かない・・・・
$ kubectl get po --show-labels mattermost-797c548f48-8rxwn NAME READY STATUS RESTARTS AGE LABELS mattermost-797c548f48-8rxwn 1/1 Running 0 17h pod-template-hash=797c548f48,run=mattermostheadless-test.yamlを修正$ kubectl edit service headless-test 〜省略〜 selector: - app: mattermost + run: mattermost # label を run に変更もう一度名前解決できるか確認
名前解決できた
$ kubectl run -i --rm test4 --image=k8spracticalguide/busybox:1.28 --restart=Never -- nslookup headless-test Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: headless-test Address 1: 10.1.0.212 10-1-0-212.headless-test.default.svc.cluster.local pod "test4" deleted次は 3.6 章をやっていきます。
写経しながら「アプリケーションを外部に公開する」を学んでいきます
最後に
Kubernetes はやっぱり Label が重要だということを改めて実感しました
書籍でも Label で紐付けているとは記載されていますが、やってみて実感してアーキテクチャを感じることができました。やっぱり、手を動かし、それが、自然と身につき、初めて、コマンドラインで機械と会話ができるって実感しました
今までの投稿
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Pod編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)NameSpace 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Label 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)ReplicaSet 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Deployment 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Service 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)ConfigMap 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Secret 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)操作編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編パート2
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編パート3(Label操作)
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編パート3(OwnerReference 操作)
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)マニュフェスト編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)マニュフェスト(ConfigMap)編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編 パート2
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編 パート3
- 投稿日:2020-04-26T18:50:23+09:00
パッケージマネージャーを利用して Windows に docker-cli を導入する
Windows が標準で備えるパッケージマネジメント機能を利用し、下記の Docker CLI ツールを導入します。
Chocolatey Software | Docker CLI 19.03.3
検証環境:
PS > $PSVersionTable Name Value ---- ----- PSVersion 5.1.18362.752 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.18362.752 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1ここでは PowerShell Core ではなく、Windows PowerShell を利用しています。
パッケージプロバイダの追加
Windows PowerShell を管理者権限で起動し、利用可能なパッケージプロバイダを確認します。
PS > Find-PackageProvider Name Version Source Summary ---- ------- ------ ------- nuget 2.8.5.208 https://onege... NuGet provider for the OneGet meta-package manager psl 1.0.0.210 https://onege... psl provider for the OneGet meta-package manager chocolatey 2.8.5.130 https://onege... ChocolateyPrototype provider for the OneGet meta-pa... PowerShellGet 2.2.4.1 PSGallery PowerShell module with commands for discovering, in... DockerMsftProvider 1.0.0.8 PSGallery PowerShell module with commands for discovering, in... DockerProvider 0.0.0.3 PSGallery PowerShell module with commands for discovering, in... ContainerImage 0.6.4.0 PSGallery This is a PackageManagement provider module which h... ChocolateyGet 1.0.0.1 PSGallery An PowerShell OneGet provider that discovers packag... NanoServerPackage 1.0.1.0 PSGallery A PackageManagement provider to Discover, Save and... GitLabProvider 1.3.8 PSGallery GitLab PackageManagement provider DockerMsftProviderInsider 1.0.0.2 PSGallery PowerShell module with commands for discovering, in... GistProvider 0.6 PSGallery Gist-as-a-Package - PackageManagement PowerShell P... GitHubProvider 0.5 PSGallery GitHub-as-a-Package - PackageManagement PowerShell ... 0install 2.17.2 PSGallery OneGet Package Provider for Zero Install TSDProvider 0.2 PSGallery PowerShell PackageManager provider to search & inst... OfficeProvider 1.0.0.1 PSGallery OfficeProvider allows users to install Microsoft Of... AppxGet 0.1.0.1 PSGallery Powershell Package Management (OneGet) Provider for... MyAlbum 0.1.2 PSGallery MyAlbum provider discovers the photos in your remot... WSAProvider 1.0.0.4 PSGallery Provider to Discover, Install and inventory windows... ChocoOneGet 0.4.0 PSGallery OneGet provider for Chocolatey Chocolatier 1.0.4 PSGallery Package Management (OneGet) provider that facilitat... Pacman-Provider 0.0.1 PSGallery Pacman provider enables installation of pacman pack...これらプロバイダのうち、今回は
ChocolateyGet
を利用します。
Install-PackageProvider
コマンドにより、このプロバイダを追加します。PS > Install-PackageProvider ChocolateyGet -Force Name Version Source Summary ---- ------- ------ ------- ChocolateyGet 1.0.0.1 PSGallery An PowerShell OneGet provider that discovers packag...Docker CLI ツールの導入
まず、プロバイダにパッケージが登録されているか確認します。
PS > Find-Package docker-cli -ProviderName ChocolateyGet Name Version Source Summary ---- ------- ------ ------- docker-cli 19.03.3 https://www.c...パッケージをインストールするには、
Install-Package
コマンドを利用します。PS > Install-Package docker-cli -ProviderName ChocolateyGet -Force Name Version Source Summary ---- ------- ------ ------- docker-cli v19.03.3 https://www.c...インストールが完了すると、以下の通り
docker
コマンドが利用可能になります。PS > docker version Client: Version: 19.03.3 API version: 1.40 Go version: go1.12.10 Git commit: 2355349d- Built: 10/14/2019 16:41:26 OS/Arch: windows/amd64 Experimental: false error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.40/version: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.Docker のデーモンが起動していないためエラーメッセージが出力されていますが、リモートの Docker ホスト等に接続すればローカルで実行する場合と同様に Docker を利用できると思います。
参考:
- 投稿日:2020-04-26T18:09:41+09:00
Dockerのproduction環境でのbundle exec方法
- 投稿日:2020-04-26T16:42:36+09:00
Dockerでの環境構築(Rails)超入門1
はじめに
Ruby on Rails初心者です。今回はDockerを使ったRailsの環境構築の初歩を勉強のために備忘録として残したいと思います。
前提
DockerでRailsの開発環境を行う
※あくまで開発環境を構築するためだけの超入門であるため、DBや細かい設定等は次回以降投稿する次回
Dockerでの環境構築(Rails)超入門2 ~Dockerfileの設定~
手順
Dockerはインストールしていることが前提
1. Dockerfile, docker-compose.yamlの作成
2. Dockerのコンテナを起動
3. Railsの設定
4. Node.jsの設定
5. Yarnのインストール実践
- Dockerfile, docker-compose.yamlの作成
・ディレクトリを作成(今回はDocker/practice)
$ cd Desktop $ mkdir docker $ mkdir practice $ cd practice・Docker hubで「ruby」を検索し、バージョンを確認
・Dockerfile作成
FROM ruby:2.6.6-stretch・docker-compose.yaml作成
version: '3' services: app: build: . volumes: - ".:/app" ports: - "3000:3000" tty: true
- Dockerのコンテナを起動
$ docker-compose up下記が表示されればOK!
(省略) Creating practice_app_1 ... done Attaching to practice_app_1 (省略)・practice_app_1の中に入る
$ docker exec -it practice_app_1 /bin/bash # Appがローカルになっているので /# cd app/3.Railsの設定
/# gem install rails /# rails new # ローカルに接続 /# rails s -b 0.0.0.0・ローカルに接続したら下記のエラーが出た
# エラー「Please run rails webpacker:install」 /# rails webpacker:install # エラー Webpacker requires Node.js >= 6.14.4 and you are using 4.9.1 Please upgrade Node.js https://nodejs.org/en/download/4.Node.jsの設定
・そのためNode.jsをアップデートする
# Node.jsのバージョン管理ツールnvmをclone $ git clone git://github.com/creationix/nvm.git ~/.nvm $ echo . ~/.nvm/nvm.sh >> ~/.bashrc $ . ~/.bashrc # nvmバージョン確認 $ nvm --version 0.35.3 # 最新の安定版をインストール $ nvm install stable # バージョン確認 $ node -v v14.0.0 # 再度試す $ rails webpacker:install Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/↑Yarnのインストールが必要とのこと、、
5.Yarnのインストール
・node.jsをインストールするとnpmが入っているはずなので以下のコマンドを実行する# node.jsのバージョンを確認 node -v # npmのバージョンを確認 npm -v # npm 経由でyarnをインストール npm install -g yarn # yarnのバージョンを確認 yarn -v /app# yarn install /app# rails webpacker:install # 成功 Webpacker successfully installed ? ? # ローカルに接続 /app# rails s -b 0.0.0.0 # エラー error Couldn't find an integrity file error Found 1 errors. ======================================== Your Yarn packages are out of date! Please run `yarn install --check-files` to update. ========================================↑言われた通りコマンドを実行
/app# yarn install --check-files # 再度接続 /app# rails s -b 0.0.0.0・下記の画面が出ればOK!
- 投稿日:2020-04-26T16:42:36+09:00
Dockerでの環境構築(Rails)超入門
はじめに
Ruby on Rails初心者です。今回はDockerを使ったRailsの環境構築の初歩を勉強のために備忘録として残したいと思います。
前提
DockerでRailsの開発環境を行う
※あくまで開発環境を構築するためだけの超入門であるため、DBや細かい設定等は次回以降投稿する手順
Dockerはインストールしていることが前提
1. Dockerfile, docker-compose.yamlの作成
2. Dockerのコンテナを起動
3. Railsの設定
4. Node.jsの設定
5. Yarnのインストール実践
- Dockerfile, docker-compose.yamlの作成
・ディレクトリを作成(今回はDocker/practice)
$ cd Desktop $ mkdir docker $ mkdir practice $ cd practice・Docker hubで「ruby」を検索し、バージョンを確認
・Dockerfile作成
FROM ruby:2.6.6-stretch・docker-compose.yaml作成
version: '3' services: app: build: . volumes: - ".:/app" ports: - "3000:3000" tty: true
- Dockerのコンテナを起動
$ docker-compose up下記が表示されればOK!
(省略) Creating practice_app_1 ... done Attaching to practice_app_1 (省略)・practice_app_1の中に入る
$ docker exec -it practice_app_1 /bin/bash # Appがローカルになっているので /# cd app/3.Railsの設定
/# gem install rails /# rails new # ローカルに接続 /# rails s -b 0.0.0.0・ローカルに接続したら下記のエラーが出た
# エラー「Please run rails webpacker:install」 /# rails webpacker:install # エラー Webpacker requires Node.js >= 6.14.4 and you are using 4.9.1 Please upgrade Node.js https://nodejs.org/en/download/4.Node.jsの設定
・そのためNode.jsをアップデートする
# Node.jsのバージョン管理ツールnvmをclone $ git clone git://github.com/creationix/nvm.git ~/.nvm $ echo . ~/.nvm/nvm.sh >> ~/.bashrc $ . ~/.bashrc # nvmバージョン確認 $ nvm --version 0.35.3 # 最新の安定版をインストール $ nvm install stable # バージョン確認 $ node -v v14.0.0 # 再度試す $ rails webpacker:install Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/↑Yarnのインストールが必要とのこと、、
5.Yarnのインストール
・node.jsをインストールするとnpmが入っているはずなので以下のコマンドを実行する# node.jsのバージョンを確認 node -v # npmのバージョンを確認 npm -v # npm 経由でyarnをインストール npm install -g yarn # yarnのバージョンを確認 yarn -v /app# yarn install /app# rails webpacker:install # 成功 Webpacker successfully installed ? ? # ローカルに接続 /app# rails s -b 0.0.0.0 # エラー error Couldn't find an integrity file error Found 1 errors. ======================================== Your Yarn packages are out of date! Please run `yarn install --check-files` to update. ========================================↑言われた通りコマンドを実行
/app# yarn install --check-files # 再度接続 /app# rails s -b 0.0.0.0・下記の画面が出ればOK!
- 投稿日:2020-04-26T16:41:26+09:00
Win10HomeのDockerでJupyterLab環境を整える
概要
仮想環境ソフトウェアDockerを使うことで、OSに関係なく計算環境を構築・移行することが出来ます。Win10HomeでJupyterLab環境を構築する手順を示します。このJupyterLab環境では、Python, R, Juliaを使うことが出来ます。
各用語の説明
- 仮想環境 : ハードウェアやOSの異なる環境でも動作する仕組みのこと。これにより、ハードウェアやOSに依存せずに環境を動作させることが可能。
- Docker : 仮想環境ソフトウェアの一つ。「コンテナ」という仕組みを採用しており、従来の仮想環境ソフトウェアと比較し軽量であるのが特徴。オープンソース。
- Dockerhub : 様々なDocker環境がアップロードされているサーバー兼ウェブサイト。たった1つのコマンドでDocker環境を構築することが出来る。
- JupyterLab : Python, R, Juliaなどの言語をインタラクティブに実行出来る計算環境。ブラウザベースで動作するため、仮想環境ソフトウェアで簡単に構築することが出来る。今回はDockerhubにアップロードされているJupyter公式のDocker環境を用いる。
手順
- Windows 10 Insider Preview ビルドをインストールする
Windows Insider Program ユーザー ガイド - Microsoft- Docker Desktop Edge 2.2.2.0をインストールする
Docker Desktop for Windows Home is here! - docker official blog- PowerShellで
docker
コマンドが正常に動くことを確認する![]()
- メニューバーのDockerアイコンを右クリックして「Linux containers」に切り替える
![]()
- メニューバーのDockerアイコンを右クリックして「設定」を選択する。Dockerと共有したいドライブにチェックを入れておく。この場合はCドライブにもDドライブにもチェックを入れておけば良い
![]()
- Powershellで以下のコマンドを走らせる。以下では共有先ディレクトリに
d:/Desktop
で「DドライブのDesktop」を指定している。各自の環境に合わせて適宜変更する。docker run -d --restart always -p 10000:8888 -e JUPYTER_ENABLE_LAB=yes -v d:/Desktop:/home/jovyan/work --name notebook jupyter/datascience-notebook jupyter-lab --NotebookApp.token='' --allow-root
- 以下のURLにアクセスする
http://localhost:10000- 正常に起動できれば、以下のように表示される。①workフォルダ以下にデスクトップのファイルが表示される。②各言語のnotebookを作成することが出来る。③
conda install (ライブラリ名)
のようにライブラリをインストールすることが出来る![]()
参考URL
- 投稿日:2020-04-26T16:41:26+09:00
Win10HomeのDockerでJupyterLab環境を構築する
概要
仮想環境ソフトウェアDockerを使うことで、OSに関係なく計算環境を構築・移行することが出来ます。Win10HomeでJupyterLab環境を構築する手順を示します。このJupyterLab環境では、Python, R, Juliaを使うことが出来ます。
各用語の説明
- 仮想環境 : ハードウェアやOSの異なる環境でも動作する仕組みのこと。これにより、ハードウェアやOSに依存せずに環境を動作させることが可能。
- Docker : 仮想環境ソフトウェアの一つ。「コンテナ」という仕組みを採用しており、従来の仮想環境ソフトウェアと比較し軽量であるのが特徴。オープンソース。
- Dockerhub : 様々なDocker環境がアップロードされているサーバー兼ウェブサイト。たった1つのコマンドでDocker環境を構築することが出来る。
- JupyterLab : Python, R, Juliaなどの言語をインタラクティブに実行出来る計算環境。ブラウザベースで動作するため、仮想環境ソフトウェアで簡単に構築することが出来る。今回はDockerhubにアップロードされているJupyter公式のDocker環境を用いる。
手順
- Windows 10 Insider Preview ビルドをインストールする
Windows Insider Program ユーザー ガイド - Microsoft- Docker Desktop Edge 2.2.2.0をインストールする
Docker Desktop for Windows Home is here! - docker official blog- PowerShellで
docker
コマンドが正常に動くことを確認する![]()
- メニューバーのDockerアイコンを右クリックして「Linux containers」に切り替える
![]()
- メニューバーのDockerアイコンを右クリックして「設定」を選択する。Dockerと共有したいドライブにチェックを入れておく。この場合はCドライブにもDドライブにもチェックを入れておけば良い
![]()
- Powershellで以下のコマンドを走らせる。以下では共有先ディレクトリに
d:/Desktop
で「DドライブのDesktop」を指定している。各自の環境に合わせて適宜変更する。docker run -d --restart always -p 10000:8888 -e JUPYTER_ENABLE_LAB=yes -v d:/Desktop:/home/jovyan/work --name notebook jupyter/datascience-notebook jupyter-lab --NotebookApp.token='' --allow-root
- 以下のURLにアクセスする
http://localhost:10000- 正常に起動できれば、以下のように表示される。①workフォルダ以下にデスクトップのファイルが表示される、②各言語のnotebookを作成、③
conda install (ライブラリ名)
コマンドで各ライブラリをインストール![]()
参考URL
- 投稿日:2020-04-26T14:18:14+09:00
ansibleでkubernetes環境の構築 2
はじめに
前回の記事でansibleを使用してkubernetesを初期化することができた
いよいよk8s workerを追加して本確定なk8s環境を作っていく環境
MBP OS Sierra
MAASサーバー(192.168.100.152 MAAS用ネットワーク:192.168.200.1)
k8s-masterサーバー(KVM:192.168.100.191)
ansibleサーバー(KVM:192.168.100.192)
k8s worker(192.168.200.151)
k8s worker(192.168.200.153)dash-board Ver.1.8
ゴール
k8sで作ったflannelネットワーク内に、MAASでOSをデプロイしたマシンをk8s-workerとして追加する
またk8sの使用状況をダッシュボードでも見ることができるようにするMAASサーバーのネットワーク設定
今回はMAASのDHCP問題の関係でk8s-masterとworkerは別のネットワークにしているため、MAASサーバーでブリッジ設定をする必要がある
ubuntu18は16までのものとネットワーク設定の仕方が変わっている
/etc/netplan/50-cloud-init.yaml_bkの記述だけでいけるはずだったが、ブリッジの設定がうまくいかなかったため今回は2種類のファイルに記述している$ sudo vi /etc/netplan/50-cloud-init.yaml_bk network: ethernets: enp0s31f6: addresses: - 192.168.100.152/24 gateway4: 192.168.100.1 nameservers: addresses: - 8.8.8.8 search: - 8.8.4.4 enp2s0: addresses: - 192.168.200.1/24 gateway4: 192.168.100.1 nameservers: addresses: - 8.8.8.8 search: - 8.8.4.4 version: 2 $ sudo vi /etc/network/interfaces auto lo iface lo inet loopback auto enp0s31f6 iface enp0s31f6 inet manual auto br0 iface br0 inet static address 192.168.100.152 netmask 255.255.255.0 gateway 192.168.100.1 dns-nameservers 8.8.8.8 bridge_ports enp0s31f6 bridge_maxwait 0 bridge_df 0 bridge_stp off auto enp2s0 iface enp2s0 inet static address 192.168.200.1 netmask 255.255.255.0 gateway 192.168.100.1 dns-nameservers 8.8.8.8 $ ifconfig br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.100.152 netmask 255.255.255.0 broadcast 192.168.100.255 inet6 fe80::329c:23ff:feac:5570 prefixlen 64 scopeid 0x20<link> ether 30:9c:23:ac:55:70 txqueuelen 1000 (Ethernet) RX packets 9579059 bytes 16579553543 (16.5 GB) RX errors 0 dropped 657286 overruns 0 frame 0 TX packets 6047022 bytes 936298283 (936.2 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 enp0s31f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::329c:23ff:feac:5570 prefixlen 64 scopeid 0x20<link> ether 30:9c:23:ac:55:70 txqueuelen 1000 (Ethernet) RX packets 21689196 bytes 26237413396 (26.2 GB) RX errors 0 dropped 475 overruns 0 frame 0 TX packets 6555651 bytes 4057603928 (4.0 GB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 16 memory 0xdf100000-df120000 enp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.200.1 netmask 255.255.255.0 broadcast 192.168.200.255 inet6 fe80::6a05:caff:fe66:a834 prefixlen 64 scopeid 0x20<link> ether 68:05:ca:66:a8:34 txqueuelen 1000 (Ethernet) RX packets 6867754 bytes 970026556 (970.0 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 13304857 bytes 15246678579 (15.2 GB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 17 memory 0xdf0c0000-df0e0000また2つのネットワークで通信できるようにNATの設定をする
sudo iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -j SNAT --to 192.168.100.152workerの追加
k8sのworkerを追加するにはマスターの場合とほとんど変わらないがflannelネットワークに参加させる最後に起動させるコマンドが必要になる
そのコマンドはkubeadm initを行なった際の出力内容に表示されるが、下記コマンドでも確認することができる
(k8s-master)$ kubeadm token create --print-join-command出てきたコマンドを使ってworker参加用のplaybookを作成する
(ansible)$ sudo vi mlp.yml --- - hosts: mlp01 remote_user: ubuntu become: yes tasks: - name: Install prerequisites and Docker.io , nfs-common apt: name={{item}} update_cache=yes with_items: - nfs-common - apt-transport-https - ca-certificates - curl - software-properties-common - docker.io - name: user add to docker group user: name=ubuntu group=docker append=yes - name: Add K8S GPG key apt_key: url: https://packages.cloud.google.com/apt/doc/apt-key.gpg - name: Add K8S APT repository apt_repository: repo: deb http://apt.kubernetes.io/ kubernetes-xenial main - name: Install K8S apt: name={{item}} update_cache=yes with_items: - kubelet - kubeadm - kubectl - name: Remove swapfile from /etc/fstab mount: name: swap fstype: swap state: absent - name: Disable swap command: swapoff -a when: ansible_swaptotal_mb > 0 - name: Set docker service to start on boot. service: name=docker enabled=yes - name: Set kubelet service to start on boot. service: name=kubelet enabled=yes - name: Join k8s-master become: yes shell: kubeadm join 192.168.100.191:6443 ~~ #上記のコマンドで出力したものを記述マスターの時と同様にhostsの編集
$ sudo vi /etc/ansible/hosts [master] k8s-master [mlp] mlp01 $ sudo vi /etc/hosts 192.168.100.191 k8s-master 192.168.200.151 mlp01ansibleのplaybook実行
python3をしようする場合は"-e"以降のオプションが必要~/ansible$ sudo ansible-playbook --private-key=id_rsa_common mlp.yml -e 'ansible_python_interpreter=/usr/bin/python3'playbookが成功した場合、以下の状態になる
(k8s-master)$ kubectl get node NAME STATUS ROLES AGE VERSION k8s-master Ready master 3d v1.10.3 mlp01 Ready <none> 3d v1.10.2nginxイメージの起動
nodeが追加された後は、ひとまずnginxのdockerイメージを走らせる
理由は後述する$ sudo vi nginx-pod.yaml apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx-container image: nginx ports: - containerPort: 80 $ kubectl apply -f nginx-pod.yaml create $ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-pod 1/1 Running 0 3dnginxがRunningになれば問題ない
Dash-boardのインストール
Dash-boardはなくても、kubernetesを使う上ではなんとかなるがせっかくなら使いたい
というわけでインストールをしていく$ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yamlエラーが出ず、「created」と表示されればOK
動いているかを確認kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE default nginx-pod 1/1 Running 0 3d kube-system kubernetes-dashboard-7d5dcdb6d9-7hptz 1/1 Running 0 3dkubeのproxyを起動
$ kubectl proxy --address 0.0.0.0 --accept-hosts '.*' Starting to serve on [::]:8001この状態になったらブラウザでアクセスして見る
ログイン画面が出てくるhttp://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login![]()
ログインするためのトークンを発行する
$ kubectl -n kube-system get secret発行されたトークンを使えば入れる
毎回トークンを発行するのが大変という人向けの設定は以下のもの
これを実行した後は、ログイン画面のSKIPで入れるようになる
ただしセキュリティ的にはガバガバなため、社内オンリーの環境など外部の人がいない条件での使用推奨$ cat <<EOF | kubectl create -f - apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard labels: k8s-app: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kube-system EOFこれでkubernetesの環境構築は終了である
おわりに
この環境を作ることができたら、あとはk8s-masterからdockerイメージを起動させればnodeに自動配布することができる
nodeの新規追加もflannelネットワークに追加するコマンドさえあればすぐできるためとても便利つまづいたところ
ネットワーク通信
この記事の冒頭の方でネットワーク設定を載せているが、これに決まるまでは通信が通らないエラーがで続けていた
ubuntu18のバージョン変更に伴う設定方法の変更に振り回された印象kubeadm initが失敗する
原因としてはswapの消去を忘れていただけだが、存在を忘れがちである
dash-boardが表示されない
マスターにノードが追加され、dash-boardをインストール→proxyを起動としただけではブラウザにdash-boardは表示されず、ブラウザのページにはファイルのディレクトリツリーだけが出てくるのみだった
試しにページの中段にあるようにproxy-podを起動させてみて、その後手順通りに進めたらdash-boardが表示されるようになった
他の参考にしたページでは同様の症状はなかったようでdash-boardのバージョンの仕様なのか、自分だけだやっていない設定があるのか、原因は不明参考にしたページ
iptables で NAT 環境を構築してみた
kubernetes 公式ページ
access control
Kubernetes/Web UI (Dashboard)の追加
KubernetesにDashboardをインストールして、認証なしでアクセスする
- 投稿日:2020-04-26T14:17:03+09:00
ansibleでkubernetes環境の構築 1
はじめに
nodeに対してのk8sのインストールなどは極力ansibleで自動化していく
ansibleの実行機やk8sのマスターはMAASサーバーのKVMを使用するゴール
ansibleでk8sをインストールできる状態まで構築する
環境
MBP OS Sierra
MAASサーバー(192.168.100.152)
k8s-masterサーバー(KVM:192.168.100.191)
ansibleサーバー(KVM:192.168.100.192)ansible Ver.2.5.1
kubernetes Ver.1.10.3MAASサーバーにKVMをインストールする
ansibleサーバー、k8sサーバーを作るためのKVMを土台となるMAASサーバーにインストールする
インストール後はlibvirtグループに参加し、sudoなしでも実行できるようにする$ sudo apt install -y qemu-kvm libvirt0 libvirt-bin virt-manager bridge-utils $ sudo systemctl enable libvirt-bin $ sudo gpasswd libvirtd -a <username>KVMの作成はデスクトップ環境を使用した方が便利なため、MAASサーバーにデスクトップをインストールする
$ sudo apt -y install ubuntu-desktopデスクトップのインストールは時間がかかるためしばし待つ
インストールが完了して再起動すれば自動でデスクトップが表示されるデスクトップ上のターミナルでKVMを起動すれば作成用ウィンドウが起動される
$ virt-manager![]()
ここで下記スペックのKVMを新規作成する
ホスト名:ansible メモリ:4GB CPU:2 ストレージ:30GB ホスト名:k8s-master メモリ:8GB CPU:4 ストレージ:40GBansibleの構築
KVMで作成したansibleサーバーに実際にansibleをインストールする
$ sudo apt-get update $ sudo apt-get install software-properties-common $ sudo apt-add-repository ppa:ansible/ansible $ sudo apt-get update $ sudo apt-get install ansible今回はhome直下にansibleフォルダを作成し、各種ファイルを管理する
$ sudo mkdir ansiblek8s-masterにk8sをインストールするためのplaybookを作成する
$ sudo vi k8s-master.yaml --- - hosts: k8s-master remote_user: $user名 become: yes tasks: - name: Install prerequisites and Docker.io #dockerインストール become: yes apt: name={{item}} update_cache=yes with_items: - apt-transport-https - ca-certificates - curl - software-properties-common - docker.io - name: user add to docker group user: name=gauss group=docker append=yes - name: Add K8S GPG key #k8sインストール準備 apt_key: url: https://packages.cloud.google.com/apt/doc/apt-key.gpg - name: Add K8S APT repository apt_repository: repo: deb http://apt.kubernetes.io/ kubernetes-xenial main - name: Install K8S apt: name={{item}} update_cache=yes with_items: - kubelet - kubeadm - kubectl - name: Remove swapfile from /etc/fstab #swapを消しておかないと失敗する mount: name: swap fstype: swap state: absent - name: Disable swap command: swapoff -a when: ansible_swaptotal_mb > 0 - name: Set docker service to start on boot. #再起動後もdockerを自動起動させる service: name=docker enabled=yes - name: Set kubelet service to start on boot. #再起動後もk8sを自動起動させる service: name=kubelet enabled=yes - name: Init k8s-master #k8smの初期化 become: yes shell: kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.100.191 - name: Make Directory .kube file: path: /.kube state: directory owner: $オーナー group: docker mode: 0755 - name: Copy the .kube config become: yes file: src: /home/$ユーザ名/ansible/admin.conf dest: ~/.kube/config owner: $オーナー group: docker mode: 0600 - name: Export Kubernetes lineinfile: path: /home/$ユーザ名/.kube/config state: absent regexp: '^%KUBECONFIG' - name: Apply Flannel $flannelのネットワークを作成 sudo: yes shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml次はansibleのhostsを追加設定
[master]$ sudo vi /etc/ansible/hostsk8s-master $ sudo vi /etc/hosts 192.168.100.191 k8s-master
準備ができたらansibleのplaybook実行
python3をしようする場合は"-e"以降のオプションが必要~/ansible$ sudo ansible-playbook --private-key=id_rsa_common k8s-master.yml -e 'ansible_python_interpreter=/usr/bin/python3'エラーが出なければ完了
おわりに
k8sはバージョンの移り変わりが早く、ubuntuも18.04と新しいバージョンでエラーが多くどうなるかと思ったが初期化の成功にひとまず安心した
つまづいたところ
dockerのバージョン
k8sの初期化をする際、最新のdocker(18.03)を入れていると、対応しているバージョンは17.03までだからダウングレードしろとメッセージが出たため、17.03を入れ直した
しかし失敗するのは変わらなかったため、docker.ioをいれたところ成功したkube-dnsが機能しなかった
ansibleファイル内で実行しているkubeadm initのコマンドにおいて、--pod-network-cidrのネットワーク表記を当初「10.0.0.0」にしていたが、その設定だとパッケージに入っているkube-dnsが機能しなかった
各ページを確認したところこのネットワークは「10.244.0.0」が正しそうだということがわかり、そちらの設定でコマンドを実行したところ正常にkube-dnsは機能してくれた参考ページ
Ubuntu 16.04: KVMをインストールして仮想マシンを起動する
Ansible入門しました。【入門編】
kubernetes 公式ページ
kubernetesによるDockerコンテナ管理入門
kubeadm で kubernetes v1.8 + Flannel をインストール
- 投稿日:2020-04-26T14:15:45+09:00
0から始めるUbuntu18.04+MAAS2.4環境作成
はじめに
現在社内でMAAS+kubernetes環境を構築しようというプロジェクトがあり、
その中で行ったもの、つまづいたところを記述していく.ゴール
Ubuntuでサーバーを構築し、独立したネットワーク内でUbuntuOSのデプロイをPXEブート経由でできるようになる.
導入前注意事項
MAASサーバーが存在するネットワークにはDHCPが存在しないことを事前に確認する.
DHCPが既存のネットワークでMAASサーバーを構築すると、後の設定でMAASサーバーがDHCPサーバーになるため、既存DHCPと競合する.
DHCPが競合すると、ネットワーク内の端末がIPアドレスを再取得する際にMAASサーバーから取得した場合、ネットワークの外側と通信できなくなる.
また、MAASクライアントになるはずの端末も、MAASサーバーと安定的に通信できなくなる.
(様々な記事を確認したが現状未解決)構築用端末
MAASサーバー用端末(IP:192.168.200.1)
MAASクライアント用端末(IP:192.168.200.151)
macbookproUbuntuインストール
ubuntuダウンロード
以下のURLからUbuntu ServerのISOイメージをダウンロードする.
http://releases.ubuntu.com/18.04/
Ubuntuイメージの起動ディスク作成
手持ちのUSBメモリにUbuntuのISOイメージを焼き付けて、インストール用メディアを作成する.
USBメモリの確認
MACにUSBメモリを差した後、ターミナルを立ち上げディスクの場所を確認する.
diskutil list![]()
コマンド実行時はUSBメモリは/dev/disk2となっていたので、これを一度MS-DOS形式でフォーマットする.
diskutil eraseDisk MS-DOS UNTITLED /dev/disk2フォーマットされたUSBメモリをアンマウントしddコマンドで起動ディスクを作成する.
diskutil unmountDisk /dev/disk2 sudo dd if=./Downloads/ubuntu-18.04-live-server-amd64.iso of=/dev/disk2 bs=4028多少時間がかかるため、コーヒータイム.
イメージ作成が完了したら、デバイスを取り外す.もし刺さったままなら、
diskutil eject /dev/disk2を実行してUSBメモリを抜く.
Ubuntuイメージのインストール
MAASサーバ用の端末に先ほど作成したUSBを差し、BOOT画面でUSB起動を指定しインストールを開始.
BOOTデバイスの指定はマシンによって異なるため省略.インストールのオプションは任意の設定で.
MAASインストール
サーバーにMAASパッケージをインストールする.
$ sudo apt -y update $ sudo apt -y upgrade $ sudo apt -y install maasインストールが完了したら管理者用ユーザの作成.
必要なユーザー名、パスワード、アドレスなどを設定.
SSHキーの登録は後で行うため、空欄のままエンターでスルー.$ sudo maas createadmin作成が完了したら「MAASサーバーのアドレス:5240/MAAS/」でログイン.
MAASの設定
ログイン画面が出てくるため、
作成したユーザーでログイン.![]()
ログイン後、イントロページが出てくる.
特に設定をいじる必要はない.後者の画像では、ダウンロードするUbuntuのOSイメージを選択する.
欲しいバージョンにチェックを入れたら、基本的に自動でダウンロードが始まるため、しばらく待つ.ダウンロードが完了し、「Status」が「Synced」になったらContinueをクリック
![]()
![]()
秘密鍵を入力する画面に移るため、Ubuntuサーバー側で鍵を生成する.
特に指定はせずに、空欄のままエンター連打.$ sudo ssh-keygen -t rsaサーバーの.sshフォルダに鍵が生成されるため、
そちらの公開鍵の中身をコピーする.cat .ssh/id_rsa.pubコピー後はMAASの管理サーバーに戻り、SourceをUploadに変え、隣の入力画面に先ほどコピーした鍵の中身をペーストし、Importをクリック.
問題がなければ「Go to dashboard」をクリック.![]()
準備として、MAASトップページ上部の「Subnets」ページ内、展開したいネットワークVLANのuntaggedを選択.
![]()
画面上部の「Take action」から「Provide DHCP」を選択.
![]()
![]()
MAASサーバーのDHCPレンジが出てくるため、任意の数を指定し、「Provide DHCP」を選択すると、同じページ内のDHCP項目がEnableになり、「Reserved ranges」に追加したネットワーク範囲が表示される.
![]()
これで一通りの下準備が完了になる.
MAASクライアントのデプロイ
![]()
MAASクライアントとなる端末のBOOT順序でPXE bootの項目を起動順序の一位へする.
その後クライアントの電源を入れると自動でMAASサーバーと通信を開始し、電源が落ちる.
電源が落ちた後は、MAASの管理画面上の「Machines」に端末が追加される.
(端末の名前は仮で動物の名前が入る)
![]()
追加されたマシンを選択し、まずは名前の変更をする.
![]()
「Configration」内の「Power configuration」で電源オプションを選択.
今回は「Manual」を選択する.
![]()
「Machines」ページで、端末のチェックボックスにチェックを入れ、「Take action」から「Commission」を選択した後、クライアント端末の電源を入れる.
![]()
再びサーバーとの通信を開始するので終了まで待つ.
無事にCommissionが終了したら、サーバーの管理画面では「Status」が「Ready」になる.
「Take action」から「Deploy」を選択し任意のOSを選択し、デプロイを開始させ、クライアントの電源を入れる.
![]()
サーバーからOSがデプロイされるため、しばし待ち、管理画面上でStatus欄がOS名に変われば成功
.
クライアント端末のネットワーク設定について
MAASのクライアント端末は基本はDHCPだが、Staticに指定することも可能.
その場合はOSのデプロイ前に端末の情報ページ内「Interfaces」内の「Actions」-「Edit Physical」を選択し、「Auto assign」を「Static」に変更し、任意のアドレスを指定する.
![]()
![]()
つまづいたところ
MAASサーバーをインストールした後、設定画面上はDHCPはEnabledになっているが、クライアントに対してアドレスの配布が行われない.
解決方法
管理画面上部「Controllers」内の「Name」にあるマシンを選択(初期だと一つしかないはず)
移ったページ内のServices項目において「dhcpd」にグリーンマークが付いていない場合があるため、一度MAASを再起動するとグリーンマークが付くようになった.これでもダメな場合は、
sudo dpkg-reconfigure maas-rack-controller sudo apt-get install maas-rack-controller sudo maas-rack register --url http://MAASサーバーアドレス:5240/で治ることもあった.
参考ページ
Mac OSX上でISOイメージからBootable USBを作成する - 1日ひとつだけ強くなる
MAASの環境構築とUbuntuのデプロイ - Qiita
公開鍵暗号を用いてのSSH接続(きほん) - Qiita
- 投稿日:2020-04-26T12:31:21+09:00
DjangoでTodoアプリを作る⑤タスク編集機能の作成
次にタスク編集機能を作成していきます。
記事一覧
DjangoでTodoアプリを作る①Dockerで環境を構築する
DjangoでTodoアプリを作る②フォルダ一覧ページの作成
DjangoでTodoアプリを作る③タスク一覧ページの作成
DjangoでTodoアプリを作る④フォルダー、タスク作成機能の実装
DjangoでTodoアプリを作る⑤タスク編集機能の作成URLの設定
まず、URLを設定していきます。
todo/urls.py
に次の一文を加えてください。todo/urls.pypath('<int:id>/tasks/<int:task_id>', views.edit_task, name='tasks.edit')リンクの挿入
templates/index.html
の編集
の部分に以下のようにリンクを挿入します。templates/index.html<a href="{% url 'tasks.edit' id=current_folder_id task_id=task.id %}}">編集</a>テンプレート
templates
ディレクトリ下にedit.html
を作成します。
そして、edit.html
を以下のように編集します。templates/edit.html{% extends 'base.html' %} {% block styles %} <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css"> <link rel="stylesheet" href="https://npmcdn.com/flatpickr/dist/themes/material_blue.css"> {% endblock %} {% block content %} <div class="container"> <div class="row"> <div class="col col-md-offset-3 col-md-6"> <nav class="panel panel-default"> <div class="panel-heading">タスクを編集する</div> <div class="panel-body"> <form method="POST"> {% csrf_token %} {{ form.as_p }} <div class="text-right"> <button type="submit" class="btn btn-primary">送信</button> </div> </form> </div> </nav> </div> </div> </div> {% endblock %} {% block scripts %} <script src="https://npmcdn.com/flatpickr/dist/flatpickr.min.js"></script> <script src="https://npmcdn.com/flatpickr/dist/l10n/ja.js"></script> <script> flatpickr(document.getElementsByName('due_date'), { locale: 'ja', minDate: new Date() }); </script> {% endblock %}次に、viewを書いていきます。
View
viewに以下の
edit_task
メソッドを追加します。views.pydef edit_task(request, id, task_id): #選ばれたタスクを取得する task = get_object_or_404(Task, id=task_id) if request.method == "POST": form = TaskForm(request.POST, instance=task) if form.is_valid(): task = form.save(commit=False) task.save() return redirect('tasks.index', id=task.folder_id.id) else: form = TaskForm(instance=task) return render(request, 'edit.html', {'form': form}, {'task':task})request.POST にデータが追加されているとき、formに入力された内容がデータベースに保存されるようにif文の処理を書いています。
完成!
これでこのチャプターは終わりで、Todoアプリの完成です!
ここまでのコードは、リポジトリのchapter5ブランチにあります。ここからさらに、削除機能とか認証機能とかつけることもできると思うので、カスタマイズしながらやってみるのもいいと思います!
このチュートリアルを参考にしていただきありがとうございました!記事一覧
DjangoでTodoアプリを作る①Dockerで環境を構築する
DjangoでTodoアプリを作る②フォルダ一覧ページの作成
DjangoでTodoアプリを作る③タスク一覧ページの作成
DjangoでTodoアプリを作る④フォルダー、タスク作成機能の実装
DjangoでTodoアプリを作る⑤タスク編集機能の作成
- 投稿日:2020-04-26T12:30:51+09:00
DjangoでTodoアプリを作る④フォルダー、タスク作成機能の実装
次は、フォルダー、タスク作成機能を実装していきます。
記事一覧
DjangoでTodoアプリを作る①Dockerで環境を構築する
DjangoでTodoアプリを作る②フォルダ一覧ページの作成
DjangoでTodoアプリを作る③タスク一覧ページの作成
DjangoでTodoアプリを作る④フォルダー、タスク作成機能の実装
DjangoでTodoアプリを作る⑤タスク編集機能の作成フォルダー作成機能の実装
URLの設定
まず、以下の定義を踏まえてURLを設定していきます。
URL 処理 /folders/create フォルダーを新たに作成する この設計にするために、
todo/urls.py
に次の一文を加えてください。todo/urls.pypath('create', views.create_folder, name='folders.create')フォームの作成
まず、
todo
ディレクトリの下にforms.py
というファイルを作成してください。
このファイルは、フォームを作成するのに必要なファイルです。forms.pyを以下のように編集します。
forms.pyfrom django import forms from .models import Folder class FolderForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(FolderForm, self).__init__(*args, **kwargs) for field in self.fields.values(): field.widget.attrs = { 'class': 'form-control' } class Meta: model = Folder fields = ('title',) labels = {'title' : 'フォルダー名'}formを作成するために必要な
forms
とFolder
モデルを1,2行目でインポートしています。
__init__の部分で、FolderFormのクラス名をform-controlにしています。これは、bootstrapを適用させるためです。djangoには、django.forms.ModelForm と言う Modelクラスを元にFieldを自動的に生成してくれるクラスがあります。登録や更新処理ではModelFormクラスを使うのが便利なようです。
Metaクラスの変数の意味は以下の通りです。
変数名 意味 model 紐付けるModelクラスを指定する fields Modelから入力フォームを生成する対象のフィールドをタプル形式で指定する labels 入力欄の表示名を変更する。(例えば、今回指定していなければ、表示名が「title」になる) フォルダー作成ページへのリンク
templates/index.html
のフォルダーを追加する
の部分にリンクを以下のように追加します。index.html<a href="{% url 'folders.create' %}" class="btn btn-default btn-block">テンプレート
templates
ディレクトリ下にcreate_folders.html
を作成します。
create_folders.html
を以下のように編集します。templates/create_folders.html{% load static %} <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Todo</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootflat/2.0.4/css/bootflat.min.css"> <link rel="stylesheet" href="{% static 'css/style.css' %}"> </head> <body> <header> <nav class="my-navbar"> <a class="my-navbar-brand" href="/">Todo</a> </nav> </header> <main> <div class="container"> <div class="row"> <div class="col col-md-offset-3 col-md-6"> <nav class="panel panel-default"> <div class="panel-heading">フォルダーを追加する</div> <div class="panel-body"> <form method="POST"> {% csrf_token %} {{ form.as_p }} <div class="text-right"> <button type="submit" class="btn btn-primary">送信</button> </div> </form> </div> </nav> </div> </div> </div> </main> </body> </html>以下の部分でCSRF対策を行っています。
templates/create_folders.html{% csrf_token %}また、以下の部分でフォルダー作成のためのフォームを展開しています。
create_folders.html{{ form.as_p }}
as_p
とは、<p> formの内容 </p>という形で展開されるということです。
次に、viewを書いていきます。
View
viewに以下の
create_folder
メソッドを追加します。views.pyfrom django.shortcuts import render, get_object_or_404, redirect#redirect関数を追加 from .forms import FolderForm def create_folder(request): if request.method == "POST": form = FolderForm(request.POST) if form.is_valid(): folder = form.save(commit=False) folder.created_at = timezone.now() folder.save() return redirect('tasks.index', id=folder.id) else: form = FolderForm() return render(request, 'create_folders.html', {'form': form})まず最初に、作成したFolderFormとredirect関数をインポートしています。
その後に、
create_folder
関数を定義しています。
request.POST にデータが追加されているとき、formに入力された内容がデータベースに保存されるようにif文の処理を書いています。確認
これでフォルダー作成機能は実装できました!
http://localhost:8000/folders/create にしてみて、以下のように表示されていればOKです!
タスク作成機能の実装
URLの設定
まず、以下の定義を踏まえてURLを設定していきます。
URL 処理 <int:id>/tasks/create タスクを新たに作成する この設計にするために、
todo/urls.py
に次の一文を加えてください。todo/urls.pypath('<int:id>/tasks/create', views.create_task, name='tasks.create')フォームの作成
forms.pyでタスク作成のためのフォームを作成します。
以下の、TaskFormクラスを追加しますtodo/forms.pyfrom .models import Folder, Task#Taskモデルをインポート class TaskForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(TaskForm, self).__init__(*args, **kwargs) for field in self.fields.values(): field.widget.attrs = { 'class': 'form-control' } class Meta: STATUS_CHOICES = [(1, '未完了'),(2, '作業中'),(3, '完了')] model = Task fields = ('title', 'status','due_date') labels = { 'title': 'タスク名', 'status': '状態', 'due_date': '期限', }まずはじめに、Taskモデルをインポートしています。
そしてTaskForm
クラスを追加しています。フォルダー作成ページへのリンク
templates/index.html
のタスクを追加する
の部分にリンクを以下のように追加します。index.html<a href="{% url 'tasks.create' id=current_folder _id %}" class="btn btn-default btn-block">テンプレート
templates
ディレクトリ下にcreate_tasks.html
を作成します。
create_tasks.html
を以下のように編集します。templates/create_tasks.html{% load static %} <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Todo</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css"> <link rel="stylesheet" href="https://npmcdn.com/flatpickr/dist/themes/material_blue.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootflat/2.0.4/css/bootflat.min.css"> <link rel="stylesheet" href="{% static 'css/style.css' %}"> </head> <body> <header> <nav class="my-navbar"> <a class="my-navbar-brand" href="/">Todo</a> </nav> </header> <main> <div class="container"> <div class="row"> <div class="col col-md-offset-3 col-md-6"> <nav class="panel panel-default"> <div class="panel-heading">タスクを追加する</div> <div class="panel-body"> <form method="POST"> {% csrf_token %} {{ form.as_p }} <div class="text-right"> <button type="submit" class="btn btn-primary">送信</button> </div> </form> </div> </nav> </div> </div> </div> </main> <script src="https://npmcdn.com/flatpickr/dist/flatpickr.min.js"></script> <script src="https://npmcdn.com/flatpickr/dist/l10n/ja.js"></script> <script> flatpickr(document.getElementsByName('due_date'), { locale: 'ja', minDate: new Date() }); </script> </body> </html>次に、viewを書いていきます。
View
viewに以下の
create_task
メソッドを追加します。views.pyfrom .forms import FolderForm, TaskForm#TaskFormをインポートする def create_task(request, id): #選ばれたフォルダを取得する current_folder = get_object_or_404(Folder, id=id) if request.method == "POST": form = TaskForm(request.POST) if form.is_valid(): task = form.save(commit=False) task.created_at = timezone.now() task.folder_id = current_folder task.save() return redirect('tasks.index', id=current_folder.id) else: form = TaskForm() return render(request, 'create_tasks.html', {'form': form}, {'id':current_folder.id})注意するところは以下の部分。
task.folder_id = current_folder
folder_id
は外部キーですが、外部キーを設定するときはオブジェクトを渡す必要があります(今回の場合はFolderオブジェクト)。テンプレートの拡張
テンプレートは同じ情報やレイアウトを複数の場所で利用したいときに役立ちます。 各ファイル内で繰り返す必要はありません。
元となるテンプレートを作るために、
todo/templates
ディレクトリ配下にbase.html
ファイルを作ります。templates ├── base.html ├── create_folders.html ├── create_tasks.html └── index.html
base.html
を以下のように編集します。base.html{% load static %} <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Todo</title> {% block styles %} {% endblock %} <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootflat/2.0.4/css/bootflat.min.css"> <link rel="stylesheet" href="{% static 'css/style.css' %}"> </head> <body> <header> <nav class="my-navbar"> <a class="my-navbar-brand" href="{% url 'tasks.index' id=1 %}">Todo</a> </nav> </header> <main> {% block content %} {% endblock %} </main> {% block scripts %} {% endblock %} </body> </html>以下の部分、HTMLが挿入されていきます。
{% block styles %} {% endblock %}ファイルの最初に以下を記述することで、base.htmlを拡張していくことができます。
{% extends 'base.html' %}これをもとに、
create_folders.html
、create_tasks
、index.html
を以下のように編集します。create_folders.html{% extends 'base.html' %} {% block content %} <div class="container"> <div class="row"> <div class="col col-md-offset-3 col-md-6"> <nav class="panel panel-default"> <div class="panel-heading">フォルダーを追加する</div> <div class="panel-body"> <form method="POST"> {% csrf_token %} {{ form.as_p }} <div class="text-right"> <button type="submit" class="btn btn-primary">送信</button> </div> </form> </div> </nav> </div> </div> </div> {% endblock %}create_tasks.html{% extends 'base.html' %} {% block styles %} <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css"> <link rel="stylesheet" href="https://npmcdn.com/flatpickr/dist/themes/material_blue.css"> {% endblock %} {% block content %} <div class="container"> <div class="row"> <div class="col col-md-offset-3 col-md-6"> <nav class="panel panel-default"> <div class="panel-heading">タスクを追加する</div> <div class="panel-body"> <form method="POST"> {% csrf_token %} {{ form.as_p }} <div class="text-right"> <button type="submit" class="btn btn-primary">送信</button> </div> </form> </div> </nav> </div> </div> <div> {% endblock %} {% block scripts %} <script src="https://npmcdn.com/flatpickr/dist/flatpickr.min.js"></script> <script src="https://npmcdn.com/flatpickr/dist/l10n/ja.js"></script> <script> flatpickr(document.getElementsByName('due_date'), { locale: 'ja', minDate: new Date() }); </script> {% endblock %}index.html{% extends 'base.html' %} {% block content %} <div class="container"> <div class="row"> <div class="col col-md-4"> <nav class="panel panel-default"> <div class="panel-heading">フォルダー</div> <div class="list-group"> {% for folder in folders %} <a href="{% url 'tasks.index' id=folder.id %}", class="list-group-item {% if current_folder_id == folder.id %}active{% endif %}" > {{ folder.title }} </a> {% endfor %} </div> <div class="panel-body"> <a href="{% url 'folders.create' %}" class="btn btn-default btn-block"> フォルダーを追加する </a> </div> </nav> </div> <div class="column col-md-8"> <div class="panel panel-default"> <div class="panel-heading">タスク</div> <table class="table"> <thead> <tr> <th>タイトル</th> <th>状態</th> <th>期限</th> <th></th> </tr> </thead> <tbody> {% for task in tasks %} <tr> <td>{{ task.title }}</td> <td> <span class="label {% if task.status == 1 %}label-danger{% endif %}{% if task.status == 2 %}label-info{% endif %}" > {{ task.get_status_display }} </span> </td> <td>{{ task.due_date }}</td> <td><a href="{% url 'tasks.edit' id=current_folder_id task_id=task.id %}">編集</a></td> </tr> {% endfor %} </tbody> </table> <div class="panel-body"> <div class="text-right"> <a href="{% url 'tasks.create' id=current_folder_id %}" class="btn btn-default btn-block"> タスクを追加する </a> </div> </div> </div> </div> </div> </div> {% endblock %}おわりに
これでこのチャプターは終わりです!
ここまでのコードは、リポジトリのchapter4ブランチにあります。
次のチャプターではタスク編集機能を実装していきます!記事一覧
DjangoでTodoアプリを作る①Dockerで環境を構築する
DjangoでTodoアプリを作る②フォルダ一覧ページの作成
DjangoでTodoアプリを作る③タスク一覧ページの作成
DjangoでTodoアプリを作る④フォルダー、タスク作成機能の実装
DjangoでTodoアプリを作る⑤タスク編集機能の作成
- 投稿日:2020-04-26T12:01:50+09:00
HTTP Real Worldの ハンズオンの準備をWindows10+Vagrant+Docker+VsCodeで行ったメモ
概要
Real World HTTP 第2版――歴史とコードに学ぶインターネットとウェブ技術を買った。
ハンズオンが準備されていたので、その環境設定を行ったメモ。
- ソース
環境
- Windows 10 Home
- Vagrant 2.2.7
- virtualbox 6.1.6
- ubuntu 18.04 LTS
- docker-ce Docker version 19.03.5, build 633a0ea838
- docker-compose version 1.25.3, build d4d1b42b
環境構築
chocolateyの準備
- 使用するパッケージを簡単にインストールできるように、Windows用のパッケージマネージャを導入
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command " [System.Net.ServicePointManager]::SecurityProtocol = 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"curl の準備
- gitbashのものを使用する
choco install git -ygolangの準備
エディタ
- vscodeのおススメを利用。(.vscode/extensions.json)に記述
- 上記を利用するために、golangのパスの場所が必要になったのでchocolateyでインストール
choco install golang -y
- TabNineの初期設定を確認するときは、ctrl+shift+pでコマンドパレットを開いて、
TabNine:config
を入力。パスを確認する。実行環境
- vagrant上でdockerを動かす。
docker/docker-compose.ymlversion: "3" services: realworld: build: ./golang volumes: - ../src:/app/src working_dir: /app ports: - 18888:18888docker/golang/DockerfileFROM golang:latestbin/go.sh#!/bin/bash bin_dir=$(cd $(dirname $0) && pwd) parent_dir=$bin_dir/.. docker_dir=$parent_dir/docker composeFile=${1:-"docker-compose.yml"} container_name=${1:-realworld} docker ps | grep $container_name if [ $? -eq 0 ]; then cd $docker_dir && docker-compose exec $container_name go run /app/src/server.go else cd $docker_dir && docker-compose run --service-ports $container_name go run /app/src/server.go fisrc/server.gopackage main import ( "fmt" "log" "net/http" "net/http/httputil" ) func handler(w http.ResponseWriter, r *http.Request) { dump, err := httputil.DumpRequest(r, true) if err != nil { http.Error(w, fmt.Sprint(err), http.StatusInternalServerError) return } fmt.Println(string(dump)) fmt.Fprintf(w, "<html><body>Hello</body></html>\n") } func main() { var httpServer http.Server http.HandleFunc("/", handler) log.Println("start http listening :18888") httpServer.Addr = ":18888" log.Println(httpServer.ListenAndServe()) }動作確認
- 上記を準備した後、vagrant上で
go.sh
を動かせば検証用のサーバが起動する。
- curlでアクセスして確認
curl --http1.0 http://192.168.50.10:18888/greeting
参考
Chocolatey Software | Installation
Chocolateyを使った環境構築の時のメモ
Docker で Go の開発環境を構築する
VSCode + golang での快適な補完について自分なりにまとめてみた
docker-compose run は port を mapping しない
- 投稿日:2020-04-26T11:00:16+09:00
コンテナオーケストレーション入門?#1(Swarmを使ってみる)
はじめに
Swarmを使用しながら、コンテナオーケストレーションの概要を体験したいと思います。
環境
- macOS Mojave 10.14.6
- Docker engine 19.03.5
内容
- Swarm機能を有効化する
- サービスを作成する
- タスクを確認する
- レプリカを作成する
- コンテナをダウンさせ、復旧させる
Swarm機能をOnにする
SwarmはDockerに付属しているAPIではあるものの、デフォルトでは使用できない状態になっています。
使用するためには、設定を変更する必要があります。現在の設定を確認する
以下のコマンドを使用することで、現在のDockerの設定を確認することができます。
docker info ... # Swarm: inactive (Swarmが使用できない状態)Swarm機能をOnにする
以下のコマンドを使用することで、Swarm機能を有効化します。
docker swarm init # Swarm initialized: current node (lo0dewyehl9qi1fd1thnza9bx) is now a manager. # To add a worker to this swarm, run the following command: # docker swarm join --token SWMTKN-1-3y9vcbhfi1ppllmqj1971ua0brhx7k52gjmhlu0264oxjpsrqm-7rbc4fnt7llsze1ou22uszkbh 192.168.65.3:2377 # To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.このノードは新しいマネジャーです。
と表示されています。
どういうことでしょうか。
docker swarm init
で起こること
docker swarm init
を行うと、今後Swarmを使用していくに当たって必要な設定が自動で行われます。
例えば...
- 公開鍵基盤(PKI)の自動設定
- ルート証明書の設定
- Join Tokenの生成
Swarmを使用することで、コンテナやそのネットワークはどんどん拡張されていきます。
ネットワークの通信を暗号化したりなど、ネットワークセキュリティに必要な内容を自動で設定しています。また、RAFTデータベースがバックグラウンドで作成されています。
ここにはSwarmの構成や最初のマネジャーが格納され、暗号化されています。このDBが自動で生成されているおかげで、これまで必要とされてきたコンフィグ用のDBは必要ありません。
docker node ls
以下のコマンドを使用することで、ノードの一覧を確認することができます。
docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION lo0dewyehl9qi1fd1thnza9bx * docker-desktop Ready Active Leader 19.03.8
docker swarm init
を実行したことで、マネジャーノードが1つ作成されています。
また、StatusがLeader
となっています。Pets vs Cattles
オンプレミスとクラウドは、しばしばペットと家畜に例えられます。
これはコンテナオーケストレーションを扱う際にも当てはまります。クラウド以前は、サーバー1台をオンプレミスで運用し、不調があれば修正するなどペットのように可愛がる必要がありました。
クラウドの時代では、サーバー1台だけを運用する事はありません。複数台のサーバー群を運用し、不調の際は手間をかける事なく落とし、代わりを立ち上げます。
コンテナオーケストレーションは、まさにコンテナやノードを「群れ」という単位で扱います。
群れに対して操作を行い、新しい群れを作成したり、群ごと削除したりできます。
docker service create
以下のコマンド実行することで、新しいサービスを作成することができます。
GoogleのDNSサーバー8.8.8.8
にpingを送り続けるaplineイメージからサービスを作成します。docker service create alpine ping 8.8.8.8 # zn0631k8t6067p9gb517m6p87
docker run
した時と同じように、IDが出力されています。
これはサービスIDです。
docker service ls
以下のコマンドを実行することでサービスの一覧を確認することができます。
docker service ls # ID NAME MODE REPLICAS IMAGE PORTS # zn0631k8t606 kind_perlman replicated 1/1 alpine:latest'REPLICAS'の値を確認することで、サービスの実行数が確認できます。
今は1/1
となっています。
docker service ps
以下のコマンドを使用することで、サービス内に含まれるタスク(コンテナ)の一覧を表示することができます。
docker service ps kind_perlman # ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS # taaj0dalmte5 kind_perlman.1 alpine:latest docker-desktop Running Running 10 minutes agoデフォルトで作成されたノードに、タスク(コンテナ)が作成されています。
docker service update
では、このサービスのレプリカを増やしてみます。
以下のupdate
コマンドを実行することで、レプリカを増やし冗長化を図ることができます。docker service update zn06 --replicas 3 # zn06 # overall progress: 3 out of 3 tasks # 1/3: running [==================================================>] # 2/3: running [==================================================>] # 3/3: running [==================================================>] # verify: Service converged
docker service ls
でサービスを確認すると、レプリカの数が増えていることが確認できます。docker service ls # ID NAME MODE REPLICAS IMAGE PORTS # zn0631k8t606 kind_perlman replicated 3/3 alpine:latestまた、`
docker service ps
を実行することで、コンテナも増えていることが確認できます。docker service ps kind_perlman # ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS # taaj0dalmte5 kind_perlman.1 alpine:latest docker-desktop Running Running 18 minutes ago # l5ply9585ptc kind_perlman.2 alpine:latest docker-desktop Running Running 2 minutes ago # rhnb1bnfsic3 kind_perlman.3 alpine:latest docker-desktop Running Running 2 minutes agoコンテナの
NAME
に、番号が自動で添えられているのもすごいですね。自動で名前が一意になるようになっています。
update
コマンドを使用することでコンテナを停止したり新しく作り直すことなしに、変更を加えることができます。
これは稼働率を確保する上で重要な特徴です。これはSwarmを使用する目的の一つでもあります。コンテナやその集合でできた環境を停止することなく、レプリケーションしたり、変更を加えることができるようになります。
もしコンテナの一部がダウンしたら
もしコンテナの一部がダウンしたらどうなるか、試してみます。
以下のコマンドを使用して、コンテナの一つを削除してみます。
docker container rm -f kind_perlman.1.taaj0dalmte5iqmagqgy97tbtサービスを確認してみると、
docker service ls # ID NAME MODE REPLICAS IMAGE PORTS # zn0631k8t606 kind_perlman replicated 3/3 alpine:latestあれ? 特に変化ありませんね。
では、タスク一覧を確認してみます。
docker service ps kind_perlman # ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS # ztbj2mfbzqzh kind_perlman.1 alpine:latest docker-desktop Running Running 18 seconds ago # taaj0dalmte5 \_ kind_perlman.1 alpine:latest docker-desktop Shutdown Failed 23 seconds ago "task: non-zero exit (137)" # l5ply9585ptc kind_perlman.2 alpine:latest docker-desktop Running Running 37 minutes ago # rhnb1bnfsic3 kind_perlman.3 alpine:latest docker-desktop Running Running 37 minutes agoコンテナ
kind_perlman.1
は確かに削除されています。でも、その数秒後には同名のコンテナが復活しています。
これがSwarmを初めとするコンテナオーケストレーションの強みです。
コンテナが落ちたとしても、即座に元の状態に自動て復旧します。
docker service rm
以下のコマンドを使用することで、サービスを削除することができます。
docker service rmサービスだけでなく、サービスに紐づいているタスク(コンテナ)も削除されます。
まとめ
- Swarm機能を有効化する
- サービスを作成する
- タスクを確認する
- レプリカを作成する
- コンテナをダウンさせ、復旧させる
上記を確認しながら、コンテナオーケストレーションの強みがわかってきました。
- 投稿日:2020-04-26T09:11:45+09:00
初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編 パート3
背景
個人的にインフラの知識以上にこれからのアプリケーションが動く環境を作ってデプロイしたりしてこれからの知識を身に着けたい。そしてより一層、自分の知識のアップデートをしたいと思いました。
その中でこの本に出会い、これから少しずつやったことを残し、未来の自分への手紙としてもあり、見つめ直せればと思いました。
引用や参考と今回の自分の勉強用の書籍の紹介
技術評論社『Kubernetes実践入門』のサンプルコード
Kubernetes実践入門 プロダクションレディなコンテナ&アプリケーションの作り方
実際の学びについて
書籍を読みながら、章ごとに少しずつ進めていきたいと思います。
GitHub のソースコードも使いながら学んで行きたいと思います。
この章の勉強は本当に書籍の写経が主になるかもしれません・・・勉強開始
- ExternalName を使って外部アプリケーションの名前を解決できることを確認します
書籍では
-o wide
を使用して確認しているので違いを比較できるように一旦確認
SELECTOR
が表示されるかを確認します > 前の章でもLabel
が重要なことが説明されていました-o wideなし$ kubectl get svc,ep mattermost-db NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/mattermost-db ClusterIP 10.104.31.215 <none> 3306/TCP 16h NAME ENDPOINTS AGE endpoints/mattermost-db 10.1.0.207:3306 16h-o wide付き$ kubectl get svc,ep mattermost-db -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/mattermost-db ClusterIP 10.104.31.215 <none> 3306/TCP 16h run=db NAME ENDPOINTS AGE endpoints/mattermost-db 10.1.0.207:3306 16hService を作成する
- ClusterIP が作成されてないことを確認
- Type が ExternalName になっていることを確認できます
$ kubectl create svc externalname ext-mattermost-db --external-name example.com service/ext-mattermost-db created $ kubectl get svc,ep ext-mattermost-db -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/ext-mattermost-db ExternalName <none> example.com <none> 35s app=ext-mattermost-db NAME ENDPOINTS AGE endpoints/ext-mattermost-db <none> 35s作成した ext-mattermost-db / example.com の名前解決をしてみる
$ kubectl run -it --rm test3 --image=k8spracticalguide/busybox:1.28 --restart=Never -- /bin/sh If you don't see a command prompt, try pressing enter. / # nslookup ext-mattermost-db Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: ext-mattermost-db Address 1: 2606:2800:220:1:248:1893:25c8:1946 Address 2: 93.184.216.34 # ext-mattermost-dbを名前解決した結果 / # nslookup example.com Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: example.com Address 1: 2606:2800:220:1:248:1893:25c8:1946 Address 2: 93.184.216.34 # example.comを名前解決した結果次は 3.5.4 章をやっていきます。
ClusterIP を使わない Headless Service を学んで行きます
最後に
個人的には、下記のようなコマンドで確認ができるよ!と書籍で記載してもらっているのが非常に助かりました。
何度も、コマンドラインで確認するために下記のようなコマンドが出現すると自然とこういう確認ができるよね!
って思える様になります
kubectl run -it --rm test3 --image=k8spracticalguide/busybox:1.28 --restart=Never -- /bin/sh
今回も、前回同様ポータビリティという言葉がぴったりハマりました。(ハマり はGood な意味です)
書籍の中で下記の言葉がすっごく印象的でした。引用させていただきます。このように、クラスタ外部のアプリケーションであっても、ExternalName を使用することで内部のアプリケーションと同じように Service 名でアクセスできます。もし将来的に、本番環境のデータベースも Kubernetes クラスタ上にデプロイすることになったとしても、Service 名を変えずに Service の種類だけを変更できるので、データベースを使用するアプリケーションに変更が及びません。
今までの投稿
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Pod編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)NameSpace 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Label 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)ReplicaSet 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Deployment 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Service 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)ConfigMap 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)Secret 編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)操作編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編パート2
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編パート3(Label操作)
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)体感編パート3(OwnerReference 操作)
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)マニュフェスト編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)マニュフェスト(ConfigMap)編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編
- 初心者のKubernetes入門(書籍 Kubernetes 実践入門の写経から学ぶ)通信編 パート2
- 投稿日:2020-04-26T08:11:49+09:00
UnityのPackageManagerに自分のパッケージを入れるまで
概要
最近、自作のEditor拡張等を入れてAssetフォルダに増えるのが厳しい感じがしたので、Unityの機能であるPackageManagerに登録することにしました。その備忘録になります。
PCに直接npmやらVerdaccio入れるのはつらい気持ちがあるので、Dockerなるものを使います。材料
※私の環境はWindows10 Homeのため
* Docker Toolbox - v19.03.1手順
1. 下準備
上記のDocker Toolboxはあらかじめインストールしておきます。
参考 - Windows環境にDocker Toolboxをインストールする2. docker-compose.ymlを作る
docker composeってなんぞや?
Compose とは、複数のコンテナを使う Docker アプリケーションを、定義・実行するツールです。Compose はアプリケーションのサービスの設定に、Compose ファイルを使います。そして、コマンドを1つ実行するだけで、設定した全てのサービスを作成・起動します。 - Docker ドキュメント日本語化プロジェクトより
その複数のコンテナを使う Docker アプリケーションを、定義するためのファイルがdocker-compose.ymlとのことです。
まずは今回のプロジェクト用のフォルダを作成し、その中にdocker-compose.ymlファイルを配置します。
フォルダ構成はこんな感じ。(Cドライブのどこかに置くこと)- LocalNpmPackageServer ├ verdaccio │ ├ config │ │ └ config.yml │ ├ plugins │ └ storage └ docker-compose.yml中身は下記
docker-compose.ymlversion: '3.1' services: verdaccio: image: verdaccio/verdaccio container_name: "verdaccio" networks: - node-network environment: - VERDACCIO_PORT=4873 ports: - "4873:4873" volumes: - "./verdaccio/storage:/verdaccio/storage" - "./verdaccio/config:/verdaccio/conf" - "./verdaccio/plugins:/verdaccio/plugins" networks: node-network: driver: bridge今回はUnityのPackageManagerのレジストリサーバーとして、Verdaccioの構成を定義しています。
3. config.yamlを作る
Verdaccioのコンフィグファイルを作成します。docker-compose.ymlのvolumesに定義されている ./verdaccio/configに配置します。
中身は下記。config.ymlstorage: ../storage auth: htpasswd: file: ./htpasswd uplinks: npmjs: url: https://registry.npmjs.org/ packages: '**': access: $all publish: $authenticated proxy: npmjs logs: - {type: stdout, format: pretty, level: http}ここで定義されているstoregeの位置はdocker-compose.ymlのvolumesに定義した./verdaccio/storageの位置です。
4.起動する
Docker Toolboxを入れたタイミングでDocker Quickstart Terminalが追加されているはずなので、起動します。
くじらのAAの黒い画面が出てきたら、docker is configured to use the default machine with IP なんとか
と、IPアドレスが出ているので覚えておきましょう。
そしてdocker-compose.ymlを置いたプロジェクトフォルダへ移動します。コマンドcd "プロジェクトフォルダのパス"移動したらDockerを起動するためのコマンドを入れます。
コマンド# デーモン状態で起動する場合はこっち(このターミナルを閉じても動いてる) docker-compose up -d # 普通に動かす場合はこっち docker-compose up
http://先ほど出ていたIPアドレス:4873
をブラウザに入れて、Verdaccioの画面が表示されたらこれで環境は作成完了です。5. パッケージを作成する
参考 - UNITYPACKAGEMANAGERのレジストリサーバーを立てる話
Unityでの作業になります。
- パッケージ構成について
個人的にはこのようなフォルダ構成にしています。
- OriginalPackage │ ├ Runtime │ │ └ OriginalPackage.Runtime.asmdef │ ├ Editor │ │ └ OriginalPackage.Editor.asmdef └ package.jsonこの時に注意するのはEditorのAssembly DefinitionのPlatformsの設定で、Any Platformのチェックを外し、Editorのみにしておきます。
また、後ほどPackageManagerからインストールする際に既に存在しているとインストールできないため、同じプロジェクトに入れる場合は最初の作成が終わったら登録する前に別の(プロジェクト外の)場所に移しておきましょう。
- package.jsonについて
中身は下記
package.json{ "name": "jp.co.mypackage.originalpackage", "displayName": "Original Package", "version": "1.0.0", "unity": "2018.1", "description": "My original package.", "keywords": [ "editor" ], "category": "", "relatedPackages": {}, "dependencies": {}, "repository": {}, "author": { "name": "My Name", "url": "" }, "license": { "type": "MIT", "url": "https://monry.mit-license.org" } }このうち、上から5項目(name・displayName・version・unity・description)は必須です。
上記の必須でない項目の一部はVerdaccioで表示されたりします。6.パッケージを登録する
またDocker Quickstart Terminalに戻ります。
まずユーザー登録をします。
コマンドnpm adduser --registry http://4で出てたIP:4873ユーザー名、パスワード、メアドを登録します。
で、ログイン。コマンドnpm login --registry http://4で出てたIP:4873で、登録。
コマンドcd "OriginalPackageのフォルダパス" npm publish --registry http://4で出てた:4873これで登録完了です。
ちなみに上記のコマンドたちは、立ち上げたVerdaccioのページに書いてあるのでコピペすると良いです。この状態でVerdaccioのページを読み込み直すとパッケージが登録されているのが確認できると思います。
7.UnityのPackageManagerからインストールする
最後です。Unityのプロジェクトフォルダ/Package/manifest.jsonを開きます。
そこに下記のようにscopedRegistriesを追加します。(dependencies以下は元からあるはずです)manifest.json{ "scopedRegistries": [ { "name": "my-package-name", "url": "http://4で出てたIP:4873/", "scopes": [ "jp.co.mypackage" ] } ], "dependencies": { "com.unity.collab-proxy": "1.2.16", "com.unity.ide.rider": "1.1.4", "com.unity.ide.vscode": "1.1.4", "com.unity.test-framework": "1.1.11", "com.unity.textmeshpro": "2.0.1", "com.unity.timeline": "1.2.12" } }これでUnityに戻りPackageManagerを見ると出ていると思います。
- 投稿日:2020-04-26T01:42:40+09:00
【LINUXコマンド】オプションの短縮表記一覧
オプションの短縮表記一覧
______________________
コマンドA____
-a
-AB____
-b
-BC____
-c
-CD____
-d
-DE____
-e
-EF____
-f
-FG____
-g
-GH____
-h
-HI____
-i
-IJ____
-j
-JK____
-k
-KL____
-l
-LM____
-m
-MN____
-n
-NO____
-o
-OP____
-p
-PQ____
-q
-QR____
-r
-RS____
-s
-ST____
-t
-TU____
-u
-UV____
-v
-VW____
-w
-WX____
-x
-XY____
-y
-YZ____
-z
-Z0____
-01____
-12____
-23____
-34____
-45____
-56____
-67____
-78____
-89____
-9#____
-#_____
-?ls1 a2
A3b4
B5c6
C7d8
D9- f10
F11G12 h13
H14i15
I16- k17 l18
L19m20 n21
N22o23 p24 q25
Q26R27 s28
S29t30
T31u32
U33v34 w35 x36
X37- Z38 - 139 - - - - - - - - - - touch40 a41 - c42 d43 - f44 - h45 - - - - m46 - - - - r47 - t48 - - - - - - - - - - - - - - - - - - cp49 a50 b51 c52 d53 - f54 - H55 i56 - - l57 - n58 - p59
P60q r27
R27s61 t62
T63u64 v65 - x66 - Z67 - - - - - - - - - - - - mv68 - b69 - - - f54 - - i56 - - - - n58 - - - - S70 t62
T63u64 v65 - - - Z38 - - - - - - - - - - - - mkdir71 - - - - - - - - - - - - m72 - - p73 - - - - - v65 - - - Z74 - - - - - - - - - - - - rmdir75 - - - - - - - - - - - - - - - p73 - - - - - v65 - - - - - - - - - - - - - - - - chown76 - - c77 - - f78 - h45
H79- - - L80 - - - P81 - R27 - - - v65 - - - - - - - - - - - - - - - - chmod82 - - c77 - - f78 - - - - - - - - - - - R27 - - - v65 - - - - - - - - - - - - - - - - cat83 A84 b85 - - e86
E87- - - - - - - - n88 - - - - s89 t90
T91u92 v93 - - - - - - - - - - - - - - - - head94 - - c95 - - - - - - - - - - n96 - - q97 - - - - v65 - - - - - - - - - - - - - - - - tail98 - - c95 - - f99
F100- - - - - - - n96 - - q97 - s101 - - v65 - - - - - - - - - - - - - - - - wc102 - - c95 - - - - - - - - l103
L104m105 - - - - - - - - - w106 - - - - - - - - - - - - - - - sort107 - b108 c109
C110d111 - f112 g113 h114 i115 - k116 - m117
M118n119 o120 - - r121
R122s123
S124t125
T126u127 V128 - - - z129 - - - - - - - - - - - - uniq130 - - c131 d132
D133- f134 - - i135 - - - - - - - - - s136 - u127 - w137 - - z129 - - - - - - - - - - - - diff138 a139 b140
B141c142
C142d143
D144e145
E146F147 - - i135
I148- - l149 - n150
N151- p152 q153 r27 s154
S155t156
T157u158
U158v159 w160
W35x161
X162y163 Z164 - - - - - - - - - - - - grep165 a139
A166b167
B168c131
C142d169
D170e171
E172f173
F174G175 h176
H177i135
I178- - l179
L180m181 n182 o183 P184 q97 r27
R185s186 T157 u187
U188v189
V159w190 x191 - z192
Z193- - - - - - - - - - - - curl194 a195
A196b197
B198c199
C200d201
D202e203
E204f205
F206g207
G208h209
H210i211
I212j213
J214k215
K216l217
L218m219
M220n221
N222o120
O223p224
P225q226
Q227r228
R229s230
S231t232
T233u234
U235v65
V159w236 x237
X238y239
Y240z241 0242 1243 2244 3245 4246 - 6247 - - - #248 - tar249 a250
A251b252
B253c254
C255d256 - f173
F257g258
G259h260
H261i262
I263j264
J265k266
K267l268
L269m270
M271n272
N273o274
O275p276
P277- r278
R279s280
S281t282
T283u64
U284v65
V285w286
W287x288
X162- z289
Z290- - - - - - - - - - - ?291 gzip292 - - c293 d294 - f54 - h209 - - - l295
L296- n297
N298- - q299 r27 S70 t300 - v65
V159- - - - - 1301 - - - - - - - 9302 - - kill303 a2 - - - - - - h209 - - - l295
L304- - - p305 q306 - s307 - - V159 - - - - - - - - - - - - - - - - df308 a2 B309 - - - - - h13
H310i311 - k312 l313 - - - P314 - - - t315
T316- v317 - x318 - - - - - - - - - - - - - - free319 - b320 c131 - - - g321 h322 - - k323 l324 m325 - - - - - s326 t327 - V159 w328 - - - - - - - - - - - - - - - vmstat329 a330 - - d331
D332- f333 - h209 - - - - m334 n335 - p336 - - s337
S338t339 - V159 w328 - - - - - - - - - - - - - - - git clone340 - b341 c342 - - - - - - j343 - l313 - n344 o345 - q299 - s346 - u347 v65 - - - - - - - - 4246 - 6247 - - - - - git init348 - - - - - - - - - - - - - - - - q299 - - - - - - - - - - - - - - - - - - - - - git add349 A2 - - - e350 f54 - - i56 - - - - n351
N352- p353 - - - - u64 v65 - - - - - - - - - - - - - - - - git mv354 - - - - - f54 - - - - k355 - - n351 - - - - - - - v65 - - - - - - - - - - - - - - - - git restore356 - - - - - - - - - - - - m117 - - p353 q299 - s357
S358- - - W359 - - - - - 2360 3361 - - - - - - - - git rm362 - - - - - f54 - - - - - - - n351 - - q299 r363 - - - - - - - - - - - - - - - - - - - - git diff364 a139 b140
B365C366 D367 - - G368 - - - - l369 M370 - O371 p353 - R372 s373
S374- u375
U158- w160
W376X377 - z378 - - - - - - - - - - - - git grep379 a139
A166B168 c131
C142- e380
E172f381
F174G175 h382
H383i135
I384- - l180
L180- n182 o183
O385p386
P184q299 r27 - - - v189 w190
W376- - z193 - - - - - - - - - - - - git log387 - - - - - - - - - - - L388 - - - - q299 - - - - - - - - - - - - - - - - - - - - - git show389 - - - - - - - - - - - L390 - - - - q299 - - - - - - - - - - - - - - - - - - - - - git status391 - b341 - - - - - - - - - - M370 - - - - - s392 - u393 v65 - - - z193 - - - - - - - - - - - - git branch394 a2 - c395C396 d397
D398- f54 - - i135 - - l295 m399
M400- - - q299 r401 - t402 u403 v65 - - - - - - - - - - - - - - - - git commit404 a2 - c405
C406- e350 F173 - - i211 - - - m407 n408 o409 p353 q299 - s410
S411t412 u393 v65 - - - z193 - - - - - - - - - - - - git merge413 - - - - e350 F173 - - - - - - m407 n414 - - q299 - s415
S411- - v65 - X416 - - - - - - - - - - - - - - git rebase417 - - C418 - - f419 - - i56 - k420 - m117 n421 - - q299 r422 s415
S411- - v65 - x423
X416- - - - - - - - - - - - - - git reset424 - - - - - - - - - - - - - n352 - p353 q299 - - - - - - - - - - - - - - - - - - - - - git switch425 - - c254
C426d427 - f54 - - - - - - m117 - - - q299 - - t402 - - - - - - - - - - - - - - - - - - git tag428 a429 - - d397 e350 f54
F173- - i135 - - l295 m407 n430 - - - - s431 - u432 v433 - - - - - - - - - - - - - - - - git fetch434 a195 - - - - f54 - - - j343 k435 - m436 n437 o438 p439
P440q299 - - t441 u442 v65 - - - - - - - - 4246 - 6247 - - - - - git pull443 a195 - - - - f54 - - - j343 k435 - - n444 - p439 q299 r445 s415
S411t441 - v65 - X416 - - - - - - 4246 - 6247 - - - - - git push446 - - - - d397 f54 - - - - - - - n351 o447 - q299 - - - u448 v65 - - - - - - - - 4246 - 6247 - - - - - docker build449 - - c450 - - f173 - - - - - - m451 - - - q299 - - t452 - - - - - - - - - - - - - - - - - - docker commit453 a454 - c455 - - - - - - - - - m407 - - p456 - - - - - - - - - - - - - - - - - - - - - - docker cp457 a50 - - - - - - - - - - L458 - - - - - - - - - - - - - - - - - - - - - - - - - - docker create459 a460 - c450 - e461 - - h462 i56 - - l463 m451 - - p464
P465- - - t466 u234 v467 w468 - - - - - - - - - - - - - - - docker events469 - - - - - f470 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - docker exec471 - - - d427 e461 - - - i56 - - - - - - - - - - t466 u234 - w468 - - - - - - - - - - - - - - - docker export472 - - - - - - - - - - - - - - o120 - - - - - - - - - - - - - - - - - - - - - - - docker history473 - - - - - - - h322 - - - - - - - - q299 - - - - - - - - - - - - - - - - - - - - - docker images474 a2 - - - - f470 - - - - - - - - - - q299 - - - - - - - - - - - - - - - - - - - - - docker import475 - - c455 - - - - - - - - - m407 - - - - - - - - - - - - - - - - - - - - - - - - - docker info476 a2 - - - - f477 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - docker inspect478 - - - - - f477 - - - - - - - - - - - - s28 - - - - - - - - - - - - - - - - - - - docker kill479 - - - - - - - - - - - - - - - - - - s307 - - - - - - - - - - - - - - - - - - - docker load480 - - - - - - - - i481 - - - - - - - q299 - - - - - - - - - - - - - - - - - - - - - docker login482 - - - - - - - - - - - - - - - p483 - - - - u234 - - - - - - - - - - - - - - - - - docker logs484 - - - - - f99 - - - - - - - - - - - - - t485 - - - - - - - - - - - - - - - - - - docker ps486 a2 - - - - f470 - - - - - l487 - n488 - - q299 - s28 - - - - - - - - - - - - - - - - - - - docker pull489 a2 - - - - - - - - - - - - - - - q299 - - - - - - - - - - - - - - - - - - - - - docker restart490 - - - - - f99 - - - - - - - - - - - - - t491 - - - - - - - - - - - - - - - - - - docker rm492 - - - - - f54 - - - - - l57 - - - - - - - - - v493 - - - - - - - - - - - - - - - - docker rmi494 - - - - - f54 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - docker run495 a460 - c450 d427 e461 - - h462 i56 - - l463 m451 - - p464
P465- - - t466 u234 v467 w468 - - - - - - - - - - - - - - - docker save496 - - - - - - - - - - - - - - o120 - - - - - - - - - - - - - - - - - - - - - - - docker search497 - - - - - f470 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - docker start498 a460 - - - - - - - i56 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - docker stats499 a2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - docker stop500 - - - - - - - - - - - - - - - - - - - t491 - - - - - - - - - - - - - - - - - - docker update501 - - c450 - - - - - - - - - m451 - - - - - - - - - - - - - - - - - - - - - - - - - docker version502 - - - - - f477 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 青字: エイリアスオプションなし
赤字: エイリアスオプションがあるが、頭文字が異なる感想
ls
やtar
やcurl
など、短縮表記を丸暗記しまっているものを、横並びに確認することで、理解が深まるかと思い作成した。(ただし、めちゃくちゃ時間がかかった。)
短縮表記は、よく使われるオプションでもあるので、コマンドの理解も少し深まった。
類似が多いわけではないので、あまり役に立たないかもしれないが、自分でオプション付きのコマンドを作るときは参考になるかもしれない。
ただし、自分でコマンドを作るとき、短縮表記は必要最低限から始めるのがいいだろう。編集リクエストも歓迎しています。
※ ただし、注釈が多すぎるためか、投稿/更新に失敗する頻度がとても高いので注意その他(編集用テキスト)
|command[^command]|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|0|1|2|3|4|5|6|7|8|9|#|?|
ls (GNU coreutils) 8.22
ls --help
参照 ↩
--all
↩
--almost-all
↩
--escape
↩
--ignore-backups
↩with -lt: sort by, and show, ctime (time of last modification of file status information); with -l: show ctime and sort by name; otherwise: sort by ctime, newest first ↩
list entries by columns ↩
--directory
↩
--dired
↩do not sort, enable -aU, disable -ls --color ↩
--classify
↩
--no-group
↩
--human-readable
↩
--dereference-command-line
↩
--inode
↩
--ignore
↩
--kibibytes
↩詳細リスト形式を表示する ↩
--dereference
↩要素のリストをカンマで区切り、一行に詰め込む ↩
--numeric-uid-gid
↩
--literal
↩-l と同様だがグループ情報を表示しない ↩
--indicator-style
↩
--hide-control-chars
↩
--quote-name
↩
--recursive
↩
--size
↩sort by file size ↩
ファイル更新時間で新しい順にソートする ↩
--tabsize
↩with -lt: sort by, and show, access time; with -l: show access time and sort by name; otherwise: sort by access time ↩
do not sort; list entries in directory order ↩
natural sort of (version) numbers within text ↩
--width
↩list entries by lines instead of by columns ↩
sort alphabetically by entry extension ↩
--context
↩list one file per line ↩
touch (GNU coreutils) 8.22
touch --help
参照 ↩アクセス日時のみ変更する ↩
--no-create
↩
--date
↩(無視される) ↩
--no-dereference
↩更新日時のみ変更する ↩
--reference
↩use [[CC]YY]MMDDhhmm[.ss] instead of current time ↩
cp (GNU coreutils) 8.22
cp --help
参照 ↩
--archive
↩--backup と同様だが引数を受け付けない ↩
deprecated, same as --preserve=context ↩
--no-dereference --preserve=links と同様 ↩
--force
↩follow command-line symbolic links in SOURCE ↩
--interactive
↩
--link
↩
--no-clobber
↩--preserve=mode,ownership,timestamps と同様 ↩
--no-dereference
↩
--symbolic-link
↩
--target-directory
↩
--no-target-directory
↩
--update
↩
--verbose
↩
--one-file-system
↩set SELinux security context of destination file to default type ↩
mv (GNU coreutils) 8.22
mv --help
参照 ↩--backup と同様だが引数を受け付けない ↩
--suffix
↩mkdir (GNU coreutils) 8.22
mkdir --help
参照 ↩
--mode
↩
--parents
↩set SELinux security context of each created directory to the default type ↩
rmdir (GNU coreutils) 8.22
rmdir --help
参照 ↩chown (GNU coreutils) 8.22
chown --help
参照 ↩
--changes
↩
--silent
,--quiet
↩if a command line argument is a symbolic link to a directory, traverse it ↩
traverse every symbolic link to a directory encountered ↩
do not traverse any symbolic links (default) ↩
chmod (GNU coreutils) 8.22
chmod --help
参照 ↩cat (GNU coreutils) 8.22
cat --help
参照 ↩
--show-all
↩
--number-nonblank
↩-vEと同じ ↩
--show-ends
↩
--number
↩
--squeeze-blank
↩-vTと同じ ↩
--show-tabs
↩(無視) ↩
--show-nonprinting
↩head (GNU coreutils) 8.22
head --help
参照 ↩
--bytes
↩
--lines
↩
--quiet
,--silent
↩tail (GNU coreutils) 8.22
tail --help
参照 ↩
--follow
↩same as --follow=name --retry ↩
--sleep-interval
↩wc (GNU coreutils) 8.22
wc --help
参照 ↩
--lines
↩
--max-line-length
↩
--chars
↩
--words
↩sort (GNU coreutils) 8.22
sort --help
参照 ↩
--ignore-leading-blanks
↩
--check
↩-c と同様だが、正しくソートされていない最初の行を出力しない ↩
--dictionary-order
↩
--ignore-case
↩
--general-numeric-sort
↩
--human-numeric-sort
↩
--ignore-nonprinting
↩
--key
↩
--merge
↩
--month-sort
↩
--numeric-sort
↩
--output
↩
--reverse
↩
--random-sort
↩
--stable
↩
--buffer-size
↩
--field-separator
↩
--temporary-directory
↩
--unique
↩
--version-sort
↩
--zero-terminated
↩uniq (GNU coreutils) 8.22
uniq --help
参照 ↩
--count
↩
--repeated
↩
--all-repeated
↩
--skip-fields
↩
--ignore-case
↩
--skip-chars
↩
--check-chars
↩diff (GNU diffutils) 3.3
diff --help
参照 ↩
--text
↩
--ignore-space-change
↩
--ignore-blank-lines
↩
--context
↩
--minimal
↩
--ifdef
↩
--ed
↩
--ignore-tab-expansion
↩
--show-function-line
↩
--ignore-matching-lines
↩
--paginate
↩
--rcs
↩
--new-file
↩
--show-c-function
↩
--brief
↩
--report-identical-files
↩
--starting-file
↩
--expand-tabs
↩
--initial-tab
↩
--unified
↩
--version
↩
--ignore-all-space
↩
--exclude
↩
--exclude-from
↩
--side-by-side
↩
--ignore-trailing-space
↩grep (GNU grep) 2.20
grep --help
参照 ↩
--after-context
↩
--byte-offset
↩
--before-context
↩
--directories
↩
--devices
↩
--regexp
↩
--extended-regexp
↩
--file
↩
--fixed-strings
↩
basic-regexp
↩
--no-filename
↩
--with-filename
↩equivalent to --binary-files=without-match ↩
--files-with-matches
↩
--files-without-match
↩
--max-count
↩
--line-number
↩
--only-matching
↩
--perl-regexp
↩
--dereference-recursive
↩
--no-messages
↩
--unix-byte-offsets
↩
--binary
↩
--invert-match
↩
--word-regexp
↩
--line-regexp
↩
--null-data
↩
--null
↩curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.44 zlib/1.2.7 libidn/1.28 libssh2/1.8.0
curl --help
参照 ↩
--append
↩
--user-agent
↩
--cookie
↩
--use-ascii
↩
--cookie-jar
↩
--continue-at
↩
--data
↩
--dump-header
↩
--referer
↩
--cert
↩
--fail
↩
--form
↩
--globoff
↩
--get
↩
--help
↩
--header
↩
--include
↩
--head
↩
--junk-session-cookies
↩
--remote-header-name
↩
--insecure
↩
--config
↩
--list-only
↩
--location
↩
--max-time
↩
--manual
↩
--netrc
↩
--no-buffer
↩
--remote-name
↩
--proxytunnel
↩
--ftp-port
↩If used as the first parameter disables .curlrc ↩
--quote
↩
--range
↩
--remote-time
↩
--silent
↩
--show-error
↩
--telnet-option
↩
--upload-file
↩
--user
↩
--proxy-user
↩
--write-out
↩
--proxy
↩
--request
↩
--speed-time
↩
--speed-limit
↩
--time-cond
↩
--http1.0
↩
--tlsv1
↩
--sslv2
↩
--sslv3
↩
--ipv4
↩
--ipv6
↩
--progress-bar
↩tar (GNU tar) 1.26
tar --help
参照 ↩
--auto-compress
↩
--catenate
,--concatenate
↩
--blocking-factor
↩
--read-full-records
↩
--create
↩
--directory
↩
--diff
,--compare
↩
--info-script
↩
--listed-incremental
↩
--incremental
↩
--dereference
↩
--format
↩
--ignore-zeros
↩
--use-compress-program
↩
--bzip2
↩
--xz
↩
--keep-old-files
↩
--starting-file
↩
--check-links
↩
--tape-length
↩
--touch
↩
--multi-volume
↩
--seek
↩
--newer
↩作成時は --old-archive と同じ. 抽出時は--no-same-owner と同じ ↩
--to-stdout
↩
--preserve-permissions
,--same-permissions
↩
--absolute-names
↩
--append
↩
--block-number
↩
--preserve-order
,--same-order
↩
--sparse
↩
--list
↩
--files-from
↩
--unlink-first
↩
--label
↩
--interactive
,--confirmation
↩
--verify
↩
--extract
,--get
↩
--gzip
,--gunzip
,--ungzip
↩
--compress
,--uncompress
↩
--help
↩gzip 1.5
gzip --help
参照 ↩
--stdout
↩
--decompress
↩
--list
↩
--license
↩
--no-namet
↩
--name
↩
--quiet
↩
--test
↩
--fast
↩
--best
↩kill from util-linux 2.23.2
/bin/kill --help
参照 ↩
--table
↩
--pid
↩
--queue
↩
--signal
↩df (GNU coreutils) 8.22
df --help
参照 ↩
--block-size
↩
--si
↩
--inodes
↩--block-size=1K と同様 ↩
--local
↩
--portability
↩
--type
↩
--print-type
↩(ignored) ↩
--exclude-type
↩free from procps-ng 3.3.10
free --help
参照 ↩
--bytes
↩
--giga
↩
--human
↩
--kilo
↩
--lohi
↩
--mega
↩
--seconds
↩
--total
↩
--wide
↩vmstat from procps-ng 3.3.10
vmstat --help
参照 ↩
--active
↩
--disk
↩
--disk-sum
↩
--forks
↩
--slabs
↩
--one-header
↩
--partition
↩
--stats
↩
--unit
↩
--timestamp
↩git version 2.25.1
git clone -h
参照 ↩
--branch
↩
--config
↩
--jobs
↩
--no-checkout
↩
--origin
↩
--shared
↩
--upload-pack
↩git version 2.25.1
git init -h
参照 ↩git version 2.25.1
git add -h
参照 ↩
--edit
↩
--dry-run
↩
--intent-to-add
↩
--patch
↩git version 2.25.1
git mv -h
参照 ↩skip move/rename errors ↩
git version 2.25.1
git restore -h
参照 ↩
--source
↩
--staged
↩
--worktree
↩
--ours
↩
--theirs
↩git version 2.25.1
git rm -h
参照 ↩allow recursive removal ↩
git version 2.25.1
git diff -h
参照 ↩
--break-rewrites
↩
--find-copies
↩
--irreversible-delete
↩look for differences that change the number of occurrences of the specified regex ↩
prevent rename/copy detection if the number of rename/copy targets exceeds given limit ↩
--find-renames
↩control the order in which files appear in the output ↩
swap two inputs, reverse the diff ↩
--no-patch
↩look for differences that change the number of occurrences of the specified string ↩
generate patch ↩
--function-context
↩
--dirstat
↩do not munge pathnames and use NULs as output field terminators in --raw or --numstat ↩
git version 2.25.1
git grep -h
参照 ↩match <pattern> ↩
read patterns from file ↩
don't show filenames ↩
show filenames ↩
don't match patterns in binary files ↩
--open-files-in-pager
↩
--show-function
↩git version 2.25.1
git log -h
参照 ↩Process line range n,m in file, counting from 1 ↩
git version 2.25.1
git show -h
参照 ↩Process line range n,m in file, counting from 1 ↩
git version 2.25.1
git status -h
参照 ↩
--short
↩
--untracked-files
↩git version 2.25.1
git branch -h
参照 ↩
--copy
↩copy a branch, even if target exists ↩
--delete
↩delete branch (even if not merged) ↩
--move
↩move/rename a branch, even if target exists ↩
--remotes
↩
--track
↩
--set-upstream-to
↩git version 2.25.1
git commit -h
参照 ↩
--reedit-message
↩
--reuse-message
↩
--message
↩
--no-verify
↩
--only
↩
--signoff
↩
--gpg-sign
↩
--template
↩git version 2.25.1
git merge -h
参照 ↩do not show a diffstat at the end of the merge ↩
--strategy
↩
--strategy-option
↩git version 2.25.1
git rebase -h
参照 ↩passed to 'git apply' ↩
--force-rebase
↩
--keep-empty
↩
--no-stat
↩
--rebase-merges
↩
--exec
↩git version 2.25.1
git reset -h
参照 ↩git version 2.25.1
git switch -h
参照 ↩
--force-create
↩
--detach
↩git version 2.25.1
git tag -h
参照 ↩
--annotate
↩print <n> lines of each tag message ↩
--sign
↩
--local-user
↩
--verify
↩git version 2.25.1
git fetch -h
参照 ↩
--keep
↩
--multiple
↩do not fetch all tags (--no-tags) ↩
--server-option
↩
--prune
↩
--prune-tags
↩
--tags
↩
--update-head-ok
↩git version 2.25.1
git pull -h
参照 ↩do not show a diffstat at the end of the merge ↩
--rebase
↩git version 2.25.1
git push -h
参照 ↩
--push-option
↩
--set-upstream
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker build --help
参照 ↩
--cpu-shares
↩
--memory
↩
--tag
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker commit --help
参照 ↩
--author
↩
--change
↩
--pause
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker cp --help
参照 ↩
--follow-link
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker create --help
参照 ↩
--attach
↩
--env
↩
--hostname
↩
--label
↩
--publish
↩
--publish-all
↩
--tty
↩
--volume
↩
--workdir
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker events --help
参照 ↩
--filter
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker exec --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker export --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker history --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker images --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker import --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker info --help
参照 ↩
--format
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker inspect --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker kill --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker load --help
参照 ↩
--input
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker login --help
参照 ↩
--password
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker logs --help
参照 ↩
--timestamps
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker ps --help
参照 ↩
--latest
↩
--last
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker pull --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker restart --help
参照 ↩
--time
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker rm --help
参照 ↩
--volumes
↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker rmi --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker run --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker save --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker search --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker start --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker stats --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker stop --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker update --help
参照 ↩Client: Docker Engine - Community; Version: 19.03.8; API version: 1.40;
docker version --help
参照 ↩
- 投稿日:2020-04-26T00:29:28+09:00
RootlessモードのDockerを試してみた
Docker 19.03で入った新機能であるDockerのRootlessモードを試してみました。
Rootlessモードとは
従来はroot権限でdockerデーモンを実行していたために、脆弱性やdockerソケットを渡すなどの設定ミスをしているとホストのroot権限を奪われてしまう可能性がありました。
Rootlessモードでは各ユーザでdockerデーモンを実行するため、脆弱性などがあった場合でもそのユーザの権限内でしか影響がなくなります(まあ、各ユーザから権限昇格されたら別でしょうが)。
RootlessモードのDockerをインストールする
実際にRootlessモードのDockerをインストールしてみます。
試した環境は以下のようになっています。
OS : Ubuntu 18.04(Hyper-V上)
Memory : 2GB
CPU : Intel Core i9
docker-composeインストール済み
インストールコマンドを実行する
$ curl -fsSL https://get.docker.com/rootless | sh.bashrcに追加を行う
インストールしたRootlesモードDockerバイナリとソケットのパスを.bashrcに記述します。インストールしたときにコンソール上に記述されている内容をコピペすればOKです。
export PATH=$HOME/bin:$PATH export DOCKER_HOST=unix:///run/user/1000/docker.sock自動起動の設定を行う
最後にRootlessモードのDockerの起動設定を行います。これはsystemctlで行います。
$ systemctl --user enable docker $ systemctl --user start docker実際にコマンドを実行してみる
単一コンテナの実行
まずは順当にhello-worldのコンテナを実行してみましょう。
$ docker run -it --rm hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 0e03bdcc26d7: Pull complete Digest: sha256:8e3114318a995a1ee497790535e7b88365222a21771ae7e53687ad76563e8e76 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/おお、sudoコマンドを使わずに行けました。
単一コンテナでポートを公開する
では、WEBサーバとして外部にポートを公開するコンテナを作ってみましょう。
昔、Dockerのポート公開はiptablesを使用してforwardしていると聞いたことがあるので、ここはさすがにいけないでしょうと思っていますが。
$ docker run -d --rm -p 80:80 nginx:1.17-alpine Unable to find image 'nginx:1.17-alpine' locally 1.17-alpine: Pulling from library/nginx cbdbe7a5bc2a: Pull complete c554c602ff32: Pull complete Digest: sha256:763e7f0188e378fef0c761854552c70bbd817555dc4de029681a2e972e25e30e Status: Downloaded newer image for nginx:1.17-alpine 45bc78be4cc1d2f35321ae80ea3d9fe82cfc3b545a17f16b2eb1c3ea81e5a535 docker: Error response from daemon: driver failed programming external connectivity on endpoint youthful_einstein (9fddff03eda43e5fc3d29328cc20040d5a1a57168bd2fcd7d08473f2a2af6e9d): Error starting userland proxy:.やっぱり駄目でした。。。
エラーメッセージからするとポート公開を設定しようとして、エラーになったようですね。
docker-composeを使ってみる
では、docker-composeで複数のコンテナを起動してみましょう。
以下の内容でdocker-compose.ymlを書きました。今回はとりあえず、giteaが動けばいいな~と思っています。
docker-compose.ymlversion: "3.7" services: server: image: gitea/gitea:latest environment: - USER_UID=1000 - USER_GID=1000 - DB_TYPE=postgres - DB_HOST=db:5432 - DB_NAME=gitea - DB_USER=gitea - DB_PASSWORD=gitea - DISABLE_SSH=false restart: always networks: - gitea volumes: - ./gitea:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - 3000:3000 depends_on: - db db: image: postgres:11-alpine restart: always environment: - POSTGRES_USER=gitea - POSTGRES_PASSWORD=gitea - POSTGRES_DB=gitea networks: - gitea volumes: - ./postgres:/var/lib/postgresql/data networks: gitea: external: false先ほどの例からするとポート公開で失敗しそうですが、とりあえず実行してみます。。。
$ docker-compose up -d Creating network "foo_gitea" with the default driver Creating foo_db_1 ... done Creating foo_server_1 ... done $ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------- foo_db_1 docker-entrypoint.sh postgres Up 5432/tcp foo_server_1 /usr/bin/entrypoint /bin/s ... Up 22/tcp, 0.0.0.0:3000->3000/tcpどうも、うまく動いていそうですね。
では、ブラウザから見てみましょう。
出ましたね。
まとめ
RootlessモードのDockerは単一で実行するようなもの(バッチ処理とか)には向いていそうです。
docker-composeでのポート公開とdockerコマンドでのポート公開で挙動が異なるのがかなり気になりますが、docker-composeを使えばWebアプリの開発環境でも使えそうです。それにしても、docker-composeのポート公開はどのようにして実現しているのでしょう??不思議でたまりません。どなたかご存じないでしょうか?