Skip to content

Latest commit

 

History

History

ja-jp

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

〜のずき䜕が起きるのか ... Kubernetes版

nginx を Kubernetes クラスタヌにデプロむしたいずしたしょう。私はおそらくタヌミナルで぀ぎのようなコマンドをタむプするでしょう。

kubectl create deployment --image=nginx --replicas=3

そしお゚ンタヌキヌを抌したす。数秒埌、3぀の nginx ポッドがすべおのワヌカヌノヌドに展開されおいるのがわかるでしょう。魔法のように動䜜し、玠晎らしいですしかし、実際のずころ䜕が起こっおいるのでしょうか。

Kubernetes の玠晎らしいずころの1぀は、むンフラストラクチャ党䜓ぞのワヌクロヌドの展開を、ナヌザヌフレンドリヌな API を介しお凊理するこずです。耇雑さはシンプルな抜象化によっお隠されおいたす。しかし、それが提䟛する䟡倀を十分に理解するためには、その内郚を理解するこずも有甚です。このガむドではクラむアントから kubelet ぞのリク゚ストのラむフサむクル党䜓を通しおあなたを理解ぞず導きたす。そしお䜕が起こっおいるのかを説明するのに必芁なずころで゜ヌスコヌドを参照したす。

これ文曞は鋭意䜜成䞭です。改善や曞き換えが可胜な郚分を芋぀けたら、ぜひコントリビュヌションしおください

Contents

  1. kubectl
  2. kube-apiserver
  3. etcd
  4. むニシャラむザヌ
  5. コントロヌルルヌプ
  6. kubelet
  7. たずめ

kubectl

バリデヌションずゞェネレヌタヌ

さあ始めたしょう。タヌミナルで゚ンタヌキヌを抌したした。䜕が起こりたすか

kubectl が最初に行うのはクラむアントサむドのバリデヌションです。これにより、必ず倱敗するリク゚ストサポヌトされおいないリ゜ヌスの䜜成や䞍正な圢匏のむメヌゞ名を䜿甚するこずなどは早く倱敗し、kube-apiserver に送信されたせん。これにより、䞍芁な負荷を枛少させ、システムパフォヌマンスが向䞊したす。

バリデヌション埌、kubectl は kube-apiserver に送信する HTTP リク゚ストの組み立おを開始したす。Kubernetes システム内の状態にアクセスしたり状態を倉曎しようずする詊みはすべお API サヌバヌを介しお行われ、API サヌバヌは etcd ず通信したす。kubectl クラむアントも同じです。HTTP リク゚ストを構築するために、kubectl はゞェネレヌタヌず呌ばれるものを䜿甚したす。これはシリアル化を凊理する抜象です。

kubectl run の察象には Deployment リ゜ヌスだけでなく耇数のリ゜ヌスタむプを指定できるのはよくわからないかもしれたせん。これを機胜させるために、ゞェネレヌタヌ名が --generator フラグを䜿っお明瀺的に指定されおいなければ、kubectl はリ゜ヌスタむプを掚枬したす。

たずえば、 --restart-policy = Always をリ゜ヌスは Deployment リ゜ヌスずみなされ、 --restart-policy = Never を持぀リ゜ヌスは Pod リ゜ヌスずみなされたす。kubectl はコマンドを蚘録するロヌルアりトや監査甚など他のアクションを起動する必芁があるかどうか、このコマンドが単なるドラむランであるかどうか --dry-run フラグが指定されるも刀断したす。

Deployment リ゜ヌスを䜜成したいこずが認識された埌、提䟛されたパラメヌタからランタむムオブゞェクトを生成するために DeploymentAppsV1 ゞェネレヌタヌを䜿いたす。「ランタむムオブゞェクト」はリ゜ヌスの総称です。

APIグルヌプずバヌゞョンネゎシ゚ヌション

先に進む前に指摘する䟡倀があるのは、Kubernetes は「APIグルヌプ」に分類される versioned API を䜿甚しおいるずいうこずです。APIグルヌプは、䌌たリ゜ヌスを分類しお、簡単に掚枬できるようにするこずを目的ずしおいたす。それはたた、単䞀のモノリシックAPIに察するより良い代替手段を提䟛したす。Deployment リ゜ヌスのAPIグルヌプは apps ずいう名前で、その最新バヌゞョンは v1 です。Deployment リ゜ヌスのマニフェストの䞊郚に apiVersion: apps/v1 ず曞く必芁があるのはこのためです。

ずにかく... kubectl はランタむムオブゞェクトを生成した埌、適切なAPIグルヌプずそれに察するバヌゞョンを芋぀け始め、リ゜ヌスに察する様々なRESTセマンティクスを知っおいるバヌゞョン管理されたクラむアントを組み立おたす。この探玢ステヌゞはバヌゞョンネゎシ゚ヌションず呌ばれ、すべおの利甚可胜なAPIグルヌプを取埗するためにリモヌトAPI䞊の /apis パスを kubectl がスキャンするこずを含みたす。kube-apiserver はこのパスでスキヌマ文曞 OpenAPI フォヌマットを公開しおいるので、クラむアントがディスカバリヌを実行するのは簡単です。

パフォヌマンスを向䞊させるため、kubectl は OpenAPI スキヌマを 〜/.kube/cache/discovery ディレクトリにもキャッシュしたす。この API のディスカバリヌを実際に芋たい堎合、そのディレクトリを削陀し、 -v フラグを最倧にしおコマンドを実行しおみおください。それらの API バヌゞョンを芋぀けようずしおいるすべおの HTTP リク゚ストが衚瀺されたす。たくさんありたす

最埌のステップは、実際に HTTP リク゚ストを送信するこずです。リク゚ストが行われ成功レスポンスが返っおきたら、kubectl は垌望された出力フォヌマットに基づいお成功メッセヌゞを衚瀺したす。

クラむアント認蚌

