20200530のdockerに関する記事は19件です。

GitLabとEclipseのEgitでGitLab Flow運用をやってみよう

はじめに

ブランチ戦略が決まったら結局何をやったら良いの?という疑問を掘り下げてみた。
CUIでやってみるのが一番理解が深まりそうだが、結局、プログラムを書く人がオペレーションするのはIDEなので、IDE上での操作を中心に運用方法を整理してみよう。

GitLabのインストール

今回の目的はちゃんとしたGitLabを作ることではないので、以下の記事を参考にしながら手抜きで作る。GitLabを起動した後のメモリ使用量は2.5GB程度になるので、t2.mediumなEC2を用意しよう。

【Qiita】Docker ComposeでGitLabを起動

ちなみに、テキトーに起動するとGitLab内のリンク動作があやしくなるので、URLだけはちゃんと設定する。本来はEIPとってRoute53でドメイン固定にするか、ALB/NLBあたりに頑張らせるかとかを考えるのだけど、面倒なので、今回はEC2起動時のパブリックDNSを使って起動することにしよう。EC2が再起動すると、ローカルリポジトリが迷子になるので、実運用では絶対にやってはいけない。

EC2のパブリックDNSをEC2自らが取得する方法は↓これ。
【AWS公式】インスタンスメタデータの取得

以下の様に環境変数を定義して、

$ export EXTERNAL_URL=`curl http://169.254.169.254/latest/meta-data/public-hostname`

こんな感じでdocker-compose.ymlに渡してあげる。

docker-compose.yml
version: "3.7"
services:
  gitlab:
    container_name: gitlab
    image: gitlab/gitlab-ce:latest
    restart: always
    volumes:
      - ".conf:/etc/gitlab"
      - ".log:/var/log/gitlab"
      - ".data:/var/opt/gitlab"
    ports:
      - "9001:80"
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url "http://${EXTERNAL_URL}"
        nginx['listen_port'] = 80
        nginx['listen_https'] = false
        gitlab_rails['time_zone'] = 'Asia/Tokyo'

これで

$ docker-compose up

で起動すればGitLabの準備完了だ!

GitLabの日本語化

英語じゃ嫌よ、と言う人はこの手順で日本語化。

右上のメニューから
キャプチャ.PNG

「Settings」を選択して
キャプチャ2.PNG

出てきた画面のサイドバーから「Preferences」を選択して
キャプチャ3.PNG

下の方にスクロールしていって、「Localization」セクションの「Language」で日本語を選択して、「Save changes」ボタンを押せば完了!
キャプチャ4.PNG

リポジトリのチェックアウト

リポジトリURIのコピー

GitLabのプロジェクトの画面で、以下のボタンを操作してURIをコピーする。
キャプチャ9.PNG

Gitリポジトリービューの表示

Eclipseのメニューの「ウィンドウ」⇒「ビューの表示」⇒「その他」を選択。
キャプチャ5.PNG

開いたダイアログで、「Git」でフィルタし、「Gitリポジトリー」を選択。
キャプチャ6.PNG

↓のようなビューが開けば成功。好きなところに配置しておく。
キャプチャ7.PNG

リポジトリのチェックアウト

Gitリポジトリービューのメニューアイコンで矢印の点のものを選択し、出てきたメニューから「リポジトリーのクローン」を選択。
キャプチャ8.PNG

開いたダイアログで、URIにコピーしたURIを貼り付け。「ホスト」と「リポジトリー・パスは」オートフィルされる。ポートは80から変更していないなら指定は不要。
認証は、GitLabの認証IDとパスワード。「セキュア・ストアに保管」にチェックを入れていると次回以降はオートフィルされる。
キャプチャ10.PNG

以降はデフォルトのまま「次へ」を選択していけば、以下の様にGitLabのリポジトリがcloneされてローカルで参照可能になる。
キャプチャ11.PNG

プロジェクト・エクスプローラーの設定

上記のままだと操作がしにくいので、プロジェクト・エクスプローラーでも編集可能なように設定をする。

プロジェクト・エクスプローラー上で右クリックをして「インポート」を選択。
キャプチャ12.PNG

開いたダイアログで、「Git」でフィルタして「Gitからプロジェクト」を選択し、「次へ」ボタンを押す。
キャプチャ13.PNG

開いたダイアログで「既存ローカルリポジトリー」を選択して「次へ」ボタンを押す。
キャプチャ14.PNG

開いたダイアログで、前の手順でcloneしたgitのローカルリポジトリを選択して「次へ」ボタンを押す。
キャプチャ15.PNG

開いたダイアログで、「一般的なプロジェクトとしてインポート」して「次へ」ボタンを押す。
もしかして、Mavenプロジェクトだった場合は「新規プロジェクト・ウィザードを使用してインポート」しないといけないかもしれない。
キャプチャ16.PNG

あとは、適当にプロジェクト名をつけて「完了」すれば良い。
キャプチャ17.PNG

プロジェクト・エクスプローラーにGitのローカルリポジトリが入った!
キャプチャ18.PNG.jpg

Gitの概念を知っておく

色々といじり倒す前に、Gitの概念をちゃんと知っておかないと痛い目にあう。
以下の記事が分かりやすい。

【Qiita】【Git】リモートからの取得とリモートへの反映で行っていること(fetch,pull,push)

記事中で「リモート追跡ブランチ」と書かれているものは、Eclipseでは「リモート・トラッキング」と表現されている。
以下はGitリポジトリービューでの表示例。リモート・トラッキングにはissue01があるが、ローカルには無い。これは、fetchはしてきたが、checkoutはしていないという状態である。この状態では編集ができない。
キャプチャ19.PNG

ヒストリーで見るとこんな感じ。色と、originが付与されているかどうかで見分けがつく。
キャプチャ20.PNG

逆に、ローカルでCommitしていても、Pushしていなければリモートに反映されないので注意が必要。

この辺りの概念を踏まえて、GitLabとEclipseで行うオペレーションを整理する。

featureブランチにIssueを登録する

GitLab Flowの原則は、masterブランチからfeatureブランチを分岐させて開発を行うことである。
GitLabでは、課題(Issue)をもとにブランチを作成するのが基本らしい。

課題(Issue)の登録

プロジェクトのサイドバーから「課題」を選択する。
キャプチャ21.PNG

開いた課題一覧の画面で「新規課題」のボタンを押す。
キャプチャ22.PNG

適当に課題を起票して「Submit 課題」ボタンを押す。
キャプチャ23.PNG
キャプチャ24.PNG

課題の詳細画面にある「マージリクエストとブランチを作成」の右にある▼のボタンを押して「ブランチ作成」を選択。ブランチ名をfeature/ブランチ名にして、ソースをmasterにしてから「ブランチ作成」ボタンを押す。
キャプチャ25.PNG

リポジトリのブランチ一覧を見ると、さきほど追加したブランチが表示されている。
キャプチャ26.PNG

Eclipseへの反映

当然、これはEclipse側には反映されていないので、Eclipse側のローカルリポジトリとリモート・トラッキングリポジトリに取り込みを行う。

Gitリポジトリービューで、対象のリポジトリを右クリックして表示されたメニューのプルを選択する。
キャプチャ27.PNG

すると、先ほど作ったブランチがPullされた旨のダイアログが表示される。
キャプチャ28.PNG

Gitリポジトリービューを見ると、リモート・トラッキング側に追加したブランチが表示されるようになる。ただし、↑に書いた通り、これはまだローカルブランチまで反映されていない。
キャプチャ29.PNG

リモート・トラッキングにfetchされてきたブランチを右クリックして、表示されたメニューで「ブランチの作成」を選択する。これ、めちゃくちゃ分かりにくいけど、「ローカルブランチの作成」を意味するらしい……
キャプチャ30.PNG

次に表示されるダイアログは、特に何もいじらず「完了」ボタンを押す。
キャプチャ31.PNG

すると、ローカルリポジトリにもPullしてきたリモート・トラッキングと同じ内容になる。
キャプチャ32.PNG

featureブランチを更新する

今回の変更の前提

