[이렇게 사용하세요!] ncloud 컨테이너 레지스트리와 쿠버네티스 연동에 필요한 명령어 (secret 생성 방법)

NAVER CLOUD PLATFORM
NAVER CLOUD PLATFORM
15 min readAug 24, 2021

네이버클라우드 개발자가 직접 알려드리는 클라우드 활용법 [이렇게 사용하세요] 시리즈.​

오늘은 네이버 클라우드 플랫폼의 Container Registry(컨테이너 레지스트리)와 Kubernetes(쿠버네티스) 연동에 필요한 명령어를 알려드리겠습니다.

네이버 클라우드 플랫폼의 컨테이너 레지스트리*와 쿠버네티스 서비스*를 연동하기 위해서는 쿠버네티스 서비스에서 secret을 생성하여 사용해야 합니다.

* 컨테이너 레지스트리(Container Registry): 프라이빗 도커 레지스트리(Private Docker Registry)에서 도커 컨테이너(Docker Container) 이미지를 손쉽게 저장하고, 관리 및 배포할 수 있도록 지원하는 서비스입니다.​

* 쿠버네티스 서비스(Kubernetes Service): 빠르고 간편하게 Kubernetes 컨테이너를 배포하고 관리할 수 있는 관리형 서비스입니다. Kubernetes 클러스터 운영을 효율적으로 관리하고, 응용 프로그램에서 사용하는 인프라 규모를 동적으로 제어할 수 있습니다. 뿐만 아니라, 관리 통계 및 모니터링으로 관리되는 Kubernetes 환경의 운영 상황을 파악할 수 있습니다.

​​

🌮애피타이저 읽기 “쿠버네티스 기반으로 운영되는 컨테이너 레지스트리”

ncloud 컨테이너 레지스트리에서 Public Endpoint 와 Private Endpoint를 제공하고 있습니다. 차이점을 살펴보면,

▶ 퍼블릭 엔드포인트(Public Endpoint)

VPC 환경의 가상 서버 인스턴스(Virtual Machine, VM) 내에서 접근하기 위해서는 외부향 인터넷 구성이 요구됩니다. NAT Gateway와 Public Subnet 구성인 경우 Public IP와 같은 리소스가 요구되며, 추가 요금이 부과될 수 있습니다.​

* 퍼블릭 엔드포인트: <registry-name>.<region-code>.ncr.ntruss.com

▶ 프라이빗 엔드포인트(Private Endpoint)

네이버 클라우드 플랫폼의 네트워크 내에서만 사용할 수 있는 컨테이너 레지스트리 엔드포인트입니다. 이를 사용하는 경우 모든 네트워크 트래픽은 네이버 클라우드 플랫폼을 통해서만 이동하므로 보안을 향상시킬 수 있습니다. 프라이빗 엔드포인트(Private Endpoint)를 사용하는 경우, Public IP와 같은 리소스 없이 VPC 내에서 컨테이너 레지스트리를 이용할 수 있습니다.

​* 프라이빗 엔드포인트: <random-id>.kr.private-ncr.ntruss.com

컨테이너 레지스터리의 엔드포인트 (ncloud 콘솔 화면)
  1. 아래 예제는 두 가지 엔드포인트 중, 퍼블릭 엔드포인트를 사용하는 경우입니다.

ncloud의 쿠버네티스 서비스를 이용하여 클러스터 생성 후(가이드 보기), ‘클러스터 상세 보기(가이드 보기)’ 에서 ‘설정파일 > 다운로드’ 버튼을 클릭하면 kubeconfig.yaml ​파일을 PC에 저장할 수 있습니다.

쿠버네티스 서비스에서의 웹 콘솔 UI

2. 이후 리눅스 머신에서 아래와 같이 config 파일을 복사합니다.​

kubectl이 기본 참고하는 위치인 <HOME_DIR>.kube/config 로 복사를 진행합니다. 이후 config는 자동으로 <HOME_DIR>.kube/config 를 참조합니다.

# ls -al ./k8s/
total 12
drwxr-xr-x 2 root root 29 Jul 5 14:48 .
dr-xr-x---. 40 root root 4096 Jul 5 14:50 ..
-rw-r--r-- 1 root root 5542 Jul 5 14:48 kubeconfig.yaml
# mkdir ~/.kube
# cp -rf ~/k8s/kubeconfig.yaml .kube/config

3. 만약 secret을 생성하지 않고 컨테이너 레지스터리와 연결하는 경우 아래 에러가 발생합니다.

테스트를 위해 kubectl run 명령을 활용하여, 퍼블릭 엔드포인트를 통해 컨테이너 이미지를 불러옵니다.

# kubectl run mytest --image=rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest
pod/mytest created

4. pod의 상태를 확인하며, ImagePullBackOff 상태인 것을 확인했습니다.​

kubectl describe pod 명령어를 통해 상세한 이슈가 무엇인지 확인합니다. ​아래와 같이 no basic auth credentials 이라는 에러 메시지가 확인이 되었습니다.

