혼자 쿠버네티스 커맨드 익숙해지고자 주저리주저리 작성하는 글입니다.

오브젝트는 쿠버네티스에 자원의 바라는 상태 (desired state) 를 정의하고 컨트롤러는 desired state = current state 가 되도록 오브젝트들을 생성 / 삭제

  • 오브젝트 : pod, service, namespace,pvc
  • 컨트롤러 : replicaset, deployment, statefulset,demonset

생성

  • kubectl run nginx-app –image nginx –port=80 => default로 deployment 생성
  • kubectl run nginx-app –generator =run-pod/v1 –image=“nginx” –port=80 => pod생성
  • kubectl apply -f nginx.yaml

조회

  • kubectl get pods,deploy,rs,svc -o wide
  • kubectl api-resources
  • kubectl explain pods
  • kubectl explain pods.spec

deployment/nginx-app.yaml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    apps: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - name: nginx-app
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 0.1
            memory: 10M
          limits:
            cpus: 0.2
            memory: 20M

=> .spec.selector.matchLabels = .spec.template.metadata.labels 랑 같아야 적용가능

pod 직접접속

kubectl exec -it podname /bin/sh

replicaset, deployment 등 컨트롤러만 지울 때

kubectl delete replicaset nginx-replicaset-tets –cascade=false
=> –cascade=false 없이 지우면 해당 deployment 관련 모든 오브젝트 삭제됨

떠있는 오브젝트, 컨트롤러 수정하기

  • kubectl edit deployment.apps/nginx-deployment
    => ex. 위 커맨드 수행시 pod의 현재정보들이 vim 편집기로 열림, 수정 후 저장하고 나오면 변경사항 적용됨
  • kubectl set image deployment.apps/nginx-deployment nginx-container=nginx:1.9.1
AL01542225:deployment nhn$ kubectl get pod,rs,deploy,svc -o wide
NAME                                    READY   STATUS              RESTARTS   AGE    IP           NODE       NOMINATED NODE   READINESS GATES
pod/nginx-deployment-57c78dbb95-6hd8x   1/1     Running             0          8m6s   172.17.0.6   minikube   <none>           <none>
pod/nginx-deployment-57c78dbb95-wnqhs   0/1     Terminating         0          8m6s   172.17.0.8   minikube   <none>           <none>
pod/nginx-deployment-77c8f4c994-6tvm8   1/1     Running             0          36s    172.17.0.9   minikube   <none>           <none>
pod/nginx-deployment-77c8f4c994-78bjk   1/1     Running             0          11s    172.17.0.7   minikube   <none>           <none>
pod/nginx-deployment-77c8f4c994-tbrxr   0/1     ContainerCreating   0          5s     <none>       minikube   <none>           <none>

NAME                                          DESIRED   CURRENT   READY   AGE    CONTAINERS        IMAGES        SELECTOR
replicaset.apps/nginx-deployment-57c78dbb95   1         1         1       8m6s   nginx-container   nginx         app=nginx-conatiners,pod-template-hash=57c78dbb95
replicaset.apps/nginx-deployment-77c8f4c994   3         3         2       36s    nginx-container   nginx:1.9.1   app=nginx-conatiners,pod-template-hash=77c8f4c994

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS        IMAGES        SELECTOR
deployment.apps/nginx-deployment   3/3     3            3           8m6s   nginx-container   nginx:1.9.1   app=nginx-conatiners

=> deployment에서 선언한 container nginx-container 의 image를 nginx -> nginx:1.9.1 로 수정함
신규 77c8f4c994 ReplicaSet이 생성되어 새로운 Pod 들이 생성되며 기존 Pod들은 rolling update 형식으로 대체됨

replica 조정

  • kubectl scale deploy nginx-app –replicas=2

deployment 롤백

  • 롤백 가능 버전 확인
$ kubectl rollout history deploy nginx-deployment

deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

$ kubectl rollout history deploy nginx-deployment --revision=1
deployment.apps/nginx-deployment with revision #1
Pod Template:
  Labels:	app=nginx-conatiners
	pod-template-hash=57c78dbb95
  Containers:
   nginx-container:
    Image:	nginx

$ kubectl rollout history deploy nginx-deployment --revision=2
deployment.apps/nginx-deployment with revision #2
Pod Template:
  Labels:	app=nginx-conatiners
	pod-template-hash=77c8f4c994
  Containers:
   nginx-container:
    Image:	nginx:1.9.1

=> 배포 버전 revision 1,2 차이는 nginx 이미지 버전 차이

  • 특정 revision 으로 롤백
$ kubectl rollout undo deploy nginx-deployment --to-revision=1
deployment.apps/nginx-deployment rolled back

kubectl get deploy,rs,pods -o wide
NAME                               READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS        IMAGES   SELECTOR
deployment.apps/nginx-deployment   5/5     5            5           35m   nginx-container   nginx    app=nginx-conatiners

NAME                                          DESIRED   CURRENT   READY   AGE   CONTAINERS        IMAGES        SELECTOR
replicaset.apps/nginx-deployment-57c78dbb95   5         5         5       35m   nginx-container   nginx         app=nginx-conatiners,pod-template-hash=57c78dbb95
replicaset.apps/nginx-deployment-77c8f4c994   0         0         0       27m   nginx-container   nginx:1.9.1   app=nginx-conatiners,pod-template-hash=77c8f4c994

