CentOS/RHELの起動スクリプト内ではsudoではなくrunuserを使う

morimorihogeです。
今朝は久々にAWSのus-eastリージョンが障害祭りみたいでどきどきしてます。今のところtokyoリージョンには問題なさそうですが、HerokuとかSlackみたいに内部的にus-eastに依存しているサービスは不安定のようですね。

小ネタです。

サーバ起動時の自動起動スクリプト

インフラ構築をしていて忘れがちですが大事なこと、それは「再起動テスト」です。
今はVPS的なクラウドサービスが主流になったので物理サーバの再起動ということはずいぶん減りましたが、それでもクラウドサービス側のメンテナンスで再起動が不定期に発生することはあります。
この際、再起動時にもきちんと必要なサービスが起動するように設定しておかないと困るわけですね。

LinuxではRedHat系(含むCentOS)もDebian系(含むUbuntu)も昔はsysvinitによる管理がされてきました(Ubuntuは途中upstartを使っていました)が、最近はsystemdを使う方向に統合されてきました。
ただ、systemdを使っていてもサービスの起動/停止用スクリプト自体はこれまで通り使うことも可能なので、その辺りは過去の資産を流用できると思います。
#実際にはsystemd用に書き直した方がシンプルになりそうですが、書き直すと検証も必要になるので互換性はありがたいです

なお、systemdで従来のsysvinit的なスクリプトを使いたい場合は、例えばHow does systemd use /etc/init.d scripts?といった記事が参考になるかと思います。

CentOS/RHEL固有の問題

世の中はsystemdに移行しつつある中とはいえ、レガシなディストリビューションを触る機会も相変わらずあります。
というわけでinit.dなスクリプトを書いていたのですが、Ubuntuでは動いていたスクリプトがCentOS7で動かなくて困りました。
具体的には、スクリプト内で書いていたsudoがrootのシェルからserviceコマンドで使う分には動作するのに、再起動時には起動しないという問題です。

どうやらCentOS/RHELのデフォルト設定では起動時のsudoは許されていない(ttyがないから?)らしく、その他の方法を使う必要があります。

runuserコマンドを使う

そんなときは

sudo -H -u app_user COMMAND

の代わりにrunuserコマンドを使い、

runuser app_user COMMAND

とすればうまいこと起動します。

ただ、runuserはUbuntuにはないパッケージのため、RHEL/CentOSとUbuntuで同じスクリプトを使い回せません。いけてない。この辺は苦し紛れに

SUDO="runuser $USER"

$SUDO COMMAND

的にsudo自体をwrapすることでとりあえず許せる範囲には満足しました。

なお、systemdを使えば

[Service]
User=app_user

するだけでディストリビューション間互換取れるんですよね。ということに後になってから気づきました。でもまあsystemdはまだ慣れてないエンジニアも多いと思うので、古いバッドノウハウを知っておくのも無駄ではないかなと思いました(願望)。

まとめ

久々にCentOSとか触ってハマったのでメモでした。最近社内環境はほとんどDocker化したのでsystemdよりsupervisordを使いこなせるようにならないといけないなーと思いつつ、レガシーな環境も触る機会はなくならないなあと思った日々でした。

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

morimorihoge

高校卒業後,学生をやりながらずっとWebアプリ開発に携わってきました.2010くらいまではPHP/Symfonyプログラマでしたが,それ以降のWeb開発はRailsほぼ一本に宗旨替えしました.開発とは別にサーバ構築・運用も10年以上やってきているので,要件定義から設計・実装・環境構築・運用まで一通り何でもこなせます.開発以外では季節により大学でWebサービス開発やプログラミング関連の非常勤講師もしており,技術の啓蒙・教育にも積極的に関わっています.最近はPM的な仕事が増えていますが,現役開発者としていつでも動ける程度にはコードもサーバも弄る日々を送っています.AWS 認定ソリューションアーキテクト – アソシエイトレベル取りました

morimorihogeの書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