LoginSignup
2
4

More than 3 years have passed since last update.

YoctoLinuxで64bit RaspberryPi環境を構築し、k3sを使用する(1)

Last updated at Posted at 2020-04-12

RaspberryPi 3B+を持っているので、k3s環境をつくってみようと思い立ち、いろいろ調べたのですが以下の理由でOS自体をYoctoで作成してみました。

  • raspbianは32bitOSだった。
  • ubuntuは64bit版が存在するが、USBからうまく起動出来なかった。
  • ArchLinuxは起動イメージ作成手順が面倒に思えた。

長くなったので(1)~(3)に分けていますが、k3s環境の構築は(2)までで終了します。
(3)はソフトウェアをパッケージ管理でソフトウェアを追加する方法になります。

OS作成

Yocto環境準備

  1. ビルド環境(docker image)
    Yoctoのビルド環境は公式マニュアル参照

    私は、使用しているNASにdockerが搭載されているので、これを使用してビルドする環境を作成した。

    1. Dockerfile

      Dockerfile
      FROM ubuntu:18.04
      ENV DEBIAN_FRONTEND noninteractive
      RUN apt-get update && apt-get dist-upgrade -y && apt-get autoremove --purge -y \
      && apt-get install -y \
      gawk wget git-core diffstat unzip texinfo gcc-multilib \
      build-essential chrpath socat cpio python python3 python3-pip python3-pexpect \
      xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \
      tmux locales libtinfo-dev libncurses5-dev \
      && rm -rf /var/lib/apt/lists/*
      # Locales
      RUN dpkg-reconfigure locales \
      && locale-gen en_US.UTF-8 \
      && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
      ENV LC_ALL   en_US.UTF-8
      ENV LANG     en_US.UTF-8
      ENV LANGUAGE en_US.UTF-8
      
    2. docker image 作成

      $ docker build [ -t {イメージ名} [ :{タグ名} ] ] {Dockerfileのあるディレクトリ}
      $ docker build -t yocto_build:001 .
      
    3. docker image 起動

      $ docker run -it -u $(id -u):$(id -g) -v /home:/home -w /home yoctobuild:${TAG} /bin/bash
      

      -vオプションは、ホストの/homeをdocker image上の/homeにマウントしてる。
      -wオプションは、起動時のカレントディレクトリを指定。

      これらオプションで作業ディレクトリをホストと共有し、docker image終了時にファイルが破棄されない様にしている。

  2. ソース取得

    適当なディレクトリに移動して以下コマンドで取得

    $ git clone https://git.yoctoproject.org/git/poky -b zeus
    $ git clone https://git.yoctoproject.org/git/meta-raspberrypi -b zeus
    $ git clone https://github.com/openembedded/meta-openembedded.git -b zeus
    

YoctoLinux作成

環境変数・カレントディレクトリ設定

  1. oe-init-build-env

    pokyディレクトリ配下のoe-init-build-envを設定ファイルに使用。

    引数に設定した文字列がカレントディレクトリになる。

    例)

    $ cd poky
    $ source oe-init-build-env raspberrypi
    $ pwd
    ~/poky/raspberrypi
    

設定変更

  1. 基本設定・ソフトウェア

    conf/local.confを修正

    1. 機種設定

      以下を記載

      MACHINE ?= "raspberrypi3-64"
      
    2. initのsystemd化

      以下を追記

      DISTRO_FEATURES_append = " systemd pam"
      VIRTUAL-RUNTIME_init_manager = "systemd"
      VIRTUAL-RUNTIME_dev_manager = "systemd"
      DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
      VIRTUAL-RUNTIME_initscripts = ""
      IMX_DEFAULT_DISTRO_FEATURES_append = " systemd"
      
    3. wifi bluetooth

      wifiとbluetoothを使ウカもしれないので機能FWを追加しておく

      COMBINED_FEATURES_append = " wifi bluetooth"
      DISTRO_FEATURES_append = " bluez5"
      
    4. 出力ファイルサイズの指定

      2GB SDカードに書き込めるサイズを指定

      IMAGE_ROOTFS_SIZE = "1787436"
      IMAGE_OVERHEAD_FACTOR = "1.0"
      
    5. ホストネーム設定

      hostname_pn-base-files = "yoctopi3"
      
    6. ユーザーの追加・変更

      piユーザーを追加、パスワードとsudoサブグループを追加しシェルをbashに変更。

      rootユーザーにパスワード追加とログイン禁止設定。

      INHERIT_append = " extrausers"
      EXTRA_USERS_PARAMS = " \
          useradd -P raspberry -G sudo -s /bin/bash pi; \
          usermod -P rootuser -s /sbin/nologin root; \
      "
      
    7. タイムゾーン

      タイムゾーン設定で日本を指定

      IMAGE_INSTALL_append = " tzdata"
      DEFAULT_TIMEZONE = "Asia/Tokyo"
      
    8. 追加設定

      rootユーザーのホームディレクトリを指定

      ROOT_HOME = "/root"
      

      cmdline.txt の内容を編集

      ルート領域をSDからUSBに変更(USBストレージからのbootを可能にする)

      CMDLINE_remove = " root=/dev/mmcblk0p2"
      CMDLINE_append = " root=/dev/sda2"
      

      この設定を無効にすると、SDカード用のイメージになる。

      cgroup機能有効化

      CMDLINE_append = " cgroup_enable=memory cgroup_memory=1"
      

      GPUメモリを16MBに変更

      GPU_MEM = "16"
      

      I2CとSPIを有効化

      ENABLE_I2C = "1"
      ENABLE_SPI_BUS = "1"
      
    9. キャッシュ類のディレクトリ変更

      DL_DIR ?= "/home/ragnadragon/yocto_zeus/download"
      SSTATE_DIR ?= "/home/ragnadragon/yocto_zeus/sstate"
      
    10. 追加ソフト

      IMAGE_FEATURES_append = " package-management"
      IMAGE_FEATURES_append = " ssh-server-openssh"
      IMAGE_FEATURES_append = " nfs-client nfs-server"
      
      IMAGE_INSTALL_append = " bash sudo"
      IMAGE_INSTALL_append = " openssh openssh-sftp-server"
      IMAGE_INSTALL_append = " acpid acpitool"
      IMAGE_INSTALL_append = " vim vim-tiny"
      IMAGE_INSTALL_append = " avahi-daemon"
      IMAGE_INSTALL_append = " util-linux usbutils"
      IMAGE_INSTALL_append = " net-tools iproute2"
      IMAGE_INSTALL_append = " wget curl python3-pip"
      IMAGE_INSTALL_append = " i2c-tools python-smbus bridge-utils hostapd"
      IMAGE_INSTALL_append = " linux-firmware-rpidistro-bcm43455 wpa-supplicant bluez5"
      
    11. コメント無し全体

      local.conf
      MACHINE ?= "raspberrypi3-64"
      MACHINE ??= "qemux86"
      DISTRO_FEATURES_append = " systemd pam"
      VIRTUAL-RUNTIME_init_manager = "systemd"
      VIRTUAL-RUNTIME_dev_manager = "systemd"
      DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
      VIRTUAL-RUNTIME_initscripts = ""
      IMX_DEFAULT_DISTRO_FEATURES_append = " systemd"
      COMBINED_FEATURES_append = " wifi bluetooth"
      DISTRO_FEATURES_append = " bluez5"
      IMAGE_ROOTFS_SIZE = "1807436"
      IMAGE_OVERHEAD_FACTOR = "1.0"
      hostname_pn-base-files = "yoctopi3"
      INHERIT_append = " extrausers"
      EXTRA_USERS_PARAMS = " \
          useradd -P raspberry -G sudo -s /bin/bash pi; \
          usermod -P rootuser -s /sbin/nologin root; \
      "
      IMAGE_INSTALL_append = " tzdata"
      DEFAULT_TIMEZONE = "Asia/Tokyo"
      ROOT_HOME = "/root"
      CMDLINE_remove = "root=/dev/mmcblk0p2"
      CMDLINE_append = "root=/dev/sda2"
      CMDLINE_append = " cgroup_enable=memory cgroup_memory=1"
      GPU_MEM = "16"
      ENABLE_I2C = "1"
      ENABLE_SPI_BUS = "1"
      DL_DIR ?= "~/download"
      SSTATE_DIR ?= "~/sstate"
      DISTRO ?= "poky"
      PACKAGE_CLASSES ?= "package_rpm"
      EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
      USER_CLASSES ?= "buildstats image-mklibs image-prelink"
      PATCHRESOLVE = "noop"
      BB_DISKMON_DIRS ??= "\
          STOPTASKS,${TMPDIR},1G,100K \
          STOPTASKS,${DL_DIR},1G,100K \
          STOPTASKS,${SSTATE_DIR},1G,100K \
          STOPTASKS,/tmp,100M,100K \
          ABORT,${TMPDIR},100M,1K \
          ABORT,${DL_DIR},100M,1K \
          ABORT,${SSTATE_DIR},100M,1K \
          ABORT,/tmp,10M,1K"
      PACKAGECONFIG_append_pn-qemu-system-native = " sdl"
      CONF_VERSION = "1"
      IMAGE_FEATURES_append = " package-management"
      IMAGE_FEATURES_append = " ssh-server-openssh"
      IMAGE_FEATURES_append = " nfs-client nfs-server"
      IMAGE_INSTALL_append = " bash sudo"
      IMAGE_INSTALL_append = " openssh openssh-sftp-server"
      IMAGE_INSTALL_append = " acpid acpitool"
      IMAGE_INSTALL_append = " vim vim-tiny"
      IMAGE_INSTALL_append = " avahi-daemon"
      IMAGE_INSTALL_append = " util-linux usbutils"
      IMAGE_INSTALL_append = " net-tools iproute2"
      IMAGE_INSTALL_append = " wget curl python3-pip"
      IMAGE_INSTALL_append = " i2c-tools python-smbus bridge-utils hostapd"
      IMAGE_INSTALL_append = " linux-firmware-rpidistro-bcm43455"
      IMAGE_INSTALL_append = " wpa-supplicant iw bluez5"
      
  2. レイヤー

    bblayers.confの設定

    1. レイヤー追加

      ダウンロードした各ソースを登録

      $ bitbake-layers add-layer ../../meta-raspberrypi
      $ bitbake-layers add-layer ../../meta-openembedded/meta-oe
      $ bitbake-layers add-layer ../../meta-openembedded/meta-networking
      $ bitbake-layers add-layer ../../meta-openembedded/meta-filesystems
      $ bitbake-layers add-layer ../../meta-openembedded/meta-webserver
      $ bitbake-layers add-layer ../../meta-openembedded/meta-multimedia
      $ bitbake-layers add-layer ../../meta-openembedded/meta-initramfs
      $ bitbake-layers add-layer ../../meta-openembedded/meta-perl
      $ bitbake-layers add-layer ../../meta-openembedded/meta-python
      
    2. カスタムレイヤー追加

      初期状態でデフォルトから変更したい設定などをレイヤー・レシピ化

      1. 初期設定

        1. レイヤー作成

          bitbake-layers create-layer ../sources/meta-local-bb
          
        2. レイヤー追加

          bitbake-layers add-layer ../sources/meta-local-bb
          
      2. 基本設定(base-files)

        1. 差分ファイル作成

          基本設定に対する以下の変更を行う

          • /usr/local以下のディレクトリを作成する
          • ユーザーデフォルトプロファイルを変更する
            標準ではsbin系がPATHに設定されないことへの対処
            標準ではsudoのコマンドをTABで補完出来ないことへの対処
          $ mkdir -p ../sources/meta-local-bb/recipes-core/base-files/files
          

          ../sources/meta-local-bb/recipes-core/base-files/base-files_%.bbappend

          base-files_%.bbappend
          FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
          
          SRC_URI += " \
              file://dot.profile \
          "
          
          do_install_append () {
              install -d ${D}/usr/local/bin
              install -d ${D}/usr/local/etc
              install -d ${D}/usr/local/include
              install -d ${D}/usr/local/lib
              install -d ${D}/usr/local/sbin
              install -d ${D}/usr/local/share
              install -d ${D}/usr/local/src
              install -d ${D}${sysconfdir}/skel
              install -m 0755 ${WORKDIR}/dot.profile ${D}${sysconfdir}/skel/.profile
          }
          

          ../sources/meta-local-bb/recipes-core/base-files/files/dot.profile

          dot.profile
          # ~/.profile: executed by Bourne-compatible login shells.
          
          if [ -f ~/.bashrc ]; then
            . ~/.bashrc
          fi
          
          # path set by /etc/profile
          export PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH"
          
          complete -cf sudo
          
          # Might fail after "su - myuser" when /dev/tty* is not writable by "myuser".
          mesg n 2>/dev/null
          
      3. sudo設定(sudo)

        1. 差分ファイル作成

          標準ではrootユーザーのみsudo可能になっている

          /etc/sudoers.d/配下にファイルを追加し、admin/sudoグループにもsudoを許可

          $ mkdir -p ../sources/meta-local-bb/recipes-core/sudo/files
          

          ../sources/meta-local-bb/recipes-core/sudo/sudo_%.bbappend

          sudo_%.bbappend
          FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
          
          SRC_URI += " \
              file://01-sudoer \
          "
          
          do_install_append() {
              install -d ${D}${sysconfdir}/sudoers.d
              install -m 0644 ${WORKDIR}/01-sudoer ${D}${sysconfdir}/sudoers.d/01-sudoer
          }
          

          ../sources/meta-local-bb/recipes-core/sudo/files/01-sudoer

          01-sudoer
          # Members of the admin group may gain root privileges
          %admin ALL=(ALL) ALL
          
          # Allow members of group sudo to execute any command
          %sudo   ALL=(ALL) ALL
          

ビルド

  1. ビルドするイメージ

    raspberry piで動作するイメージは以下の中から選ぶ

    • CUI

      core-image-base

    • GUI(X11)

      core-image-sato

    • GUI(Wayland/Weston)

      core-image-weston

    ※起動確認以降の手順はcore-image-baseで進める。

    そのほかにcore-image-minimalを選択出来るが、カーネルモジュールが取り込まれず、GPIOなどの使用に支障が出る模様。

    conf/local.confに以下の設定を追加すればおおよそのモジュールは取り込まれる。

    MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS += "kernel-modules"
    

    core-image-baseと差分がほぼなくなるので積極的に選択する理由はない。

    また、core-image-satoはコンポーネントgstreamerの依存パッケージ「faad2」のライセンスがcommercialとなっている、このライセンスを許容するためにconf/local.confに以下の設定を追加する必要がある。

    LICENSE_FLAGS_WHITELIST += "commercial"
    

    ※core-image-westonはGUIが起動しなかった。

  2. core-image-baseをビルド

    以下コマンドでビルドを実施

    $ bitbake core-image-base
    

    以下のイメージが作成される

    $ ls tmp/deploy/images/raspberrypi3-64
    ・・・
    core-image-base-raspberrypi3-64.rpi-sdimg   (シンボリックリンク)
    core-image-base-raspberrypi3-64-<yyyyMMddHHmmss>.rootfs.rpi-sdimg
    ・・・
    
  3. core-image-satoをビルド

    以下コマンドでビルドを実施

    $ bitbake core-image-sato
    

    以下のイメージが作成される

    $ ls tmp/deploy/images/raspberrypi3-64
    ・・・
    core-image-sato-raspberrypi3-64.rpi-sdimg   (シンボリックリンク)
    core-image-sato-raspberrypi3-64-<yyyyMMddHHmmss>.rootfs.rpi-sdimg
    ・・・
    
  4. core-image-westonをビルド

    以下コマンドでビルドを実施

    $ bitbake core-image-weston
    

    以下のイメージが作成される

    $ ls tmp/deploy/images/raspberrypi3-64
    ・・・
    core-image-weston-raspberrypi3-64.rpi-sdimg   (シンボリックリンク)
    core-image-weston-raspberrypi3-64-<yyyyMMddHHmmss>.rootfs.rpi-sdimg
    ・・・
    

起動確認

  1. balenaEtcherやddコマンドを使用して作成したイメージをメディアに書き込む。

    USBからのブート用の場合はUSBメモリ・USB-SSDなどUSB接続のストレージに、SDカード用イメージであればSDカードに書き込む。

  2. Raspberry Piにメディアを接続し、有線LANを接続して電源を投入する。

  3. 起動が完了するまで待って、sshコマンドでアクセスする。

    ssh pi@yoctopi3.local
    

    pi@yoctopi3.localの部分は、conf/local.confで設定したパラメータを使い、「<ユーザー名>@<ホスト名>.local」とする。

    (windows10 1809以降であればopensshが取り込まれているため、powershellやコマンドプロンプトからでも上記コマンドでアクセス可能)

    powershellで実行すると以下の様になる。

    PS C:\Users\ragna> ssh pi@yoctopi3.local
    The authenticity of host 'yoctopi3.local (2400:4053:c081:2d00:ba27:ebff:fe26:5877)' can't be established.
    ECDSA key fingerprint is SHA256:Wvo4trcK8bp79pVZkl3JASKZI829Rt6k4kfQaqNnM/U.
    Are you sure you want to continue connecting (yes/no)?    <-yesを入力
    Warning: Permanently added 'yoctopi3.local,2400:4053:c081:2d00:ba27:ebff:fe26:5877' (ECDSA) to the list of known hosts.
    pi@yoctopi3.local's password:    <-パスワード[raspberry]を入力
    yoctopi3:~$
    
  4. sudoが有効である事とタイムゾーンがJSTになっている事を確認

    以下コマンドで確認

    yoctopi3:~$ sudo date
    Password:            <-パスワード[raspberry]を入力
    Thu Mar 26 00:56:01 JST 2020    <-現在時刻がJSTで表示される事を確認
    yoctopi3:~$
    

    現在時刻は「systemd-timesyncd」サービスによって、NTPで時刻合わせが行われる。

  5. ネットワーク設定変更
    固定IPアドレス設定とホストネームの変更方法は以下になる

    1. 固定IP化
      systemd-networkのデフォルト設定ファイルを/etc/systemd/network/にコピーして編集
      [Network]部分を修正

      $ sudo cp /lib/systemd/network/80-wired.network /etc/systemd/network/
      $ sudo vi /etc/systemd/network/80-wired.network
      [Match]
      Name=en* eth*
      KernelCommandLine=!nfsroot
      
      [Network]
      DNS=192.168.25.1
      Address=192.168.25.99/24
      Gateway=192.168.25.1
      
      [DHCP]
      RouteMetric=10
      ClientIdentifier=mac
      

      設定変更を読み込み、サービスを再起動

      $ sudo systemctl daemon-reload
      $ sudo systemctl restart systemd-networkd
      

      sshが切断されるので、再接続する。
      ネットワークを確認

      $ ip a
      ・・・
      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
          link/ether b8:27:eb:26:58:77 brd ff:ff:ff:ff:ff:ff
          inet 192.168.25.99/24 brd 192.168.25.255 scope global eth0
             valid_lft forever preferred_lft forever
          inet6 2400:4053:c081:2d00:ba27:ebff:fe26:5877/64 scope global dynamic mngtmpaddr noprefixroute
             valid_lft 2591944sec preferred_lft 604744sec
          inet6 fe80::ba27:ebff:fe26:5877/64 scope link
             valid_lft forever preferred_lft forever
      ・・・
      
    2. ホスト名変更
      hostnamectlコマンドを使用する
      「yoctopi3」から「yoctopi3-master」に変更

      yoctopi3:~$ hostname
      yoctopi3
      yoctopi3:~$ sudo hostnamectl set-hostname yoctopi3-master
      yoctopi3:~$ hostname
      yoctopi3-master
      

      シェルを再接続

      yoctopi3-master:~$ hostname
      yoctopi3-master
      
2
4
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
2
4