제미나이 CLI(Gemini CLI)로 쿠버네티스 관리하기
터미널에서 인공지능 에이전트를 통해 업무 효율성을 높이는 도구로는 클로드 코드(Claude Code)가 가장 유명합니다. 다만 클로드 코드의 경우 무료 사용자는 경험해 보기조차 어려워 제한적인 사용자들만 사용하고 있는 상태입니다.
이러한 문제는 6월 말 공개된 ‘제미나이 CLI(Gemini CLI)’로 개선되었습니다. 이제는 인공지능 에이전트를 필요로 하는 누구나 터미널 환경에서 제미나이 CLI로 기술을 경험하고 사용할 수 있습니다.

물론 제공하는 기능이나 옵션은 클로드가 월등히 많아 할 수 있는 것도 많습니다. 그러나 빠른 체험으로 효과를 알기 위해서는 제미나이 CLI도 충분히 괜찮은 결과물을 보여줍니다.

이번 글에서는 그러한 제미나이 CLI를 활용해 쿠버네티스를 관리하는 방법에 대해 알아보겠습니다.
제미나이 CLI 설치하기
그럼 제미나이 CLI를 설치하는 것부터 진행해 보겠습니다.
*제미나이 CLI 설치 방법은 계속 달라질 수 있으므로, 기준 시점에서 공식 깃허브 페이지를 참고하는 것이 좋습니다.
제미나이 CLI는 Node.js 18 이상 버전을 요구하므로, 페이지 안내에 따라 우선 Node.js를 설치하고 구성해야 합니다.

제미나이 CLI를 활용하려면 ‘제미나이 API 키’를 입력해야 합니다.
이를 위해 구글 AI 스튜디오(Google AI Studio)에 접속합니다. 기존 프로젝트가 있다면 이를 선택하고, 없다면 프로젝트를 새로 생성합니다. 그런 다음 해당 프로젝트에서 + API 키 만들기 버튼을 클릭합니다.

API 키를 생성했다면, 이를 복사합니다.
참고로 API 키는 실제로는 공개적으로 노출되지 않아야 하는 정보입니다. (아래 예시의 API 키는 이미 삭제된 상태입니다.)

API 키는 export 명령으로 사용할 수도 있지만, 편리하게 쓰려면 zshrc나 bashrc 파일에 추가해 셸(shell)을 시작할 때마다 자동으로 불러오도록 설정할 수 있습니다.

다음으로, 명령어를 설치하고 구성하기 위해 npm install 명령어를 실행합니다.

이렇게 간단하게 제미나이 CLI에 명령을 실행할 준비를 마쳤습니다.
제미나이 CLI로 현재 쿠버네티스 정보 확인하기
본격적으로 명령을 실행하기 전에는 새 디렉터리를 생성하는 것을 권장합니다. 수행하는 명령에 따라 .py나 .yaml 파일을 생성하거나 중간 데이터를 저장하는 경우가 있기 때문입니다.
다음 명령어로 디렉터리를 만들고 이동합니다.

이제 gemini 명령을 실행하면 아래와 같은 환영 페이지가 나타납니다. 명령이 아닌 일반 구문을 입력할 수 있는 터미널 화면입니다.

/help 명령어로 어떤 명령어를 쓸 수 있는지 확인합니다.

처음부터 자주 사용할 명령어가 많지는 않습니다. 간단히 현재 셸(shell)의 상태를 확인하기 위한 용도로 !ls -l 정도 사용할 수는 있습니다. 다만 실제 터미널을 따로 사용하는 것이 더욱 편리합니다.
첫 질문으로 내가 가진 클러스터의 종류를 물어봅니다. 자세히 어떻게 하라고는 지시하지 않았습니다.
Prompt | What kind of cluster I have?
제미나이 CLI는 기본적으로 kubectl version 명령을 실행하려고 시도합니다. 질문 자체가 잘못이어서 답도 잘 못 나온 경우입니다. 이 명령이 불필요하다고 느껴지면 No를 선택하거나 esc 키를 눌러 종료합니다.

이처럼 진행을 매번 확인하는 것이 번거롭다고 느낄 수 있습니다. 그럴 때는 ctrl+y를 눌러 앞으로의 명령을 자동으로 모두 yes 처리하도록 설정할 수 있습니다. 하지만 이번에는 이 설정을 적용하지 않았습니다.
그 대신 /quit 명령어를 입력하거나 crtl+c를 눌러 현재 제미나이 터미널을 종료하고, gemini -y를 실행해 자동으로 YES 되도록 설정했습니다. 그런 다음 다시 제미나이 CLI를 실행했습니다.

