ry's Tech blog

Cloud Native技術などについて書いていきます。

Kubenews #46

2021-02-04

10 real-world stories of how we’ve compromised CI/CD pipelines (click here to source)

NCC Groupというセキュリティの会社のサイバーセキュリティコンサルティングの人が、JenkinsGitlab CI/CDに対して実際にできてしまった攻撃を紹介してくれています。

Restricting cluster-admin Permissions (click here to source)

マルチユーザー/マルチテナントのKubernetesクラスターを管理している場合のRBACに関して書かれた記事になってます。

通常、クラスターの管理者には、cluster-admin というClusterRoleが割り当てられます。

これにより、管理者はクラスター内のすべてのリソースに対してすべての操作を実行するためのアクセスとアクセス許可を得ることができます。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-admin
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'

ここで、クラスター管理者によって実行されるアクションをブロックする必要がある場合はを考えてみます。

経緯としては、Giant Swarmで、クラスター管理者が使用するCLIの1つによって、意図したよりも多くのリソースを誤って削除するという問題が発生しましたことでした。

Giant Swarmでは、Kyvernoを利用することで、cluster-admin(および他のすべてのユーザー)が、今回の問題の原因となった特定の削除アクションの実行をブロックするクラスターポリシーを展開しました。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: block-bulk-certconfigs-delete
  annotations:
    policies.kyverno.io/title: Block bulk certconfig deletes
    policies.kyverno.io/subject: CertConfigs
    policies.kyverno.io/description: >-
      A bug in an old kubectl-gs version causes all certconfigs to
      be deleted on performing a login, this policy blocks that
      action while still allowing the single delete.
spec:
  validationFailureAction: enforce
  background: false
  rules:
  - name: block-bulk-certconfigs-delete
    match:
      any:
      - resources:
          kinds:
          - CertConfig
    preconditions:
      any:
      - key: ""
        operator: Equals
        value: ""
    validate:
      message: "Your current kubectl-gs version contains a critical bug, please update to the latest version using `kubectl gs selfupdate`"
      deny:
        conditions:
        - key: ""
          operator: In
          value:
          - DELETE

まず、以下で今回のPolicyの対象を指定します。(今回は、CertConfig というCRD)

    match:
      any:
      - resources:
          kinds:
          - CertConfig

preconditions では、リクエストに基づいて、フィルタリングをかける前提条件を設定します。 この例では、名前が指定されていないリクエスト(--all オプションなど)を対象とします。

    preconditions:
      any:
      - key: ""
        operator: Equals
        value: ""

最後にPolicyにおけるアクションを指定します。

今回は、validation を行います。

denyを用いて、指定リソースに対する DELETE を拒否しています。

    validate:
      message: "Your current kubectl-gs version contains a critical bug, please update to the latest version using `kubectl gs selfupdate`"
      deny:
        conditions:
        - key: ""
          operator: In
          value:
          - DELETE

Scaling Kubernetes to Over 4k Nodes and 200k Pods (click here to source)

ワークロードの大部分はApacheMesosで実行されていたPayPalが、Kubernetes環境に移行する際に行ったパフォーマンステストに関するナレッジの共有がされています。

内容としては、スケーリング時に直面したいくつかの課題と、それらをどのように解決したかについて説明されています。

環境としては、GCPを使っています。

ワークロード

ユースケースに合わせて、指定値の変更が可能なオープンソースのワークロードジェネレーターであるk-benchを使用。

github.com

規模

各ワーカーノードには4つのCPUコアがあり、最大40のポッドを保持するようにし、約4,100ノードまでスケーリングをさせました。

ベンチマークに使用されたアプリケーションは、100ミリコアの保証されたサービス品質(QoS)において実行されるステートレスサービスでした。

最初、1,000ノードに対し2,000ポッドから始め、次に16,000ポッド、次に32,000ポッドまで増やしました。 この後、ノードを4100までスケールさせ、ポッドを150,000にし、続いて200,000ポッドまで増やしました。

これ以上のポッド数に対応するには、各ノードのコア数を増やす必要がありました。

API Server

APIサーバーへのいくつかの接続が、ローカルクライアントレベルのスロットリング(exponential backoff)に加えて、504のゲートウェイタイムアウトを返したときに、API Serverがボトルネックであることが判明しました。

Controller Manager

Controller Manager が状態をAPI Serverと同期できる速度は制限されていたので、チューニングするために以下を設定した。

  • kube-api-qps — コントローラーマネージャーが特定の1秒間にAPIサーバーに対して実行できるクエリの数。
  • kube-api-burst — これは、kube-api-qpsのバースト時の値.
  • concurrent-deployment-syncs — デプロイメント、レプリカセットなどのオブジェクトの同期呼び出しにおける並列実行。

Scheduler

独立したコンポーネントとして独立してテストした場合、スケジューラーは1秒あたり最大1,000ポッドの高スループットレートをサポートできます。

ただし、稼働中クラスターにおけるスケジューラーでは、実際のスループット値は低下します。

etcdインスタンスが遅いと、スケジューラのバインディングレイテンシーが増加し、Pendingキューのサイズが数千ポッドに対するオーダーが発生したタイミングで増加しました。

なので、テスト中はそのオーダー数を100未満に保つようにしました。

他にも、リーダー選出のパラメータをいじって、ネットワークパーティションにおいて誤った短期間の再起動であったり、ネットワークの輻輳に対して回復力を持たせることを実施した。

etcd

Etcdをスケールさせると、多くのRaftのProposalが失敗し始めた。

GCPは100GのディスクサイズでPD-SSDディスクに対するスループットを毎秒約100MiBに抑制したことが確認できました。

現状、スループット制限を増やす方法を提供していません。

これに対し、ローカルSSDを使用することにしました。

ただ、永続的ではないため、障害が発生した場合にデータが失われる可能性がわずかに高くなりますが、スループットが非常に高くなります。

ただこれでは終わらず、SSDから期待されるパフォーマンスが得られませんでした。

これはext4ファイルシステムwrite barrier cache commitsに起因していました。

これに対し、etcdは write-ahead logging を使用し、raftログにコミットするたびにfsyncを呼び出すようにしました。

この場合、write barrierを無効にしても問題ありません。

この変更後、ローカルSSDの数値はPD-SSDに匹敵するように改善されました。

続いて、v1.20のetcdYAMLにLiveness Proveの下記のようなバグがあることがわかりました。

The etcd server would still restart occasionally and just a single restart can spoil the benchmark results, especially the P99 numbers.

これについては、the failure threshold count を増やすことで対処できます。

最後に、etcdのスケールアップ可能なリソース(CPU、メモリ、ディスク)を使い果たすと、etcdのパフォーマンスがrange queryによって影響を受けることがわかりました。

range queryが多く、Raftログへの書き込みが失敗すると、Etcdはうまく機能せず、クラスターのレイテンシーが遅くなります。

対応としては以下のようです。(よくわからなかったので原文を載せます)

After sharding the etcd server on the events resource, we saw an improvement in cluster stability when there is high contention of pods.