3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ノートパソコンGalleriaを使ってnvidia-dockerサーバもどき作ってみた2019年2月

Posted at

初めての投稿です、こんにちは。サウスブリッジです。
今回は、ノートパソコンでDockerサービスを常時可動させる環境を作ろうとしたら 予想外にハマった のでその記録を残そうと思います。もう落ち着いた頃合いだと思ったんだけどな…

パーティション設定とOSインストール

まさかここから波乱だとは思わなかったんだぜ…

まずはいつもの手順でLinuxを導入します。
今回はUbuntu Desktop 18.04LTS 日本語Remixを使います。
選定理由は「ゆるふわな筆者にも扱いやすいから」その他諸々です。

とりあえずUbuntuを勢いでズバーンっ…ではなくインストール済みのWindowsをどうにかします。
未練がなければバッサリ消してもいいのですが、 なにせあのWindowsです 。気が変わったときにロストしたときの悔しみがスゴそうな方は、回復手段をいくつか用意しておきましょう。私は用意しました。その手順を含めて進めていきます。

まずは取説通りの手順でセットアップし、Microsoftアカウントに紐つけておきます。その後アップデートと再起動を繰り返し、Windowsを最新の状態にします。
次に取説通りの手順で回復ディスクを作成します。16GB以上のUSBメモリが必要だそうです。ナメきって8GBをブッ刺したら怒られました。ナメてました…作成した回復ディスクは取り外してラベルを貼り、近くに置いておきます。

ここからUbuntuを扱い始めます 。Windows上で、Ubuntu Japanese Teamホームページから.isoイメージを、以下に示した参考記事のリンクからUniversal USB Installerをダウンロードします。
(別のUbuntu機で作ったインストールメディアは何故か起動に失敗しました。情報も少ないのでインストールメディアはWindowsで作ることをオススメします。)
Ubuntu 18.04 LTS 日本語 Remix リリース
UbuntuのLive USBをつくる | MKTIAの備忘録
上に示した参考記事の手順に従ってUbuntuインストールメディアを作成します。用意するUSBメモリは4GBで十分です。DVDに入っちゃうからねぇ…

インストールメディアができたら、刺したままWindowsに再起動の指示を出します。ブートはインストールメディアに 切り替わってくれない のでDeleteキーを連打してBIOSに入ります。 Galleriaロゴが出る前 の画面が暗いうちから連打しましょう。
BIOSに入れたら設定をしておきます。ブート順を変更した後、後でつまづくので Secure Bootを切って おきましょう。(入れっぱなしだとGRUBのインストールに失敗します。)

再起動から開けるとUbuntuが試用版で起動しているはずです。ここでシステムディスクと回復ディスクをddでバックアップしておきます。以下の記事を参考にしました。
dd コマンドによるディスクバックアップ・リストアメモ | アプ研
バックアップ先は64GBぐらいの外部ドライブが転がっていればなんとかなりそうですが、私の自宅には転がっていなかったのでたまたま置いてあったSAMBA共有NASを使うことにしました。CIFSでのマウント方法は以下の記事を参考にしました。
LinuxからWindows共有フォルダをマウントする | Kapibara Tech Blog
マウントコマンドは手元の環境に合わせて以下のように少し変更しました。

terminal
$ mkdir /home/tmpBkup
$ sudo mount -t cifs -o username=,password=,vers=1.0 //共有サーバのアドレス/共有ディレクトリ名 /home/tmpBack

匿名利用を許可しているので、usernameとpasswordの指定はするように見せかけてしない状態で十分です。versの指定は1.0でないとエラーが出ました。ウチの設備が骨董品なんですね、トホホ…
あとはddでバックアップ祭りです。まずは$ fdisk -lでシステムディスクと回復ディスクのアタリをつけます。パーティション単位(/dev/sdb1)ではなくドライブ単位(/dev/sdb)のように指定したほうが面倒が無いです。geditあたりにコピペでメモっておきましょう。
バックアップを走らせるコマンドは以下のとおりです。

terminal
$ sudo dd if=/dev/sdb bs=64k | gzip -c > /home/tmpBkup/sdb.ddimg.gz

これでデータの吸い出しから圧縮、NASへの転送まで一気に進みます。CPUのスレッドが暇そうだったので新たに端末を開き、システムディスクと回復ディスク同時バックアップをやらせました。