今回の修正は以下のような内容とする。
これを、masterに書き戻すところまでやってみよう。

test.sh(変更前)
#!/bin/sh

echo "master"
test.sh(変更後)
#!/bin/sh

echo "master"

echo "feature/issue01"

更新したらまずはCommitする

上記の更新をしたら、まずはCommitをしてみよう。

プロジェクト・エクスプローラーの対象リポジトリのプロジェクトを右クリックして、表示されたメニューで「チーム」⇒「コミット」を選択する。
キャプチャ33.PNG

Gitステージングのビューが開くので、Commitしようとしているブランチが正しいか確認し、「ステージされた変更」に対象ファイルが入っていることを確認したら「コミット」ボタンを押す。入っていなかったら「ステージされていない変更」から「ステージされた変更」にドラッグ&ドロップする。
「コミット」ボタンは、その左の「コミット及びプッシュ」ボタンでも良いが、今回は状態も含めて確認するために一旦Commitのみにする。
あと、例では書き忘れたらコミット・メッセージが入っていないとエラーになるので注意。
キャプチャ34.PNG

こうすると、Gitリポジトリービューのブランチの表示に「↑1」という文字が現れる。
これは、まだリモートリポジトリにPushしていないものがあるということを意味する。
キャプチャ35.PNG

次は、Gitリポジトリービューで対象のリポジトリを右クリックして「アップストリームへプッシュ」をする。
キャプチャ36.PNG

すると、プッシュ結果と、「マージリクエストするならここに来い」というリンクが表示される。
このリンクを踏むとEclipse内でブラウザが上がってうざいので、通常使っているブラウザにコピー&ペーストしよう。
キャプチャ37.PNG

リモートリポジトリ側も確認してみよう。ちゃんと更新が反映されている!
キャプチャ38.PNG

featureブランチをmasterブランチにマージする

さて、課題からブランチを作ったのだから課題からマージができるのだろうと思うが、課題からマージリクエストとしようとするとなぜかブランチがもう一本できてしまうので、手動でマージリクエストをする。

プロジェクト画面のサイドバーから「マージリクエスト」を選択し、表示されたマージリクエストの一覧画面で「New Merge Request」ボタンを押す。
キャプチャ39.PNG

Source Branchの「ソースブランチを選択」のプルダウンから対象のブランチ(今回はfeature/issue01)を選択し、Target Branchは今回はそのままで問題ないはず。もし、masterが選択されていないようであれば、masterにして、「Compare branches and continue」のボタンを押す。
キャプチャ40.PNG

マージリクエストの詳細はテキトーに入れて、「Submitマージリクエスト」のボタンを押す。
ソースブランチは消しちゃっても問題ないが、今回は一応消さないようにチェックを外しておく。
キャプチャ41.PNG
キャプチャ42.PNG

マージリクエストが送られたら、マージ可能なユーザが詳細画面に行き「Merge」ボタンを押す。
キャプチャ43.PNG

マージ完了!普通はここからCI/CDが起動するから、実運用時はちゃんとコードレビューが終わってからマージするように。
キャプチャ44.PNG

グラフを確認しても、ちゃんとfeature/issue01がmasterに取り込まれたグラフになっていることが分かる。
キャプチャ45.PNG

なお、マージ前のレビューはWebからも行える。
詳細画面の「Web IDEで開く」ボタンを押す。
キャプチャ46.PNG

こんな感じでdiff確認のようなものができる。
小さいソースでやる分には良いけど、差分が多かったりしたらEclipseとかの方がレビューしやすいのではないかな、と思う。
キャプチャ47.PNG

なお、マージ後のローカルリポジトリへの反映は、最初と同じようにPullすれば良い。
キャプチャ48.PNG

ここから後は

基本は同じ。pre-productionブランチなり、productionブランチなりにマージリクエストをすればよい。ブランチに合わせてCI/CDパイプラインを作っておけば、夢の「起動環境ごとの自動化」も実現可能。夢が広がる。

ちなみに、GUIは乏しいが、この記事で書いたことはCodeCommitでも行える。CodeCommitの場合、マージリクエストではなくプルリクエストという名称だが、中身は変わらない。たぶんGitHubも同じだと思う(GitHubは使ったことがない)。

masterが次期開発で汚れているときのhotfixのcherry-pickはどうやるべきなの?といった課題は出てくるので、追々検証して追記してみようと思う。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerでCakePHP4.0.8さわってみました。(apach)

はじめに

今回githubの方にまとめる形をとってみました!!

手順まとめてあるので以下見てください!:relaxed:
https://github.com/sachiko-kame/docker_cakePHP

ちなみにDockerコマンド打てるところからお願いします!
打てない場合『困ったときは以下も』の一番上のリンクから行う形になるかんじです!
apacheとかあまりないような気がして今回載せました。

一応:

CakePHP 4.0.8 Strawberry
php7.4
mysql8
docker ver3
Apache/2.4.38 (Debian) ←指定したわけでなくコマンドで確認したもの($ apachectl -v)

工夫したところ

ボリュームするとコピーファイル消えるので、コンテナ中で作成したものをコマンドで移動すると言う方法を取りました。
コマンドで移動出来なかったものは手作業で移動しています。
apacheのファイルのみ移動すれば問題ないと思ったのですが本来入るべき場所にとあるもの全部移動した感じです。

image5.png

困ったときは以下も

全部自分の記事です!:relaxed:

Dockerの大まかなイメージから自分が作成したものをDockerhubにあげて、インストールして実行まで

[Docker][apache][CakePHP]The requested URL was not found on this server.

CakePHPハマったの対策

とりあえずhtmlの表示をDocker使って行う[apacheバージョン]

最後に

テーブルの自動作成とか出来たら良かったのですがそこまで出来ませんでした?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dockerのMutagen-based caching導入におけるファイル権限が変わってしまう場合の対応

はじめに

docker for macを使っていましたが速度が遅く、vagrantを立ててその中にdockerを構築しようと思ったのですが、dockerのアップデートで Mutagen-based cachingが導入されたようでdocker for macを快適に利用できるようになりました。

ただファイルの権限が変わってしまうようで、自分はmysqlが下記のエラーが発生して起動できなくなってしまいました。

mysqld: can't create/write to file

この対処法を書いていきます。

dockerの再インストール

現在Edge Releaseされているものはmutageでファイルを同期させた場合権限が変わってしまい、それに対してissueが上がっていました。

https://github.com/docker/for-mac/issues/4593

このissueにて早速修正されたものがアップされているようですので下記のURLからdockerをダウンロードして再インストールし、再度ファイルの同期を行えば権限の問題が解消されます。

https://desktop-stage.docker.com/mac/edge/45429/Docker.dmg

またデフォルトでの権限を変更したい場合はホームディレクトリ直下に.mutagen.ymlファイルを作成して

sync:
  defaults:
    permissions:
      defaultFileMode: 0655
      defaultDirectoryMode: 0755

みたいに権限のデフォルト設定ができるようですが、自分はうまくいきませんでした....

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerについて

前提

Dockerについて学んだことを書いていきます。

本題

基本コマンド

docker image build -t
Dockerfileの情報を元にコンテナのイメージをbuildする。

Build

指定したディレクトリに存在するDockerfileを読み込みコンテナイメージをbuildする。

buildしたコンテナイメージは実行したマシンに保存される。
保存する時の名前を-tのタグでつける。

ローカルに保存されているDockerコンテナの内容表示
docker image ls

docker run -d -p 8080:80 dockerdemo:latest
-d デタッチ(コンテナをバックグランドで起動する)
-p パブリッシュ(ポートを指定、左側がホストからの接続ポート・右側がコンテナ側への接続ポート)
ホストへは8080のポートで接続するが、実際には80ポートに変換されるイメージ。

実行中のコンテナの出力
docker container ls

コンテナの停止
docker container stop コンテナID

コンテナのネットワークとは

