はじめに
EC2で稼働しているgitlabを、別AWSアカウントのEC2に移行したいという要件がありました。
そこで、EC2にgitlabのインストールからセットアップ、gitリポジトリの移行までを備忘がてら手順を残します。
やること
- 新gitlabインスタンスの立ち上げ
- 旧gitlabから新gitlabへのリポジトリ移行
- 新gitlabにローカル環境から接続(commit, pushなど)
【環境】
EC2 OS: Amazon Linux2
gitlab: ver15.0
■ インストールと初期設定
新しくEC2インスタンスを起動します。
今回は、AMIにAmazon Linux2
を使用しました。
(インスタンスタイプが小さすぎると処理しきれない可能性があります。今回は、m5.large
で行います。)
今回だと、gitlabインスタンスはパブリックサブネット内に配置する要件なので、ElasticIPをアタッチします。
新しく起動したEC2に↓記事を参考にgitlabをインストールします。
$ sudo yum install -y gitlab-ee
完了しました!
#root権限で作業
$ sudo su
$ vi /etc/gitlab/gitlab.rb
~
external_url 'http://gitlabインスタンスのグローバルIPアドレス'
~
~
#gitを再起動
$ gitlab-ctl reconfigure
ブラウザで確認
なぜか、rootユーザー(管理者アカウント)のパスワード変更画面にならなかったので、ログインできず・・・
↓記事を参考に管理者アカウントのパスワードを設定
コンソールからパスワード設定後、ログインし無事スタート画面に来ました!
※追記
あとで知ったのですが、rootユーザーの初期パスワードは、インスタンス内のここに存在していた👀
Password: XXXXXXXXXXXXXXXXXXXXXXXXXXXX
■ ドメインの設定
Route53にAレコード登録
Route53のホストゾーンに対するサブドメインとして、EC2インスタンスにアタッチしたEIPをルーティング先にしたAレコード
を登録します。
名前解決の確認
登録したドメイン名がEC2インスタンスのEIPと名前解決できているか、dig
コマンドまたはnslookup
コマンドなどで確認します。
$ dig ドメイン名 a
■ SSL証明書の取得
gitlabはnginxが内蔵されている
nginxのインストールから nginx ⇄ gitlab
間の通信が必要かと思ったのですが、調べてみると、
実はgitlab
ではデフォルトでnginx
がバンドルされているそうなので、このプロセスは不要でした・・・
Let's encryptでの取得
基本的には↓記事の手順どおり実行
↑記事内の$ certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com
の部分を↓のように変更して実行
--webroot
や--standalone
などは取得する方法によって変わります。
$ certbot certonly --standalone -d ドメイン名
=> could not bind tcp port 80 because it is already in use by another process on this system (such as a web server). please stop the program in question and then try again.
しかし、ポート80番は既に使われているから使えないよと言われてしまった。
色々調査したところ、原因は、gitlab.rb
のexternal_url
がhttp://ドメイン名
だったこと。
external_url "http://ドメイン名"
sudo lsof -i :80
で使用している80番ポートを確認すると、なんかいろいろ起動している。
nginx 19178 root 7u IPv4 117001 0t0 TCP *:http (LISTEN)
nginx 19179 gitlab-www 7u IPv4 117001 0t0 TCP *:http (LISTEN)
nginx 19180 gitlab-www 7u IPv4 117001 0t0 TCP *:http (LISTEN)
/etc/gitlab/gitlab.rb
に↓の内容を追記。gitを再起動してあげると・・・
external_url "https://ドメイン名"
#letsencrypt['enable'] = true #GitLab 10.5 and 10.6 require this option
nginx['redirect_http_to_https'] = true
nginx['redirect_http_to_https_port'] = 80
# ↓証明書の位置を設定(※これを設定しないと、更新の際に設定した証明書を見に行ってくれない)
nginx['ssl_certificate'] = "/etc/letsencrypt/live/[ドメイン名]/fullchain.pem"
nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/[ドメイン名]/privkey.pem"
#gitの再起動
$ gitlab-ctl reconfigure
無事、htts://ドメイン名
でアクセスできた!!🙌
一応、これで証明書の取得と、https
化の設定は終わりです。
が、しかし・・・
これだと、証明書更新の際に、
インスタンスを起動し80番ポートを常時開放した上で、webサーバを停止しておく必要がある など、セキュリティ的に何かと都合が悪いので、DNS-01チャレンジ
というRoute53を使用した方法に切り替えて再度、取得し更新まで実装しました。
Let's Encryptのログ確認
/var/log/letsencrypt/letsencrypt.log
Route53を使用したDNS-01チャレンジでSSL証明書を取得し直す
#すでにある証明書無効・削除
$ certbot revoke --cert-path /etc/letsencrypt/live/ドメイン名/fullchain.pem
#再度取得
$ certbot certonly --manual \
--server https://acme-v02.api.letsencrypt.org/directory \
--preferred-challenges dns \
-d ドメイン名 \
-m 登録するメールアドレス \
--agree-tos \
--manual-public-ip-logging-ok
cronでの自動更新
証明書の更新は、root権限でないとできないので、rootユーザーのcronに以下を設定。
letsencryptの有効期限は3ヶ月。
--force-renewal
をオプションで指定すると期限が来なくても強制的に取得することができる。
#毎月1日のAM10:00にLet's encryptのSSL証明書を更新
#* * * * * の意味は、左から、[分 時 日 月 曜日]
00 10 1 * * certbot renew --force-renewal --dns-route53 --post-hook "gitlab-ctl restart"
自動更新の確認
EC2にRoute53を操作するIAMロールをアタッチ
- 以下のjson内容を持つカスタム管理ポリシーを任意の名前で作成
- 作成したポリシーをIAMロールに追加
- gitlabインスタンスに、このIAMロールをアタッチ
これをしないと、EC2からRoute53へのドメインの問い合わせができないです。
{
"Version": "2012-10-17",
"Id": "certbot-dns-route53 sample policy",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:GetChange"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/ホストゾーンID"
]
}
]
}
証明書の有効期限確認
/etc/letsencrypt/live/ドメイン名
にfullcain.pem
が存在します。
↓コマンド実行結果のnotAfter
が設定されている証明書の有効期限となっています
$ sudo openssl x509 -in /etc/letsencrypt/live/ドメイン名/fullchain.pem -noout -dates
=>
notBefore=May 17 04:00:58 2022 GMT
notAfter=Aug 15 04:00:57 2022 GMT
証明書更新テスト
証明書更新コマンドに、--dry-run
オプションをつけてあげると、実際には更新されず更新できるかどうかのテストをしてくれます。
$ certbot renew --force-renewal --dry-run --dns-route53 --post-hook "gitlab-ctl restart"
#dns-route53プラグインなるものをインストールしてくれと言われる
=>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/ドメイン名
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Failed to renew certificate ドメイン名 with error: The requested dns-route53 plugin does not appear to be installed
ここが結構ハマりました。certbot-dns-route53
をインストールしようとpip
やapt
, snap
など色々試しましたが、なかなかうまくいかず・・・😖
結局は、snap
ではなくyum
から再度cerbot
を入れ直すことで解決しました。
certbot-dns-route53
のインストール
$ amazon-linux-extras install -y epel
$ sudo yum install certbot
$ sudo yum install python2-certbot-dns-route53
#certbotプラグイン一覧を確認
$ certbot pulgins
=>
#これがあればOK
* dns-route53
Description: Obtain certificates using a DNS TXT record (if you are using AWS
Route53 for DNS).
Interfaces: IAuthenticator, IPlugin
Entry point: dns-route53 =
certbot_dns_route53._internal.dns_route53:Authenticator
~~
再度更新テストを実行すると成功!
$ certbot renew --force-renewal --dry-run --dns-route53 --post-hook "gitlab-ctl restart"
Lambda✖︎EventBridgeで証明書更新時にインスタンスの起動設定
今回のgitlabインスタンスの運用として、基本は停止状態で必要なときのみ立ち上げるスタンスだったので、cron実行されるタイミングでgitlabインスタンスが立ちあがっておく必要がある。
そこで、LambdaとEventBridgeで毎月1日にインスタンスを立ち上げる関数を作成し、cronが実行できる状態にしておく。
■ Gitlabリポジトリの移行
新規リポジトリ作成
新gitlab上で、リポジトリを作成しておきます。
--mirror
オプションで旧リポジトリをローカルに取り込みます。リモート先を変更し、pushします。
(※注意)--mirror
でとってきたリポジトリは、dokcer.gitみたいになっており、そのリポジトリ内ではgitコマンドを使用できない
mkdir gitlab_dir
cd gitlab_dir
git clone --mirror 旧gitlabのリポジトリ(git@git~~~~~/XX.git)
#remote先を確認
git remote -v
git remote set-url origin 新gitlabのリポジトリ(git@~~~~~/XX.git)
#remote先が変更されていることを確認
git remote -v
git push --mirror origin master
GitlabにSSH接続
基本的には、↓記事の通りにやれば問題ないかと思います。
/.ssh/config
に追記する情報として以下のように設定します。
User
の部分は自分のgitlabアカウント作成時に設定した@移行
になります。
Host ホスト
#gitlabの @移行の名前
User ユーザー名
Port 22
HostName ホスト
TCPKeepAlive yes
identitiesonly yes
IdentityFile ~/.ssh/鍵.pub