Successfully reported this slideshow.
Your SlideShare is downloading. ×

Jenkins x Kubernetesが簡単だと思ったら大変だった話

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Docker & Kubernetes基礎
Docker & Kubernetes基礎
Loading in …3
×

Check these out next

1 of 67 Ad

Jenkins x Kubernetesが簡単だと思ったら大変だった話

JapanContainerDays v18.12 にて発表した資料です。
https://containerdays.jp

コンテナやkubernetesに対応したCI/CDツールはたくさんありますが、古くからあるJenkinsも当然対応しています。今回はプロダクション環境で実際に使用した経験から、Dockerビルドの苦労話や、Declarative Pipelineでコード化することでいわゆる「Jenkinsおじさん問題」を解決したことをお話しします。

JapanContainerDays v18.12 にて発表した資料です。
https://containerdays.jp

コンテナやkubernetesに対応したCI/CDツールはたくさんありますが、古くからあるJenkinsも当然対応しています。今回はプロダクション環境で実際に使用した経験から、Dockerビルドの苦労話や、Declarative Pipelineでコード化することでいわゆる「Jenkinsおじさん問題」を解決したことをお話しします。

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Similar to Jenkins x Kubernetesが簡単だと思ったら大変だった話 (20)

Advertisement

More from Masaki Yamamoto (17)

Recently uploaded (20)

Advertisement

