はじめに
以前の記事でGitLab Runnerからオンプレ環境AAPの設定を行う方法を試しました。
その際、インターネットからオンプレ環境にあるAAPへの通信手段としてCloudflare Zero Tunnelを使い、AAPのWebhookを実行していました。
しかし、この方法ではAAP側にPlaybookを実行するためのジョブテンプレートを用意しておく必要があり、また投入結果をGitLab側から確認することができませんでした。
その後、色々調べてみるとGitLab Runnerをオンプレ環境側に置いてそこから処理できるらしく、今回はGitLab RunnerからPlaybookを実行してAAP設定変更をやってみました。
全体構成は下図のとおり。
特徴としては、GitLab Runnerのexecutorとしてpodmanを利用し、podman-in-podman構成にしてEEによるPlaybook実行環境を構築しています。
環境
AAP
- OS: RHEL 8.6
- AAP: 2.2
- ansible.controller collection: 4.4.0
GitLab Runner
- OS: RHEL9
- GitLab Runner: 16.4.1
構築
GitLab Runnerサーバ構築
まずは、オンプレ環境にGitLab Runnerを構築します。
前提として、SELinuxはdisableにします。
基本的には、GitLab Runnerドキュメントを参考に構築しています。
GitLab Runnerのインストール
以下コマンドでYUMレポジトリを追加します。
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash
その後、dnfコマンドでgitlab-runnerをインストールします。
dnf install gitlab-runner
インストールされると、gitlab-runner
コマンドとユーザが作成されます。
podmanのインストール
以下コマンドより、podmanをインストールします。
dnf install podman
インストールできたら、本来はrootfullモードとしてgitlab-runner
ユーザとしてrootlessモードとしたほうがいいですが面倒なのでpodman.socket
を立ち上げます。
systemctl --now enable podman.socket
GitLab Runner登録
GitLab RunnerとGitLabを紐づけるための設定を行います。
まずは、GitLabでRunnerを利用したイレポジトリにアクセスし、
設定
> CI/CD
> Runner
より新規プロジェクトRunner
を選択します。
ここでは、tagにtokyo
を指定して、ワークフローでタグ指定された際に、当該Runnerを動かすように設定します。
ランナーを作成
を押すと、以下画面が出てGitlab Runnerを登録するためのトークン情報が含まれたコマンドが出力されます。
これを、Runnerサーバで実行すると以下ガイダンスプロンプトが始まります。
ぽちぽち進めていけばいいですが、Enter an executor
はdocker
を選択してください。
# gitlab-runner register --url https://gitlab.com --token ************
Runtime platform arch=amd64 os=linux pid=16918 revision=d89a789a version=16.4.1
Running in system-mode.
Enter the GitLab instance URL (for example, https://gitlab.com/):
[https://gitlab.com]:
Verifying runner... is valid runner=BCiv6Tvms
Enter a name for the runner. This is stored only in the local config.toml file:
[hostname.local]:
Enter an executor: docker-windows, shell, ssh, virtualbox, docker-autoscaler, docker+machine, custom, docker, instance, parallels, kubernetes:
docker
Enter the default Docker image (for example, ruby:2.7):
quay.io/podman/stable
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
podman-in-podman利用するための設定変更
今回実行するパイプラインはpodman-in-podman利用するため、podman上からpodmanを実行するための権限が必要になります。
そのため、設定ファイル(/etc/gitlab-runner/config.toml
)を直接編集する必要があります。
変更箇所としては、privileged
をtrue
にするのみでOK!
concurrent = 1
check_interval = 0
shutdown_timeout = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "hostname.local"
url = "https://gitlab.com"
id = *******
token = "**************"
token_obtained_at = 2023-10-13T13:15:44Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "docker"
[runners.cache]
MaxUploadedArchiveSize = 0
[runners.docker]
tls_verify = false
image = "quay.io/podman/stable"
#privileged = false
privileged = true # ★trueに変更
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
CI/CDパイプラン定義
まずは、CI/CDパイプラインで利用する変数を定義します。
今回は以下のような変数を用意しました。
registryへの認証情報は、Registry Service Accountsを作成して今回のレポジトリ専用のものを入力しました。
-
CONTROLLER_HOST
: AAPのURL -
CONTROLLER_OAUTH_TOLEN
: AAPのadmin権限トークン(事前にAAP側で作成) -
REDHAT_REGISTRY
: registry.redhat.io(EEダウンロードのために利用) -
REDHAT_REGISTRY_USER
: registryへのログインユーザ名 -
REDHAT_REGISTRY_PASSWORD
: registryへのログインパスワード
次にパイプライン本体ですが、以下のとおりです。
workflow:
rules:
- if: $CI_COMMIT_BRANCH == "main"
stages:
- deploy
deploy-aap:
stage: deploy
tags:
- tokyo
image: quay.io/podman/stable:latest
script:
- podman login -u $REDHAT_REGISTRY_USER -p $REDHAT_REGISTRY_PASSWORD $REDHAT_REGISTRY
- dnf install -y python3 python3-pip
- pip install ansible-navigator
- >-
ansible-navigator run configure_aap.yml
--eei registry.redhat.io/ansible-automation-platform-24/ee-supported-rhel8:latest
--penv CONTROLLER_HOST
--penv CONTROLLER_OAUTH_TOKEN
--mode stdout
--pae false
--lf /dev/null
tagsで先ほど作成したRunnerのtagを指定することで実行するRunnerを指定することができます。
AAPを設定変更するために、ansible.controller
コレクションが必要となり二通りを検討しました。
①Automation Hubからコレクションとして取得する
②Red Hat RegistryからAAP用のEEの中にあるものを使う
どちらも、認証が必要となるのですが①は30日利用しないと失効するトークンを使う必要があるので、運用しやすさから②の方法にしました。
EEからの実行となるため、Ansible Navigatorを使ってEEから実行するようにしました。
環境変数はそのままでは使えないのでAAPへの接続情報を--penv
で渡しています。
デフォルトだと、ユーザインターフェースモードがinteractive
となり、Runnerではエラーとなってしまうので--mode stdout
にしています。
あとは、出力されるファイルをゼロにするためオプションを追加しています。
実行結果
レポジトリのmainにpushすると、パイプラインが実行され、オンプレ側のGitLab Runnerから実行されました。
特に、CPU負荷も上がらず実行完了。
時間についても、通常のGitLab Runnerを使うぐらいのスピードで
- 実行準備~実行開始:10秒
- 実行開始~Ansible Navigator準備:180秒
- Playbook実行:100秒
と大体4分程度で実行完了しました。
Playbookログも色付きで出力されるので証跡としても十分使いやすくなりました。
おわりに
GitLab Runnerでpodmanを使う方法ですが以前はドキュメントになく、トリッキーな方法でしたがGitLab 15.3で方法追加されたようでかなり使いやすくなったみたいです。
podman-in-podmanはとても便利で、使い方次第ではなんでもできると感じたので使い方を探っていきたいと思います。
セキュリティ的にも外向きに穴をあけるわけでもないので十分堅牢かと思うので今後もGitLab Runnerを活用したいと思います。
ただ、rootless podman使っていないのは個人的には気になるのでそこは今後修正します。
参考リンク