Trending keywords: security, cloud, container,

GKEセキュリティ:ベストプラクティスガイド

SHARE:

サイバーセキュリティの脅威と攻撃が増えるにつれ、クラウドセキュリティはクラウドインフラのますます重要な側面となっています。インフラを保護する上で重要な役割を果たす2つのアクターがいます。クラウド・プロバイダー顧客です。

  • クラウド・プロバイダーは、そのインフラを保護し、ソフトウェアのセキュリティ問題に対処する責任があります。
  • 顧客は、自身のアプリケーションのセキュリティに責任を負います。また、クラウドプロバイダーのインフラストラクチャ内でデータとワークロードを保護するために提供されるコントロールを正しく使用しなければなりません。

この記事では、主要なプロバイダの1つであるGoogle Kubernetes Engine、略してGKEに焦点を当てます。Kubernetesは複雑なシステムで、セキュリティのベストプラクティスを含め、常にその機能を改善しており、新しい機能を追加したり、既存の機能(PSPなど)を削除したり、新しい機能に置き換えたりしています。Google Kubernetes Engine (GKE)のセキュリティとベストプラクティスについて詳しく説明します。

クラウドネイティブ・セキュリティ

Cloud Native Computing Foundation (CNCF)は、クラウドネイティブスタックを基盤、ライフサイクル、環境のレイヤーで構成されると定義しており、ライフサイクル自体は、開発、配布、デプロイ、ランタイムで構成されています。これらのレイヤーはすべて、GKEセキュリティを含むクラウドセキュリティに含まれるべきです。

These layers are depicted in the following image.

Cloud Native Stack

図1 – クラウドネイティブ・スタック – – Cloud Native Security Whitepaper

ライフサイクル

ライフサイクルは、開発、配布、デプロイ、ランタイムで構成されます。

開発

Develop

図2 – 開発 – Cloud Native Security Whitepaper

「開発」は、アーティファクトの作成に関するこのサイクルの最初のものです。これには、Infrastructure as Code、有効なコンテナやマニフェストファイルなどが含まれます。これは、SCM(ソース管理)に新しい変更をコミットする前のステップです。

  • Cloud Codeは、Kubernetesアプリケーションを開発する際に、設定ファイルの作業に時間を費やすのではなく、コード/アプリケーションの記述に集中できるようにします。
  • Center of Internet Security (CIS) ベンチマークは、開発チームや組織に、デフォルトで安全なワークロードを作成するためのガイドを提供します。Google Cloudは、これらのベストプラクティスのセキュリティ推奨事項を提供しています: CISベンチマーク

その他の重要な検討事項:

  • Google CloudのContainer-Optimized OS、COSを使用します。
  • イメージを常に最新の状態に保ちましょう。
  • コンテナに必要なアプリケーションのみをインストールします。
  • K8s マニフェストファイルの検証には、任意の linting ツールを使用してください。

配布

Distribute

Figure 3 – 配布 – Cloud Native Security Whitepaper

次のステップでは、前のステップで準備したマニフェストまたはアーティファクトを使用します。マニフェストまたはアーティファクトをビルドし、レジストリに送信する必要があります。次に、さまざまな種類のテストを実行し、イメージをスキャンし、署名して、新しく作成されたリソースにポリシーを適用します。

「開発」フェーズでは、Google Cloudは以下のツールを提供します:

  • Cloud Buildでは、Kubernetesアプリケーションの開発中、ファイルの設定よりもコードの記述に集中することができます。
  • Google Artifact RegistryとGoogle Container Registryは、ビルドの成果物や依存関係を安全に保存するために使用できます。これらはディープスキャン機能を使って自動的にスキャンされ、新しい脆弱性を特定します。トリガーを作成することで、パッケージに対するアップストリームの変更を検出し、それらを強制的に再構築してスキャンすることができます。

デプロイ

Deploy

図4 – デプロイ – Cloud Native Security Whitepaper

これは、対象となるランタイム環境にアプリケーションを出荷する前に行われるチェックです。チェックは、実施されているすべてのポリシーとコンプライアンスを満たす必要があります。

Google CloudはBinary Authorizationツールを提供します。これはレジストリとポリシーを結びつけるものです。コンテナイメージのメタデータに基づいてデプロイメントポリシーを定義できます。このポリシーは、前のステップでのスキャン結果や、その場にある QA プロセスに基づくことができます。

ランタイム

Runtime

図5 – ランタイム – Cloud Native Security Whitepaper

図 1 に示すように、このフェーズはコンピュート、アクセス、ストレージから構成されます。