バックアップが終わったらいよいよパーティション操作です。変な汗が出る作業ですね。ここで残念なお知らせです。WindowsはUEFI環境下にインストールすると 基本パーティションを4つ全部作りやがります 。(参考 : EFI/GPT ベースのハード ドライブ パーティション | Hardware Dev Center) 気が変わったときのためにデュアルブートにしておこうという思いは儚く消え去りました。吹っ切れながら パーティションテーブルごと消し飛ばしてやりましょう
Superキーを押してDashu検索からGpartedを起動し、システムディスクとデータディスクのアタリをつけておきます。まずはシステムディスクでパーティションテーブルを作成します。ディスクごとバックアップ済みなので迷わず消し飛ばせますねっ。GalleriaはUEFI環境なので、Ubuntu 16.04 その43 - UEFIでパーティションが一つもないHDDにUbuntuをインストールしようとすると、インストーラーがフリーズする不具合 | kledgebにならってパーティションを組んでいきます。
パーティションテーブルの種類はgptを選択し、先頭にEFIパーティションを作成します。256MB程度のfat32パーティションを作成し、bootフラグとespフラグを設定します。
残りのエリアは自由に使いましょう。私は48GBをLinux swapに、残りをシステム用のext4パーティションに設定しました。ついでにDドライブ相当のHDDをパーティションテーブルgpt、全領域をext4パーティションとして設定しました。なぜかパーティションの境目に1MBの空きエリアができたりするけど気にしないスタイルで行くんだぜ。

ディスクの準備ができたのでいよいよUbuntuをインストールします。ドライブの利用方法の設定(システム用パーティションを/に、データ用パーティションを/homeに使用し、それぞれフォーマットを行う)以外は何も考えずにスムーズに進みます。インストーラの作業が終わったら、指示通りに再起動すると そのままフリーズします 。(正確にはログアウトに失敗して操作を受け付けなくなります。) 予定調和です 。臆せずSysreq+Bで再起動させましょう。画面が暗くなったタイミングでDeleteキーを連打すればBIOSに入れるので、落ち着いてUSBメモリを引き抜き起動ドライブを変更し、システムを起動します。

入れたてホヤホヤのUbuntuが起動し、初期設定をして欲しそうな画面を出してこちらを伺ってきます。 まだコイツに手を付けてはいけません。完了間際でフリーズしやがります 。早急にnvidiaプロプライエタリドライバをインストールしましょう(openのnvidiaドライバがログアウト不良の原因です。)
SuperキーでDash検索を呼び出し、「Update」と入力して「ソフトウェアの更新」を起動します。隅っこにある設定ボタンを押し、「追加のドライバー」タブを開き「nvidia-driver-???」のラジオボタンに選択を入れます。エラーを吐いてこなければインストールは成功しています。
ついでにホームディレクトリ内の日本語ディレクトリ名を英語表記化しておきましょう。以下の記事を参考にコマンドを叩き、ディレクトリ名を一括変更します。
Ubuntuでホームディレクトリの中身を英語にする | @taiko19xx

terminal
$ LANG=C xdg-user-dirs-gtk-update

ここで一旦システムを再起動しましょう。念の為、
Sysreq+R→Sysreq+S→Sysreq+U→Sysyreq→B
の順でフラッシュメモリへの書き込みを済ませてから再起動します。正規の手順で再起動しようとすると ログアウトのタイミングでフリーズ して操作を受け付けなくなります。勇気を持ってSysreqで叩き斬りましょう。

無事に再起動に成功したら一安心です。ウズウズ待っていた初期設定画面に従って設定を済ませ、Ubuntuの初期設定を完了させましょう。特にLivePatchを適用しておくことを推奨します。再起動したくなくなるマシンですからねっ。

また、Dockerサーバを常時可動させてどこかに仕掛ける予定であれば、モニタ蓋を閉じてサスペンドに入られると大変困ります。ここで設定を変えておきましょう。以下の記事を参考にしました。
モニターを閉じるとサスペンドされるのを防止 | @tukiyo3
設定ファイルの一部を書き換えます。

terminal
$ sudo gedit /etc/systemd/logind.conf

該当行をコメントアウトし、設定値を書き換えて上書きします。

/etc/systemd/logind.conf
- #HandleLidSwitch=suspend
+ HandleLidSwitch=ignore

書き換えたら設定を反映させましょう。

terminal
$ sudo systemctl restart systemd-logind

Dockerの導入

お待たせしました。前座が既にスゴいのですが、 ここからが本番 です。

まずはDocker本体を下記の参考記事と公式ページを見ながらインストールします。
Ubuntuにdockerをインストールする | @tkyonezu
Get Docker CE for Ubuntu | docker docs
ついでにDockerコマンドをsudo無しで叩けるようにしておきましょう。
ユーザをdockerグループに入れる | @tifa2chan

terminal
$ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common

$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu$(lsb_release -cs)stable"
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io

