本記事は
マイグレーションウィーク
2日目の記事です。
💻🖥
1日目
▶▶ 本記事 ▶▶
3日目
🖥💻
はじめに
ドーモ、ウキタです。 皆さん、Jenkins使っていますか? 今回は、EC2を使っている上で避けては通れないOSのEOLによるJenkins移行の話しをしていきます。
移行した背景
CI/CDを実現するのにEC2(CentOS 7)でJenkinsを利用しています。 CentOS 7のサポート終了(2024年6月30日)*1に伴い、CentOS 7でのJenkinsの実行が2023年11月16日にサポートされなくなりました。 そのため、CentOS 7で動いていたJenkinsを別サーバへ移行しました。
After Nov 16, 2023, the Jenkins project will no longer support running Jenkins on Red Hat Enterprise Linux 7 or any of its derivatives.
引用)https://www.jenkins.io/blog/2023/05/30/operating-system-end-of-life/
事前調査
現行構成の把握
ALB + EC2のシンプルな構成で、EC2が1台のみ起動しています。 ACMで発行された証明書をALBに設定しており、特定の開発者のみがアクセスできるようにALBのセキュリティグループでアクセス制御をしています。
開発者がhttps:// hogehogeを叩くと、ALBを経由しEC2にあるJenkinsへアクセスします。
現行設定の確認
2017年頃ChefでJenkinsサーバーが構築されて以来、ほとんどコードによる管理がされていませんでした。 また、Jenkinsに関する資料も存在しなかったので、EC2へログインし地道に内容を確認していきます。
OS周り
一般的にLinuxに設定するであろう項目を確認します。
確認項目 | コマンド |
---|---|
ホスト名 | hostname |
ユーザ | cat /etc/passwd |
グループ | cat /etc/group |
SELinux | getenforce もしくは sestatus |
タイムゾーン | timedatectl |
ロケーション、キーボードキーレイアウト | localectl status |
bashrcやbash_profileを確認 | cat /etc/bashrc cat /etc/profile cat /path/to/.bashrc cat /path/to/.bash_profile |
サービス周り
使っているサービスを洗い出します。 ChefのコードやJenkinsジョブで叩かれているコマンド、cloud-initの設定ファイルの確認を忘れないようにしましょう。
確認項目 | コマンド |
---|---|
インストールされたパッケージ | yum list installed |
稼働しているサービス | systemctl list-units --type=service |
自動起動するサービス | systemctl list-unit-files -t service | grep enabled |
稼働しているプロセス | ps axf |
Jenkinsや監視・運用で使っているパッケージのconfを確認 | cat /path/to/xxx.conf |
Jenkinsデータの移行方法を調査
Jenkinsジョブやプラグイン、クレデンシャルをどのように移行するか迷っていましたが、別プロジェクトでJenkinsのホームディレクトリを丸々コピーしてデータを移行していたので、同じ方法を採用しました。
移行先OSの調査
Red Hat Enterprise LinuxのABI(Application Binay Interface)互換を目指すAlmaLinux*2やRocky Linux*3, AWSが提供しているAmazon Linux 2023*4が移行先の主な候補でした。 AlmaLinuxとRocky Linuxは、他プロジェクトでの利用経験がないため候補から除外しました。 最終的に、Amazon Linuxの方がAWSの継続的なサポートを見込めるということで、Amazon Linux 2023を移行先に選びました。
AlmaLinuxやRocky Linuxだと移行ツールあるのになぁ
CentOS 7とAmazon Linux 2023の比較
CentOS 7 | Amazon Linux 2023 | |
---|---|---|
ベースOS | Red Hat Enterprise Linux | Fedora |
サポート期限 | 2024年6月30日 | 2028年3月15日 |
デフォルトユーザ | centos | ec2-user |
パッケージ管理ツール | yum | dnf |
SELinux | Enforcing(移行元ではDisabledモードを使用) | Permissive*5 |
ロギング | journald(移行元ではrsyslogを使用) | journald |
スケジューリング | systemd timer(移行元ではcronを使用) | systemd timer |
移行元のCentOS 7ではrsyslogを使っていましたが、ログを転送する要件がないことやログのサイズが小さいこと、頻繁にログを確認しないことからjournaldを採用しました。 journaldのログはデフォルトで揮発しますが、/var/log/journalディレクトリが存在する場合、ログは永続化します。 ログのサイズはデフォルトでファイルシステム容量の10%(4GBが上限)に制限され、これを超えると古いログが削除されるので注意が必要です。 Amazon Linux 2023ではjournalディレクトリが存在する*6ので、ログは永続化されます。
また、Amazon Linux 2023では、リポジトリバージョンによりパッケージが特定のバージョンに固定されています。
そのため、今までのようにdnf update
を叩いてもインストール済みパッケージをアップデートすることはできません。
アップデートしたい場合は、dnf upgrade --releasever=<リポジトリバージョン>
を叩きます。
最後に、Amazon Linux は、柔軟で一貫性のある更新メカニズムである、バージョニングされたリポジトリを通じた決定論的更新を提供します。これは、断然私のお気に入りのポリシーです。ディストリビューションは Amazon Linux パッケージリポジトリの特定のバージョンにロックされるため、更新を適用する方法とタイミングを制御できます。
方針
データ移行
今回はJenkinsのデータを別サーバへ移行したかっただけなので、ドメインやALBは既存のものを流用します。 移行前後で整合性を保つため、Jenkinsを停止してデータを移行します。
また、移行後に動作確認をするため、EC2(Amazon Linux 2023)用のリスナーとターゲットグループを作成しEC2(Amazon Linux 2023)を登録します。 ALBにアタッチしたセキュリティグループのインバウンドルールでHTTPS:8080を開放し、EC2(Amazon Linux 2023)側のJenkinsへアクセスできるようにします。
切り替え
切り替え時にサービス停止しても問題ないので、ターゲットグループのインスタンス登録と解除で切り替えを行います。
EC2へのログイン
今まで踏み台サーバを経由してCentOS 7へログインしていましたが、運用・管理コストがかかっていたので踏み台を廃止して、代わりにSSM Session Managerによるログインへ変更しました。 厳密にはSSM Session Managerはログインしているわけではないのと、デフォルトのシェルはbashではなくshなので、bashrcやbash_profileは読み込まれません。 bashrcやbash_profileで設定した内容が必要な場合は、AWSマネージメントコンソールのセッションマネージャーにあるLinux shell profileに設定を移しましょう。 また、ログインユーザはec2-userではなくssm-userです。
設定を反映
さて、ここから設定をしていきます。
EC2(Amazon Linux 2023)を作成
VPCやサブネット・インスタンスタイプ・IAMロール・キーペアなどEC2(CentOS 7)と同じように設定していき、EC2(Amazon Linux 2023)を作成します。 EC2(CentOS 7)のときはEBSのストレージが暗号化されていなかったので、EC2(Amazon Linux 2023)ではKMSでEBSを暗号化します。
また、SSM Session Managerによるログインをしたいので、EC2(Amazon Linux 2023)にアタッチしたIAMロールにカスタムインラインポリシーを作成します。
以下のドキュメントを参考に作成します。 docs.aws.amazon.com
ポリシーの例)
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Action": "ssm:StartSession", "Resource": "arn:aws:ec2:<リージョン>:<アカウントID>:instance/*" }, { "Sid": "", "Effect": "Allow", "Action": [ "ssm:GetConnectionStatus", "ssm:DescribeSessions", "ssm:DescribeInstanceProperties", "ec2:DescribeInstances" ], "Resource": "*" }, { "Sid": "", "Effect": "Allow", "Action": [ "ssm:TerminateSession", "ssm:ResumeSession" ], "Resource": "arn:aws:ssm:*:*:session/${aws:userid}-*" } ] }
OSの設定を行う
EC2(Amazon Linux 2023)へログインし、ホスト名の変更とSELinuxを無効化します。
aws ssm start-session --target i-xxxx hostnamectl set-hostname <ホスト名> grubby --update-kernel ALL --args selinux=0 reboot
パッケージをインストール
Jenkinsとその実行に必要なJavaをインストールします。 OSとJenkinsバージョンの変更を同時に行うと問題があったときの切り分けが大変なので、今回はEC2(CentOS 7)と同じJenkinsとJavaのバージョンをインストールしています。 Jenkinsでコンテナイメージのビルドを行うジョブがあるのでdockerとdocker composeをインストールし、jenkinsユーザとssm-userユーザがdockerコマンドを叩けるようにします。 他にも色々とインストールしていますが割愛します。
dnf install java-11-amazon-corretto // dnfによるJenkinsのインストールも可能だがバージョン管理をしたかったため、以下の方法でインストール // 必要に応じて設定ファイルを更新する rpm -ivh https://get.jenkins.io/redhat-stable/jenkins-2.414.1-1.1.noarch.rpm vim /etc/sysconfig/jenkins systemctl enable jenkins dnf install -y docker usermod -aG docker jenkins usermod -aG docker ssm-user systemctl enable docker mkdir -p /usr/local/lib/docker/cli-plugins curl -SL https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
データ移行
Jenkinsのデータ移行
EC2(Amazon Linux 2023)側の設定が終わったら、EC2(CentOS 7)のJenkinsを停止しデータを移行します。 操作ミスをしても元へ戻せるようにするため、EC2(CentOS 7)のバックアップを取得します。 また、EC2(Amazon Linux 2023)を作成するときに用意したキーペアの秘密鍵をCentOS 7側にコピーします。 必要に応じて秘密鍵の権限を設定してください。
◾️ CentOS 7側での作業
Jenkinsのワークスペースが13GB(デカイ)もあり、移行後に必要ないので削除しました。
今思えば、tarのexcludeオプションを使えばディレクトリを除外できるので、削除しなくてもよかったです。
// ログイン ssh <IPアドレス> // Jenkinsを停止させる systemctl stop jenkins // 移行しても使わないため、Jenkinsのワークスペースより下を全て削除する cd /var/lib/jenkins rm -rf workspace/* // データを圧縮する tar -zcvf /home/centos/jenkins.tar.gz . // データを転送する scp -i /home/centos/.ssh/xxxx.pem /home/centos/jenkins.tar.gz ssm-user@<EC2(Amazon Linux 2023)のプライベートIPアドレス>:/home/ssm-user
◾️ Amazon Linux 2023側での作業
// ログイン aws ssm start-session --target i-xxxx // Jenkinsが起動している場合、停止させる systemctl stop jenkins // データ解凍 cd /home/ssm-user tar xzvf jenkins.tar.gz -C /var/lib/jenkins/ // Jenkins起動 systemctl start jenkins
動作確認
HTTPS:8080でJenkinsのGUIへアクセスし、ログインできるか、ジョブやプラグインが存在するかなどを確認します。 その後、Jenkinsジョブを一通り流して動作確認を行い、エラーが出たら修正します。
CentOS 7からAmazon Linux 2023へ切り替える
EC2(CentOS 7)側のターゲットグループから、EC2(CentOS 7)の登録解除とEC2(Amazon Linux 2023)のインスタンス登録を行います。 ネットワークの経路が変わったので念のため、Jenkinsへログインできるかを確認し簡易なジョブをいくつか流します。 特に問題なければ、切り替え完了です。
後片付け
安定して稼働していることを確認し、不要になったリスナーやターゲットグループ・セキュリティグループのHTTPS:8080・キーペア・EC2(CentOS 7)を削除します。
おわりに
設計書がない状態でJenkinsをCentOS 7からAmazon Linux 2023へ移行しました。 今回は、1からOSの設定やconfの設定を確認していくのが一番大変でした。 こうならないように皆さんはドキュメントを作成しましょう。 とはいえ、久しぶりにLinuxの設定を手動で行い、インフラやってる感があり懐かしかったです。
踏み台廃止については、コストが掛からなくなったことに加え、セキュリティグループのインバウンドにSSHを解放しなくて良くなったためセキュリティが向上しました。 個人的には、AWSマネージメントコンソールから気軽にログインできるようになったことが嬉しかったです。