Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

- Co-chair Masaya Aoyama + CREATIONLINE / DENSO - 技術アドバイザ + SAKURA Internet Research Center – 客員研究員 + 3-shake 技術顧問 + PLAID - Organizer - KaaS Product Owner - Publications Twitter: @amsy810

Slide 3

Slide 3 text

さっそく本題

Slide 4

Slide 4 text

・任意のスキーマで CustomResource を追加する機能がある ・Controller を実装するライブラリ・フレームワークが提供されている Controllerの中⾝ = API の操作 + ロジック 元となるリソースの データを監視し reconcile() { … } 何かしらの処理をする (調整・収束させ続ける) ,VCFSOFUFT $POUSPMMFSͷ෮श

Slide 5

Slide 5 text

そしてすべてが Kubernetes マニフェストで 管理される Kubernetes-native になる

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

https://employment.en-japan.com/engineerhub/entry/2020/04/16/103000 11 microservices ʴЋ Kubernetes-native testbed for the future (still alpha release) ࠓճ͸Ұ൪ཧղ͠΍͍͢͜ͷ෦෼ͷઆ໌Λ͠·͢

Slide 10

Slide 10 text

ࢀՃऀಛయ ࠓճ঺հ͢Δ Kubernetes-native testbed ͷ CI/CD ͷ෦෼ͷΈΛൈ͖ग़͠ɺ େ෯ʹਐԽͤͨ͞όʔδϣϯΛ͓࣋ͪؼΓͰ͖·͢ɻ 要望があれば 今日の Kubernetes-native CI/CD の デモを紹介するのを Youtube とかで やろうかなというお気持ち

Slide 11

Slide 11 text

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ͷ෮श

Slide 12

Slide 12 text

Continious Integration

Slide 13

Slide 13 text

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ͷ෮श

Slide 14

Slide 14 text

アプリケーションのテスト コンテナイメージのビルド コンテナレジストリへのプッシュ ( ) マニフェストの更新 ⼀連のパイプライン処理 etc $*1JQFMJOF

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

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ͷఆٛ

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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͸ͨͩͷఆٛͳͨΊɺ ొ࿥ͯ͠΋Կ΋ى͖ͳ͍

Slide 19

Slide 19 text

複数の Task を組み合わせたもので、並列実⾏ や 依存関係 などを定義 複数の Task にまたがって利⽤する Params や Resource を定義 3FTPVSDF 1BSBNT 3FTPVSDF 1BSBNT 5BTL 5BTL 1JQFMJOF 3FTPVSDF 1BSBNT 1BSBNT 1JQFMJOF

Slide 20

Slide 20 text

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 参照

Slide 21

Slide 21 text

1JQFMJOF3VO Pipeline の定義をもとに実際に実⾏するためのリソース 意味を持たせるために Params や Resource の実体を指定する 1BSBNT 3FTPVSDF 1BSBNT 1JQFMJOF3VO 3FTPVSDF 1BSBNT 3FTPVSDF 1BSBNT 5BTL 5BTL 1JQFMJOF 3FTPVSDF 1BSBNT 1BSBNT

Slide 22

Slide 22 text

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 実⾏に必要な具体的な実体を指定 実⾏するパイプラインを指定

Slide 23

Slide 23 text

&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Ϧιʔε͕࡞੒͞ΕΔ࢓૊Έʂ

Slide 24

Slide 24 text

৚݅෼ذʹ૬౰͢Δػೳ 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

Slide 25

Slide 25 text

%BTICPBSE

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

ίϯςφΠϝʔδͷϏϧυ 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ܦ༝Ͱ ѱ͕͞Ͱ͖Δ

Slide 28

Slide 28 text

ίϯςφΠϝʔδͷϏϧυ 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

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

$POUBJOFS3FHJTUSZ デフォルトで Trivy / Clair の 脆弱性スキャナ が内包 • Push 時の⾃動脆弱性スキャン • 脆弱性のあるイメージの Pull を拒否(CVE 毎に allow / deny なども設定可能) Harbor と外部レジストリとの Replication が可能 • ローカルキャッシュ相当の利⽤︓Remote registry to local harbor • バックアップ⽤途の同期︓Local harbor to remote registry Harbor が API を提供 + イベントを元にした Webhook の送信が可能(Slack 宛にも対応) プロジェクト単位のクオータ設定やユーザ管理も可能

Slide 31

Slide 31 text

$MFBOJOHJNBHFT 1.Garbage Collection 機能 タグを上書きした場合に、タグが付与されていない不要なイメージの削除 2.Tag Retention 機能 ルールにマッチするイメージを⾃動的に削除 対象となる リポジトリ/タグ などを正規表現で指定 • 過去 X⽇以内に「Push」「Pull」されたイメージのみ保持 • 直近で「Push」「Pull」されたイメージのうち X 個のみを保持 CI 利⽤時にイメージ数が膨⼤になることでディスク容量が逼迫する問題にも対応可能

Slide 32

Slide 32 text

/PUF Nginx Ingress 経由でコンテナイメージをプッシュする場合、HTTP Status code 413 が返る ⇒ Ingress のアノテーションで Body Size の上限値を緩和する error parsing HTTP 413 response body: invalid character '<' looking for beginning of value: "¥r¥n413 Request Entity Too Large¥r¥n¥r¥n

413 Request Entity Too Large

¥r¥n
nginx/1.17.10¥r¥n¥r¥n¥r¥n" nginx.ingress.kubernetes.io/proxy-body-size: 32m

Slide 33

Slide 33 text

%BTICPBSE

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Continious Delivery

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

"SHP$% 基本的にはデプロイされている⾃⾝の Kubernetes クラスタに対してマニフェストをapply 強い権限がクラスタ外に出ない(cf. GitOps vs CIOps) Kustomize、Helm などにも Argo がネイティブで対応 将来的には GitOps Engine の⽅にコア機能はライブラリとして寄っていく様⼦ v1.7.4 で prune 周りの処理を確認したところ、既に GitOps Engine 側に移動 CD Manifest Manifest

Slide 40

Slide 40 text

ґଘؔ܎ͷ੍ޚ 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 …

Slide 41

Slide 41 text

"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 が存在しない場合に⾃動的に作成

Slide 42

Slide 42 text

%BTICPBSE

Slide 43

Slide 43 text

Complete CI/CD?

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

We need more secure.

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

ϙϦγʔνΣοΫ 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]) }

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

ԣஅͰͷνΣοΫ 例)設定の衝突 依存リソースの存在 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 などで参照

Slide 50

Slide 50 text

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 などでインストールした場合

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

ΠϝʔδεΩϟϯ デフォルトで 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 などでインストールした場合

Slide 54

Slide 54 text

47(JNBHFΛΠϯϙʔτ͢Δͱ ͳ่͔ͥΕΔʜ ೉ಡԽ͞ΕͯΔঢ়ଶΛ දݱ͍ͯ͠ΔΘ͚Ͱ͸ͳ͍

Slide 55

Slide 55 text

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/

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

*OHSFTT$FSUNBOBHFSʹΑΔެ։ Ingress︓複数のドメインやパスをもとに Service へルーティング

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

Kubernetes-native CI/CD 2020

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

Let’s build archtecture with OSS ecosystem

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

Thank you for your attention @amsy810