Kubernetes Basics
Kubernetesの基礎
このページの元の著者は Jorge (彼の元の投稿は こちら)
アーキテクチャと基礎
Kubernetesは何をするのか?
コンテナエンジンでコンテナを実行することができます。
スケジュールにより、コンテナのミッションを効率的に行うことができます。
コンテナを生きたままに保つことができます。
コンテナ間の通信を可能にします。
デプロイメントの技術を可能にします。
大量の情報を処理します。
アーキテクチャ
ノード: ポッドまたはポッドを持つオペレーティングシステム。
ポッド: 1つのアプリケーションのみを含むべきです(通常、1つのコンテナのみを実行するため、ポッドはコンテナ技術の実行方法を抽象化するためのものです)。
サービス: 各ポッドは、ノードの内部範囲から1つの内部IPアドレスを持っています。ただし、サービスを介しても公開できます。サービスにもIPアドレスがあり、その目的はポッド間の通信を維持することです。したがって、1つのポッドが死んだ場合、新しい置き換え(異なる内部IPを持つ)は、サービスの同じIPでアクセス可能になります。内部または外部として設定できます。サービスは、2つのポッドが同じサービスに接続されている場合にロードバランサーとして機能します。 サービスが作成されると、実行中の各サービスのエンドポイントを見つけることができます
kubectl get endpoints
Kubelet: プライマリノードエージェント。ノードとkubectlの間の通信を確立し、ポッドのみを実行できます(APIサーバーを介して)。Kubeletは、Kubernetesによって作成されていないコンテナを管理しません。
Kube-proxy: apiserverとノード間の通信(サービス)を担当するサービスです。ノードのIPテーブルをベースにしています。経験豊富なユーザーは、他のベンダーからの他のkube-proxyをインストールすることができます。
サイドカーコンテナ: サイドカーコンテナは、ポッド内のメインコンテナと一緒に実行する必要があるコンテナです。このサイドカーパターンは、現在のコンテナの機能を拡張および強化するものです。現在、アプリケーションをどこでも実行するためにコンテナ技術を使用して依存関係をすべてラップすることを知っています。コンテナは1つのことだけを行い、そのことを非常によく行います。
マスタープロセス:
APIサーバー: ユーザーとポッドがマスタープロセスと通信するための方法です。認証されたリクエストのみが許可されるべきです。
スケジューラ: スケジューリングは、Kubeletが実行できるように、ポッドがノードにマッチングされることを確認することを指します。スケジューラは、より多くの利用可能なリソースを持つノードを決定し、新しいポッドをそれに割り当てるための十分な知識を持っています。スケジューラは新しいポッドを起動するのではなく、ノード内で実行されているKubeletプロセスと通信するだけです。
Kube Controller Manager: レプリカセットやデプロイメントなどのリソースをチェックし、正しい数のポッドやノードが実行されているかどうかを確認します。ポッドが欠落している場合、スケジューラと通信して新しいポッドを起動します。これにより、APIへのレプリケーション、トークン、およびアカウントサービスの制御が可能になります。
etcd: データストレージ、永続的で一貫性のある分散データベースです。Kubernetesのデータベースであり、クラスターの完全な状態を保持するためのキーバリューストレージです(変更はすべてここに記録されます)。スケジューラやコントローラマネージャなどのコンポーネントは、変更が発生したことを知るためにこのデータに依存します(ノードの利用可能なリソース、実行中のポッドの数など)。
クラウドコントローラーマネージャ: AWSやOpenStackなどのクラスターがある場合、フローコントロールとアプリケーションのための特定のコントローラーです。
ノードが複数ある場合(複数のポッドを実行している場合)、アクセス先のApiサーバーは負荷分散され、etcdは同期されることに注意してください。
ボリューム:
ポッドが消えても失われてはならないデータを作成する場合、物理ボリュームに保存する必要があります。Kubernetesは、データを永続化するためにボリュームをポッドにアタッチすることを許可します。ボリュームはローカルマシンまたはリモートストレージにある場合があります。異なる物理ノードでポッドを実行している場合は、リモートストレージを使用する必要があります。
その他の設定:
ConfigMap: サービスにアクセスするためのURLを設定できます。ポッドは、他のサービス(ポッド)との通信方法を知るためにここからデータを取得します。ただし、
PKIインフラストラクチャ - 証明書機関 CA:
CAはクラスタ内のすべての証明書の信頼されたルートです。
コンポーネント同士の相互検証を可能にします。
クラスタのすべての証明書はCAによって署名されます。
ETCdには独自の証明書があります。
タイプ:
apiserver証明書。
kubelet証明書。
スケジューラ証明書。
基本的な操作
Minikube
Minikubeは、完全なKubernetes環境を展開する必要なく、Kubernetes上でいくつかのクイックテストを実行するために使用できます。マスターとノードプロセスを1つのマシンで実行します。Minikubeは、ノードを実行するためにvirtualboxを使用します。ここでインストール方法を確認してください。
Kubectlの基本
**Kubectl
**は、Kubernetesクラスターのためのコマンドラインツールです。これは、KubernetesのマスタープロセスのApiサーバーと通信して、Kubernetesでのアクションを実行したりデータを要求したりします。
Minikube ダッシュボード
ダッシュボードを使用すると、minikubeが実行している内容を簡単に確認できます。アクセスするためのURLは以下の場所にあります:
YAML設定ファイルの例
各設定ファイルには3つのパートがあります: metadata(メタデータ)、specification(起動する必要があるもの)、status(望ましい状態)。 デプロイメント設定ファイルのspecificationの中には、実行するイメージを定義する新しい構成構造で定義されたテンプレートが含まれています。
同じ設定ファイルで宣言されたデプロイメント+サービスの例(こちらから)
サービスは通常、1つのデプロイメントに関連しているため、同じ設定ファイルで両方を宣言することができます(この設定で宣言されたサービスは内部からのみアクセス可能です)。
外部サービスの設定の例
このサービスは外部からアクセス可能です(nodePort
とtype: LoadBalancer
属性を確認してください):
これはテストには便利ですが、本番環境では内部サービスのみと、アプリケーションを公開するためのIngressを持つべきです。
Ingress設定ファイルの例
これにより、アプリケーションが http://dashboard.com
で公開されます。
シークレット設定ファイルの例
パスワードがB64でエンコードされていることに注意してください(これは安全ではありません!)
ConfigMapの例
ConfigMapは、ポッドに与えられる設定であり、他のサービスの場所を特定し、アクセスする方法をポッドに知らせるために使用されます。この場合、各ポッドは、mongodb-service
という名前が、通信できるポッドのアドレスであることを知っています(このポッドはmongodbを実行しています):
次に、デプロイメント設定内でこのアドレスを指定することで、ポッドの環境変数に読み込まれるようになります。
ボリューム設定の例
https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumesには、さまざまなストレージ設定のyamlファイルの例があります。 ボリュームは名前空間の内部にありません
名前空間
Kubernetesは、同じ物理クラスタをバックエンドとする複数の仮想クラスタをサポートしています。これらの仮想クラスタは名前空間と呼ばれます。これらは、多くのユーザーが複数のチームまたはプロジェクトに分散している環境で使用することを想定しています。数人から数十人のユーザーがいるクラスタでは、名前空間を作成したり考えたりする必要はありません。Kubernetesで展開されたアプリケーションの各部分をより良く制御し、組織化するために名前空間を使用する必要があります。
名前空間は名前のスコープを提供します。リソースの名前は名前空間内で一意である必要がありますが、名前空間間では一意である必要はありません。名前空間は互いにネストすることはできず、各Kubernetesリソースは1つの名前空間にのみ存在できます。
minikubeを使用している場合、デフォルトで4つの名前空間があります。
kube-system: ユーザーが使用することを意図されていないため触れないでください。マスターとkubectlプロセス用です。
kube-public: 公開可能なデータです。クラスター情報を含むコンフィグマップが含まれています。
kube-node-lease: ノードの可用性を決定します。
default: ユーザーがリソースを作成するために使用する名前空間です。
ほとんどのKubernetesリソース(例:ポッド、サービス、レプリケーションコントローラなど)は、いくつかの名前空間に存在します。ただし、名前空間リソースやノード、永続ボリュームなどの低レベルリソースなど、他のリソースは名前空間に存在しません。Kubernetesリソースが名前空間に存在するかどうかを確認するには、次の手順を実行します:
そのコンテキストで、すべての後続のkubectlコマンドのために名前空間を保存することができます。
Helm
HelmはKubernetesのパッケージマネージャーです。YAMLファイルをパッケージ化し、公開およびプライベートのリポジトリで配布することができます。これらのパッケージはHelmチャートと呼ばれます。
Helmは変数を使用して設定ファイルを生成することができるテンプレートエンジンです。
Kubernetesのシークレット
シークレットは、パスワード、トークン、キーなどの機密データを含むオブジェクトです。このような情報は通常、Podの仕様やイメージに配置されます。ユーザーはシークレットを作成することもできますし、システムもシークレットを作成します。シークレットオブジェクトの名前は有効なDNSサブドメイン名である必要があります。公式ドキュメントを参照してください。
シークレットには以下のようなものがあります:
API、SSHキー。
OAuthトークン。
資格情報、パスワード(平文またはb64 + 暗号化)。
情報やコメント。
データベース接続コード、文字列など。
Kubernetesにはさまざまなタイプのシークレットがあります。
組み込みタイプ | 使用法 |
---|---|
Opaque | ユーザー定義の任意のデータ(デフォルト) |
kubernetes.io/service-account-token | サービスアカウントトークン |
kubernetes.io/dockercfg | シリアル化された~/.dockercfgファイル |
kubernetes.io/dockerconfigjson | シリアル化された~/.docker/config.jsonファイル |
kubernetes.io/basic-auth | 基本認証の資格情報 |
kubernetes.io/ssh-auth | SSH認証の資格情報 |
kubernetes.io/tls | TLSクライアントまたはサーバーのデータ |
bootstrap.kubernetes.io/token | ブートストラップトークンデータ |
Opaqueタイプはデフォルトのタイプであり、ユーザーによって定義される典型的なキーと値のペアです。
シークレットの動作方法:
次の設定ファイルは、username: YWRtaW4=
とpassword: MWYyZDFlMmU2N2Rm
の2つのキーと値のペアを持つmysecret
というシークレットを定義しています。また、secretpod
というポッドも定義されており、mysecret
で定義されたusername
とpassword
が環境変数SECRET_USERNAME
とSECRET_PASSWORD
で公開されます。さらに、username
シークレットをmysecret
内のパス/etc/foo/my-group/my-username
に0640
のパーミッションでマウントします。
etcd内のシークレット
etcdは、Kubernetesのバックエンドストアとして使用される一貫性のある高可用性のキーバリューストアです。etcdに保存されているシークレットにアクセスしましょう。
以下は、/hive/hacktricks-cloud/pentesting-cloud/kubernetes-security/kubernetes-basics.md ファイルからのコンテンツです。訳文を提供しますが、コード、ハッキング技術の名前、ハッキング用語、クラウド/SaaSプラットフォームの名前(Workspace、aws、gcpなど)、'leak'という単語、pentesting、およびマークダウンタグなどは翻訳しないでください。また、翻訳とマークダウンの構文以外の追加の要素は追加しないでください。
訳文:
通信を確立すると、シークレットを取得することができます。
ETCDへの暗号化の追加
デフォルトでは、etcd内のすべてのシークレットは平文で保存されます。ただし、暗号化レイヤーを適用しない限り、これは変わりません。以下の例は、https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/を基にしています。
その後、作成した設定ファイルの場所を指すように、kube-apiserver
の --encryption-provider-config
フラグを設定する必要があります。/etc/kubernetes/manifest/kube-apiserver.yaml
を編集し、以下の行を追加します:
volumeMounts の中をスクロールダウンしてください:
ボリュームマウントの中で、hostPathにスクロールダウンしてください。
データが暗号化されていることの確認
データはetcdに書き込まれる際に暗号化されます。kube-apiserver
を再起動した後、新しく作成されたまたは更新されたシークレットは、保存される際に暗号化されるはずです。確認するために、etcdctl
コマンドラインプログラムを使用してシークレットの内容を取得できます。
default
ネームスペースにsecret1
という新しいシークレットを作成します:
etcdctlコマンドラインを使用して、etcdからそのシークレットを読み取ります:
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
[...]
はetcdサーバーに接続するための追加の引数である必要があります。
保存されたシークレットが
k8s:enc:aescbc:v1:
で始まることを確認します。これは、aescbc
プロバイダーが結果のデータを暗号化したことを示しています。API経由で取得した際にシークレットが正しく復号化されていることを確認します:
はmykey: bXlkYXRh
と一致するはずです。mydataはエンコードされています。シークレットを完全にデコードするには、シークレットのデコードを確認してください。
シークレットは書き込み時に暗号化されるため、シークレットの更新を行うとその内容が暗号化されます。
最終的なヒント:
秘密をファイルシステムに保存しないようにし、他の場所から取得してください。
https://www.vaultproject.io/ をチェックして、秘密情報をさらに保護します。
参考文献
最終更新