1インフラCI/CD継続的改善の道のり渡部 龍一 / GMO PEPABO inc.2023.03.14 CI/CD Conference 2023
View Slide
2セッション対象● インフラのCI/CDパイプラインの管理者● インフラのCI/CDの実装に興味がある方話す事● ペパボのインフラCI/CDについて● インフラCI/CDをどのように開発/運用/改善しているか話さないこと● CI/CDの基礎的な話
3アジェンダ1. 自己紹介2. 担当サービス紹介3. 所属チーム紹介4. インフラCI/CDについて5. 抱えていた課題6. 解決へのアプローチ7. まとめ8. 参考
41. 自己紹介
技術部プラットフォームグループ2021年 中途入社5自己紹介渡部 龍一 Watanabe Ryuichi● ロール: SRE● 趣味: 旅行、ドライブ、(緩めの)自宅サーバ● 好きな言語: Go、C言語● Twitter : @ryuichi_1208
6自己紹介● 経歴○ 2017年〜 Linux向けファイルシステムの開発プロジェクト■ テストやデプロイの自動化を担当○ 2019年〜 ニュースサイトの開発/運用■ CI/CDパイプラインの改善でJenkinsやCircleCIの導入推進■ インフラをメインで見ていたがアプリも書いたりしていた
72. 担当サービス紹介
8
91. インターネットでものを売りたい人を支援2. 2005年にサービスの提供を開始3. 総流通額1兆円以上4. 複数のユーザーで1つのリソースを共有するマルチテナント5. ざっくりアプリエンジニア : 30〜名、SRE: 6名
● カラーミーショップのインフラの歴史● オンプレ期● プライベートクラウド期● k8s on プライベートクラウド期● ハイブリッドクラウド期● 詳しく知りたい方へ (https://speakerdeck.com/ch1aki/onpurek8stoeksnobing-xing-yun-yong-noshi-ji)10
113. 所属チーム紹介
● 所属● 技術部プラットフォームグループ● 役割● ペパボのサービスの可用性を確保し、成長に合わせて適切な環境を提供するグループ● ミッション● サーバーの調達やキッティングに止まらず、SRE によるサービスレベルの向上やクラウド環境の検証や選定を行い、必要に応じて事業部門のアプリケーションの改善、開発を通して事業の成長を支える12
● 主な活動● 私の所属している技術部プラットフォームグループでは事業部を横断してSRE活動を実施● 詳しく知りたい方へ(https://tech.pepabo.com/pdf/pepabo-sre-202104.pdf)13
144. インフラについて
15サービスの構成LB App DBVM or k8s AWSで稼働● プライベートクラウドとパブリッククラウドを用いたハイブリッドクラウド● アプリケーションは80以上のロールで構成されている● AWSとプライベートクラウドは専用線 (Direct Connect)で通信
16サービスの構成LB App DBVM or k8s AWSで稼働● 積極的にk8sへの移行は実施している○ それでもロールの数は VM > k8s○ VMとk8sが混在している○ 一部のロールはコンテナ化はしない予定なので今後もこの状況は続く
17インフラ周りで使っている技術スタック(抜粋)プラットフォーム OpenStack, AWS, Kubernetes開発言語 Ruby, mruby, Goミドルウェア Nginx, MySQL, Redis, memcachedCI/CD GitHub Actions, ArgoCD監視 Mackerel, Prometheus, Grafana, ElasticAPM, DataDogIaC Puppet, Ansible, Chef, Terraform
18● Puppet○ puppetlabs/puppet○ OS設定やアプリケーションの構築を自動化するオープンソース・ソフトウェア○ Pullモデル○ manifestはRuby-likeなDSL(Domain Specific Language: ドメイン固有言語)で記述する○ 今回紹介するサービスではメインで使用している主要ツールの紹介
19● Serverspec○ mizzy/serverspec○ サーバの構成を自動でテストするオープンソースのテストフレームワーク○ RubyのRSpecのような使い方が可能○ 「サーバ構築後の確認作業の自動化」「稼働しているサーバの監視」「サーバの再起動時の状態確認」などに使う事ができる○ 今回紹介するサービスではインフラのCIへの組み込みに加えて稼働しているサーバに対しての実行も行っている主要ツールの紹介
20● CI/CD(VMの場合)● OpenStackレイヤの管理はTerraformを使用i. インスタンスやネットワーク領域● ミドルウェアの管理はPuppetを使用i. ミドルウェアの設定や監視も担当デプロイパイプラインの紹介ローカルでの確認は各自でVMを用意 コンテナに対してPuppetをapplyServerspecを使ってテストを実施integration/staging/production環境ごとデプロイ
21デプロイパイプラインの紹介manifestの修正をpush DockerfileのテストDockerImageのbuild/push● CI/CD(Kubernetesの場合)● kubectlのデプロイは原則禁止● GitOpsのフローを取っているi. main branchがstaging環境へ適用ii. release branchの状態がproduction環境へ適用
225. 抱えていた課題
● インフラテストへの課題● コードとサーバで差分が発生している問題● 暗黙知前提の運用問題● VMとコンテナ混在問題● セキュリティ対応問題● 使用しているツールが多く学習に時間がかかる問題23
24● デプロイまでのフロー○ 例) nginxのパラメータを一つ変えるためのPRを出すまでに■ 設定変更を入れるようにコードを修正● ローカルにVMを用意してコードを適用する(15分)● Serverspecと実際のVMの設定を見て問題ないかを確認する■ 問題なければGitHubにpushしCIが実行される● lintやセキュリティの静的チェック● CIでコンテナを起動してコードが適用される(20分)● CIは毎回プレーンな環境で実行される○ 修正とは関係ない箇所の適用もやり直しになる○ 末尾セミコロンを忘れた際の修正確認でも20分追加でかかるテストに時間がかかりすぎる問題
25● 久々にPRを作ったら、変更箇所以外のところでテストが通らなくなってる○ CIは実際のVMではなくコンテナを使ってVMをエミュレートしている○ 存在しないパッケージをインストールしようとして落ちている○ latest指定しているパッケージが後方互換性がなく落ちている○ token期限切れて落ちている○ 障害対応でCIを飛ばしてリリースした時の修正が原因で落ちている○ テスト自体の取り決めもなかったので粒度がバラバラ○ linterとかをアップデートしたらCIが通らなくなった○ 何もしなくても時間の経過と共にシステムは壊れていく■ システム疲労テストのメンテナンス大変問題
26● VMはミュータブル○ 構成ドリフトやスノーフレークサーバが存在していた● 障害時のアドホックな対応などが残っているケース● 半年近くデプロイされていないロールが存在する○ パッケージのバージョンがlatestで指定されているものもある○ 意図せず大きめのアップデートが走ってしまう● 構築時にコード管理せずに管理されたロールも存在する● テスト環境で動作が問題なしでもproductionでは動かないケース○ オートメーション恐怖症○ さらにコードを触る人が減っていき属人化が進んでしまうコードとサーバで差分がある問題
27● インフラのコードを触るメンバーが固定されており暗黙知が多く存在した○ セットアップの手順書はあるがメンテされていない○ デプロイが各自のローカルから実行されている○ コード変更の作業=SREチームへの依頼で本来やりたい作業が進まない○ CIの実行方法もお作法がある暗黙知前提の運用問題
28● 積極的にコンテナ化はしつつもVMとコンテナが混在している状況● ミドルウェアの設定変更をする際はVMとコンテナ両方必要● VM向けに最適化されたミドルウェアの設定などもある○ スケールアウトが前提ではない設定○ /procから取れるメトリクスで上げていたアラートVMとコンテナ混在問題
29● パッケージ等の脆弱性をチェックするツールは動いていた○ Trivyやtfsecが実行されている● 報告される数が膨大で全てを対応することはできていない○ 報告された脆弱性は深刻度が高いもの以外の優先度が上がらない○ パッケージアップデートした後に期待する動作をするかどうかを知る術がなかった○ 既知の脆弱性へのパッチなど、セキュリティアップデートを自動化セキュリティ対応問題
30● IaCだけでも複数ツールが使われている○ Puppet, Ansible, Chef, Terraform● 運用ツールなんかも多数の言語で実装されている○ ShellScript, Perl, Ruby, Python, Go● インフラの設定変更を入れたくても複数ツールを学ぶ必要があり最初のステップのハードルが高くなっていた使用しているツールが多く学習コストが高い問題
31● 暗黙知前提での運用でインフラを触れるメンバーがスケールしない● 開発環境を用意するだけでも一苦労だと触りたい人も増えない● 変更の影響箇所が見えづらく触るのが怖い● SREチーム ≒ インフラ作業多めの脱却はチームの課題でもあったアプリケーションエンジニアも安心して触れるインフラCI/CDを目指して改善
326. 解決へのアプローチ
● CIの高速化● 暗黙知の徹底排除● テストの拡充● 開発環境の整備● 構成ドリフト検出のための仕組みの実装● コンテナ on VM● 監視の見直し● デイリーでコンテナイメージをビルドする仕組み● 権限移譲を進めた33
34インフラテストの課題
35● GitHub Actionsの設定のチューニング○ bundle installやlibrarian-puppet installを都度実行していた○ actions/cacheの導入やstep の並列化の基本的なことを実施○ 2~3分程度の時間の削減に繋がったCIの高速化
36● パイプラインの最適化○ キャッシュを有効活用していく戦略○ kernelヘッダーやgccのアップデートなど変更と関係ない部分をキャッシュ■ 毎日朝に適用済みのコンテナイメージを pushしておきそのイメージを使う■ 10~15分程度の時間の削減に繋がったCIの高速化
37暗黙知前提での運用
38● 誰でも簡単に触れるように○ ドキュメントの整備、勉強会、ワークショップの実施○ 認知負荷を減らすためにCIに関する作業の自動化を実施■ mainブランチへマージ後にローカルから必要だったデプロイを自動実行するようにパイプラインを修正■ テストを動かすためのコマンドはあるがオプションが大量にあって何を指定すればよいかわからない● Makefileを用意して指定するオプションの最小化を目指した■ CIを実行するにはPRに対して必要なラベルを自分で設定する必要があった● 修正したファイルによって適切なCIが実行される仕組みを自動化した● サービスの説明や構成図を作成○ k1LoW/ndiagを用いて構成図などもコード管理を実施暗黙知の徹底排除
39● テスト通る=本番でも期待している動作をするを目指した○ テスト自体が形骸化しているロールが多数存在したので直していく○ nginxを例に■ パッケージをインストールするまでがテストされていた■ configが正しいかや正しくてもきちんと起動するかまでは確認されていなかった■ PuppetやAnsibleでtemplateを使って生成するファイルが正しく生成されているか■ 期待したポートでlistenされているかやupstream設定が正しいかの振る舞いテストも行うようにしたテストの拡充
40● 開発環境のセットアップもテストする○ setupコマンド自体が動かなくなるケースもあったので定期的にCI環境で実行する仕組みを入れた● ローカル環境での動作確認を簡単にできる仕組みを用意した○ Vagrantを使っていたがM1 Macだと動かせなくて動作確認がすぐできない○ ローカルで色々試せない=入門へのハードルが上がる○ ローカルでもコンテナを使って試すことができる用に環境を整備開発環境の整備
41コードとサーバで差分が発生している問題
42● 構成情報と本番環境で差分がある問題○ 基本的に手動変更は行わない運用をしているが全てを強制はできていない○ VMだと手動で適用された変更がそのままになっていたり○ AWSや監視設定が手動で変更されていて差分が発生する○ いざコードを修正するときに修正箇所以外の差分が出てくる構成ドリフト検出のための仕組みの実装
43● 定期的に差分検出やコード適用を実施○ TerraformのplanやPuppetのデプロイを時間を決めて自動実行する○ 定期実行のplanで差分が出る=コード化されていない変更有○ Serverspecを稼働しているサーバに実行し差分がないかを確認● デプロイフローが複数あって何が適用されているかわかりにくかった○ 変更履歴の管理が容易になりいつ誰が変更したかを追跡しやすくなった構成ドリフト検出のための仕組みの実装
44VMとK8s混在問題
45● VMとKubernetesの移行期間○ VMで起きた問題を対応する際にVMでは修正したがコンテナは修正されていないという事が度々発生した○ Kubernets化をすぐにできれば色々な経緯があってうまくできていない● Kubernetesを使わずにVM上でコンテナを動かす○ DockerをVMで動かして1コンテナ=1VMで動かす○ VMへの修正=Dockerfileを修正してimageをpushしておけばよい○ 修正漏れが減るメリットはあるがデプロイフローが複雑化するコンテナ on VM(取り組み中)
46セキュリティへの課題
47● パッケージの脆弱性は最新版では改善されているケースがある○ プログラミング言語やミドルウェアを除いてDockerfileのパッケージバージョンではlatestを指定○ ビルドしたイメージをpushしておきstagingなどで動作確認○ 問題なければproductionに出し○ ミュータブルなVMでもyum-cronなどの仕組みを用いて実施■ 全台同時に更新ではなく一部の VMのみに適用し問題ないかを確認する■ 問題がなければ全台に適用○ 脆弱性があるまま運用するよりもよりセキュアな状態になる方向へ舵を切って進めているデイリーでパッケージを最新化していく
48● 自動化しても拾いきれない脆弱性は存在する○ 例■ パッケージ管理ツール以外でインストールしたミドルウェア■ EOLを迎えているアプリケーションを使い続けている○ アップデートするためには専属のメンバーをアサインして対応■ 脆弱性報告へのトリアージ /対応■ 脆弱性アラートの仕組みの改善活動■ 1週間交代で進めていくセキュリティ対応体制
49権限移譲
50● これまで実施したインフラCI/CDの改善で触りやすくはなった● ブランチの運用ルールでSREチームのレビューが必須となっていたので設定変更を実施○ SREチームの作業負荷が下がる=アプリケーションエンジニアの負荷が上がるにならないように作業難易度を都度確認してどちらのチームが行うかの判断は行っている○ インフラの操作によってはアプリケーションエンジニアが持っている権限では行えないものも存在するので移譲できない物については引き続きSREチームへの依頼が発生している権限移譲を進めた
51● 暗黙知前提での運用でインフラを触れるメンバーがスケールしない● 開発環境を用意するだけでも一苦労だと触りたい人も増えない● 変更の影響箇所が見えづらく触るのが怖い● SREチーム ≒ インフラ作業多めの脱却はチームの課題でもあったアプリケーションエンジニアも安心して触れるインフラCI/CDを目指して改善
52● 取り組み前に比べて作業依頼がほぼ無くなった○ ドキュメント整備やCIの高速化やローカルで開発しやすくなったことで触りやすくなった○ 設定変更などはアプリケーションエンジニアのみでデプロイまで完結できる状況になったアプリケーションエンジニアが触る機会は増えたのか
53● CI/CD改善で生産性はどう変化したのかを計測○ Four Keysを用いて可視化を行いより改善活動を効果的に実施したい● Immutable Infrastructureの推進○ Kubernetes化は引き続き進めていくのに加え難しい箇所はコンテナ on VMの構成が取れる箇所は取っていく● CI/CDパイプラインで使うツールの継続的アップデート○ IaCを実現するためのツール自体は手動でアップデートする必要がある○ CI/CDパイプラインのセキュア化という課題への取り組み今後やっていきたいこと
547. まとめ
55● SREチーム以外のメンバーが触りやすいCI/CDを目指し改善活動を行った結果CI/CDパイプラインを継続的に改善していく必要もあると感じた○ 改善したが時間の経過でドキュメントが古くなったりCIが遅くなったりは定期的に見ていく必要はある○ コンテナとVMの混在環境は今後も減っていきはするが完全に0になることはないので解決策は現在も試行錯誤中● SREチームへのインフラ周りの権限集中という新たな課題も見えてきたまとめ
568. 参考
● Web● インフラCICDの勘所● 現場に合わせて考えた パイプラインのデザインパターン● 書籍● インフラCI実践ガイド Ansible/GitLabを使ったインフラ改善サイクルの実現● Infrastructure as Code● Serverspec● Kubernetes CI/CDパイプラインの実装● 継続的デリバリー57
58ご静聴ありがとうございました