Failed to pull image “rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest”: rpc error: code = Unknown desc = Error response from daemon: Get https://rk84-continer-210607.kr.ncr.ntruss.com/v2/rk84rc1/manifests/latest: no basic auth credentials

# kubectl get pods
NAME READY STATUS RESTARTS AGE
mytest 0/1 ImagePullBackOff 0 13s
# kubectl describe pod mytest
Name: mytest
Namespace: default
Priority: 0
Node: nks-pool-1061-w-fvs/192.168.21.10
Start Time: Mon, 05 Jul 2021 19:50:55 +0900
Labels: run=mytest
Annotations: <none>
Status: Pending
IP: 198.18.0.47
IPs:
IP: 198.18.0.47
Containers:
mytest:
Container ID:
Image: rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest
Image ID:
Port: <none>
Host Port: <none>
State: Waiting
Reason: ImagePullBackOff
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-twffm (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-twffm:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-twffm
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 48s default-scheduler Successfully assigned default/mytest to nks-pool-1061-w-fvs
Normal SandboxChanged 46s kubelet Pod sandbox changed, it will be killed and re-created.
Normal BackOff 19s (x4 over 46s) kubelet Back-off pulling image "rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest"
Warning Failed 19s (x4 over 46s) kubelet Error: ImagePullBackOff
Normal Pulling 5s (x3 over 47s) kubelet Pulling image "rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest"
Warning Failed 4s (x3 over 47s) kubelet Failed to pull image "rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest": rpc error: code = Unknown desc = Error response from daemon: Get https://rk84-continer-210607.kr.ncr.ntruss.com/v2/rk84rc1/manifests/latest: no basic auth credentials
Warning Failed 4s (x3 over 47s) kubelet Error: ErrImagePull

5. kubectl 명령어를 이용하여 regcred라는 이름의 secret을 생성합니다.​

secret 생성에 필요한 Access Key ID, Secret Key는 아래 그림과 같이 확인합니다. 만약 키가 없다면, 신규 API 인증키를 생성합니다.

네이버 클라우드 플랫폼 콘솔 > 계정관리 > 인증키 관리

* docker-username : Access Key ID

* docker-password : Secret Key

앞전에 언급한 endpint에 관련된 정보입니다.

* docker-server : rk84-continer-210607.kr.ncr.ntruss.com

email 정보를 기입합니다.

* docker-email : casong99@example.com

kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>

6. 생성한 secret을 아래와 같이 확인합니다.

kubectl get secrets

만약 잘못 생성한 경우 아래와 같이 생성한 secret을 삭제합니다.

kubectl delete secret regcred

7. 아래와 같이 test.yaml 파일을 만듭니다.

apiVersion: v1
kind: Pod
metadata:
name: mytest
spec:
containers:
- name: rk84-continer-210607
image: rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest
imagePullSecrets:
- name: regcred

8. kubectl 명령어 활용하여 만든 파일을 실행합니다.

kubectl apply -f test.yaml

9. 해당 컨테이너가 정상으로 올라오는 것을 확인할 수 있습니다.

# kubectl describe pod mytest
Name: mytest
Namespace: default
Priority: 0
Node: nks-pool-1061-w-fvs/192.168.21.10
Start Time: Mon, 05 Jul 2021 20:38:44 +0900
Labels: <none>
Annotations: <none>
Status: Running
IP: 198.18.0.224
IPs:
IP: 198.18.0.224
Containers:
rk84-continer-210607:
Container ID: docker://5a6cd3ae7e72827e7436ed1da323dc7e76066d3acf745a3b6ed5def9b8e4900b
Image: rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest
Image ID: docker-pullable://yhgdmtjp.kr.private-ncr.ntruss.com/rk84rc1@sha256:6c887065808c90893383b84d4fd1ebe9f8c1ed66549de373fc4d787c58bb6619
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 05 Jul 2021 20:39:07 +0900
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-twffm (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-twffm:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-twffm
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 78s default-scheduler Successfully assigned default/mytest to nks-pool-1061-w-fvs
Normal Pulling 78s kubelet Pulling image " rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest"
Normal Pulled 58s kubelet Successfully pulled image " rk84-continer-210607.kr.ncr.ntruss.com/rk84rc1:latest"
Normal Created 56s kubelet Created container rk84-continer-210607
Normal Started 56s kubelet Started container rk84-continer-210607
# kubectl get pods
NAME READY STATUS RESTARTS AGE
mytest 1/1 Running 0 83s

예제 실행 중 어려움이 있으시면 댓글로 남겨주시거나, 네이버 클라우드 플랫폼 페이스북 유저그룹에 남겨주시면 빠르게 도와드리겠습니다.​

--

--

NAVER CLOUD PLATFORM
NAVER CLOUD PLATFORM

We provide cloud-based information technology services for industry leaders from startups to enterprises.