サーバにはLANポートがある。
物理的にLANケーブルを接続するNICがいくつかある。
EC2などの仮想サーバも同様。
EC2はこのようなNICが仮想化されているだけで仕組みは物理サーバと同様。
Eth0にきた通信はKernelで制御される。
リナックスだとiptablesなどで通信の制御をしたりすることがある。
Dockerはこのようなカーネルレベルでもいい感じに動作し、コンテナと外部通信の橋渡しをしてくれる。

Eth0のような物理的なレイヤーを通過

Dockerネットワークのレイヤーに到着

Dockerデーモンが物理レイヤーとDockerレイヤーのネットワークを接続する

コンテナはDockerデーモンを通じて外部のネットワークと通信している
↓Dockerレイヤーの中身
もっともよく使われているシンプルなネットワーキングBridge

Bridgeという仮想的なネットワークの接続ポイントを使用した方法

コンテナを3つ立ち上げた場合

vethをかいして、それぞれのコンテナはBridgeに接続している

Bridgeはネットワーク機器でいうとスイッチのような役割で、Bridge自体は独立したネットワーク領域

Bridgeに応じたIPアドレスがコンテナに割り当てられる

Bridgeは複数作成することができる

docker network ls
現在のDockerネットワークの情報を表示する。

docker network inspect bridge
ネットワークアドレスが何になるか確認。

Bridge作成
docker network create --attachable -d bridge --subnet=10.99.0.0/16 greenbridge

コンテナのボリュームとは

デフォルトでは、コンテナの内部で生成されたデータはコンテナの内部に保存される。
→コンテナを削除してしまうと綺麗さっぱり消えてしまう。
コンテナは不変かつ一時的な実行プロセスという特徴の一つであり、諸刃の剣。
データベース系のコンテナはずっと消えることのないデータを必要としている。

コンテナの中にカスタマイズしたデータを保存しないようにする。

Dockerのmountを使用することでコンテナとホスト、両方ファイルを共有することができる。

ファイルを共有する領域がDockerの管理下にあるか、ホスト側の管理下にあるかの違い。

Volumes
コンテナとDockerエリアと連携する方法

Bind mount
任意のファイルシステムの領域とコンテナがファイルを共有できる

Dockerの管理下Volumesのmount方法
Dockerfileの編集
VOLUME /var/www/html
VOLUMEはコンテナ側のマウントポイントを指定する

Bind mountでファイル共有方法
docker container run --name bindmount1 -d -p 80:80 -v /root/bindmount:/var/www/html volumdemo:latest

-v
左側にホストでマウントさせたいディレクトリを指定する。
:を挟んで右側のコンテナ側のマウントさせたい領域

docker container run --name bindmount1 -d -p 80:80 -v ${pwd}:/var/www/html volumdemo:latest

${pwd}で現在いるディレクトリを自動的に置き換わる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dockerのイメージ操作コマンドまとめ

イメージの操作

イメージのダウンロード

$ docker image pull [オプション] イメージ名[:タグ名]

イメージの一覧表示

$ docker image ls [オプション] イメージ名[:タグ名]
オプション 説明
--all, -a 全てのイメージを表示
--digests ダイジェストを表示するか
--no-trunc 結果を全て表示する
--quiet, -q DockerイメージIDのみ表示

イメージの詳細確認

$ docker image inspect
  • イメージID
  • 作成日
  • Dockerバージョン
  • CPUのアーキテクチャ

がわかる

イメージのタグ設定

$ docker image tag 

イメージの検索

$ docker search [オプション] 検索キーワード
オプション 説明
--limit n件の検索結果を表示す
--filter=stars=n お気にり数を指定
--no-trunc 結果を全て表示する

イメージの削除

$ docker rm [オプション] イメージ名 [イメージ名]
オプション 説明
--force, -f イメージを強制的に削除する
--no-prun 中間イメージを削除しない

未使用のDockerイメージを削除する

$ docker prune [オプション] 
オプション 説明
--force, -f イメージを強制的に削除する
--all, -a 使用していないイメージをすべて削除

イメージのアップロード

$ docker image push イメージ名[:タグ名}

DockerHubの操作

Docker Hubへのログイン

$ docker login [オプション] [サーバ]
オプション 説明
--password, -p パスワード
--username,-u ユーザ-名

Docker Hubへのログアウト

$ docker logout [サーバ]

参考

https://www.amazon.co.jp/dp/B017UGA7NG/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-composeの運用コマンドをまとめ

Docker Composeのバージョン確認

$ docker-compose --version

複数コンテナの生成

$ docker-compose up [オプション] [サービス名.]
オプション 説明
-d バッググラウンドで実行
--no-deps リンクのサービスを起動
--build イメージをビルドする
--no-build イメージをビルドしない
-t, --timeout コンテナのタイムアウトを秒指定
-scale SERVICE=サービス数 サービスの数を指定

複数コンテナの確認

状態確認

$ docker-compose ps

ログの確認

$ docker-compose logs

コンテナでのコマンド実行

$ docker-compose run

複数コンテナの起動

$ docker-compose start

複数コンテナの停止

$ docker-compose stop

複数コンテナの停止

$ docker-compose restart

複数コンテナの一時停止

$ docker-compose pause

複数コンテナの再開

$ docker-compose unpause

サービスの構成確認

$ docker-compose port [オプション] サービス名 プライベートポート番号
オプション 説明
--protocol=proto プロトコル。tcpまたはudp
--index=index コンテナのインデックス数

複数コンテナの強制停止

$ docker-compose kill

-sで、Linuxのシグナルを送ることが可能。

複数コンテナの削除

$ docker-compose rm

複数リソースの一括削除

$ docker-compose down
オプション 説明
--rmi all 全てのイメージを削除
--rmi local カスタムタグのないイメージだけ削除
-v, --volumes Compose定義ファイルのデータボリュームを削除
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker初心者が、docker-compose.ymlの書き方をまとめる

docker-composeとは

複数のコンテナをまとめて管理するためのツール

docker-compose.ymlにコンテナの構成情報を定義することで、同一のホスト常の複数コンテナを一括管理できます。
docker-compose

Webアプリケーションの依存関係をまとめて設定できます。
複数のコンテナを的mて起動したり停止したりできる。

コンテナの構成情報をYAML形式のファイルとして管理できるため、継続的デプロイやインテグレーションのプロセスに置いて自動テストを行うときに環境構築でそのまま利用できる。

docker-compose.ymlの概要

versionによってかける内容が異なる。
今回かくのは、3.3です。

サンプルファイル

#バージョンの指定
version: "3"

#サービス定義
services:
  webserver:
    image: ubuntu
    ports:
     - "80:80"
    networks:
      - webnet
 redis:
   image: redis
   networks:
     - webnet

#ネットワーク定義
networks:
  webnet:

#データボリューム定義
volumes:
  data-volume:

イメージの指定

imagesを使って指定する。

#サービス定義
services:
  webserver:
    image: ubuntu

イメージのビルド

buildを使って指定する。

#サービス定義
services:
  webserver:
    build: . #カレントディレクトリ

カレントディレクトリにDockerfileも用意し、ベースイメージを指定する、
Dockerfileで指定されたイメージが自動ビルドされる。
contextでDockerfileがあるディレクトリを指定して、指定したファイルをDockerfileとして読み込める。

#サービス定義
services:
  webserver:
    build:
    context: /work
      dockerfile: Dockerfile-all

コンテナ内で動かすコマンドを指定

command: /bin/bash

entrypointを上書きすることも可能です。

コンテナ間の連携

logserverに連携したい場合は、以下のように書く。エイリアス名を付けたいときは「サービス名:エイリアス名」を書く

links:
  - logserver
  - logserver:log01

コンテナ間の通信

コンテナが公開するポートは、portsで指定。
ホストマシンのポート番号:コンテナのポート番号を指定するか、コンテナのポート番号のみを指定する。
コンテナポート飲みを指定したときは、ホストマインのポートはライダムな値が設定される。

ports:
  - "3000"
  - "8000:8000"
  - "127.0.0.1:8001:8001"

ホストマシンへポートを公開せず、リンク機能を使って連携するコンテナにのみポートを公開するときはexpose

expose:
  - "3000"
  - "8000"

サービスの依存関係の定義

