🍖

GitLab Runnerが動かなくなってCI/CDが壊滅した話

2025/01/07に公開

事の発端

年末に掛けて身辺整理をするに当たり、社内で運用しているセルフホスティングのGitLabのアップデートを実施した。

cat /opt/gitlab/version-manifest.txt | grep gitlab-ctl
gitlab-ctl                     17.6.2                                     
gitlab-ctl-ee                  17.6.2     

うんうん、2024年も終わり、お疲れ様でした〜ん。

年明け

社内エンジニア「なんかCIがコケちゃうんですよね〜タイムアウトしちゃって...」

えぇ...該当のジョブをチェックしてみる。

Running with gitlab-runner 15.6.0 (b8468294)
  on ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal XXXXX_
  feature flags: FF_USE_FASTZIP:true
Preparing the "docker+machine" executor
07:52
ERROR: Preparation failed: exit status 1
Will be retried in 3s ...
ERROR: Preparation failed: exit status 1
Will be retried in 3s ...
ERROR: Preparation failed: signal: terminated
Will be retried in 3s ...
ERROR: Job failed (system failure): signal: terminated

あ?gitlab-runner 15.6.0

あ、やっべぇrunnerの方アプデしてねぇから?

GitLabのバージョニングポリシーでは:

同じメジャーバージョン内での互換性は保証される
GitLab RunnerはGitLabより2つ前のメジャーバージョンまでサポート

あれ、それじゃ17と15だからまだセーフじゃないのか
ってことではなくてアップデートしてない時点でもうダメなんよな。

対応しなきゃ

GitLab runnerサーバに入って段階的にアップデートを実施。

yum install gitlab-runner-15.6.0-1
⋮
yum install gitlab-runner-17.6.1-1

エグいて。
コレ自体はなんてことないけど問題は

gitlab-runner restart

頼む...!

