Help us understand the problem. What is going on with this article?

RaspberryPiにDockerを構築する

RaspberryPi上にDockerを走らせて、実際にミニサーバー代わりに使っている様子をネットに公開している人が少ないと思ったので記録に。あと今までどうやって設定を行ったかを記録代わりに。ラズパイの初期設定とかは何番煎じか分からないけど。

対象機種

  • Raspberry pi 3 B+
  • Raspberry pi 4 B (4GB RAM)

初期設定

Raspberry PiにRaspbianをインストールする for Mac OSX

OSをSDカードに書き込む

  • SDカードを挿して、カードの場所を調べる。/dev/disk2だった。
$ diskutil list
  • SDカードをアンマウントする。
$ sudo diskutil unmountDisk /dev/disk2
  • /dev/disk2にraspbianを書き込む。書き込む場所を間違えると最悪パソコンのデータを完全消去することになる。
$ sudo dd bs=1m if=/your/directory/2019-09-26-raspbian-buster.img of=/dev/disk2

無線LAN設定

ここからは、raspberry piを直接ディスプレイに表示して操作。

  • iwlistで、Wi-FiのSSIDを調べる
$ sudo iwlist wlan0 scan | grep ESSID
  • /etc/wpa_supplicant/wpa_supplicant.confにWi-Fi設定を記述する。
    • 国設定は必須(country=JP)。
    • Wi-Fiパスワードが平文なのが気持ち悪ければ、sudo wpa_passphrase "SSID" "pass" | sudo tee -a /etc/wpa_supplicant/wpa_supplicant.confと暗号化されたパスワードを書き加えて、平文は消す。
$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP
network={
   ssid="Free001"
   psk="password"
   key_mgmt=WPA-PSK
}
  • ラズパイを再起動。ip aでWi-Fiに接続しているかを確認。wlan0inet 192.168.nn.nnとipアドレスが書かれていれば接続に成功している。
$ ip a
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.nn.nn/24 brd 192.168.0.255 scope global noprefixroute wlan0
       valid_lft forever preferred_lft forever

参考サイト

ssh有効化

sudo raspi-configraspi-configを起動。5 Interface Options > P2 SSH を選択してSSHを有効化する。

ssh pi@192.168.nn.nn等で接続できるか確認。これ以降はリモートでラズパイを操作可能。

固定IP設定

ラズパイのIPアドレスをいちいち調べるのは面倒なので、固定IPを割り振る。dhcpcd.confに以下を追記する。

$ sudo nano /etc/dhcpcd.conf
/etc/dhcpcd.conf
interface wlan0
static ip_address=192.168.xx.xxx/24
static routers=192.168.xx.x
static domain_name_servers=192.168.xx.x 8.8.8.8 8.8.4.4

参考リンク

パッケージの更新

パッケージの更新。とりあえず以下のコマンドを実行する。

$ sudo rpi-update #ファームウェアとOSのカーネルをバージョンアップ
$ sudo reboot #再起動
$ sudo apt update #OSのパッケージを管理しているリストを更新
$ sudo apt full-upgrade #パッケージの更新
$ sudo apt-get autoremove -y 
$ sudo apt-get autoclean #SDカードの空き容量を確保する為、不要ファイルを削除
$ sudo reboot #再起動

参考リンク

ラズパイにSSH接続(鍵認証)

sshのログイン方法を公開鍵認証にする。

  • ssh接続元で鍵生成をする
ssh-keygen -t rsa
  • 一旦、ラズパイ(ssh接続先)にssh接続した後。ホームディレクトリ(~/)で隠しディレクトリ.ssh等々の作成を行う。
# ログイン
$ ssh hoge_user@hogehoge.hoge.com
# フォルダとファイルを作る(既に存在している場合は実行しなくても可)
$ mkdir .ssh
$ touch .ssh/authorized_keys
  • 公開鍵(デフォルトだとid_rsa.pub)を転送。
$ scp ~/.ssh/id_rsa.pub pi@192.168.nnn.nnn:~/.ssh
  • 権限設定。公開鍵をauthorized_keysに登録。