이번에는 질문을 조금 바꿔 쿠버네티스 클러스터의 컨텍스트(context)를 나열해 달라고 요청합니다.
Prompt | List up my kubernetes clusters's context
질문을 영어로 작성한 이유는 한글과 영어를 동시에 입력하는 것이 불편하기도 하고, 때로는 용어 차이로 정확하지 않은 답변이 나올 수 있기 때문입니다. 물론 한글 입력을 선호한다면 한글로 질문해도 무방합니다. 잘못된 답변이 나오면 다시 질문해 해결하면 됩니다.

답이 나왔습니다. ‘kubernetes-admin@kubernetes’ 컨텍스트를 복사해 만들었기에 화면에는 4개가 나타나지만, 실제로는 모두 동일한 항목임을 알 수 있습니다. 또한, -y(자동 수락) 모드로 진행해 확인 절차 없이 즉시 명령이 수행된 것도 보입니다.
이번에는 컨텍스트를 gke로 바꿔 달라고 요청합니다.
Prompt | how could I change context to gke?

잘 수행된 것처럼 보입니다. 그래도 확인이 필요하니 현재 컨텍스트를 보여달라고 합니다
Prompt | show current context

큰 문제는 없습니다. 다만 -y모드(yolo 모드)는 편리해도, 작업 중에 생성하고 적용하는 부분이 생길 수 있어 그대로 두기가 위험해 보입니다. 따라서 본격적인 작업을 진행할 때는 yolo 모드를 사용하지 않는 것이 좋습니다.
저 역시 본격적인 테스트에 앞서 ctrl+y를 입력해 yolo 모드를 해제했습니다.
간단한 테스트를 완료했으니 이제 제미나이 CLI로 쿠버네티스에 앱을 배포하는 실습을 진행하겠습니다.
제미나이 CLI로 쿠버네티스에 애플리케이션을 배포하고 서비스로 노출하기
이제 웹 애플리케이션을 배포하고 80번 포트로 노출해달라고 요청해 봅니다.
Prompt | Deploy web application to current context and expose it for port 80

그러나 이 정도의 요청으로는 바로 배포되지 않습니다. 제미나이(Gemini)가 ‘이미지를 어떻게 지정하면 좋을까?’라고 다시 질문합니다.
이미지는 nginx stable 버전을 사용하며, 이름도 그대로 사용해 달라고 요청합니다.
Prompt | image is nginx stable version and name is same as that
하지만, 이 요청에 따라 제미나이가 구글 검색으로 nginx stable 버전을 찾는 중 아래처럼 쿼터(quota) 제한에 걸렸습니다. 이는 제 기존 사용 이력이 누적되어 발생한 것으로, 제미나이를 사용할 때는 이 제한을 우회할 방법이 있습니다.

쿼터 제한 문제를 해결하기 위해 다른 계정으로 구글 AI 스튜디오에 로그인해 새 API 키를 발급받습니다. 그렇게 받은 새 API 키를 export 명령으로 다시 적용하면 해결됩니다.

새로운 API 키 등록까지 마치고 다시 제미나이 CLI를 실행했습니다. 한 번 더 nginx stable 이미지를 지정하고 배포를 요청합니다.
Prompt | Deploy web application to current context and expose it for port 80. web application image is nginx stable version

명령이 내가 의도한 내용과 일치하는지 먼저 확인합니다. 문제가 없었기에, Yes, Allow once 옵션을 선택합니다.
이때 Allow always “kubectl …” 옵션을 선택하면 앞으로 kubectl 관련 명령어는 별도 확인 없이 즉시 실행됩니다. 안전을 위해 ‘Yes, Allow once’를 선택해 진행하는 것이 좋습니다.

배포된 nginx-deployment 서비스를 외부에 노출시키기 위한 명령 또한 의도와 같다면, 다시 한번 Yes, Allow once를 선택합니다.
모든 과정을 거쳐 nginx-deployment 서비스가 노출되었다고 표시됩니다.

이로써 기본적인 웹 애플리케이션을 배포하고 로드밸런서(LoadBalancer) 타입으로 노출했습니다. 이제 제미나이 CLI로, 가용성을 더 높이거나 개선할 부분이 있는지 분석하고 적용해 보겠습니다.
제미나이 CLI로 쿠버네티스에 배포된 앱의 상태 개선하기
고가용성 확보 제안과 적용
(답이 정해져 있는 질문을 하는 것 같지만) nginx에 대한 고가용성(HA)을 확보하려면, 어떻게 하는 것이 좋을지 의견을 물어봅니다.
Prompt | how could I do HA for nginx?