コンピューティングは、Google Cloudのグローバルなインフラストラクチャ上でアプリケーションを作成し、実行できるようにするGKEインフラストラクチャの重要な基盤です。しかし、その前に、セキュリティが確保されていることを確認する必要があります。

  • 名前空間は、リソースを論理的に分離する機能を提供します。これは、組織化、セキュリティ、そしてパフォーマンスにおいて、あなたやあなたのチームを助けることができます。単一のGKEクラスタ内に複数の名前空間を持つことができます。.


ネームスペースを作成する簡単な方法を以下に示します:

$> kubectl create namespace online-web-development

$> cat >> online-web-staging.yaml <<EOF
apiVersion: v1
kind: Namespace
metadata:
  name: online-web-staging
EOF

$> kubectl apply -f online-web-staging.yaml
  • RBACを使用すると、クラスタ内の任意のKubernetesオブジェクト、またはクラスタ内の特定のネームスペースで対話できるGoogle Cloudユーザーまたはユーザーグループを設定できる、よりきめ細かく特定の権限セットを持つことができます。最小特権の原則に常に従い、既存のロールを定期的に監査して、使用されていないロールや非アクティブなロールを削除することも良い習慣です。RoleとRoleBindingは名前空間レベルで適用されるKubernetesオブジェクトですが、ClusterRoleとClusterRoleBindingはクラスタレベルです。
# Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  Name: cluster-metadata-viewer
  Namespace: default
rules:
apiGroups:
“”
  resources:
configmaps
  resourceNames:
cluster-metadata
  verbs:
get

# RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  Name: cluster-metadata-viewer
  Namespace: default
roleRef:
  apiGroups: rbac.authorization.k8s.io
  Kind: Role
  Name: cluster-metadata-viewer
subject:
apiGroups: rbac.authorization.k8s.io
  Kind: Group
  Name: system: authenticated
  • ポッドセキュリティポリシー(PSP)は、クラスタレベルでセキュリティを制御し、ポッドの作成や更新の権限を設定できるポリシーです。特権コンテナの実行(フィールド名:privileged)、ホスト名前空間の使用(フィールド名:hostPID、hostIPC)、ポッドのボリュームを所有するFSGroupの割り当て(フィールド名:fsGroup)などに適用できます。完全な情報はここにあります。なお、PSPはKubernetes v1.21で非推奨となり、v1.25で削除される予定です。
  • アドミッションコントローラを有効にすることで、ポッドセキュリティポリシーをオプションで実装し、実施することができます。ただし、注意してください。ポリシーの認証を行わずにPSPを適用すると、クラスタにポッドを作成できなくなります。GKEは、Open Policy Agent (OPA)を使用するGatekeeperを使用してPSPを適用することを推奨します。
  • Workload Identityは、GKEで動作するポッドからGoogleのサービス群(Storage Buckets、App Engineなど)に認証するためのGoogle推奨の方法です。Kubernetesサービスアカウント(KSA)をGoogle Cloud IAMサービスアカウント(GSA)にリンクすることで実現します。これにより、KubernetesシークレットやGSAキーを管理することなく、Kubernetesネイティブリソースを使用してワークロードIDを定義し、GCP内のサービスへのアクセスを制御できます。これは、IAMとKSAクレデンシャル間の信頼された関係を作成するWorkload Identity Poolによって処理されます。
  • リソース要求と制限は、意図的に(ハッキングによって)、または意図せずに(設定ミスによって)、Kubernetesノードとクラスタレベルのリソースが枯渇しないように設定する非常に重要なプロパティです。
# Pod definition
apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
name: app
    image: busybox
    resources:
      requests:
        memory: “32Mi”
        cpu: “200m”
      limits:
        memory: “64Mi”
        cpu: “250m”Code language: PHP (php)
  • クラスタのアップグレードも、GKE セキュリティのベストプラクティスの一環として実施されるべきです。定期的なアップグレードは、重大なセキュリティ上の欠陥やその他のバグを修正し、新しい機能を導入します。GKE は、クラスタとそのノードプールのアップグレードのバージョンとアップグレードの周期を管理するリリースチャネルを提供します。下位レベル(サンドボックスやプリプロダクションなど)では常に自動アップグレードを行い、アップグレード後にレビューを行うことをお勧めします。そのレベルですべてが期待通りに動作したら、次の自動アップグレードを次のレベルの環境(本番環境など)に適用できます。

