쿠버네티스를 다루다보면 트러블 슈팅을 위해 pod에 직접 접근해야하는 경우가 발생한다. 이때 파드에 직접 접속하는 명령어는 다음 두 가지가 있다.
- kubectl attach
- kubectl exec
처음 두 명령어를 접하면 어떤 차이가 있는지 매우 햇갈리고, attach는 특히나 실제 사용 사례를 검색하여도 잘 찾아지지 않기 때문에 이번 글에서는 위 두 가지 명령어의 쓰임과 차이점에 대해 분석하고자 한다.
kubectl attach
attach의 설명을 구글링해보면 다음과 같이 나온다.
- Attach to a process that is already running inside an existing container. -> 공식 문서
- The kubectl attach command is similar to kubectl exec, but it attaches to the main process running in the container instead of running an additional one. -> chatgpt의 답변
영어를 보면 마음이 매우 불편하기 때문에 한글로 번역하면 다음과 같다.
- Attach 는 컨테이너 내에서 이미 동작중인 프로세스에 붙는 명령어이다.
- kubectl attach는 kubectl exec와 매우 유사하지만, kubectl attach로 파드에 붙는 경우엔 추가적인 프로세스를 동작시키는 것이 아니라 컨테이너에서 동작중인 메인프로세스에 붙는것이다.
한글을 읽어도 이해가 안가는 경우가 많으니.. 테스트를 해보며 결과를 보는것이 가장 빠르다.
attach 테스트
1) nginx 파드 생성 후 attach
$ kubectl run nginx --image=nginx:latest
$ kubetcl attach -it nginx
위 예시 명령어로 간단하게 nginx pod를 생성하고 attach를 시도해보았다.
여기서 옵션을 간단히 설명하면 다음과 같다.
-i : --stdin 의 줄임말로, 파드의 표준입력을 활성화하는 것이다. -i 옵션이 있어야만 명령어 입력을 제공할 수 있다.
-t : --tty의 줄임말로, 파드와 표준 입출력을 연결하는 터미널을 활성화하는 옵션이다. 이 옵션을 사용하면 파드에서 실행중인 명령어에 대한 결과를 실시간으로 표시 가능하다.
결과를 보면 뭔가 에러메시지도 없고 접속은 된거같은데 명령어를 입력하거나 작업을 수행할 수 없다. 즉 파드에 -it 옵션을 활성화하여 붙었지만, /bin/bash와 같이 쉘이 메인프로세스로 동작하고 있지 않기 때문에 사용자가 원하는 명령어를 입력하는 등의 동작을 할 수 없다.
2) pod에 stdin 과 tty 설정 추가
$ vi nginx_tty_stdin.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-tty-stdin
spec:
containers:
- image: nginx:latest
name: nginx-tty-stdin
tty: true
stdin: true
$ kubectl apply -f nginx_tty_stdin
$ kubectl attach -it nginx_tty_stdin
이번에는 yaml 파일을 통해 pod에 stdin과 tty 설정을 true 해주고 테스트를 진행해봤다.
아까와는 다르게 tty 옵션이 잘 적용되어 사용자의 화면에 파드로그가 출력되지만 쉘이 메인프로세스로 동작하고 있지 않기 때문에 여전히 사용자의 명령어 입력은 불가능하다.
ctrl+c를 입력하면 SIGINT 신호가 입력되어 프로세스를 중지시킬 수 있다. 여기서 알 수 있는점은 kubectl attach로 파드에 붙은 후 ctrl+c로 접속을 종료하면 메인 프로세스가 종료되어 컨테이너가 재시작된다는 것이다.!
3) command: ["/bin/bash"] 설정 추가
$ vi nginx-tty-stdin-bash
apiVersion: v1
kind: Pod
metadata:
name: nginx-tty-stdin-bash
spec:
containers:
- image: nginx:latest
name: nginx-tty-stdin-bash
command: ["/bin/bash"]
tty: true
stdin: true
restartPolicy: Never
$ kubectl apply -f nginx-tty-stdin-bash
$ kubectl attach -it nginx-tty-stdin-bash
command에서 /bin/bash를 실행하도록 설정하였으므로 이제 메인프로세스로 /bin/bash가 동작중일 것이다.
도커 컨테이너내에는 command로 지정한 프로세스가 PID1 즉, 메인프로세스가 된다.
추가적으로 ctrl+d 로 쉘을 종료하는 경우 컨테이너가 죽는지 확인하기 위해 restartPolicy: Never를 설정하여 컨테이너 프로세스가 죽어도 컨테이너를 재시작하지 않도록 설정하였다.
드디어 원하는대로 bash 쉘에 사용자가 원하는대로 명령어를 입력할 수 있는 형태로 attach 되었다.
마지막으로 exit(ctrl+d)로 attach 상태를 종료하면 컨테이너 메인 프로세스가 종로되어 아래와 같이 Pod 상태가 Error로 바뀌게 되는 것을 볼 수 있다.
kubectl exec
kubectl exec 사용법은 예시를 통해 살펴보도록 하겠다.
1) 파드에 접근하여 명령어 1회 수행
$ kubectl exec nginx -it -- ls
2) 파드에 bash 쉘로 접근
$ kubectl exec nginx -it -- /bin/bash
3) 1회용 테스트 파드 생성 -> 테스트 완료후 자동 제거
$ kubectl run test --image=nginx -it --rm --restart=Never -- /bin/bash
--rm : ctrl+d로 파드 쉘을 종료하면 파드가 자동으로 제거된다.
--restart=Never : 컨테이너의 프로세스가 종료되어도 컨테이너를 재시작하지 않도록 설정
컨테이너가 생성됨과 동시에 파드에 bash 쉘로 붙게된다.
ctrl+d로 bash쉘을 종료하여 파드에서 빠져나오면 pod까지 자동으로 제거된다.
kubectl exec의 경우 메인프로세스로 접근하는 것이 아닌 새로운 프로세스로 bash 쉘을 동작시켜 접근하는 것이기 때문에 기본적으로는 exit 명령어를 입력하여도 컨테이너가 죽지 않지만 위에 예시처럼 --rm 옵션을 사용하면 attach와 비슷하게(?) 사용이 가능하다.
'k8s' 카테고리의 다른 글
DevOps를 위한 쿠버네티스 마스터 강의 정리(2) (0) | 2024.03.12 |
---|---|
DevOps를 위한 쿠버네티스 마스터 강의 정리(1) (0) | 2024.03.12 |
[Helm 작성하기 (1)] Helm 차트 구조 (0) | 2023.02.03 |
쿠버네티스 완벽 가이드 2장 : 쿠버네티스 특징 간단히 알아보기 (1) | 2023.02.02 |
쿠버네티스 완벽 가이드 1장 : Docker (0) | 2023.01.19 |