$ sudo groupadd docker
$ sudo usermod -aG docker $USER

次にdocker-composeをインストールします。
Install Docker Compose | docker docs

terminal
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

一旦再起動し、インストールが成功したか確認します。

terminal
$ docker run hello-world
$ docker-compose --version

nvidiaがいらない方はここまでで導入完了です。

ここからnvidia-dockerをインストールしていきますが、 バトルです 。一時期平和になったような気がしてたんですけど、いつの間にか闘いの形相を呈していました。びっくりポンです。
最近はnvidia-docker-runtimeに名を改めたようですね。公式の手順に沿って操作を進めましょう。
Repository configuration | nvidia-container-runtime

terminal
$ curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey |   sudo apt-key add -
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list |   sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
$ sudo apt update

$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo gedit /etc/systemd/system/docker.service.d/override.conf
/etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --host=fd:// --add-runtime=nvidia=/usr/bin/nvidia-container-runtime
terminal
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

$ sudo gedit /etc/docker/daemon.json
/etc/docker/daemon.json
{
    "default-runtime": "nvidia"
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}
terminal
$ sudo pkill -SIGHUP dockerd

コレで適当なnvidia-dockerコンテナを探して立ち上げ、

terminal
$ docker exec -it 適当なコンテナの名前 /bin/bash
コンテナの中# nvidia-smi

で搭載されているnvidiaチップが認識されていればインストール成功です!

リバースプロキシの導入

ここまででnvidia-dockerでグリグリ遊ぶ環境はできましたが、人は欲望の塊ゆえ「自作サービスを立ち上げてLAN内で使えるようにしたい」とか思ってしまうものです。私は思ってしまいました。ていうかポートフォワードの管理がカオスになるのが割としんどい…
そこでここからは「自作サービス作ったらDockerサーバでdocker-compose up -dするだけでLAN内からサブドメインでアクセスできる」とかいうステキ環境を作っていきましょう。
( この記事をメッチャ参考にしました。
複数のWebアプリを1サーバーのDockerを使ってSSL対応のサブドメインで簡単に運用する | QUARTETCOM TECH BLOG )

まずはLAN内からdockerサーバへアクセスできるようにしていきます。dnsmasqをインストールしてDHCP+DNSサーバとして働かせます。私は既にDHCP用にRaspberry Pi上でdnsmasqを動かしていましたが、今から始めるのであれば先程完成したDockerサーバで動かすのも良いかと思います。
※手製DNSサーバが落ちると家中のインターネット接続がコケます。管理とメンテをしっかり行いましょう!

以下の記事を参考にしながらdnsmasqのインストールと設定を進めていきます。
Raspberry pi を DHCP + DNS サーバーにしたい | 子育てしながらエンジニアしたい
dnsmasqをインストールし、追加設定ファイルを読み込む設定にします。

terminal
$ sudo apt install dnsmasq
$ sudo gedit /etc/dnsmasq.conf

設定ファイル内該当行のコメントアウトを外します。

/etc/dnsmasq.conf
# Include another lot of configuration options.
- #conf-file=/etc/dnsmasq.more.conf
+ conf-file=/etc/dnsmasq.more.conf

追加設定ファイルを新規作成して中身を作っていきます。

terminal
$ sudo gedit /etc/dnsmasq.more.conf
/etc/dnsmasq.more.conf
domain-needed
bogus-priv

# ノリで決めたドメイン名を書いておく。
# 後ろをjpにしないと何故か後工程がうまく行かなかったのは何故なんだぜ。
local = /mynet.jp/
domain = mynet.jp
expand-hosts

# 自宅のLANは192.168.3.n/24で回してます。
# dhcp-range = DHCP割当範囲、サブネットマスク、貸出時間の設定
# のフォーマットで書きます。
# プロバイダ貸出ルータのDHCP機能は割当範囲
# 192.168.3.1~192.168.3.1とかにして封印しておきましょう。
dhcp-range = 192.168.3.10, 192.168.3.200, 255.255.255.0, 6h

# DHCPクライアントに通知するルータのアドレスはプロバイダ貸出ルータにしておきます。
dhcp-option = option:router, 192.168.3.1
# DHCPクライアントに通知するDNSサーバのアドレスは後述する自分のアドレスにします。
dhcp-option = option:dns-server, 192.168.3.5
# NTPサーバもここで指定するようなのでプロバイダ貸出ルータを指定しておきます
dhcp-option = option:ntp-server, 192.168.3.1

# DHCPサーバで固定貸出したい機器を登録します。もちろん自分もリストに入れておきます。
# dhcp-host = MACアドレス, 割り当てたいIPアドレス, ノリでつけるホスト名
# のフォーマットで書き連ねていきます。
dhcp-host = ho:ge:hu:ga:pi:yo, 192.168.3.5, docker-server

