배포 Step1
컨테이너 배포에 대한 첫번째 단계로, 환경별 배포, Helm 적용, ReadinessProbe/LivenessProbe에 대한 기능 확인을 실습합니다.
파이프라인 전체 구성 및 흐름
1. 개발 소스 생성
1-1) 새 프로젝트 생성
[새 프로젝트 생성]
File > NEW > Spring Starter Project
[New Spring Starter Project]
Name: database
Packaging: War
Type: Gradle Project
[New Spring Starter Project Dependencies]
Spring Boot Version: 2.6.x
Available: Spring Boot Actuator, Spring Boot DevTools, Spring Configuration Processor
1-2) application 파일 Convert 및 내용 추가
[application Convert]
application.properties > [마우스 우클릭] > [Convert .properties to .yaml]
[환경별(dev, qa, prod) 파일 생성]
application-dev.yaml
application-qa.yaml
application-prod.yaml
application-dev.yaml 내용 추가 (qa, prod 반복 적용)
# 서버 정보 (localhost:8080/app/database)
server:
servlet:
context-path: /app
port: 8080
# Readinessprobe, Livenessprobe 용
# /app/actuator/health/liveness, /app/actuator/health/readiness
management:
endpoint:
health:
probes:
enabled: true
health:
livenessstate:
enabled: true
readinessstate:
enabled: true
# Database 접속정보
database:
ip: 10.10.10.1
port: 1234
username: dev
password: dev
1-3) 자바 소스 파일 추가 (Database Domain, Controller)
[com.example.demo] 패키지에서 마우스 우클릭 > [New] > [Class] > Name: Database
[com.example.demo] 패키지에서 마우스 우클릭 > [New] > [Class] > Name: DatabaseController
Database.java
// 어노테이션 추가
@Configuration
@ConfigurationProperties(prefix = "database")
// 변수 추가
private String ip;
private String port;
private String username;
private String password;
// 마우스 우클릭 > [Source] > Generate Getters and Setters > [Select All] > [Generate]
// 마우스 우클릭 > [Source] > Generate toString()... > [Generate]
// Ctrl + Shift + o 로 Library Import
DatabaseController.java
@RestController
public class DatabaseController {
@Autowired
private Database database;
@GetMapping(value="/database")
@ResponseBody
public ResponseEntity<Object> database() {
return ResponseEntity.ok(database.toString());
}
}
// Ctrl + Shift + o 로 Library Import
1-4) Application Arguments 설정
[Boot Dashboard] > database [devtools] > 마우스 우클릭 > [Open Config] > Arguments
> VM arguments : -Dspring.profiles.active="dev" > [Apply]
1-5) Application 호출
http://localhost:8080/app/database
# livenessProbe, readinessProbe
http://localhost:8080/app/actuator/health/liveness
http://localhost:8080/app/actuator/health/readiness
2. 배포 파일 생성 (Docker, Helm, Kubectl)
2-1) Dockerfile 생성
# 프로젝트에 폴더 생성
[root] > deploy
[root] > deploy > docker
# 프로젝트에 dockerfile 생성
[root] > deploy > docker > [New] > [File] > name: Dockerfile
# Dockerfile 내용 추가
FROM bitnami/tomcat:9.0.41-debian-10-r0
COPY app.war /opt/bitnami/tomcat/webapps_default
# https://artifacthub.io/packages/helm/bitnami/tomcat/7.1.2
# https://hub.docker.com/ (bitnami/tomcat) (.WAR)
# webapps이 아닌 webapps_default에에 대한 레퍼런스
# https://docs.bitnami.com/tutorials/deploy-java-application-kubernetes-helm/
2-2) Tomcat Helm 패키지 다운
# 다운로드 및 압축 풀기
C:\helm-ide> helm 폴더 생성
C:\helm-ide\helm> curl -O https://kubetm.github.io/helm/tomcat-7.1.2.tgz
C:\helm-ide\helm> 압축해제
# 프로젝트에 폴더 생성
[root] > deploy > helm
[root] > deploy > helm > tomcat 폴더 복사
2-3) 환경별(dev, qa, prod) values.yaml 파일 생성
values-dev.yaml
image:
registry: docker.io
repository: kubetm/database-service # kubetm -> 개인 <docker id>로 변경
tag: latest
# docker build -t kubetm/database-service:latest
tomcatAllowRemoteManagement: 1
persistence:
enabled: false
service:
type: NodePort
nodePort: "30081" # dev(30081), qa(30082), prod(30083)
extraEnvVars:
- name: JAVA_OPTS
value: '-Dspring.profiles.active=dev'
2-4) 환경별(dev, qa, prod) Namespace 배포 파일 생성
# 프로젝트에 폴더 생성
[root] > deploy > kubectl
ns-dev.yaml 파일 생성
kind: Namespace
apiVersion: v1
metadata:
name: dev
3. Source Push
3-1) Github에 App 올리기
- 사전에 Github에 가입되어 있어야 함
[Github에서 Repository 만들기]
Repositories > New > database-service
[프로젝트 Git 설정]
프로젝트 root 폴더 > team > Share Project.. > Repository [Create..] > [Browse..] > C:\helm-ide\git-db 폴더 생성/선택
[Eclipse 소스 Push하기]
프로젝트 root 폴더 > team > commit > 파일 Staged Changes 후 Commit
Github Repository(database-service)에서 [Code]클릭 후 Clone HTTPS 주소 복사 클릭 > Eclipse에서 [Push HEAD..] 클릭 > Preview > Preview
[Github에서 소스 확인]
4. GeustOS 세팅 수정
Jenkins에서 kubectl, helm 사용할 수 있도록 설정
4-1) jeknins에서 Helm, Kubectl을 사용할 수 있도록 설정
# Jeknins로 사용자 변경
[root@cicd-server ~]# su - jenkins -s /bin/bash
# kubectl, helm 명령어 사용 확인
-bash-4.2$ kubectl get nodes
-bash-4.2$ helm list
[root@cicd-server ~]# mkdir /var/lib/jenkins/.kube/
[root@cicd-server ~]# cp /root/.kube/config /var/lib/jenkins/.kube/
[root@cicd-server ~]# chown -R jenkins:jenkins /var/lib/jenkins/.kube
# Jeknins로 사용자 변경
[root@cicd-server ~]# su - jenkins -s /bin/bash
# kubectl, helm 명령어 사용 확인
-bash-4.2$ kubectl get nodes
-bash-4.2$ helm list
4-2) jeknins가 Docker를 사용할 수 있도록 설정
# Jeknins로 사용자 변경
[root@cicd-server ~]# su - jenkins -s /bin/bash
-bash-4.2$ docker ps
# Docker 사용 권한 변경
[root@cicd-server ~]# chmod 666 /var/run/docker.sock
[root@cicd-server ~]# usermod -aG docker jenkins
# Jeknins로 사용자 변경
[root@cicd-server ~]# su - jenkins -s /bin/bash
-bash-4.2$ docker ps
# Jeknins에서 docker login
-bash-4.2$ docker login
-bash-4.2$ 개인 dockerhub id/pw 입력
# Docker 로그인 정보 저장
-bash-4.2$ cat ~/.docker/config.json
5. 배포 프로젝트 생성
5-1) jeknins 접속
접속url: http://192.168.56.20:8080
id/pw: admin/admin
5-2) jeknins에서 새 Project 추가
# Job 생성
Dashboard > 새로운 Item > Enter an item name > [database-dev] > Freestyle project > ok
[General]
- Github project 체크
Project url : https://github.com/kubetm/database-service/
# kubetm -> 개인 <docker id>로 변경
[소스 코드 관리]
- Git 체크
Repositories > Repository URL > https://github.com/kubetm/database-service.git
Credentials > kubetm/***** 선택
# kubetm -> 개인 <docker id>로 변경
[Build]
- [Add build step] > [Invoke Gradle script] 선택
Invoke Gradle > Gradle Version : gradle-7.3
Tasks : clean build
[Advanced..]
Root Build script : ./database
- [Add build step] > [Execute shell] 선택
Command
mv ./database/build/libs/database-0.0.1-SNAPSHOT.war ./database/deploy/docker/app.war
chmod 777 ./database/deploy/docker/app.war
docker build -t kubetm/database-service:latest ./database/deploy/docker
docker push kubetm/database-service:latest
# kubetm -> 개인 <docker id>로 변경
/usr/local/bin/kubectl apply -f ./database/deploy/kubectl/ns-dev.yaml
/usr/local/bin/helm upgrade myapp-dev ./database/deploy/helm/tomcat --install -f ./database/deploy/helm/values-dev.yaml -n dev
[저장]
[Build Now]
5-3) Pod 접속 테스트
dev
-bash-4.2$ kubectl get ns # 콘솔 Namespace 확인
-bash-4.2$ kubectl get -n dev pods # Pod 확인
http://192.168.56.30:30081/app/database # 브라우저 접속
http://192.168.56.30:30081/app/actuator/health/liveness
# Pod Yaml에서 env 확인
kubectl get -n dev pods -o yaml
# Pod 접속
kubectl exec -n dev myapp-dev-tomcat-<random>-<random> -it -- /bin/sh
# Pod 내 env 확인
env
# 톰켓 기동로그
ps -ef | grep java
5-4) QA 및 운영 Project 추가 (이후 Prod 반복)
Dashboard > 새로운 Item [클릭]
Enter an item name > [database-qa]
Copy form > [database-dev]
[OK]
- [Build] > [Execute shell] 수정
Command
/usr/local/bin/kubectl apply -f ./database/deploy/kubectl/ns-qa.yaml
/usr/local/bin/helm upgrade myapp-qa ./database/deploy/helm/tomcat --install -f ./database/deploy/helm/tomcat/values-qa.yaml -n qa
# QA에서 별도로 War 빌드 및 Docker Push를 안할 경우.
- [Build] > [Invoke Gradle script] 삭제
qa
-bash-4.2$ kubectl get ns # 콘솔 Namespace 확인
-bash-4.2$ kubectl get -n qa pods # Pod 확인
http://192.168.56.30:30082/app/database # 브라우저 접속
prod
-bash-4.2$ kubectl get ns # 콘솔 Namespace 확인
-bash-4.2$ kubectl get -n prod pods # Pod 확인
http://192.168.56.30:30083/app/database # 브라우저 접속