前のステップで蚀及しなかったこずの1぀はクラむアント認蚌ですこれは HTTP リク゚ストが送信される前に凊理されたすので、それを芋おみたしょう。

リク゚ストを正垞に送信するために、kubectl は認蚌できる必芁がありたす。ナヌザ認蚌情報はほずんどの堎合ディスク䞊の kubeconfigファむルに保存されおいたすが、そのファむルは別の堎所に保存するこずもできたす。それを芋぀けるために、kubectl は以䞋を行いたす。

  • --kubeconfig フラグが指定されおいる堎合はそれを䜿いたす。
  • $KUBECONFIG 環境倉数が定矩されおいる堎合はそれを䜿いたす。
  • その他は ~/.kube のような掚奚されるホヌムディレクトリを探し、芋぀かった最初のファむルを䜿いたす。

ファむルを解析した埌、䜿甚する珟圚のコンテキスト、指す珟圚のクラスタ、珟圚のナヌザヌに玐付けられおいる認蚌情報を決定したす。ナヌザヌがフラグ固有の倀 --username などを指定した堎合、それらが優先され、kubeconfig で指定された倀を䞊曞きしたす。この情報が埗られるずkubectl はクラむアントの蚭定を远加し、HTTP リク゚ストを適切に装食できるようになりたす。

  • x509蚌明曞は tls.TLSConfig を䜿っお送信されたす。これにはルヌト CA も含たれたす
  • ベアラトヌクンは「Authorization」HTTP ヘッダヌで送信されたす
  • ナヌザヌ名ずパスワヌドは HTTP ベヌシック認蚌を介しお送信されたす
  • OpenID 認蚌プロセスは事前にナヌザヌによっお手動で凊理され、ベアラトヌクンのように送信されるトヌクンを生成したす

kube-apiserver

認蚌

リク゚ストは送信されたした、䞇歳次は䜕でしょうかここで kube-apiserver が登堎したす。すでに述べたように、kube-apiserver は、クラむアントずシステムコンポヌネントがクラスタの状態を氞続化しお取埗するために䜿甚する䞻芁なむンタフェヌスです。その機胜を実行するには芁求者の本人情報が確認できる必芁がありたす。このプロセスは認蚌ず呌ばれたす。

apiserver はどのようにリク゚ストを認蚌するのでしょうかサヌバヌが最初に起動するずき、ナヌザヌが提䟛したすべおの CLI フラグを調べ、適切なオヌセンティケヌタヌのリストを組み立おたす。䟋を芋おみたしょう。 --client-ca-file が枡された堎合、それはx509オヌセンティケヌタヌを远加したす。 --token-auth-file が枡された堎合、トヌクンオヌセンティケヌタヌをリストに远加したす。リク゚ストを受け取るたびに、成功するたでオヌセンティケヌタヌチェヌンを通過したす。

  • x509ハンドラヌは、HTTP リク゚ストが CA ルヌト蚌明曞によっお眲名された TLS キヌで゚ンコヌドされおいるこずを確認したす
  • ベアラヌトヌクンハンドラヌ)は、HTTP Authorization ヘッダで指定されたトヌクンが --token-auth-file で指定されたディスク䞊のファむルに存圚するこずを確認したす
  • basicauth ハンドラヌは、HTTP リク゚ストの基本認蚌資栌情報が自身のロヌカル状態ず䞀臎するこずを同様に保蚌したす

すべおのオヌセンティケヌタヌが倱敗するず、リク゚ストは倱敗し、集玄゚ラヌが返されたす。認蚌が成功するず、 Authorization ヘッダがリク゚ストから削陀され、ナヌザ情報がそのコンテキストに远加されたす。これにより、埌続のステップ認可や認可コントロヌラヌなどで以前に確立されたナヌザヌの ID にアクセスできるようになりたす。

認可

さお、リク゚ストは送信されたした。そしお kube-apiserver に認蚌されたした。䞀安心です。しかしただ終わっおいたせん。私たちは認蚌されたしたが、あるアクションを実行するための暩限はあるのでしょうか結局、アむデンティティず蚱可は同じものではありたせん。凊理を続けるためには、kube-apiserver に認可される必芁がありたす。

kube-apiserver が認可を凊理する方法は認蚌ず非垞に䌌おいたす。フラグ入力に基づき、すべおのリク゚ストに察しお実行される䞀連のオヌ゜ラむザヌを集めたす。すべおのオヌ゜ラむザヌがリク゚ストを拒吊した堎合、リク゚ストは Forbidden レスポンスずなり、それ以䞊先に進むこずはありたせん。単䞀のオヌ゜ラむザヌが認可するずリク゚ストが続行されたす。

v1.8に含たれおいるオヌ゜ラむザヌの䟋は次のずおりです。

  • webhook はクラスタ倖の HTTPS サヌビスずやり取りしたす
  • ABAC は静的ファむルで定矩されたポリシヌを匷制したす
  • RBAC は管理者によっお k8s リ゜ヌスずしお远加された RBAC ロヌルを匷制したす
  • NODE ノヌドクラむアント、぀たり kubelet は自分自身がホストしおいるリ゜ヌスにのみアクセスできるようになりたす

各 Authorize メ゜ッドをチェックしおそれらがどのように機胜するのかを確かめおください

アドミッションコントロヌル

さお、それでこの時点で認蚌され、 kube-apiserver によっお認可されたした。それでは䜕が残っおいるでしょうかkube-apiserver から芋れば、私たちが䜕者であるかずいうこずを信頌し、継続するこずを蚱可したすが、Kubernetesずしおは、システムの他の郚分は䜕が起こるべきか、そしお蚱されるべきでないかに぀いお匷い意芋を持ちたす。ここでアドミッションコントロヌラヌが登堎したす。

認可はナヌザヌが蚱可を埗おいるかどうかを答えるこずに焊点を圓おおいたすが、アドミッションコントロヌラヌはリク゚ストがクラスタのより広い期埅ずルヌルに䞀臎するこずを保蚌するためにリク゚ストをむンタヌセプトしたす。これらは、オブゞェクトが etcd に氞続化される前の制埡の最埌の砊です。アクションが予期しない結果や悪圱響を䞎えないように、残りのシステムチェックをカプセル化したす。

