Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kubernetes-native な管理をおこなう CI/CD 2020 / cndt202...

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などコミュニティ活動にも従事。

Masaya Aoyama (@amsy810)

September 09, 2020
Tweet

More Decks by Masaya Aoyama (@amsy810)

Other Decks in Programming

Transcript

  1. - Co-chair Masaya Aoyama + CREATIONLINE / DENSO - 技術アドバイザ

    + SAKURA Internet Research Center – 客員研究員 + 3-shake 技術顧問 + PLAID - Organizer - KaaS Product Owner - Publications Twitter: @amsy810
  2. ・任意のスキーマで CustomResource を追加する機能がある ・Controller を実装するライブラリ・フレームワークが提供されている Controllerの中⾝ = API の操作 +

    ロジック 元となるリソースの データを監視し reconcile() { … } 何かしらの処理をする (調整・収束させ続ける) ,VCFSOFUFT $POUSPMMFSͷ෮श
  3. 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ͷ෮श
  4. 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ͷ෮श
  5. 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ͷఆٛ
  6. 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
  7. 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͸ͨͩͷఆٛͳͨΊɺ ొ࿥ͯ͠΋Կ΋ى͖ͳ͍
  8. 複数の Task を組み合わせたもので、並列実⾏ や 依存関係 などを定義 複数の Task にまたがって利⽤する Params

    や Resource を定義 3FTPVSDF 1BSBNT 3FTPVSDF 1BSBNT 5BTL 5BTL 1JQFMJOF 3FTPVSDF 1BSBNT 1BSBNT 1JQFMJOF
  9. 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 参照
  10. 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 実⾏に必要な具体的な実体を指定 実⾏するパイプラインを指定
  11. &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Ϧιʔε͕࡞੒͞ΕΔ࢓૊Έʂ
  12. ৚݅෼ذʹ૬౰͢Δػೳ 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
  13. $POUBJOFS3FHJTUSZ デフォルトで Trivy / Clair の 脆弱性スキャナ が内包 • Push

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

    リポジトリ/タグ などを正規表現で指定 • 過去 X⽇以内に「Push」「Pull」されたイメージのみ保持 • 直近で「Push」「Pull」されたイメージのうち X 個のみを保持 CI 利⽤時にイメージ数が膨⼤になることでディスク容量が逼迫する問題にも対応可能
  15. /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
  16. 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
  17. 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
  18. "SHP$% 基本的にはデプロイされている⾃⾝の Kubernetes クラスタに対してマニフェストをapply 強い権限がクラスタ外に出ない(cf. GitOps vs CIOps) Kustomize、Helm などにも

    Argo がネイティブで対応 将来的には GitOps Engine の⽅にコア機能はライブラリとして寄っていく様⼦ v1.7.4 で prune 周りの処理を確認したところ、既に GitOps Engine 側に移動 CD Manifest Manifest
  19. ґଘؔ܎ͷ੍ޚ 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 …
  20. "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 が存在しない場合に⾃動的に作成
  21. 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
  22. ϙϦγʔνΣοΫ 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]) }
  23. 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
  24. ԣஅͰͷνΣοΫ 例)設定の衝突 依存リソースの存在 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 などで参照
  25. 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 などでインストールした場合
  26. 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
  27. ΠϝʔδεΩϟϯ デフォルトで 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 などでインストールした場合
  28. 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/
  29. 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