본문으로 건너뛰기

4.1. OPENMARU COP CLI


OPENMARU COP는 표준 **kubectl**과 helm CLI를 사용합니다. 별도의 전용 CLI 없이 순수 Kubernetes 생태계 도구를 그대로 사용할 수 있는 것이 특징입니다.

kubeconfig 설정

kubectl/helm은 클러스터 접속 정보가 담긴 kubeconfig 파일을 통해 인증합니다. Master 노드에는 클러스터 설치 시 기본 kubeconfig가 생성되어 있습니다.

# Master 노드 기본 kubeconfig 위치(RKE2)
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
# 또는 설치 스크립트가 별도로 배치한 위치
export KUBECONFIG=/root/.kube/config

# 접속 확인
kubectl cluster-info
kubectl get nodes

원격지(개발자 PC 등)에서 접속하려면 Master 노드의 kubeconfig 파일을 로컬로 복사한 뒤 server 주소를 실제 API 서버 도메인(https://api.{sub_domain}.{domain}.{TLD}:6443)으로 맞춰줘야 합니다. 지속적으로 사용하려면 ~/.bashrc 등에 export KUBECONFIG=... 구문을 추가해 두는 것을 권장합니다.

ℹ️ 참고: OPENMARU COP Console에 여러 클러스터가 등록되어 있는 경우, 클러스터별 kubeconfig가 별도로 존재합니다. 대상 클러스터를 반드시 확인한 후 명령을 실행하십시오.


Helm 기본 명령어

# 저장소(Repository) 등록/갱신
helm repo add openmaru http://chartmuseum.{sub_domain}.{domain}.{TLD}:8181
helm repo update

# Chart 검색
helm search repo openmaru

# 설치
helm install <release> openmaru/<chart> -n <namespace> --create-namespace -f values.yaml

# 업그레이드 / 롤백
helm upgrade <release> openmaru/<chart> -n <namespace> -f values.yaml
helm rollback <release> <revision> -n <namespace>

# 조회
helm list -A
helm status <release> -n <namespace>
helm history <release> -n <namespace>

# 삭제
helm uninstall <release> -n <namespace>

⚠️ 주의: ArgoCD(GitOps)가 관리하는 Release에는 helm upgrade/helm rollback을 직접 실행하지 마십시오. auto-sync/self-heal이 설정된 경우 Git 저장소 기준으로 즉시 원복되어 변경이 무효화됩니다. 이 경우 Git 매니페스트를 수정 후 argocd app sync로 반영하거나 argocd app rollback을 사용해야 합니다.


Pod 로그 보는 방법

# 기본 로그 조회
kubectl logs -n <namespace> <pod-name>

# 실시간 스트리밍(follow)
kubectl logs -n <namespace> <pod-name> -f

# 이전(재시작 전) 컨테이너 로그 조회
kubectl logs -n <namespace> <pod-name> --previous

# 최근 100줄만 조회
kubectl logs -n <namespace> <pod-name> --tail=100

# 최근 1시간 로그만 조회
kubectl logs -n <namespace> <pod-name> --since=1h

# Pod 내 특정 컨테이너 로그 조회(다중 컨테이너 Pod)
kubectl logs -n <namespace> <pod-name> -c <container-name>

Pod 내 원격 접속

# 대화형 셸 접속
kubectl exec -it <pod-name> -n <namespace> -- bash

# bash가 없는 이미지의 경우
kubectl exec -it <pod-name> -n <namespace> -- sh

# 다중 컨테이너 Pod에서 특정 컨테이너 지정
kubectl exec -it <pod-name> -n <namespace> -c <container-name> -- bash

ℹ️ 참고: OPENMARU COP Console에서도 Pod 상세 화면의 Terminal 버튼을 통해 동일한 기능을 웹 브라우저에서 바로 사용할 수 있습니다.


비정상 Pod 삭제

# 특정 Pod 삭제(ReplicaSet/Deployment가 있으면 자동 재생성됨)
kubectl delete pod <pod-name> -n <namespace>

# 정상 종료 없이 즉시 강제 삭제(최후 수단)
kubectl delete pod <pod-name> -n <namespace> --grace-period=0 --force

# Running이 아닌 모든 Pod 조회 후 개별 판단
kubectl get pods -A | grep -v Running

⚠️ 주의: --force 옵션은 Pod가 정상적으로 정리되지 않은 채 즉시 삭제되므로, 데이터 정합성에 영향을 줄 수 있는 워크로드에는 신중하게 사용해야 합니다.


Running 중인 Pod의 Node 확인

kubectl get pod <pod-name> -n <namespace> -o wide

NODE 컬럼에서 해당 Pod가 실행 중인 노드를 확인할 수 있습니다.


Node별 Pod 정보 확인

# 특정 노드에서 실행 중인 Pod 목록
kubectl get pods -A -o wide --field-selector spec.nodeName=<node-name>

# 노드 상세 정보(할당 리소스, Conditions 등)
kubectl describe node <node-name>

# 전체 노드 리소스 사용량
kubectl top nodes

애플리케이션 SSL 적용 방법

애플리케이션에 TLS를 적용하려면 Ingress에 TLS Secret을 연결합니다.

# cert-manager를 통해 자동 발급받은 인증서는 자동으로 Secret 생성됨
# 수동으로 인증서/키를 등록하는 경우:
kubectl create secret tls my-app-tls \
--cert=my-app.crt --key=my-app.key \
-n <namespace>
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
namespace: my-app
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts: ["my-app.{domain}"]
secretName: my-app-tls
rules:
- host: "my-app.{domain}"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 8080

cert-manager를 사용하는 경우 ClusterIssuer(예: Let's Encrypt, 사내 CA)를 미리 구성해두면 Ingress 생성만으로 인증서가 자동 발급/갱신됩니다.

Console에서 확인: OPENMARU COP Console의 인증서 관리 메뉴에서 발급된 Certificate 목록과 상태, ClusterIssuer/Issuer 설정을 조회할 수 있습니다.

Certificate 목록

Pod 내 파일/폴더를 로컬로 가져오기

kubectl cp <namespace>/<pod-name>:/path/in/container ./local-path

# 특정 컨테이너 지정
kubectl cp <namespace>/<pod-name>:/path/in/container ./local-path -c <container-name>

로컬 폴더를 Pod로 전송하기

kubectl cp ./local-path <namespace>/<pod-name>:/path/in/container

ℹ️ 참고: kubectl cp는 대용량 디렉터리 전송 시 속도가 느릴 수 있습니다. 반복적으로 파일을 주고받아야 하는 경우 PVC(공유 볼륨)를 활용하는 것을 권장합니다.


Pod 내 명령어 실행(exec)

# 단발성 명령 실행
kubectl exec <pod-name> -n <namespace> -- ls -al /app

# 대화형 세션 없이 표준출력만 확인
kubectl exec <pod-name> -n <namespace> -- cat /app/config.yaml

Pod 증가 및 감소

# 특정 개수로 스케일
kubectl scale deployment my-app -n my-app --replicas=5

# 현재 Replica 수 확인
kubectl get deployment my-app -n my-app

# 표준 HPA로 자동 스케일링 설정(운영 트래픽에 따라 자동 증감)
kubectl autoscale deployment my-app -n my-app --cpu-percent=70 --min=2 --max=10

ℹ️ 시간 예약 기반 스케일링은 3.1. OPENMARU COP 운영절차 - 오토스케일링(HPA/CronHPA) 설정을 참고하십시오.


애플리케이션 빌드 관리 명령어

# S2I 빌드 실행
s2i build <소스_위치> <빌더_이미지> <결과_이미지>:<태그>

# Harbor 로그인(최초 1회 또는 자격 증명 만료 시)
docker login registry.{sub_domain}.{domain}.{TLD}:8443 -u admin -p ${HARBOR_PASSWORD}

# 이미지를 레지스트리로 Push
docker push registry.{sub_domain}.{domain}.{TLD}:8443/apps/<이미지명>:<태그>

# Deployment 이미지 태그 업데이트(롤링 업데이트 트리거)
kubectl set image deployment/my-app my-app=registry.{sub_domain}.{domain}.{TLD}:8443/apps/my-app:<신규_태그> -n my-app

# 배포 상태(롤아웃) 확인
kubectl rollout status deployment/my-app -n my-app

# 롤아웃 이력 확인
kubectl rollout history deployment/my-app -n my-app

# 이전 버전으로 롤백
kubectl rollout undo deployment/my-app -n my-app

배포/빌드/이미지 클린업

# 노드 내 미사용 컨테이너 이미지 정리(containerd)
crictl rmi --prune

# 노드 저널 로그 용량 제한
journalctl --vacuum-size=1G

# Harbor 미사용(Untagged) 이미지는 Harbor 콘솔의
# Administration > Garbage Collection 스케줄로 정리

Deployment 리소스 제한 설정

resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
# 기존 Deployment에 리소스 제한 패치
kubectl patch deployment my-app -n my-app --type='json' \
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/resources","value":{"limits":{"cpu":"1000m","memory":"1Gi"}}}]'

Pod 오토스케일링 설정

kubectl autoscale deployment my-app -n my-app --cpu-percent=70 --min=2 --max=10

# 생성된 HPA 확인
kubectl get hpa -n my-app
kubectl describe hpa my-app -n my-app

CronHPA를 함께 사용하는 경우 3.1. OPENMARU COP 운영절차를 참고하십시오.


프로젝트 쿼터 설정

apiVersion: v1
kind: ResourceQuota
metadata:
name: my-app-quota
namespace: my-app
spec:
hard:
requests.cpu: "8"
requests.memory: 16Gi
limits.cpu: "16"
limits.memory: 32Gi
pods: "50"
kubectl apply -f resourcequota.yaml
kubectl describe resourcequota my-app-quota -n my-app

프로젝트의 Pod/Container Limits 설정

apiVersion: v1
kind: LimitRange
metadata:
name: my-app-limits
namespace: my-app
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "250m"
memory: "256Mi"
max:
cpu: "2"
memory: "4Gi"
kubectl apply -f limitrange.yaml
kubectl describe limitrange my-app-limits -n my-app

Pod Terminating 상태 해제

Pod가 장시간 Terminating 상태에 머무를 경우 다음을 확인합니다.

# 강제 종료(최후 수단 - 데이터 정합성 영향 가능)
kubectl delete pod <pod-name> -n <namespace> --grace-period=0 --force

PV가 Terminating에서 멈춘 경우 finalizer 제거가 필요할 수 있습니다.

kubectl patch pv <pv-name> -p '{"metadata":{"finalizers":null}}'

⚠️ 주의: finalizer를 강제로 제거하면 실제 스토리지 백엔드의 볼륨 정리(삭제)가 누락될 수 있습니다. 스토리지 관리자와 함께 실제 볼륨 상태를 확인한 후 진행하십시오.


신규 프로젝트 생성

# 네임스페이스 생성
kubectl create namespace my-app

# 리소스 쿼터/제한 범위 함께 적용
kubectl apply -f resourcequota.yaml
kubectl apply -f limitrange.yaml

# CIS 보안 수준 라벨 적용
kubectl label namespace my-app pod-security.kubernetes.io/enforce=restricted

# 레지스트리 접근을 위한 ImagePullSecret 생성
kubectl create secret docker-registry harbor-secret \
--docker-server=registry.{sub_domain}.{domain}.{TLD}:8443 \
--docker-username=admin \
--docker-password=${HARBOR_PASSWORD} \
-n my-app

ℹ️ Console 또는 Jenkins 00-NEW-PROJECT Job을 통한 생성 절차는 3.1. OPENMARU COP 운영절차 - 프로젝트(네임스페이스) 생성을 참고하십시오.


Pod 내 컨테이너 메모리/CPU 확인

# 네임스페이스 전체 Pod 리소스 사용량
kubectl top pod -n <namespace>

# 클러스터 전체 Pod 리소스 사용량(메모리 기준 정렬)
kubectl top pods --all-namespaces --sort-by=memory

# 특정 Pod 상세 리소스 설정/사용량
kubectl describe pod <pod-name> -n <namespace>

Git 형상관리 저장소 주소 변경 시 작업

애플리케이션의 소스 저장소(GitLab 등) 주소가 변경된 경우 다음 항목을 함께 갱신해야 합니다.

  1. Jenkins Job의 GIT_URL 파라미터 갱신
  2. ArgoCD Application의 저장소 URL 갱신
    argocd app set my-app --repo https://gitlab.{sub_domain}.{domain}.{TLD}:1080/new-group/my-app.git --grpc-web
  3. 기존 Webhook(GitLab → Jenkins/ArgoCD) 재등록
  4. 필요 시 Git 자격 증명 Secret 갱신

⚠️ 주의: 저장소 주소 변경 후에는 반드시 1회 수동 빌드/동기화를 실행하여 파이프라인이 정상 동작하는지 확인하십시오.