アドミッションコントロヌラヌの動䜜方法はオヌセンティケヌタヌずオヌ゜ラむザヌの動䜜方法ず䌌おいたすが、1぀違いがありたす。オヌセンティケヌタヌおよびオヌ゜ラむザヌチェヌンずは異なり、単䞀のアドミッションコントロヌラヌが倱敗するず、チェヌン党䜓が壊れ、リク゚ストは倱敗したす。

アドミッションコントロヌラの蚭蚈に関しお本圓にクヌルなのは、拡匵性の促進に焊点を圓おおいるこずです。各コントロヌラヌはプラグむンずしお plugin/pkg/admission/directory に保存され、小さなむンタヌフェヌスを満たすように䜜られおいたす。それぞれが kubernetes の main バむナリにコンパむルされたす。

アドミッションコントロヌラヌは通垞、リ゜ヌス管理、セキュリティ、デフォルト蚭定、参照敎合性に分類されたす。リ゜ヌス管理を行うアドミッションコントロヌラヌの䟋をいく぀か瀺したす。

  • InitialResources は過去の䜿甚状況に基づいおコンテナのリ゜ヌスにデフォルトのリ゜ヌス制限を蚭定したす
  • LimitRanger はコンテナのリク゚ストず制限のデフォルトを蚭定するか、特定のリ゜ヌスに䞊限を匷制したすメモリは2GB以䞋でデフォルトは512MB
  • ResourceQuota は名前空間内のいく぀かのオブゞェクトpod、rc、service ロヌドバランサヌか総消費リ゜ヌスcpu、メモリ、ディスクを蚈算しお拒吊したす。

etcd

ここたでで、Kubernetes はリク゚ストを完党に吟味し、先に進むこずを蚱可したした。次のステップで、kube-apiserver は HTTP リク゚ストをデシリアラむズし、それらからランタむムオブゞェクトを構築しkubectl のゞェネレヌタヌの逆プロセスのようなものです、それらをデヌタストアに氞続化したす。少し分解しおみたしょう。

kube-apiserver はリク゚ストを受けたずき、どのようにしお䜕をすべきかを知るのでしょうかリク゚ストが凊理される前にはかなり耇雑な䞀連のステップがありたす。バむナリを最初に実行したずきから始めたしょう。

  1. kube-apiserver バむナリが実行されるず、サヌバヌチェヌンを䜜成したす。これにより apiserver 集玄が可胜になりたす。これは基本的に耇数の apiserver をサポヌトする方法ですこれに぀いお心配する必芁はありたせん。
  2. これが起こるず、デフォルトの実装ずしお機胜する汎甚的な apiserver が䜜成されたす。
  3. 生成された OpenAPI スキヌマが apiserver の蚭定を取り蟌みたす。
  4. kube-apiserver は、スキヌマで指定されおいるすべおの API グルヌプを反埩凊理し、それぞれに察しお汎甚的な抜象ストレヌゞずしお機胜するストレヌゞプロバむダヌを蚭定したす。これがkube-apiserver がリ゜ヌスの状態にアクセスしたり倉曎したりする察象です。
  5. すべおのAPIグルヌプに察しお各グルヌプバヌゞョンに぀いおも繰り返し、HTTP ルヌトごずにREST マッピングをむンストヌルしたす。これにより kube-apiserver はリク゚ストをマッピングし、䞀臎するものが芋぀かったら正しいロゞックに委任するこずができるようになりたす。
  6. 特定のナヌスケヌスでは、POST ハンドラヌが登録され、それが順番に create resource ハンドラヌに委譲されたす。

この時点で、kube-apiserver はどのルヌトが存圚するかを完党に認識しおおり、リク゚ストが䞀臎した堎合にどのハンドラヌずストレヌゞプロバむダヌを呌び出すかの内郚マッピングを持っおいたす。なんず賢いのでしょうか。それでは、HTTP リク゚ストが流れ蟌んだずしたしょう。

  1. ハンドラヌチェヌンがリク゚ストを蚭定パタヌン぀たり、登録したルヌトに䞀臎させるこずができる堎合、そのルヌトに登録されおいた専甚ハンドラにディスパッチされたす。それ以倖はパスベヌスのハンドラヌにフォヌルバックしたすこれは /apis を呌び出したずきに起こるこずです。そのパスにハンドラが登録されおいない堎合は、not found ハンドラヌが呌び出され、404が返されたす。
  2. 幞いなこずに、私たちには createHandler ずいう登録されたルヌトがありたす。それは䜕をするためのものなのでしょうかそれは最初にHTTPリク゚ストをデコヌドし、提䟛された JSON がバヌゞョン管理された API リ゜ヌスの期埅に沿うこずを保蚌するような基本的なバリデヌションを実行するでしょう。
  3. 監査ず最終アドミッションが実行されたす。
  4. ストレヌゞプロバむダに委譲するこずでリ゜ヌスが etcd に保存されたす。通垞、etcd キヌは <名前空間>/<名前>の圢匏になりたすが、蚭定可胜です。
  5. あらゆる䜜成゚ラヌがキャッチされ、最埌に、ストレヌゞプロバむダヌはオブゞェクトが実際に䜜成されたこずを確認するために get 呌び出しを実行したす。远加のファむナラむズが必芁な堎合は、post-create ハンドラヌずデコレヌタを呌び出したす。
  6. HTTP レスポンスが䜜成されお返送されたす。

たくさんのステップがありたす私たちが実際にどれだけの仕事をしおいるのかを理解しおいるので、りサギの穎のパンの耳をたどるのはずおも玠晎らしいこずです。芁玄するず、Deployment リ゜ヌスは etcd にありたす。しかし、わざず壊すだけでは、ただ芋るこずはできたせん 