webserverコンテナを開始する前にdbコンテナとredisコンテナを開始したいとき

services:
  webserver:
    build:
    depends_on:
      - db
      - redis
 redis:
   images: redis
 db:
   image: postgres

depend_onがコンテナの開始の順序を制御するだけで、コンテナ上のアプリケーションが利用可能になるまで待つという制御を行わない。
=> アプリケーション側での制御が必要。

コンテナの環境変数の指定

enviroment:
  - HOGE=fuga
  - FOO

設定したい環境変数が多いときは、別ファイルに環境変数を定義して、そのフォイルを読み込みこともできる。

env_file:
  - ./envfile1
  - ./app/envfile2

コンテナ名の指定

container_name: コンテナ名

コンテナ名は一意でないといけない。

コンテナのデータ管理

ボリュームの指定

volumes:
  - /var/lib/mysql
  - cache/:/tmp/cache

ボリュームの読み取り専用の指定

:roをつけると、読み取り専用になり、書き込みができなくなります。設定ファイルなどに付与。

volumes:
  - ~/config:/etc/configs/:ro

ボリュームのマウント指定

別のコンテナから全てのボリュームをマウントするときは、volumes_fromにコンテナ名を指定する

volumes_from:
  - log
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker Desktop for WSL2のKubernetesコンテキストをWSL2と同期する

Windows側のシステムトレイ上のDocker Desktop for WSL2メニューにあるKubernetesコンテキストを、WSL2側の~/.kube/configと同期するための手順です。同期することで以下のようなことができるようになります。

  • WindowsのシステムトレイにあるDocker DesktopメニューからKubernetesコンテキストの参照および切り替えができる。切り替えた場合はWSL2側にKubernetesコンテキストが反映される。
  • WSL2側から~/.kube/configを更新した場合に、Docker DesktopメニューのKubernetesコンテキストに反映される。

NOTE:
そもそも何故この同期設定が盛り込まれてないのかが個人的には疑問です。どこかのタイミングでDocker Desktop for WSL2がこの同期設定に対応するかもしれないので、その際にはコメントをいただければ幸いです。

設定手順

WSL2およびDocker Desktop for WSL2がインストール済みで利用できる状態を想定しています。

  1. Windows側(Docker Desktop)に%USERPROFILE%\.kube\configを作成する。既に存在する場合はスキップする。
  2. Windows側の~/.kube/configを参照するシンボリックリンクをWSL2側に作成する。WSL2のターミナルから以下のようなコマンドを実行することで作成できる。既にWSL2側に~/.kube/configがある場合はバックアップを取るか削除すること。

    # システムドライブがCドライブ、Windowsユーザがtaroの場合
    # NOTE: c, taroの部分は適切な値に置き換えること
    mkdir -p ~/.kube
    ln -s /mnt/c/Users/taro/.kube/config $HOME/.kube/config
    

これで設定完了となります。
なお、この設定手順ではWindows側の./kube/configがマスタファイルになります。

以下のようにWSL2側のKubernetesコンテキストとWindows側のDocker DesktopメニューのKubernetesコンテキストが同期していることが分かります。

k8s-context-menu-01.png

以下はkindのKubernetesクラスタをWSL2上から作成した直後の画像です。kindのKubernetesクラスタが作成されるとWSL2側の~/.kube/configのKubernetesコンテキストが追加&更新されますが、これがWindows側のDocker DesktopメニューのKubernetesコンテキストと同期していることが分かります。

k8s-context-menu-02.png

NOTE:
ちなみにWSL2のターミナルのシェルプロンプトの「絵文字 + カラフル文字」でのKubernetesコンテキスト表示はkube-ps1.shを利用して実現してます。Kubernetes上での開発や検証が多い人にはお勧めです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-compose up -d時にThe container name "/XXX" is already in use by container.

docker-compose up -d時にThe container name "/XXX" is already in use by container.

$ docker-compose up -d
Creating XXX ... error

ERROR: for XXX  Cannot create container for service XXX: Conflict. The container name "/XXX" is already in use by container. You have to remove (or rename) that container to be able to reuse that name.

以前に起動したコンテナと名前が重なっているので、以下の通りdocker rmで不要なコンテナを削除して再実行して解決

$ docker rm $(docker ps -aq)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerfileのファイル設定の書き方

ファイル/ディレクトリの追加

ADD <ホストのファイルパス> <Dockerイメージのファイルパス>

ADD命令はホスト上のファイル/ディレクトリやリモートファイルを、Dockerイメージ内にコピーする。
リモートファイルのダウンロードや、アーカイブの解凍などの機能がある。
ADD命令は認証をサポートしていないため、リモートファイルのダウンロードに認証が必要なときは、RUN命令でwgetコマンドやcurlコマンドを使う。

ファイルのコピー

COPY <ホストのファイルパス> <Dockerイメージのファイルパス>

COPY命令は、ホスト上のファイルをイメージ内に「コピーする」処理だけを行う。

ボリュームのマウント

VOLUME ["/マウントポイント"]

VOLUME命令は、指定した名前のマウントポイントを作成し、ヒストやその他のコンテナからボリュームの外部マウントを行う。
コンテナは永続データを保持するには向いていないので、永続化が必要なら、コンテナ外のストレージに保存するのが良い。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerfileでの環境や、ネットワークの設定の書き方

環境変数の設定

ENV [key] [value]
ENV [key]=[value]

複数を設定するには、

ENV [key]=[value]

を使います。

作業ディレクトリの指定

WORKDIR [作業ディレクトリのパス]

ユーザの指定

USER [ユーザー名/UID]

ラベルの指定

イメージにバージョン情報や作成者情報、コメントなどの情報をもとせるときは、ラベルを使う。

LABEL <キー名>=<値>

ポートの設定

EXPOSE <ポート番号>

Dockerfile内変数の設定

ARG <名前>[=デフォルト値]

デフォルトシェルの設定

SHELL ["シェルのパス", "パラメータ"]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VboxとSambaを用いたwindows10 HomeでのDocker環境の構築

概要

 先日WSL2が正式リリースとなりwindows homeでもDockerが使えるようになりましたが、個人的にLinux版のDockerのほうが好みだったので、windowsでLinux版Dockerを使えないか考えたところネットワークドライブを使えば可能なのでは??と思ったので作ってみました。

準備

  • Vbox(Hyper-vでも可)
  • CentOS7のISO(8やubuntuでも可)

手順

仮想マシンの作成

  1. VMにNATアダプター、ホストオンリーアダプターを追加する。
  2. VboxでCentOS7のVMを立ち上げる。
  3. yum -y updateを実行し最新版にする。

パッケージのインストール

yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum -y install samba samba-common docker-ce docker-ce-cli containerd.
curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

Sambaの構築

サービスの起動、Firewallの設定、SeLinuxの無効化

systemctl start smb nmb
systemctl enable smb nmb
firewall-cmd --add-service=samba --permanent
firewall-cmd --reload
vi /etc/selinux/config
    SELINUX=enforcing    //enforcingをdisabledに変更
vi /etc/samba/smb.conf   //下記のように変更
mkdir /develop           //このディレクトリがネットワークドライブとして割り当てられる
testparm                 //smb.confにエラーがないか確認

    Load smb config files from /etc/samba/smb.conf
    Loaded services file OK.
    Server role: ROLE_STANDALONE

    Press enter to see a dump of your service definitions

    # Global parameters
    [global]
        disable spoolss = Yes
        dos charset = CP932
        load printers = No
        netbios name = FS
        security = USER
        wins support = Yes
        workgroup = CRAYON
        idmap config * : backend = tdb


    [homes]
        comment = Home Directories
        inherit acls = Yes
        read only = No
        valid users = %S %D%w%S


    [Share]
        comment = Share Folder for All Users
        path = /develop
        read only = No
chmod -R 0777 /develop/
chown -R nobody:nobody /develop/

/etc/samba/smb.confの内容

[global]
#       workgroup = SAMBA
        workgroup = <windos work group>
        security = user

        netbios name = fs

        unix charset = UTF-8
        dos charset = CP932
        wins support = yes

        passdb backend = tdbsam