Jenkins x Kubernetesが簡単だと思ったら大変だった話

  1. 1. Jenkins x Kubernetesが 簡単だと思ったら 大変だった話 Japan Container Days v18.12 2018/12/05 山本 誠樹 株式会社SRIA
  2. 2. 自己紹介 2 Masaki YAMAMOTO Twitter:@nnasaki Microsoft MVP for Microsoft Azure 2014.7 〜 2019.6
  3. 3. CI/CDとは? • Continuous Integration(CI) – 継続的インテグレーション – 自動ビルド・テスト – エクストリーム・プログラミング (XP) のプラクティスの一つ • Continuous Delivery(CD) – 継続的デリバリー – CI実行後、テスト環境や本番環境へデプロイ
  4. 4. 本日のゴール • CI/CDを実運用した体験の共有 • 皆様の苦労を少しでも減らしたい • 俺の屍を超えていけ
  5. 5. CI/CD導入
  6. 6. なぜCI/CDが必要か? • プロダクトをより迅速に正確にリリースしたい • DevOpsの実現に必須 • クラウドネイティブなアプリケーション作成に必須 • CNCF Cloud Native Trail Map の2番目に登場
  7. 7. Cloud Native Trail Map 1. CONTAINARIZATION 2. CI/CD 3. ORCHESTRATION & APPLICATION DEFINITION 4. OBSERVABILITY & ANALYSIS 5. … And more! https://github.com/cncf/landscape/blob/master/README.md
  8. 8. Cloud Native Trail Map • コンテナー化の次にCI/CD • CI/CDを用意する重要性が高まっている
  9. 9. CI/CD設計
  10. 10. CI/CDの基本 BTS Git CI CD テスト 環境 本番 環境 成果物
  11. 11. CI/CDの基本 BTS Git CI CD テスト 環境 本番 環境 成果物 • 各機能は独立して動く • 機能間のプロトコルは様々 • HTTP, SSH, RPC • SaaSを組み合わせて使うことも増えてきた
  12. 12. • CNCF Cloud Native Interactive Landscape • 前述のCloud Native Trail Mapで使用するツール郡 • 605個(2018/12/1現在) • https://landscape.cncf.io/
  13. 13. • CI/CDだけで33個 • すべて使用する必要はない • 必要に応じて選択して使う
  14. 14. CIを動かす BTS Git CI CD テスト 環境 本番 環境 成果物 1. ソースコード をプッシュ 2. プルリクエスト 3. トリガー
  15. 15. CIが動く BTS Git CI CD テスト 環境 本番 環境 成果物 1. ソースコード を取得 2. ビルド 3. 成果物を 格納
  16. 16. CDを動かす BTS Git CI CD テスト 環境 本番 環境 成果物 1. プルリクエスト をマージ 2. トリガー
  17. 17. CDが動く BTS Git CI CD テスト 環境 本番 環境 成果物 1. 成果物を 取得 2. デプロイ
  18. 18. CI/CDに必要なもの(例) BTS Git CI CD テスト 環境 本番 環境 成果物
  19. 19. CI/CDに必要なもの(例) BTS Git CI CD テスト 環境 本番 環境 成果物
  20. 20. CI/CDに必要なもの(例) BTS Git CI CD テスト 環境 本番 環境 成果物
  21. 21. 今回の構成 BTS Git CI CD テスト 環境 本番 環境 成果物 1. REST API Webhook 2. kubectl
  22. 22. 今回の構成(BTS, Git) BTS Git CI CD テスト 環境 本番 環境 成果物 • GitHubのBTSとGitを使う • 他のCI/CDツールとも連携が豊富 • プルリクエストにCIの結果が統合 されるので、見やすい • SaaSなので管理の手間が無い
  23. 23. 今回の構成(CI, CD) BTS Git CI CD テスト 環境 本番 環境 成果物 • Jenkinsを使用 • 枯れてる • GitHubとの連携は Webhook • IaaSなので管理が 大変 • パッチ当て • スケール監視
  24. 24. 今回の構成(テスト環境, 本番環境) BTS Git CI CD テスト 環境 本番 環境 成果物 • Kubernetesを使用 • Azureで構成(AKS) • マスターはPaaSなので手間いらず • ノードはIaaSなので管理が大変 • パッチ当て • ノードの再起動
  25. 25. CI/CD運用
  26. 26. CI/CD運用 • SaaSの場合、ほとんど気にする必要は無い – ただしスケールを上げると高額になる – 高ワークロードの場合IaaSのほうが安くなる • IaaSの場合、ケアする範囲が広くなる – パッチ当て(OS、ミドル、アプリなど) – サービス再起動 – ディスク容量 – 死活監視 – スケールアウトのケア(自動起動など)
  27. 27. Jenkinsの運用 • IaaSゆえの悩みが多かった • パッチ当て、ディスク容量、死活監視などもれなく苦労 した • GUIの設定が多く煩雑になりがちだった
  28. 28. Declarative Pipelineを使う • ファイルを用意する(Jenkinsfileが一般的) • GUIの設定無しにビルドをコードで定義 – Groovyスクリプト • CircleCIなどのyamlの定義より細かな制御可能 • Docker, Terraform, kubectlなど周辺ツールが利用可能
  29. 29. Declarative Pipeline サンプルコード pipeline { agent { docker 'maven:3-alpine' } stages { stage('Example Build') { steps { sh 'mvn -B clean verify' } } } } • pipelineの宣言
  30. 30. Declarative Pipeline サンプルコード pipeline { agent { docker 'maven:3-alpine' } stages { stage('Example Build') { steps { sh 'mvn -B clean verify' } } } } • ビルドするエージェントを指定 • mavenのdockerイメージを使用
  31. 31. Declarative Pipeline サンプルコード pipeline { agent { docker 'maven:3-alpine' } stages { stage('Example Build') { steps { sh 'mvn -B clean verify' } } } } • ビルドのステージを使用する宣言
  32. 32. Declarative Pipeline サンプルコード pipeline { agent { docker 'maven:3-alpine' } stages { stage('Example Build') { steps { sh 'mvn -B clean verify' } } } } • ビルドのステージ定義 • 「Example Build」を指定
  33. 33. Declarative Pipeline サンプルコード pipeline { agent { docker 'maven:3-alpine' } stages { stage('Example Build') { steps { sh 'mvn -B clean verify' } } } } • ビルドの実行ステップを記載 • Shellでmavenを実行
  34. 34. Declarative Pipeline サンプルコード pipeline { agent any stages { stage('Build‘) { ... } stage('Test’) { ... } stage('Deploy’) { ... } } } • 複数のステージを記載可能 • ビルド、テスト、デプロイ • 途中で失敗すると止まる
  35. 35. Declarative Pipeline サンプルコード pipeline { agent any stages { stage('No-op') { ... } } post { always { ... } success { echo 'I succeeeded!' } unstable { echo 'I am unstable :/' } failure { echo 'I failed :(' } changed { echo 'Things were different before...' } } } • ビルド結果に応じてクリーンアップ可能 • dockerイメージやtempファイルなど消せる
  36. 36. Declarative Pipelineの良いところ • 数100個のリポジトリに対して一つ一つJenkinsプロジェ クトを作る必要がなくなった – 各リポジトリにJenkinsfileのテンプレートを用意 – 個別のビルド手順をデベロッパーが記載 • ビルド手順のブラックボックス化がなくなった – すべてJenkinsfileに記載 – 「Jenkins職人」化を防げた
  37. 37. Declarative Pipelineの悪いところ • 情報が少ない – ググってもなかなか出てこない – やりたいことを試行錯誤 • Groovyスクリプトに慣れが必要 – 追加の学習コスト – 文字列や日付の扱いに戸惑うことがある
  38. 38. JENKINS X KUBERNETES
  39. 39. JenkinsからKubernetesへデプロイ BTS Git CI CD テスト 環境 本番 環境 成果物 kubectl
  40. 40. Jenkins で kubectl • kubectl先の設定方法 – 複数のKubernetesクラスタを使う – 複数の設定情報が必要 – KUBERNETES_MASTER環境変数とパラメーターを使用 – 詳細は後述 • デプロイ用のファイルは別途準備 – CI用のJenkinsfileとCD用のJenkinsfileは別 – 環境ごとにk8sのDeployment用yamlを分ける • ベストプラクティスかどうかはわからない – spinnakerとかを使用したほうが良いかも
  41. 41. Dockerイメージ保存 BTS Git CI CD テスト 環境 本番 環境 成果物 Azure Container Registry (ACR)
  42. 42. Dockerイメージ作成 • Dockerビルド用イメージとリリース用イメージは別 • できるだけリリース用イメージは軽くする – イメージが軽いほどコンテナアプリの起動が早くなる – スケールアウトに強くなる – マルチステージビルドの活用
  43. 43. Dockerイメージ保存 • Jenkins上ではなく専用のサービスを使う – Docker Hub(無料版はパブリックのみ) – Amazon Elastic Container Registry – Azure Container Registry(ACR) – GCP Container Registry • ビルド機能が備わっているサービスもある • イメージの脆弱性スキャン機能なども
  44. 44. Declarative Pipelineでの認証情報 • そのまま書くと平文でLogに出力される • Jenkinsの認証プロバイダーにKeyValueで保存 • スクリプト上でwithCredentialsを使用して読み込む
  45. 45. Declarative Pipeline サンプルコード stage('deploy') { steps { script { withCredentials([string(credentialsId: 'k8s-dev', variable: 'master'), file(credentialsId: 'k8s-dev-client-cert', variable: 'cert'), file(credentialsId: 'k8s-dev-client-key', variable: 'key')]) { sh """ export KUBERNETES_MASTER=${master} kubectl apply -f deploy.yaml --client-certificate=${cert} --client- key=${key} """ } } } } • 認証情報をJenkinsの認証プロバイダーから 読み込む
  46. 46. Declarative Pipeline サンプルコード stage('deploy') { steps { script { withCredentials([string(credentialsId: 'k8s-dev', variable: 'master'), file(credentialsId: 'k8s-dev-client-cert', variable: 'cert'), file(credentialsId: 'k8s-dev-client-key', variable: 'key')]) { sh """ export KUBERNETES_MASTER=${master} kubectl apply -f deploy.yaml --client-certificate=${cert} --client- key=${key} """ } } } } • 複数行のShellはヒアドキュメント形式 • 環境変数が適用されないため複数行にする
  47. 47. Declarative Pipeline サンプルコード stage('deploy') { steps { script { withCredentials([string(credentialsId: 'k8s-dev', variable: 'master'), file(credentialsId: 'k8s-dev-client-cert', variable: 'cert'), file(credentialsId: 'k8s-dev-client-key', variable: 'key')]) { sh """ export KUBERNETES_MASTER=${master} kubectl apply -f deploy.yaml --client-certificate=${cert} --client- key=${key} """ } } } }
  48. 48. 実運用で困ったこと
  49. 49. ビルド時にtoo many linksエラー • なぜかCI中にビルドエラーが起きます!と連絡 • ローカル環境では問題なし • Jenkinsのログを調べてみるとCIでDockerイメージビル ド中に「 too many links」エラーと出て失敗する • エラーログ – link /lib/docker/overlay/(省略)/checksum_type /lib/docker/overlay/(省略)/checksum_type: too many links Jenkins Docker Kubernetes
  50. 50. ビルド時にtoo many linksエラー • ハードリンクが使いつくされ、i-nodeが枯渇 • Jenkins上でDocker Imageのクリーンアップが行われて いなかった • 約3000イメージファイルが存在 • とあるイメージは2GBを超えていた Jenkins Docker Kubernetes
  51. 51. ビルド時にtoo many linksエラー • Dockerイメージの削除を実施 – docker image prune だと 削除時にdockerd が応答しなくな るほどのメモリ、CPU負荷が発生 – docker image ls | grep -v “” | awk ‘{print $1“:”$2}’ | xargs docker rmi で少しずつ削除 Jenkins Docker Kubernetes
  52. 52. ビルド時にtoo many linksエラー • cronで定期的にDocker Image削除を実施 – docker image prune • Overlay2ドライバを使用(未実施) – 当時はOverlayドライバを使用していた – Overlay2ドライバを使用することで解消するかも – https://docs.docker.com/storage/storagedriver/overlayfs -driver/#how-the-overlay2-driver-works Jenkins Docker Kubernetes
  53. 53. マルチステージビルドに失敗する • Dockerのマルチステージビルドがたまに失敗する • 失敗する理由が毎回違う Jenkins Docker Kubernetes
  54. 54. マルチステージビルドに失敗する • docker-workflowプラグインの問題っぽい • https://issues.jenkins-ci.org/browse/JENKINS- 44609 の問題っぽい Jenkins Docker Kubernetes
  55. 55. マルチステージビルドに失敗する • Shellで直接実行することにした • 修正前 – docker.build(”hogehoge:hoge", ". -f Dockerfile") • 修正後 – sh "docker build . -f Dockerfile –t hogehoge:hoge” – docker.image(”hogehoge:hoge") Jenkins Docker Kubernetes
  56. 56. マルチステージビルドに失敗する • 現状なし • Issueは修正中のように見えるけど。。。 Jenkins Docker Kubernetes
  57. 57. Jenkinsファイルの文法チェックをしたい • Jenkinsfile はデベロッパーが書いていた • カッコのとじ忘れなど軽微なミスが多かった • Jenkinsfile の動作チェックがローカルで行えなかった • 動作確認のたびにCIを回す必要がありストレスだった Jenkins Docker Kubernetes
  58. 58. Jenkinsファイルの文法チェックをしたい • curlでチェックできるようにした • curl -X POST -H $JENKINS_CRUMB -F "jenkinsfile=<Jenkinsfile" $JENKINS_URL/pipeline- model-converter/validate • 詳細は下記参照 • https://jenkins.io/doc/book/pipeline/development/ #linter Jenkins Docker Kubernetes
  59. 59. 特定のコマンドを実行したい • Terraform, Azure-CLIなど • JenkinsのホストOSにインストールされていない • ホストOSに余計なコマンドやミドルは入れたくない Jenkins Docker Kubernetes
  60. 60. 特定のコマンドを実行したい • コマンド実行用のDockerイメージを用意 stage('cli-sample') { agent { dockerfile { docker 'hogehoge' } } steps { sh 'hogehoge' } } Jenkins Docker Kubernetes
  61. 61. 共通ライブラリを扱いたい • Gitのサブモジュールが利用できない環境 • 数100リポジトリから共通的に参照 • 手間なく運用したい Jenkins Docker Kubernetes
  62. 62. 共通ライブラリを扱いたい • サブディレクトリを作成しGitをチェックアウト dir('hogehoge-repo') { git url: "hogehoge/common.git", branch: "master", credentialsId: credentialsId } Jenkins Docker Kubernetes
  63. 63. まとめ
  64. 64. パブリッククラウドの比較 • Jenkinsを扱うのにパブリッククラウドの比較をすると書 いていましたが… • IaaSになるので各社変わらずという結論 – 料金面、IOPSなど細かい違いはありますが… • Kubernetesなど利用したい環境に応じて設置すればよい のではないでしょうか?
  65. 65. よりよいCI/CDライフを!
  66. 66. Creating with you
  67. 67. アンケートのご協力をお願いします! https://jp.surveymonkey.com/r/ZRV6NNK

×