> For the complete documentation index, see [llms.txt](https://donghyunlee.gitbook.io/write-up/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://donghyunlee.gitbook.io/write-up/project/how-to-find-container-platform-escape-bug/kubernetes/kubernetes-practice.md).

# Kubernetes Practice

아래 자료들을 참고해 정리하였다. 특히 총 7강의 영상이 큰 도움이 되었다.

{% embed url="<https://www.youtube.com/playlist?list=PL9mhQYIlKEhdTu31zyb_QelQMaqFGgASA>" %}

{% embed url="<https://github.com/subicura/workshop-k8s-basic>" %}

{% embed url="<https://subicura.com/2019/05/19/kubernetes-basic-1.html>" %}

## Install

k3s를 설치한다.

```bash
curl -sfL https://get.k3s.io | sh -
sudo chown donghyunlee:donghyunlee /etc/rancher/k3s/k3s.yaml
```

확인

```bash
kubectl get nodes
```

kube config

```bash
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
```

기본 storage class가 없기때문에 Local path provisioner를 설치한다.

```bash
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
```

Set default

```bash
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
```

확인

```bash
kubectl get storageclass
```

## kubectl

자주 사용하는 kubectl 명령어를 알아본다. 기본 명령어는 아래와 같다.

* apply
  * Apply a configuration to a resource by filename or stdin
* get
  * Display one or many resources
* describe
  * Show details of a specific resource or group of resources
* delete
  * Delete resources by filenames, stdin, resources and names, or by resources and label selector
* logs
  * Print the logs for a container in a pod
* exec
  * Execute a command in a container

get

```bash
# pod, replicaset, deployment, service 조회
kubectl get all

# node 조회
kubectl get no
kubectl get node
kubectl get nodes

# 결과 포맷 변경
kubectl get nodes -o wide
kubectl get nodes -o yaml
kubectl get nodes -o json
```

describe

```bash
# kubectl describe type/name
# kubectl describe type name
kubectl describe node/<node name>
kubectl describe node <node name>
```

그 외 자주 사용하는 명령

```bash
kubectl exec -it <POD_NAME>
kubectl logs -f <POD_NAME|TYPE/NAME>

kubectl apply -f <FILENAME>
kubectl delete -f <FILENAME>
```

## Pod

빠른 예제

```bash
kubectl run whoami --image subicura/whoami:1 # deprecated soon..
# kubectl get po
# kubectl get pod
kubectl get pods
kubectl get pods -o wide
kubectl get pods -o yaml
kubectl get pods -o json
kubectl logs whoami-<xxxx>
kubectl logs -f whoami-<xxxx>
kubectl exec -it whoami-<xxxx> sh
kubectl describe pods whoami-<xxxx>
kubectl delete pods whoami-<xxxx>
kubectl get pods
kubectl get all
kubectl delete deployment/whoami
```

YAML 파일을 아래와 같이 만들 수 있다.

```yaml
# whoami-pod.yml

apiVersion: v1
kind: Pod
metadata:
  name: whoami
  labels:
    type: app
spec:
  containers:
  - name: app
    image: subicura/whoami:1
```

다음 명령을 통해 적용 및 삭제가 가능하다.

```bash
kubectl apply -f <filename>
kubectl delete -f <filename>
```

Pod ready 개념은 아래 그림을 통해 도식화 할 수 있다.

![](/files/-MGTEjOumqQrwf95xUI4)

livenessProbe 예제 (살아 있는지 조사)

```yaml
# whoami-pod-lp.yml

apiVersion: v1
kind: Pod
metadata:
  name: whoami-lp
  labels:
    type: app
spec:
  containers:
  - name: app
    image: subicura/whoami:1
    livenessProbe:
      httpGet:
        path: /not/exist
        port: 8080
      initialDelaySeconds: 5
      timeoutSeconds: 2 # Default 1
      periodSeconds: 5 # Defaults 10
      failureThreshold: 1 # Defaults 3
```

readinessProbe 예제 (준비가 되었는지 조사)

```yaml
# whoami-pod-rp.yml

apiVersion: v1
kind: Pod
metadata:
  name: whoami-rp
  labels:
    type: app
spec:
  containers:
  - name: app
    image: subicura/whoami:1
    readinessProbe:
      httpGet:
        path: /not/exist
        port: 8080
      initialDelaySeconds: 5
      timeoutSeconds: 2 # Default 1
      periodSeconds: 5 # Defaults 10
      failureThreshold: 1 # Defaults 3
```

health check 예제

```yaml
# whoami-pod-health.yml

apiVersion: v1
kind: Pod
metadata:
  name: whoami-redis
  labels:
    type: stack
spec:
  containers:
  - name: app
    image: subicura/whoami-redis:1
    env:
    - name: REDIS_HOST
      value: "localhost"
  - name: db
    image: redis
```

multi container 예제

```yaml
# whoami-pod-redis.yml

apiVersion: v1
kind: Pod
metadata:
  name: whoami-redis
  labels:
    type: stack
spec:
  containers:
  - name: app
    image: subicura/whoami-redis:1
    env:
    - name: REDIS_HOST
      value: "localhost"
  - name: db
    image: redis
```

```bash
kubectl get all
kubectl logs whoami-redis
kubectl logs whoami-redis app
kubectl logs whoami-redis db
kubectl exec -it whoami-redis
kubectl exec -it whoami-redis -c db sh
kubectl exec -it whoami-redis -c app sh
  apk add curl busybox-extras # install telnet
  curl localhost:4567
  telnet localhost 6379
    dbsize
    KEYS *
    GET count
    quit
kubectl get pod/whoami-redis
kubectl get pod/whoami-redis -o yaml
kubectl get pod/whoami-redis -o jsonpath="{.spec.containers[0].name}"
kubectl get pod/whoami-redis -o jsonpath="{.spec.containers[*].name}"
kubectl describe pod/whoami-redis
```

다음 명령어로 정리한다.

```bash
kubectl delete -f ./
```

## Replicaset

개념은 다음과 같다.

> ReplicaSet -> Find pod by labels -> Create pod from template

기본 예제

```yaml
# whoami-rs.yml

apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
  name: whoami-rs
spec:
  replicas: 1
  selector:
    matchLabels:
      type: app
      service: whoami
  template:
    metadata:
      labels:
        type: app
        service: whoami
    spec:
      containers:
      - name: whoami
        image: subicura/whoami:1
        livenessProbe:
          httpGet:
            path: /
            port: 4567
```

```bash
kubectl get pods --show-labels
kubectl label pod/whoami-rs-<xxxx> service-
kubectl label pod/whoami-rs-<xxxx> service=whoami
kubectl scale --replicas=3 -f whoami.yml
```

스케일 아웃 예제

```yaml
# whoami-rs-scaled.yml

apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
  name: whoami-rs
spec:
  replicas: 4
  selector:
    matchLabels:
      type: app
      service: whoami
  template:
    metadata:
      labels:
        type: app
        service: whoami
    spec:
      containers:
      - name: whoami
        image: subicura/whoami:1
        livenessProbe:
          httpGet:
            path: /
            port: 4567
```

정리

```bash
kubectl delete -f ./
```

## Deployment

> Deployment using replicaset

기본 예제

```yaml
# whoami-deploy.yml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: whoami-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      type: app
      service: whoami
  template:
    metadata:
      labels:
        type: app
        service: whoami
    spec:
      containers:
      - name: whoami
        image: subicura/whoami:1
        livenessProbe:
          httpGet:
            path: /
            port: 4567
```

```bash
kubectl set image deploy/whoami-deploy whoami=subicura/whoami:2
kubectl apply -f whoami-deploy.yml
kubectl get rs -w
kubectl describe deploy/whoami-deploy
kubectl rollout history -f whoami-deploy.yml
kubectl set image deploy/whoami-deploy whoami=subicura/whoami:1 --record=true
kubectl rollout history -f whoami-deploy.yml
kubectl rollout history -f whoami-deploy.yml --revision=2
kubectl rollout status deploy/whoami-deploy
kubectl rollout undo deploy/whoami-deploy
kubectl rollout undo deploy/whoami-deploy --to-revision=3
```

추가 예제

```yaml
# whoami-deploy-strategy.yml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: whoami-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      type: app
      service: whoami
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        type: app
        service: whoami
    spec:
      containers:
      - name: whoami
        image: subicura/whoami:1
        livenessProbe:
          httpGet:
            path: /
            port: 4567
```

```bash
kubectl describe deploy/whoami-deploy
kubectl set image deploy/whoami-deploy whoami=subicura/whoami:2
kubectl get rs -w
```

정리

```bash
kubectl delete -f ./
```

## Service

StaticIP와 NodePort에 대해 실습한다.

기본 예제

```yaml
# redis-app.yml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      type: db
      service: redis
  template:
    metadata:
      labels:
        type: db
        service: redis
    spec:
      containers:
      - name: redis
        image: redis
        ports:
        - containerPort: 6379
          protocol: TCP
---

apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  ports:
  - port: 6379
    protocol: TCP
  selector:
    type: db
    service: redis
```

```yaml
# whoami-deploy.yml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: whoami
spec:
  selector:
    matchLabels:
      type: app
      service: whoami
  template:
    metadata:
      labels:
        type: app
        service: whoami
    spec:
      containers:
      - name: whoami
        image: subicura/whoami-redis:1
        env:
        - name: REDIS_HOST
          value: "redis"
        - name: REDIS_PORT
          value: "6379"
```

```bash
kubectl get ep
kubectl exec -it whoami-<xxxxx> sh
  apk add curl busybox-extras # install telnet
  curl localhost:4567
  curl localhost:4567
  telnet localhost 6379
  telnet redis 6379
    dbsize
    KEYS *
    GET count
    quit
```

노드 포트

```yaml
# whoami-svc.yml

apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  type: NodePort
  ports:
  - port: 4567
    protocol: TCP
  selector:
    type: app
    service: whoami
```

정리

```bash
kubectl delete -f ./
```
