한화 시스템 부트 캠프 22주차 회고
뭔가 요즘은 6시에 끝은 나지만 집에는 10시에 가는 것 같다 ,, 집이랑 강의장이 생각보다 멀어서 10시에 집에 가면 12시즈음 도착하게 된다. 뭔가 저녁 시간이니까 사람이 다 빠져서 빠르게 도착할 것 같지만 오히려 차가 별로 없어서 더 늦게 가는 기분...!
얼른 멋지게 끝내서 칼퇴하는 날이 오면 좋겠다.
이번 주에는 현재 프로젝트에 CI/CD를 적용했다.
CI/CD
지속적 통합(Continuous Integration) 및 지속적 제공/배포(Continuous Delivery/Deployment)를 의미하며, 소프트웨어 개발 라이프사이클을 간소화하고 가속화하는 것을 목표로 한다.
지속적 통합이란 어플리케이션의 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트 되어 공유 레포지토리에 통합하는 것을 의미한다.
진행 순서를 정리 했을 때, 순차적으로 해야 될 것이라고 말씀 하셨다.
- Kubernetes 클러스터 배포 및 MetalLB 설정
- LoadBalancer 서비스 및 Ingress 설정
- 도메인 연결 및 SSL 설정
- CI/CD 파이프라인 설정 (Jenkins 사용)
- 무중단 배포 설정
나는 여기에서 Ingress 설정과 도메인 연결 및 SSL 설정을 맡게 되었다.
또한 Kafka또한 K8S를 통해 배포를 해야 하기 때문에 yaml파일을 작성했다.
순차적으로 하나씩 정리를 해 보겠다.
일단 K8S는 저번 4번째 토이 프로젝트 때 환경 설정을 해 둔 것이 있어서 그나마 편하게 할 수 있었다.
일단 달라진 것은 HTTPS로 적용을 해야 하기에 SSL을 추가해야 한다는 것이다.
HTTPS의 특징은
- 암호화 통신: SSL(Secure Sockets Layer) 또는 TLS(Transport Layer Security)를 사용하여 데이터를 암호화하여 전송한다. 이를 통해 데이터의 기밀성과 무결성을 보장한다.
- 포트 번호: 기본적으로 포트 443을 사용한다.
- 인증서 필요: 신뢰할 수 있는 인증 기관(CA)에서 발급한 SSL/TLS 인증서가 필요하다. 이 인증서는 서버의 신원을 확인하는 데 사용된다.
- 보안 강화: 중간자 공격, 데이터 도청, 변조 등의 보안 위협으로부터 데이터를 보호한다..
- SEO 우대: 구글과 같은 검색 엔진은 HTTPS를 사용하는 웹사이트를 더 신뢰할 수 있는 사이트로 간주하여 검색 순위를 높게 평가한다.
HTTPS를 구현하기 위해서 SSL 인증서를 발급 받아야 한다.
ZeroSSL에서 발급 받았다.
SSL 인증서 발급 받는 방법
New Certificate 클릭
사용 할 도메인 입력
-> 도메인은 어디서 발급 받냐?
무료 도메인 인증 센터인 [ 내 도메인 한국 ] 에서 받을 수 있다.
https://xn--220b31d95hq8o.xn--3e0b707e/
내도메인.한국 - 한글 무료 도메인 등록센터
한글 무료 도메인 내도메인.한국, 웹포워딩, DNS 등 무료 도메인 기능 제공
xn--220b31d95hq8o.xn--3e0b707e
도메인을 생성 해 주고, IP연결에는 K8S에 배포한 frontend 서비스의 IP를 적어주면 된다.
위에 생성한 도메인 주소를 입력 해 주고 Next Step을 넘어간다.
90-Day 로 설정 해 주고 Next Step
추가 기능을 선택하는 칸도 그냥 아무것도 체크 안 하고 Next Step
무료 버전을 선택하고, Next
이제 다음으로 가면 검증 방법을 선택하라고 하는데, DNS를 선택하고
아래에 나오는 Name, Point To 를 잘 복사해서 내 도메인 한국에 있는
이 칸에 잘 넣어주면 된다. 그럼 이제 키를 다운 받을 수 있는데, 이 키의 압축을 해제하고 내가 찾을 수 있는 폴더 안에 잘 넣어주면 된다. 나는 c드라이브에 넣어놨다.
이제 이 키를 인증서를 생성하기 위해 쿠버네티스 환경을 만들어 놓은 마스터 계정으로 들어왔다.
key파일을 옮기기 위해서 < 파일 질라 > 프로그램을 사용 했으며, 내 c드라이브에 있는 파일을 파일 질라를 통해 k8s환경을 구축 해 놓은 마스터 계정 home 안에 넣어놨다.
이제 K8s 클러스터에서 ingress-nginx를 사용하여 HTTPS를 설정하고, SSL 인증서를 적용하기 위한 단계를 차근차근 정리하겠다.
1. 인증서 파일을 준비한다.
위에 앞서 말 했던 것 처럼 key 파일을 옮긴 폴더 안으로 간다.
인증서 파일은
certificate.crt, ca_bundle.crt, private.key가 준비되어 있어야 한다.
2. 인증서 파일을 병합한다.
cat certificate.crt ca_bundle.crt > fullchain.crt
이 명령어는 서버 인증서와 CA 번들을 하나의 파일인 fullchain.crt로 병합하는 것이다. 이는 SSL 인증서를 제대로 검증하기 위해서 필요하고, fullchain.crt 파일은 클라이언트가 서버의 SSL 인증서를 신뢰할 수 있도록 모든 필요한 중간 인증서를 포함한다.
3. Secret 생성
kubectl create secret tls tls-secret --cert=fullchain.crt --key=private.key -n default
default 네임 스페이스에 tls-secret 라는 이름의 TLS Secret를 생성한다.
4. Ingress 리소스 설정 확인
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: calit-ingress
namespace: default
spec:
ingressClassName: "nginx"
tls:
- hosts:
- www.calit.kro.kr
secretName: tls-secret
rules:
- host: www.calit.kro.kr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: backend-svc
port:
number: 8080
1. ingressClassName: "nginx": ingress-nginx 컨트롤러를 사용하도록 지정합니다.
2. tls: TLS 설정을 정의하며, www.calit.kro.kr 호스트에 대해 tls-secret을 사용하도록 지정합니다.
3. rules: HTTP 및 HTTPS 요청을 해당 서비스로 라우팅합니다.
혹여나 ingress 리소스를 수정했거나, 새로 생성한 경우 Kubernetes 클러스터에 적용 하기 위해서는
kubectl apply -f calit-ingress.yaml
명령어를 통해 적용할 수 있다.
이제 브라우저에서 [https:// 도메인 주소] 에 접근하여 SSL 인증서가 올바르게 적용 됐는지 시각적으로 확인 가능하다.
앞서 말씀 드린 것 처럼, 채팅 기능을 배포하기 위해서 공부하고 준비한 방법을 설명 드리겠습니다.
Kubernetes 클러스터에 Zookeeper와 Kafka를 배포하고, 백엔드 애플리케이션과 연결하는 과정
1. zookeeper 먼저 배포
apiVersion: apps/v1
kind: Deployment
metadata:
name: zookeeper-deployment
labels:
app: zookeeper
spec:
replicas: 1 # Zookeeper 인스턴스 수
selector:
matchLabels:
app: zookeeper
template:
metadata:
labels:
app: zookeeper
spec:
containers:
- name: zookeeper
image: zookeeper:3.8.0
ports:
- containerPort: 2181 # Zookeeper 클라이언트 포트
env:
- name: ALLOW_ANONYMOUS_LOGIN
value: "yes" # 익명 로그인 허용 (기본 설정)
- name: ZOOKEEPER_CLIENT_PORT
value: "2181" # Zookeeper 클라이언트 연결 포트
- name: ZOOKEEPER_SERVER_ID
value: "1" # Zookeeper 서버 ID
---
apiVersion: v1
kind: Service
metadata:
name: zookeeper-service
labels:
app: zookeeper
spec:
ports:
- port: 2181
targetPort: 2181
selector:
app: zookeeper
2. Kafka 배포
apiVersion: apps/v1
kind: Deployment
metadata:
name: kafka-deployment
labels:
app: kafka
spec:
replicas: 1 # Kafka 브로커의 수 (하나의 브로커로 설정)
selector:
matchLabels:
app: kafka
template:
metadata:
labels:
app: kafka
spec:
containers:
- name: kafka
image: confluentinc/cp-kafka:7.4.6
ports:
- containerPort: 9092 # Kafka 브로커 포트
env:
- name: KAFKA_BROKER_ID
value: "1" # Kafka 브로커의 ID
- name: KAFKA_ZOOKEEPER_CONNECT
value: "zookeeper-service:2181" # Zookeeper 서비스와 연결
- name: KAFKA_ADVERTISED_LISTENERS
value: "PLAINTEXT://kafka-service:9092" # Kafka의 광고 주소
- name: KAFKA_LISTENERS
value: "PLAINTEXT://0.0.0.0:9092" # 모든 인터페이스에서 수신 대기
- name: KAFKA_LISTENER_SECURITY_PROTOCOL_MAP
value: "PLAINTEXT:PLAINTEXT" # 보안 프로토콜 설정
- name: KAFKA_INTER_BROKER_LISTENER_NAME
value: "PLAINTEXT" # 브로커 간 통신에 사용할 리스너 이름
- name: KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR
value: "1" # 카프카 토픽 오프셋 복제 계수
- name: KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS
value: "0" # 초기 리밸런스 지연 시간
---
apiVersion: v1
kind: Service
metadata:
name: kafka-service
labels:
app: kafka
spec:
ports:
- port: 9092 # Kafka 브로커가 클라이언트에게 노출될 포트
selector:
app: kafka
그럼 이제 백엔드 애플리케이션과 Kafka를 어떻게 연결하면 좋을지,,,
jenkins - 시스템 - 환경변수를 사용해서 배포 과정에서 해당 환경 변수를 주입할 수 있게 해준다.
jenkins /setting/system에서 KAFKA_SERVER 안에 kafka-service(k8s kafka 서비스 이름):9092 를 해주면
-> kafka-service:9092
dockerFile에서
# ARG 선언과, ENV 설정을 해 젠킨스 파일에서Docker Build & Push 할 때 --build-arg KAFKA_SERVER=${KAFKA_SERVER} \
를 해주면 applicaion.yml 에서 잘 받아오게 해준다.
kafka:
bootstrap-servers: ${KAFKA_SERVER}
producer:
bootstrap-servers: ${KAFKA_SERVER}
consumer:
bootstrap-servers: ${KAFKA_SERVER}
Kafka가 잘 실행 됐는지 알기 위해서는 Pod 이벤트를 확인 해 보면 된다.
schedduled : 배치할 노드를 선택하고, pod의 스케쥴링이 완료
Pulling : 컨테이너 이미지 다운로드 작업을 시작
Pulled : 컨테이너 이미지가 성공적으로 다운로드
Created : 컨테이너 생성 완료
Started : 컨테이너가 실행 → 서비스 정상적 실행 시작
이렇게 뜨면 성공 한 것이다. 백엔드 파드 안으로 가서 정상 실행이 됐는지, kafka 로그가 뜨는지를 보며 확인 할 수 있다.
이렇게 22주차의 회고록이 끝나게 되고, 직접 배포를 하려고 하니 많이 어려웠다. 이번 주는 개발을 멈추고 only 배포만 한 것 같다.
저번 4번째 토이 프로젝트 때 한 차례 했던 것이라 편할 줄 알았는데, 그때 기반을 잡아놓지 않았더라면 이 시간 안에 하지 못 했을 것 같다는 생각이 들었다.
개발만 하는 게 중요한 것이 아니라 CI/CD, K8S, Jenkins와 같은 도구를 잘 다뤄야 하는 이유를 뼈저리게 느끼게 됐다.
아쉬운 것이 있다면 아무래도 시간이 부족하다 보니 저번 토이 프로젝트 때 K8S yaml이나, JenkinsFile을 작성하는 것을 같이 맡았다는 점이다..! 나중에 따로 공부를 해 해 보는 시간을 가져야 할 것 같다.
Kafka를 배포하면서 yaml을 찾아보고 작성했는데, 뭔가 개발에서 효율적으로 확장 가능함을 느낄 수 있었다. 자원을 할당해주고 운영하는 것에 편리함을 확실하게 느꼈다.
무중단 배포를 통해 사용자에게 영향을 주지 않고, 새로운 기능을 배포할 수 있게 도와주는 작업을 했고, 아직 많은 테스트를 거치지는 않았지만 했다는 것에 많이 신기했다.
현대 소프트웨어 개발에서 신속한 배포, 서비스 안정성은 이제 필수로 잡혀가는 것 같다. 이를 통해 생산성과 협업을 극대화 할 수 있기 때문에 ,, 꼭 갖춰야 할 기술인 것 같다. 오늘도 적으면서 많은 것을 느꼈다. 열심히 살아야겠다...!
내일은 팀끼리 만나 발표 준비를 하기 때문에 일요일에 적지 못할 것 같아 먼저 적었다..!
다들 주말 잘 보내시고, 행복한 하루 보내셔요.
