Kubernetes基礎(10)：Deployment

##Deployment Overview
<img width="785" alt="スクリーンショット 2020-07-08 15.39.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/aa6822fb-63af-976a-8e8a-c5e5b1e1bc6c.png">
##Deploy Specification
![スクリーンショット 2020-07-08 14.33.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/68cbc6fb-a0e6-3bdf-bd5e-2e1f14bebbd8.png)
Deploymentを作成するとv1のPodが作成される。
ReCreateのDeploymentはまずv1のPodを削除して、その次v2のPodを作成する。
ReCreateのDeploymentは削除して作成する間のダウンタイムが発生するのが欠点である。
![スクリーンショット 2020-07-10 10.10.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/3eba96c8-d77d-6541-792d-fd2ab9f9bc7b.png)
Deploymentを作成するときにyamlファイルのように「selector」、「replicas」、「template」を設定するが、これらはDeploymentがReplicaSetを作成するときに設定する値である。
作成されたReplicaSetは設定通りに（templateのPodの内容、replicasの作成するPodの数、selectorのPodのLabel）Podを作成する。
Serviceを作成してPodと繋げるとServiceを介してPodにアクセスできるようになる。
Update（Deploy)をする時はtemplateのPodをv2に変更するとDeploymentはv1のReplicaSetのreplicasを0に変更させるのでReplicaSetが全てのPodを削除した後、Deploymentは新しくReplicaSetとv2のPodを作成するのでここでダウンタイムが発生することになる。
ReCreateのDeploymentはPodは全て削除するがReplicaSetはyamlファイルの「revisionHistoryLimit」の設定の数だけ残す。
ここでは１なので現在サービスの前のサービスのReplicaSetが残ることになる。（デフォルト：１０）
![スクリーンショット 2020-07-08 14.33.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/e22b78b8-7817-3a48-0f08-70f15d99f626.png)
Upgradeの時、DeploymentはReCreateとは違って最初からv1のPodを削除せずにv2のPodを先に1つ作成する。
Podが1つ増えただけリソースの使用量も増える。
この状態はv1とv2両方ともサービスが可能である
その次、Deploymentはv1を1つ削除してv2を1つ作成した後、残りのv1を削除することでユーザーが完全にv2へ移行が可能となる。
このDeploymentはDeployしている間に追加されたPodの数だけリソースが必要になるが、ダウンタイムが発生しないことがメリットである。
![スクリーンショット 2020-07-10 10.10.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/4eda5576-a624-5873-d768-eac57615ee18.png)
v1が存在している状態でDeploymentのtemplateをv2に変更すると、rolling updateが始まる
DeploymentはReplicaSetを作成し、replicasが2であるため、v2のPodを2つ作る。
v2はv1のlabelと同じlabelで作成されるからServiceに自動に接続され、Serviceに入ってくるトラフィックがv1とv2に分散されることになる。
Deploymentはv1のreplicasを1に変更させてv1のPodを１つ削除して、v2のreplicasを2に変更させてPodを1つ増やす。
最後にv1のreplicasを0に変更させて残りv1のPodをすべて削除する。
このDeploymentもReCleateと同様にReplicaSetを削除しない。
![スクリーンショット 2020-07-08 14.33.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/04297bc3-a3e1-27f8-9409-8535e65b92b1.png)
Blue/GreenはDeploymentが提供する機能はなく、ReplicaSetのようにreplicasを管理ができるControllerならできる機能である。
Controllerとv1のPodを生成して、PodのLabelとServiceのSelectorでPodとServiceを接続する。
このような状態でControllerをもう一つ作成してv2のPodを作成する。
この時、リソースの使用量は、従来の二倍になる。
ServiceのLabelをv2のLabelに変更するだけでv1との接続は切れてv2と接続される。
従ってユーザーはv2のサービスを使用することができるようになる。
一瞬で変更されるのでサービスのダウンタイムは発生しない。
ところが、もしv2に問題が発生した場合、ServiceのLabelのみ変更することで既存のサービスに簡単に切り替えが可能で、v2に問題がなければ、既存のController及びPodを手動で削除すればよい。
このDeploymentは非常に多く使用されて安定したDeploymentだが欠点は、リソースが2倍も必要であることだ。
###CanaryのDeployment：Label
![スクリーンショット 2020-07-08 14.33.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/4a1f5f03-e77c-c8dc-5346-b1bc5261addc.png)
カナリアは1秒に心臓が17回も動くほど心拍数が高く、有害な空気を吸うとすぐ死んでしまう。
だからカナリアを鉱山の中にガスが漏れているかを確認するために連れて行ったり暖房付けたとき一酸化炭素を確認する目的で使っていた。
カナリアDeployというのは実験体を介して危険を検証し、リスクがないことが確認できたらDeployするDeploymentである。
v1のPodのLabelが上の図のように設定されている状態で、ServiceとPodを「ver」ではなく、「ty」で接続をする。
この状態で実験用のControllerをreplicas＝1にして作成するとv2のPodが1つ作成される。
このPodもv1と同様に「ty」Labelを設定して置いたらPodが生成されるときにServiceと自動に接続される。
サービスのtrafficの中でいくつかはv2へアクセスすることになって、実験用のv2に対してテストが可能になる。
もし問題が発生した場合、実験用のControllerのreplicasを0に指定すればよい。
###CanaryのDeployment：Ingress Controller
![スクリーンショット 2020-07-08 14.34.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/c073709b-76f3-d553-0b43-b8092de73973.png)
v1とv2 Serviceをそれぞれ作成し、Ingress Controller（trafficをURLによってServiceに接続するController）によって上記の図のようにv2/appのtrafficのみv2のサービスを使用することになる。
例えば、グローバルなサービスを運用する際に、新しくDeployしたサービスをアメリカをテストエリアにしたい場合、URLの前にenを付けるようにするとIngress Controllerがアメリカからアクセスするユーザーにだけv2のサービスに接続してくれる。
このように、特定のターゲットを決めてテストをすることができる。
問題がなければv2のPodをv1の数だけ増やして、Ingress Controllerの設定を/v2/app → /appに変更した後、既存v1を削除すればよい。
ダウンタイムは発生しないが、テストを行うPodの数だけのリソースが必要になる。