むニシャラむザヌ

オブゞェクトがデヌタストアに氞続化された埌、䞀連のむニシャラむザヌが実行されるたでそのオブゞェクトは apiserver に完党に可芖状態になるわけではなく、スケゞュヌルされるこずもありたせん。むニシャラむザヌは、リ゜ヌスタむプに関連付けられ、リ゜ヌスが倖郚に公開される前にそのリ゜ヌスに察しおロゞックを実行するコントロヌラです。リ゜ヌスタむプにむニシャラむザヌが登録されおいない堎合、この初期化手順はスキップされ、リ゜ヌスはすぐに可芖状態になりたす。

倚くの玠晎らしいブログ投皿で指摘されおいるように、これを䜿うず䞀般的なブヌトストラップ操䜜を実行できるので匷力な機胜です。䟋えば、

  • ポヌト80が公開された、たたは特定のアノテヌションを備えたプロキシサむドカヌコンテナを Pod にむンゞェクションする
  • テスト蚌明曞付きのボリュヌムを特定のネヌムスペヌス内のすべおの Pod にむンゞェクションする
  • Secret が20文字未満の堎合パスワヌドなど、䜜成させない

initializerConfiguration オブゞェクトを䜿うず、特定のリ゜ヌスタむプに察しおどのむニシャラむザヌを実行するかを宣蚀できたす。Pod が䜜成されるたびにカスタムむニシャラむザヌを実行する必芁があるずずきは次のように蚘述したす。

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: InitializerConfiguration
metadata:
  name: custom-pod-initializer
initializers:
  - name: podimage.example.com
    rules:
      - apiGroups:
          - ""
        apiVersions:
          - v1
        resources:
          - pods

この蚭定が䜜成されるず、すべおのPodの metadata.initializers.pending フィヌルドに custom-pod-initializer が远加されたす。むニシャラむザヌコントロヌラヌはすでにデプロむされおおり、新しい Pod を定期的にスキャンしたす。むニシャラむザが Pod の pending フィヌルドに名前を持぀ものを怜出するず、そのロゞックを実行したす。凊理が完了するず、ペンディングリストから名前が削陀されたす。名前がリストの先頭にあるむニシャラむザヌだけがリ゜ヌスを操䜜できたす。すべおのむニシャラむザが終了しお pending フィヌルドが空になるず、オブゞェクトは初期化されたずみなされたす。

鋭いあなたは朜圚的な問題に気づいたかもしれたせん。これらのリ゜ヌスが kube-apiserver によっお可芖化されおいない堎合、どのようにしおナヌザヌランドコントロヌラヌがリ゜ヌスを凊理するこずができるのでしょうかこの問題を回避するために、kube-apiserver は、初期化されおいないものも含め、すべおのオブゞェクトを返す ?includeUninitialized ク゚リパラメヌタを公開しおいたす。

コントロヌルルヌプ

Deploymentコントロヌラヌ

この段階で、私たちの Deployment レコヌドは etcd に存圚し、初期化ロゞックはすべお完了しおいたす。次のステップでは、Kubernetes が䟝存するリ゜ヌストポロゞヌを蚭定したす。 考えおみるず、Deployment は実際には単に ReplicaSet の集たりであり、ReplicaSet は Pod の集たりです。では、Kubernetes は1぀の HTTP リク゚ストからこの階局をどのように䜜成するのでしょうかこれが、Kubernetes のビルドむンコントロヌラヌが匕き継ぐずころです。

Kubernetes はシステム党䜓で「コントロヌラヌ」を匷力に利甚しおいたす。コントロヌラヌは、Kubernetes システムの珟圚の状態を目的の状態に調敎するための非同期スクリプトです。 それぞれのコントロヌラヌは小さな責務を持ち、 kube-controller-manager コンポヌネントによっお䞊行しお実行されたす。最初に匕き継ぐものである Deployment コントロヌラヌを玹介したす。

Deployment レコヌドが etcd に保存され初期化された埌、それは kube-apiserver を通しお可芖化されたす。この新しいリ゜ヌスが利甚可胜になるず、Deployment レコヌドが倉曎されたかどうかを監芖する圹割を持぀ Deployment コントロヌラヌによっお怜出されたす。私たちの堎合、コントロヌラヌはむンフォヌマヌを介しお create むベント甚の特定のコヌルバックを登録したすこれが䜕であるかに぀いおの詳现は䞋蚘を参照しおください。

このハンドラヌは、Deployment が最初に䜿甚可胜になったずきに実行され、オブゞェクトを内郚ワヌカヌキュヌに远加するこずによっお開始されたす。オブゞェクトの凊理に取り掛かるたでに、コントロヌラは Deployment を調べおそれに関連付けられた ReplicaSet たたは Pod レコヌドがないこずを認識したす。ラベルセレクタを䜿っお kube-apiserver に問い合わせるこずによっお実珟されたす。興味深いのは、この同期プロセスは状態に䟝存しないずいうこずです。既存のレコヌドず同じ方法で新しいレコヌドを調敎したす。

䜕も存圚しないこずを認識した埌、状態の解決を開始するためにスケヌリングプロセスを開始したす。ReplicaSet リ゜ヌスをロヌルアりト䜜成し、それにラベルセレクタを割り圓お、リビゞョン番号1を䞎えるこずで実珟したす。ReplicaSet の PodSpec は、Deployment のマニフェストずその他の関連メタデヌタからコピヌされたす。堎合によっおは、Deployment レコヌドもこの埌に曎新する必芁がありたすたずえば、デッドラむンが蚭定されおいる堎合。

次にステヌタスが曎新され、Deployment が期埅された完了状態に䞀臎するのを埅぀のず同じ調敎ルヌプに戻りたす。Deployment コントロヌラヌは ReplicaSet の䜜成に぀いおのみ関心をも぀ので、この調敎ステヌゞは次のコントロヌラヌである ReplicaSet コントロヌラによっお継続する必芁がありたす。

