Cloud Platform/Naver Cloud

[NCP] Ncloud Kubernetes Service 사용하기(kubectl 사용하여 pod 생성하기) - 2편

코끼리 개발자 2024. 3. 19. 23:31
728x90
SMALL

 

 

 

 

1편에 이어 2편에서는 cluster와 상호작용하기 위해 서버에 접속하여 pod를 생성하는 작업을 

진행해보려고 한다.

*pod 내부에서 외부로 접속되지 않는 현상으로 인해 문제가 있었고 이를 해결하는 과정도 작성되어있으니 같은 문제가 발생한다면 참고하여 해결하는데 도움이 될 수 있을 것 이다!*

 

1편에서는 서버 생성과 vpc 생성, kubernetes 생성 및 Container Registry 생성 방법에 대해 작성했으니

참고하면 된다.

 

[NCP] Ncloud Kubernetes Service 사용하기(+ Container Registry 사용 까지) - 1편

프로젝트를 진행하면서, 롤링 업데이트 배포 전략을 사용하기 위해 NCP에서 제공해주는 쿠버네티스를 이용해 보았다. 진행 중에 내 입맞에 맞는 알맞는 가이드를 잘 못찾아서 해결하느라 정말

elephant-dev.tistory.com

 

 

 

이제 클러스터와 상호작용 하기 위해 만들어 두었던 서버에 접속해서 pod 생성을 해보려고 한다.

우선 서버 생성시 사용했던 인증키 (xxx.pem 파일)을 드래그해서 관리자 비밀번호를 확인한다.

해당 비밀번호를 통해 ssh 접속을 시도하면 된다.

ssh root@공인IP

접속해서 출력된 비밀번호 입력하여 접속하면 된다.

 

서버 접속에 성공했다면 이제 도커와 kubectl을 설치 해야 한다.


1. docker 설치

 

홈디렉터리에서 작업을 시작할 것이므로 홈 디렉터리로 이동한다.

cd ~

 

도커를 설치하기 위해 도커 Yum 레포지토리를 등록한다.

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

 

 

도커를 설치한다.

yum install docker-ce docker-ce-cli containerd.io -y

 

 

도커 서비스를 시작하고 서버 재 구동 시 자동으로 도커가 시작될 수 있도록 설정한다.

systemctl start docker
systemctl enable docker

 

나의 경우, 이미 컨테이너 레지스트리에 도커 이미지를 올려놓은 상태이므로 참고하자

레지스트리에 도커 이미지를 업로드 하는 방법에 대해서는 이후 추가 포스팅 하겠다.

 

이후 도커에 로그인 해야하는데 이전에 만들었던 Container Registry에 출력되었던 login 방법을 수행하면 된다.

해당 부분을 복사해서 입력하면 key를 입력하라고 할 것 이다.

 

API 키를 발급받아야 하는데 

계정 관리 탭에 들어가 API 인증키를 발급 받거나, 이미 있다면 해당 Key와 Secret Key를 이용하여 로그인 하면 된다.

push할 이미지가 있다면 미리 registry에 push 해 놓으면 된다.

 


2. Kubectl, ncp-iam-authenticator 설치

 

최신 버전의 kubectl 바이너리를 다운로드 한다. 시간이 좀 소요될 수도 있다.

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

 

 

다운로드한 kubectl을 설치하고 파일의 권한을 수정한다.

현재 root로 접속했기 때문에 sudo 명령어 없이 그냥 진행해주면 된다.

sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

 

설치를 완료하고 잘 설치 되었는지 클라이언트 버전 확인 명령어를 통해 버전이 잘 출력되는지 확인한다.

kubectl version --client

 

다음은 ncp-iam-autentication 바이너리 파일을 네이버 클라우드에서 다운로드 한다.

curl -o ncp-iam-authenticator https://kr.object.ncloudstorage.com/nks-download/ncp-iam-authenticator/v1.0.0/linux/amd64/ncp-iam-authenticator

 