NAME                                    READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
pod/nginx-deployment-57c78dbb95-8lbh6   1/1     Running   0          26s   172.17.0.8    minikube   <none>           <none>
pod/nginx-deployment-57c78dbb95-dzjj7   1/1     Running   0          19s   172.17.0.6    minikube   <none>           <none>
pod/nginx-deployment-57c78dbb95-q7rjq   1/1     Running   0          33s   172.17.0.11   minikube   <none>           <none>
pod/nginx-deployment-57c78dbb95-qbkxs   1/1     Running   0          33s   172.17.0.13   minikube   <none>           <none>
pod/nginx-deployment-57c78dbb95-rmfh9   1/1     Running   0          33s   172.17.0.12   minikube   <none>           <none>

=> nginx:1.9.1 버전을 사용하는 77c8f4c994=> 57c78dbb95 으로 롤백됨

  • 롤백 버전 정보 보려면 annotations를 추가한다
$ cat nginx-deployment.yaml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-deployment
  annotations:
    kubernetes.io/change-cause: version test

=> deployment 정의 yaml파일에서 annotations 필드를 추가함. kubernetes.io/change-cause: 구문 뒤에 해당 버전에 대한 설명 기재

$ kubectl apply -f nginx-deployment.yaml

$ kubectl rollout history deploy nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
2         <none>
3         version test

각 pod의 .metadata.labels.app 필드 확인하기

$ kubectl get pods -o=jsonpath="{range .items[*]}{.metadata.name}{'\t'}{.metadata.labels}{'\n'}{end}"
nginx-replicaset-test-8pbqk	map[app:nginx-replicaset-container]
nginx-replicaset-test-8pltx	map[app:nginx-replicaset-container]
nginx-replicaset-test-v9gw9	map[app:nginx-replicaset-container2]

statefullset.yaml

  • statefulset는 상태가 유지되어야 하는 pod들을 관리하는 컨트롤러로 아래같은 경우에 사용함
    • pvc 를 사용해서 데이터를 저장하여 pod이 재시작되어도 데이터를 유지해야할 때
    • 여러 pod 사이에 순서를 지정해서 실행이 필요할 때
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-statefulset-service
  labels:
    app: nginx-statefulset-service
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx-statefulset

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx-statefulset
  serviceName: nginx-statefulset-service
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx-statefulset
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx-statefulset
        image: nginx
        ports: 
        - containerPort: 80
          name: web
    updateStrategy:
      type: RollingUpdate

=> statefulset 설정의 .spec.serviceNmae 필드에서 사용할 service를 설정함
service 설정의 .spec.selector 필드의 값과 statefulset 설정의 .spec.template.metadata.labels의 값이 같아야 해당 pod을 연결하는 서비스가 됨

$ kubectl get pods


NAME        READY   STATUS    RESTARTS   AGE
pod/web-0   1/1     Running   0          35s
pod/web-1   1/1     Running   0          20s
pod/web-2   1/1     Running   0          5s

=> statefulset의 기본동작은 순서대로 pod을 관리하는 것이기 때문에 pod이 0,1,2, 순서대로 생성되지만
statefulset의 .spec.podManagementPolicy: Parallel 옵션으로 Pod들이 병렬로 실행되게 할 수 있음

statefulset pod update

  • partition 설정
$ kubectl edit statefulset web
.
.
.
  updateStrategy:
    rollingUpdate:
      partition: 0    <==== 이부분 1로 수정
    type: RollingUpdate
.
.

$ kubectl set env statefulset web testenv=testvalue02
statefulset.apps/web env updated

$ kubectl get pods -o jsonpath="{range .items[*]}{.metadata.name}{.spec.containers[0].env}{'\n'}{end}"
web-0[map[name:testenv value:testvalue01]]   ==> 변동x
web-1[map[name:testenv value:testvalue02]]   
web-2[map[name:testenv value:testvalue02]]

=> .spec.updateStragegy.rollingUpdate.partition 필드값인 1보다 작은 번호의 pod 은 업데이트 되지 않음

  • type 설정

=> statefulset의 기본 updateStrategy는 rollingUpdate 라서 statefulset template이 변경되면 신규 pod 생성 + 기존 pod 삭제로 업데이트 내용이 바로 반영됨
.spec.updateStrategy.type: OnDelete 로 변경하면 기존 pod이 삭제되어야 업데이트 내용이 반영된 새 pod이 생성됨

service

  • 컨트롤러를 통해 실행된 pod는 재생성 될 때마다 IP가 변경되기 때문에 동적으로 변하는 pod에 고정적으로 접근하는 방법이 필요함
    => service 가 그 역할을 하며 네가지 type이 있음
  • ClusterIP: cluster 내부에서만 접근 가능한 서비스
  • NodePort: Node의 port를 클러스터 내부의 pod과 매핑시킴, 클러스터 외부에서 안으로 접근하는 가장 간단한 방법
  • LoadBalancer : 로드밸런서와 pod를 연결하여 해당 로드밸런서의 IP로 클러스터 외부에서 pod으로 접근하게 하는 방법 (EXTERNAL-IP)
  • ExternalName: CNAME을 이용하여 클러스터 내부 -> 외부로 접근하는 방법
---
apiVersion: v1
kind: Service
metadata: 
  name: service-test
spec:
  type: ClusterIP
  clusterIP: 10.0.10.10
  selector:
    app: myapp
  ports:
  - protocal: TCP
    port: 80
    targetPort: 80

=> type: ClusterIP이므로 내부 통신용 service,
labels = myapp 이고 port가 80로 열려있는 pod 을 연결하는 service 이며 10.0.10.10:80 으로 접근함

---
apiVersion: v1
kind: Service
metadata: 
  name: service-test
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
  - protocal: TCP
    port: 80
    targetPort: 80
    nodePort: 30080