hylom'sWeblog

- hylom's blog
| about hylom / hylom.net | old contents | login

Ubuntu 18.04でioDriveを使う

posted on 2019/01/29 17:31:54

 一昔前にフラッシュメモリベースのデータセンター向けストレージ「ioDrive」が一瞬話題になったが、このioDriveはUbuntu 18.04を公式にはサポートしていない。うっかり使っているサーバーをUbuntu 16.04から18.04にアップデートしてしまいトラブったのだが、自前でドライバをビルドすることでとりあえず動くようにはなる。当然サポート範囲外だが、手順をメモしておく。

 まず、Ubuntu 18.04にアップデートして再起動した時点でioDriveをマウントできなくなり、/etc/fstabで起動時にioDriveをマウントするよう設定している場合復旧モードで起動する羽目になる。そのため、まずはここで/etc/fstabを編集し、ioDriveに関する宇の記述をコメントアウトする。自分の環境ではioDriveは/dev/fioa1として認識されていたので、この記述をコメントアウト。

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda1 during installation
UUID=29279b34-d2fd-4a10-b3ac-378884b6f579 /               ext4    relatime,errors=remount-ro 0       1
# swap was on /dev/sda5 during installation
UUID=ff4e823a-c074-41bf-aa7c-5e63bd8c3f6a none            swap    sw              0       0
#/dev/fioa1 /fioa1 ext4 auto,rw,relatime,stripe=8,data=ordered 0 0

 続いてWestern Digitalのサポートサイトの「Downloads」リンク経由で最新のドライバを入手する(要アカウント登録)。ダウンロードページで「ioDrive」-「Linux_ubuntu-16.04」-「Current Version」(今回使用したのは「3.2.16」)を選択して「Software Source」からソースtarball(今回は「iomemory-vsl_3.2.16.1731-1.0.tar.gz」)をダウンロードする。なお、このページはCORS関連の問題でChromeではまともに動作しないようだ(Firefoxではダウンロードできた)。

 ダウンロードしたアーカイブを適当なディレクトリに展開する。

$ tar xvzf iomemory-vsl_3.2.16.1731-1.0.tar.gz
$ cd iomemory-vsl-3.2.16.1731/

 このソースtarballにはroot/usr/src/iomemory-vsl-3.2.16/kfio/以下にコンパイル済みオブジェクトファイル(いわゆるバイナリblob)が含まれており、このオブジェクトファイルをコンパイル時にリンクして使用するようになっている。このオブジェクトファイルは異なるコンパイラでビルドしたと思われる複数のものが用意されており、ファイル名の「cc??」の部分がコンパイラのバージョンに対応するようだ。今回使用したiomemory-vsl_3.2.16.1731-1.0.tar.gzでは次のようにGCC 4.1/4.3/4.4/4.8/4.9/5.3/5.4/6.3用のバイナリが入っていた。

$ /root/usr/src/iomemory-vsl-3.2.16/kfio/
x86_64_cc41_libkfio.o_shipped  x86_64_cc44_libkfio.o_shipped  x86_64_cc49_libkfio.o_shipped  x86_64_cc54_libkfio.o_shipped
x86_64_cc43_libkfio.o_shipped  x86_64_cc48_libkfio.o_shipped  x86_64_cc53_libkfio.o_shipped  x86_64_cc63_libkfio.o_shipped

 Ubuntu 18.04のデフォルトのGCCはバージョン7.3だが、これに対応するバージョンのバイナリはない。ただ幸いなことにUbuntu 18.04ではGCC 4.8がパッケージで提供されているので、これを利用する。

# apt-get install gcc-4.8

 GCC 4.8をインストールしたら、次のように「CC=gcc-4.8」を指定して「dpkg-buildpackage」コマンドを実行する。

$ CC=gcc-4.8 dpkg-buildpackage -b -us -uc

 正常にコンパイルとパッケージ作成が完了すると、親ディレクトリに次のようにファイルが作成される。

