쿠버네티스 자주 사용하는 명령어 정리

Published: by Creative Commons Licence

현재 쿠버네티스를 사용하면서 자주 사용하고 있는 명령어 및 유용한 Kubernetes CLI 명령어들을 정리해 두려고 한다. 매번 뭐였더라 하면서 인터넷 검색을 해왔는데 오늘이라도 노트에 정리해 보려고 한다.

리소스 조회

kubectl get + Resource명을 붙여서 조회한다. Resource의 종류에는 namespace, node, pod, svc, deployment, pv, pvc, configmap, secret 등이 있다.
pod Resource의 경우는 IP,NODE,NOMINATED NODE,READINESS GATES 정보를 추가로 확인이 가능하다.

# 기본조회  
$ kubectl get pod 

AME                      READY   STATUS    RESTARTS   AGE   
aaa-pod                  1/1     Running   0          7d18h

# 옵션을 통한 상세조회
$ kubectl get pod -o wide

AME                      READY   STATUS    RESTARTS   AGE     IP              NODE             NOMINATED NODE   READINESS GATES
aaa-pod                  1/1     Running   0          7d18h   10.244.3.137    cluster-01       <none>           <none>

# 상세 출력을 위한 Describe 커맨드
kubectl describe nodes my-node
kubectl describe pods my-pod

# Name으로 정렬된 서비스의 목록 조회
kubectl get services --sort-by=.metadata.name

# 재시작 횟수로 정렬된 파드의 목록 조회
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

# PersistentVolumes을 용량별로 정렬해서 조회
kubectl get pv --sort-by=.spec.capacity.storage

오브젝트 생성

# 파일이 있을 경우
$ kubectl create -f ./pod-multi-container.yaml

# stdin으로 단일 YAML 오브젝트 생성
$ kubectl create -f - <<END
apiVersion: v1
kind: Pod
metadata:
  name: pod-init
spec:
  containers:
  - name: container
    image: coolguy239/init
END  

# stdin으로 다수의 YAML 오브젝트 생성
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: busybox-sleep
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - sleep
    - "1000000"
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox-sleep-less
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - sleep
    - "1000"
EOF

로그확인

# app이 web인 파드 로그 조회
$ kubectl logs -f -l app=web

# 특정 파드만의 로그 확인 since 옵션을 주지 않으면 pod가 배포된 처음 로그부터 출력된다.
$ kubectl logs -f web-7bf57cd587-67vl5 --since=1m

파드의 컨테이너 접속

# 단일 Container의 경우
$ kubectl exec -ti web-7bf57cd587-67vl5 bash 

# 하나의 파드에 Multi Container로 구성된 경우
$ kubectl exec -ti -c container-name web-7bf57cd587-67vl5 bash

Pod의 리소스 사용량 조회

# CPU 높은순 
$ kubectl top pod --sort-by cpu | grep batch

# MEMORY 높은순 
$ kubectl top pod --sort-by memory | grep batch

events 조회

현재 운영중인 시스템에서 pod의 상태를 체크하는 배치가 돌면서 문제가 있을때 알람을 보내주는데 아무런 장애없이 pod의 running 상태가 1/1 아닌 0/1인 경우 알람이 오게 된다. evnet 확인을 위해 아래 명령어를 실행한다.

$ kubectl get events

LAST SEEN   TYPE      REASON      OBJECT                     MESSAGE
18s         Warning   Unhealthy   pod/web-7bf57cd587-m9qkp   Readiness probe failed: xxx
10m         Warning   Unhealthy   pod/web-7bf57cd587-m9qkp   Readiness probe failed: xxx

배포

# Rollout history(현 리비전을 포함한 디플로이먼트의 이력을 체크)
$ kubectl rollout history deployment/service1

# Rollout
kubectl rollout restart deploy/service1

# Rollout 중단(1대 배포 완료되고)
kubectl rollout pause deploy/service1

# Rollout 재개
kubectl rollout resume deploy/service1

# undo1(이전 디플로이먼트로 롤백 | 파드 한대만 배포 후 정상확인이 안되면 resume이 아닌 undo)
kubectl rollout undo deploy/service1

# undo2(특정 리비전으로 롤백)
kubectl rollout undo deploy/service1 --to-revision=86  

# pod 삭제
kubectl delete pod [pod name]             

쿠버네티스 대시보드 관련

계정생성

ServiceAccount를 admin-user라는 이름으로 만든다. ServiceAccount는 쿠버네티스에서 관리하는 계정을 의미한다. 쿠버네티스 대시보드 pod가 설치된 namespace에 ServiceAccount를 생성한다. 권한 롤은 이미 쿠버네티스내에서 정의되어 있는 권한 cluster-admin을 사용하게 되며 이는 모든 클러스터에 대한 접근을 할 수 있는 권한임을 의미합니다.

$ kubectl create -f - <<END
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: admin-user
    namespace: kubernetes-dashboard
END

계정생성 확인

$ kubectl get sa -n kubernetes-dashboard
NAME                   SECRETS   AGE
admin-user             1         2m26s
default                1         57m
kubernetes-dashboard   1         57m

계정 토큰 조회

계정 생성 후 토큰을 가지고 온다. 토큰에는 admin-user계정에 cluster-admin 권한 롤을 가지고 있다는 것을 의미한다. 이 토큰 값을 가지고 내가 유효한 자격을 소유하고 있다는 것을 증명할 수 있게 된다.

$ kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
Name:         admin-user-token-5t9t8
Namespace:    kubernetes-dashboard
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: admin-user
              kubernetes.io/service-account.uid: 840dd195-4443-4491-809d-c19c41015bc2

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1099 bytes
namespace:  20 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IktpaENCQUVMMXBsRXAtd1JFb0JEb1dZUDltMjNyZWhiZElXQWxWb0JPYmMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTV0OXQ4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI4NDBkZDE5NS00NDQzLTQ0OTEtODA5ZC1jMTljNDEwMTViYzIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.h3jZcuelIgzhtoPf-jz5XYOsdkf50Uz8Y5zEcNC_E3IFuUH4TtIIPagqpWo_EMHWob1zpm6qfi61sr7UjKQtjdT3_GaAiybAcbVj_V0-CQ6SgtFoTuEDmWxE549FFEgNXQolMOpELhwywDdpB1zTrLRoZxlry1jvFmFHXhsy0PE3glxSIztTEmJflOJYqbo4lZT5KJpzvyhvhT0TLXcZY8p4eR-Dz3BJtN0T1SvNOqjoF8jYr5fEZR13M9_M1J00Jm77NFbo5c2klHQzdLTAILlGJSZOJbpinuuP-EB82DOgSeNZSMn5RYYHJo6JK_A2CX3yQq-Zoscsxm0_sD5mWA

대시보드 로그인

토큰을 가지고 로그인 창에서 토큰을 선택하고 로그인을 진행하면 현재 쿠버네티스에 정의되어 있는 모든 자원을 확인할 수 있게 된다.

대시보드 삭제

$ kubectl --namespace kubernetes-dashboard delete deployment,service kubernetes-dashboard  

대시보드 백그라운드 실행

$ nohup kubectl proxy --port=8001 --address=192.168.56.30 --accept-hosts='^*$' >/dev/null 2>&1 &

쿠버네티스 Internal IP 변경

로컬 Virtualbox + vagrant 쿠버네티스 환경 구성 후 Pod내 Multi Container 구성을 하고 접속을 하려고 하는데 접속이 되지 않았다.
unable to upgrade connection: pod does not exist 오류메세지로 검색을 해보니 Internal IP가 동일해서 변경을 해야 한다는 얘기가 있어 변경 후 Container 접근이 가능해 졌다.

Internal IP 변경전

$ kubectl exec -ti -c container1 pod-1 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
error: unable to upgrade connection: pod does not exist

# kubectl get no -o wide
NAME          STATUS   ROLES                  AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION           CONTAINER-RUNTIME
k8s-master    Ready    control-plane,master   106m   v1.22.0   10.0.x.15     <none>        CentOS Linux 7 (Core)   3.10.0-1127.el7.x86_64   docker://20.10.8
k8s-worker1   Ready    <none>                 76m    v1.22.0   10.0.x.15     <none>        CentOS Linux 7 (Core)   3.10.0-1127.el7.x86_64   docker://20.10.8
k8s-worker2   Ready    <none>                 75m    v1.22.0   10.0.x.15     <none>        CentOS Linux 7 (Core)   3.10.0-1127.el7.x86_64   docker://20.10.8

Internal IP 변경

참고했던 블로그에서는 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 경로의 파일이 있다고 했는데 나같은 경우에는 /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf 경로에 파일이 있었다.
Master, Work 노드의 해당 경로의 파일의 마지막 줄에 –node-ip 를 추가한다. 에는 나의 host IP를 입력한다. 변경전

ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

변경후

ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS --node-ip <hostip>

systemctl daemon-reload && systemctl restart kubelet 실행

$ systemctl daemon-reload && systemctl restart kubelet

노드 정보 확인

kubectl get nodes -o wide  
NAME          STATUS   ROLES                  AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION           CONTAINER-RUNTIME
k8s-master    Ready    control-plane,master   131m   v1.22.0   192.168.xx.x1   <none>        CentOS Linux 7 (Core)   3.10.0-1127.el7.x86_64   docker://20.10.8
k8s-worker1   Ready    <none>                 101m   v1.22.0   192.168.xx.x2   <none>        CentOS Linux 7 (Core)   3.10.0-1127.el7.x86_64   docker://20.10.8
k8s-worker2   Ready    <none>                 100m   v1.22.0   192.168.xx.x3   <none>        CentOS Linux 7 (Core)   3.10.0-1127.el7.x86_64   docker://20.10.8

k8s-master, k8s-worker1, k8s-worker2 노드에서 각각 hostip를 추가하고 kubelet을 restart 한다.

Resource Edit 수정

$ kubectl edit svc/svc-03
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Service
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"svc-03","namespace":"default"},"spec":{"ports":[{"port":8080,"protocol":"TCP","targetPort":8080}],"selector":{"ver":"v1"}}}
  creationTimestamp: "2021-09-15T15:27:46Z"
  name: svc-03
  namespace: default
  resourceVersion: "117755"
  uid: 609d018e-fae1-4b44-8524-408117d3e54f
spec:
  clusterIP: 10.101.0.145
  clusterIPs:
  - 10.101.0.145
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    ver: v4
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
service/svc-03 edited

참고

Kubernetes 공식 Document
KUBERNETES DASHBOARD 사용하기
K8S node Internal IP 변경