# Dockerメモ {%hackmd theme-dark %} Ubuntu18.04で、Tensorflow-gpu, Keras, ROSが動く環境を作りたい。普通に設定すると、他の学生がPCを触った際に壊れるので、Dockerを使って管理したい。 DockerFileを作って環境設定を行い、人追従プログラムが動かせることを最終目的とする。 ## Nvidia-Dockerとは GPUを使う際に、必要となるのがNvidia-Dockerである。Nvidia-Dockerには、1と2があり、夫々別の特徴がある。 - Nvidia-Docker まず、Nvidia-Dockerの存在意義について、通常のDockerでGPUを使おうとすると、コンテナ内にNVIDIA-Driverを完全に再インストールしてからホストにあるデバイスファイルをコンテナ起動時に渡す必要があった。この方法ではホストのドライバとコンテナのドライバのバージョンが一致していなければならない。 そこで、Nvidia-Dockerはコンテナ起動時にホストのドライバとデバイスファイルをDockerVolumeとして渡すことで、コンテナ側のドライバインストールを不要としている。 NVIDIA-DockerはDockerコマンドのラッパであるNvidia-DockerコマンドとホストマシンのGPUのデバイスファイルとドライバが入ったDockerVolumeを作成するNvidia-Docker-pluginというデーモンから成る。 - Nvidia-Docker2 Nvidia-Docker2は1と実装が異なっており、Nvidia-Docker-Pluginが必要ない。また、公式配布以外のNvidia/Cudaイメージ以外も有効にできるようになっている。 ## Docker使用したコマンド一覧 セキュリティの関係上、Dockerにルート権限を持たせたくないので、Sudoを付ける。ただ、毎回Sudoをつけるのは面倒なので.bahsrcなどでAlias docker="sudo docker"をしておく。 イメージの確認 ``` $ docker images ``` コンテナの確認 ``` $ docker ps -a ``` Cudaバージョンを指定して、Nvidia-smiを実行するコンテナを使い捨てで立ち上げる。 ``` docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi ``` DockerFileを指定してイメージを作成 ``` $ docker build -f <ドッカーファイル名> -t <イメージ名> ドッカーファイルまでのパス 例:docker build -f Dockerfile -t unkonow . ``` イメージを指定してコンテナを作成し、中に入る(下はNvidia-Driverを使うとき) ``` $ docker container run -it --name <コンテナ名> <イメージ名> bash $ docker container run --runtime=nvidia -it --name <コンテナ名> <イメージ名> bash ``` 全てのコンテナを削除する ``` $ docker rm $(sudo docker ps -aq) ``` イメージを削除する ``` $ docker rmi イメージ名 ``` ホストPCからコンテナにファイルをコピーする。 ``` $ docker cp ファイル <ContainerID>:Path ``` Realsense ``` $ sudo docker run --net=host --privileged --volume=/dev:/dev -it iory/docker-ros-d415:docker.d415 /bin/bash' ``` コンテナからイメージを作成する ``` $ docker commit CONTAINER_NAME IMAGE_NAME ``` 音声デバイスの権限を付与して、コンテナを起動 ``` docker run -it --privileged --volume /dev/dsp:/dev/dsp:rw julius_base bash ``` ## Dockerfile作成時の注意点 - Base Image(親を持たないイメージ)は、最初にFROM scrathをつける。 - 最初にRUN apt-get update -y をしないと、Apt-getコマンドは何も通らない。 ## DockerHubにDockerFileが無い理由 - 単にユーザーがセットアップしていない - chrootが必要なファイルやディレクトリから作られたbaseイメージで、この工程を表すDockerfileの記法がなかった。 - ビルドに自動ビルドでは用意できない特別な引数/ファイルが必要だった。 - 複数のタグを作るのに、自動ビルドでは都合が悪かった。 - interactiveなステップが必要であり、Dockerfileの記法で書けなかった。 ## CentOS7.7を使ってサーバ管理 CentOS7.7のイメージをPull ``` docker pull centos:7.7.1908 ``` イメージからコンテナを作成 ``` docker run -it -p 5000:5000 mec_mock docker run -it -p 1883:1883 -p 5000:5000 mec_mock ``` ## Dockerを使ったMQTT通信 DockerFileを作成(作業用PCのsrc/k8s_mqtt/dockerへ配置) 下記コマンドでDockerFileからイメージを作成する。 pahoのバージョン違いによるエラーだと思われる! と思ったが、local/containerのpahoはともに1.6.1だった、、。 mosquittoのバージョンはどうだろうか? ローカル: mosquitto=2.0.15 mqttブローカーのサポートバージョンはv5.0/v3.1.1/v3.1 コンテナ: mosquitto=1.6.9 mqttブローカーのサポートバージョンはv3.1.1 コンテナの方が古いのが問題だと思われる。 mosquittoのバージョンを最新にするため、下記を実行する $ apt install software-properties-common $ apt-add-repository ppa:mosquitto-dev/mosquitto-ppa $ apt-get update $ apt-get dist-upgrade →これによってmosquitto=2.0.15で揃ったがそれでもまだだめ。 mosquittoのバージョンは揃ったが、疎通が取れない OpenCVの実行時にエラーが出るので、[こちら](https://qiita.com/narista/items/a3d7d26ae50d54c2553a)を参考にする。 OpenCVインストール時にタイムゾーンどこ?と聞いてくるせいで進まないので、[こちら](https://qiita.com/yagince/items/deba267f789604643bab)で対応すること。 ブローカーの状態を確認するためのトピック一覧はこちら https://creepfablic.site/2020/01/24/mosquitto-broker-status/ systemctl側からの確認方法 sudo systemctl status mosquitto 外部のIPアドレスから叩けるようにするためのMOSQUITTO設定 https://diysmarthome.hatenablog.com/entry/2022/07/23/210903 コンピュータの外部からの接続を受け付けるためには、デフォルト設定に対して、追加設定が必要になります。LANからの匿名アクセスを受け付ける場合、 /etc/mosquitto/mosquitto.conf の最後に次の2行を追加します。 ``` allow_anonymous true listener 1883 ``` これで動いた!!!!! 神かな??素晴らしい!!! # エッジ側 ``` # DockerFileからImageをビルドする $ docker image build -t object_detector_mqtt:latest . # ロボカー側のPod起動方法について $ docker run --net=host --privileged --volume=/dev:/dev --gpus all --rm -it -p 192.168.100.101:8883:1883 --name object_detector_mqtt_sub object_detector_mqtt:latest python3 /robocar_gpu_offloader.py ``` # サーバ側 ``` docker image build -t object_detector_mqtt:latest . docker run --gpus all --rm -it -p 172.21.6.2:8883:1883 --name object_detector_mqtt object_detector_mqtt:latest python3 /mqtt_subscriber.py docker run --gpus all --rm -it -p 172.21.6.2:8884:1883 --name object_detector_mqtt_pub object_detector_mqtt:latest python3 /mqtt_publisher.py ``` # 可視化PC側の開発 ``` # DockerFileからImageをビルドする $ docker image build -t result_mqtt_ros_bridge:latest . # 画像をSubscribeして画像処理を行うPodを起動する $ docker run --rm -it --net=host -p 192.168.100.100:8883:1883 --name object_detector_mqtt result_mqtt_ros_bridge:latest python3 /mqtt_ros_visalizer.py # 画像をPublishする画像処理をするPodを起動する $ docker run --gpus all --rm -it -p 192.168.100.100:8884:1883 --name image_publisher_mqtt result_mqtt_ros_bridge:latest python3 /mqtt_publisher.py ``` # トラブルシュート おもしろ記事 https://zenn.dev/turing_motors/articles/4247435fcc8ace docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]]. 認識できるGPUが無いとのことだが、nvidia-smi等は通る謎のエラー [この記事](https://cocoinit23.com/docker-gpu-error-response-from-daemon-linux-runtime-spec-devices-could-not-select-device-driver-with-capabilities-gpu/)によると、Nvidia Toolsを入れ直したのにDockerのデーモンが再起動していないために起こるとのことだったので、一度PCごと再起動してみる。 治らなかったため、[別の記事](https://www.yurui-deep-learning.com/2021/08/17/docker-error-response-from-daemon-could-not-select-device-driver-with-capabilities-gpu/)で下記を実行したら治った sudo apt-get install nvidia-container-runtime service docker restart docker でビルドするたびに名前を失ったDangling(宙ぶらりん)ファイルが生成されてします。それを消すコマンドが下記。 ``` $ docker image prune ``` [PlantUML is 糞](https://qiita.com/sakai00kou/items/18e389fc85a8af59d9e0) OpenCV周りでエラーが出る。 これは、作業用PCでに入れたDockerイメージ(Ubuntu20.04:latest)にOpenCVがデフォルトで入っていたのに対し、Jetpack版Ubuntuがそうでは無いため、Requirement.txtに入れる必要があるようだ。 が、それでも問題があった。よく考えたらROSにOpenCVが入っているためそちらで良い気がするのでROSを先に入れることにする。 no space on deviceが表示されDocker各種コマンドが実行できなくなった。 下記が参考になりそう。 https://qiita.com/ponsuke0531/items/edf2eee638202aa7f61f 下記で解決した。デバイスファイルが圧迫しているようだった。 https://qiita.com/shione/items/dfa956a47b6632d8b3b3 やはりPython2系で動かすとTorchがエラーを吐く。 当然、最新のモデルを使いたいのであればPython3系での動作が必須だが、同時にロボカーのドライバ類が2系が必須であり、取れる手段は下記2つとなる。 ①ロボカーのローカルでROS1を、Docker内でROS2を動かしその2つを通信させてROS上での動作を行う(力技) ②Docker内でもROS1を動かし、推論部分のみをPython3で動かすようにする。(小手先術) ②が楽で嬉しいが、無理なら①で動かしたい。 いや、両方面倒くさいので一旦ROS無しで動かしてみて、無事動作した後にROS化を考える。 →それで問題無く動いたらそこから考えるで良いと思われる。 OpenCVのダウンロードが止まっているように見える問題は、単純に長過ぎてそう見えるだけだったようだ。 pipオプションに--verboseをつけるとしっかり進んでいるのがわかる。 →が、だめ進んでいるが最終的に下記と同様のエラーが出る。 https://stackoverflow.com/questions/63732353/error-could-not-build-wheels-for-opencv-python-which-use-pep-517-and-cannot-be アップグレード対応をしたが、同様のエラーを吐くため別の方法を探す。 動いたら次はどの推論器を使うか?について考える。 →今日中にサーバ・ロボカーでの物体認識の動作を確認する。 →それが動いたら物体検出・セグメンテーションの実装とその可視化を行う Jetpackに依存する、Torchのバージョンのいくつが入るか?などにも依存するため、後回しでも良いかも? ただただ一枚の画像を投げて、それを受け取ったら処理して返すだけ。 →同じモデルで実行する。 →サーバ上の推論器は動きそう。同じ重みでロボカーも実装したいが、Imagebuild中なので別の作業をすすめる。 Ping情報のコード上での取得は下記URLを参考に開発するべし。 https://shigeblog221.com/python-ping/ あと必要なのは、受け取った情報を可視化するところ。 →これは作業用PCにてMQTTの情報を待ち受けていて、受け取ったらそれを可視化するという方法で良いかもしれない。 # Torchのデフォルトだと認識精度悪すぎ問題 車載カメラ動画だとほぼ認識されない問題に直面している。 → # Segmentation 可視化 scikit-imageを入れる。 pyenvで3.9.12であることを確認して下記のコマンドを実行 ``` $ python -m pip install scikit-image ``` importの環境でROSのPythonパスが通ってると壊れてるから再インストールしてねと表示されるため、Bashrcから消しておくこと。 # Protobuf 勉強 画像サイズが224*224をBase64エンコードするとAWS上限に引っかかるみたい。 そのため、グーグルが出している早くて軽いProtobufでのエンコードを検討する [こちら](https://self-development.info/protobuf%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%80%90python%E3%81%A7protocol-buffers%E3%80%91/)の記事を参考にした。 行った手順:pyenvを使っている場合、pipは必ずpython -mから実行すること ``` python -m pip install --upgrade google-api-python-client, google python -m pip install protobuf ``` すると書き方が古いみたいで、3.20.x以下にしてねとゴネられたので下記を実行したところ ``` python -m pip install protobuf==3.20.0 ``` いや、糞面倒くさいから後回しにしてとりあえず、Zipで →今日この後やっておこう。 sys pc docker run --rm -it --net=host -p 192.168.100.110:8883:1883 --name od_offloader result_mqtt_ros_bridge:latest python3 /mqtt_ros_visalizer.py docker run --net=host --privileged --volume=/dev:/dev --gpus all --rm -it -p 192.168.100.110:8883:1883 --name od_offloader od_offloader:latest python3 /robocar_gpu_offloader.py
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up