Kubernetes-native な管理をおこなう CI/CD 2020 / cndt2020-k8s-amsy810

Kubernetes-native な管理をおこなう CI/CD 2020 / cndt2020-k8s-amsy810

https://event.cloudnativedays.jp/cndt2020/talks/9

様々なものごとをマニフェストで記述して自動化するエコシステムにより、管理系統をすべてKubernetesに寄せることができます。 CI/CDについても、Tekton Pipeline & Triggers、ArgoCD、Kaniko、Harbor Operator、Trivy、Conftest、OPA Gatekeeperなどを用いてGitOpsを実現するKubernetes-nativeなCI/CD環境を作り上げることが可能です。 本セッションでは2020年に作るべき、CI/CD環境について紹介します。

青山 真也
CyberAgent, Inc.
Software Engineer
OpenStackを使ったプライベートクラウドやGKE互換なコンテナプラットフォームをゼロから構築。CyberAgentでは Kubernetes/CloudNative 領域の Developer Expertsとしても従事。国内カンファレンスでのKeynoteや海外カンファレンス等、登壇経験多数。世界で2番目にKubernetesの認定資格を取得。著書に『Kubernetes完全ガイド』『みんなのDocker/Kubernetes』。現在はOSSへのContribute 活動をはじめ、CNCF公式のCloud Native Meetup TokyoやKubernetes Meetup TokyoのOrganizerなどコミュニティ活動にも従事。

De266761b955b2636e454a1bc7a99ed4?s=128

Masaya Aoyama (@amsy810)

September 09, 2020
Tweet

