Docker のコンテナイメージをローカル環境にプールするためのレジストリサーバを構築します。
※ここでは実際に設定、動作したものを掲載していますが、内容について保証するものではありません。流用される場合は各自の責任でお願いします。
構築する環境の要件等については 「ローカル環境にプールしたDockerイメージからコンテナを起動する仕組みを構築」 をご参照ください。
全体の構築作業は以下のとおりですが、今回は「① ローカル環境にDockerイメージをプールするためのサーバを構築」を実施します。
① ローカル環境にDockerイメージをプールするためのサーバを構築
② ローカルプールからDockerイメージをダウンロードし、起動するためのサーバを構築
今回の構築範囲は下図のとおりです。

セキュリティ機能の無効化
検証環境ではセキュリティ機能の影響を気にしたくないため、いくつかの機能を無効化しておきます。(実施する場合は各自の責任でお願いします)
SELinux のアクセス制御無効
[root@registry ~]# cp /etc/selinux/config /tmp
[root@registry ~]# vi /etc/selinux/config
[root@registry ~]# diff /tmp/config /etc/selinux/config
7c7
< SELINUX=enforcing
---
> SELINUX=permissive
Firewall 停止
[root@registry ~]# systemctl stop firewalld
[root@registry ~]# systemctl disable firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
ライブラリの最新化と必要なツールのインストール
パッケージ更新
OS にインストールされているパッケージを最新化しておきます。
[root@registry ~]# dnf update -y
…
アップグレード済み:
NetworkManager-1:1.40.16-15.el8_9.x86_64 NetworkManager-libnm-1:1.40.16-15.el8_9.x86_64 NetworkManager-team-1:1.40.16-15.el8_9.x86_64
NetworkManager-tui-1:1.40.16-15.el8_9.x86_64 acl-2.2.53-3.el8.x86_64 audit-3.1.2-1.el8.x86_64
…
xz-5.2.4-4.el8_6.x86_64 xz-libs-5.2.4-4.el8_6.x86_64 yum-4.7.0-20.el8.noarch
zlib-1.2.11-26.el8.x86_64
インストール済み:
glibc-gconv-extra-2.28-251.el8_10.4.x86_64 grub2-tools-efi-1:2.02-156.el8.rocky.0.1.x86_64 kernel-4.18.0-553.16.1.el8_10.x86_64 kernel-core-4.18.0-553.16.1.el8_10.x86_64
kernel-modules-4.18.0-553.16.1.el8_10.x86_64 libevent-2.1.8-5.el8.x86_64 libxkbcommon-0.9.1-1.el8.x86_64 pinentry-1.1.0-2.el8.x86_64
python3-systemd-234-8.el8.x86_64 python3-unbound-1.16.2-5.el8_9.6.x86_64 unbound-libs-1.16.2-5.el8_9.6.x86_64 xkeyboard-config-2.28-1.el8.noarch
完了しました!
OS を再起動します。
[root@registry ~]# systemctl reboot
EPEL リポジトリインストール
Python 等、EPEL(Extra Packages for Enterprise Linux)からインストールするため、EPEL のリポジトリをインストールします。
[root@registry ~]# dnf install epel-release -y
…
インストール済み:
epel-release-8-18.el8.noarch
完了しました!
jq インストール
JSON 形式のテキスト編集用のツールです。本環境ではプールに登録したイメージの一覧を表示する際に使用します。
[root@registry ~]# dnf install jq -y
…
インストール済み:
jq-1.6-9.el8_10.x86_64 oniguruma-6.8.2-3.el8.x86_64
完了しました!
Python3 インストール
Ansible のインストール要件に Python3.9 以上が必要なためインストールします。
Python3.9 が未インストールであること確認します。(インストール済の場合、リポジトリ名の前に@が付きます。)
[root@registry ~]# dnf list | grep python39
python39.x86_64 3.9.19-7.module+el8.10.0+1860+afcc1c71 appstream
…
python39-xmltodict.noarch 0.12.0-1.el8 epel
Python3.9 のパッケージの情報を確認します。
[root@registry ~]# dnf info python39
メタデータの期限切れの最終確認: 0:11:25 前の 2024年09月01日 11時30分33秒 に実施しました。
利用可能なパッケージ
名前 : python39
バージョン : 3.9.19
リリース : 7.module+el8.10.0+1860+afcc1c71
Arch : x86_64
サイズ : 34 k
ソース : python39-3.9.19-7.module+el8.10.0+1860+afcc1c71.src.rpm
リポジトリー : appstream
概要 : Version 3.9 of the Python interpreter
URL : https://www.python.org/
ライセンス : Python
説明 : Python 3.9 is an accessible, high-level, dynamically typed, interpreted
…
Python3.9 をインストールします。
[root@registry ~]# dnf install python39 -y
…
インストール済み:
python39-3.9.19-7.module+el8.10.0+1860+afcc1c71.x86_64 python39-libs-3.9.19-7.module+el8.10.0+1860+afcc1c71.x86_64
python39-pip-20.2.4-9.module+el8.10.0+1860+afcc1c71.noarch python39-pip-wheel-20.2.4-9.module+el8.10.0+1860+afcc1c71.noarch
python39-setuptools-50.3.2-6.module+el8.10.0+1861+0f5e39ec.noarch python39-setuptools-wheel-50.3.2-6.module+el8.10.0+1861+0f5e39ec.noarch
python39-tkinter-3.9.19-7.module+el8.10.0+1860+afcc1c71.x86_64
完了しました!
Python3 のバージョンを確認します。
[root@registry ~]# python3 -V
Python 3.9.19
[root@registry ~]# pip3 -V
pip 20.2.4 from /usr/lib/python3.9/site-packages/pip (python 3.9)
pip を最新化しておきます。(pip は Python のパッケージ管理システムです)
[root@registry ~]# python3 -m pip install pip --upgrade
WARNING: Running pip install with root privileges is generally not a good idea. Try `python3 -m pip install --user` instead.
Collecting pip
Downloading pip-24.2-py3-none-any.whl (1.8 MB)
|????????????????????????????????| 1.8 MB 2.7 MB/s
Installing collected packages: pip
Successfully installed pip-24.2
[root@registry ~]# pip3 -V
pip 24.2 from /usr/local/lib/python3.9/site-packages/pip (python 3.9)
Ansible インストール
本環境では Ansible のインストールは pip で行います。対象モジュールを個別にインストールすることもできますが、ここではモジュール名のリストを作成し、pip でまとめてインストールします。
インストール対象のモジュール名(Ansible 等)を requirements.txt に登録します。
[root@registry ~]# vi requirements.txt
[root@registry ~]# cat requirements.txt
ansible
ansible-core
Jinja2
requests
モジュールを pip でインストールします。
[root@registry ~]# python3 -m pip install -r requirements.txt
…
Successfully installed Jinja2-3.1.4 MarkupSafe-2.1.5 PyYAML-6.0.2 ansible-8.7.0 ansible-core-2.15.12 certifi-2024.8.30 cffi-1.17.0 charset-normalizer-3.3.2 cryptography-43.0.1 idna-3.8 importlib-resources-5.0.7 packaging-24.1 pycparser-2.22 requests-2.32.3 resolvelib-1.0.1 urllib3-2.2.2
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable.It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.
インストールした Ansible のバージョンを確認します。
[root@registry ~]# ansible --version
ansible [core 2.15.12]
config file = None
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.9.19 (main, Aug 29 2024, 05:41:50) [GCC 8.5.0 20210514 (Red Hat 8.5.0-22)] (/usr/bin/python3)
jinja version = 3.1.4
libyaml = True
Ansible のコレクションをインストールします。コレクションはモジュール等をパッケージ化したものです。
インストール対象のコレクション名を requirements.yml に登録します。
[root@registry ~]# vi requirements.yml
[root@registry ~]# cat requirements.yml
---
collections:
- name: community.general
source: https://galaxy.ansible.com
- name: community.docker
source: https://galaxy.ansible.com
- name: ansible.posix
source: https://galaxy.ansible.com
コレクションをインストールします。
[root@registry ~]# ansible-galaxy collection install -r requirements.yml
Starting galaxy collection install process
Nothing to do. All requested collections are already installed. If you want to reinstall them, consider using `--force`.
Docker インストール
Docker のリポジトリをインストールするためのツールをインストールします。
[root@registry ~]# dnf install yum-utils -y
…
インストール済み:
yum-utils-4.0.21-25.el8.noarch
完了しました!
Docker のリポジトリをインストールします。
[root@registry ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
repo の追加: https://download.docker.com/linux/centos/docker-ce.repo
Docker をインストールします。
[root@registry ~]# yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
…
インストール済み:
container-selinux-2:2.229.0-2.module+el8.10.0+1843+6892ab28.noarch containerd.io-1.6.32-3.1.el8.x86_64
docker-buildx-plugin-0.14.0-1.el8.x86_64 docker-ce-3:26.1.3-1.el8.x86_64
docker-ce-cli-1:26.1.3-1.el8.x86_64 docker-ce-rootless-extras-26.1.3-1.el8.x86_64
docker-compose-plugin-2.27.0-1.el8.x86_64 fuse-common-3.3.0-19.el8.x86_64
fuse-overlayfs-1.13-1.module+el8.10.0+1843+6892ab28.x86_64 fuse3-3.3.0-19.el8.x86_64
fuse3-libs-3.3.0-19.el8.x86_64 libcgroup-0.41-19.el8.x86_64
libslirp-4.4.0-2.module+el8.10.0+1843+6892ab28.x86_64 slirp4netns-1.2.3-1.module+el8.10.0+1843+6892ab28.x86_64
tar-2:1.30-9.el8.x86_64
完了しました!
Docker の起動状況を確認します。(→ Docker の自動起動は disabled、現在は inactive(停止中))
[root@registry ~]# systemctl is-enabled docker; systemctl is-active docker
disabled
inactive
Docker の自動起動を enable とし、即時起動します。
[root@registry ~]# systemctl enable docker --now
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.
Docker が起動していることを確認します。
[root@registry ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2024-09-01 13:35:40 JST; 35s ago
Docs: https://docs.docker.com
Main PID: 8503 (dockerd)
Tasks: 8
Memory: 39.7M
CGroup: /system.slice/docker.service
└8503 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
9月 01 13:35:39 registry systemd[1]: Starting Docker Application Container Engine...
9月 01 13:35:39 registry dockerd[8503]: time="2024-09-01T13:35:39.343521801+09:00" level=info msg="Starting up"
9月 01 13:35:39 registry dockerd[8503]: time="2024-09-01T13:35:39.406922385+09:00" level=info msg="Loading containers: start."
9月 01 13:35:40 registry dockerd[8503]: time="2024-09-01T13:35:40.077493387+09:00" level=info msg="Loading containers: done."
9月 01 13:35:40 registry dockerd[8503]: time="2024-09-01T13:35:40.098389387+09:00" level=info msg="Docker daemon" commit=8e96db1 containerd-snapshotter=false stora>
9月 01 13:35:40 registry dockerd[8503]: time="2024-09-01T13:35:40.098597754+09:00" level=info msg="Daemon has completed initialization"
9月 01 13:35:40 registry dockerd[8503]: time="2024-09-01T13:35:40.163326594+09:00" level=info msg="API listen on /run/docker.sock"
9月 01 13:35:40 registry systemd[1]: Started Docker Application Container Engine.
SSH 用キーの配置
のちほど起動するコンテナの OS(linux)のカスタマイズ(アプリのインストール等)は Ansible で自動化します。カスタマイズ時、Ansible はコンテナの OS に SSH公開鍵認証で接続します。
レジストリサーバに鍵が作成されていない場合は ssh-keygen コマンドで作成してください。
以下のファイル(id_rsa:秘密鍵、id_rsa.pub:公開鍵)は root アカウントで ssh-keygen コマンドを実行し作成したときの鍵です。コマンド実行時のパラメータ指定は全てデフォルト(未指定)です。また、アクセス権を緩めると SSH 接続時に失敗する可能性がありますのでご注意ください。
[root@registry ~]# ls -la ~/.ssh
合計 8
drwx------. 2 root root 38 9月 4 13:23 .
dr-xr-x---. 5 root root 225 9月 4 13:14 ..
-rw-------. 1 root root 3247 6月 18 14:16 id_rsa
-rw-r--r--. 1 root root 742 6月 18 14:16 id_rsa.pub
プール作成
registry コンテナはプールした Docker イメージをコンテナ内の /var/lib/registry 配下に保存します。そのため、registry コンテナを削除するとプールしたイメージも消えてしまいます。Docker ではコンテナのディレクトリを外部ディスクにマウントすることで、コンテナ削除後もデータを残すことが可能です。本設定では registry コンテナ内の /var/lib/registry をコンテナのホストであるレジストリサーバのディスクにマウントします。
レジストリサーバにマウント先のディレクトリを作成します。
[root@registry ~]# mkdir /registry
[root@registry ~]#
以下のコマンドで registry イメージからコンテナを起動します。registry イメージがレジストリサーバに存在しない場合、先に registry イメージが Docker HUB からダウンロードされます。-v のオプションで registry コンテナ内の /var/lib/registry をレジストリサーバの /registry にマウントしています。
[root@registry ~]# docker run -d -p 5000:5000 -v /registry:/var/lib/registry --name registry registry:2
Unable to find image 'registry:2' locally
2: Pulling from library/registry
930bdd4d222e: Pull complete
a15309931e05: Pull complete
6263fb9c821f: Pull complete
86c1d3af3872: Pull complete
a37b1bf6a96f: Pull complete
Digest: sha256:12120425f07de11a1b899e418d4b0ea174c8d4d572d45bdb640f93bc7ca06a3d
Status: Downloaded newer image for registry:2
a72f7529596adb78eebcbaa97b0e3e92e1773db0fc86ee10e14d97baeec694fd
レジストリサーバにダウンロードされている registry イメージを確認します。
[root@registry ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2 cfb4d9904335 11 months ago 25.4MB
registry コンテナの起動状況を確認します。
[root@registry ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a72f7529596a registry:2 "/entrypoint.sh /etc…" 30 seconds ago Up 28 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry
プールにイメージを登録
プールに登録するイメージを作成
本環境では2つのイメージを作成しプールします。(下表参照)
名前 | ベースとなるイメージ (*1) | インストールするアプリ | 役割 |
---|---|---|---|
r8bind | rockylinux:8.8 | BIND | DNS Server |
r8stub | rockylinux:8.8 | dnsperf、kdig 等 | Client |
ベースとなるイメージのダウンロードと OS の最低限の設定 (*2) についての手続きは Dockerfile に定義します。アプリのインストールおよびコンフィグ設定は Ansible で自動化します。
*1 Docker HUB から自動的にダウンロードされます。
*2 基本ツールのインストール、アカウント設定、SSH接続設定など。
イメージ作成のおおまかな流れは以下のとおりです。
- Dockerfile の定義に基づきコンテナの起動と最低限の設定を行う (*3)
- Ansible でコンテナをカスタマイズ(アプリのインストール等)する
- カスタマイズ済みのコンテナからイメージを作成する
*3 本設定では docker compose コマンドでコンテナを起動します。docker compose コマンドには YAML 形式の定義ファイルをオプションとして指定します。YAML ファイル内には Dockerfile のパスが指定されており、docker compose コマンドは間接的に Dockerfile を読み込みます。
以降の手順 (*4) では /home/docker をカレントディレクトリとして作業を行っています。(*5)
*4 ここでは Docker および Ansible の学習を目的としているわけではないため、仕様の細かい説明は行わない予定です。インターネット上に詳しい情報があると思いますのでそちらをご参照ください。
*5 docker アカウントを作成しているわけではありません。単に /home の下に docker ディレクトリを作成しているだけです。
docker compose コマンドで r8bind と r8stub のコンテナを起動します。(*6)
*6 コンテナの起動元のイメージがレジストリサーバに存在しない場合、先に Docker HUB からダウンロードされます。
[root@registry docker]# docker compose -f ./compose_bind.yml up -d
WARN[0000] /home/docker/compose_network.yml: `version` is obsolete
WARN[0000] /home/docker/compose_bind.yml: `version` is obsolete
…
? Network net01 Created 0.2s
? Container r8bind Started 0.4s
[root@registry docker]# docker compose -f ./compose_mob.yml up -d
WARN[0000] /home/docker/compose_network.yml: `version` is obsolete
WARN[0000] /home/docker/compose_mob.yml: `version` is obsolete
…
? Container r8stub Started 0.5s
ダウンロードされたイメージを確認します。
[root@registry docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
r8bind latest 1ea1463cf211 About an hour ago 1.06GB
r8stub latest d2f47b50190b About a minute ago 1.06GB
registry 2 cfb4d9904335 11 months ago 25.4MB
コンテナの起動状況を確認します。
[root@registry docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7d480dedbff r8stub "/sbin/init" About a minute ago Up About a minute 0.0.0.0:2220->22/tcp, :::2220->22/tcp r8stub
cf22808e34f9 r8bind "/sbin/init" About an hour ago Up About an hour 0.0.0.0:2210->22/tcp, :::2210->22/tcp r8bind
a72f7529596a registry:2 "/entrypoint.sh /etc…" 22 hours ago Up 22 hours 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry
コンテナの起動は docker compose コマンドで行いますが、どのようなコンテナかは -f オプションに指定するYAML 形式のファイルで定義づけられます。本環境では、compose_bind.yml により r8bind(DNS Server)が、compose_mob.yml で r8stub(Client)が起動するように定義しています。ただし、compose_bind.yml と compose_mob.yml は同じ Dockerfile を使用しているため、起動するコンテナは IP アドレス、ホスト名等を除けばほぼ違いはありません。それぞれの固有の設定は、のちほど Ansible で行います。
コンテナ起動用に用意した定義ファイルを以下に示します。
ファイル (*7) | 内容 |
---|---|
./compose_bind.yml | r8bind(DNS Server)起動用の定義ファイル |
./compose_mob.yml | r8stub(Client)起動用の定義ファイル |
./compose_network.yml | コンテナが接続する LAN の定義ファイル |
./dockerfiles/rocky8/Dockerfile | Rocky8 をベースとした OS の基本設定が定義されたファイル |
./dockerfiles/rocky8/id_rsa | |
./dockerfiles/rocky8/id_rsa.pub | |
./dockerfiles/rocky9/Dockerfile | Rocky9 をベースとした OS の基本設定が定義されたファイル (*8) |
./dockerfiles/rocky9/id_rsa | |
./dockerfiles/rocky9/id_rsa.pub |
*7 ファイルおよびディレクトリは /home/docker からの相対パスです。
*8 起動するコンテナ(r8bind、r8stub)はいづれも Rocky8 をベースとしているため、こちら(Rocky9用)の Dockerfile は本環境では使用していません。
compose_network.yml は docker compose コマンドの -f オプションで指定することはありませんが、compose_bind.yml と compose_mob.yml から include されているため、間接的に読み込まれます。compose_network.yml には、コンテナが接続する LAN(net01:172.18.1.0/24、net02:172.18.2.0/24)が定義されています。
id_rsa と id_rsa.pub はそれぞれ、SSH公開鍵認証で使用する秘密鍵と公開鍵です。のちほど Ansible でコンテナをカスタマイズする際、SSH公開鍵認証で接続します。そのため前述の「SSH 用キーの配置」でホストサーバ(レジストリサーバ)に配置したものと同じ鍵をコンテナにも配置する必要があります。Dockerfile には、これらの鍵をコンテナ OS 内の所定のディレクトリに配置するための手続きが定義されています。
各ファイルの内容について簡単に説明します。(compose_mob.yml の内容は、compose_bind.yml と同等のため説明は割愛させていただきます。)
compose_bind.yml
version: '3' << [1]
services:
r8bind:
image: r8bind <<イメージ化した際のイメージ名
container_name: r8bind <<コンテナ名
hostname: r8bind <<コンテナで起動する OS のホスト名
privileged: true
build:
context: ./dockerfiles/rocky8/ <<Dockerfile の配置場所
dockerfile: Dockerfile <<Dockerfile の名前
…
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
- /home/docker/vol/r8bind:/home/docker/files:rw << [2]
…
ports:
- "2204:22" <<ポート指定 [3]
networks:
net01:
ipv4_address: 172.18.1.4 <<コンテナOS へ割り当てられる IPアドレス
ipv6_address: fd00::4
priority: 1000
include:
- ./compose_network.yml <<LAN の定義ファイルを include [4]
[1] Docker Compose v2 以降は version: 指定は非推奨らしいです。docker compose コマンド実行時の警告メッセージは無視でかまいませんが、煩わしい場合はこの指定を削除(もしくはコメント化)してください。
[2] コンテナ OS の /home/docker/files を レジストリサーバの /home/docker/vol/r8bind にマウントしています。このディレクトリを介してコンテナ OS とレジストリサーバのデータの受け渡しが可能です。また、このディレクトリにデータを保存することで、コンテナ削除後もデータを残すことが可能です。
[3] ホスト OS とコンテナ OS のポートをつなぐための指定ですが、本設定では SSH ポート(22)を接続しています。外部からレジストリサーバの 2204 ポートへ接続すると、コンテナ OS の 22 ポートへ SSH 接続されます。
[4] コンテナが接続する LAN が定義されたファイルを include しています。include せずに compose_network.yml の内容をここに直接展開しても問題ありません。
compose_network.yml
version: '3'
networks:
net01:
name: net01 <<ネットワーク名
driver: bridge <<ブリッジネットワークの指定 [1]
enable_ipv6: true <<IPv6 通信の有効化
ipam:
driver: default
config:
- subnet: "172.18.1.0/24" <<サブネットの指定(IPv4)
gateway: "172.18.1.1" <<ゲートウェイの指定(IPv4)
- subnet: "fd00::/64" <<サブネットの指定(IPv6)
gateway: "fd00::1" <<ゲートウェイの指定(IPv6)
net02:
…
[1] 同じブリッジネットワークに接続するコンテナ間では通信が可能です。
Dockerfile
FROM rockylinux:8.8 <<Docker HUB からダウンロードするイメージ
…
RUN dnf update -y <<パッケージ更新や基本ツールのインストール
RUN dnf install -y epel-release
…
ENV ssh_pub id_rsa.pub <<SSH公開鍵認証のための設定
…
RUN echo ${root_password} | passwd --stdin root <<root のパスワード設定
# disable DNS lookup
RUN sed s/.*UseDNS.*/"UseDNS no"/ -i /etc/ssh/sshd_config <<SSH 用の設定
VOLUME [ "/sys/fs/cgroup" ]
#ENTRYPOINT ["/sbin/init"]
CMD ["/sbin/init"] <<開始プロセス [1]
[1] linux では最初のプロセスとして init を起動し、そこから OS に必要なプロセスを順次起動します。CMD に別のコマンドを指定した場合、そのコマンドで起動されるプロセス専用のコンテナとなります。
Docker コンテナは本来、機能特化した環境を作ることを目的としているようです。例えば、Web 専用、DNS 専用、のような感じです。単一機能に必要なアプリやライブラリ、リソースをコンテナに集約・独立させることで、ホスト OS や他のコンテナのアップデート等による影響を低減させています。
本環境のコンテナは、一般的な OS 起動と同じく init プロセスを最初に起動させます。
次に Ansible でコンテナのカスタマイズを行います。
対象コンテナが hosts に登録されていることを確認します。
[root@registry docker]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.18.1.4 r8bind
172.18.1.30 r8stub
対象コンテナの SSH キーが known_hosts に登録済みの場合、Ansible が対象コンテナへ接続する際にエラーとなるため、予め削除しておきます。
[root@registry docker]# vi ~/.ssh/known_hosts
ansible-playbook コマンドで r8bind と r8stub のカスタマイズを実行します。
[root@registry docker]# ansible-playbook -i inventory.ini r8bind_main.yml
PLAY [r8bind] ********************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************
The authenticity of host 'r8bind (172.18.1.4)' can't be established.
ECDSA key fingerprint is SHA256:AE0HpbyDKGU2VntPAM25x/0owRxEss0iH0zBAFdE2K8.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes <yesを回答すると~/.ssh/known_hostsにキーが登録される
…
PLAY RECAP ***********************************************************************************************************************
r8bind : ok=14 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@registry docker]# ansible-playbook -i inventory.ini r8stub_main.yml
PLAY [r8stub] ********************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************
The authenticity of host 'r8stub (172.18.1.30)' can't be established.
ECDSA key fingerprint is SHA256:J8y2zFOOhbXzSES86aWr2RaR7GZLijJMIOmosSUPfjs.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
…
PLAY RECAP ***********************************************************************************************************************
r8stub : ok=12 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
カスタマイズは ansible-playbook コマンドで実行しますが、そのオプションにスクリプトファイルを指定します。r8bind のカスタマイズには r8bind_main.yml を、r8stub のカスタマイズには r8stub_main.yml を指定しています。
カスタマイズの内容が定義されているファイルを以下に示します。
ファイル (*9) | 内容 |
---|---|
./inventory.ini | 操作対象のノードのリスト |
./r8bind_main.yml | r8bind カスタマイズ用スクリプトの開始ファイル |
./r8stub_main.yml | r8stub カスタマイズ用スクリプトの開始ファイル |
./group_vars/all.yml | 環境変数が登録されたファイル |
./roles/install_bind/ | r8bind のカスタマイズに必要なファイルが置かれたディレクトリ |
./roles/install_bind/files/com.zone | BIND 用のコンフィグファイルとゾーンファイル |
./roles/install_bind/files/jp.zone | 〃 |
./roles/install_bind/files/named.conf | 〃 |
./roles/install_bind/files/root.zone | 〃 |
./roles/install_bind/files/test.co.jp.zone | 〃 |
./roles/install_bind/files/test.com.zone | 〃 |
./roles/install_bind/handlers/main.yml | notify イベントで起動するハンドラーが登録されているファイル |
./roles/install_bind/tasks/install_bind.yml | BIND をインストールするスクリプト |
./roles/install_bind/tasks/main.yml | install_bind.yml を呼び出すスクリプト |
./roles/setup_os/ | OS のカスタマイズに必要なファイルが置かれたディレクトリ |
./roles/setup_os/tasks/main.yml | setup_os.yml を呼び出すスクリプト |
./roles/setup_os/tasks/setup_os.yml | OS 共通設定用のスクリプト |
./roles/setup_os/templates/gai.conf.j2 | IPv4優先するコンフィグのテンプレート |
./roles/setup_os/templates/resolv.conf.j2 | resolv.conf のテンプレート(本設定では未使用) |
./roles/setup_stub/ | r8stub のカスタマイズに必要なファイルが置かれたディレクトリ |
./roles/setup_stub/tasks/main.yml | setup_stub.yml を呼び出すスクリプト |
./roles/setup_stub/tasks/setup_stub.yml | dnsperf 等のツールをインストールするスクリプト |
*9 ファイルおよびディレクトリは /home/docker からの相対パスです。
r8bind_main.yml と r8stub_main.yml 以外のスクリプトはこれらのスクリプトから順次呼び出されます。以下にコーリングシーケンスを示します。
r8bind_main.yml
→./roles/setup_os/tasks/main.yml
→./roles/setup_os/tasks/setup_os.yml
→./roles/install_bind/tasks/main.yml
→./roles/install_bind/tasks/install_bind.yml
r8stub_main.yml
→./roles/setup_os/tasks/main.yml
→./roles/setup_os/tasks/setup_os.yml
→./roles/setup_stub/tasks/main.yml
→./roles/setup_stub/tasks/setup_stub.yml
各ファイルの内容について簡単に説明します。(一目瞭然のファイルについては割愛させていただきます。)
setup_os.yml
---
- name: set timezone to Asia/Tokyo <<TimeZone設定
become: true
community.general.timezone:
name: Asia/Tokyo
- name: prefer ipv4 over ipv6 on system wide <<IPv4優先のコンフィグをテンプレートから作成し
become: true <<コンテナ OS に配置
ansible.builtin.template:
src: gai.conf.j2
dest: /etc/gai.conf
owner: root
group: root
mode: 0644
backup: yes
# when: prefer_ipv4_over_v6_system_wide
install_bind.yml
---
- name: install bind << dnf で BIND をインストール
become: true
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop:
- bind
- name: start bind <<systemd で named.service を起動
become: true
ansible.builtin.systemd:
state: started
name: "{{ item }}"
enabled: true
loop:
- named.service
- name: copy named.conf and zone file <<BIND のコンフィグ&ゾーンファイルを
block: <<コンテナにコピー
- name: copy named.conf
become: true
ansible.builtin.copy:
src: named.conf
dest: /etc/named.conf
owner: root
group: named
mode: '0640'
backup: yes
…
notify: reload named <<named プロセスを再起動(ハンドラー起動)
setup_stub.yml
---
- name: install dnsperf and kdig <<dnf で dnsperf と kdig(knot-utils)をインストール
become: true
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop:
- dnsperf
- knot-utils
- name: preparate to install Metasploit <<Metasploit をインストール
become: true
ansible.builtin.shell:
cmd: "curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > /tmp/msfinstall"
register: result
- debug: msg="{{ result.stdout_lines }}"
…
- name: install scapy <<scapy をインストール
become: true
ansible.builtin.shell:
cmd: "python3 -m pip install scapy"
register: result
- debug: msg="{{ result.stdout_lines }}"
カスタマイズ後のコンテナでコマンド(uname -a と ps)を実行し、問題ないことを確認します。
[root@registry docker]# docker exec -it r8bind uname -a;ps
Linux r8bind 4.18.0-553.16.1.el8_10.x86_64 #1 SMP Thu Aug 8 17:47:08 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
PID TTY TIME CMD
10137 pts/0 00:00:00 bash
26309 pts/0 00:00:00 ps
[root@registry docker]# docker exec -it r8stub uname -a;ps
Linux r8stub 4.18.0-553.16.1.el8_10.x86_64 #1 SMP Thu Aug 8 17:47:08 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
PID TTY TIME CMD
10137 pts/0 00:00:00 bash
26332 pts/0 00:00:00 ps
カスタマイズ済みのコンテナからプール登録用のイメージを作成します。
[root@registry docker]# docker commit r8bind localhost:5000/r8bind
sha256:1ad1dad765ea4a2d4390938ff342b3aaaf0e030714500e21c09df8560673047c
[root@registry docker]# docker commit r8stub localhost:5000/r8stub
sha256:5eb1968e9c85ead86816404f2ac993c86f6633aa0756a3a0728150331d978a72
新たに作成したイメージを確認します。
[root@registry docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost:5000/r8stub latest 5eb1968e9c85 38 seconds ago 2.13GB
localhost:5000/r8bind latest 1ad1dad765ea 39 minutes ago 1.19GB
r8bind latest 1ea1463cf211 2 hours ago 1.06GB
r8stub latest d2f47b50190b 2 hours ago 1.06GB
registry 2 cfb4d9904335 11 months ago 25.4MB
イメージをプールに登録
作成したイメージ(localhost:5000/r8bind, localhost:5000/r8stub)をプールに登録します。
[root@registry docker]# docker push localhost:5000/r8bind
…
121bf763d994: Pushed
964fc91a3863: Pushed
latest: digest: sha256:a19bb7ce8d3631fd8dc32540117046946d5357b9ad06d8cd1a991c9a3b062a6b size: 8074
[root@registry docker]# docker push localhost:5000/r8stub
…
121bf763d994: Mounted from r8bind
964fc91a3863: Mounted from r8bind
latest: digest: sha256:8357a1c13dc253e51fde284a3185dd0b08ba74d09c639c816bed1876d99eab8e size: 8075
プールに登録したイメージを確認します。
[root@registry docker]# curl -s http://localhost:5000/v2/_catalog | jq
{
"repositories": [
"r8bind",
"r8stub"
]
}
不要なコンテナおよびイメージの削除
プールへの登録元のイメージおよびコンテナは不要となります。ディスク容量節約のため削除します。
コンテナを停止します。
[root@registry docker]# docker stop r8bind r8stub
r8bind
r8stub
コンテナを削除します。
[root@registry docker]# docker rm r8bind r8stub
r8bind
r8stub
イメージを削除します。
[root@registry docker]# docker rmi localhost:5000/r8stub localhost:5000/r8bind
Untagged: localhost:5000/r8stub:latest
Untagged: localhost:5000/r8stub@sha256:8357a1c13dc253e51fde284a3185dd0b08ba74d09c639c816bed1876d99eab8e
Deleted: sha256:5eb1968e9c85ead86816404f2ac993c86f6633aa0756a3a0728150331d978a72
Deleted: sha256:d8c54a9be9e1d8731bf8260de859075e1fcd87d6952570d9e2247487dd003d1a
Untagged: localhost:5000/r8bind:latest
Untagged: localhost:5000/r8bind@sha256:a19bb7ce8d3631fd8dc32540117046946d5357b9ad06d8cd1a991c9a3b062a6b
Deleted: sha256:1ad1dad765ea4a2d4390938ff342b3aaaf0e030714500e21c09df8560673047c
Deleted: sha256:fd569ad8a0073eb5ef7a7cc26cb1665e5bd79be390f37b81f198fc6625f65301
[root@registry docker]# docker rmi r8stub r8bind
Untagged: r8stub:latest
Deleted: sha256:d2f47b50190bcca11f1e83ad1e32170425a0365ccb299e5f732d7889ddd549a9
Untagged: r8bind:latest
Deleted: sha256:1ea1463cf2119337a210395d98793495d2ea267308ae880e6eed6d2703a2dabc
不要なオブジェクトを削除します。(コンテナ削除後、net01 ネットワークはどこからも参照されなくなるため削除対象となります)
[root@registry docker]# docker system prune
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- unused build cache
Are you sure you want to continue? [y/N] y
Deleted Networks:
net01
…
Total reclaimed space: 862.9MB
プールに登録済みのイメージを削除
プールにイメージを再登録する場合は、事前に古いイメージをプールから削除する必要があります。手順について以下に示します。
registry コンテナを環境変数(REGISTRY_STORAGE_DELETE_ENABLED=true)付きで再起動します。
registry コンテナの起動状況を確認します。
[root@registry docker]# docker ps -f name=registry
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a72f7529596a registry:2 "/entrypoint.sh /etc…" 2 days ago Up 2 days 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry
registry コンテナの停止と削除。
[root@registry docker]# docker stop registry
registry
[root@registry docker]# docker rm registry
registry
registry コンテナを再起動します。
[root@registry docker]# docker run -d -p 5000:5000 -e REGISTRY_STORAGE_DELETE_ENABLED=true -v /registry:/var/lib/registry --name registry registry:2
8c045932271502a6f1006c64ac89eb1cfac45bbfcc104f94b71bfebdd50e2233
プールに登録済みのイメージを確認します。(以降の手順で r8bind を削除します)
[root@registry docker]# curl -s http://localhost:5000/v2/_catalog | jq
{
"repositories": [
"r8bind",
"r8stub"
]
}
r8bind イメージのダイジェストを確認します。
[root@registry docker]# curl -i -H "Accept: application/vnd.docker.distribution.manifest.v2+json" http://localhost:5000/v2/r8bind/manifests/latest | grep Docker-Content-Digest
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 8074 100 8074 0 0 606k 0 --:--:-- --:--:-- --:--:-- 606k
Docker-Content-Digest: sha256:a19bb7ce8d3631fd8dc32540117046946d5357b9ad06d8cd1a991c9a3b062a6b
r8bind イメージ(のマニフェスト?)を削除します。
[root@registry docker]# curl -X DELETE -D - http://localhost:5000/v2/r8bind/manifests/sha256:a19bb7ce8d3631fd8dc32540117046946d5357b9ad06d8cd1a991c9a3b062a6b
HTTP/1.1 202 Accepted
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Fri, 01 Sep 2024 04:33:44 GMT
Content-Length: 0
r8bind イメージの実態を削除します。
[root@registry docker]# rm -rf /registry/docker/registry/v2/repositories/r8bind
[root@registry docker]#
参考:イメージの実態の削除(別の方法)
イメージの実態の削除は、registry コンテナにログインして行うこともできます。
[root@registry docker]# docker exec -it registry sh
/ # ls /var/lib/registry/docker/registry/v2/repositories
r8bind r8stub
/ # rm -rf /var/lib/registry/docker/registry/v2/repositories/r8bind
/ #
registry コンテナを再起動します。
[root@registry docker]# docker restart registry
registry
registry コンテナが起動していることを確認します。
[root@registry docker]# docker ps -f name=registry
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8c0459322715 registry:2 "/entrypoint.sh /etc…" 24 minutes ago Up 20 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry
イメージ(r8bind)が削除されていることを確認します。
[root@registry docker]# curl -s http://localhost:5000/v2/_catalog | jq
{
"repositories": [
"r8stub"
]
}
補足:コンテナへの IP アドレスの追加
コンテナに IP アドレスを追加する例を示します。以下は r8bind コンテナに IPv4 と IPv6 を追加するコマンドです。
docker exec r8bind ip addr add 172.18.1.5/24 dev eth0
docker exec r8bind ip addr add fd00::5/64 dev eth0