다운로드가 완료되었다면 chmod 명령어를 통해 실행 권한을 추가하고 바이너리를 복사해서 생성한다

chmod +x ./ncp-iam-authenticator && mkdir -p /root/bin && cp ./ncp-iam-authenticator /root/bin/ncp-iam-authenticator

 

다음은 Bash 프로파일에 위에서 만든 bin폴더를 path에 추가하여 바라볼 수 있도록 해준다

echo 'export PATH=$PATH:HOME/bin' >> ~/.bash_profile

 

다음은 새로 적용한 bash_profile을 적용할 수 있도록 아래 중 한가지를 입력하여 재 적용 해준다

. ~/.bash_profile
source ~/.bash_profile

 

ncp-iam-autentication가 제대로 설치되었는지 help 명령어를 통해 잘 출력되는지 확인한다.

ncp-iam-authenticator help

 

다음은 IAM Autentication 설정 파일을 생성하고 편집진행해야한다

아래 커맨드 순서대로 진행해서 파일과 폴더를 생성해준다.

mkdir ~/.ncloud: ~/.ncloud
vi ~/.ncloud/configure

 

이제 configure파일에 위에서 확인했던 API key를 작성하고 esc -> :wq를 통해 저장하고 나온다

[DEFAULT]
ncloud_access_key_id=<Access key>
ncloud_secret_access_key=<Secret Key>
ncloud_api_url=https://ncloud.apigw.ntruss.com

[project]
ncloud_access_key_id=<Access key>
ncloud_secret_access_key=<Secret Key>
ncloud_api_url=https://ncloud.apigw.ntruss.com

 

다음은 .bash_profile을 열어 NCLOUD API 키 관련 설정값을 추가해 줄 것이다

vi ~/.bash_profile

 

다음의 내용을 .bash_profile의 맨 끝에 위에서 확인했던 API Key를 올바르게 기입해서 추가해주면 된다.

NCLOUD_ACCESS_KEY=<Access Key>
NCLOUD_SECRET_KEY=<Secret Key>
NCLOUD_API_GW=https://ncloud.apigw.ntruss.com
NCLOUD_PROFILE=project

 

다음은 IAM Authenticator를 사용해 Kubernetes의 kubeconfig 파일을 생성해 주면 된다

ncp-iam-authenticator create-kubeconfig --region KR --clusterUuid <kubernetes uuid> > kubeconfig.yml

위 커맨드에서 필요로하는 cluster uuid는 ncp 페이지의 Ncloud Kubernetes Service에 클러스터 uuid를 입력하면 된다.

<kubernetes uuid> 이 부분을 치환해서 넣고 그 옆 > 꺽쇠는 살려두어야 yml파일 생성되니 주의하자!

빨간색 복사 버튼을 눌러 클러스터 uuid를 가져오면 된다.

 

이제 생성된 kubeconfig 파일을 이용하여 쿠버네티스 클러스터의 네임스페이스를 조회했을 시 잘 출력된다면 잘 연결 되었음을 알 수 있다.

kubectl get namespaces --kubeconfig kubeconfig.yml

 

이제 bash_profile을 열어 kubeconfig 파일을 사용해 kubectl 명령어를 사용할 수 있도록 alias를 걸어준다.

alias kubectl='kubectl --kubeconfig="/root/kubeconfig.yml"'

 

완료가 되었다면 다시 .bash_profile 적용을 위해 두 명령어 중 한가지를 수행하여 수정된 프로파일을 적용해준다.

. ~/.bash_profile
source ~/.bash_profile

 

도커의 레지스트리 접근정보를 사용해 쿠버테시트 시크릿을 생성한다.

kubectl create secret docker-registry regcred 
--docker-server=<Contaner registry public Endpoint> --docker-username=<사용자의 Access key> 
--docker-password=<Secret Key> --docker-email=<ncp 계정메일>

 