#       printing = cups
#       printcap name = cups
#       load printers = yes
        load printers = no
        disable spoolss = yes
#       cups options = raw

[homes]
        comment = Home Directories
        valid users = %S, %D%w%S
        browseable = yes
        writable = yes
        read only = no
        inherit acls = Yes

[Share]
        comment = Share Folder for All Users
        path = /develop
        browsable = yes
        writable = yes
        read only = no

#[printers]
#       comment = All Printers
#       path = /var/tmp
#       printable = Yes
#       create mask = 0600
#       browseable = No

#[print$]
#       comment = Printer Drivers
#       path = /var/lib/samba/drivers
#       write list = @printadmin root
#       force group = @printadmin
#       create mask = 0664
#       directory mask = 0775

Sambaアクセス用ユーザー追加

 今回のファイルサーバーでは、ゲストアカウントはアクセスできないため、アクセス用にユーザーの作成が必要になります。ユーザーはLinux側で作成した後に、Sambaに用意されている"pdbedit"コマンドでファイルサーバー用に設定を行います。ここでは”rem-test01”というユーザーを作成してみます。

useradd rem-test01
passwd rem-test01
ユーザー rem-test01 のパスワードを変更。
新しいパスワード:     任意のパスワード
新しいパスワードを再入力してください:     同じパスワードを入力
passwd: すべての認証トークンが正しく更新

pdbedit -a -u rem-test01 -f "windows user name"
new password:     passwdコマンドで設定したものと同じパスワードを入力
retype new password:     確認用にパスワードを再入力

pdbedit -L
rem-test01:1004:<windows user name>

systemctl restart smb nmb

確認・接続

CMDよりping fsを実行して到達するかを確認します。pingの応答が確認できたら、次にコンピューター名を指定してSambaサーバーへ接続できることを確認します。windowsキー+Rでファイル名を指定して実行できるのでそこで表示されたダイアログの名前に”\fs”と入力してOKをクリックします。「ネットワーク資格情報の入力」ダイアログが開きます。ここで先ほど作ったlinux userの情報を入力します。入力した情報が正しい場合、エクスプローラーに設定した共有フォルダが表示されます。
このShareが/developの下になってるはずです。\Shareでフォルダーを作成して/developに配置されていれば構築完了です。/developにwindowsからcompose fileを作成してsshでBuildすればDocker環境として利用することができるともいます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerfileのCMDとENTRYPOINTの違い【Dockerfileのコマンド実行、デーモン実行】

コマンドの実行

RUN命令を使う

RUN [実行したいコマンド]

Shell形式での記述

# Nginxのインストール
RUN apt-get install -y nginx

Exec形式での記述

# Nginxのインストール
RUN ["/bin/bash", "-c", "apt-get install -y nginx"]

どのようなコマンドを実行されたかを確認するには?

docker history 

デーモンの実装

CMD命令を使う
bash
CMD [実行したいコマンド]

イメージをもとに生成したコンテナ内でコマンドを実行するには、CMD命令を使う。
Dockerfileには、1つのCMD命令を記述することができる。
もし、複数指定した時は、最後のコマンドのみが有効になる。

Shell形式での記述

# Nginxのインストール
CMD nginx -g 'deamon off'

Exec形式での記述

# Nginxのインストール
CMD ["nginx", "-g", "daemon off;"]

デーモンの実行

ENTRYPOINT命令を使う

ENTRYPOINT [実行したいコマンド]

Shell形式での記述

# Nginxのインストール
ENTRYPOINT nginx -g 'deamon off'

Exec形式での記述

# Nginxのインストール
ENTRYPOINT ["nginx", "-g", "daemon off;"]

CMDとENTRYPOINTの違い

docker container run コマンド実行時の動作が違います。

CMDの場合

コンテナ起動時に実行したいコマンドを定義しても、docker container runコマンド実行時に引数で新たなコマンドを指定した場合、そちらを優先実行する

ENTRYPOINT

必ずコンテナで実行されますが、実行時にコマンド引数を指定したい時は、CMD命令と組みわせて使う。
ENTRYPOINT命令で実行したいコマンドそのものを指定し、CMD命令でそのコマンドの引数を指定し、コンテナをデフォルトで実行した時の動作を決定できる。

ビルド完了後に実行される命令

ONBUILD [実行したいコマンド]

自身のDockerfileから生成したイメージをベースイメージとした別のDockerfileをビルドするときに実行したいコマンドを記述

例えば、
アプリ実行環境の構築イメージ実行してから、開発したプログラムをデプロイしたイメージを実行
で使用。

システムコールシグナルの設定

STOPSIGNAL [実行したいコマンド]

コンテナのヘルスチェック命令

HEALTHCHECK [オプション] CMD [実行したいコマンド]

Dockerに対してコンテナの正常性をどのように確認するか設定

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Windows 10 Home で Docker Tool Box から Docker Desktop (with WLS2) に移行した

こんにちは。2020年5月28日よりWindows 10 May 2020 Update (version 2004) が配信開始されましたね。
新機能の中でも、WSL2 により Docker Desktop も Windows 10 Homeでも使えるようになりました。

私の PC 環境は Docker Tool Box + Windows 10 Home だったので
WSL2 を導入し、Windows 10 Home でも Docker Desktop を使えるようにしてみました。

Windows 10 Version 2004 への更新

Windows 10 のダウンロード にある「今すぐアップデート」より、アップデーターをダウンロード・インストールします。

image.png

「設定」-「システム」-「バージョン」から以下のようになっていれば OK です。
image.png

WSL2 の設定

仮想化の有効化

タスクマネージャーの CPU 欄にて、仮想化が有効になっているか確認します。

task_cpu

なっていない場合は、BIOSの設定から、有効化する必要があります。
UEFI/BIOS によって設定方法が異なるため、以下を参考にして仮想化を有効にしてください。

WSLの有効化

Power Shell を管理者で起動し、下記コマンドを入力して OSの再起動 をします。

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

WSL 2 Linux カーネルの更新

WSL 2 Linux カーネルの更新 | Microsoft Docs のリンクを開き、最新の WSL2 Linux カーネル更新プログラム パッケージをダウンロードを選択して、インストーラーをダウンロード・インストールします。

image.png

Linuxのディストリビューションをインストール

こちら より、Microsoft Store 経由で Linux のディストリビューションを選択して、インストールします

筆者は、Ubuntsu-20.04 LTS をインストールしました。

WSL に Linuxのディストリビューションを割り当て

WSL に インストールした Linux のディストリビューションを割り当てます

wsl --set-version Ubuntsu-20.04 2

Docker Desktop のインストール

以下より、Docker Desktop インストーラーをダウンロードしてインストールします。
Docker Desktop for Mac and Windows | Docker

image.png

インストーラーを進めていき、ConfigurationEnable WSL 2 Windows Features に チェックが入っていること を確認してください(入っていなければ入れてください)

image.png

完了後、タスクバーの Docker Desktop アイコンを右クリックして、Settings を選択します

env_variable

Generals の Use the WSL 2 based engine にチェックが入っていることを確認します。

image.png

また、Resources の Enable integration with my default WSL distro にチェックが入っていることを確認します。

image.png

Docker Toolbox の設定削除

環境変数の削除

タスクバーの検索ボックスに system と入力し、コントロールパネルのシステムを開きます

system_search

「システムの詳細設定 」 - 「環境変数」と選択して、以下の環境変数を削除します。

env_variable

DOCKER_TLS_VERIFY
DOCKER_CERT_PATH
DOCKER_HOST
DOCKER_TOOLBOX_INSTALL_PATH

これらを削除しないと、Docker Toolboxで設定した環境変数を Docker Desktop でも読み込んでしまうため、イメージを Pull する際に イメージリポジトリに接続できませんでした。

参考:error during connect Get https://192.168.99.100:2376/v1.38/containers/json · Issue #2596 · docker/for-win

Docker コンテナの起動確認

コマンドプロンプト または Power shell から、以下をコマンドを入力します


docker run -dp 80:80 docker/getting-started