# 権限の設定。個々を間違えると、公開鍵認証でログイン出来ないので注意
$ sudo chmod 700 .ssh
$ cat id_rsa.pub >> .ssh/authorized_keys # 公開鍵の内容を追加。
$ sudo chmod 600 .ssh/authorized_keys 
$ rm id_rsa.pub # SCPした公開鍵を削除削除
  • /etc/ssh/sshd_configを変更してsshの各種設定を行う。以下の各種設定は万が一攻撃者がきても簡単に侵入させないようにするため。
/etc/ssh/sshd_config
# port番号設定
Port nnnnn

# rootログインの禁止
PermitRootLogin no

# 鍵認証を有効化
PubkeyAuthentication yes

# パスワード認証を無効化
PasswordAuthentication no
  • sshサーバーを再起動
$ sudo /etc/init.d/ssh restart
  • 接続の確認
$ ssh -i .ssh/[非公開鍵] -p [port番号] pi@nnn.nnn.nnn.nnn

参考サイト

Pi user-change or create new

新しいユーザーを作成してデフォルトのpiユーザーを無効化する。これもセキュリティ対策で攻撃者にユーザー名を推測しにくくするため。

  • 新しいユーザーを作成
$ sudo adduser newusername #新しいユーザーを作成
  • 新しいユーザーにpiと同じグループに所属させる
$ sudo usermod -a -G adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,spi,i2c,gpio newusername #新しいユーザーにpiと同じグループに所属させる
  • 新規作成したユーザーにログイン
  • piユーザーを無効化する
$ sudo usermod -L -s /bin/false -e 1 pi #piユーザーを無効化する

上のコマンドはなんだかやりすぎな気がするので、以下でもアカウントをロック可能

$ sudo passwd --lock pi

ファイアウォール設定

ファイアウォールを設定するのが楽なufwでファイアウォールを設定。

$ sudo apt-get install ufw  # ufwのインストール
$ sudo ufw allow 99  # ポートの開放
$ sudo ufw default deny  # 許可されたポート以外を閉じる
$ sudo ufw enable  # ufwの有効化

もう少し細かく設定したい場合はiptablesが難しいためufwでWEBサーバーのファイアウォール設定を参照。

SDカードの寿命を延ばす

連続稼働が前提にするので、なるべくSDカードが壊れにくい設定にする。
Raspberry PiのSDカードが壊れた!寿命を延ばす方法 5+1選!を参考に。

スワップを無効にする

スワップ領域を確認。

$ free -h
              total        used        free      shared  buff/cache   available
Mem:          3.8Gi       170Mi       3.1Gi        46Mi       521Mi       3.5Gi
Swap:          99Mi          0B        99M

スワップ設定を切る。

$ sudo swapoff --all

ラズパイのスワップファイルはdphys-swapfileを使っていて自動起動されているので、それも切る。