アクセスはセキュリティのもう一つの重要な側面で、図1に描かれているように、ランタイムの一部です。

  • Google Cloud Project が作成されると、デフォルトでは自分だけがプロジェクトやそのリソースにアクセスできます。誰がそのプロジェクトにアクセスでき、何が許可されているかを管理するために、アイデンティティアクセス管理(IAM)はGoogle Cloudリソースとそのアクセスを管理する機能を提供します。役割ベースのアクセス制御(RBAC)がクラスタと名前空間レベルでアクセスを制御するのに対し、IAMはプロジェクトレベルで機能します。
  • もう1つのGKEセキュリティのベストプラクティスは、ネットワークをセグメント化または分離することです。これは、仮想プライベートクラウド(VPC)ネットワークを通じて行うことができます。GKEクラスタは、同じネットワーク上にある限り、異なるリージョン(例えば、us-east1とeurope-west1)であっても、内部IPを介して相互に通信することができます。
  • GKEでは、限定公開クラスタは、コントロールプレーンノードをパブリックインターネットからアクセスできないようにするクラスタです。限定公開クラスタでは、ノードはパブリックIPアドレスを持たず、プライベートアドレスのみを持ちます。これにより、ワークロードを分離された環境で実行できます。Control PlaneノードとWorkerノードは、VPCピアリングを使用して相互に通信します。
  • デフォルトでは、Kubernetesクラスタのネットワークトラフィックはオープンで、ポッドとサービスが相互に通信できるようになっています。ポッド間の通信を制限したり、必要なサービス間のみを許可するように制限したりするには、Networking Policyを使用します。ネットワークポリシーはラベルを使用してPodを選択し、ルールを使用してそれらのPodに向けられるネットワークトラフィックを定義します。
# Deny all traffic in the default namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: default
spec:
  podSelector: {}
  policyTypes:
Ingress
Egress

# NetworkPolicy that selects pods with label app=hello,
# and specifies Ingress policy to allow traffic only from Pods
# with the label app=foo: (GitHub repo)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: hello-allow-from-foo
spec:
  policyTypes:
  - Ingress
  podSelector:
    matchLabels:
      app: hello
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: foo

ネットワークポリシーを使用して、kubeletが使用するポート10250や10255などの機密ポートへのネットワークアクセスを制御することもできます。

  • 承認済みネットワークを使用すると、CIDR範囲を指定し、その範囲内のIPアドレスがHTTPSを使用してクラスタコントロールプレーンのエンドポイントにアクセスできるようにすることができます。マスター承認済み済みネットワークを有効にすると、承認済みネットワークを追加して、指定したIPアドレスのセットへのアクセスをさらに制限することができます。
  • ロードバランサ のサービスタイプを作成すると、Google Cloud はプロジェクトの外部からアクセス可能な安定した IP アドレスを持つネットワークロードバランサーをプロジェクト内に設定します。このサービスをGKEクラスタ内でアクセスできるようにしたい場合は、Kubernetesサービスマニフェストにアノテーションを追加します。しかし、インターネットに面したロードバランサーが必要で、すべてのIPアドレスに開放したくない場合は、loadBalancerSourceRangesをサービス仕様に追加して、接続を許可するIPアドレスブロックを制限することができます。
# Internal LB and Limit IP address on loadBalancerSourceRanges
# Resource internal load balancing.
apiVersion: v1
kind: Service
metadata:
  name: internal-load-balancer
  annotations:
    networking.gke.io/load-balancer-type: “Internal”
  labels:
    app: hello
spec:
  type: LoadBalancer
  selector:
    app: hello
  ports:
port: 80
targetPort: 8080
protocol: TCP
  loadBalancerSourceRanges:
10.88.0.0/16
35.35.35.10/32Code language: PHP (php)
  • GKEはコンテナネイティブ/レイヤ7ロードバランシングも導入しています。このイングレスオプションにより、いくつかの種類のロードバランサがポッドを直接ターゲットにし、ポッドにトラフィックを均等に分散できるようになります。これにより、ポッドはロードバランシングの第一級市民とみなされます。これは、ネットワークエンドポイントグループ(NEG)と呼ばれるGoogle Cloudデータモデルで実現できます。NEGはIP-ポート・ペアで表されるネットワーク・エンドポイントの集まりです。NEG が GKE Ingress とともに使用される場合、Google が管理する Kubernetes ingress コントローラーが採用され、L7 ロードバランサーのすべての側面の作成が容易になります。 これには仮想IPアドレスの作成、転送ルール、ヘルスチェック、ファイアウォールルールなどが含まれます。