$ cd ..
$ ls -1
iomemory-vsl-3.2.16.1731
iomemory-vsl-4.15.0-43-generic_3.2.16.1731-1.0_amd64.deb
iomemory-vsl-config-4.15.0-43-generic_3.2.16.1731-1.0_amd64.deb
iomemory-vsl-source_3.2.16.1731-1.0_amd64.deb
iomemory-vsl_3.2.16.1731-1.0.tar.gz
iomemory-vsl_3.2.16.1731-1.0_amd64.buildinfo
iomemory-vsl_3.2.16.1731-1.0_amd64.changes

 このうち、「iomemory-vsl-4.15.0-43-generic_3.2.16.1731-1.0_amd64.deb」をインストールすれば良い。そのため、まずすでにインストールされているパッケージをアンインストールする。

# dpkg -r iomemory-vsl-source iomemory-vsl-config-3.13.0-77-generic  iomemory-vsl-3.13.0-77-generic libvsl

 続いて新たに作成したパッケージをインストールする。

# dpkg -i iomemory-vsl-4.15.0-43-generic_3.2.16.1731-1.0_amd64.deb

 最後にmodprobeコマンドで「iomemory-vsl」モジュールをロードすればioDriveが利用可能になる。fstabファイルでコメントアウトした部分を元に戻し、問題なくマウントできればOK。

# modprobe iomemory-vsl
# vi /etc/fstab
# mount /fioa1

CentOS+Docker関連でregistry.access.redhat.comのDockerレジストリからpullできなくなった場合の対処

posted on 2018/12/04 18:46:37

 CentOS 7でpython-rhsm-certificatesパッケージの仕様が変わり、今までここに含まれていたRed Hat関連の証明書がなくなってしまった模様(CentOS Bug Tracker)。そのせいで、Red Hatが提供しているDockerコンテナリポジトリであるregistry.access.redhat.comにCentOS 7環境からアクセスできなくなる状況が発生する。

 たとえば、CentOS上で組んだKubernetes環境ではregistry.access.redhat.com/rhel7/pod-infrastructureというコンテナが使われるのだが、このイメージがPullできなくなるエラーが発生する。

ErrImagePull: "image pull failed for registry.access.redhat.com/rhel7/pod-infrastructure:latest, this may be because there are no credentials on this request.  details: (open /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt: no such file or directory)"

 この変更はほかのさまざまなパッケージでも影響が出ているようだが、根本的な問題解決はRed Hat/Cent OS側で対処してもらうしかない。とりあえずは古いpython-rhsm-certificatesパッケージをダウンロードして、そこから問題の証明書を抜き出して手動で配置することで対処は可能。手順的には下記となる。

$ wget http://mirror.centos.org/centos/7/os/x86_64/Packages/python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm
$ rpm2cpio python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm | cpio -iv --to-stdout ./etc/rhsm/ca/redhat-uep.pem | tee redhat-uep.pem
$ sudo cp redhat-uep.pem /etc/rhsm/ca/

Kubernetesのサービス周りのトラブルシュート

posted on 2018/07/04 19:13:50

 自前で構築したKubernetesクラスタでサービス(serivces、svc)関連がうまく動かない場合、原因としてfirewall関連の設定が不適切だったということがよくあります。kube-dns関連のトラブル(kube-dns Podが起動しないなど)もこれが原因であることがよくあります。

 そういった場合、とりあえずiptablesが正しく設定されているか、またクラスタ内からapiserverのbind-addressで指定したアドレスの8080番および6443番ポート)にアクセスできるよう設定しているかを確認してみましょう。

 また、Kubernetesのパケットは複雑な経路でやってくるので、インターフェイス単位でアクセス許可を指定した場合うまく動かない場合があります。そのため、たとえばfirewalldを利用している場合、コンテナに割り当てられるネットワーク(たとえば172.17.0.0/16)をinternalゾーンに追加したうえで8080/tcpおよび6443/tcpを許可する、もしくはtrustedゾーンに追加する、といったようにネットワーク単位で設定した方が確実です。