タスクバーにある Docker Desktop を右クリックして Dashboard をクリックします。

env_variable

下記のように、 getting-started イメージでコンテナが起動できていればOKです。

image.png

最後に、Docker Toolbox をアンインストールして、完了です。お疲れさまでした。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerfileを理解し、Dockerfileでnginxを起動させる

Dockerfileとは?

  • ベースになるDockerイメージ
  • Dockerコンテナ内で行った操作(コマンド)
  • 環境変数などの設定
  • Dokcerコンテナ内で動作させておくデーモン実行

などのDocker上で動作させるコンテナの構成情報を記述するためのファイルのことです。

Dockerfileの基本構文

Dockerfileの基本書式

命令 引数

Dockerfileの命令

命令 説明
FROM ベースイメージの指定
RUN コマンド実行
CMD コンテナの実行コマンド
LABEL ラベルを設定
EXPOSE ポートのエクスポート
ENV 環境変数
ADD ファイル/ディレクトリの追加
COPY ファイルのコピー
ENTRYPOINT コンテナの実行コマンド
VOLUME ボリュームのマウント
USER ユーザーの指定
WOEKDIR 作業ディレクトリ
ARG Dockerfile内の変数
ONBUILD ビルド実行後に実行される命令
STOPSSIGNAL システムコールシグナルの設定
HEALTHCHECK コンテナのヘルスチェック
SHELL デフォルトシェルの設定

Dockerfileの作業の流れ

Dockerfileを作成

Dockerfileでは、DockerコンテナをどのDockerイメージから生成するかを必ず書く必要があります。
bash
FROM [イメージ名]
FROM [イメージ名]:[タグ名]
FROM [イメージ名]@[ダイジェスト]

FROM命令は必須です。ダイジェストは、DockerHubにアップロードすると自動で付与される識別子で、ユニーク。

Dockerfileのビルド

docker build -t [生成するイメージ名]:[タグ名] [Dockerfileの場所]

ビルドをして、イメージを作成。
初回実行時は、Dockerレポジトリからベースイメージをダウンロードするため処理に時間がかかる
2回目以降は、すでにイメージがあるため、ダウンロードはしない。

Dockerイメージのレイヤー構造

Dockerfile
# STEP1 Ubuntu
FROM ubuntu:latest
# STEP2 Nginxのインストール
RUN apt-get update && apt-get install -y -q nginx
# STEP3 ファイルのコピー
COPY index.html /usr/share/nginx/html/
# STEP4 Nginxの起動
CMD ["nginx","-g","deamon off;"] 

この例のDockerfileと同じディレクトリに任意の「index.html」という名前のファイルを用意する。
このファイルをbuildすると、命令1行ごとにイメージを生成される。
生成された4つのイメージから共有イメージが作成される。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerfileの書き方を理解して、Dockerfileでnginxを起動させる

Dockerfileとは?

  • ベースになるDockerイメージ
  • Dockerコンテナ内で行った操作(コマンド)
  • 環境変数などの設定
  • Dokcerコンテナ内で動作させておくデーモン実行

などのDocker上で動作させるコンテナの構成情報を記述するためのファイルのことです。

Dockerfileの基本構文

Dockerfileの基本書式

命令 引数

Dockerfileの命令

命令 説明
FROM ベースイメージの指定
RUN コマンド実行
CMD コンテナの実行コマンド
LABEL ラベルを設定
EXPOSE ポートのエクスポート
ENV 環境変数
ADD ファイル/ディレクトリの追加
COPY ファイルのコピー
ENTRYPOINT コンテナの実行コマンド
VOLUME ボリュームのマウント
USER ユーザーの指定
WOEKDIR 作業ディレクトリ
ARG Dockerfile内の変数
ONBUILD ビルド実行後に実行される命令
STOPSSIGNAL システムコールシグナルの設定
HEALTHCHECK コンテナのヘルスチェック
SHELL デフォルトシェルの設定

Dockerfileの作業の流れ

Dockerfileを作成

Dockerfileでは、DockerコンテナをどのDockerイメージから生成するかを必ず書く必要があります。
bash
FROM [イメージ名]
FROM [イメージ名]:[タグ名]
FROM [イメージ名]@[ダイジェスト]

FROM命令は必須です。ダイジェストは、DockerHubにアップロードすると自動で付与される識別子で、ユニーク。

Dockerfileのビルド

docker build -t [生成するイメージ名]:[タグ名] [Dockerfileの場所]

ビルドをして、イメージを作成。
初回実行時は、Dockerレポジトリからベースイメージをダウンロードするため処理に時間がかかる
2回目以降は、すでにイメージがあるため、ダウンロードはしない。

Dockerイメージのレイヤー構造理解して、nginx起動させる

Dockerfile
# STEP1 Ubuntu
FROM ubuntu:latest
# STEP2 Nginxのインストール
RUN apt-get update && apt-get install -y -q nginx
# STEP3 ファイルのコピー
COPY index.html /usr/share/nginx/html/
# STEP4 Nginxの起動
CMD ["nginx","-g","deamon off;"] 

この例のDockerfileと同じディレクトリに任意の「index.html」という名前のファイルを用意する。
このファイルをbuildすると、命令1行ごとにイメージを生成される。
生成された4つのイメージから共有イメージが作成される。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

図解:Docker全体像(状態遷移、コマンド)

はじめに

初めてDockerを触ってみて、ややこしいと感じた、

  • 状態遷移
  • イメージとコンテナ
  • アタッチとデタッチ
  • これらに紐づくコマンド

を1枚の図にまとめてみました。

Docker全体像

DockerStateDiagram.jpg

参考

Lifecycle of Docker Container
Dockerイメージの理解とコンテナのライフサイクル

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(試行錯誤中)DockerからREALSENSE D435iを繋いで、ROS2で表示してみる

やりたいこと

  • RealSense D435iをDockerコンテナで使って表示したい
  • DockerコンテナでD435iをROS2で扱いたい

※現在はこんな感じ。
RealSenseViewerでは表示されますが、ROS2から呼ぶと異常が発生して表示されません。
Screenshot from 2020-05-30 09-15-31.png

前回の記事でDocker環境からGUIをうまく使えるようになったので、USBデバイスも使えるようにしようとしたが、USB機器をつなぐところではまったのでやり方を記録しました。
あと、ROS2側は鋭意デバッグ中。

環境

  • amd64のUbuntu18の入ったノートPC
  • GPUはGTX1660Ti
  • RealSense D435iを使用する

実施

DockerfileにRealSenseのドライバやアプリのセットアップを追加します。
IntelRealSense/librealsense Linux Distribution

Dockerfile
#(前は省略)
# REALSENSEの追加
RUN cd /home/developer
RUN apt-get update && apt-get install -y software-properties-common
RUN sudo apt-key adv --keyserver keys.gnupg.net --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE || sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE
RUN sudo add-apt-repository "deb http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo bionic main" -u
RUN sudo apt-get install -y librealsense2-dkms
RUN sudo apt-get install -y librealsense2-utils
RUN sudo apt-get install -y librealsense2-dev
RUN sudo apt-get install -y librealsense2-dbg
RUN sudo apt-get install -y v4l-utils 

v4l-utilsは動作確認用で追加しました。
ビルドして実行しますが、うまく動きませんでした。
docker runのオプションの方に問題がありそうです。

REALSENSEをホストマシンで確認する

ホストマシンにv4l2-ctlをインストールして、デバイスを確認します。

$ sudo apt install v4l-utils 
$ v4l2-ctl --list-device
Intel(R) RealSense(TM) Depth Ca (usb-0000:00:14.0-2):
    /dev/video2
    /dev/video3
    /dev/video4
    /dev/video5
    /dev/video6
    /dev/video7

Integrated_Webcam_HD: Integrate (usb-0000:00:14.0-5):
    /dev/video0
    /dev/video1

REALSENSEは2〜7に割り当てられています。

REALSENSEをDockerの中から確認する

$ v4l2-ctl --list-device
Failed to open /dev/video0: Permission denied

パーミッションで弾かれます。