생성이 완료되었다면 적용이 잘 되었는지 다음 명령어를 통해 시크릿 목록을 확인한다.

kubectl get secret

 

 

이렇게 출력이 잘 되면 잘 생성 된 것 이다.


이제 파드들을 띄우기 위한 설정을 진행할 예정이다.

우선 pod를 직접 실행시키기 위한 pod.yaml, deployment를 생성하기 위한 deployment.yaml과

서비스를 등록하기 위한 service.yaml을 구성하는 예시를 작성하겠으나 실제로 서버에는 deployment와 서비스만 등록하여
사용할 예정이다

 

pod란? 

pod는 kubernetes에서 애플리케이션의 가장 실행 단위를 말하며 컨테이너의 그룹을 실행하는 단위이다.

하나 이상의 컨테이너를 포함할 수 있으며, 이 컨테이너들은 저장소와 네트워킹을 공유한다.

각 pod는 고유한 IP주소를 가지며 kubernetes 클러스터 내에서 스케줄링되어 실행 된다.

 

Deployment란?

pod의 상태를 선언적으로 관리하는 리소스이다.

pod를 3개 실행하고 싶다면 이를 선언하고 Deployment 사용하여 선언하고 관리하게 할 수 있다.
Deployment는 pod들을 직접 관리하고 제어하는데 사용되기 때문에 kubernetes가 지정된 상태를 유지하도록 할 수 있다.

특정 이미지를 사용하는 pod 복제본 수를 정의하고, 이 상태를 유지하려면 Deployment 리소스를 사용한다.

Deployment는 pod의 생성, 삭제, 업데이트를 관리하여 지정된 상태를 유지한다.

 

이 때문에 나는 Deployment로 pod를 2개 생성해서 관리하게 하는 yaml파일을 작성하고 사용하려 한다.

사실 node를 2개 만들었는데 node 2개에 2개의 pod를 두는 것 즉, node의 개수와 pod의 개수가 일치하거나 더 많게 설정하면

고가용성이ㅣ 중요한 상황에서는 효율성에 문제가 있을 수 있어 권장되지는 않는 방법이다. 

 

하지만 이번에는 서버 비용 문제와 공부 목적에 더 의의를 두고 2개의 노드와 2개의 pod를 생성해보려 한다.

중요한 서버를 구성하기 위한 목적을 두고 있다면 애플리케이션 요구사항과 클러스터 리소스를 균형있게 고려해서 설계 후 적용하여야 한다.

 

 

vi ~/.pod.yaml

 

pod.yaml 작성

apiVersion: v1
kind: Pod
metadata:
  name: debug-pod
spec:
  containers:
  - name: debug-container
    image: busybox
    command: ['sh', '-c', 'env']

간단하게 디버깅을 위해 환경을 출력하는 pod의 예시이다.

이렇게 설정해서 파드가 running 상태일 때 pod의 로그를 확인하여 환경 정보들을 확인할 수 있다.

물론 애플리케이션을 pull받아서 직접 파드로 올리도록 구성할 수 있다.

하지만 위에서 언급했듯이, deployment를 이용해서 pod를 생성할 것이기 때문에 그 작업은 deployment.yaml에서 진행하겠다.

 

pod.yaml을 작성한 후 다음과 같이 적용할 수 있다.

kubectl apply -f pod.yaml

 

그 후 pod가 실행되고 있는지 목록을 조회하여 확인한다.

kubectl get pods

 

status가 completed인 것으로 보아 잘 실행된 것을 확인할 수 있다.

위에서 설명한 것 처럼 환경변수 출력이 잘 되었는지 로그도 확인해보자

kubectl logs debug-pod

debug-pod 이부분은 여러분이 사용한 pod이름을 입력하면 된다.

 

잘 출력되고 있는 것을 확인할 수 있다.

 

이제 여기서 커맨드 입력이 너무 번거로우므로 kubectl 자동완성을 사용해 볼 것이다.