# Ingress Resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  labels:
    app.kubernetes.io/name: sre-devops
  annotations:
    # To force https which requires the secretName
    kubernetes.io/ingress.allow-http: “false”
    # Annotation for an internal L7 load balancer
    kubernetes.io/ingress.class: gce-internal
    # Annotation for an external L7 load balancer
    kubernetes.io/ingress.class: “gce”
spec:
  tls:
hosts:
“my-example.foo.com”
    secretName: foo.com
  rules:
host: “my-example.foo.com”
    http:
      paths:
path: /*
          pathType: ImplementationSpecific
          backend:
            service:
              name: my-service
              port:
                number: 443

# Service Resource
# To bind the service to ingress, Type: ClusterIP is needed and
# annotation: cloud.google.com/neg: ‘{“ingress”: true}’
apiVersion: v1
kind: Service
metadata:
  name: my-service
  annotations:
  # Required annotation
  cloud.google.com/neg: ‘{“ingress”: true}’
  # To force https from the LB to the backend
  cloud.google.com/app-protocols: ‘{“my-https-port”: “HTTPS”}’
  # Applies backend-config named allowed-ingress-acls
  cloud.google.com/backend-config: ‘{“default”: allowed-ingress-acls}’
spec:
  # Make sure this is set and not LoadBalancer
  type: clusterIP
  ports:
Name: my-https-port
    Port: 443
    Protocol: TCP
    targetPort: 8080
  selector:

ストレージは、GKE 上で実行するアプリケーションのデータを保存する場所です。いくつかのオプションから選択できます。

  • データベースの場合は、Cloud SQLDatastore、またはCloud Spanner
  • オブジェクトストレージならCloud Storage
  • プライベートコンテナイメージ、helm charts、ビルドアーティファクトには、Artifact Registry を使用できます。
  • ットワーク接続ストレージ(NAS)を必要とするアプリケーションには、Filestoreを使用します。
  • ブロックストレージを必要とするアプリケーションには、persistent diskを使用します。このディスクは、手動でプロビジョニングすることも、GKE によって動的にプロビジョニングすることもできます。
  • PersistentVolume(PV)は、Podがストレージとして使用できるクラスタリソースです。一方、PersistentVolumeClaim(PVC)は、Compute Engine Persistent diskでバックアップされたPersistentVolumeをクラスタで使用するために動的にプロビジョニングするために使用できます。
  • Google Key Management Store (KMS) を使用して、アプリケーションで使用する暗号化された StorageClass を作成できます。

Google Cloud監査ログ

GKE セキュリティのもう一つの重要な側面は、監査ログです。これは以下の点で重要です:

  • クラスタのセキュリティを評価するための監査証跡。
  • 既存または将来の脅威の分析
  • 過去のインシデントや将来の脅威に基づいて、既存のネットワークポリシーとセキュリティポリシーを更新します。

GKEは、クラウドモニタリングクラウドロギングで構成される優れたGoogle Cloudのオペレーションスイートを提供します。

クラウドロギングでは、ダッシュボードやアラートを設定することができ、脅威の特定に役立ちます。これにより、継続的に監視し、クラウドロギングによって報告された内容に基づいて既存のセキュリティポリシーを更新することができます。

結論

Kubernetesは成長と拡張を続けるテクノロジーです。したがって、GKEのセキュリティもそれに合わせる必要があります。システムを保護し、セキュアにすることは、時に、圧倒的です。この記事で紹介するGKEセキュリティの助けを借りれば、これを達成することができます。

たとえば、次のような方法があります:

  • シフトレフト – セキュリティは、ソフトウェア開発ライフサイクルの左側、つまり開発から始めるべきです。Cloud Codeを使い、イメージをスキャンし、Artifact Registryにアーティファクトを保存することは、良いスタートです。
  • システムのアップグレード – これはコンテナアプリケーションやKubernetesなどです。GKEはリリースチャネルを提供しています。
  • アクセスの制限 – コンピュート、Kubernetesリソース、ストレージ、ワークロード/サービスなどへのアクセスを制限する必要があります。このために、GKEはRBAC、IAM、ロードバランシング、ネットワークポリシー、プライベートクラスタ、サービスメッシュなどを提供します。RBAやIAMなど、理解しやすく実装しやすいものから始めるようにすればよいのです。
  • 最小特権、リソースとリクエストの制限 – これは、rootユーザーがポッド内のどのプロセスも実行できないようにするために重要です(良いスタートです)。また、ノードやクラスタが過剰に使用されるのを防ぐために、リソースとリクエストの上限を適宜設定する必要があります。
  • クラウドロギングを使用した継続的な監査 – 脅威の特定に役立ち、既存のネットワークやセキュリティポリシーを更新できます。

その他の資料