$ sudo v4l2-ctl --list-device
Integrated_Webcam_HD: Integrate (usb-0000:00:14.0-5):
    /dev/video0

特権モードでは問題ないようです。

--deviceオプションでビデオデバイスをいちいち登録するよりも、ホストのユーザーとかファイルなどを全部マウントしてしまったほうが、設定が楽そうです。
色々試したところ、こんな形に落ち着きました。

launch.sh
docker run --gpus all -it --rm \
    --privileged \
    --user=$(id -u $USER):$(id -g $USER) \
    --env="DISPLAY" \
    --workdir="/home/$USER" \
    --volume="/home/$USER:/home/$USER" \
    --volume="/etc/group:/etc/group:ro" \
    --volume="/etc/passwd:/etc/passwd:ro" \
    --volume="/etc/shadow:/etc/shadow:ro" \
    --volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
    --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
    -e DISPLAY=$DISPLAY --name glvnd cuda_gui

# 参考
# http://wiki.ros.org/docker/Tutorials/GUI

ros.orgを参考に、ホストの構成を全部突っ込む感じで動かしてみます。

terminal
$ sudo realsense-viewer

sudo つけないと動きませんでした。(この部分は要調査)

Screenshot from 2020-05-30 09-54-10.png

とりあえず、問題なく表示されていますね。
そして、一応使えているけど、汚いDockerfileですね。
一応、ここに載せておきます。

Dockerfile
# GPUとGUIが使えるDockerfileをamd64で動かす

FROM nvidia/cudagl:10.2-base-ubuntu18.04

# これを入れないとtzdataで設定入力を求められて停止する
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -yq wget curl git build-essential vim sudo lsb-release locales bash-completion tzdata

# Replace 1000 with your user / group id
RUN export uid=1000 gid=1000 && \
    mkdir -p /home/developer && \
    echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
    echo "developer:x:${uid}:" >> /etc/group && \
    echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
    chmod 0440 /etc/sudoers.d/developer && \
    chown ${uid}:${gid} -R /home/developer

RUN curl -sSL http://get.gazebosim.org | sh

ENV ROS_DISTRO dashing

# ロケールのセットアップ
RUN apt-get update && apt-get install -y locales && \
    dpkg-reconfigure locales && \
    locale-gen ja_JP ja_JP.UTF-8 && \
    update-locale LC_ALL=ja_JP.UTF-8 LANG=ja_JP.UTF-8
ENV LC_ALL   ja_JP.UTF-8
ENV LANG     ja_JP.UTF-8
ENV LANGUAGE ja_JP.UTF-8

# APTソースリストの設定
RUN apt-get update && \
    apt-get install -y curl gnupg2 lsb-release && \
    curl http://repo.ros2.org/repos.key | apt-key add - && \
    sh -c 'echo "deb [arch=amd64,arm64] http://packages.ros.org/ros2/ubuntu \
    `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list' && \
    apt-get update

# ROS2パッケージのインストール
RUN export ROS_DISTRO=dashing && \
    apt-get install -y ros-$ROS_DISTRO-desktop \
    python3-colcon-common-extensions python3-rosdep python3-argcomplete && \
    rosdep init && \
    rosdep update

# REALSENSEの追加
RUN cd /home/developer
RUN apt-get update && apt-get install -y software-properties-common
RUN sudo apt-key adv --keyserver keys.gnupg.net --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE || sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE
RUN sudo add-apt-repository "deb http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo bionic main" -u
RUN sudo apt-get install -y librealsense2-dkms
RUN sudo apt-get install -y librealsense2-utils
RUN sudo apt-get install -y librealsense2-dev
RUN sudo apt-get install -y librealsense2-dbg
RUN sudo apt-get install -y v4l-utils 

USER developer
ENV HOME /home/developer

## 環境設定
RUN    echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrc

整理が必要です。
適当なタイミングで

ROS2でPointCloudしてみる(試行錯誤中)

こちらを参考にして、セットアップして動かしてみます。
ros2_intel_realsense
https://github.com/intel/ros2_intel_realsense

このissueの方もDockerで動かそうとしています

Dockerfileに書き込んであれこれするまえに、コンテナの中でセットアップしてみます。
※事前にホストPCで sudo usermod -a -G video username (usernameにユーザー名を入力)して、置かないと、ROS2でD435iのパーミッションに引っかかります。

カメラの確認方法。

terminal
$ ls -al /dev/video*
$ v4l2-ctl --list-device

どちらもsudoをつけないと動かないですね。
うまい方法が思いつかなかったので、chmodを使うこととします。

terminal
sudo chmod 777 /dev/video*

うーん、もっとスマートな方法はないものか・・・。

sudo usermod -a -G users "$(whoami)"
sudo usermod -a -G video "$(whoami)"

はどうか?という記事も見ましたが、すでにグループ登録されているはず・・・
※この件は一旦保留。

terminal
$ sudo apt-get install ros-dashing-cv-bridge ros-dashing-librealsense2 ros-dashing-message-filters ros-dashing-image-transport
$ sudo apt-get install -y libssl-dev libusb-1.0-0-dev pkg-config libgtk-3-dev
$ sudo apt-get install -y libglfw3-dev libgl1-mesa-dev libglu1-mesa-dev
$ sudo apt-get install ros-dashing-realsense-camera-msgs ros-dashing-realsense-ros2-camera

$ mkdir -p ~/ros2_ws/src
$ cd ~/ros2_ws/src
$ git clone https://github.com/intel/ros2_intel_realsense.git

$ cd ~/ros2_ws
$ source /opt/ros/dashing/setup.bash
$ colcon build --base-paths src/ros2_intel_realsense

$ source /opt/ros/dashing/setup.bash
$ source ~/ros2_ws/install/local_setup.bash
# To launch with "ros2 run"
$ ros2 run realsense_ros2_camera realsense_ros2_camera
# OR, to invoke the executable directly
$ realsense_ros2_camera

という流れで、セットアップしたのですが、異常が出ます。

terminal
$ ros2 run realsense_ros2_camera realsense_ros2_camera
[INFO] [RealSenseCameraNode]: RealSense ROS v2. 0.1
[INFO] [RealSenseCameraNode]: Running with LibRealSense v2.16.5
[INFO] [RealSenseCameraNode]: getParameters...
[INFO] [RealSenseCameraNode]: setupDevice...
 30/05 06:26:38,998 ERROR [140404533152256] (types.h:180) get_xu(...). xioctl(UVCIOC_CTRL_QUERY) failed Last Error: Device or resource busy
[ERROR] [RealSenseCameraNode]: An exception has been thrown: get_xu(...). xioctl(UVCIOC_CTRL_QUERY) failed Last Error: Device or resource busy
terminate called after throwing an instance of 'rs2::backend_error'
  what():  get_xu(...). xioctl(UVCIOC_CTRL_QUERY) failed Last Error: Device or resource busy

ソースコードを追うと、ここで異常が出ているようです。

realsense_camera_node.cpp
void setupDevice()
(中略 error358行目)

    } catch (const std::exception & ex) {
      RCLCPP_ERROR(logger_, "An exception has been thrown: %s", ex.what());
      throw;
    } catch (...) {
      RCLCPP_ERROR(logger_, "Unknown exception has occured!");
      throw;
    }

なんですかね?RCLCPP_ERROR?
types.h:180を確認したほうが良い?

長くなってきたので、次の記事に続きます。
(試行錯誤中)DockerからREALSENSE D435iを繋いで、ROS2で表示してみるエラーをデバッグする

Dockerファイルを調整したら、加速度計が動かなくなった

Dockerfileの中から、もう意味のなさそうな記述を削除しました。

ホストPCの構成を千部取り込むことにし、不要と判断。

Screenshot from 2020-05-31 08-04-28.png

これで、実行してみると、RealSenseViewerを実行すると、D435iの加速度計だけがPermisson deniedが発生して動きません。

Backend in rs2_open_multiple(sensor:0x7fdba80168a0, profiles:0x7fdba8d76168, count:2):
Failed to open scan_element /sys/devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.5/0003:8086:0B3A.000A/HID-SENSOR-200076.3.auto/
iio:device1/scan_elements/in_anglvel_x_en Last Error: Permission denied