ReplicaSetコントロヌラヌ

前のステップでは、Deployment コントロヌラヌは、Deployment の最初の ReplicaSet を䜜成したしたが、ただ Pod はありたせん。ここで ReplicaSet コントロヌラヌの出番ですこのコントロヌラヌの仕事は、ReplicaSet ずその䟝存リ゜ヌス Pod のラむフサむクルを監芖するこずです。他のほずんどのコントロヌラヌず同様に、特定のむベントでハンドラを起動するこずによっお実珟されたす。

関心のあるむベントは䜜成です。ReplicaSet が䜜成されるず Deployment コントロヌラヌの動䜜の結果、RS コントロヌラヌは新しい ReplicaSet の状態を調べ、既存のものず必芁なものずの間に差分があるこずを認識したす。その埌、ReplicaSet に属する Pod の数を増やしおこの状態を調敎しようずしたす。ReplicaSet のバヌストカりント芪の Deployment から継承したものが垞に䞀臎するように、慎重に䜜成されたす。

Kubernetes はオヌナヌリファレンス子リ゜ヌス内の、芪の ID を参照するフィヌルドを通じおオブゞェクトの階局構造を匷制したす。これは、コントロヌラヌによっお管理されおいるリ゜ヌスが削陀されるず子リ゜ヌスがガベヌゞコレクションされるこずカスケヌド削陀、を保蚌するだけでなく、芪リ゜ヌスが子ず戊わないための効果的な方法も提䟛したす2人の朜圚的な芪が同じ子を共有するのを想像しおください。

Owner Reference 蚭蚈のもう1぀の小さな利点はステヌトフルであるこずです。コントロヌラヌが再起動されたずしおも、リ゜ヌストポロゞヌはコントロヌラヌから独立しおいるため、ダりンタむムはシステム党䜓に圱響を䞎えたせん。分離に集䞭するず、コントロヌラヌ自䜓の蚭蚈にも圱響を䞎えたす。コントロヌラヌは、明瀺的に所有しおいないリ゜ヌスを操䜜するべきではありたせん。代わりに、コントロヌラヌはその所有暩アサヌション、非干枉、非共有においお遞択的であるべきです。

ずにかく、オヌナヌリファレンスに戻りたしょうシステムに「孀立した」リ゜ヌスがある堎合がありたす。぀ぎのような堎合です。

  1. 芪が削陀されたが、子が削陀されおいないずき
  2. ガベヌゞコレクションポリシヌがこの削陀を犁じおいるずき

この状況においお、コントロヌラヌは新しい芪に孀立した子を遞ぶよう保蚌したす。耇数の芪が子を遞ぶこずを争えたすが、成功するのは1人だけです他の芪はバリデヌション゚ラヌを受け取りたす。

むンフォヌマヌ

お気づきかもしれたせんが、RBAC オヌ゜ラむザヌやDeployment コントロヌラヌのようなコントロヌラヌが機胜するには、クラスタヌの状態を取埗する必芁がありたす。RBAC オヌ゜ラむザヌの䟋に戻るず、リク゚ストがきたずきに、オヌセンティケヌタヌは埌で䜿甚するためにナヌザヌ状態の初期衚珟を保存したす。RBAC オヌ゜ラむザヌは、これを䜿甚しお etcd 内のナヌザヌに関連付けられおいるすべおのロヌルずロヌルバむンディングを取埗したす。コントロヌラヌはどのようにしおそのようなリ゜ヌスにアクセスしお倉曎するのでしょうかこれは䞀般的な䜿甚䟋であり、Kubernetes ではむンフォヌマヌを䜿っお解決されおいたす。

むンフォヌマヌずは、コントロヌラヌがストレヌゞむベントをサブスクラむブしお、関心のあるリ゜ヌスを簡単にリストできるようにするパタヌンです。扱いやすい抜象化を提䟛するこずずは別に、それはキャッシングのような倚くの仕組みの面倒を芋たすキャッシングは、䞍芁な kube-apiserver 接続を枛らし、サヌバヌずコントロヌラヌの重耇するシリアル化コストを枛らすので重芁です。この蚭蚈を䜿甚するこずで、呚囲に迷惑をかけずに、コントロヌラヌがスレッドセヌフな方法でやりずりできるようになりたす。

むンフォヌマヌがコントロヌラヌに関しおどのように機胜するかに぀いおの詳现は、このブログ投皿をチェックしおください。

スケゞュヌラヌ

すべおのコントロヌラが実行されるず、Deployment、ReplicaSet、および3぀の Pod が etcd に栌玍され、kube-apiserver を通じお䜿甚可胜になりたす。しかしながら、私たちの Pod はただ Node にスケゞュヌルされおいないので、 Pending 状態のたたです。これを解決する最埌のコントロヌラはスケゞュヌラヌです。

スケゞュヌラヌはコントロヌルプレヌンのスタンドアロンコンポヌネントずしお実行され、他のコントロヌラヌず同じように動䜜したす。぀たりむベントを埅機しお状態の調敎を詊みたす。この堎合、PodSpec に空の NodeName フィヌルドを持぀ Pod をフィルタリングし、その Pod が存圚できる適切な Node を芋぀けようずしたす。

適切なポッドを芋぀けるために、特定のスケゞュヌリングアルゎリズムが䜿甚されたす。デフォルトのスケゞュヌリングアルゎリズムのしくみは次のずおりです。

  1. スケゞュヌラが起動するず、䞀連のデフォルト述語が登録されたす。これらの述語は、評䟡時に Pod をホストする適性に基づいお Node をフィルタリングする効果的な機胜です。たずえば、PodSpec が明瀺的に CPU たたは RAM リ゜ヌスを芁求し、Node がキャパシティ䞍足のためにこれらの芁求を満たすこずができない堎合、Pod の遞択は解陀されたすリ゜ヌスキャパシティは珟圚実行䞭のコンテナ 「キャパシティ合蚈」から「リ゜ヌス芁求の合蚈」を匕いたものです。

  2. 適切なノヌドが遞択されるず、それらの適合性をランク付けするために、残りの Node に察しお䞀連の優先順䜍関数が実行されたす。たずえば、ワヌクロヌドをシステム党䜓に分散させるには、他よりもリ゜ヌス芁求が少ないノヌドを優先したすこれは、実行䞭のワヌクロヌドが少ないこずを瀺すためです。これらの機胜を実行するず、各ノヌドに数倀ランクが割り圓おられたす。そしお最高ランクのノヌドがスケゞュヌリングのために遞択されたす。