kubectlコマンドで「NotAcceptable」というエラーが出たときの話

posted on 2018/07/04 18:20:48

 テスト用のKubernetesクラスタをメンテナンスしていたら、突然クラスタの操作ができなくなった。次のようなエラーが出る。

$ kubectl get nodes
No resources found.
Error from server (NotAcceptable): unknown (get nodes)

 色々調べたところ、うっかりkubectlコマンドをアップデートしてしまってクラスタ側とバージョンが一致しなくなっていた(クラスタ側は1.7.7、kubectlコマンドは1.11)。kubectlコマンドをダウングレードすることで対処できた。

Fedora28で自前Kubernetesクラスタを作るメモ

posted on 2018/05/11 19:48:58

 とりあえず基本的な流れは以前さくらのナレッジに書いたものと同じ。ただし、クラスタノードのkubelet設定ファイル(/etc/kubernetes/kubelet)の「KUBELET_ARGS」に次のように「--kubeconfig」および「--require-kubeconfig」パラメータを追加した上で、kubelet.ymlファイルを用意する必要がある。

KUBELET_ARGS="--cgroup-driver=systemd --fail-swap-on=false --kubeconfig=/etc/kubernetes/kubelet.yml --require-kubeconfig"

 kubelet.ymlファイルはこんな感じ。

kind: Config
clusters:
- name: local
  cluster:
    server: http://<api-serverのホスト名かIPアドレス>:8080
users:
- name: kubelet
contexts:
- context:
    cluster: local
    user: kubelet
  name: kubelet-context
