지난 글에서는 "도커를 활용한 3-Tier 컨테이너 환경 구성"을 해보았다.
https://syhwang.tistory.com/54
이번 글에서는 쿠버네티스를 활용한 3-Tier 컨테이너 환경 구성을 해보고자 한다. 구성은 도커와 동일하게 아래와 같이 간다.
- WEB = NginX
- WAS = Tomcat
- DB = MySQL
이번에는 구성 시에 1-Container에 WEB/WAS/DB Pod를 각각 띄울 예정이다.
동일한 컨테이너에서 기동하기 때문에 서로에 대한 IP는 변하지 않을 것이고 IP Address는 localhost로 설정해주어야 한다.
그렇기 때문에!!
- WEB-WAS 사이의 연동 설정에서 IP를 localhost로 변경
- WAS-DB 사이의 연동 설정(어플리케이션 부분)에서 DB IP를 localhost로 변경
해주어야한다.. 그렇다면 이미지 부터 다시 말아보자.
1. WEB 구성
1-1. NginX의 WAS 연동 설정 파일에서 IP Address를 localhost로 변경 후 다시 이미지 생성
> $ vi /root/nginx-for-petclinic/nginx/conf
17 http { 18 upstream was-list { 19 #server tomcat-petclinic:8080; 20 server localhost:8080; 21 } 22 23 include mime.types; 24 default_type application/octet-stream; |
1-2. Dockerfile을 이용하여 이미지 생성
root@master:~/nginx-for-petclinic# pwd /root/nginx-for-petclinic root@master:~/nginx-for-petclinic# docker build -t nginx-petclinic:2.0 . # 이미지 생성 후, 확인 root@master:~/nginx-for-petclinic# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx-petclinic 2.0 1f34b3ccac6d 5 seconds ago 133MB |
1-3. 이미지를 Dockerhub에 저장
> 내가 생성한 이미지를 이따 yaml파일에서 로드할 수 있도록..
root@master:~# docker tag nginx-petclinic:2.0 ghkd5216/nginx-petclinic:2.0 root@master:~# docker push ghkd5216/nginx-petclinic:2.0 The push refers to repository [docker.io/ghkd5216/nginx-petclinic] 52efdeec58ec: Pushed 201e7ba1790a: Pushed 9959a332cf6e: Layer already exists f7e00b807643: Layer already exists f8e880dfc4ef: Layer already exists 788e89a4d186: Layer already exists 43f4e41372e4: Layer already exists e81bff2725db: Layer already exists 2.0: digest: sha256:15cf195c6e6575d744fa0eb07b429d0db3d99f61 |
2. WAS 구성
2-1. WAS에서는 AP쪽에 DB 설정이 있기 때문에 소스 빌드 및 해당 소스가 디플로이된 이미지를 다시 생성해야 한다.
> $vi /root/spring-framework-for-petclinic/pom.xml
> 515번 라인과 같이 localhost로 변경해주면 된다.
509 <id>MySQL</id> 510 <properties> 511 <db.script>mysql</db.script> 512 <jpa.database>MYSQL</jpa.database> 513 <jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName> 514 <!--<jdbc.url>jdbc:mysql://mysql-petclinic:3306/petclinic?useUnicode=true</jdbc.url>--> 515 <jdbc.url>jdbc:mysql://localhost:3306/petclinic?useUnicode=true</jdbc.url> 516 <jdbc.username>root</jdbc.username> 517 <jdbc.password>petclinic</jdbc.password> 518 </properties> |
2-2. 소스 빌드를 위한 자바 변경
> 자바 버전이 1.8이 되도록 수정
root@master:~/spring-framework-for-petclinic# sudo update-java-alternatives --jre-headless --jre --set java-1.8.0-openjdk-amd64 root@master:~/spring-framework-for-petclinic# java -version openjdk version "1.8.0_292" OpenJDK Runtime Environment (build 1.8.0_292-8u292-b10-0ubuntu1~20.04-b10) OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode) |
2-3. 소스 빌드
> 소스를 빌드하고 나면, 현 디렉토리에 target 안에 petclinic.war라는 소스 파일이 빌드되어 있을 것이다.
root@master:~/spring-framework-for-petclinic# mvn clean package -Dmaven.test.skip=true -P MySQL ...(중략) [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 13.144 s [INFO] Finished at: 2021-11-16T18:04:01+09:00 [INFO] ------------------------------------------------------------------------ |
2-4. WAS 이미지 생성
> 이제 만든 소스를 활용하여 tomcat 이미지를 만들어보도록 하자.
우선 이미지 생성을 위해 Dockerfile을 생성하고 위에서 만들었던 petclinic.war 파일을 Dockerfile 디렉토리에 위치시킨다.
root@master:/home/dockerfile/petclinic# pwd /home/dockerfile/petclinic root@master:/home/dockerfile/petclinic# ls -arlt total 40644 drwxr-xr-x 5 root root 4096 11월 7 14:06 .. -rw-r--r-- 1 root root 41605349 11월 7 14:06 petclinic.war -rw-r--r-- 1 root root 64 11월 7 14:06 Dockerfile drwxr-xr-x 2 root root 4096 11월 7 14:06 . ================================================== 하기는 Dockerfile 내용이다. ================================================== root@master:/home/dockerfile/petclinic# cat Dockerfile From tomcat:8-jre8 ADD petclinic.war /usr/local/tomcat/webapps/ |
위와 같이 준비가 되었다면 이제 해당 위치에서 이미지 빌드를 하면 된다.
커맨드는 아래와 같다.
root@master:/home/dockerfile/petclinic# docker build -t tomcat-petclinic:2.0 . Sending build context to Docker daemon 41.61MB Step 1/2 : From tomcat:8-jre8 ---> cff25871f024 Step 2/2 : ADD petclinic.war /usr/local/tomcat/webapps/ ---> 1c6d007012d5 Successfully built 1c6d007012d5 Successfully tagged tomcat-petclinic:2.0 |
2-5. 이미지를 Dockerhub에 저장
> 내가 생성한 이미지를 이따 yaml파일에서 로드할 수 있도록..
root@master:~# docker tag tomcat-petclinic:2.0 ghkd5216/tomcat-petclinic:2.0 root@master:~# docker push ghkd5216/tomcat-petclinic:2.0 The push refers to repository [docker.io/ghkd5216/tomcat-petclinic] 3fe16f1fe077: Pushed 7a1149e8d0d8: Layer already exists f3d15ade5c54: Layer already exists 80ac7083a323: Layer already exists 01de28a83f3f: Layer already exists 74a293db1084: Layer already exists 68c1e7509c65: Layer already exists 6ccd0e6bdf7a: Layer already exists 9f9f651e9303: Layer already exists 0b3c02b5d746: Layer already exists 62a747bf1719: Layer already exists 2.0: digest: sha256:7ee8909691df00b211aa42f1605062019422b0d93d52053d4ad01034390e04a7 size: 2631 |
3. YAML 파일 생성
이제 이미지도 준비되었고, yaml 파일만 생성하여 기동해보면 된다.
도커와는 다르게 쿠버네티스의 경우에는 쿠버네티스 클러스터 내에서 동작하기 때문에 생성된 컨테이너의 IP 또한 클러스터 내의 CNI 네트워크 대역으로 할당된다.
그렇기 때문에 외부에서 해당 컨테이너에 접근하여 서비스를 호출하려면 Service를 통해 가능하다. AWS나 GCP같은 Public Cloud의 경우에는 Service에서 LoadBalnancer를 제공하여 외부로 노출할 IP를 할당 받지만, 우리가 테스트하는 방식과 같이 Baremetal(On-Premise) 환경에서는 LoadBalancer 기능이 없다. 그래서 LoadBalancer타입을 지원하게끔 하기 위해 MetalLB라는 놈을 사용해주어야 한다.
먼저 metalb을 설치해보면 아래와 같다.
root@master:~/yaml# kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml ================================= metallb.yaml 파일을 이용하여 파드와 기타 등등의 서비스를 실행한다. 이후, metallb-system 네임스페이스에 있는 리소스들을 조회해본다. ================================= root@master:~/yaml# kc get all -n metallb-system NAME READY STATUS RESTARTS AGE pod/controller-675d6c9976-d5k57 1/1 Running 0 9s pod/speaker-h4l8n 1/1 Running 0 9s pod/speaker-rm54l 1/1 Running 0 9s NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/speaker 2 2 2 2 2 beta.kubernetes.io/os=linux 9s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/controller 1/1 1 1 9s NAME DESIRED CURRENT READY AGE replicaset.apps/controller-675d6c9976 1 1 1 9s |
이제 3-Tier환경의 컨테이너를 생성할 차례다.
yaml 파일의 경우 아래와 같다.
모든 항목들을 세세히 설명할 수는 없고 하나씩 찾아보면 기본적인 설정(포트/환경변수)만 되어있음을 볼 수 있다.
이 글에서는 가볍게 구성해보는 것이기 때문에 다음 글에서 좀 더 yaml 문법이나 파라미터 값을 공부해보아야 겠다.
apiVersion: apps/v1 kind: Deployment metadata: name: petclinic-deployment namespace: default labels: app: petclinic-deployment spec: replicas: 1 selector: matchLabels: app: petclinic-app template: metadata: labels: app: petclinic-app spec: containers: - image: mysql:5.7.8 imagePullPolicy: Always name: mysql-petclinic ports: - containerPort: 3306 protocol: TCP env: - name: MYSQL_ROOT_PASSWORD value: petclinic - name: MYSQL_DATABASE value: petclinic - image: docker.io/ghkd5216/nginx-petclinic:2.0 imagePullPolicy: Always name: nginx-petclinic ports: - containerPort: 80 protocol: TCP - image: docker.io/ghkd5216/tomcat-petclinic:2.0 imagePullPolicy: Always name: tomcat-petclinic env: - name: JAVA_OPTS value: "-Xms1024m -Xmx1024m" ports: - containerPort: 8080 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: petclinic-svc spec: type: LoadBalancer selector: app: petclinic-app ports: - port: 80 protocol: TCP targetPort: 80 --- apiVersion: v1 kind: ConfigMap metadata: namespace: metallb-system name: metallb-config data: config: | address-pools: - name: default protocol: layer2 addresses: - 192.168.56.240-192.168.56.250 |
> 제일 하단에 metallb 관련 설정을 보면 addresses 범위 안에서 외부로 노출할 ExternalIP 대역을 설정할 수 있다.
이제 만든 yaml 파일을 실행하여 보자!!
4. Kubernetes를 통한 컨테이너 배포
root@master:~/yaml# kc apply -f petclinic-app.yaml deployment.apps/petclinic-deployment created service/petclinic-svc created configmap/config created root@master:~/yaml# kc get all NAME READY STATUS RESTARTS AGE pod/petclinic-deployment-86dc87794d-j69mm 3/3 Running 0 24s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d service/petclinic-svc LoadBalancer 10.109.251.153 192.168.56.240 80:30560/TCP 24s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/petclinic-deployment 1/1 1 1 24s NAME DESIRED CURRENT READY AGE replicaset.apps/petclinic-deployment-86dc87794d 1 1 1 24s |
> 위와 같이 LoadBalancer 타입의 Service가 생성되어 External-IP를 할당하여 외부로 노출하는 것을 볼 수 있다.
이제 모든 준비가 끝났다.
실제로 외부의 웹 브라우저에서 클라이언트 입장으로 서비스를 호출해보자. 호출 url은 EXTERNAL_IP:[LB PORT]/petclinic 이다.
나의 경우에는 http://192.168.56.240:80/petclinic/으로 호출하면 된다.
5. 서비스 호출
> 외부 노출 IP로 정상적으로 접근 가능하다. 몇 가지 업무 테스트를 해보면,
정상적으로 데이터가 DB에 저장되는 것을 볼 수 있다.
이상.
K8S를 활용한 3-Tier 컨테이너 환경 구성 실습을 마무리 하겠다.