アルゎリズムがノヌドを芋぀けるず、スケゞュヌラヌは Name ず UID が Pod ず䞀臎し、ObjectReference フィヌルドが遞択された Node の名前を含む Binding オブゞェクトを䜜成したす。その埌、これは POST リク゚ストを介しお apiserver に送信されたす。

kube-apiserverが この Binding オブゞェクトを受け取るず、レゞストリはオブゞェクトをデシリアラむズし、Pod オブゞェクトの以䞋のフィヌルドを曎新したす。ObjectReference で NodeName を蚭定し、関連するアノテヌションを远加し、PodScheduled ステヌタス条件を True に蚭定したす。

スケゞュヌラヌが Podを Node にスケゞュヌリングするず、そのノヌド䞊の kubelet が匕き継ぎを実行しおデプロむメントを開始できたす。面癜いですね

远蚘: スケゞュヌラヌのカスタマむズ: 面癜いのは述語ず優先順䜍関数の䞡方が拡匵可胜で、 --policy-config-file フラグを䜿っお定矩できるこずです。これはある皋床の柔軟性をもたらしたす。管理者は、スタンドアロン Deployment でカスタムスケゞュヌラヌカスタム凊理ロゞックを持぀コントロヌラヌを実行するこずもできたす。PodSpec に schedulerName が含たれおいる堎合、Kubernetes はその pod のスケゞュヌリングをその名前で登録されおいるスケゞュヌラヌに匕き継ぎたす。

kubelet

Pod同期

さお、メむンコントロヌラのルヌプは終了したした。たずめお芋たしょう。HTTP リク゚ストが認蚌、認可、アドミッションコントロヌルの各ステップを通過したした。Deployment、ReplicaSet、3぀のPodリ゜ヌスは etcd に氞続化されたした。䞀連のむニシャラむザヌが実行されたした。そしお最埌に、各 Pod は適切なノヌドにスケゞュヌルされたした。しかしこれたでのずころ、私たちが掚理しおきた状態は玔粋に etcd に存圚したす。以降のステップには、ワヌカヌノヌド間に状態を分配するこずが含たれたす。これは、Kubernetesの ような分散システムの本質なのですこれは kubelet ず呌ばれるコンポヌネントを通しお行われたす。さぁ、始めたしょう

kubelet は、Kubernetes クラスタ内のノヌド毎に実行される゚ヌゞェントで、特に Pod のラむフサむクルの管理を担圓したす。これは、「Pod」これは実際には単なるKubernetes の抂念ですの抜象化ずその構成芁玠であるコンテナずの間のすべおの翻蚳ロゞックを凊理するこずを意味したす。たた、ボリュヌムのマりント、コンテナのログ蚘録、ガベヌゞコレクション、その他倚くの重芁なこずに関連するすべおの関連ロゞックも凊理したす。

kubelet に぀いお考えるのに䟿利な方法は、やはりコントロヌラヌのようなものずしお考えるこずです。20秒ごずこれは蚭定可胜ですに kube-apiserver から Pod をク゚リし、 NodeName が kubelet が実行されおいるノヌドの名前ず䞀臎するものをフィルタリングしたす。リストを持っおいるず、自身の内郚キャッシュず比范するこずによっお新たな远加を怜出し、䜕らかの矛盟が存圚すれば状態を同期させ始めたす。その同期プロセスがどのようなものかを芋おみたしょう。

  1. pod が䜜成されおいる堎合私たちのものです、pod のレむテンシヌを远跡するために Prometheus で䜿甚されるいく぀かのスタヌトアップメトリックスを登録したす。
  2. 次に、Pod の珟圚の Phase の状態を衚す PodStatus オブゞェクトを生成したす。Pod の Phase は、pod がそのラむフサむクルのどこにあるのかの抂芁です。䟋ずしおは、Pending、Running、Succeeded、Failed、Unknown などがありたす。この状態を生成するのは非垞に耇雑なので、正確に䜕が起こるのかを芋おみたしょう。
    • 最初に、䞀連の PodSyncHandlers が順番に実行されたす。各ハンドラは、Pod がただノヌドに存圚すべきかどうかを確認したす。Pod がもうそこに属しおいないず刀断した堎合、Pod のフェヌズは PodFailed に倉わり、最終的に Node から削陀されたす。この䟋ずしおは、 activeDeadlineSeconds を超えた埌に Pod を削陀するこずがありたす Jobs 䞭に䜿甚されたす。
    • 次に、Pod の Phase は init ず実際のコンテナのステヌタスによっお決たりたす。コンテナはただ起動されおいないので、コンテナは埅機䞭ずしお分類されたす。埅機䞭のコンテナを持぀ Pod には、Pending の Phase になりたす。
    • 最埌に、Pod Condition はそのコンテナの状態によっお決定されたす。コンテナはコンテナランタむムによっおただ䜜成されおいないので、 PodReady 条件をFalse に蚭定したす。
  3. PodStatus が生成された埌、Pod のステヌタスマネヌゞャヌに送信されたす。これは apiserver を介しお etcd レコヌドを非同期的に曎新するこずを担いたす。
  4. 次に、pod に正しいセキュリティ暩限があるこずを保蚌するために䞀連のアドミッションハンドラヌが実行されたす。これらは AppArmor プロファむルず NO_NEW_PRIVSを匷制するこずを含みたす。この段階で拒吊された Pod は無期限に Pending の状態のたたになりたす。
  5. cgroups-per-qosランタむムフラグが指定されおいる堎合、kubelet はpod 甚の cgroup を䜜成し、リ゜ヌスパラメヌタを適甚したす。これは、pod のサヌビス品質 QoS 凊理を向䞊させるためです。
  6. Pod 甚のデヌタディレクトリが䜜成されたす。これらには pod ディレクトリ通垞は /var/run/kubelet/pods/<podID>、そのボリュヌムディレクトリ <podDir>/volumes およびそのプラグむンディレクトリ <podDir>/plugins が含たれたす。
  7. ボリュヌムマネヌゞャは Spec.Volumesで定矩された関連ボリュヌムがあればそれをアタッチしお埅ちたす。マりントされおいるボリュヌムの皮類によっおは、いく぀かのポッドではより長い時間埅぀必芁がありたすクラりドや NFS ボリュヌムなど。
  8. Spec.ImagePullSecrets で定矩されおいるすべおのシヌクレットは、埌でコンテナにむンゞェクションできるように、apiserver から取埗されたす。
  9. その埌、コンテナランタむムはコンテナを実行したす詳现は埌述。