systemctl status gitlab-runner -l
● gitlab-runner.service - GitLab Runner
   Loaded: loaded (/etc/systemd/system/gitlab-runner.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2025-01-07 12:37:14 JST; 29s ago
 Main PID: 5698 (gitlab-runner)
    Tasks: 24
   Memory: 34.0M
   CGroup: /system.slice/gitlab-runner.service
           ├─5698 /usr/bin/gitlab-runner run --config /etc/gitlab-runner/config.toml --working-directory /home/gitlab-runner --service gitlab-runner --user gitlab-runner
           ├─5761 docker-machine --bugsnag-api-token=no-report stop runner-t1pxlfmx-gitlab-job-1736220969-f1ed3b35
           └─5766 /usr/local/bin/docker-machine

gitlab-runner[5698]: Processing runner                
gitlab-runner[5698]: Acquiring executor from provider 
gitlab-runner[5698]: Docker Machine Details           
gitlab-runner[5698]: Failed to process runner         
gitlab-runner[5698]: Feeding runners to channel       
gitlab-runner[5698]: Feeding runner to channel        
gitlab-runner[5698]: Processing runner                
gitlab-runner[5698]: Acquiring executor from provider 
gitlab-runner[5698]: Docker Machine Details           
gitlab-runner[5698]: Failed to process runner         

ダメっぽいですね...

docker-machine ls
NAME                                         ACTIVE   DRIVER      STATE     URL                       SWARM   DOCKER    ERRORS
runner-t1pxlfmx-runner-00000000-0000000   -        amazonec2   Running   tcp://xxx.xxx.xxx.xxx:2376           Unknown   Unable to query docker version: Cannot connect to the docker engine endpoint

あかん。

原因を探る

AWSのマネコンを見るとrunnerがジョブサーバを立ち上げているのは確認出来る

docker-machine lsによるマシン状態を確認してると一定時間置きに起動と停止を繰り返している模様
(マネコンを見てるとEC2が次々作られては消えていった...)

root@gitlab-runner [14:10 Tue Jan 07] docker-machine ls
NAME                                         ACTIVE   DRIVER      STATE      URL   SWARM   DOCKER    ERRORS
runner-t1pxlfmx-runner-1736226571-8ee6e74f   -        amazonec2   Stopping                 Unknown   
root@gitlab-runner [14:14 Tue Jan 07] docker-machine ls
NAME                                         ACTIVE   DRIVER      STATE     URL   SWARM   DOCKER   ERRORS
runner-t1pxlfmx-runner-1736226862-d9fa72b4            amazonec2   Timeout                          
root@gitlab-runner [14:14 Tue Jan 07] docker-machine ls
NAME                                         ACTIVE   DRIVER      STATE     URL                       SWARM   DOCKER    ERRORS
runner-t1pxlfmx-runner-1736226862-d9fa72b4   -        amazonec2   Running   tcp://172.30.0.240:2376           Unknown   Unable to query docker version: Cannot connect to the docker engine endpoint

なるほど。分からん。

起動したマシンに入ってみようとしてもコネクションをブチ切られるので調べようがないっていう。

docker-machine ssh runner-t1pxlfmx-runner-1736226862-d9fa72b4
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-1052-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud

229 packages can be updated.
158 updates are security updates.

New release '18.04.6 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
ubuntu@runner-t1pxlfmx-runner-1736226862-d9fa72b4:~$ Connection to xxx.xxx.xxx.xxx closed by remote host.

起動時ログを生成して中身を確認出来れば...って思ったけどssh切れちゃうしなぁ...
一応組み込んでみる

user-data.sh
#!/bin/bash
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
echo "Start"

# Dockerのインストールプロセスをログ
curl -fsSL https://get.docker.com -o get-docker.sh
sh ./get-docker.sh 2>&1

# Dockerサービスの状態を確認
systemctl status docker

echo "Completed"

config.tomlに起動時のアクションを追記する

/etc/gitlab-runner/config.toml
[runners.machine]
    MaxGrowthRate = 1
    IdleCount = 1
    IdleTime = 1800
    IdleScaleFactor = 1.0
    IdleCountMin = 1
    MachineDriver = "amazonec2"
    MachineName = "runner-%s"
    MachineOptions = [
      #↓これ
      "amazonec2-userdata=/etc/gitlab-runner/user-data.sh", 
      "amazonec2-region=ap-northeast-1",
      "amazonec2-instance-type=m6i.large",
      "amazonec2-vpc-id=vpc-xxxxxxxx",
      "amazonec2-subnet-id=subnet-xxxxxxxx",
      "amazonec2-zone=a",
      "amazonec2-use-private-address",
      "amazonec2-root-size=8",
      "amazonec2-security-group=gitlab-runner",
      "amazonec2-access-key=XXXXXXXXXXXXXXXXXX",
      "amazonec2-secret-key=XXXXXXXXXXXXXXXXXXXXXXXXX",
      "engine-install-url=https://get.docker.com"
    ]

どうしたものやら
Claudeに聞いてみる

あー手動で作ればいいのか、盲点。

 docker-machine create \
>   --driver amazonec2 \
>   --amazonec2-region ap-northeast-1 \
>   --amazonec2-instance-type m6i.large \
>   --amazonec2-vpc-id vpc-xxxxxxx \
>   --amazonec2-subnet-id subnet-xxxxxxx \
>   --amazonec2-zone a \
>   --amazonec2-use-private-address \
>   --amazonec2-root-size 8 \
>   --amazonec2-security-group gitlab-runner \
>   --amazonec2-access-key xxxxxxxxx \
>   --amazonec2-secret-key xxxxxxxxxxxxxxxx \
>   test-runner
Running pre-create checks...
Creating machine...
(test-runner) Launching instance...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with ubuntu(systemd)...
Installing Docker...
Error creating machine: Error running provisioning: error installing docker:

Dockerのインストール失敗してる!これや!

docker-machine ssh test-runner

sudo apt-get update
Hit:1 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu xenial InRelease
Hit:2 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu xenial-updates InRelease                     
Hit:3 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu xenial-backports InRelease                   
Get:4 https://download.docker.com/linux/ubuntu xenial InRelease [66.2 kB]                              
Ign:4 https://download.docker.com/linux/ubuntu xenial InRelease                                                    
Hit:5 http://security.ubuntu.com/ubuntu xenial-security InRelease                 
Fetched 66.2 kB in 0s (145 kB/s)                       
Reading package lists... Done
W: GPG error: https://download.docker.com/linux/ubuntu xenial InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 7EA0A9C3F273FCD8
W: The repository 'https://download.docker.com/linux/ubuntu xenial InRelease' is not signed.
N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.
N: See apt-secure(8) manpage for repository creation and user configuration details.

ちゃんとコケた!

そして解決へ...

GPGエラーのようなので追加する(ここからずっとClaude任せ)

sudo rm /etc/apt/sources.list.d/docker.list
sudo sed -i '/download.docker.com/d' /etc/apt/sources.list

# キーの再設定
sudo apt-key del 7EA0A9C3F273FCD8
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# リポジトリの追加(新しい方式で)
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu xenial stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# アップデートの実行
sudo apt-get update

# Dockerのインストール
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

これでOKだったので一度runnerに戻って起動時シェルを修正

/etc/gitlab-runner/user-data.sh
#!/bin/bash
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
echo "Starting user-data script..."
date

# Dockerリポジトリの設定をクリーンアップ
rm -f /etc/apt/sources.list.d/docker.list
sed -i '/download.docker.com/d' /etc/apt/sources.list

# Dockerの公式GPGキーを追加(新方式)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Dockerリポジトリの追加
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu xenial stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

# パッケージの更新とDockerのインストール
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io

# Dockerサービスの起動確認
systemctl start docker
systemctl enable docker
systemctl status docker

echo "Completed user-data script"
date

runnerを再起動する

gitlab-runner stop
rm -rf /root/.docker/machine/*
docker-machine ls
NAME   ACTIVE   DRIVER   STATE   URL   SWARM   DOCKER   ERRORS
# 何もない状態
gitlab-runner start

docker-machine ls
NAME                                         ACTIVE   DRIVER      STATE     URL                       SWARM   DOCKER     ERRORS
runner-t1pxlfmx-runner-xxxxxxxx-xxxxxxx   -        amazonec2   Running   tcp://xxx.xxx.xxx.xxx:2376           v20.10.7   

おおおお、来た!

GitLabに戻ってテストジョブを流してみる

出来たあああああ!!!

まとめ

  • メジャーバージョンをゴリゴリに更新したせいでUbuntu,Docker,GitLab,Runnerと変わってしまった箇所が多くて原因解明に時間が掛かった。
  • 困ったときは手動でdocker-machineを作れば調べやすい。
  • 大型アップデートの際は細心の注意を払いましょう。初心忘るべからず。

おわり。

Discussion