2021년 08월 31일 TIL
오늘은 이전 O-GYM 프로젝트의 배포에 대해 팀원과 함께 문서화 작업을 했다. 첫 배포였기에 굉장히 많은 시행착오를 겪은 과정이었지만, 그럼에도 즐거운 과정이었다고 생각한다.
✔ 배포 문서 ✔
Date : 2021-08-31
목차
Setting
-
microk8s 공식문서
-
Docker, cri-o Docker 공식문서 Cri-o 공식문서
-
Jenkins Jenkins 공식문서
-
ArgoCD ArgoCD 공식문서
-
prometheus, Grafana Prometheus 공식문서 Grafana 공식문서
Issue&Prerequisites
- 데이터베이스 덤프 파일
- data.sql, schema.sql을 통해 실행하면 자동으로 생성됩니다!
-
Jenkins가 GitLab에서 코드를 가져오기 위한 설정
-
Jenkins, Docker 설치가 필수
-
-
Jenkins Pipeline 내 Docker Hub에 접속해서 만들어진 이미지를 Push
- Docker Hub에 가입 필수! Docker Hub
-
이미지를 통해서 만들어진 리소스 yaml 파일들을 Github에 push
-
원래는 public repo 였으나, AWS S3 보안 키 issue
Email 과 같은 문제가 발생
-
Private Repo에서 git 코드에 ACCESS 할 수 있는 ssh 설정 필요
-
-
kubectl을 이용해 이미지에서 리소스 파일 추출
-
kubectl 명령어 사용이 필수
- microk8s를 snap 명령어로 install 후
microk8s kubectl처럼 사용이 가능
- microk8s를 snap 명령어로 install 후
## 예시 microk8s kubectl get pods -
배포 준비 과정
-
GitLab에서 Jenkins로 코드를 보내주기 위한 설정
-
GitLab WebHook 생성
-
Jenkins 환경설정에서 GitLab 정보 등록
-
-
Jenkins Pipeline 작성
Jenkins Pipeline에서 작성 시 주의사항
-
openjdk-11, gradle 직접 설정
-
jenkins 내 Global Tool Configuration
-
Gradle, JDK 설정을 해주어야 합니다
-
java는 다른 버전을 지원하지 않아 adoptopenjdk.net에서 받아서 사용
-
Gradle은 7.1.1 버전을 사용합니다
-
-
Github Authenticaiton이 8월 13일 자 이후로, password
-
-
// 저희 pipeline 구성 코드입니다
pipeline {
agent any
tools {
jdk("openjdk-11")
gradle "test_gradle"
}
stages {
stage('Git clone') {
steps {
git branch: 'release', url: 'https://[아이디]:[비번]@lab.ssafy.com/s05-webmobile1-sub3/S05P13B305.git'
}
}
stage('Gradle version') {
steps {
sh '''gradle --version
echo $JAVA_HOME
docker version
'''
}
}
stage('Gradle') {
steps {
sh '''
cd ./BackEnd
echo ">> project Build Start"
chmod +x gradlew
./gradlew build --no-daemon --stacktrace --exclude-task test
'''
}
}
stage('JAR Make Test') {
steps {
sh '''
cd ./BackEnd
echo ">> pwd"
pwd
echo ">> go jar"
cd ./build/libs
JAR_NAME=ogym-0.0.1-SNAPSHOT.jar
'''
}
}
stage('Make Image') {
steps{
writeFile file:'Dockerfile', text: '''FROM adoptopenjdk/openjdk11:latest
ARG JAR_FILE=BackEnd/build/libs/ogym-0.0.1-SNAPSHOT.jar
EXPOSE 8081
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar","/app.jar", "--spring.profiles.active=prod"]
'''
sh '''
docker login -u 39ghwjd -p !!95dlfwls
docker build -t 39ghwjd/demo_backend .
docker push 39ghwjd/demo_backend:latest
'''
}
}
stage('Make yaml in kubectl'){
steps {
sh '''
mkdir -p BackEnd/deploy
kubectl create deployment demobackend --image=39ghwjd/demo_backend:latest --dry-run -o=yaml> BackEnd/deploy/deployment_backend.yaml
echo --- >> BackEnd/deploy/deployment_backend.yaml
kubectl create service clusterip demobackendservice --tcp=8081:8081 --dry-run -o=yaml | kubectl set selector --local -f - 'app=demobackend' -o=yaml >> BackEnd/deploy/deployment_backend.yaml
cat BackEnd/deploy/deployment_backend.yaml
'''
}
}
stage('FrontEnd'){
steps {
sh '''
cd ./FrontEnd
docker build -t 39ghwjd/demo_frontend .
docker push 39ghwjd/demo_frontend:latest
'''
}
}
stage('Make frontEnd yaml in kubectl'){
steps {
sh '''
mkdir -p FrontEnd/deploy
kubectl create deployment demofrontend --image=39ghwjd/demo_frontend:latest --dry-run -o=yaml > FrontEnd/deploy/deployment_frontend.yaml
echo --- >> FrontEnd/deploy/deployment_frontend.yaml
kubectl create service clusterip demofrontendservice --tcp=80:80 --dry-run -o=yaml | kubectl set selector --local -f - 'app=demofrontend' -o yaml >> FrontEnd/deploy/deployment_frontend.yaml
cat FrontEnd/deploy/deployment_frontend.yaml
'''
}
}
stage('Deploy GitHub'){
steps {
withCredentials([string(credentialsId: 'IMHOJEONG', variable: 'TOKEN')]) {
sh '''
git config user.email 39ghwjd@naver.com
git config user.name IMHOJEONG
mkdir -p deploy
cd ./BackEnd/deploy
cp deployment_backend.yaml ../../deploy/deployment_backend.yaml
cd ../../FrontEnd/deploy
cp deployment_frontend.yaml ../../deploy/deployment_frontend.yaml
cd ../../deploy/
cat deployment_backend.yaml >> deployment.yaml
rm -rf deployment_backend.yaml
echo --- >> deployment.yaml
cat deployment_frontend.yaml >> deployment.yaml
rm -rf deployment_frontend.yaml
git add .
git commit -m 'Triggered Build: ${env.BUILD_NUMBER}'
git push -f https://IMHOJEONG:$TOKEN@github.com/IMHOJEONG/GitOps_Project.git
'''
}
}
}
}
}
- microk8s 구성
-
microk8s enable명령어로 필요한 addon들 추가- ingress, metallb, metrics-server, prometheus
-
microk8s kubectl 명령어, yaml 파일 설정으로 리소스 customize 필수
-
리소스 yaml 파일 작성 후, microk8s kubectl apply -f ~~~.yaml로 설치
-
metallb 구성 시, ec2 private ip를 loadbalancer ip로 작성 해야 로드밸런서가 처리할 수 있게 됨
-
### ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: http-ingress
spec:
tls:
- hosts:
- i5b305.p.ssafy.io
secretName: i5b305-p-ssafy-io
rules:
- host: i5b305.p.ssafy.io
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: demofrontendservice
port:
number: 80
- pathType: Prefix
path: /api
backend:
service:
name: demobackendservice
port:
number: 8081
- pathType: Prefix
path: /test
backend:
service:
name: web
port:
number: 8080
### ingress-service.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress
namespace: ingress
spec:
selector:
name: nginx-ingress-microk8s
type: LoadBalancer
# loadBalancerIP is optional. MetalLB will automatically allocate an IP
# from its pool if not specified. You can also specify one manually.
# loadBalancerIP: x.y.z.a
loadBalancerIP: 172.26.8.91 ## EC2 Private IP!
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 443
- mysql pod, statefulset 구성
### mysql-storageclass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: manual
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
### mysql-pv 구성
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
### mysql-deployment 구성
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- protocol: TCP
port: 3306
nodePort: 30036
targetPort: 3306
selector:
app: mysql
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:8.0.26
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: root
- name: MYSQL_ROOT_HOST
value: '%'
- name: MYSQL_USER
value: i5b305
- name: MYSQL_PASSWORD
value: 1q2w3e4r
- name: TZ
value: Asia/Seoul
- name: MYSQL_HOST
value: '%'
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
-
openvidu 설정 : on-premise
-
https 통신을 위한 인증서 발급 방법
-
ec2에 nginx를 직접 설치 후, 인증서를 발급 받음
-
그 후에, 올라가 있던 nginx service stop하고, ingress에 tls 인증서를 추가해 주면 됨
-
인증서 방식은 letsencrypt로 certbot을 이용해 발급 받는다
-
대신, openvidu에서는 이미 발급된 인증서 기반으로 사용해야 하기 때문에 owncert로 설정을 바꾸어 사용해준다.
-
- argocd 구성
-
ssh을 이용하는 repo를 생성
-
ec2 내 ssh 키를 발급받고 github private repo에 public key, kubernetes pod를 올린 argocd 내부에서 private key를 넣어서 생성
-
그 후, 인식하고, auto-sync enable로 github의 코드가 변경될 시, 리소스를 새로 만들어주게 구성
-
redis, openvidu, jenkins는 docker로 -p 옵션을 주어 포트포워딩을 해서 올림
- jenkins는 -v 옵션으로 볼륨 마운트를 통해 파이프라인 내부에서 docker 명령어를 사용할 수 있게 해주어야 함