検索すると

権限エラーは不適切にインストールされたことが原因である可能性がありますudev-rules。インストールガイドで指定されているスクリプトを実行しましたか? ./scripts/setup_udev_rules.sh

この現象をなんとかしようとインストールガイドを読んでいたら・・・
Linux Ubuntu Installation

LinuxでRealSenseデプスカメラを実行するには、修正したカーネルドライバーにパッチを適用して挿入する必要があります。

通常のインストールではDockerと相性悪すぎなのか。
・・・とりあえず、加速度計は使わないので、次行ってみよう。
もしかしたら、ROS2で今出ている異常も、加速度計を除外したら動くのかもしれない。

(試行錯誤中)DockerからREALSENSE D435iを繋いで、ROS2で表示してみるエラーをデバッグする

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerからREALSENSE D435iを繋いで、ROS2で表示してみる

やりたいこと

  • RealSense D435iをDockerコンテナで使って表示したい
  • DockerコンテナでD435iをROS2で扱いたい

最終的にこんな感じになりました。
Screenshot from 2020-05-30 09-15-31.png

前回の記事でDocker環境からGUIをうまく使えるようになったので、USBデバイスも使えるようにしようとしたが、USB機器をつなぐところではまったのでやり方を記録しました。

環境

  • amd64のUbuntu18の入ったノートPC
  • GPUはGTX1660Ti
  • RealSense D435iを使用する

実施

DockerfileにRealSenseのドライバやアプリのセットアップを追加します。
IntelRealSense/librealsense Linux Distribution

Dockerfile
#(前は省略)
# REALSENSEの追加
RUN cd /home/developer
RUN apt-get update && apt-get install -y software-properties-common
RUN sudo apt-key adv --keyserver keys.gnupg.net --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE || sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE
RUN sudo add-apt-repository "deb http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo bionic main" -u
RUN sudo apt-get install -y librealsense2-dkms
RUN sudo apt-get install -y librealsense2-utils
RUN sudo apt-get install -y librealsense2-dev
RUN sudo apt-get install -y librealsense2-dbg
RUN sudo apt-get install -y v4l-utils 

v4l-utilsは動作確認用で追加しました。
ビルドして実行しますが、うまく動きませんでした。
docker runのオプションの方に問題がありそうです。

REALSENSEをホストマシンで確認する

ホストマシンにv4l2-ctlをインストールして、デバイスを確認します。

$ sudo apt install v4l-utils 
$ v4l2-ctl --list-device
Intel(R) RealSense(TM) Depth Ca (usb-0000:00:14.0-2):
    /dev/video2
    /dev/video3
    /dev/video4
    /dev/video5
    /dev/video6
    /dev/video7

Integrated_Webcam_HD: Integrate (usb-0000:00:14.0-5):
    /dev/video0
    /dev/video1

REALSENSEは2〜7に割り当てられています。

REALSENSEをDockerの中から確認する

$ v4l2-ctl --list-device
Failed to open /dev/video0: Permission denied

パーミッションで弾かれます。

$ sudo v4l2-ctl --list-device
Integrated_Webcam_HD: Integrate (usb-0000:00:14.0-5):
    /dev/video0

特権モードでは問題ないようです。

--deviceオプションでビデオデバイスをいちいち登録するよりも、ホストのユーザーとかファイルなどを全部マウントしてしまったほうが、設定が楽そうです。
色々試したところ、こんな形に落ち着きました。

launch.sh
docker run --gpus all -it --rm \
    --privileged \
    --user=$(id -u $USER):$(id -g $USER) \
    --env="DISPLAY" \
    --workdir="/home/$USER" \
    --volume="/home/$USER:/home/$USER" \
    --volume="/etc/group:/etc/group:ro" \
    --volume="/etc/passwd:/etc/passwd:ro" \
    --volume="/etc/shadow:/etc/shadow:ro" \
    --volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
    --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
    -e DISPLAY=$DISPLAY --name glvnd cuda_gui

# 参考
# http://wiki.ros.org/docker/Tutorials/GUI

ros.orgを参考に、ホストの構成を全部突っ込む感じで動かしてみます。

terminal
$ sudo realsense-viewer

sudo つけないと動きませんでした。(この部分は要調査)

Screenshot from 2020-05-30 09-54-10.png

とりあえず、問題なく表示されていますね。
そして、一応使えているけど、汚いDockerfileですね。
一応、ここに載せておきます。

Dockerfile
# GPUとGUIが使えるDockerfileをamd64で動かす

FROM nvidia/cudagl:10.2-base-ubuntu18.04

# これを入れないとtzdataで設定入力を求められて停止する
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -yq wget curl git build-essential vim sudo lsb-release locales bash-completion tzdata

# Replace 1000 with your user / group id
RUN export uid=1000 gid=1000 && \
    mkdir -p /home/developer && \
    echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
    echo "developer:x:${uid}:" >> /etc/group && \
    echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
    chmod 0440 /etc/sudoers.d/developer && \
    chown ${uid}:${gid} -R /home/developer

RUN curl -sSL http://get.gazebosim.org | sh

ENV ROS_DISTRO dashing

# ロケールのセットアップ
RUN apt-get update && apt-get install -y locales && \
    dpkg-reconfigure locales && \
    locale-gen ja_JP ja_JP.UTF-8 && \
    update-locale LC_ALL=ja_JP.UTF-8 LANG=ja_JP.UTF-8
ENV LC_ALL   ja_JP.UTF-8
ENV LANG     ja_JP.UTF-8
ENV LANGUAGE ja_JP.UTF-8

# APTソースリストの設定
RUN apt-get update && \
    apt-get install -y curl gnupg2 lsb-release && \
    curl http://repo.ros2.org/repos.key | apt-key add - && \
    sh -c 'echo "deb [arch=amd64,arm64] http://packages.ros.org/ros2/ubuntu \
    `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list' && \
    apt-get update

# ROS2パッケージのインストール
RUN export ROS_DISTRO=dashing && \
    apt-get install -y ros-$ROS_DISTRO-desktop \
    python3-colcon-common-extensions python3-rosdep python3-argcomplete && \
    rosdep init && \
    rosdep update

# REALSENSEの追加
RUN cd /home/developer
RUN apt-get update && apt-get install -y software-properties-common
RUN sudo apt-key adv --keyserver keys.gnupg.net --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE || sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE
RUN sudo add-apt-repository "deb http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo bionic main" -u
RUN sudo apt-get install -y librealsense2-dkms
RUN sudo apt-get install -y librealsense2-utils
RUN sudo apt-get install -y librealsense2-dev
RUN sudo apt-get install -y librealsense2-dbg
RUN sudo apt-get install -y v4l-utils 

USER developer
ENV HOME /home/developer

## 環境設定
RUN    echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrc

整理が必要です。
適当なタイミングで

ROS2でPointCloudしてみる(試行錯誤中)

こちらを参考にして、セットアップして動かしてみます。
ros2_intel_realsense
https://github.com/intel/ros2_intel_realsense

このissueの方もDockerで動かそうとしています

Dockerfileに書き込んであれこれするまえに、コンテナの中でセットアップしてみます。
※事前にホストPCで sudo usermod -a -G video username (usernameにユーザー名を入力)して、置かないと、ROS2でD435iのパーミッションに引っかかります。

カメラの確認方法。

terminal
$ ls -al /dev/video*
$ v4l2-ctl --list-device

どちらもsudoをつけないと動かないですね。
うまい方法が思いつかなかったので、chmodを使うこととします。

terminal
sudo chmod 777 /dev/video*

うーん、もっとスマートな方法はないものか・・・。

terminal
$ sudo apt-get install ros-dashing-cv-bridge ros-dashing-librealsense2 ros-dashing-message-filters ros-dashing-image-transport
$ sudo apt-get install -y libssl-dev libusb-1.0-0-dev pkg-config libgtk-3-dev
$ sudo apt-get install -y libglfw3-dev libgl1-mesa-dev libglu1-mesa-dev
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む