Dockerイメージを構築し、GitLabでDockerイメージリポジトリをホストする方法
序章
コンテナ化は、クラウド環境でアプリケーションをパッケージ化およびデプロイするための最も受け入れられている方法に急速になりつつあります。 それが提供する標準化は、そのリソース効率(完全な仮想マシンと比較した場合)および柔軟性とともに、最新のDevOpsマインドセットの優れたイネーブラーになります。 アプリケーションとマイクロサービスが完全にコンテナー化されると、多くの興味深いクラウドネイティブのデプロイ、オーケストレーション、および監視戦略が可能になります。
Docker コンテナーは、今日最も一般的なコンテナータイプです。 Docker Hub のようなパブリックDockerイメージリポジトリには、docker pull
で今日使用できるコンテナ化されたオープンソースソフトウェアイメージがたくさんありますが、プライベートコードの場合は、ビルドするためにサービスを支払う必要があります。画像を保存するか、独自のソフトウェアを実行して保存します。
GitLab Community Editionは、Gitリポジトリホスティング、プロジェクトトラッキング、CI / CDサービス、Dockerイメージレジストリなどの機能を提供するセルフホストソフトウェアスイートです。 このチュートリアルでは、GitLabの継続的インテグレーションサービスを使用して、サンプルのNode.jsアプリからDockerイメージを構築します。 これらのイメージはテストされ、独自のプライベートDockerレジストリにアップロードされます。
前提条件
始める前に、継続的インテグレーションタスクを実行するために安全なGitLabサーバーとGitLabCIランナーをセットアップする必要があります。 以下のセクションでは、リンクと詳細を提供します。
SSLで保護されたGitLabサーバー
ソースコードを保存し、CI / CDタスクを実行し、Dockerレジストリをホストするには、Ubuntu16.04サーバーにGitLabインスタンスをインストールする必要があります。 GitLabは現在、少なくとも2つのCPUコアと4GBのRAMを備えたサーバーを推奨しています。 さらに、Let'sEncryptのSSL証明書を使用してサーバーを保護します。 そのためには、サーバーを指すドメイン名が必要です。
次のチュートリアルを使用して、これらの前提条件を完了することができます。
- DigitalOceanでホスト名を設定する方法は、DigitalOceanコントロールパネルでドメインを管理する方法を示します
- Ubuntu 16.04を使用した初期サーバーセットアップは、root以外の、sudo対応のユーザーをセットアップし、Ubuntuの
ufw
ファイアウォールを有効にします。 - Ubuntu 16.04にGitLabをインストールして構成する方法では、GitLabをインストールし、Let'sEncryptの無料のTLS/SSL証明書を使用して構成する方法を説明します。
GitLabCIランナー
Ubuntu16.04でGitLabCIと継続的インテグレーションパイプラインを設定する方法では、GitLabのCIサービスの概要を説明し、ジョブを処理するためのCIランナーを設定する方法を示します。 このチュートリアルで作成したデモアプリとランナーインフラストラクチャの上に構築します。
ステップ1—特権GitLabCIランナーのセットアップ
前提条件のGitLab継続的インテグレーションチュートリアルでは、sudo gitlab-runner register
とそのインタラクティブな構成プロセスを使用してGitLabランナーをセットアップしました。 このランナーは、分離されたDockerコンテナー内でソフトウェアのビルドとテストを実行できます。
ただし、Dockerイメージをビルドするには、ランナーがDockerサービス自体に完全にアクセスできる必要があります。 これを構成するための推奨される方法は、Dockerの公式docker-in-docker
イメージを使用してジョブを実行することです。 これには、ランナーに特別なprivileged
実行モードを付与する必要があるため、このモードを有効にして2番目のランナーを作成します。
注:ランナーに特権モードを付与すると、基本的に、コンテナーを使用することによるセキュリティ上の利点がすべて無効になります。 残念ながら、Docker対応のランナーを有効にする他の方法にも同様のセキュリティ上の影響があります。 さまざまなランナーオプションの詳細と、状況に最適なものについては、 DockerBuildに関する公式のGitLabドキュメントをご覧ください。
特権ランナーの使用にはセキュリティ上の影響があるため、hello_hapi
プロジェクトでDockerジョブのみを受け入れるプロジェクト固有のランナーを作成します(GitLab管理者は、このランナーを他のプロジェクトにいつでも手動で追加できます。後で)。 hello_hapi
プロジェクトページで、左側のメニューの下部にある設定をクリックし、サブメニューの CI /CDをクリックします。
次に、ランナー設定セクションの横にある展開ボタンをクリックします。
登録トークンなど、特定のランナーの設定に関する情報があります。 このトークンに注意してください。 これを使用して新しいランナーを登録すると、ランナーはこのプロジェクトにのみロックされます。
このページを表示しているときに、共有ランナーを無効にするボタンをクリックします。 Dockerジョブが常に特権ランナーで実行されるようにする必要があります。 非特権の共有ランナーが利用可能な場合、GitLabはそのランナーを使用することを選択する可能性があり、その結果、ビルドエラーが発生します。
現在のCIランナーが存在するサーバーにログインします。 ランナーを使用してマシンをセットアップしていない場合は、先に進む前に、前提条件のチュートリアルのGitLabCIランナーサービスのインストールセクションに戻って完了してください。
次に、次のコマンドを実行して、特権プロジェクト固有のランナーを設定します。
sudo gitlab-runner register -n \ --url https://gitlab.example.com/ \ --registration-token your-token \ --executor docker \ --description "docker-builder" \ --docker-image "docker:latest" \ --docker-privileged
OutputRegistering runner... succeeded runner=61SR6BwV Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
必ず自分の情報に置き換えてください。 プロンプトでは--docker-privileged
モードを指定できないため、インタラクティブプロンプトを使用する代わりに、コマンドラインですべてのランナーオプションを設定します。
これで、ランナーがセットアップ、登録、および実行されます。 確認するには、ブラウザに戻ります。 メインのGitLabメニューバーのレンチアイコンをクリックしてから、左側のメニューのRunnersをクリックします。 ランナーが一覧表示されます:
Dockerイメージを構築できるランナーができたので、イメージをプッシュするためのプライベートDockerレジストリを設定しましょう。
ステップ2—GitLabのDockerレジストリを設定する
独自のDockerレジストリを設定すると、独自のプライベートサーバーからイメージをプッシュおよびプルできるため、セキュリティが強化され、ワークフローが外部サービスに依存することが少なくなります。
GitLabは、いくつかの構成を更新するだけでプライベートDockerレジストリをセットアップします。 まず、レジストリが存在するURLを設定します。 次に、(オプションで)S3互換のオブジェクトストレージサービスを使用してデータを保存するようにレジストリを構成します。
GitLabサーバーにSSHで接続し、GitLab構成ファイルを開きます。
sudo nano /etc/gitlab/gitlab.rb
コンテナレジストリ設定セクションまで下にスクロールします。 registry_external_url
行のコメントを解除し、ポート番号5555
のGitLabホスト名に設定します。
/etc/gitlab/gitlab.rb
registry_external_url 'https://gitlab.example.com:5555'
次に、次の2行を追加して、Let'sEncrypt証明書の場所をレジストリに通知します。
/etc/gitlab/gitlab.rb
registry_nginx['ssl_certificate'] = "/etc/letsencrypt/live/gitlab.example.com/fullchain.pem" registry_nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/gitlab.example.com/privkey.pem"
ファイルを保存して閉じてから、GitLabを再構成します。
sudo gitlab-ctl reconfigure
Output. . . gitlab Reconfigured!
レジストリポートへのトラフィックを許可するようにファイアウォールを更新します。
sudo ufw allow 5555
次に、Dockerがインストールされている別のマシンに切り替えて、プライベートDockerレジストリにログインします。 ローカル開発コンピューターにDockerがない場合は、Dockerが既にインストールされているため、GitLabCIジョブを実行するように設定されているサーバーを使用できます。
docker login gitlab.example.com:5555
ユーザー名とパスワードの入力を求められます。 GitLabクレデンシャルを使用してログインします。
OutputLogin Succeeded
成功! レジストリが設定され、機能しています。 現在、GitLabサーバーのローカルファイルシステムにファイルを保存します。 代わりにオブジェクトストレージサービスを使用する場合は、このセクションに進んでください。 そうでない場合は、ステップ3にスキップします。
レジストリのオブジェクトストレージバックエンドを設定するには、オブジェクトストレージサービスに関する次の情報を知っている必要があります。
- アクセスキー
- シークレットキー
- たとえば、AmazonS3を使用している場合はRegion (
us-east-1
)、S3互換サービスを使用している場合は Region Endpoint (https://nyc.digitaloceanspaces.com
) - バケット名
DigitalOcean Spacesを使用している場合は、 DigitalOceanSpaceとAPIキーの作成方法を読んで、新しいSpaceを設定する方法と上記の情報を取得する方法を確認できます。
オブジェクトストレージ情報を入手したら、GitLab構成ファイルを開きます。
sudo nano /etc/gitlab/gitlab.rb
もう一度、コンテナレジストリセクションまでスクロールダウンします。 registry['storage']
ブロックを探し、コメントを外して、次のように更新します。ここでも、必要に応じて独自の情報に置き換えてください。
/etc/gitlab/gitlab.rb
registry['storage'] = { 's3' => { 'accesskey' => 'your-key', 'secretkey' => 'your-secret', 'bucket' => 'your-bucket-name', 'region' => 'nyc3', 'regionendpoint' => 'https://nyc3.digitaloceanspaces.com' } }
Amazon S3を使用している場合は、region
のみが必要であり、regionendpoint
は必要ありません。 SpacesなどのS3互換サービスを使用している場合は、regionendpoint
が必要です。 この場合、region
は実際には何も構成せず、入力する値は重要ではありませんが、空白ではなく存在する必要があります。
ファイルを保存して閉じます。
注:現在、オブジェクトストレージバケットが空の場合、30秒後にレジストリがシャットダウンするというバグがあります。 これを回避するには、次の手順を実行する前にファイルをバケットに入れます。 レジストリが独自のオブジェクトを追加した後、後で削除できます。
DigitalOcean Spacesを使用している場合は、コントロールパネルのインターフェイスを使用してドラッグアンドドロップでファイルをアップロードできます。
GitLabをもう一度再構成します。
sudo gitlab-ctl reconfigure
他のDockerマシンで、レジストリに再度ログインして、すべてが正常であることを確認します。
docker login gitlab.example.com:5555
Login Succeeded
メッセージが表示されます。
Dockerレジストリーがセットアップされたので、アプリケーションのCI構成を更新してアプリをビルドおよびテストし、Dockerイメージをプライベートレジストリーにプッシュします。
ステップ3—gitlab-ci.yaml
を更新してDockerイメージを構築する
注: GitLab CI に関する前提条件の記事を完了していない場合は、サンプルリポジトリをGitLabサーバーにコピーする必要があります。 GitHubからのサンプルリポジトリのコピーセクションに従ってください。
Dockerでアプリをビルドするには、.gitlab-ci.yml
ファイルを更新する必要があります。 このファイルをGitLabで直接編集するには、プロジェクトのメインページからファイルをクリックし、編集ボタンをクリックします。 または、リポジトリをローカルマシンに複製し、ファイルを編集してから、git push
してGitLabに戻すこともできます。 これは次のようになります。
git clone [email protected]:sammy/hello_hapi.git cd hello_hapi # edit the file w/ your favorite editor git commit -am "updating ci configuration" git push
まず、ファイル内のすべてを削除してから、次の構成で貼り付けます。
.gitlab-ci.yml
image: docker:latest services: - docker:dind stages: - build - test - release variables: TEST_IMAGE: gitlab.example.com:5555/sammy/hello_hapi:$CI_COMMIT_REF_NAME RELEASE_IMAGE: gitlab.example.com:5555/sammy/hello_hapi:latest before_script: - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN gitlab.example.com:5555 build: stage: build script: - docker build --pull -t $TEST_IMAGE . - docker push $TEST_IMAGE test: stage: test script: - docker pull $TEST_IMAGE - docker run $TEST_IMAGE npm test release: stage: release script: - docker pull $TEST_IMAGE - docker tag $TEST_IMAGE $RELEASE_IMAGE - docker push $RELEASE_IMAGE only: - master
強調表示されたURLとユーザー名を自分の情報で更新してから、GitLabの変更のコミットボタンで保存してください。 GitLabの外部でファイルを更新する場合は、変更をコミットしてgit push
をGitLabに戻します。
この新しい構成ファイルは、GitLabに最新のDockerイメージ(image: docker:latest
)を使用し、それをdocker-in-dockerサービス(docker:dind)にリンクするように指示します。 次に、build
、test
、およびrelease
ステージを定義します。 build
ステージは、リポジトリで提供されるDockerfile
を使用してDockerイメージを構築し、それをDockerイメージレジストリにアップロードします。 それが成功すると、test
ステージは、作成したばかりのイメージをダウンロードし、その中でnpm test
コマンドを実行します。 テストステージが成功すると、release
ステージがイメージをプルし、hello_hapi:latest
のタグを付けて、レジストリにプッシュバックします。
ワークフローに応じて、test
ステージを追加したり、アプリをステージング環境または本番環境にプッシュするdeploy
ステージを追加したりすることもできます。
構成ファイルを更新すると、新しいビルドがトリガーされるはずです。 GitLabのhello_hapi
プロジェクトに戻り、コミットのCIステータスインジケーターをクリックします。
結果のページで、ステージのいずれかをクリックして、進行状況を確認できます。
最終的には、すべてのステージで、緑色のチェックマークアイコンを表示して成功したことを示す必要があります。 左側のメニューのRegistry項目をクリックすると、ビルドされたばかりのDockerイメージを見つけることができます。
画像名の横にある小さな「ドキュメント」アイコンをクリックすると、適切なdocker pull ...
コマンドがクリップボードにコピーされます。 次に、イメージをプルして実行できます。
docker pull gitlab.example.com:5555/sammy/hello_hapi:latest docker run -it --rm -p 3000:3000 gitlab.example.com:5555/sammy/hello_hapi:latest
Output> [email protected] start /usr/src/app > node app.js Server running at: http://56fd5df5ddd3:3000
イメージはレジストリからプルダウンされ、コンテナで開始されました。 ブラウザに切り替え、ポート3000でアプリに接続してテストします。 この場合、ローカルマシンでコンテナを実行しているため、次のURLでlocalhostを介してコンテナにアクセスできます。
http://localhost:3000/hello/test
OutputHello, test!
成功! CTRL-C
でコンテナを停止できます。 これ以降、リポジトリのmaster
ブランチに新しいコードをプッシュするたびに、新しいhello_hapi:latest
イメージを自動的にビルドしてテストします。
結論
このチュートリアルでは、Dockerイメージをビルドするための新しいGitLabランナーをセットアップし、それらを格納するためのプライベートDockerレジストリを作成し、Dockerコンテナ内でビルドおよびテストするためにNode.jsアプリを更新しました。
このセットアップで使用されるさまざまなコンポーネントの詳細については、 GitLab CE 、 GitLab Container Registry 、およびDockerの公式ドキュメントをご覧ください。