$ sudo systemctl stop dphys-swapfile #停止
$ sudo systemctl disable dphys-swapfile #自動起動停止
$ systemctl status dphys-swapfile #停止されたか確認

 dphys-swapfile.service - dphys-swapfile - set up, mount/unmount, and delete a 
   Loaded: loaded (/lib/systemd/system/dphys-swapfile.service; disabled; vendor 
   Active: inactive (dead)

不要パッケージの削除

SDカードの寿命とは関係ないけれど、不要なパッケージを消す

$ sudo apt-get autoremove -y python-pygame #ゲーム作らないので
$ sudo apt-get autoremove -y galculator #GUI計算機も消す
$ sudo apt-get remove --purge libreoffice* #Libre Officeを消す
$ sudo apt-get clean
$ sudo apt-get autoremove

Raspberry Piにdockerとdocker-composeを導入

以下のコマンドで簡単にdockerをインストール。

$ curl -sSL https://get.docker.com | sh

pipを使えば簡単にdocker-composeをインストールできる。

$ sudo pip3 install docker-compose

パスが通っていない場合があるので、必要ならパスを通す。.bashrcに以下を追記。source .bashrcで設定を反映。再起動してもパスが通っているか確認する。

.bashrc
export PATH="$PATH:~/.local/bin"

Docker buildx

ラズパイはARMなので、世の中を支配しているインテルのx_86とは違うCPUアーキテクチャー。よって、ほとんどのパソコンのDockerイメージとラズパイのDockerイメージに互換性がない。

Docker公式イメージ以外のほとんどのイメージはx_86ベースなので、一からラズパイでARMアーキテクチャーのイメージを構築する必要性が出てくる。ラズパイでいちから構築するよりはx_86のパソコン/サーバーでARM版のイメージを作ってから、イメージをラズパイに転送する方が効率が良い。DockerHubが使えない時点でDockerの利点が半減している点は目をつむってください。buildxで構築する方法を記す予定でしたが、ココで力尽きたのでリンク先をみてください(他力本願)。

軽いdockerイメージならraspberry pi上でdocker-compose buildとビルドするのも一つの手。公式DockerイメージならばARMアーキテクチャーのイメージがあるので、簡単な環境なら公式イメージを基に構築すればよい。ほぼゼロから構築するのでやっぱりDockerの恩恵にあずかれない。やり方はおまけ:状態監視を参照。

結論

データ収集環境をラズパイに移行。Raspberry Pi買って拡張していくよりもミニデスクトップPC買った方が安いんじゃないのかと思わなくもないけれど、足りない周辺機器とか諸々含めると3,4万円

  • t2.microで動かして10時間かかっていたスクレイピング作業が、6時間に短縮
  • 最初は1000円/月で動いていたデータ収集環境も収集データが増えることで収集時間が長くなり2000円/月に。この金額はEC2無料枠を使い切ったうえでの値段なので、無料枠がなくなったときの値段が怖い。

おまけ:状態監視

ラズパイの温度を調べる

ラズパイの温度とか知りたい場合は以下のコマンド(RaspberryPi(Raspbian)のCPUの温度をcatを使わないで取得してみた)

$ vcgencmd measure_temp

Netdata

Raspberrypi 4BはCPU温度が気になってしまいますが、いちいちコマンド打つのも面倒なのでNetdataでラズパイをモニターする。Tecnativa/docker-socket-proxyAMDでビルドされていないので、ラズパイでbuildする必要がある。手順としては

  1. githubのレポジトリをクローン。
  2. クローンしたディレクトリからDockerfilehaproxy.cfgを取り出して、docker-compose.ymlと同一ディレクトリに配置。
  3. docker-compose.ymlを置いてあるディレクトリに移動してdocker-compose buildを実行。
docker-compose.yml
version: '3'
services:
  netdata:
    image: netdata/netdata
    ports:
      - 19999:19999
    cap_add:
      - SYS_PTRACE
    security_opt:
      - apparmor:unconfined
    volumes:
      - /etc/passwd:/host/etc/passwd:ro
      - /etc/group:/host/etc/group:ro
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
    environment:
      - DOCKER_HOST=proxy:2375
  proxy:
    build:
      context: ./
      dockerfile: Dockerfile
    restart: always
    volumes:
     - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - CONTAINERS=1

温度を取得するのであれば有志が作ってくれたDockerイメージを使う。

あるいは/usr/lib/netdata/conf.d/charts.d.confの設定ファイルで# sensors=forceとコメントアウトされているのをsensors=forceとコメントを外せばCPU温度が有効化される。

おまけ:PiJuice

24時間稼働前提のミニサーバーとして使うので、UPSとしてPiJuiceを購入。

PiJuiceをRaspberryPiにさす前に、PiJuice-guiをインストール(詳しいドキュメントはPiSupply/PiJuiceREADME)。

Note: 'pijuice_cli' must be run as user Pi

READMEを読むとpiユーザーが存在することが前提なので、piユーザーを無効にした場合はapt-get install pijuice-guiでうまくいかない場合がある。その時はマニュアルインストールをする(以下の手順ではマニュアルインストールはcliまでしかインストールしていない)。

インストール

$ sudo apt-get install pijuice-gui

マニュアルインストール

$ sudo apt-get install python3-urwid

gitレポジトリから最新の debファイルをダウンロードして、インストール。

$ wget https://github.com/PiSupply/PiJuice/raw/master/Software/Install/pijuice-base_1.5_all.deb
$ sudo dpkg -i ./pijuice-base_1.5_all.deb

PiJuiceRaspberry Pi 4を使う場合はpijuice_cliのステータスが起動しない(関連イシュー)。/boot/config.txtに以下の一文を追加する。

/boot/config.txt
dtoverlay=i2c-bcm2708
k_ken
掲載内容は私個人の見解であり、所属組織を代表するものではありません。
fujitsu
富士通グループのソフトウェア技術者有志により運営しているコミュニティです。
http://www.fujitsu.com/jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away