[k8s]リソースの削除方法について確認した時のメモ(kubectl delete or kubectl apply --prune)

リソース削除時の挙動について確認した時のメモ。
詳細は以下にある

[How to delete objects](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/#how-to-delete-objects)

# 環境

```bash
kubectl version
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.5", GitCommit:"20c265fef0741dd71a66480e35bd69f18351daea", GitTreeState:"clean", BuildDate:"2019-10-15T19:16:51Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"14+", GitVersion:"v1.14.9-eks-c0eccc", GitCommit:"c0eccca51d7500bb03b2f163dd8d534ffeb2f7a2", GitTreeState:"clean", BuildDate:"2019-12-22T23:14:11Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"linux/amd64"}
```

# kubectl delete -f 

使い方はシンプルで -f で削除したいオブジェクトのファイル名を指定すれば良い。

なお、

>Recommended: kubectl delete -f <filename>

と書いてあり、現在はこちらがオススメのようである。

そもそも `kubectl apply --prune`はまだアルファであるというのもあるだろうし、後述するように 意図せず、オブジェクトが削除されることもあるので注意してというのもありそう。

>    Warning: You must be careful when using this command, so that you do not delete objects unintentionally.

# kubectl apply --prune

## ファイルを削除した場合

以下を参考に2つファイルを作る

[Create static Pods](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/)

```sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
```

```sample-pod2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-web-2
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
```

フォルダ以下に配置する

```bash
# フォルダ配下のマニュフェストファイルを再帰的に apply
$kubectl apply -f test/ -R
pod/static-web created
pod/static-web-2 created

# フォルダから一つのファイルを移動
$mv test/sample-pod2.yaml .

# 再度適用しても static-web-2 は削除されない
$kubectl apply -f test/ -R
pod/static-web unchanged
```

上記のようなユースケースで利用することでリソースの削除が可能。
なお、ラベルの指定が必要。

```bash
# --prune を指定すると存在しなくなった static-web-2 も削除される
$kubectl apply -f test/ -R --prune -l role=myrole
pod/static-web unchanged
pod/static-web-2 pruned
```

## マニュフェストからリソースを削除された場合

以下のように一つのファイルに複数の Pod が記載されたファイルをを作る。

```sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
---
apiVersion: v1
kind: Pod
metadata:
  name: static-web-second
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
```

```bash
# 2 つの Pod が作成される
$kubectl apply -f test/sample-pod.yaml

# static-web-second の記述を削除
$vi test/sample-pod.yaml

# static-web-second は消えない
$kubectl apply -f test/sample-pod.yaml
pod/static-web unchanged

# static-web-second　が削除される
$kubectl apply -f test/sample-pod.yaml --prune -l role=myrole
pod/static-web unchanged
pod/static-web-second pruned
```

## 気をつけること

実際にはこれは対象リソースを削除しているのではなく、、ラベルに一致する全リソースのリストから、「kubectlapply」に渡したマニフェストにないものを全て削除する仕組みで動作と書いてある。
これを踏まえると以下のようになる可能性がある。

```bash
# ２つのフォルダにマニュフェストがあり、それぞれ同じラベルで別名称の Pod を定義
$ kubectl apply -f test/sample-pod.yaml
pod/static-web unchanged

$kubectl apply -f test2/sample-pod2.yaml
pod/static-web-second created

$kubectl get pods -l role=myrole
NAME                READY   STATUS    RESTARTS   AGE
static-web          1/1     Running   0          20m
static-web-second   1/1     Running   0          70s

# 意図せず test2 配下の Pod が消えてしまう
$kubectl apply -f test/sample-pod.yaml --prune -l role=myrole
pod/static-web unchanged
pod/static-web-second pruned
```