ここまででDHCPサーバとしては動くのですが、肝心のDNSサーバとしての動きがイマイチになるので別のファイルも書き換えておきます。

terminal
$ sudo gedit /etc/hosts
/etc/hosts
127.0.0.1	localhost
::1		localhost ip6-localhost ip6-loopback
ff02::1		ip6-allnodes
ff02::2		ip6-allrouters

# DNSサーバとしてこの名前を通知します。
127.0.1.1	docker-server

# ここから下は名前解決したいホストをリストしていきます。
# IPアドレス  名前解決したいオレオレドメイン付きアドレス  ホスト名
# のフォーマットでリストしていきます。
# とりあえず自分をリストに入れておきましょう
192.168.3.5  docker-server.mynet.jp  docker-server

ここまで設定できたらdnsmasqを再起動し、設定を反映させます。

terminal
$ sudo systemctl dnsmasq restart

ただ、IPアドレスの取り直しは勝手にやってくれないようなのでマシンごと再起動してもいいかもしれません…

DNSがうまく動いたら、リバースプロキシをDocker上に立ち上げます。jwilder/nginx-proxyというDockerイメージが ドチャクソ便利 なので早速使っていきます。
/homeディレクトリに適当な名前のディレクトリを作り、その中にリバースプロキシ用のdocker-compose.ymlを書いていきます。

/home/user/docker-service/service-proxy/docker-compose.yml
# ~/service-proxy/docker-compose.yml
version: '2.3'
services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./certs:/etc/nginx/certs:ro
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
    restart: always
  letsencrypt-nginx-proxy-companion:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-letsencrypt
    volumes:
      - ./certs:/etc/nginx/certs
      - /var/run/docker.sock:/var/run/docker.sock:ro
    volumes_from:
      - nginx-proxy
    restart: always

networks:
  default:
    name: service_net

これでdocker-compose up -dするとリバースプロキシが立ち上がり、Dockerネットワークservice_netが作られます。ここに自作サービスコンテナ群を吊るすと自動で見つけてアクセスを振り分けてくれるというギミックです。スゲェッ

お試しでTaiga.ioを動かしてみる

ものは試しで何かWebサービス的なものを乗っけてみましょう。ここは適当にアジャイルツールのTaigaを置いてみます。割とメンテナンスが続いてるDockerイメージが以下になるので、参考にしながら置いてみます。
GitHub - benhutchins/docker-taiga: Docker container for Taiga https://taiga.io
セットアップ方法は以下の記事を左脳にしました。
taigaでgsuiteのsmtpリレーを利用しようとしてはまった(未解決) | @obilixilido

まず/home/user以下の適当な場所でリポジトリをcloneします。

terminal
git clone https://github.com/benhutchins/docker-taiga-example.git mytaiga && cd mytaiga

設定ファイル2つと、docker-compose.ymlを編集、作成します。

./conf/taiga/local.py
# If you want to modify this file, I recommend check out docker-taiga-example
# https://github.com/benhutchins/docker-taiga-example
#
# Please modify this file as needed, see the local.py.example for details:
# https://github.com/taigaio/taiga-back/blob/master/settings/local.py.example
#
# Importing docker provides common settings, see:
# https://github.com/benhutchins/docker-taiga/blob/master/docker-settings.py
# https://github.com/taigaio/taiga-back/blob/master/settings/common.py

from .docker import *

# とりあえず一見様もアクセスできるようになります。
PUBLIC_REGISTER_ENABLED = True
# DEBUG = Trueにしておくとdocker-compose up(-d無し)で標準出力にログがデロデロ出てくるようになります。
DEBUG = True
TEMPLATE_DEBUG = False
./conf/taiga/conf.json
{
    "api": "http://taiga.docker-server.mynet.jp/api/v1/", # サブドメインをノリで決めて書いておきます
    "eventsUrl": null,
    "eventsMaxMissedHeartbeats": 5,
    "eventsHeartbeatIntervalTime": 60000,
    "eventsReconnectTryInterval": 10000,
    "debug": true,
    "debugInfo": true,
    "defaultLanguage": "ja",
    "themes": ["taiga"],
    "defaultTheme": "taiga",
    "publicRegisterEnabled": true,
    "gravatar": false,
    "feedbackEnabled": false,
    "privacyPolicyUrl": null,
    "termsOfServiceUrl": null,
    "maxUploadFileSize": null,
    "contribPlugins": []
}

docker-compose.ymlはgit cloneで出来たディレクトリの直下に配置します。

