この記事はGWアドベントカレンダーの8日目の記事です。
GitLabのパイプラインでdocker loginしようとすると以下のエラーで失敗しました。
docker -l debug login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} http://${CI_REGISTRY}
Error response from daemon: Get https://xxx.xxx.xxx.xxx:4567/v2/: http: server gave HTTP response to HTTPS client
以下にあるdaemon.jsonの設定をrunnerに追加することで解決しました。
registryをHTTPS化することも考えましたが、このregistryがリバースプロキシ配下になく、一旦HTTPのままで対処しました。
Test an insecure registry
この記事はGWアドベントカレンダーの7日目の記事です。
「Ansible 実践ガイド 第3版」を読みました。 この本は、これからAnsibleを始めようとする方や少し触ってみたものの、実際の環境にどのように適用すべきか検討し始めたくらいの方に最適と思います。 ただ、既に色々とAnsibleを適用しているものの構成が複雑で保守しづらくなってしまうというような方にも向いていると思います。 具体的なプレイブックの例がいくつも紹介されており、それぞれにプレイブックのノウハウがあります。
AnsibleやYAMLについての基本的な説明から始まっていて、その後具体的なプレイブックの紹介や保守性を考慮したディレクトリ構成等の実践的な内容へと移っていきます。 プレイブックのデバッグ方法についても様々な手法が説明されており、Ansibleを利用していく上で必要なことが一通り学べるようになっていると思います。
この記事はGWアドベントカレンダーの5日目の記事です。
Gitlabのリポジトリにsshで接続するときはOSのgitユーザを使います。
このユーザはGitlabのユーザすべてで共用します。
そのため、全利用者の公開鍵情報をgitユーザに紐付けて管理する必要があります。
これを実現する方法として、gitユーザのauthorized_keysに全ユーザ分の公開鍵を書いておく方法がありますが、sshアクセスの度にファイルを上からスキャンし、確認する必要があり効率が悪いです。
そこでユーザ名に応じた公開鍵を返すコマンドを用意することで余計な確認を減らすことで高速化することができる仕組みがあります。
以下にGitlabでの設定の仕方が書いてありますが、OpenSSHの提供するAuthorizedKeysCommandという設定を使うことで実現できます。この設定に、公開鍵を返すコマンドを指定します。
Fast lookup of authorized SSH keys in the database
この仕組みを使うと、gitユーザのauthorized_keysに公開鍵を記載する必要がありません。
この記事はGWアドベントカレンダーの3日目の記事です。
GitlabとGitlab Runnerのバージョン情報がどこにあるのか書きます。
最新バージョンが出たかどうかを知るときや、アップデートするときのバージョンを指定したい場合に具体的なバージョンを知る必要があります。
実際には使用するリポジトリのバージョン名を知る必要がありますが、開発元のリリース情報は以下にあります。
なお、GitlabとGitlab Runnerのバージョンは対応していて、同じバージョンがリリースされるみたいです。
Gitlabのリリース情報
ここにあります。
Gitlab Runnerのリリース情報
ここにあります。
この記事はGWアドベントカレンダーの2日目の記事です。
1日目の記事で、CDの対象にすべきではありませんと述べましたが、ではどのようにデプロイすべきでしょうか。
CIサーバのデプロイ方法と言っても、単なるインストール手順のことではありません。CIサーバのライフサイクルを考えた上でデプロイ手順全体を指します。
なお、本記事ではGitlabを対象に述べます。
本番用CIサーバのライフサイクル
まずは本番用のCIサーバのライフサイクルについて考えます。
- サーバデプロイ(OS構築)
- Gitlabインストール
- Gitlabアップデート
- Gitlabアップデート
- 以後、アップデートを繰り返す
上記のように、一度インストールした後はアップデートを繰り返します。
アップデートの際に新バージョンのインスタンスを用意すれば良いように思うかもしれませんが、GitlabはDBにデータを持っていて、異なるバージョン間でのリストアはサポートされていません。
Gitlabの場合、バックアップの仕組みを持っていますが、リストアできるバージョンは、
バックアップ取得時と同じバージョンのみがサポートされています。
そのため、アップデート済みの新インスタンスを用意してもそこへ旧バージョンのデータをリストアすることはできません。
テスト用CIサーバのライフサイクル
次にテスト用のCIサーバについて考えます。
テスト用のCIサーバは本番用と同じ操作を実施すべきなので、
テストの度に、本番用CIサーバと同じバージョンのものを再構築して動作を確認します。
ここで本番用CIサーバのバックアップデータを使ってテスト用CIサーバを構築するのがポイントです。
バックアップデータには各種プロジェクト情報やその設定値などが含まれています。これらのデータも本番用と同じものを使ってテストするのが理想的です。
したがって、テスト用CIサーバのライフサイクルは以下のようになります。
- サーバデプロイ(OS構築)
- Gitlabインストール
- 本番用Gitlabのバックアップデータをリストア
- Gitlabアップデート
- 以後、サーバデプロイから繰り返す
本番用CIサーバのデプロイ方法
前述のように本番用CIサーバを一度構築した後は、アップデートの適用のみを実施するようなケースを考えた場合には、その都度、アップデートを適用する方法が考えられます。
この方法の場合には、初期構築手順とアップデート手順の二つがあれば良いことになります。
これらの手順を自動化しておくことで効率的にデプロイが実現できます。
ただし、故障発生などにより最初から構築する必要があった場合に、正しく構築できるかどうか懸念が残ります。
これを解決するのがImmutable
Serverです。1日目の記事でCDの対象外と述べましたが、パイプライン中でのデプロイを行わないのであれば、テスト用CIサーバを本番用CIサーバとして利用するように切り替えることも可能です。
こうすることでImmutable ServerとしてCIサーバを扱うことができます。
しかし、このような運用をする場合には注意点があります。本番用のDBバックアップを取得してから本番用CIサーバに対し何か変更があると(管理対象プロジェクトのコミット等)、それが失われる可能性があります。
つまり、利用を制限した上でバックアップから切り替えまでを完了できる必要があります。
これは多くの場合は難しいと思います。
結論
結局のところ、Immutable
Serverとして扱うよりも、常にアップデートし続けるデプロイ方法の方が現実的ではないかと考えています。
明日はGitlabのバージョン情報について書く予定です。
この記事はGWアドベントカレンダーの1日目の記事です。
Infrastructure as Codeの考えでは、アプリケーションだけでなくインフラ部分(OSやミドルウェアなど)についてもCI/CDの対象として扱います。
この記事では、IaCに取り組もうと考えて最初に悩む(?)CIサーバ自身のCI/CDについて説明します。
CIサーバというのは、JenkinsやGitlabのようにコミットやプッシュを契機(trigger)に自動的にジョブを実行する機能を持つサーバのことです。
CIサーバ自身も様々な設定を持つ重要なサーバであり、管理対象です。
本記事では簡単のためにCIを自動構築と自動テストと定義します。また、CDを自動デプロイと定義します。
CI/CDのパイプラインとして自動にすべき部分や手動にすべき部分がありますが、本記事ではすべて自動で実施する場合としています。
前提
IaCの文脈で、各サーバをImmutable Serverとして扱う場合を想定しています。
環境としてテスト環境と本番環境があります。CIサーバはテスト環境と本番環境の両方にアクセスできるので、便宜上CI環境に配置されているとします。
CIとして、テスト環境の再構築とテストを実施し、CDとして本番環境の再構築とテストを実施するものとします。
CIサーバをCDの対象とすべきかどうか
CIサーバをCDの対象とするということは、CI環境のCIサーバを再構築(破棄、作成)することになります。
CIサーバをImmutable Serverとして扱うと、パイプラインの途中でCIサーバの再構築が行われるため、必ず途中で中断することになりCDの対象とすることはできません。
CIサーバをいくつものコンポーネントに分けて、一部の機能のみCDの対象とすることはできると思います。
CIサーバはImmutable Serverではない(Mutable Server)として扱うとCIサーバをCDの対象とすることができます。しかし、パイプラインを実行中のCIサーバを変更するというのは複雑で、避けるべきと思います。
したがって、CIサーバはCDの対象とすべきではないと考えます。
CIサーバをCIの対象とすべきかどうか
CIの対象(以下、CI管理対象)というのは理想的にはすべてのサーバです。したがってCIサーバもCI管理対象とすべきと考えられます。
CIサーバのテスト用インスタンスを作成し、テストを実施することは有効です。ただし、テスト用インスタンスを使って実際のパイプラインを実行してはいけません。
実際のパイプラインはテスト用のCIサーバインスタンスの再構築を含んでいたり、テスト環境や本番環境のサーバ再構築を含んでいます。実行して良いのは接続確認のような環境に変更を加えない内容のものだけです。
結論
CIサーバはCIの対象としますが、CDの対象外とします。
CIのパイプラインではテスト用インスタンスを作成し、自動テストを実行します。自動テストによってCIサーバの構築手順の妥当性を確認できます。
明日はCIサーバのデプロイ方法についての予定です。
インフラCI 実践ガイドを読みました。 以前読んだInfrastructure as Code(以下、IaC書籍)に対し、具体的な実装方法について説明しており今の自分に欲しい情報がたくさん得られて非常に満足しました。
本書はこれからインフラCIを始めようとする方向けの本です。インフラCIの具体的な実装の説明と、インフラCIの外側にある要素についても説明しています。 インフラCIの外側にある要素というのはシステムのデザインやリリースに関する制約やチームメンバのスキルなどです。インフラCIを導入し成功させるためにはインフラCIの外側にある要素も非常に重要です。
実際にインフラCIの環境を読者が実際に動かすことができるよう、演習環境としての構築方法とそれに必要な構成定義ファイルを提供しており、まさにこれから始める人にはうってつけの内容と思います。 また、インフラCIの技術的な側面だけでなく、インフラCIを実践するために必要な非技術的な要素についても随所で触れており、インフラCIをこれから導入しようとする場合のポイントについても理解ができるようになっています。 実際に最後の方の章では、技術的な観点というよりはインフラCIよりも広い範囲を考えた場合の導入方法についても述べられています。
IaC書籍は本書の中でも参照されており、より抽象的な概念の理解のためにIaC書籍を読んでおくと、本書の理解もより深まると思います。 実際に私もIaC書籍を読んでから本書を読みましたが、IaC書籍の内容ともリンクしてわかりやすかったです。
記述のスタイルとして、結果をまず述べてからその仕組みについて説明する形になっており、構成定義ファイルの中身についての説明が後回しになっていたり、省略されていたりします。そのため、具体的な構成定義ファイルの中身を見た方がイメージしやすい読者の場合には、ここに記載されている構成定義ファイルをPC上で見ながら本書を読むのも良いかと思います。
「Infrastructure as Code」を読みました。
タイトル通り、システムのインフラ(アプリケーションの土台部分)をコードとして表現することについての本です。
アプリケーションはそもそもコードとして定義されているのが普通ですが、インフラは設計書や手順書によって表現されることが多くあります。
インフラをコードとして表現することで、様々な恩恵を得られるということを謳っています。
この本の中で繰り返し述べられていることは、以下のことです。
- 常に同じやり方をすること
- すべてコードに表現すること
- VCSを使ってコードを管理すること
- 繰り返しそのコードを使ってインフラを構築すること
- 人による判断が必要な個所以外は自動化すること
どんなツールを使うかやコードの管理や自動テストの行い方や管理単位の分割の仕方といった実現方法は、使う組織や運用に合わせて柔軟に変える必要があります。
この本では具体的なツールの使い方にはほとんど触れず、ツールの特徴の紹介と運用パターンの選び方(や選択肢)の紹介が多いです。
言い方を変えると特定のツールによらない普遍的な考え方を中心に述べており、Infrastructure as Codeの概念やメリットを理解したい人に向いています。
具体的なツールの使い方についての説明はありませんが、ツールの名前や特徴については簡単に触れられているので、ツールについて調べる取っ掛かりにもなります。
Infrastructure as Codeをこれから始めようと考えている人にとっては、良い参考書となると思います。
ゼロから仕組みを構築したいときには、考慮すべき観点のチェックリストにもなりますし、既に仕組みがある場合でもより効率化するためのヒントが得られるように思います。