- 投稿日:2020-01-26T22:44:36+09:00
DockerでCMakeビルド環境を作る
はじめに
- WindowsPC上で、Linuxに対応したCppプロジェクトを作成したい
- CMakeのDockerコンテナを探しても見つからなかったので今回作成した
良い点
- ローカルフォルダをマウントするよう設定
- ローカルフォルダ上でコードを編集すると、すぐにコンテナへ変更が反映される
- コンテナにログインせずとも、VS code などのエディタで編集できる
- ビルド後のファイルもdocker cp コマンドを使わずに取り出せる
ダウンロード
- この記事で紹介したDocker imageは、DockerHub からダウンロードすることができます。
フォルダ構成
- 下図のようにDockerfile, docker-compose.ymlを配置する
- ソースコードは記事の下部に記載
- cppフォルダは、docker-compose up によって自動生成される
- このフォルダ内に ソースコードを置く
treeフォルダ構成 ├── Dockerfile ├── docker-compose.yml └── cpp ← 自動生成されるDockerfile
DockerfileFROM ubuntu:18.04 RUN apt-get update && \ apt-get install -y sudo && \ apt-get install -y vim && \ apt-get install -y wget # Install compilers. RUN apt-get install -y gcc && \ apt-get install -y g++ RUN apt-get install -y cmake 3.10.2 # SET path to compilers. # https://stackoverflow.com/questions/17275348/how-to-specify-new-gcc-path-for-cmake ENV CC=/usr/bin/gcc \ CXX=/usr/bin/g++ # OpenBlas, Lapack RUN apt-get install -y libopenblas-dev && \ apt-get install -y liblapack-dev # Please use below directory to install cpp libraries. WORKDIR $HOME/usr/ RUN mkdir /library CMD ["bash"]docker-compose.yml
docker-compose.ymlversion: '3' services: cmake: container_name: cmake_container build: context: . dockerfile: Dockerfile tty: true command: /bin/bash volumes: - ./cpp:/usr/cpp使い方
コンテナの起動
ローカル環境# コンテナの初回起動 docker-compose up -d # 起動中のコンテナに入る docker-compose run cmakeソースコードのコンパイル
@make_container# コンテナ内のcppフォルダに入る cd cpp # build フォルダを作成し入る mkdir build cd build # cmakeの実行 cmake ../ # makeの実行 make活用例
- ①cppフォルダ内に、.cppファイルやCMakeLists.txtを置く
- VSCodeなど、自分の使い慣れたエディタで編集する
- ②コンテナ内に入り、ビルド実行
- ③ビルド後のファイルは、ローカル環境のcppフォルダから取り出すことができる
![]()
注意点
- OS依存のライブラリは、cppフォルダ内で展開・インストールしないでください
- 筆者は以下のエラーメッセージが表示され、コンテナのマウントが解除されてしまいました。
docker compose error while creating mount source path...- 依存ライブラリはコンテナ内で別フォルダを作り、そこにインストールしてください
- 例) OpenCV
チュートリアル
- 以下では、
Hello CMake!と書かれたソースコードをビルドするまでをご紹介します。- cppフォルダ内に以下の2つのファイルを作成してください。
cppフォルダ内の構成cpp ├── main.cpp └── CMakeLists.txt
- 各ファイルに以下の内容をコピーしてください。
main.cpp#include <iostream> #include <string> int main(void){ std::cout << "Hello CMake!" << std::endl; return 0; }CMakeLists.txt# プロジェクト名 project("testCMake") # CMakeのバージョンを設定 cmake_minimum_required(VERSION 2.8) # testCMake.outという実行ファイルをmain.cppから作成 add_executable(testCMake main.cpp)
- 次に、コンテナでのビルド作業に入ります。
- 以下のコマンドを順に入力してビルドします。
@cmake_container# コンテナ内のcppフォルダに入る cd cpp # ビルドフォルダを作る mkdir build cd build # ビルド実行 cmake ../ make
- 最後にビルドしたプログラムを走らせてみましょう!
./testCMakeと入力し、Hello CMake!と出力されれば成功です。@cmake_container./testCMake Hello CMake!
- CMakeの使い方等はこちらの記事をご参考ください
- 投稿日:2020-01-26T22:44:36+09:00
CMake on DockerでC++コードを簡単ビルド
はじめに
- WindowsPC上で、Linuxに対応したCppプロジェクトを作成したい
- CMakeのDockerコンテナを探しても見つからなかったので今回作成した
良い点
- ローカルフォルダをマウントするよう設定
- ローカルフォルダ上でコードを編集すると、すぐにコンテナへ変更が反映される
- コンテナにログインせずとも、VS code などのエディタで編集できる
- ビルド後のファイルもdocker cp コマンドを使わずに取り出せる
ダウンロード
- この記事で紹介したDocker imageは、DockerHub からダウンロードすることができます。
フォルダ構成
- 下図のようにDockerfile, docker-compose.ymlを配置する
- ソースコードは記事の下部に記載
- cppフォルダは、docker-compose up によって自動生成される
- このフォルダ内に ソースコードを置く
treeフォルダ構成 ├── Dockerfile ├── docker-compose.yml └── cpp ← 自動生成されるDockerfile
DockerfileFROM ubuntu:18.04 RUN apt-get update && \ apt-get install -y sudo && \ apt-get install -y vim && \ apt-get install -y wget # Install compilers. RUN apt-get install -y gcc && \ apt-get install -y g++ RUN apt-get install -y cmake 3.10.2 # SET path to compilers. # https://stackoverflow.com/questions/17275348/how-to-specify-new-gcc-path-for-cmake ENV CC=/usr/bin/gcc \ CXX=/usr/bin/g++ # OpenBlas, Lapack RUN apt-get install -y libopenblas-dev && \ apt-get install -y liblapack-dev # Please use below directory to install cpp libraries. WORKDIR $HOME/usr/ RUN mkdir /library CMD ["bash"]docker-compose.yml
docker-compose.ymlversion: '3' services: cmake: container_name: cmake_container build: context: . dockerfile: Dockerfile tty: true command: /bin/bash volumes: - ./cpp:/usr/cpp使い方
コンテナの起動
ローカル環境# コンテナの初回起動 docker-compose up -d # 起動中のコンテナに入る docker-compose run cmakeソースコードのコンパイル
@make_container# コンテナ内のcppフォルダに入る cd cpp # build フォルダを作成し入る mkdir build cd build # cmakeの実行 cmake ../ # makeの実行 make活用例
- ①cppフォルダ内に、.cppファイルやCMakeLists.txtを置く
- VSCodeなど、自分の使い慣れたエディタで編集する
- ②コンテナ内に入り、ビルド実行
- ③ビルド後のファイルは、ローカル環境のcppフォルダから取り出すことができる
![]()
注意点
- OS依存のライブラリは、cppフォルダ内で展開・インストールしないでください
- 筆者は以下のエラーメッセージが表示され、コンテナのマウントが解除されてしまいました。
docker compose error while creating mount source path...- 依存ライブラリはコンテナ内で別フォルダを作り、そこにインストールしてください
- 例) OpenCV
チュートリアル
- 以下では、
Hello CMake!と書かれたソースコードをビルドするまでをご紹介します。- cppフォルダ内に以下の2つのファイルを作成してください。
cppフォルダ内の構成cpp ├── main.cpp └── CMakeLists.txt
- 各ファイルに以下の内容をコピーしてください。
main.cpp#include <iostream> #include <string> int main(void){ std::cout << "Hello CMake!" << std::endl; return 0; }CMakeLists.txt# プロジェクト名 project("testCMake") # CMakeのバージョンを設定 cmake_minimum_required(VERSION 2.8) # testCMake.outという実行ファイルをmain.cppから作成 add_executable(testCMake main.cpp)
- 次に、コンテナでのビルド作業に入ります。
- 以下のコマンドを順に入力してビルドします。
@cmake_container# コンテナ内のcppフォルダに入る cd cpp # ビルドフォルダを作る mkdir build cd build # ビルド実行 cmake ../ make
- 最後にビルドしたプログラムを走らせてみましょう!
./testCMakeと入力し、Hello CMake!と出力されれば成功です。@cmake_container./testCMake Hello CMake!
- CMakeの使い方等はこちらの記事をご参考ください
- 投稿日:2020-01-26T22:03:31+09:00
DockerでMysqlコンテナを作る
この記事について
dockerコマンドをよく忘れるのでメモしておきます
mysqlを例にしています。
ただの備忘録ですdocker pull Dockerイメージの取得
docker pull mysqldocker images -a Docker イメージの一覧を表示
docker images -a REPOSITORY TAG IMAGE ID CREATED SIZE mysql latest 3a5e53f63281 11 days ago 465MB mysql <none> d5127813070b 2 years ago 407MBdocker run コンテナの作成
docker run --name mysql-for-test -e MYSQL_ROOT_PASSWORD=password -d -p 13307:3306 mysql:latest-dはコンテナをバックグラウンド実行するオプション
docker rundocker start [name] コンテナの起動
docker start mysql-for-test mysql-for-testdocker ps -a 現在実行中のコンテナの確認
docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a0371102cea6 mysql:latest "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 33060/tcp, 0.0.0.0:13307->3306/tcp mysql-for-testdocker stop [name] コンテナの停止
docker stop mysql-for-test mysql-for-testdocker rmi イメージ削除
docker rmi mysql:latest Untagged: mysql:latest Untagged: mysql@sha256:f1df505c4c6e8eae599a0482e3bde3e761cd700c00cbc371a8161648a26817c0 Deleted: sha256:3a5e53f6328162f8d8bc70131658a721e8e7dcf7495f2fae7cfe4febdbcfefbb Deleted: sha256:f2533710d884b7eb9329d63844e1504c2d166cdb9139be622f9a5ed5dbd8044c Deleted: sha256:573b1ee1cfefd4e3c18ade60576f03e275e28b73d985ce551ae78b1a93a81ace Deleted: sha256:a7de8634d9c2f1188b74aceb18c048e37ea86eace1c4614996e76abc065e71fb Deleted: sha256:96b788fd084094ed5b2b00b29865ec25bdba4aba633b8a86bb7e485df21e9dfb Deleted: sha256:c1f124fbef5b35b53dadbd9caa1a272bde42490963ec68daa0a0e52a516cf5f9 Deleted: sha256:5f7c68324b959d2c806db18d02f153bc810f9842722415e077351bc834cc8578 Deleted: sha256:338fc0cd3fb4b87a2b83d274e8fbf475fbde19947c4ac5c5eb6e981a6fb0e8f0 Deleted: sha256:f7a4ccab931f1d1e861961eb951a7806d91ccb375e737fe1f84282f6bbafd2be Deleted: sha256:f388e1092f8fb931a3cd07a7381bd9707d19526ff81f8b624e932f4919c27a3e Deleted: sha256:e209b7a884b4d2e9d56bbac40ced48f2caa6a19e7ad6eb6dd20ff754f3af2c5d Deleted: sha256:2401cf11c5455d505ef49657afcc709197ffcdfc9bd732508e9b62578a30b3a5 Deleted: sha256:814c70fdae62bc26c603bfae861f00fb1c77fc0b1ee8d565717846f4df24ae5dコンテナ起動時はコンテナに使用しているイメージは削除できない
MySQL Workbenchで接続する設定
上記の例だと
IP 127.0.0.1
Port 13307
username root
Password password
で繋がるはずdocker volume ls Dockerボリュームを表示する
docker volume ls DRIVER VOLUME NAME local 4af0b51aff028e66d409e273378cbae94384a5a19ad4d2b2e22020a050c2f1abdocker volumeとはデータを永続化する場所とのこと
Mysqlのコンテナを作成するとVolumeも作成されています。
イメージやコンテナを削除してもVolumeは削除されない
Docker、ボリューム(Volume)について真面目に調べたdocker inspect [ボリューム名] Dockerボリュームの詳細を表示する
docker inspect 4af0b51aff028e66d409e273378cbae94384a5a19ad4d2b2e22020a050c2f1ab [ { "CreatedAt": "2020-01-26T11:30:51Z", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/4af0b51aff028e66d409e273378cbae94384a5a19ad4d2b2e22020a050c2f1ab/_data", "Name": "4af0b51aff028e66d409e273378cbae94384a5a19ad4d2b2e22020a050c2f1ab", "Options": null, "Scope": "local" } ]docker volume rm [ボリューム名] Dockerボリュームを削除する
docker volume rm e50120cd5bd6f95e469e056390285e62d4607cb171578ab965c404bd9cc6ac35 e50120cd5bd6f95e469e056390285e62d4607cb171578ab965c404bd9cc6ac35使用中のボリュームを削除しようとした場合は以下のようにエラーが出て削除できません
docker volume rm e78cc14f113a5604b8ce19be097b9a293bf10e35ea17d0643ebfe8f1b875e416 Error response from daemon: remove e78cc14f113a5604b8ce19be097b9a293bf10e35ea17d0643ebfe8f1b875e416: volume is in use - [d78ae59aa2db6328999a0a02b552a72f5f8bf7ef047673778323fe1b4d276c7a]docker volume prune 停止しているコンテナのDockerボリュームを一括削除する
docker volume prune WARNING! This will remove all local volumes not used by at least one container. Are you sure you want to continue? [y/N] y Deleted Volumes: 9f2e7aece432721df0c486f424deaac4fd2ec599164f5dc942c68cb81cbed8b1 4af0b51aff028e66d409e273378cbae94384a5a19ad4d2b2e22020a050c2f1ab d8158a2830563c99eb8907feacbe85da49f7186e9d4464d6e4ccc0666cd66b44 44e1f3a93792855219d361a11381fc5ce21eb7bac7f6940ef2617ebcb916c74e d296e6bf49ecb4da2a84589ce1d7439621eedd1242fc979cfcff6636e175f568 e4a3ffc963c51b5d86e787344ee483215c354a8f72bbe6640a51d9c9760b8e5c Total reclaimed space: 891.7MBdocker volume create [ボリューム名] Dockerボリュームを新規作成する
docker volume create mysql-test-volume mysql-test-volumeDockerボリュームを指定してコンテナを作成する
docker run --name mysql-for-test -v mysql-test-volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password -d -p 13307:3306 mysql:latest eb61f634a9b04e86e81470096489938cac77682e20be551c961f7395d18fc836これでデータが永続化される・・・はず。
今度書く
docker-compose使う方法
- 投稿日:2020-01-26T21:45:04+09:00
簡単なForm作成から学ぶVue(TypeScript)の書き方 その0 環境構築編
Dockerを用いてVue環境を作り、いい感じのフォームを作成しながらVueを学習していく。
Dockerざっくりした理解
Dockerコンテナ
→ アプリケーションの実行環境
ホストOS上に論理的な区画を作ったもの。OSやIPアドレスなどのシステムリソースをコンテナが見かけ上占有できる。
コンテナに必要なモジュールのみを詰めてアプリケーションを実行できる。Dockerイメージ
→ コンテナを構成するための設計図。
DockerHubを介して種々のイメージを共有できる。Dockerコマンドの利用
よくあるDockerの練習としてnginxを用いたサーバー構築がある。
nginxでサーバー構築$ docker pull nginx //DockerHubからイメージ取得 $ docker run --name webserver -d -p 80:80 nginx //起動。デーモン化。ブラウザからアクセスできるようになる。 $ docker ps //プロセス確認 $ docker stop webserver //停止 $ docker rm webserver //削除Dockerfile
→ DockerfileはDockerイメージを構成するための構成情報ファイル。
上の練習ではDockerHub上のイメージを取得し、そのまま起動させるものだが、実際の開発では、内部の構成に手を加え、独自のイメージを創り、コンテナを生成することとなる。
コマンドで環境を構築してもよいが、本格的な開発となった場合に以下のような構成情報を別途ドキュメントとして残す必要が出てしまう。
- 元となるDockerイメージ
- コンテナ内で実行するコマンド
- 環境変数などの設定値
こうした構成情報を記述しておくファイルがDockerファイルであり、
docker buildコマンドを用いると、このDockerfileを元にしてDockerイメージを作成できるため無駄やミスがない。Docker Compose
これまでのDockerは1つのコンテナを用いる話だった。先述の通りコンテナは論理的に1区画を創るものであり、複数のコンテナを生成することもできる。複数のコンテナを生成し、それらをコンテナ内部のネットワークで繋ぐこともできる。
これらを束ねるのがdocker-composeであり、その設定ファイルがdocker-compose.ymlである。
vue環境の構築
参考→https://cloudpack.media/43078
正直この通りやっていけばできる。複数選択のものはスペースで選択できる。
設定は少し変更あり。DockerfileFROM node:10.8.0-stretch RUN npm install --global @vue/cli WORKDIR /projectsdocker-compose.ymlversion: '3' services: app: build: . ports: - "8080:8080" volumes: - ".:/projects" tty: true$ docker-compose up -d $ docker-compose exec app bash設定部分# vue create app Vue CLI v4.0.5 ? Please pick a preset: Manually select features ? Check the features needed for your project: Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E ? Use class-style component syntax? Yes ? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes ? Use history mode for router? (Requires proper server setup for index fallback in production) Yes ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with dart-sass) ? Pick a linter / formatter config: Basic(一番目を選択) ? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)Lint on save ? Pick a unit testing solution: Mocha ? Pick a E2E testing solution: Cypress ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files ? Save this as a preset for future projects? No ? Pick the package manager to use when installing dependencies: NPM構築が終わったらappディレクトリに移行して下のコマンドを実行。ブラウザから
localhost:8080にアクセスして確認。# cd app # npm run servectrl+Cで終了し、
exitでDockerから抜けた後$ docker-compose downでコンテナごと終了。お世話になった参考サイト
- 投稿日:2020-01-26T17:26:17+09:00
コード内で環境名 (dev,stg,prod) を使用しないことのすすめ
サービスを運用する場合、開発、運用で複数の環境でサーバーを動かしている場合がよくあると思います。このとき、パラメータ設定の口が柔軟でないと設定値の変更がしにくかったり、サーバーのビルドを環境毎にしなければならなず(特に docker 使っている場合)、デプロイに時間がかかったりします。
そうならないために環境名 (dev,stg,prod) を使用して動作変更するのをやめることをおすすめします。記事内では以下のような環境があると想定し、Javascript (Node.js) でいくつかの例を示します。
- 開発時ローカル PC
- ステージングサーバー環境
- 本番サーバー環境
変数を環境名に依存させるのをやめよう
サーバーでエラーが起きたときに管理者にメールを送るというケースで送り先を分ける場合で説明します。
悪い例(コード内で環境ごとのメールアドレスを決めている)
コード内で設定されているアドレスにしか送ることができません、送信するメールアドレスが変更になったときはコードの変更が必要。
// process.env.NODE_ENV に環境名が指定されている function sendErrorMail() { let email = 'default@example.com'; switch(process.env.NODE_ENV) { case 'development': email = 'dev@admin.com'; break; case 'staging': email = 'stg@admin.com'; break; case 'production': email = 'prod@admin.com'; break; default: break; } // sendMail は email アドレスとメール本文を指定してメールを送る関数 sendMail(email, 'Server Error Occurred'); }良い例(環境変数としてメールアドレス自体を指定している)
メールアドレスが変更になったときでも環境変数の指定を変更するだけで送信先が変更できる
// process.env.ADMIN_EMAIL_ON_ERROR にエラー時のメール送り先が指定されている function sendErrorMail() { // sendMail は email アドレスとメール本文を指定してメールを送る関数 sendMail(process.env.ADMIN_EMAIL_ON_ERROR, 'Server Error Occurred'); }動作を環境名に依存させるのをやめよう
次も似た例ですが、ログのレベル設定を例に説明します。
logWarnという警告ログを出力する関数があるとします。開発環境だったら debug ログを出す、というパターンはよくあると思いますが、一つの環境変数としてログレベルを設定すると柔軟です。悪い例(コード内で環境名でレベルを決めている)
// process.env.NODE_ENV に環境名が指定されている function logWarn(message) { if (process.env.NODE_ENV == 'development') { console.warn(message); } }良い例(ログレベルを環境変数として設定する)
const LogLevel = { DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, TRACE: 4, }; // process.env.LOG_LEVEL にログレベルが設定されている function logWarn(message) { if (process.env.LOG_LEVEL <= LogLevel.WARN) { console.warn(message); } }最後に
この話は主流にありつつある(すでに主流?) Docker でのサーバーデプロイの背景が大きいです。Docker image を build して デプロイしてという流れで運用している場合、ちょっとした動作の変更によって Docker image の build し直ししなければならないとか、環境毎に image を build し直さなければけ無いとなると、build 時間はわりとかかるケース(色々なケースがありますが、数分から10分は最低でもかかると思います)が多いので、build し直ししなくてもいいように(実行時に環境変数として設定すればいいだけにするために)設定類は個別の設定毎に外出ししていくと便利だと考えています。
- 投稿日:2020-01-26T15:19:30+09:00
GoとRedisでAPIを実装する (Part.1)
はじめに
本記事では、Go 言語と Redis を使用し簡単なAPIの作成手順について説明する。docker-compose を使って実装していく為、環境に依存しない開発環境で実装する。効率的に開発が行える様、開発の中でいくつかの工夫を施しているので参考になれば幸いである。
また、今回は記述量が多くなるので以下の2部構成にした。
- Part.1 : 環境構築 ~ 動作確認
- Part.2 : API実装 ~ 実装検証
本記事では環境構築から動作確認までを説明する。
初めて実装していく方の為に、実行環境と予備知識としていくつか説明する。
1. 実行環境
- macOS Catalina Ver.10.15.2
- Docker version 19.03.5, build 633a0ea
- docker-compose version 1.24.1, build 4667896b
- golang 1.13.6
- Redis 5.0.7
【補足①】
- Go言語
- 2009年、Googleによって開発されたオープンソース(OSS)のプログラミング言語。
- 特徴として、「高速コンパイル」、「シンプルな記述」が挙げられる。
【補足②】
- Redis
- キーバリュー型(KVS)の NoSQL の一種。
- キーと5種類の値型の対応関係を格納ができる。
- インメモリデータベースであるため、高速なデータへのアクセスが可能である。
【補足③】
- Docker
- コンテナ型の仮想化ツール。
- 従来のハイパーバイザ型(Hyper-V)、ホスト型(VMWareやVirtualBoxなど)に比べ軽量で、且つ利便性が高い。
- docker-compose を使用する事で、複数のコンテナを組み合わせて1つのアプリケーションを構成できる。
2. 前提条件
今回、実装するに至って用意するべき事項は以下の2点である。
- PC内に docker、docker-composeがインストールされている
- Goの開発環境が整備されている
docker、docker-compose が動作する環境があれば、特必要となるものは無い。コードを書く際は、好みのエディター (Atom、VSCodeなど)を使用すると良い。Goの開発環境に関しては、開発を進める上で
go.mod、go.sumを事前に作成しておく必要がある為、インストールしている。Goの開発環境に関しては、
Homebrewを使用した環境構築がオススメである。以下にインストール手順を示しておく。$ brew install go尚、今回使用するものが正常にインストールされているかどうかを確認したい場合は、以下のコマンドで確認が可能である。
# Goの確認 $ go version go version go1.13.6 darwin/amd64 # dockerの確認 $ docker version Client: Docker Engine - Community Version: 19.03.5 API version: 1.40 ... # docker-composeの確認 $ docker-compose version docker-compose version 1.24.1, build 4667896b docker-py version: 3.7.3 ...3. 環境構築
3.1. ファイル構成
今回のファイル構成は以下の通りである。
sample_project ├── docker │ ├── api │ │ └── Dockerfile-api //API用 │ └── database │ └── Dockerfile-redis //DB用 ├── docker-compose.yml └── src └── app ├── controller │ ├── sender.go │ └── receiver.go ├── infrastructure │ └── database.go ├── interface │ └── user.go └── main.go今回は個々の処理を各ディレクトリに分けた。構成に関しては様々な設計思想があると思うので、それに基づいて開発を行う場合は、はじめにファイル構成などを考えてから構築して行くと良い。
3.2. Go Modulesの作成
Goでは
Go Modulesと呼ばれる外部パッケージの管理システムがある。今回はそれを使用する為、事前にmain.goが配置されているディレクトリで以下のコマンドを実行し、go.mod、go.sumを作成しておく。# appディレクトリまで移動 ~/sample_project $ cd src/app # go.modファイルを作成する ~/sample_project/src/app $ go mod init main.go # go build コマンド、または go mod download コマンドのどちらかを実行する ~/sample_project/src/app # go build ~/sample_project/src/app # go mod download次に、Dockerfileの作成する。
3.3. Dockerfileの作成
3.3.1. Dockerfile (API)
まず、API用のDockerfileを作成していく。API側のDockerfileではGoの環境を構築していく。開発環境ではソースコードが随時更新される事を考慮し、ホットリロード環境を導入するために
freshと呼ばれるライブラリを使用した。Dockerfile-api############################### # Builder Container ############################### FROM golang:1.13.6 AS builder # Go Moduleが使えるようにする ENV GO111MODULE=on WORKDIR /go/src/app/ # GOROOTが/goになるため COPY src/app /go/src/app # gormとginのドライバをインストールする RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y git && \ go mod download && \ go get github.com/pilu/fresh && \ # ホットリロードを実行する CMD ["fresh"] ############################### # Production Container ############################### FROM golang:1.13.6-alpine AS production COPY --from=builder /go/src/app/ /app上記の様に、開発環境と本番環境とで環境を分ける為、マルチステージビルドしても良い。マルチステージビルドを使用する事で、可読性、保守性を保つ事ができる。また、逐一
Dockerfileを最適化するために書き直す面倒くささも解消できる。尚、環境を分割する必要のない場合、以下の記述例でも良い。
Dockerfile-api-slimFROM golang:1.13.6-alpine ENV GO111MODULE=on WORKDIR /go/src/app/ COPY src/app /go/src/app RUN apk add --no-cache --virtual alpine-sdk git && \ go mod download && \ go get github.com/pilu/fresh CMD ["fresh"]
alpineを使用する事で、イメージが軽量化されるので、ビルド時間の短縮にもなる。しかし、RUNコマンドの記述が上記とは異なる為、注意してほしい。※ alpine : Alpine Linuxと呼ばれる、BusyBoxとmuslをベースにしたLinuxディストリビューションを指す
今回は、簡単なAPIの実装なので
Dockerfile-api-slim(alpineの方)を使用して開発を行う。3.3.2. Dockerfile (Database)
DB用のDockerfileを作成していく。DB側のDockerfileではRedisの環境を構築していく。
こちら側では今回、特に設定をする事はないので下記のような記述で良い。Dockerfile-databaseFROM redis:5.0.7-alpineDockerfileの作成は以上である。
3.4. docker-compose.yml
次に、docker-compose.ymlの作成を行う。
docker-compose.ymlversion: '3.7' services: api: build: context: . # マルチステージビルドを使用しない場合、targetは不要 target: builder dockerfile: ./docker/api/Dockerfile-api container_name: sample_project-api image: sample_project/api:0.1.0 ports: - "8080:8080" # ホストOSとコンテナ内でソースコードを共有 volumes: - ./src/app:/go/src/app depends_on: - redis tty: true redis: build: context: . dockerfile: ./docker/database/Dockerfile-database container_name: sample_project-redis image: sample_project/redis:0.1.0 ports: - "6379:6379" restart: always volumes: - ./docker/database:/data今回の実装の場合、DB側のコンテナの起動が完了してからAPIのコンテナを起動させたいので、
depends_onでコンテナの作成順序を依存関係を決めている。また、
tty:trueを追記する事でコンテナを常時起動させる。ポート番号に関しては、デフォルトの8080、6379をそれぞれ設定している。マルチステージビルドを採用している場合は、
targetの箇所で、自分がビルドしたいステージを指定すると良い。3.5. main.go
コンテナのイメージを作成後に正しく環境構築されているかどうかを確認するために、
main.goの作成をしておく。ここでは、簡単に作成し、後ほどAPIの開発のために改修していく。以下に作成したソースコードを示す。
main.gopackage main import ( "github.com/gin-gonic/gin" ) func main() { router := gin.Default() router.GET("/", func(context *gin.Context) { context.JSON(200, gin.H{ "message": "Hello, World!!", }) }) router.Run(":8080") }今回は、GoのWebフレームワークの1種である、Gin を使用した。処理の内容としては、
http://localhost:8080/へアクセスすることでHello, World!!とメッセージが返ってくるだけの簡単なものである。3.6. dockerイメージの作成
Dockerfile,docker-compose.ymlを作成後、以下のコマンドを実行し dockerイメージを作成する。~/sample_project $ docker-compose up -d実行後、イメージができているかどうかを以下のコマンドを実行し、確認する。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE sample_project/redis 0.1.0 b68707e68547 9 days ago 29.8MB redis 5.0.7-alpine b68707e68547 9 days ago 29.8MB sample_project/api 0.1.0 f8d6549bee6c 24 minutes ago 449MB golang 1.13.6-alpine 9954d1348cd8 10 days ago 359MB3.7. コンテナの起動 / 動作確認
イメージの作成後、以下のコマンドを実行しコンテナを起動させる。
$ docker-compose up # docker-composeコンテナ一覧の確認 $ dokcer-compose ps Name Command State Ports -------------------------------------------------------------------------------------- sample_project-api fresh Up 0.0.0.0:8080->8080/tcp sample_project-redis docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcpコンテナを起動後、http://localhost:8080/ へアクセスするか、または
curlコマンドを実行する事で確認できる。$ curl localhost:8080 {"message":"Hello, World!!"}また、redisの接続確認は以下のコマンドの通りである。
# コンテナ内部に入る $ docker exec -it [CONTAINER ID] sh # redis-cliの起動 /data # redis-cli # 以下のIPアドレスに入れればOK 127.0.0.1:6379>以上まで確認できれば、一通りの環境構築、動作検証は終了である。
4. まとめ
今回は環境構築から動作確認までを行った。今回の構成を真似しなくとも、ホットリロード環境は便利なので今後参考にして頂ければと思う。
次回は、この続きでAPIの実装を行っていく。
- 投稿日:2020-01-26T15:19:17+09:00
Docker+ROSの環境をWindows10PROで整える
書いた理由
Docker+ROSで開発する人は多くいて、懇切丁寧なチュートリアルがDockerHubのROSのリポジトリにも書いてありますが、私のようにまったくDocker使ったことない人には、Dockerの使い方やコマンドからメモっておかないと使えません(泣)
3日経ったらやり方を忘れてしまうと思って備忘録代わりに書いておきます。環境
Windows10Pro
HomeエディションではHyperVを使用できなかったため、アップグレードして使用しました。想定する使い方
WindowsのDockerコンテナにハードウェアをマウントすることは2020/01/26現在は無理のようです。
WindowsPCとJetson-nanoを無線LANでつなぎ、ハードウェアの集まるJetson-nanoとROSでデータを交換しながら開発する。
最終的にはJetson-nano単独で動かしますが、開発だけでも大きなPCでできれば楽ができます。Docker+ROSの環境で開発したい
Jetson-nanoにつないだ小さなディスプレイで開発するのが大変になってきたので、Windows10をProにアップグレードしてDocker DeskTopを使うことにしました。
DonkeyCar用にAnacondaの環境が入っているので、競合を回避するのが目的です。
また、DockerHubのリポジトリを持ってくることで環境構築の負担を減らすのが目的です。
もともと仮想マシンでUbuntuを入れてみましたが、うまく動かないのでDockerに宗旨替えしました。Docker Desktopのインストール
https://www.docker.com/products/docker-desktop
公式のマニュアルに沿ってインストールします。
Windows10Proじゃないと、HyperVが動かないので使えません。
HyperVを有効にして再起動したらあっさり動きました。
GUIでDockerHubのユーザーIDとかを設定しておきます。ROSのイメージをPULLしてみる
適当なディレクトリを作って、コマンドを開いて、
docker pull ros
これでDockerHubからROSのリポジトリを引っ張れました。
バージョンを指定するときは、
docker pull ros:melodic
とかするとOK。ROSのイメージの中で作業する
docker run -it --name test ros
pullしたコンテナイメージを動かし、コンテナの中で作業できます。
-itコンテナのSTDINにアタッチし疑似ターミナルを割り当て
-nameホスト名を決めてコンテナ起動ROSコンテナにtoolをインストール
catkin buildが動かないので、ツールは公式イメージに入っていないらしいです。
コンテナの中でツールをインストールします。
sudo apt install python-catkin-tools
では何故かインストールできなかったので、apt-getを使いました。ROSsudo apt-get update sudo apt-get install python-catkin-toolsで、セットアップ完了。
ROSmkdir -p catkin_ws/src/ cd .. catkin buildこれでパッケージのビルドができるようになりました。
exitで抜けることができます。抜けてもコンテナは動作している状態です。
再度、開始とアタッチをするならcommanddocker start test docker attach testコンテナイメージのバックアップ
exitした後、タグをつけてイメージを保存します。
commanddocker commit test ros:ros-testこのタグを使って新しいイメージを起動します。名前は先ほど使ったtestを使うとコンテナ名が重複するのでNG。
commanddocker run -it --name build ros:ros-testDockerHubにリポジトリを登録する
DockerHubに保存するため、新しいリポジトリを作成します。
docker commit build tkumazawa/ros:buildと打ち込んで実行し、イメージを確認します。
tkumazawaは私のDocker HubのIDです。rosがリポジトリ名。buildがタグです。タグはver1.0などとしたほうがいいかもしれません。command> docker commit build tkumazawa/ros:build > docker images REPOSITORY TAG IMAGE ID CREATED SIZE tkumazawa/ros build 2ff967da7a65 30 seconds ago 1.28GB ros ros-build 2edba62b8053 22 hours ago 1.28GB整ったらDockerHubにPUSHします。
command>docker push tkumazawa/ros The push refers to repository [docker.io/tkumazawa/ros] 8493815d0ca4: Pushed 372ede2259c3: Pushed 9e4af5cbf92b: Pushed 5d0ac2ca4dca: Mounted from library/ros b0264d2ecd66: Mounted from library/ros dc1e02c4e5b2: Mounted from library/ros 93928f93457b: Mounted from library/ros 95c9f2e4b310: Mounted from library/ros 5dfc22a79953: Mounted from library/ros deb603bf064b: Mounted from library/ros f5a315154171: Mounted from library/ros 55388b609b06: Mounted from library/ros f55aa0bd26b8: Mounted from library/ros 1d0dfb259f6a: Mounted from library/ros 21ec61b65b20: Mounted from library/ros 43c67172d1d1: Mounted from library/ros build: digest:これでDockerで整えた環境をDockerHubに保存してバックアップすることができます。
実際にDocker+ROSで動かす方法はここを参考にしました。
Docker + ROS(kinetic)でチュートリアルコンテナの削除がめんどくさい
やっているうちに大量のコンテナとイメージがメモリを圧迫しています。
ROSのコンテナが複数起動しているので、どうにもなりません。
で、「Docker実践入門」という本を教科書にしてますが、bashだと
docker rm $(docker ps -qa)で済むんですよね?
Windowsで同じことやろうとしたら、command#停止中コンテナの全消去 for /f "usebackq" %x in (`docker ps -aq`) do docker rm %x #起動中コンテナも停止中コンテナも全消去 for /f "usebackq" %x in (`docker ps -aq`) do docker rm -f %x #未参照のイメージを全消去 for /f "usebackq" %x in (`docker images -q`) do docker rmi %x参考にしたのはこちら。
WindowsのDockerで溜まったコンテナやイメージを削除するコンテナを消し終わったら、タグ付きでコミットしたイメージを消去。
怖いので一個ずつ消す。
docker rmi ros:ros-test
これやったら根っこから全部消える。もう一回、DockerHubからとってくるならOK。
docker rmi rosVSCodeでDockerコンテナにリモート接続する
編集するときにいちいちエディタをコンテナにインストールするのが面倒だと思っていたらVSCodeにRemote Containersなる拡張を発見。
microsoft/vscode-remote-releaseインストールして左下の隅っこをクリックするとメニューが開くので、
Remote-Containers: Attach to running Containerで接続したい対象を選択できます。
まず、先ほどDockerHubにpushしたイメージからコンテナを起動します。
docker run -it --name ros-wk tkumazawa/ros先ほど立ち上げたros-wkを選択すると、新しいVSCodeのウィンドウが立ち上がるので、フォルダを選択して起動。
確かに中身が見えます。GitHubからコンテナの中にリポジトリをcloneする
githubから編集中の自分のROSのパッケージをcloneします。
https://github.com/kumaxxp/ros_rc_package.git
これで、コンテナの中にgithubの内容を取り込んで編集できそうです。
ただし、GitHistoryやGitLensは無効で動きませんでした。なにか制限がかかっているようです。
VSCode標準のgit機能は問題なく使えます。githubへのpushもできますが、いちいちパスワードとIDを打ち込むのは面倒ですね。
かといってしょっちゅう生成と削除を繰り返す前提のコンテナイメージのssh-keyを登録するのもどうかと思いますので、その辺りは悩ましいところです。
とりあえずcatkin buildしてみます。ROS# catkin build ---------------------------------------------------- Profile: default Extending: [env] /opt/ros/melodic Workspace: /root/catkin_ws ---------------------------------------------------- Build Space: [exists] /root/catkin_ws/build Devel Space: [exists] /root/catkin_ws/devel Install Space: [unused] /root/catkin_ws/install Log Space: [exists] /root/catkin_ws/logs Source Space: [exists] /root/catkin_ws/src DESTDIR: [unused] None ---------------------------------------------------- Devel Space Layout: linked Install Space Layout: None ---------------------------------------------------- Additional CMake Args: None Additional Make Args: None Additional catkin Make Args: None Internal Make Job Server: True Cache Job Environments: False ---------------------------------------------------- Whitelisted Packages: None Blacklisted Packages: None ---------------------------------------------------- Workspace configuration appears valid. ---------------------------------------------------- [build] Found '1' packages in 0.0 seconds. [build] Updating package table. Starting >>> ros_rc_package Finished <<< ros_rc_package [ 4.5 seconds ] [build] Summary: All 1 packages succeeded! [build] Ignored: None. [build] Warnings: None. [build] Abandoned: None. [build] Failed: None. [build] Runtime: 4.5 seconds total. [build] Note: Workspace packages have changed, please re-source setup files to use them.とりあえず、パッケージは問題なくbuildできたみたいです。
(pythonで記述したものは実行するとエラーが確実に出るのでここでは動かせない)ROS# . ~/catkin_ws/devel/setup.bash # rospack list ... ros_rc_package /root/catkin_ws/src/ros_rc_package ...setupの後、パッケージのリストを出力させると、パッケージは登録されていました。
続くかも
Dockerを使った機能の作成方法を、全部メモしてみました。
記述したコマンドをアレンジして使えば、とりあえずWindowsでDocker+ROS開発は問題なく実施できるかと思われます。
- 投稿日:2020-01-26T12:00:44+09:00
アラフォーのおっさんが一ヶ月でWebサービスを作った話
初めてWebサービスを作ってみました。
年末年始を使い、約1ヶ月程度で、どうにか公開までこぎつけられたので、振り返ってみたいと思います。モチベーション
筆者は職業プログラマーではありませんが、将来に不安を感じ、プログラミングスキルを磨くことにしました。
「プログラマ35歳定年説」に言われる30代半ばを突き抜けた、まもなく40歳になるオッサンが、プログラミングスキルへ投資することに賭けたのです。アラフォーになるまでの経験値
- ユーザ系システムインテグレータに勤務
- 数年前まではインフラ業務を担当(「VMware」とか)
- 今は社内システム(バッケージソフトウェアで構築)の保守を担当
- 数年前から深層学習(「TensorFlow」とか)の本を読み始めた
作り始める前(1ヶ月前)のレベル
- 「jQuery」が少し分かる
- 最近のWebシステムのトレンドって何?
- フレームワークって何を使うといいの?「React」、「Vue」とか一杯あるけど
- 「WebPack」?「Bazel」?何それ?
- いつか「Docker」を使ってみたい
- バックエンドはConcurrent(並行)処理に強い「Go」がいいらしい?
どんなWebサービスを作ったのか
手書き文字(カタカナ)の認識です。
深層学習ライブラリ「TensorFlow」を使った、「MNIST」等の手書き数字認識のカタカナ版になります。[カタカナ道場]
https://katakanadojo.tokyo筆者には子供がいますが、この子の書くカタカナが怪しい。
(「シ」と「ツ」、「ソ」と「ン」が同じに見えるなど)「コンピュータが読める字を書けた方がいいぞ!」とモチベーションを促し、字の上達につなげてもらう目論見で作りました。
※突貫工事で作ったので今後、手直ししていく予定です。メンテナンス中で落ちている場合があるのでご容赦ください。他人様に見せられる状態になったらソースコードもアップします。
まずは認識モデルを作る
画像認識の界隈では、「VGG-19」などの事前学習モデルを使った転移学習モデルが高精度の結果を出していますが、シンプルな畳み込み層だけで実装することにしました。
実際にご自身で試していただきたいと思いますが、雑に書いた字でも認識してくれるので、重厚なモデルは使わなくても十分かと考えます。
得点は認識モデルが出力した確率を1万倍しています。
最初はパーセンテージで出力しようとしたのですが、小さい子にパーセンテージの概念は難しいようだったので整数にしました。認識モデルが返すJSON出力はこんな感じです。
{ predict: 'MO', top_3: [ { label: 'MO', probability: 0.93235594 }, { label: 'NE', probability: 0.05294613 }, { label: 'SE', probability: 0.013120668 } ] }トレーニングセットはETL文字データベースを使わせていただきました。
http://etlcdb.db.aist.go.jp/?lang=jaWeb化する
先述の認識モデルを作る際の言語は「Python」を使いました。
pythonでWeb化するには、ということで調べてみると、「Django」や「Flask」というWebフレームワークがあることがわかりました。
どちらも「WSGI」と呼ばれるインターフェースをベースにしているようなので、以下のパッケージを使って試しに書いてみました。from wsgiref.simple_server import make_serverここで疑問が
- もっと速くできないか?
- 認識モデルをメモリに常駐させておくとして、同時アクセスに耐えられるか?
- フレームワークを使えばスレッドをうまく使ってくれるのか?
そうだ、「Go」にしよう
「TensorFlow」ライブラリは、「Python」以外の言語版APIも公開されているということで、「Go」版を調べてみました。
[TensorFlow Go API]
https://www.tensorflow.org/install/lang_goCaution: The TensorFlow Go API is not covered by the TensorFlow API stability guarantees.
「安定性は保証しない」とあります。
これが企業の開発なら即刻、候補から外されるのでしょうが、個人の開発なので試してみることにしました。
「Go API」の詳細については、他の方が書いた記事をご覧ください。[GoでTensorFlowのAPIを使ってみた話]
https://qiita.com/yasuno0327/items/8f8fa5629df3243347bd結果は・・・速い。採用!!!
見た目をリッチにする
フロントエンドに着手します。
どのフレームワークを使うか、この辺の技術選定は本当に悩ましい。
筆者には遠回りしている時間がない。これから生き残るであろう技術を選びたい。
今回は「React」を使うことにしました。
理由はモバイル開発にもつなげられそうだと感じたからです。バックボーンや目的によって違ってくるかと思います。他の方が書いた記事をご覧ください。
[ReactとVueのどちらを選ぶか]
https://qiita.com/yoichiwo7/items/236b6535695ea67b4fbe「Material-UI」といった「UIフレームワーク」が公開されているので活用させていただきました。
クライアント側は、画像をBase64エンコードして、Ajax通信でサーバ(Goで実装)にPOSTします。VPSを借りる
「create-react-app」コマンドで「React」アプリを作り、それをbuildすると、画面に「ZEIT Now」を紹介する出力が出てきます。
Webのフロント部分だけなら、「Zeit Now」でいいと思いました。
ドメイン、証明書まで付いていて無料。すごい。しかし、今回は「TensorFlow」のモデルを動かすので、ある程度のリソース(CPU、メモリ)は確保したい。
NTTPC社が提供するVPSサービス「WebARENA」を使うことにしました。
https://web.arena.ne.jp/indigo/メモリ1GBプラン、月額349円(税込)をチョイス。
「1vCPU」、「1GBメモリ」、OSは「CentOS」か「Ubuntu」を選択可能。この辺はVPSサービスから探し始めて、わりと直感的に決めてしまった面があり、「AWS」や「Azure」といったクラウドサービスは検討していません。
時代はパブリッククラウドの流れにあるし、後になって検討すべきだったと悔いるかもしれません。でも、いいのだ。コンテナ化する
「Ubuntu」上に「Docker」エンジンを入れます。
Dokerホストが1台だけなので「kubernetes」は無し。
(「kubernetes」がどんなものなのか興味はありましたが、今回はパス)
下記3つのコンテナを立てました。
- HTTPS化、証明書周り(「https-portal」)
- リクエストを振り分けるリバースプロキシ(「Node.js」)
- Base64エンコードされた画像を認識し判別結果をJOSNで返す(「Go」)
図にすると以下のようなイメージになります。
1vCPU、1GBメモリのゲストOS上で動いていることに驚嘆します。
ドメインを取る
「ムームードメイン」で、1年契約の「katakanadojo.tokyo」を取りました。
消費税込みで「110円」でした。
「お名前.com」と「ムームードメイン」の2つを見て、安い方にしました。かかった費用
VPS利用料が毎月349円、ドメイン契約料が毎年発生するして、ランニング費用は月額500円を切るといったところでしょうか。
個人で容易にサービスを公開できる時代になったと感じます。
このサービスをいつまで維持するかは未定です。終わりに
ざっと振り返った流れは以上になります。
一ヶ月前のことなのに忘れかけている部分も多く、せっかく苦労して乗り越えた部分を残せていないと感じました。
もし興味を持っていただける方がいらっしゃいましたら、詳細を加筆していきたいと思います。最後まで読んでいただき、ありがとうございました。
- 投稿日:2020-01-26T11:22:14+09:00
Dockerで作成したNetwork Namespaceへアタッチする
Dockerのデフォルト・ネットワーク(bridge)では、コンテナを作成するたびにNetwork Namespaceが作成される。
しかし以下コマンドを実行するだけでは取得する事ができない。$ sudo ip netns lsip netns は/var/run/netns 配下のファイルを一覧表示する実装になっているが、
Docker経由でNetwork Namespaceを作成した場合はこのディレクトリ配下にファイルが作成されない(というかこのディレクトリ自体作られない)。
そのため以下手順を実行する必要がある$ sudo mkdir /var/run/netns $ pid=$(docker inspect $CONTAINER_ID --format '{{.State.Pid}}’) $ sudo ln -s /proc/${pid}/ns/net /var/run/netns/[任意のファイル名]作業ログ
[ec2-user@dockerHost ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 71de02f377ed busybox "sh" 45 minutes ago Up 45 minutes c1 [ec2-user@dockerHost ~]$ ip netns list [ec2-user@dockerHost ~]$ [ec2-user@dockerHost ~]$ CONTAINER_ID=71de02f377ed [ec2-user@dockerHost ~]$ pid=$(docker inspect ${CONTAINER_ID} --format '{{.State.Pid}}') [ec2-user@dockerHost ~]$ sudo mkdir /var/run/netns [ec2-user@dockerHost ~]$ sudo ln -s /proc/${pid}/ns/net /var/run/netns/tmp-container-ns [ec2-user@dockerHost ~]$ sudo ip netns ls tmp-container-ns (id: 0) [ec2-user@dockerHost ~]$ sudo ip netns exec tmp-container-ns bash [root@dockerHost ec2-user]#
- 投稿日:2020-01-26T10:08:46+09:00
xysfdx+dockerでSalesforce開発環境構築
xysfdx+dockerでSalesforce開発環境構築
必要なものをインストールする
- vscode
- docker
- xysfdx
xysfdxでdocker images と docker containerが作成できるから、手動でコマンドの発行が不要。 デフォルトショットキー:
ctrl+shift+jpull images
pull images :
docker: pull image exiasfdc/sfdxcreate container
create container :
docker: create sfdx containeruse docker shell
use docker shell :
docker: attach docker shellおめでとうございます、
xysfdxのSfdx Docker開発環境構築完了しました。注意点
- 現時点で
force:auth:web:loginorforce:auth:web:login:setdefaultusernameがwindowsのdocker環境で使えませんから、xy:auth:username:loginを使って認証してください。xy:auth:username:loginはexiahuang/sfdx-xy-pluginプロジェクトのコマンドです、すでにdocker image exiasfdc/sfdx に含みます。- dockerモードでxysfdxの
force:project:createコマンドが発行できません、手動でプロジェクトを作成お願いします。
- 投稿日:2020-01-26T09:03:30+09:00
Docker for Windows で Kubernetesが起動しないときのトラブルシューティング
毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。0. 始めに
社内でKubernetesの勉強会をしたのですが、その時にKubernetesサーバーを立てるのも大変だったので、Docker for WindowsのKubernetesを使おうと言うことになり、複数の人にWindows10へDocker for Windowsを入れてもらい、Kubernetes機能を有効にしたのだけど、Kubernetes機能がいつまで経っても起動してこない人がいた(私です)ので、トラブルシューティングしてみました。
1. Docker for Windowsのインストールについて
以下をご参照ください。
Docker for WindowsでKubernetesを試してみる - Qiita
https://qiita.com/h-r-k-matsumoto/items/68f694650029ddf7351dDockerのトラブルシューティングについては以下をご覧ください。
Windows10 × Docker for Windows トラブルシューティング - Qiita
https://qiita.com/takeru08ma/items/7878a293c55a9902f4042. インストールしたバージョン
3. 状況
下のDockerとKubernetesで、Kubernetes側がいつまで経ってもオレンジでした
(以下の画像は動くようになった時のステータスです)
Hyper-VマネージャーもずっとCPU使用率が0%でした。
(以下の画像は動くようになった時のステータスです)
4. 対応策
3日ほど放っておいても改善しないのでググってみました。
以下を見つけました。Unable to start kubernetes on docker desktop win 10 pro · Issue #3799 · docker/for-win
https://github.com/docker/for-win/issues/3799どうも、以前Docker for WindowsでKubernetesを動かしたことがある人の固有の問題のようです。
C:\Users<Windowsアカウント>.kubeフォルダー
と
C:\ProgramData\DockerDesktop\pki
が関係しているらしく、中を見ると
.kubeフォルダー
Kubernetesを構築したことがある人はピンとくると思いますが、各種Kubernetesのサービス用のサーバー証明書が入っています。
pkiフォルダーを削除します。
タスクトレイのDockerから「Restart」を選択してDockerを再起動します。
5. 原因
Hyper-Vで動くKubernetesの仮想サーバーで使うTLSの鍵情報を新しい鍵情報を作ろうとしていたが、以前インストールした時のものが残っていてDocker for Windowsはデフォルトでは上書きしない為、いつまで経っても起動しなかった。
ということのようです。
6. まとめ
Happy, Kuberneting!
WSL2が待ち遠しいです。
- 投稿日:2020-01-26T02:38:25+09:00
Pytorch+JupyterLab+GPUをDockerで作成
ぐぐりながら見様見真似でdockerを使ってみました。
目的
- PyTorchによる発展ディープラーニングができる環境を作る
- やるならJupyterLabを使いたい
- Dockerでのコンテナ化もやってみたい
結果
初めはjupyterのdocker-stacksのベースを書き換えたりして試行錯誤してましたが、公式のpytorch/pytorchをベースにjupyterlabなど必要なライブラリをインストールすることで目的のものができました。
環境
Dockerやnvidia-container-toolkitはインストール済みとします。
- GPU: GTX1080
- OS: Ubuntu 18.04.3 LTS
- Nvidia driver: 440.48.02 CUDA Version: 10.2
- Docker: 19.03.5手順
適当な作業用フォルダを作成し移動
$ mkdir pytorch-lab[なんでも良い] $ cd pytorch-labDockerfileを作成
$ vim DockerfileDockerfileFROM pytorch/pytorch:latest # Install required libraries RUN conda config --add channels pytorch \ && conda config --append channels conda-forge \ && conda update --all --yes --quiet \ && conda install --yes --quiet \ ipywidgets \ jupyterlab \ matplotlib \ nodejs \ opencv \ pandas \ scikit-learn \ seaborn \ sympy \ && conda clean --all -f -y # Install jupyter extensions RUN jupyter nbextension enable --py --sys-prefix widgetsnbextension \ && jupyter labextension install @jupyter-widgets/jupyterlab-manager COPY jupyter_notebook_config.py /root/.jupyter/やっていることは
- base imageとしてpytorch/pytorchを使用。
- そのままconda updateを行うとpytorchがダウングレードされてしまうので、
conda config --add channels pytorchでpytorchのライブラリを高優先度で追加。- condaのライブラリだけだと足りないことがあるので
conda config --append channels conda-forgeでconda-forgeのライブラリを低優先度で登録。- 必要なライブラリのインストール。
- jupyterlabでtqdmでの進捗バー表示が行えるようにjupyterlabの拡張機能をインストール。
- 後述するjupyterの設定ファイルをコピー。
jupyterの設定ファイルを作成。
Dockerfileと同じ場所にjupyter_notebook_config.pyを作成。
私は試行錯誤していた際に使用したjupyter/docker-stacks/base-notebook/jupyter_notebook_config.pyをコピーして設定を書き加えています。
追加した設定は
- c.NotebookApp.allow_root = True : rootでの起動を許可
- c.NotebookApp.password = 'パスワードのハッシュ値' : ログインパスワードを設定
パスワードのハッシュ値はローカルのpythonにipythonがインストールされていれば、以下のコマンドで生成できます。
$ ipython In [1]: from IPython.lib import passwd In [2]: passwd()パスワードを設定して表示される'sha1:~'をコピーしておいてください。
jupyter_notebook_config.pyc.NotebookApp.allow_root = True c.NotebookApp.password = 'sha1:~'これらを
c.NotebookApp.open_browser = Falseの後ろあたりに打ち込んでください。imageのビルド
上記のDockerfileおよびJupiter_notebook_configのあるフォルダでビルドを行います。
pytorch-labのところはわかりやすい任意の名前をつけてください。
初回はベースのpytorch/pytorchのダウンロードが行われるのでしばらく時間がかかります。$ docker build -t pytorch-lab ./
docker imagesで作成したイメージが追加されていたら成功です。$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE pytorch-lab latest bd952fdf9b43 12 seconds ago 6.15GB pytorch/pytorch latest 37b81722dadc 9 days ago 4.16GB起動方法
/home/[ユーザー名]/ML/にデータを保存するとします。
$ docker run -d --rm --gpus all -v ~/ML:/workspace -p 8888:8888 --name pytorch pytorch-lab jupyter labオプション
-dバックグラウンドで実行
--rmコンテナ終了時にコンテナを削除
--gpus allコンテナでGPUを使用可能にする
-v ~/ML:/workspaceローカルの~/MLをコンテナの/workspaceにマウントして作成したファイルが保存されるようにする。
-p 8888:8888ローカルのポート8888への接続をコンテナの8888(jupyterlab)へ送る。
--name pytorchコンテナに任意の名前をつける。使い方
ブラウザから
http://localhost:8888/に接続、ログインページが表示されるので設定したパスワードでログインする。問題点
- pytorchのイメージもライブラリもバージョンを指定せずビルドの度に最新のものがインストールされるので、今後のアップデート次第では作ったイメージがうまく動作しない可能性がある。
- rootでjupyterlabを起動するのはセキュリティ的にどうなんだろう(SSHポートフォワードを前提にはしている)。
- tqdmの表示はうまくいくが、torch vision.datasets.MNISTなどのダウンロード時の進捗バーは正常に表示されない。


















