local에서 minikube를 이용하여 k8s기반 spring app을 개발하면서, deploy를 위해 spring app에 대한 docker image를 docker hub에 push 하는 것이 마음에 들지 않았다. 모든 것을 local에서 처리하고 싶었기 때문이다. 그래서 docker hub 대신, private registry를 minikube위에 만들고, 해당 resgitry에 있는 image를 동일한 minikube에 deploy 하기로 결심했다.
설치 가이드를 안내하기 전에, 작성자가 사용한 개발환경은 다음과 같다.
다음의 명령어를 입력해서 minikube에 private registry를 활성화하자.(minikube가 실행되고 있어야함)
minikube addons enable registry
Registry addon with docker driver uses port 49955 please use that instead of default port 5000
작성자의 경우에는 사용할 포트번호로 49955가 나왔다. 앞으로 이 포트번호를 이용하여 가이드를 작성할 예정이다.
client가 http를 통해 image를 pull할 수 있도록 설정한다. service cluster ip는 10.0.0.1
에서 사용가능하기 때문에, 이 범주에 있는 ip주소는 http를 사용할 수 있도록 설정한다.(https://minikube.sigs.k8s.io/docs/handbook/registry/#enabling-insecure-registries 참고)
minikube config set insecure-registry "10.0.0.0/24"
curl http://localhost:49955/v2/_catalog
{"repositories":[]}
kubectl get service --namespace kube-system
작성자의 경우 다음의 결과를 얻었다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 33m
registry ClusterIP 10.102.107.53 <none> 80/TCP,443/TCP 30m
registry가 minikube 위에서 활성화 되면, registry addon은 minikube의 가상 머신 위에서 포트번호 80을 expose한다는 것을 확인할 수 있다.
spring app에 사용된 개발환경은 다음과 같다.
참고로 테스트에 사용한 spring app은 https://github.com/Dev-Hi/minikube-docker-registry-test 에서 확인할 수 있으며, 아주 간단한 spring app이다. 참고로 작성자의 경우 spring app의 프로젝트 경로는 wsl2상에 존재한다.
jib를 사용하면 spring app build, image build, image를 registry에 push하는 것을 정말 쉽게 할 수 있다. build.gradle
에 다음의 내용을 추가하자.
plugins {
id 'com.google.cloud.tools.jib' version '3.3.1'
}
jib {
to {
image = "localhost:49955/example"
}
// local docker registry를 사용하기 때문에, http 허용
allowInsecureRegistries true
}
registry addon에서 제공한 포트번호를 사용한다는 점 잊지말자. 작성이 완료됐다면, 프로젝트 루트 경로에서 다음의 명령어를 입력한다.
./gradlew jib
위의 명령어를 실행이 완료됐다면, spring app image가 정상적으로 registry에 올라갔는지 확인하기 위해 이전에 사용했던 curl 명령어를 다시 사용하자.
curl http://localhost:49955/v2/_catalog
다음의 결과가 나와야 정상이다.
{"repositories":["example"]}
이로써 spring app을 private registry에 올리는 것까지 완료했다. 이제 registry에 있는 spring app을 minikube에 deploy하자
편의성을 위해 하나의 yaml파일에서 spring app에대한 deployment, service를 작성했다. 여기서 image
에 yourClusterIP
가 있는데, 이 부분을 지우고 본인의 registry cluster ip를 작성하면 된다. /example
은 삭제하면 안된다. 참고로 이 yml
파일은 프로젝트의 deployment/example-app-deployment.yaml
에서 확인할 수 있다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: yourClusterIP/example
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
type: NodePort
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
nodePort: 31212
registry cluster ip를 확인하는 방법은 이전에 registry cluster가 존재한지 확인하기 위해 사용했던 명령어와 동일하다.
kubectl get services --namespace kube-system
작성자의 경우에는 10.102.107.53
를 사용할 예정이다. 본인의 cluster ip에 맞게 설정했으면, kubectl명령어를 확인하여 deploy를 하자.
kubectl apply -f example-app-deployment.yaml
deploy가 정상적으로 작성됐는지 확인하기 위해 브라우저를 열고 url을 입력하자. 우리는 minikube에 있는 spring app에 대한 service를 통해 접근할 것이기 때문에, 아래의 명령어를 입력해야한다.
minikube service myapp-svc
그러면 2개의 URL이 출력된다는 것을 확인 할 수 있는데, 여기서 127.0.0.1
(localhost)를 포함하는 URL를 복사하고 URL/ping를 브라우저에 입력한다.
http://127.0.0.1:43987/ping
그러면 화면에는 pong
이라는 글자가 나오는 것을 확인할 수 있다. 이거와는 별개로 k9s를 이용하면 deployment와 service에 대한 자세한 내용을 쉽게 확인할 수 있다. 이 부분의 내용은 생략한다.
우리의 PC의 전원을 종료할 수 있다. 재부팅 이후의 minikube의 registry는 어떻게 사용할까??
방법은 간단한데 docker desktop을 실행하고, minikube start
명령어를 입력하면 된다.
사용된 코드는 https://github.com/Dev-Hi/minikube-docker-registry-test 에서 확인할 수 있다.
안녕하세요~ 좋은 글 감사합니다. 비슷한 케이스에서 테스트를 해보고 있는데요, 저 같은 경우는 minikube가 내려갔다가 다시 뜨면 private registry가 빈 것으로 보이는데요...! 혹시 이 부분은 테스트하시면서 발생하신 적은 없는지 궁금합니다.
또, 저같은 경우는 위와 같이 해도 외부 docker hub에서 이미지를 땡겨와지는 것으로 보여서.. 혹시 비슷한 상황 발생하신적은 없는지 궁금합니다~ 감사합니다.