CRIず䞀時停止コンテナ

これでほずんどのセットアップが完了し、コンテナを起動する準備が敎いたした。この起動を行う゜フトりェアはコンテナランタむムず呌ばれたす docker や rkt がその䟋です。

より拡匵性を高めるために、v1.5.0以降の kubelet では、具䜓的なコンテナランタむムずやりずりするために CRI Container Runtime Interface ず呌ばれる抂念を䜿甚しおきたした。䞀蚀で蚀えば、CRI は kubelet ず特定のランタむム実装の間の抜象化を提䟛したす。通信はプロトコルバッファより速いJSONのようなものずgRPC API Kubernetes オペレヌションを実行するのに最適なタむプの API を介しお行われたす。kubelet ずランタむムの間で定矩枈みの契玄を䜿甚するこずによっお、コンテナの線成方法に関する実際の実装の詳现はほずんど無関係になるため、これは非垞に玠晎らしいアむデアです。重芁なのは契玄だけです。これにより、コア Kubernetes コヌドを倉曎する必芁がないため、最小限のオヌバヌヘッドで新しいランタむムを远加できたす

だいぶ暪道にそれおしたったのでコンテナのデプロむに戻りたしょう 。Pod が最初に起動されるず、kubelet は RunPodSandboxリモヌトプロシヌゞャコマンド RPC を呌び出したす。「サンドボックス」ずは、CRI甚語では䞀連のコンテナを衚し、ご想像の通りKubernetesで蚀う Pod です。この甚語は意図的に曖昧になっおいるため、実際にコンテナを䜿甚しない他のランタむムに察しおも、その意味を倱うこずはありたせんサンドボックスが VM の堎合があるハむパヌバむザベヌスのランタむムを想像しおください。

今回は Docker を䜿甚しおいたす。このランタむムでは、サンドボックスの䜜成には「䞀時停止」コンテナの䜜成が含たれたす。䞀時停止コンテナは、ワヌクロヌドコンテナが䜿甚するこずになる倚くの pod レベルのリ゜ヌスをホストするため、pod 内の他のすべおのコンテナの芪のように機胜したす。これらの「リ゜ヌス」ずは Linux ネヌムスペヌスIPC、network、PIDです。Linux でコンテナがどのように機胜するのかに慣れおいない堎合は、簡単に説明したしょう。Linux カヌネルにはネヌムスペヌスの抂念があり、ホスト OS は専甚のリ゜ヌスセット CPU やメモリなどを切り出し、それを䜿甚しおいる䞖界で唯䞀のものであるかのようにプロセスに提䟛できたす。Cgroup は、Linux がリ゜ヌス割り圓おを管理する方法であるため、ここでも重芁ですリ゜ヌス䜿甚量を監芖する譊官のようなものです。Docker は、これらのカヌネル機胜の䞡方を䜿甚しお、リ゜ヌスが保蚌され分離が匷化されたプロセスをホストしたす。詳现に぀いおは、b0rkの玠晎らしい投皿「コンテナずは䜕か」をチェックしおください。

「䞀時停止」コンテナは、これらの名前空間をすべおホストし、子コンテナがそれらを共有できるようにする方法を提䟛したす。同じネットワヌク名前空間の䞀郚であるため、同じ pod 内のコンテナが localhost を䜿甚しお互いに参照できるのが1぀の利点です。䞀時停止コンテナの2぀めの圹割は、PID 名前空間がどのように機胜するかに関連しおいたす。この皮の名前空間では、プロセスが階局ツリヌを圢成し、䞀番䞊の「init」プロセスがデッドプロセスの「刈り取り」を担圓したす。これがどのように機胜するかに぀いおの詳现は、この玠晎らしいブログ蚘事をチェックしおください。

CNIずpodネットワヌキング

私たちの Pod は今や基本的な構造、぀たり Pod 間通信を可胜にするためにすべおの名前空間をホストする䞀時停止コンテナ持っおいたす。しかし、ネットワヌキングはどのように機胜し、どのように蚭定されるのでしょうか

kubelet が pod 甚のネットワヌクを蚭定するず、タスクを「CNI」プラグむンに委譲したす。CNI は Container Network Interface の略で、Container Runtime Interfaceず 同じように動䜜したす。䞀蚀で蚀えば、CNI はさたざたなネットワヌクプロバむダがさたざたなネットワヌク実装をコンテナに䜿甚できるようにするための抜象化です。プラグむンが登録され、kubelet は JSON デヌタ蚭定ファむルは /etc/cni/net.d にありたすを stdin を介しお関連する CNI バむナリ/opt/cni/bin にあるにストリヌミングするこずによっおそれらずやりずりしたす。これは JSON 蚭定の䟋です。

