実行条件にはプロセス監視以外にHTTP/TCPやシェルスクリプトで成否を設定することも可能
- Istio
- Linkerd
- Contour
- Ambassador
Envoyを並べて、最初にそれを受けて、本体のコンテナへプロキシさせる
各ノードにラベルを貼り付けることにより、Podをスケジューリングする際に選択基準の一つにすることが出来る (例えば、メモリ多いノード郡、CPU性能が高いノード郡等)
kube-publicに全ユーザが共通して使用する設定値(ConfigMap)を配置 Namespaceだけでは完全な分離性が確保されていないので、RBACやNetwork Policyで分離性を高める
namespace/contextを変更することを容易にする為のコマンド
例としては、プロキシ・設定値の動的な書き換え・ローカルキャッシュ用・SSL終端用等がある。 デザインパターンとしては
- サイドカーパターン: メインコンテナに機能を追加する(データや設定関係が多い)
- 特定の変更を検知した際に動的に設定を変更する
- Gitリポジトリとローカルストレージを同期する(これは使えるかもしれないアプリケーションのアップデート)
Pod コンテナA(Application) <- サイドカー <- Git Syncer - アプリケーションのログをオブジェクトストレージに転送する
- アンバサダーパターン: 外部システムとのやり取りの代理で行う
- アンバサダーコンテナで使用するDBを選択、メインコンテナからはDBにlocalhostで接続することで依存性を下げる
- アダプターパターン: 外部からのアクセスのインターフェースとなる
サイドカーでメインコンテナに終了フラグ的なものを渡して、プロセスを終了させる、または更新されたソースコードにするとか? プロセスが終了するとセルフ・ヒーリングが動作するので。
Deploymentは使用できなくてもReplicaSetを使ってセルフヒーリング機能だけでも使用したい。 世代管理はラベル等でどうにかするしか無い。(ローリングアップデートはできない)
理由はPodはネットワークの名前空間を共有しているため(やはりPodに1つのNICが割り当てられている仕様の為) 例となるマニフェストを提示
apiVersion: v1
kind: Pod
metadata:
name: simple-2-pods
spec:
containers:
- name: nginx-container-112
image: nginx:1.12
- name: nginx-container-113
image: nginx:1.13
コマンドを使ってDeploymentoを変更しても適用は一時停止させることが出来る
停止) kubectl rollout pause deployment sample-deployment 再開) kubectl rollout resume deployment sample-deployment
1ノード1Podという制約があるため、Deployment(maxSurge: 超過可能Pod数)を選択出来ず、停止可能Pod数(maxUnavailable)で調整をする 例えばこれを2に設定すると、2つずつ更新が行われる
StatefulSetによって作成される各Podに対して、PersistentVolumeClaimを設定すると、PersistentVolumeをPodにアタッチすることが出来るようになる これにより、Podの再起動時や別ノードへの移動時に同じデータを保持した状態でコンテナが再生成されるようになる
ss -napt | grep LISTEN
kubectl apply -f sample-deployment.yaml --record
kubectl rollout status
- Liveness Probe: Podが正常に動作しているかの確認(失敗時はPodを再起動)
- Readness Probe: Podがサービス飲する準備がで来ているかの確認(失敗時はトラフィックを流さない、Podも再起動しない)
- exec: コマンドを実行し、終了コードが0でなければ失敗
- httpGet: HTTP GET リクエストを実行し、Statusが200-399でなければ失敗
- tcpSocket: TCPセッションが確立出来なければ失敗
livenessProbe:
exec:
command: ["ls", "/usr/sbin/nginx"]
設定は細かい所まで行うことが可能
livenessProbe:
httpGet:
path: /health
port: 80
scheme: HTTP
host: web.example.com
httpHeaders:
- name: Authorization
value: Bearer TOKEN
livenessProbe:
tcpSocket:
port: 80
kubectl get pods sample-readiness --watch
- Always: Podが停止すると、常にPodを再起動
- OnFuilure: Podの停止が予期せぬ停止(終了コード0以外)の場合、Podを再起動させる (これがdockerの stopedなんとかか)
- Never: Podが終了しても、Podを再起動させない
Kubernetes v1.8から導入されたPrioirtyClassを使うことで、Podがすでにリソースの限界までスケジューリングされている状態で より優先度の高いPodを作成しようとする場合に、既存のPodを退避させる事が可能になる
それに紐づくPodも全て削除されてしまう。仕様上で停止機能はないので、削除するしかない。 Podのラベルを更新させて、ReplicaSetに紐付かないようにすると、ReplicaSetを削除したとしてもPod自身は残り続ける
ただし、ReplicaSetを削除するということはロールバック処理ができなくなる。 kubectl rollout undo
ができなくなる。
が、一世代前のマニフェストを使って kubectl apply -f replicaset_manifest.yaml
を実行すれば一つ前の物を作成することが出来る
- Deploymentでローリングアップデートする時に、どうやってPodを選定しているのかを調査したい
- リリース時に現時点でproduction投入されているReplicaSetだけ(Podには何もしない)を停止・削除処理をすると、セルフヒーリングは機能しなくなると考えたが、どうだろうか
- セルフヒーリングが動作しないのであれば、ヘルフチェック等でリクエストを受け付けない設定にして、最終的に自身を終了するようにすれば行けるような
- サイドカー
- プロセスを終了させるステータス・フラグ/アプリのバージョン等のようなものをもたせる(メインコンテナで動作させるのが領域外と思われる)
- またはメインコンテナで終了しても良いのかという状態をチェックさせる必要があるのならメインコンテナ側で終了可能チェックを追加しても良さそう
- ヘルスチェックでそれをチェックし、メインコンテナ共々Podを終了させる
- ReplicaSet:
- セルフヒーリング(Pod数の担保)
- Label
- 更新/変更処理
- ReplicaSetに紐付いているラベルを更新させる
- restartPolicy(コンテナ)
- onFailure
- Podを再起動させない仕組み
- ヘルスチェック
- Readness Probe
- これ以上アプリがアップデートされリクエストを受け付けたくない時
- PodをReplicaSetで作成する。 (この時ReplicaSetとPodのマニフェストを同一ファイル上に記述するかは考慮する必要がある
- マニフェスト上にReadness Probeヘルスチェックを加えて、リクエストを受け付けなくなる条件を定義
- kubectl apply -f f.yamlでReplicaSet/Podを生成
- 新しいアプリが入った、ReplicaSetを新規作成する。その分のリソースは必要。あとからReplicaSetの数を増やせるので最初は小さくても良い。(A/Bテスト的に)
- ReplicaSetを削除したい(理由はセルフヒーリング機能を起動させたくない、ただエラーがこの間に発生してしまうとどうする)
- PodのラベルがReplicaSetに紐付いているので、ReplicaSetまたはPodのラベルを紐付かないように更新
- ReplicaSetを削除
- Podの処理が完了するまで待機
- Podが現在の処理を終了し、手持ちタスクがなくなったらPodが死んでも良い状態になる
- サイドカー等で新しいバージョンが来ていることを確認できるようにし、メインコンテナの状態を合わせてヘルスチェックが失敗する
- Podがリクエストを受け付けなくなり、ただRunning状態になる
- [ReplicaSetのときのラベルまたは、更新したラベルを使って、Podを削除する?]
- [Podは restartPolicy: onFailure なので、Podは自分自身で終了してくれる?メインコンテナが正常終了すれば]
- ReplicaSet/Podがなくなる
- 削除したReplicaSetを再度作成し直す必要があり、一つ前のReplicaSetのマニフェストを使って kubectl apply -f file.yamlを実行
- 新しいバージョンのアプリが入ったReplicaSetは削除