./docker-compose.yml
version: '2.3'

services:
  taiga:
    image: benhutchins/taiga
    # リバースプロキシが良きに計らってくれるのでポートフォワードを切っておきます。
    #ports:
      # - 80:80
      # - 443:443 # To enable SSL, uncomment this line
    depends_on:
      - postgres
    volumes:
      # I recommend specifying a volume that maps to taiga's media,
      # this way uploaded files are not lost during upgrades of the taiga image
      - ./media:/usr/src/taiga-back/media

      # If you'd like to store the configuration outside of the container,
      # uncomment this volume. This allows for easy changes to the configuration.
      - ./conf/taiga:/taiga

      #- ./ssl.crt:/etc/nginx/ssl/ssl.crt:ro # To enable SSL, uncomment this line
      #- ./ssl.key:/etc/nginx/ssl/ssl.key:ro # To enable SSL, uncomment this line
    environment:
      # 適当に決めたサブドメイン入りホスト名を入れておきます。
      # Your hostname (REQUIRED)
      TAIGA_HOSTNAME: taiga.docker-server.mynet.jp

      # Database settings
      # To use an external database, simply update these and remove the postgres
      # service from this docker-compose.yml file
      TAIGA_DB_NAME: taigadb
      TAIGA_DB_HOST: postgres
      TAIGA_DB_USER: postgres
      TAIGA_DB_PASSWORD: password
      TAIGA_SLEEP: 15 # when the db comes up from docker, it is usually too quick

      # SSL対応は…諦めた…
      TAIGA_SSL: "false" # To enable SSL, uncomment this line
      TAIGA_SSL_BY_REVERSE_PROXY: "false" # To enable SSL, handling by a reverse proxy, uncomment this

      # メールを送れないとユーザを作れません。捨て垢を作って設定しておきましょう
      # gmail側で「安全性の低いアクセス」を有効化しておかないとメール送信できないようです…
      # To use an external SMTP for emails, fill in these values:
      TAIGA_ENABLE_EMAIL: "True"
      TAIGA_EMAIL_FROM: no-reply@taiga.docker-server.mynet.jp
      TAIGA_EMAIL_USE_TLS: "True"
      TAIGA_EMAIL_HOST: smtp.gmail.com
      TAIGA_EMAIL_PORT: 587
      TAIGA_EMAIL_USER: dummy.account@gmail.com
      TAIGA_EMAIL_PASS: hogehogepiyopiyo

      # ※ここが大事!
      # リバースプロキシは環境変数VIRTUAL_HOSTを設定したコンテナを探して設定してくれます。
      # ノリで決めたサブドメインを含めたフルパスを書いておきましょう。
      # nginx reverse proxy
      VIRTUAL_HOST: taiga.docker-server.mynet.jp
      LETSENCRYPT_HOST: taiga.docker-server.mynet.jp
      LETSENCRYPT_EMAIL: your@email.com

    restart: always

  postgres:
    image: postgres
    environment:
      POSTGRES_DB: taigadb
      POSTGRES_PASSWORD: password
      POSTGRES_USER: postgres
    ports:
      - 5432
    volumes:
      # this helps prevent your postgres data from deleted
      - ./pgdata:/var/lib/postgresql/data

    restart: always

# ここも大事!
# リバースプロキシと同じネットワークにぶら下げましょう。設定は以下のとおりです。
networks:
  default:
    external: true
    name: service_net

ノリで決めたサブドメインを含めたフルパスは、dnsmasqにも登録しておきます。

/etc/hosts
# IPアドレスは親亀のアドレスを指定しておきます。
192.168.3.5  docker-server.mynet.jp  docker-server
+ 192.168.3.5  taiga.docker-server.mynet.jp  taiga

ここまで設定できたらdnsmasqを再起動し、設定を反映させます。

terminal
$ sudo systemctl dnsmasq restart

さぁ、docker-compose up -dしてサービスを立ち上げ、お好みのブラウザでhttp://taiga.docker-server.mynet.jp/にアクセスしてみましょう。リバースプロキシが自動でアクセスを振ってくれて、サービスにアクセスできるハズです。


うまくアクセスできた方、 おめでとうございます!お疲れさまです! これで、

  • nvidiaを使える docker環境
  • マシンに簡単アクセスできる DNS環境
  • 自作サービスを簡単に設置できるリバースプロキシ
  • ついでに俺得プロジェクトを無尽蔵に管理できる アジャイルツール

がゴッソリ手に入りました。
作ったインフラを活かして、面白いサービスをジャンジャン作って動かしましょう!

それでは、楽しいDockerライフを!

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?