AI가 현재 1개인 파드(Pod)를 3개로 늘리라고 제안합니다. AI의 제안을 실제 수행으로 이어가려면, Yes, Allow once를 선택하면 됩니다.
곧 배포를 마쳤다고 안내가 나왔지만, 그래도 일반 터미널에서 배포 상태를 실제로 확인하는 것이 좋습니다. k get po,svc로 확인했고, 큰 문제는 없었습니다.

파드 수를 늘리자는 1번 제안 외에도 AI는 추가로 고가용성을 높일 방법들을 주었습니다.


2번 제안은 헬스 체크(Health check)로 상태를 보고 정상 상태의 파드에만 서비스 트래픽이 전달되도록 설정하는 것, 3번 제안은 안티 어피니티(Anti-Affinity) 패턴 적용으로 가능한 파드가 서로 다른 노드에 균등하게 배포되도록 설정하는 것입니다. 또, 4번째로는 AZ(가용 영역)를 이용한 배치도 제안했으나, 현재 환경에는 AZ가 존재하지 않으므로 이 부분은 의미가 없습니다.
사실 이런 제안은 긴 데다 영어라 읽기 어려울 수 있습니다. 그럴 때는 다음과 같이 요청합니다.
Prompt | 한국어로 짧게 설명해줘
AZ가 빠진 3가지 방법으로만 정리해 줬습니다. 또, 이미 실행한 1번 외에 2번을 진행하는 것이 어떻겠냐고 물어옵니다.

이에 따라 2번 항목인 헬스 체크 구성을 요청합니다.
Prompt | okay please apply Health probes for nginx app
AI는 이를 적용하기 위해 현재 배포된 워크로드의 YAML 파일을 확인하겠다고 합니다. Yes, Allow once를 선택합니다.

기존 YAML 내용을 확인한 AI는 헬스 체크를 위한 프로브(probe) 설정을 추가하여 보여줍니다. 설정 내용을 다시 확인한 후 다음 이어 진행합니다.

… 중략 …

이렇게 헬스 체크 프로브 추가를 위한 kubectl patch 명령 수행이 완료되었습니다.

다음으로 안티 어피니티(anti-affinity) 설정을 진행하기 전, 정확히 어떠한 작업이 수행되는지 세부 내용을 문의합니다.
Prompt | How about anti-affinity? do you have any suggestion?
AI가 적용할 내용을 보여주며 실행 여부를 묻습니다.

이 설정을 반드시 적용해야 하는지 의문이 생깁니다. 설정 적용 시 장단점에 대해 다시 문의합니다.
Prompt | What is the pros and cons?

중간에 한글로 요청해서 그런지 한국어가 섞여 나옵니다. 종합적인 답을 보니 설정이 꼭 필요한 것으로 보이지 않습니다. 쿠버네티스 스케줄러가 기본적으로 최선을 다해(best-effort) 파드를 분산 배치하기 때문입니다. 따라서 이번 설정은 건너뛰기로 합니다.
실제 환경에 유용한 리소스 요청과 제한에 대한 제안과 적용
그 대신, 현업 환경에서 더욱 유용한 리소스 요청(request)과 제한(limit)을 제안해 달라고 AI에게 요청합니다.
Prompt | How about request and limit. do you have any suggestion value?

제안 받은 값이 마음에 듭니다. 이제 AI가 제안한 값을 nginx-deployment에 적용해달라고 요청합니다.
Prompt | yes I want to apply requests and limits for nginx-deployment

생성된 내용을 확인하고 Yes, Allow once를 선택했습니다. 곧 적용 완료 메시지까지 확인했습니다.
이제까지 적용한 방법들 외에 서비스 관련해 추천할 다른 것이 있는지 문의했습니다.
Prompt | Do you have recommendation for nginx-deployment service?


인그레스(Ingress) 사용과 로드밸런서 관련 externalTrafficPolicy 적용을 추천합니다.
하지만 답을 보고 나니, ‘externalTrafficPolicy는 사이드 이펙트가 있을텐데’라는 생각이 들었습니다. 기본값을 벗어날 때는 항상 유의해야 합니다.(관련 링크) 이런 문제를 AI에 다시 물었습니다.
Prompt | Side effect for externalTrafficPolicy to Local


AI는 설정을 반드시 적용해야 하는 것처럼 답했습니다. 그래도 객관적인 확인을 위해 클로드(Claude)에게 같은 것을 물었습니다.
Prompt | externalTrafficPolicy를 Local로 하는 경우 문제점

