배포 Step1

컨테이너 배포에 대한 첫번째 단계로, 환경별 배포, Helm 적용, ReadinessProbe/LivenessProbe에 대한 기능 확인을 실습합니다.



파이프라인 전체 구성 및 흐름


Step1 Overview for Helm Deploy Step1

1. 개발 소스 생성

Develop Source for Helm Deploy Step1

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)

Deploy Files for Helm Deploy Step1

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

Push Github for Helm Deploy Step1

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 사용할 수 있도록 설정

CICD Setting for Helm Deploy Step1

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. 배포 프로젝트 생성

Jenkins Project for Helm Deploy Step1

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  # 브라우저 접속