source /usr/share/bash-completion/bash_completion

해당 명령어를 통해 bash-completion을 설치한다.

 

그 다음엔 시스템 전체에 적용되도록 설정하자.

kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null

 

우리는 여기에서 추가로 kubectl에 대한 alias가 존재하므로 더 간결하게 수정하고 적용해보겠다.

echo 'alias k=kubectl --kubeconfig="/root/kubeconfig.yml"' >> ~/.bashrc
echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
exec bash

 

이제 kub까지만 치고 탭키를 눌러보면 커맨드들이 자동 완성 된다.

 

더 편리해진 상태로 이제 service를 등록해보자

 

vi melody-service.yaml

나는 서비스 yaml파일 이름을 이렇게 했지만 자유롭게 수정해도 무방하다.

kind: Service
apiVersion: v1
metadata:
  name: melody-service
spec:
  ports:
  - port: 80
    targetPort: 9090
  selector:
    app: melody
  type: LoadBalancer

여기에서 service name과 원하는 포트를 기입해서 수정할 수 있다.

 

서비스도 적용해보자

kubectl apply -f service.yaml

 

실행 중인 서비스를 확인해보자

 

kubectl get service

 

 

만일 아래와 같이 connection refuse가 뜬다면 아까 적용한 bash-completion 때문이다.

vi ~/.bashrc 커맨드를 입력해 아래와 같이 수정하자

#alias k=kubectl --kubeconfig="/root/kubeconfig.yml" 잘못 기입된 것 아래와 같이 수정필요
alias k='kubectl --kubeconfig="/root/kubeconfig.yml"'

그 다음 적용한 후 kubectl 대신 k로 조회하자

exec bash
k get service

 

앞으로는 kubectl 커맨드를 적용한 alias k로 입력하겠다.

 

적용하지 않은 경우 k 대신 kubectl을 사용하면 된다.

vi ~/melody-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: melody-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: melody
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: melody
    spec:
      containers:
      - name: melody
        image: 레지스트리 public endpoint/melody-market:1.0v
        ports:
        - containerPort: 9090
        env:
        - name: SPRING_DATASOURCE_URL
          value: "jdbc:mysql://1xx.xxx.xxx.xxx:포트/db명?characterEncoding=utf8&useSSL=false"
        - name: SPRING_DATASOURCE_USERNAME
          value: "유저네임"
        - name: SPRING_DATASOURCE_PASSWORD
          value: "비밀번호"
        - name: SPRING_REDIS_HOST
          value: "호스트IP"
        - name: SPRING_REDIS_PORT
          value: "포트"
      imagePullSecrets:
      - name: regcred

 

개인에 따라 다르겠지만 롤링 업데이트 배포전략 적용을 위해 전략 설정을 롤링 업데이트로 기입해주었고 -- 옵션사항,

containers는 Container Registry에 업로드  된 도커 이미지를 pull받아 사용하도록 했다

env도 역시 옵션사항인데 나의 경우 pod내부에 애플리케이션이 실행 될 때 필요한 환경 정보들을 기입해주었다.

 

deployment 도 적용 해보자

-- alias를 적용한 경우 커맨드
k apply -f melody-deploy.yaml

-- alias 적용하지 않은 경우
kubectl apply -f melody-deploy.yaml

 

이제 deployment가 잘 적용 되었는지 확인해보자

-- alias 적용 한 경우
k get pods

-- alias 적용하지 않은 경우
kubectl get pods

 

 

위에 적용했던 pod가 나오지 않는 이유는 지웠다! 필요없기 때문에.. 그리고 환경 변수만 확인하는 pod라 아마 CrashLoopBackOff 
발생했을 것 이다

 

pod 삭제는 다음과 같이 하면 된다

-- alias 적용 한 경우
k delete pods <pod이름>

-- alias 적용하지 않은 경우
kubectl delete pods <pod이름>

 