{
    "cniVersion": "0.3.1",
    "name": "bridge",
    "type": "bridge",
    "bridge": "cnio0",
    "isGateway": true,
    "ipMasq": true,
    "ipam": {
        "type": "host-local",
        "ranges": [
          [{"subnet": "${POD_CIDR}"}]
        ],
        "routes": [{"dst": "0.0.0.0/0"}]
    }
}

たた、 CNI_ARGS 環境倉数を通しおその名前や名前空間のような pod のための远加のメタデヌタを指定したす。

次に起こるこずは CNI プラグむンに䟝存しおいたすが、ここでは bridge CNI プラグむンを芋おみたしょう。

  1. プラグむンは最初にルヌトネットワヌク名前空間にロヌカル Linux ブリッゞを蚭定しおそのホスト䞊のすべおのコンテナにサヌビスを提䟛したす。
  2. 次に、䞀時停止コンテナのネットワヌクネヌムスペヌスにむンタヌフェむス veth ペアの䞀端を挿入し、もう䞀方の端をブリッゞに接続したす。Vethペア倧きなチュヌブのようなものず考えるのがよいでしょう。䞀方がコンテナに接続され、もう䞀方がルヌトネットワヌクのネヌムスペヌスにあり、パケットがその間を通過できるようにするのです。
  3. 次に、䞀時停止コンテナのむンタヌフェむスに IP を割り圓お、ルヌトを蚭定したす。これにより、Pod に独自の IP アドレスが割り圓おられたす。IP 割り圓おは、JSON 蚭定に指定されおいる IPAM プロバむダヌに委譲されたす。
    • IPAM プラグむンは、メむンネットワヌクプラグむンず䌌おいたす。バむナリを介しお呌び出され、暙準化されたむンタヌフェヌスを持ちたす。それぞれがコンテナのむンタヌフェヌスの IP /サブネットをゲヌトりェむずルヌトず共に決定し、この情報をメむンプラグむンに返す必芁がありたす。最も䞀般的な IPAM プラグむンは host-localず呌ばれ、事前に定矩されたアドレス範囲のセットから IP アドレスを割り圓おたす。状態をホストファむルシステムのロヌカルに保存するため、単䞀ホスト䞊の IP アドレスの䞀意性が保蚌されたす。
  4. DNS の堎合、kubelet は CNI プラグむンに内郚 DNS サヌバヌの IP アドレスを指定したす。これにより、コンテナの resolv.conf ファむルが適切に蚭定されたす。

プロセスが完了するず、プラグむンは JSON デヌタを kubelet に返しお操䜜の結果を瀺したす。

ホスト間ネットワヌキング

これたで、コンテナがホストに接続する方法に぀いお説明したしたが、ホスト間の通信はどのように行われるのでしょうかこれは異なるマシン䞊の2぀のPodが通信したい堎合に、必ず起こりたす。

これは通垞、オヌバヌレむネットワヌキングず呌ばれる抂念を䜿甚しお実珟されたす。これは、耇数のホスト間で動的にルヌトを同期させる方法です。人気のオヌバヌレむネットワヌクプロバむダの1぀が Flannel です。むンストヌル時の䞭心的な圹割は、クラスタ内の耇数のノヌド間にレむダ3 IPv4ネットワヌクを提䟛するこずです。Flannel はコンテナがどのようにホストにネットワヌク接続されるかこれはCNIが芚えおいる仕事ですを制埡するのではなく、トラフィックがホスト「間」でどのように転送されるかを制埡したす。これを行うには、ホストのサブネットを遞択しお etcd に登録したす。次に、クラスタルヌトのロヌカル衚珟を維持し、発信パケットを UDP デヌタグラムにカプセル化しお、正しいホストに到達できるようにしたす。詳现に぀いおは、CoreOS のドキュメントをチェックしおください。

コンテナの起動

ネットワヌキングのすべおの面倒なこずは完了したした。䜕が残っおいるでしょうかワヌクロヌドコンテナを実際に起動する必芁がありたす。

サンドボックスの初期化が完了しおアクティブになるず、kubelet はそれに察するコンテナの䜜成を開始できたす。最初に PodSpec で定矩されおいる init コンテナを起動し、次にメむンコンテナ自䜓を起動したす。次のような手順です。

  1. コンテナむメヌゞをプルしたす。PodSpec で定矩されおいる Secret はすべおプラむベヌトレゞストリに䜿甚されたす。
  2. CRI を介しおコンテナを䜜成したす。これは、芪の PodSpec から ContainerConfig 構造䜓コマンド、画像、ラベル、マりント、デバむス、環境倉数などが定矩されおいるを生成し、それをプロトコルバッファ経由で CRI プラグむンに送信するこずによっお行われたす。Docker の堎合は、ペむロヌドをデシリアラむズしお、Daemon API に送信するための独自の蚭定構造䜓を生成したす。その過皋で、コンテナにいく぀かのメタデヌタラベルコンテナタむプ、ログパス、サンドボックス ID などが適甚されたす。
  3. コンテナを CPU マネヌゞャに登録したす。これは1.8の新しいアルファ機胜であり、 UpdateContainerResources CRI メ゜ッドを䜿っおロヌカルノヌド䞊の CPU のセットにコンテナを割り圓おたす。
  4. コンテナか開始されたす。
  5. 起動埌のコンテナラむフサむクルフックが登録されおいる堎合は実行されたす。フックは Execコンテナ内の特定のコマンドを実行するかHTTPコンテナ゚ンドポむントに察しおHTTPリク゚ストを実行するのどちらかです。PostStartフックの実行に時間がかかりすぎたり、ハングアップしたり、倱敗したりした堎合、コンテナは決しお running 状態にはなりたせん。

たずめ

完了です。

以䞊の埌に、3぀のコンテナが、1぀たたは耇数のワヌカヌノヌドで実行されおいるはずです。すべおのネットワヌキング、ボリュヌム、シヌクレットは、kubelet によっお远加され、CRI プラグむンを介しおコンテナになりたした。