0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dockerコンテナでcron, sshできるようにする

Posted at

TL;DR

完成したdockerfile

背景

遊休パーツがあったので、ubuntuマシンを1台組んだ。
今後、環境構築は死ぬほどやりたくなかったので、
dockerにて管理することにした。この記事はその時の備忘録となる。
ラズパイで動いていたもの、AWSで動いていたもの、ここで一元管理したい。
リスク分散?知らないな....

前提とか

ホストマシンのOS

Ubuntu 24.04 LTS

作るコンテナで何をするつもり?

  • cronで指定時間にファイルをDLするスクリプトを実行する。
  • sshで保存したファイルを見に行けるようにしておく。

1. 公式ドキュメントを読んでみる

ベストプラクティスのページを読んで考え方について把握しておく。
後でぐちゃぐちゃになった環境で困るのは自分だから。
ちなみに日本語化プロジェクトがあるので、最初はここを読むと良い気がする。

ベストプラクティス

Dockerfile を書くベストプラクティス — Docker-docs-ja 24.0 ドキュメント
理由、経緯は省略して、ここからいくつか引用する

不要なパッケージを入れることに関しては「禁止」とかなり強い言葉を使っており、
笑いそうになったが「とりあえずあったら便利だし入れとくか!」のようなナイーヴな考え方は捨てろと言っている。お前のことだぞ。(自戒)
(ちなみに以前のドキュメントには「不要なパッケージのインストールを避ける」と書いており、今よりだいぶ優しい。何があったんだ。)

以上を念頭において「あっ、俺が今やっていることは異常かもしれない」と自覚しながら作っていく。

2. NETWORKS作成

LAN内の他の端末からもアクセスしたかったため、
ブロードキャストドメインはホストマシンと同一にする。
設定にはmacvlanを使用する。
macvlan ネットワークの使用 — Docker-docs-ja 24.0 ドキュメント

ホストマシンが使用している物理ネットワークインタフェース名、subnet、gatewayをあらかじめメモしておく。

インタフェース名確認
ip addr

上記でメモっておいた各種値を確認しながら、コンテナに使用するネットワーク設定を作成する。

mynet作成
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=enp4s0 mynet

ここでmacvlanを使用して作成できるもののイメージは以下ページ引用

Dockerでmacvlanを使う | Reafnex

image.png

俺がここで何を言いたいのかというと、
ホストマシンとポートは共有しているため、外部とやり取りする場合はポートフォワード系のケアが必要
になるということ。

後述するssh設定では、コンテナ上のsshで使用するポートを変更しています。

3. Dockerfile作成

sshの設定を行う

ホストマシンでもsshを使用している場合、ポート変更は必須です。

ssh
RUN apt install openssh-server -y
# 使用するポートを2223へ変更
RUN sed -i 's/#*Port 22/Port 2223/' /etc/ssh/sshd_config
# 公開鍵認証を使用した接続を許可
RUN sed -i 's/#*PubkeyAuthentication [a-z]*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
# パスワードを使用した接続を許可
RUN sed -i 's/#*PasswordAuthentication [a-z]*/PasswordAuthentication yes/' /etc/ssh/sshd_config

ちなみに公開鍵認証を有効した場合、公開鍵は ~/.ssh/authorized_keys に置きましょう。

cronの設定を行う

cron
# cron と nano
RUN apt install cron nano -y
# UTC であることに注意
RUN (crontab -l -u user; echo "00 16 * * 02 ur/file.sh")| crontab -u user -

なんか変な書き方してるので少し説明します。

オプション 効果
-l 一覧出力
-u 実行ユーザ指定
- 標準入力受付

「一覧出力」 + 「echoで追記した文字列」を標準入力でcrontabに流し込む。
って感じです。

コンテナ起動時にssh/cronも起動させる

以下スクリプトを用意して、dockerfileの最後の方で実行するように書きます。

startup.sh
#!/bin/sh

# Start the ssh server
/etc/init.d/ssh start

# Start the cron
service cron start

# Execute the CMD
exec "$@"
dockerfileの最後の方
# startup
COPY startup.sh /startup.sh
RUN chmod +x /startup.sh
ENTRYPOINT ["/startup.sh"]

CMD ["/bin/bash"]

これでコンテナ起動時にスクリプトが実行されます。
最後のCMDは、コンテナ起動後すぐに落ちてしまわないようにするためです。
コンテナはやることがなくなったら落ちるので。

完成したdockerfile

すこしずつ切り取られると理解しにくいと思うので一応全体を載せときます。
説明していない部分、伏せてる部分もあるので注意。

dockerfileの最後の方
FROM ubuntu:latest

RUN apt update && apt dist-upgrade -y && apt autoremove


# add user
# パスワードは手動で設定が必要
ARG USERNAME=hxbdy
ARG GROUPNAME=hxbdy
ARG UID=1001
ARG GID=1001
RUN groupadd -g $GID $GROUPNAME && useradd -m -s /bin/bash -u $UID -g $GID $USERNAME

# apt install
# cron
RUN apt install cron nano -y
# ssh
RUN apt install openssh-server -y
# git
RUN apt install git -y


# SSH
# 鍵は手動で追加が必要
RUN sed -i 's/#*Port 22/Port 2222/' /etc/ssh/sshd_config
RUN sed -i 's/#*PubkeyAuthentication [a-z]*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
RUN sed -i 's/#*PasswordAuthentication [a-z]*/PasswordAuthentication yes/' /etc/ssh/sshd_config


# make workspace
ARG WORKSPACE=/home/$USERNAME/workspace
WORKDIR $WORKSPACE
RUN chmod 777 $WORKSPACE


USER $USERNAME


RUN git clone https://github.com/???/???.git


# cron
# UTC であることに注意
RUN (crontab -l -u hxbdy; echo "00 16 * * 02 $WORKSPACE/???.sh")| crontab -u hxbdy -


# startup
USER root
COPY startup.sh /startup.sh
RUN chmod +x /startup.sh
ENTRYPOINT ["/startup.sh"]

CMD ["/bin/bash"]

以上。ビルドして完成。

4. IMAGES作成

あらかじめ作成しておいていたネットワーク設定を使い、ホストマシン起動と同時にコンテナも実行するコマンドはこうだ~~~

実行
docker run -it --name ubuntu --hostname="docker-ubuntu" --network mynet --ip 192.168.100.111 --restart unless-stopped ubuntu

疎通確認

windows powershellから確認した。

実行
 Test-NetConnection 192.168.100.111 -Port 2223

色々出てくるけど、
TcpTestSucceeded : True
となっていればOK

逆引き目次

コンテナ起動直後にスクリプトを実行したい

sshできない

  • ホストマシンと使用ポートがバッティングしている
  • ユーザのパスワードを設定していない
  • ユーザの公開鍵を置いていない

コンテナがすぐ落ちる

タイムゾーンを変更しても次回起動時UTCに戻ってしまう

参考

Docker ドキュメント日本語化プロジェクト — Docker-docs-ja 24.0 ドキュメント

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?