current-context: kubelet-context

 --api_servers(--api-servers)オプションは廃止されているので、このように設定ファイルでapi-serverのURLを指定しなければならない模様(https://github.com/kubernetes/website/issues/7417)。

(追記@2018-05-15)

 kube-proxyにはiptables 1.6.2と組み合わせて使うとiptablesルールを適切に設定できないという不具合がある。Fedora 28のiptablesは1.6.2なので、これに引っかかる。Fedora 28のKubernetesパッケージに含まれているkubeletでは現時点でこれが修正されていない。とりあえずFedora 27用のiptables 1.6.1に置き換えることで問題は回避できそう。

$ wget https://dl.fedoraproject.org/pub/fedora/linux/releases/27/Everything/x86_64/os/Packages/i/iptables-1.6.1-4.fc27.x86_64.rpm
$ wget https://dl.fedoraproject.org/pub/fedora/linux/releases/27/Everything/x86_64/os/Packages/i/iptables-libs-1.6.1-4.fc27.x86_64.rpm
# dnf install iptables-*.rpm

Debianで突然mysqlサービスが起動しなくなった

posted on 2018/05/07 14:02:44

 Debianのmysqlパッケージをアップデートしたら突然mysqlサービスが起動しなくなった。journalctlでエラーメッセージを見ると、次のように出力されている。

# journalctl -u mysql
  :
  :
May 07 06:10:09 gate mysqld[3528]: /usr/sbin/mysqld: Error on realpath() on '/var/lib/mysql-files' (Error 2)
May 07 06:10:09 gate mysqld[3528]: 180507  6:10:09 [ERROR] Failed to access directory for --secure-file-priv. Please make sure that directory exists and is accessible by MySQL Server. Supplied value : /var/lib/mysql-files

 この場合、/var/lib/mysql-filesディレクトリを作成すればOKのようだ。問題のパラメータ「--secure-file-priv」についてのドキュメントはここにある

# mkdir /var/lib/mysql-files
# chown mysql:mysql  /var/lib/mysql-files
# chmod 700 /var/lib/mysql-files

JenkinsのWebフックによるビルド設定メモ

posted on 2018/04/25 22:15:53

 Jenkinsをアップデートしたらグローバルセキュリティ設定を確認しろというメッセージが出たので色々設定したら、gitのpushに対応させてビルドするために設定していたWebフックが動かなくなった。そのための対応メモ。アドホックにやったので正しい対策ではないかもしれない。

グローバルセキュリティ設定

 「行列による権限管理(プロジェクト単位)」を有効にして、匿名ユーザーに対し「ジョブ」の「Build」を許可する。このとき、ログインしているユーザーに全権限を与えないとその後Jenkinsの操作ができなくなる場合がある(ググればその場合の対策法が出てくる)。

 また、「CSRF対策」は無効にする。有効にすると事前にトークンの取得が必要になるらしい(参考:https://stackoverflow.com/questions/38137760/jenkins-rest-api-create-job)。面倒臭いので無効にする。

プロジェクト単位の権限設定

 匿名ユーザーに「ジョブ」の「Build」、「Read」、「Workspace」を有効にする。

 これでビルドできた。「リモートからビルド」は有効にしておくが、認証トークンが必要かどうかは不明。

Raspberry Piを使ってSpotifyをheadlessで聞く

posted on 2018/03/21 17:23:26

 Raspberry Piを使ってSpotifyを再生できるデバイスを作ったので手順などを備忘録代わりに。使用したデバイスはRaspberry Pi Zero W。OSはRaspbian(Stretch)。なお利用にはSpotifyの有料アカウントが必須。

Spotify Connectデバイスとして使用する

 Spotifyを再生するためには、デバイス側でSpotifyにログインしてプレイリストなどの情報を取得して再生する、という処理を全部行うやり方と、PC/Macやスマートフォン、タブレットなどのSpotifyアプリ側で認証やプレイリスト/楽曲管理などを行い、Spotifyとの通信およびデータダウンロード、再生などのみをデバイス側で行う「Spotify Connect」という機能を使うやり方がある。

 Spotify Connectデバイスとして利用する場合、Raspotifyというソフトウェアを利用すると簡単に実現できる。librespotというオープンソースで開発されているSpotifyクライアントライブラリが使われているが、これらを含有したRaspberry Pi向けのバイナリパッケージが配布されているので、これをインストールし、設定ファイルを編集してサービスを起動するだけで良い。

 設定ファイルは/etc/default/raspotify。変更したのはデバイス名を指定する「DEVICE_NAME」、ビットレートを指定する「BITRATE」といくつかのオプション。オプションについてはlibrespotのドキュメントにまとめられているが、ここでは使用するALSAデバイスを指定する「--device」、Spotifyアプリとの接続に使用するポートを指定する「--zeroconf-port」、キャッシュディレクトリを指定する「--cache」、音量の自動調整を有効にする「--enable-volume-normalisation」、初期音量を指定する「--initial-volume」を使用している。--deviceの引数はALSAの設定によって変わるので適宜適切なものを選択(後述)。ユーザー名などはSpotifyアプリ経由で取得するので設定不要。「--zeroconf-port」は指定しなくても良いのだが、指定するとポートを固定できるためファイアウォールの設定が簡単になる。

# /etc/default/raspotify -- Arguments/configuration for librespot

# Device name on Spotify Connect
#DEVICE_NAME="raspotify"
DEVICE_NAME="5potpy"

# Bitrate, one of 96 (low quality), 160 (default quality), or 320 (high quality)
#BITRATE="160"
BITRATE="320"

# Additional command line arguments for librespot can be set below.
# See `librespot -h` for more info. Make sure whatever arguments you specify
# aren't already covered by other variables in this file. (See the daemon's
# config at `/lib/systemd/system/raspotify.service` for more technical details.)
#
# To make your device visible on Spotify Connect across the Internet add your
# username and password which can be set via "Set device password", on your
# account settings, use `--username` and `--password`.
#
# To choose a different output device (ie a USB audio dongle or HDMI audio out),
# use `--device` with something like `--device hw:0,1`. Your mileage may vary.
#
#OPTIONS="--username <USERNAME> --password <PASSWORD>"
OPTIONS="--device mydev --zeroconf-port 65432"

# Uncomment to use a cache for downloaded audio files. Cache is disabled by
# default. It's best to leave this as-is if you want to use it, since
# permissions are properly set on the directory `/var/cache/raspotify'.
CACHE_ARGS="--cache /var/cache/raspotify"

# By default, the volume normalization is enabled, add another volume argument
# here if you'd like, ie `VOLUME_ARGS=--initial-volume 100`.
VOLUME_ARGS="--enable-volume-normalisation --initial-volume 100"

 設定ファイルを作成したら、systemctlコマンドでサービスを開始できる。

# systemctl start raspotify

 ログはjournalctlコマンドで閲覧できる。

# journalctl -u raspotify

 確認していないが、zeroconfを使っているとのことで別途avahi-daemonも必須かもしれない。

# systemctl start avahi-daemon

Webブラウザ経由で操作できるSpotifyクライアントを使う

 基本的にはSpotify Connect経由での利用で事足りるのだが、Webブラウザ経由で操作できるクライアントについても試しに導入してみた。こちらはMopidyというミュージックサーバーソフトウェアとSpotify用のプラグインを組み合わせて利用することで実現できる・

 Mopidy自体はRaspbian標準でパッケージが提供されているので、これをインストールする。

# apt-get install mopidy

 次に、Spotify用のプラグインをインストールする。必要なのは下記。

  • mopidy-mopify:MopidyにSpotify連携用のWeb UIを追加するプラグイン
  • mopidy-spotify:MopidyにSpotifyからのストリーミング再生機能を追加するプラグイン
  • libspotify:かつてSpotifyが公式に提供していたSpotify連携ライブラリ。すでに開発終了でいつサポートが終了してもおかしくない
  • pyspotify:libspotifyのPythonラッパー

 libspotifyとコンパイル済みのpyspotifyはMopidyのaptリポジトリから入手可能(ドキュメント)。自分は次のように直接ダウンロードして使用した。

$ wget http://apt.mopidy.com/dists/jessie/non-free/binary-armhf/libspotify12_12.1.103-0mopidy1_armhf.deb
$ wget http://apt.mopidy.com/dists/jessie/contrib/binary-armhf/python-spotify_2.0.5-0mopidy1_armhf.deb

 いくつか依存するパッケージがあるので、それはapt-getでインストールする。mopidy-spotifyとmopidy-mopifyについてはpipでインストールできる。

# pip install Mopidy-Spotify
# pip install Mopidy-Mopify

 続いて設定ファイルの編集。

[core]
cache_dir = /var/cache/mopidy
config_dir = /etc/mopidy
data_dir = /var/lib/mopidy

[logging]
config_file = /etc/mopidy/logging.conf
debug_file = /var/log/mopidy/mopidy-debug.log

[local]
media_dir = /var/lib/mopidy/media

[m3u]
playlists_dir = /var/lib/mopidy/playlists

[http]
enabled = true
hostname = 192.168.1.210
port = 6680
zeroconf = Mopidy HTTP server on $hostname

[mopify]
enabled = true
debug = false

[spotify]
enabled = true
username = <Spotifyのユーザー名>
password = <Spotifyのパスワード>
client_id = <client ID>
client_secret = <client secret>
bitrate = 320

 hostnameやusername、passwordは各自適切な物を指定する。client_idおよびclient_secertはMopidyのWebサイトにアクセスして「LOG IN WITH SPOTIFY」リンクをクリックしてOAuth認証を行うと、このページにリダイレクトされて設定すべきclient_idおよびcluent_secretが表示される。これをコピペすればOK。

ALSAの設定

 RaspotifyもMopidyもサウンド出力にはALSAを使用する。認識されているデバイスは/proc/asound/cardsファイルで確認できる。たとえば次の例では、デバイス0としてRaspberry Pi内蔵オーディオ(Raspberry Pi Zero Wの場合HDMI経由での出力に相当するはず)、デバイス1としてUSB端子に接続したオーディオIFが認識されている。

# cat /proc/asound/cards
 0 [ALSA           ]: bcm2835 - bcm2835 ALSA
                      bcm2835 ALSA
 1 [USB            ]: USB-Audio - <USBサウンドデバイスの情報がここに表示される>

 ALSAの場合、各アプリケーションが使用するサウンドデバイスに関する設定は/etc/asound.confで行える。今回はデフォルト設定(pcm.!default)に加えて、「pcm.mydev」という設定を作ってこれをRaspotifyで使用するよう指定している(前述)。dmixerの設定ではuidが異なる複数のプロセスからの非排他的音声出力を可能にするため「ipc_key_add_uid 0」「ipc_perm 0660」の2つを指定している。また、「slave」以下で「hw:1」を指定することで、オーディオデバイス1、つまりUSBサウンドデバイスを使用するよう指定している。

# cat /etc/asound.conf 
pcm.mydev {
  type plug
  slave {
    pcm "dmixer"
  }
}

pcm.!default {
  type plug
  slave {
    pcm "dmixer"
  }
}

pcm.dmixer {
  type dmix
  ipc_key 1024
  ipc_key_add_uid 0
  ipc_perm 0660
  slave {
    pcm "hw:1"
  }
}

問題点

 Mopidyでは一部のプレイリストが適切に取得できなかったりする模様。これはlibspotifyがもうdeprecatedであるためらしい。

 また、MopidyとRaspotify両方で発生する問題だが、ネットワークが遅くなる時間帯だとストリームのキャッシュに時間がかかったり、間に合わずに音切れが発生する状況となっている。Spotifyアプリだとこの問題は発生しないのでパケットを調べたりしたのだが、どうもSpotify公式アプリはakamai経由でコンテンツをダウンロードしているため混雑時でも高速にコンテンツをダウンロードできているようだ。この機能はMopidy(libspotify)やlibrespotではサポートされていないようなので、簡単には解決できなさそうである。

SELinuxを有効にしている場合にDockerコンテナからホストのファイルシステムにアクセスできない場合の対処法

posted on 2018/03/07 17:45:42

 dockerでローカルのファイルシステムをコンテナ内にマウントして利用するとき、パーミッションは適切なはずなのにそのディレクトリにアクセスできないトラブルに遭遇(環境はFedora 25)。

 とりあえず、SELinuxの状況を確認。

# getenforce
Enforcing

 有効となっていたので、ログ(/var/log/audit/audit.lo)を確認。次のように対象ディレクトリ(ここでは「hal」)に対するログが見つかった。つまり、SELinuxによってアクセスがブロックされていたということ。

type=AVC msg=audit(1520416357.374:153155): avc:  denied  { write } for  pid=18595 comm="java" name="hal" dev="dm-0" ino=398292 scontext=system_u:system_r:container_t:s0:c825,c930 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=dir permissive=0a

 細かくSELinuxのルールを設定するのが適切なのだが、今回はテスト環境なので次のようにしてcontainer_tに関するアクセス制御を全部無効にすることで対処。

# semanage permissive -a container_t

「start-limit-hit」といったメッセージが出てdocker serviceの起動に失敗した場合の対処法

posted on 2018/03/07 17:14:13

 systemdでdocker serviceの起動時に、次のようなエラーが出て起動できない場合がある(このメッセージはjournalctl -xeコマンドで確認)。

-- The result is failed.
 3月 07 18:28:10 fedora25 systemd[1]: docker.service: Unit entered failed state.
 3月 07 18:28:10 fedora25 systemd[1]: docker.service: Failed with result 'start-limit-hit'.

 このエラーは使用しているdockerのバージョンとsystemdのdocker.service設定ファイルの内容が合っていない場合に出るようだ。このエラーが出た環境は、Dockerが配布しているパッケージでDockerをインストール後、そのパッケージを削除してFedora 25標準のパッケージに入れ直したというもの。自分で作成して忘れていたのか、それともパッケージによってインストールされたのか分からないが、/etc/systemd/systemディレクトリ以下にdocker.serviceファイルが残っていたのが原因。

 このファイルを削除し、systemctl daemon-reloadでsystemdの設定を読み直したら復旧した。