2018年9月30日日曜日

【Docker】コンテナ起動時に一般ユーザ権限でコマンドを実行したい

…ってことありませんか?
システムの初期化するとか初期設定するとかイニシャライズするとか。

普通の物理マシンや仮想マシンならナンボでも方法はあるんですが、Dockerにはブートという概念がないのでちょっとハマりました。

さて、どうしよう

起動スクリプト+sudo

多分一番簡単なのがコレじゃないでしょうか。
DockerfileのENTRYPOINTで実行するスクリプトの中で、sudoで実行。

実行したいスクリプトが複数ある場合や複数のユーザ権限を使いたい場合は、例えば/var/scriptsの下に各ユーザごとのディレクトリを作って、その中に実行したいファイルを作成。 その上で/var/scripts以下にこんなかんじのonboot.shを置いて、ENTRYPOINTに/var/scripts/onboot.shを指定してやればよさそう。
#!/bin/bash

for dirname in *; do
 if [ ! -d $dirname ]; then
  # ディレクトリ以外
  continue
 fi

 # ディレクトリならその下のスクリプトファイルを検索
 for scriptname in $dirname/*.sh; do
  # ディレクトリ名をユーザ名とみなしてsudo
  sudo -u $dirname bash $scriptname
 done
done

cron@reboot

そしてcronを使うともっと手軽に実現できます。
実行したいユーザのcrontabに@reboot foo.shを追加するだけ。

ただし、もちろんcronをインストール&ENTRYPOINTでcronを起動してやらないと動きません。
あと、cronは起動時にリブート中か否かを/var/run/crond.rebootというファイルの存在で判定するので、ENTRYPOINT内でこのファイルも削除してやる必要があります。
#!/bin/bash

# このファイルを削除したあとでcronを起動
rm -f /var/run/crond.reboot
service cron start
cronデーモン起動時にこのファイルが存在していれば、システムのブート中ではなくすでに起動しているシステムでcronのデーモンを起動していたとみなされ、@rebootは実行されません。

こっちのほうが手軽と書きましたが、いろいろ注意することがあるのでsudoを使ったほうが手軽かも。

0 件のコメント:

コメントを投稿