이제 deployment 또는 pod 내가 겪었던 문제 기준으로 문제 발생 시 해결 방법에 대해 추가 설명 하겠다.

 

문제 발생 내용은 다음과 같은 커맨드를 통해 log를 확인할 수 있다

-- alias 적용한 경우
k logs <pod 또는 deployment 이름>

-- alias 적용하지 않은 경우
kubectl logs <pod 또는 deployment 이름>

 

발생 문제 1.

Status가 imagePull에러가 발생한다

 

해결 방법

1. 이미지를 pull 받아오기 위한 Container Registry에 yaml에 기입한 내용과 동일한 이미지 이름을 기입했는가? 확인해보자

public endpoint 혹은 private endpoint를 올바르게 기입했는가?

 

2. kubectl create secret 생성 시 올바른 정보를 기입한 것이 맞는가?? 내 API KEY와 Secret key와 계정 이메일을 올바르게 기입한게 맞는지 반드시 확인해보자

 

3. Container Registry로 통신이 나가는지 ping 테스트 해보자

ping <public endpoint> 시도 시 잘 수행되는지 체크해보아야한다.

 

4. 서브 계정으로 수행중이라면 서브 계정에 권한을 부여했는가? 체크해보자

 

발생 문제 2.

web server를 구성했는데 ncp에 구성한 데이터 베이스 서버 혹은 다른 서버로 접속이 안된다.

 

해결 방법

1. 접속하고자 하는 서버에 접속이 잘 되는지 확인해보자

curl -v IP:PORT 입력해서 connection이 성공하는지 확인해보자

-> 안되는 경우 해당 서버에서 ACG에 현재 서버 IP와 Port를 인바운드 규칙에 추가해 주어야 한다.

 

2. 1번은 잘 수행되는데 pod 내부에서 안되는 것 같은 경우 deploy.yaml에 접속한 정보들이 정말 올바르게 쓰여있는지 확인하자.

 

3. 2번까지 모두 성공했을 시 pod가 timeout이 발생하며 죽기 전까지 순식간에 파드 내부로 접속해서 curl -v 명령어를 통해 확인해야한다.

커맨드 순서는 아래와 같으며 반드시 Status가 Running 상태일 때 수행해야한다. 죽기전 그 순간을 노려서 접속해야한다.

-- alias 적용한 경우
k exec -it <deploy이름> -c <컨테이너 이름> -- /bin/bash

-- alias 적용하지 않은 경우
kubectl exec -it <deploy이름> -c <컨테이너 이름> -- /bin/bash

 

deployment가 실패할 경우 다시 재 시작하기 때문에 살아날 때 까지 나의 경우 계속 반복해서 순간을 노리기 위해 해당 커맨드를 날렸다.

그 다음 curl -v IP:PORT 명령어를 날려 확인하자 

 

나는 이 부분에서 원인을 파악했고 해결하기 위해 노드들의 IP를 접속하고자하는 서버의 ACG에 인바운드 규칙으로 넣어줬다.

 

노드 IP 확인 방법

-- alias 적용한 경우
k get nodes -o wide

-- alias 적용하지 않은 경우
kubectl get nodes -o wide

 

출력된 노드의 IP 중 External IP와 필요한 port를 넣으면 다음 deployment 시도 시 정상화 될 것이다.

 

 

좀 더 자세한 서버 통신 방법을 확인하고 싶다면 아래의 포스트를 확인하자.

 

[Linux] 서버 간 통신 테스트 방법

# 접속 성공ㅇ Linux 서버에서 개발을 진행 할 때 서버 간 통신이 필요한 경우가 많다. 이 때 내가 통신하고 싶은 서버와 포트로 통신이 가능한지 테스트 하는 방법을 정리 해보았다. - TELNET telent

elephant-dev.tistory.com

 

 

여기 까지 한 후 load blancer의 접속 정보로 접속해보면 web서버인 경우 잘 접속되는 것을 확인할 수 있다.

 

728x90
LIST