Transcript

  1. Masaya Aoyama CyberAgent Kubernetes-native ͳ؅ཧΛߦ͏ CI/CD 2020 @CloudNative Days Tokyo

    2020 @amsy810
  2. - Co-chair Masaya Aoyama + CREATIONLINE / DENSO - 技術アドバイザ

    + SAKURA Internet Research Center – 客員研究員 + 3-shake 技術顧問 + PLAID - Organizer - KaaS Product Owner - Publications Twitter: @amsy810
  3. さっそく本題

  4. ・任意のスキーマで CustomResource を追加する機能がある ・Controller を実装するライブラリ・フレームワークが提供されている Controllerの中⾝ = API の操作 +

    ロジック 元となるリソースの データを監視し reconcile() { … } 何かしらの処理をする (調整・収束させ続ける) ,VCFSOFUFT $POUSPMMFSͷ෮श
  5. そしてすべてが Kubernetes マニフェストで 管理される Kubernetes-native になる

  6. 課題 こうしたソフトウェアの使⽤感・運⽤感は ⼩規模なデモ環境だと予測しづらい

  7. None
  8. Kubernetes-native testbed for the future (still alpha release) https://employment.en-japan.com/engineerhub/entry/2020/04/16/103000 11

    microservices
  9. https://employment.en-japan.com/engineerhub/entry/2020/04/16/103000 11 microservices ʴЋ Kubernetes-native testbed for the future (still

    alpha release) ࠓճ͸Ұ൪ཧղ͠΍͍͢͜ͷ෦෼ͷઆ໌Λ͠·͢
  10. ࢀՃऀಛయ ࠓճ঺հ͢Δ Kubernetes-native testbed ͷ CI/CD ͷ෦෼ͷΈΛൈ͖ग़͠ɺ େ෯ʹਐԽͤͨ͞όʔδϣϯΛ͓࣋ͪؼΓͰ͖·͢ɻ 要望があれば 今日の

    Kubernetes-native CI/CD の デモを紹介するのを Youtube とかで やろうかなというお気持ち
  11. GitOps: マニフェストが保存されたリポジトリを⽤意し、Kubernetes に同期を⾏う⼿法 Infrastructure as Code / PR and Review

    Process / History / Single Source of Truth source code k8s manifest container image CD CI developer (JU0QTʹΑΔ $*$%1JQFMJOFͷ෮श
  12. Continious Integration

  13. GitOps: マニフェストが保存されたリポジトリを⽤意し、Kubernetes に同期を⾏う⼿法 Infrastructure as Code / Single Source of

    Truth / PR and Review Process / History source code k8s manifest container image CD CI developer (JU0QTʹΑΔ $*$%1JQFMJOFͷ෮श
  14. アプリケーションのテスト コンテナイメージのビルド コンテナレジストリへのプッシュ ( ) マニフェストの更新 ⼀連のパイプライン処理 etc $*1JQFMJOF

  15. None
  16. Kubernetes の CustomResource として Pipeline を定義 cf. circleci.yml, concourse.yaml, Jenkinsfile,

    etc. Tekton といっても実は 2 種類に分かれている apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: build-and-push spec: params: - name: TAG default: latest resources: inputs: - name: source-repo type: git outputs: - name: image-repo type: image steps: - name: build-and-push-step workingdir: /workspace/source-repo image: ... command: - build.sh - --dest=$(outputs.resources.image-repo.url) - --tag=$(inputs.params.TAG) resources: requests: cpu: 100m memory: 128Mi $*1JQFMJOFͷఆٛ
  17. Tekton における最⼩単位の実⾏ Step (コンテナイメージと実⾏コマンド)をまとめたもの Step︓Task ≒ Init Containers︓Pod の関係に近い Params︓⽂字列変数

    Resource︓Gitリポジトリ、コンテナイメージ、ストレージ(GCS)、PR などの抽象化モデル 3FTPVSDF 3FTPVSDF 1BSBNT 1BSBNT TUFQ TUFQ TUFQ TUFQ 5BTL https://github.com/tektoncd/pipeline/blob/master/docs/resources.md#resource-types https://github.com/tektoncd/pipeline/blob/master/pkg/apis/resource/resource.go 5BTL
  18. 3FTPVSDF 3FTPVSDF 1BSBNT 1BSBNT TUFQ TUFQ TUFQ TUFQ 5BTL apiVersion:

    tekton.dev/v1beta1 kind: Task metadata: name: build-and-push spec: params: - name: TAG default: latest resources: inputs: - name: source-repo type: git outputs: - name: image-repo type: image steps: - name: build-and-push-step workingdir: /workspace/source-repo image: ... command: - build.sh - --dest=$(outputs.resources.image-repo.url) - --tag=$(params.TAG) resources: requests: cpu: 100m memory: 128Mi 実⾏する Step(コンテナ)の定義 https://github.com/tektoncd/pipeline/blob/release-v0.15.x/pkg/apis/pipeline/v1beta1/task_types.go#L119-L126 5BTLͷఆٛ 5BTL͸ͨͩͷఆٛͳͨΊɺ ొ࿥ͯ͠΋Կ΋ى͖ͳ͍
  19. 複数の Task を組み合わせたもので、並列実⾏ や 依存関係 などを定義 複数の Task にまたがって利⽤する Params

    や Resource を定義 3FTPVSDF 1BSBNT 3FTPVSDF 1BSBNT 5BTL 5BTL 1JQFMJOF 3FTPVSDF 1BSBNT 1BSBNT 1JQFMJOF
  20. 3FTPVSDF 1BSBNT 3FTPVSDF 1BSBNT 5BTL 5BTL 1JQFMJOF 3FTPVSDF 1BSBNT 1BSBNT

    1JQFMJOFͷఆٛ apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: ci namespace: tekton-pipelines spec: resources: - name: source-repo type: git - name: image-repo type: image params: - name: MICROSERVICE tasks: - name: build-and-push taskRef: name: kaniko-build-and-push params: - name: CONTEXT value: ./microservices/$(params.MICROSERVICE) resources: inputs: - name: source-repo resource: source-repo outputs: - name: image-repo resource: image-repo - name: pull-request-manifest taskRef: name: pull-request-manifest runAfter: - build-and-push params: {...} resources: {...} タスク間の依存関係を定義 複数 Task から共通の Resource や Param 参照
  21. 1JQFMJOF3VO Pipeline の定義をもとに実際に実⾏するためのリソース 意味を持たせるために Params や Resource の実体を指定する 1BSBNT 3FTPVSDF

    1BSBNT 1JQFMJOF3VO 3FTPVSDF 1BSBNT 3FTPVSDF 1BSBNT 5BTL 5BTL 1JQFMJOF 3FTPVSDF 1BSBNT 1BSBNT
  22. 1JQFMJOF3VOͷఆٛ apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: ci-20200810 namespace: tekton-pipelines

    spec: timeout: 1h0m0s pipelineRef: name: ci params: - name: MICROSERVICE value: microservice-a resources: - name: source-repo resourceSpec: type: git params: - name: url value: https://github.com/.../... - name: revision value: abcdef - name: image-repo resourceSpec: type: image params: - name: url value: myregistry/$(params.MICROSERVICE):abcdef 1BSBNT 3FTPVSDF 1BSBNT 1JQFMJOF3VO 3FTPVSDF 1BSBNT 3FTPVSDF 1BSBNT 5BTL 5BTL 1JQFMJOF 3FTPVSDF 1BSBNT 1BSBNT 実⾏に必要な具体的な実体を指定 実⾏するパイプラインを指定
  23. &WFOU͔Βͷ 5SJHHFS PipelineRun リソースを作成すると実際に CI パイプラインが実⾏される GitHub 上で PR が作成されたタイミングなどでパイプラインを実⾏するには︖

    コミットハッシュなど動的に決定される情報を指定して実⾏するには︖ &WFOU-JTUFOFS 5SJHHFS5FNQMBUF 5SJHHFS#JOEJOH 1JQFMJOF3VO 3FTPVSDF 1BSBN 1BSBN 1JQFMJOF 5BTL 5BTL 1BSBN 3FTPVSDF 1BSBN ΠϕϯτΛड͚ͨࡍʹ࡞੒͢Δ 1JQFMJOF3VOͳͲΛఆٛ ड͚ͨΠϕϯτͷ৘ใΛݩʹ 1BSBNΛಈతʹܾఆ ྫʣίϛοτϋογϡ ྫʣ(JUϦϙδτϦͷ63- ͲͷΑ͏ͳΠϕϯτΛѻ͏͔ ˞ &WFOU-JTUFOFSΛ࡞੒͢Δͱ ϦΫΤετΛड͚Δ 4FSWJDFϦιʔε͕࡞੒͞ΕΔ࢓૊Έʂ
  24. ৚݅෼ذʹ૬౰͢Δػೳ 1.Condition リソース Pipeline 実⾏時に該当 Task を実⾏するかを判断 基本的には Task と同じように

    Param と Resource を受け取りコマンド実⾏ 2.CEL(Common Expression Language)https://github.com/google/cel-spec EventListener がイベント受信時に PipelineRun などを作成するかを判断 - cel: filter: body.ref == 'refs/heads/develop' && !body.commits[0].message.startsWith('[Update manifest]') script: git fetch --unshallow; IS_CHANGED=$(git diff --name-only `git show ${COMMIT_HASH} --pretty="%P" | head -n 1` | grep -e "^microservices/${MICROSERVICE}/"); if [ -z "${IS_CHANGED}" ]; then exit 1; fi
  25. %BTICPBSE

  26. None
  27. ίϯςφΠϝʔδͷϏϧυ Docker デーモンに依存せずにコンテナ内のユーザ空間でイメージをビルドするツール DinD︓セキュリティの問題がやや発⽣しやすい(+特定のケースで動作しない) DooD︓セキュリティの問題が発⽣しやすい Kernel Docker Container Docker Container

    Docker in Docker Image Kernel Docker Container Container Docker outside of Docker Image Kernel Docker Container kaniko Kaniko Image ΤϛϡϨʔτͯ͠ΔͬΆ͍ײ͡ 1SJWJMFHFEݖݶ͕ඞཁ ϗετͷ%PDLFSܦ༝Ͱ ѱ͕͞Ͱ͖Δ
  28. ίϯςφΠϝʔδͷϏϧυ Kaniko バイナリ以外にも要件があるため提供されているコンテナイメージを利⽤する gcr.io/kaniko-project/executor:VERSION Kubernetes などの上で安全にコンテナイメージのビルドが可能 別途キャッシュの設定なども可能(Volume Mount) Container kaniko

    Image Container kaniko Image Container kaniko Image Container kaniko Image Container kaniko Image Container kaniko Image Container kaniko Image Container kaniko Image
  29. None
  30. $POUBJOFS3FHJTUSZ デフォルトで Trivy / Clair の 脆弱性スキャナ が内包 • Push

    時の⾃動脆弱性スキャン • 脆弱性のあるイメージの Pull を拒否(CVE 毎に allow / deny なども設定可能) Harbor と外部レジストリとの Replication が可能 • ローカルキャッシュ相当の利⽤︓Remote registry to local harbor • バックアップ⽤途の同期︓Local harbor to remote registry Harbor が API を提供 + イベントを元にした Webhook の送信が可能(Slack 宛にも対応) プロジェクト単位のクオータ設定やユーザ管理も可能
  31. $MFBOJOHJNBHFT 1.Garbage Collection 機能 タグを上書きした場合に、タグが付与されていない不要なイメージの削除 2.Tag Retention 機能 ルールにマッチするイメージを⾃動的に削除 対象となる

    リポジトリ/タグ などを正規表現で指定 • 過去 X⽇以内に「Push」「Pull」されたイメージのみ保持 • 直近で「Push」「Pull」されたイメージのうち X 個のみを保持 CI 利⽤時にイメージ数が膨⼤になることでディスク容量が逼迫する問題にも対応可能
  32. /PUF Nginx Ingress 経由でコンテナイメージをプッシュする場合、HTTP Status code 413 が返る ⇒ Ingress

    のアノテーションで Body Size の上限値を緩和する error parsing HTTP 413 response body: invalid character '<' looking for beginning of value: "<html>¥r¥n<head><title>413 Request Entity Too Large</title></head>¥r¥n<body>¥r¥n<center><h1>413 Request Entity Too Large</h1></center>¥r¥n<hr><center>nginx/1.17.10</center>¥r¥n</body>¥r¥n</html>¥r¥n" nginx.ingress.kubernetes.io/proxy-body-size: 32m
  33. %BTICPBSE

  34. 2. webhook 7. Update manifest (Pull requests) 5. Push container

    image 4. Build container image 1. Modify application source code 3. Kick pipelines Continuous Integration source manifests
  35. None
  36. Continious Delivery

  37. GitOps: マニフェストが保存されたリポジトリを⽤意し、Kubernetes に同期を⾏う⼿法 Infrastructure as Code / Single Source of

    Truth / PR and Review Process / History (JU0QTʹΑΔ $*$%1JQFMJOFͷ෮श source code k8s manifest container image CD CI developer
  38. None
  39. "SHP$% 基本的にはデプロイされている⾃⾝の Kubernetes クラスタに対してマニフェストをapply 強い権限がクラスタ外に出ない(cf. GitOps vs CIOps) Kustomize、Helm などにも

    Argo がネイティブで対応 将来的には GitOps Engine の⽅にコア機能はライブラリとして寄っていく様⼦ v1.7.4 で prune 周りの処理を確認したところ、既に GitOps Engine 側に移動 CD Manifest Manifest
  40. ґଘؔ܎ͷ੍ޚ Resource Hooks (Phase) https://argoproj.github.io/argo-cd/user-guide/resource_hooks/ マニフェスト適⽤前後、成功 or 失敗時にリソースを作成する Job リソースを利⽤した

    DB のマイグレーション、Slack 通知、etc Sync waves https://argoproj.github.io/argo-cd/user-guide/sync-waves/ 各 Hooks にも順位が付けられる (default: 0) 例)App 更新 > DB migrate > Front 更新 metadata: annotations: argocd.argoproj.io/hook: PreSync argocd.argoproj.io/sync-wave: "5" Phase Wave pre-sync -1 0 … 1 … sync -1 0 … 1 … post-sync sync-fail -1 0 … 1 …
  41. "VUP4ZODपΓͷઃఆ Auto Prune Git リポジトリから削除された際に該当リソースを削除 CI で kubectl apply --prune

    より安全(個⼈の⾒解) Sync windows https://argoproj.github.io/argo-cd/user-guide/sync_windows/ [ArgoCD 1.3 〜] 特定の時間帯の同期を避けることが可能なため、業務時間をベースに同期制限も可能 Retry sync [ArgoCD 1.7 〜] リソースの依存や validating webhook 失敗時などの再同期も可能に 今までは同⼀コミットハッシュの場合は再同期されなかった Namespace auto creation [ArgoCD 1.7 〜] Namespace が存在しない場合に⾃動的に作成
  42. %BTICPBSE

  43. Complete CI/CD?

  44. 2. webhook 7. Update manifest (Pull requests) 5. Push container

    image 4. Build container image 1. Modify application source code 8. Pull manifests 3. Kick pipelines Continuous Integration Continuous Delivery source manifests 9. Apply manifests
  45. We need more secure.

  46. None
  47. ϙϦγʔνΣοΫ manifests Conftest Gatekeeper Rego ⾔語を⽤いてポリシーを記述可能 https://www.openpolicyagent.org/docs/latest/policy-language/ ⼊⼒(input)に対して適切な設定値になっているかをチェックする ポリシーチェックは 2

    段階で実施がおすすめ deny[msg] { input.kind == "Deployment" container := input.spec.template.spec.containers[_] container.securityContext.privileged == true msg = sprintf("Do not use privileged containers: Name=%s", [input.metadata.name]) }
  48. 2. webhook 7. Update manifest (Pull requests) 5. Push container

    image 4. Build container image 1. Modify application source code 8. Pull manifests 9. Apply manifests 3. Kick pipelines Continuous Integration Continuous Delivery source manifests 6. Scan container image Conftest Gatekeeper
  49. ԣஅͰͷνΣοΫ 例)設定の衝突 依存リソースの存在 Conftest では --combine option を利⽤することで複数マニフェスト横断のチェックが可能 • 通常時

    • --combine 利⽤時 Gatekeeper では Kubernetes API と同期を取ることが出来るため、 data.inventory.namespace[NAMESPACE][groupVersion][kind][NAME].kind などで 参照した既存のリソース情報を元にポリシーチェックが可能 ︓Ingress の FQDN が衝突していないか ︓Deployment に対応する PodDisruptionBudget リソースが存在するか ︓resource なので input.kind などで参照 ︓input = files なので input[files][resources].kind などで参照
  50. 01" Ҏ֎ͷϙϦγʔνΣοΫ Kubeval - https://github.com/instrumenta/kubeval リソースの YAML 構造が指定したバージョンの Kubernetes に準拠しているかをチェック

    Pluto - https://github.com/FairwindsOps/pluto 指定したバージョンの Kubernetes で⾮推奨/廃⽌になった API バージョンの有無をチェック Kubernetes 1.19 から deprecation warning が出⼒されるようになったが… https://kubernetes.io/blog/2020/09/03/warnings/#deprecation-warnings * Helm, Harbor operator などでインストールした場合
  51. None
  52. 2. webhook 7. Update manifest (Pull requests) 5. Push container

    image 4. Build container image 1. Modify application source code 8. Pull manifests 9. Apply manifests 3. Kick pipelines Continuous Integration Continuous Delivery source manifests 6. Scan container image ࡞੒͞ΕͨίϯςφΠϝʔδʹର͢Δ ΠϝʔδεΩϟϯ Conftest Gatekeeper
  53. ΠϝʔδεΩϟϯ デフォルトで Trivy / Clair の 脆弱性スキャナ が内包* • Push

    時の⾃動脆弱性スキャン • 脆弱性のあるイメージの Pull を拒否(CVE 毎に allow / deny なども設定可能) • OS のパッケージの脆弱性スキャン(.rpm, .deb, etc.) • アプリケーションライブラリの脆弱性スキャン(gem, pip, etc.) ※ Trivy のみ OPA Image Scanner Admission Controller(未検証)https://github.com/sysdiglabs/opa-image-scanner • スキャン結果を元に Pod 作成時の Accept / Reject • Namespace ・クラスタ・イメージによって柔軟なポリシー設定が可能 * Helm, Harbor operator などでインストールした場合
  54. 47(JNBHFΛΠϯϙʔτ͢Δͱ ͳ่͔ͥΕΔʜ ೉ಡԽ͞ΕͯΔঢ়ଶΛ දݱ͍ͯ͠ΔΘ͚Ͱ͸ͳ͍

  55. 4FDSFUͷ҉߸Խํࣜ SealedSecret SealedSecret LVCFTFBM $-* Secret SealedSecret Secret 公開鍵/秘密鍵 4FBMFE4FDSFU

    $POUSPMMFS kubesec ExternalSecret Berglas ExternalSecret Secret &YUFSOBM4FDSFU $POUSPMMFS ExternalSecret 4FDSFU.BOBHFS Secret (暗号化済) Secret Secret LVCFTFD $-* ,.4 Pod (env 等で参照) Pod NVUBUJOH 4FDSFU.BOBHFS($4 JOKFDU 悩みに悩んだ Kubernetes Secrets の管理方法、 External Secrets を選んだ理由 https://tech.plaid.co.jp/nayanda-kubernetes- secret-management/
  56. None
  57. *OHSFTT$FSUNBOBHFSʹΑΔެ։ Ingress︓複数のドメインやパスをもとに Service へルーティング

  58. *OHSFTT$FSUNBOBHFSʹΑΔެ։ Ingress︓複数のドメインやパスをもとに Service へルーティング ExternalDNS︓払い出された IP アドレスを⾃動的に DNS へ登録

  59. *OHSFTT$FSUNBOBHFSʹΑΔެ։ Ingress︓複数のドメインやパスをもとに Service へルーティング ExternalDNS︓払い出された IP アドレスを⾃動的に DNS へ登録 Cert-manager︓ACME

    Challenge を利⽤して証明書を⾃動的に発⾏
  60. *OHSFTT$FSUNBOBHFSʹΑΔެ։ Ingress︓複数のドメインやパスをもとに Service へルーティング ExternalDNS︓払い出された IP アドレスを⾃動的に DNS へ登録 Cert-manager︓ACME

    Challenge を利⽤して証明書を⾃動的に発⾏ OAuth2 Proxy︓Ingress と OAuth2 provider と連携して認証を提供
  61. Kubernetes-native CI/CD 2020

  62. 2. webhook 7. Update manifest (Pull requests) 5. Push container

    image 4. Build container image 1. Modify application source code 8. Pull manifests 9. Apply manifests 3. Kick pipelines Continuous Integration Continuous Delivery source manifests 6. Scan container image Conftest Gatekeeper
  63. Let’s build archtecture with OSS ecosystem

  64. Kubernetes-native testbed for the future (still alpha release) https://employment.en-japan.com/engineerhub/entry/2020/04/16/103000 11

    microservices
  65. Thank you for your attention @amsy810