답변 가운데 ‘가용성 저하가 나타날 수 있다’는 점은 실제 문제가 될 수 있습니다. 문제가 있다, 없다 판단하는 기준이 모호한 경우, 잘못 판단하면 서비스 장애로 이어질 수도 있습니다.
그래서 이는 더 진행하지 않기로 합니다.
보안 관련 포트 사용에 대한 제안과 적용
마지막으로, 보안 관점에서 80번 포트를 꾸준히 사용해도 되는지 AI에게 문의합니다.
Prompt | no how about port 80. is it unsecure?


제가 문의한 80번 포트는 파드 외부로 노출하는 포트를 의미한 것입니다. 내용을 좀 더 정확하게 수정해 다시 문의합니다.
Prompt | I mean just 80 port for outside. I think 8080 and container port 80 is better?


AI는 곧 내부와 외부에서 모두 80번 포트를 사용하는 것을 추천하였습니다. 또한 굳이 8080번 포트가 필요하다면 인그레스(Ingress)를 활용하는 편이 더 좋다고 추가로 제안합니다.
지금 환경에서는 AI 추천을 따르는 것이 더 나을 것으로 판단하여 설정을 유지하기로 결정합니다.
마치며
이렇게 제미나이 CLI 설치부터 간단한 쿠버네티스 배포와 개선 작업을 진행했습니다.
도구를 쓰다 보니 질문 잘하는 법과 답을 잘 구분해 내는 법이 필요할 것으로 느껴졌습니다. AI가 현재 상태를 분석하고 뛰어난 제안을 하지만 그것을 판단하고 적용하는 것은 오롯이 인간의 몫이었습니다.
다음에는 제미나이 CLI로 프로메테우스와 그라파나를 배포하고 연동하는 법을 알아보겠습니다. 마지막으로 제미나이 CLI 사용을 위해 알아야 할 것도 정리해 보겠습니다.
작가
조훈(CNCF 앰버서더)
시스템/네트워크 IT 벤더의 경험 이후, 메가존 GCP 클라우드 팀에서 쿠버네티스와 연관된 모든 프로젝트에 대한 Tech Advisor 및 Container Architecture Design을 제공하고 있다. 페이스북 ‘IT 인프라 엔지니어 그룹’의 운영진을 맡고 있으며, 오픈 소스 컨트리뷰터로도 활동한다. 지식 공유를 위해 인프런/유데미에서 앤서블 및 쿠버네티스에 관한 강의를 하기도 한다. 책 <컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커> 등 3권을 썼다. CNCF(Cloud Native Computing Foundation) 앰버서더로서 쿠버네티스 생태계가 더 활발하게 퍼질 수 있도록 기여하고 있다.
심근우
LG유플러스 CTO부문에서 대고객 비즈니스 시스템의 DevOps를 담당하는 UcubeDAX팀의 팀장으로 일하고 있다. 퍼블릭 클라우드와 프라이빗 클라우드에 걸친 쿠버네티스 클러스터를 안정적으로 운영하기 위해 노력하고 있으며, 특히 주니어 DevOps 엔지니어들의 육성에 큰 관심을 가지고 있다.
문성주
체커(CHEQUER) 사의 DevOps Engineer로서 쿠버네티스의 멀티 클러스터 관리 방법론과 쿠버네티스 구현체(CAPI, OCI)에 대한 명세와 컨테이너 리소스 격리 방법에 대한 연구를 병행하고 있다. 이런 연구 활동을 기반으로 쿠버네티스 볼륨 테스트 파트에 컨트리뷰션했다. 본업은 쿠버네티스 오퍼레이터와 같은 CRD(커스텀 리소스)를 개발해 현업에서 쿠버네티스를 좀 더 편리하게 사용할 수 있도록 돕는 일이다. 또한, 페이스북 그룹 ‘코딩이랑 무관합니다만'과 ‘IT 인프라 엔지니어 그룹'의 운영진을 맡고 있다.
이성민
미국 넷플릭스(Netflix) 사의 Data Platform Infrastructure 팀에서 사내 플랫폼 팀들과 데이터 사용자들을 어우르기 위한 가상화 및 도구들을 개발하는 일들을 하고 있다. 과거 컨테이너와 쿠버네티스에 큰 관심을 두고 ingress-nginx를 비롯한 오픈 소스에 참여했으며, 현재는 데이터 분야에 일하게 되면서 stateful 한 서비스들이 컨테이너화에서 겪는 어려움을 보다 근본적으로 해결하기 위한 많은 노력을 하고 있다.
©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.