3tier 참고 구성도
https://pearlluck.tistory.com/78
* WAS란?
Web Application System을 의미한다.
일전에 html을 이용해서 페이지를 만들었던 적이 있다. 그때 만들었던 페이지는 움직이기는 하나,
데이터가 한번 입력되면 바꿀 수 없는 구조였다.
이제는 데이터와 페이지를 엮을 수도 있고 여러가지 변화들을 담을 수있는 '동적'페이지를 만들려고 한다.
그런 동적페이지를 만들기 위해 java에서 만든 프로그램이 'Servlet'이며
Servlet 프로그램말고도 다른 프로그램들도 존재한다.
또한 그런 Servlet들의 실행을 할 수 있게 해주는 프로그램이 'Tomcat' 이다.
이 역시도 다른 프로그램들도 존재한다.
이때 Tomcat이 WAS이며 Servlet이 실행되게 도와주며 다양한 Servlet들을 담고 있다.
[출처] 4. Servlet - Tomcat(WAS)과 Servlet이란?|작성자 고미
l WAS(Web Application Server)
- DB 조회나 다양한 로직 처리를 요구하는 동적인 컨텐츠를 제공하기 위해 만들어진 Application Server
- 프로그램 실행 환경과 DB 접속 기능 제공
- 여러 개의 트랜잭션 관리 기능
- 업무를 처리하는 비즈니스 로직 수행
- Tomcat
l Web Server와 WAS를 구분하는 이유
- 클라이언트에게 정적인 파일을 우선 제공, 필요할 때만 동적인 파일을 제공하여 빠른 처리, 부담을 줄인다.
- 요청에 맞게 데이터를 DB에서 가져오고 비즈니스 로직에 맞추어 그때 그때 결과를 만들어서 제공함으로써
자원을 효율적으로 사용
- 기능을 분리함으로 서버 부하 방지, 빠른 동작, 여러 대의 WAS 연결 가능
① 클라이언트의 웹 브라우저가 HTTP Request를 한다.
② 웹 서버는 WAS에 웹 애플리케이션 실행을 위임한다.
③ WAS는 해당하는 로직을 수행하다가 DB접근이 필요하면 SQL 질의를 한다.
④ 질의에 따른 응답을 보낸다.
⑤ 실행 결과를 반환한다.
⑥ WAS로부터 받은 결과를 웹 브라우저에 HTTP로 송신한다
AWS나 GCP 같은 퍼블릭 클라우드 플랫폼에서는 기본적으로 쿠버네티스에서 로드밸런서를 지원하지만
로컬에 설치된 K8S는 로드밸런서를 사용할 수 없다.
가장 큰 불편한점은 ingress controller 접속 방법이다.
ingress controller은 서비스 타입이 로드밸런서를 사용하지 않으면 <노드IP>:<nodeport>로 접근해야 하는데,
마치 google.com을 접속하기 위해 google.com:32000 을 입력하는 것이 필요햐다.
k create deployment web-apaches --image=httpd:latest --replicas=3
k exec web-apaches-575b5dd79d-4pgv5 -it -- /bin/bash
cat > /usr/share/nginx/html/index.html << EOF
cat > /usr/local/apache2/htdocs/index.html << EOF
<html>
<body>
<h1> sonharin server docker man sei </h1>
</body>
</html>
EOF
https://kubernetes.io/ko/docs/tutorials/stateful-application/basic-stateful-set/
https://kubernetes.io/ko/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
mkdir /nginx_st
나중에 서비스에 로드밸런서 내용 넣어서 yaml파일 실행해줘야 메탈lb작동하는거 잊지 말기
쿠버네티스에선 파드가 수시로 올라가고 내려가며 할당되는 노드도 바뀌는 등 변동 가능성이 존재하기 때문에 html 파일이나 다른 구성 파일들을 따로 pv에 유지시킬 필요가 있다.
이런 경우 nginx를 statefulset으로 실행하는 것이 바람직하다.
mkdir /data001/{pv0001,pv0002}
각 노드에 index파일을 넣어준다.
해당 노드에 할당된 파드는 pv설정을 통해 노드의 파일시스템에 있는 index파일을 본인의 컨테이너 안에 업데이트한다.
scp /data001/pv0001/index.html node2:/data001/pv0002/index.html
scp /data001/pv0001/index.html node3:/data001/pv0002/index.html
https://codecollector.tistory.com/1337
1) 메탈 LB
2) 스테이트풀셋 nginx가 2레플리카 돌아간다 (다이나믹pv)
3) 데몬셋 : 설정된 노드가 생성되면 자동으로 모니터링 pod가 할당되어 돌아간다
4) Nginx 포드와 PHP FPM 포드를 같은 노드에 할당해도 되는 이유 : nginx는 많은 리소스를 사용하지 않는다.
metal LB로드밸런싱 확인
nginx web-0과 web-1 페이지 내용 다르게 하고 호스트 pc의 cmd창에서 확인해본다.
외부 cluster IP 하나로 로드밸런싱 당해서 두종류의 페이지가 번갈아 출력된다.
==========================================================
톰켓 + mysql
여기까지만 하면 원하던 구상도가 거의 완성되었다.
하지만 사용자 -> 로드밸런서 -> web -> was -> DB 이렇게 트레픽이 흘렀으면 하는 구상도에서
지금은 직접 사용자 -> was -> DB 로 흐르는 구조다.
tomcat과 nginx를 프록시 설정을 통해 연동해줄 필요가 있다.
nginx의 설정을 configmap화 하여 volume파일로 저장하는 방식을 채택하겠다.
http://chomman.github.io/blog/java/tomcat/nginx/tomcat-nginx/
컨피그맵 작
# server 부분에 아래와 같은 "/" 접근 proxy_pass 설정을 한다.
/etc/nginx/nginx.conf
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
data:
nginx-main.conf: |
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#include /etc/nginx/conf.d/*.conf; 이 아래로는 새로 작성한 부분입니다
upstream tomcat {
server 컨테이너ip:8080;
server 컨테이너ip:8080;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
proxy_pass http://tomcat;
}
}
}
nginx 스테이트풀셋에 컨피그맵 볼륨 설정 추가
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeMounts:
- name: nginx-cfg
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: nginx-cfg
configMap:
name: nginx-conf
items:
- key: nginx-main.conf
path: nginx.conf
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
컨피그맵 볼륨에 대한 이론
https://timewizhan.tistory.com/entry/Kubernetes-ConfigMap
특정한 config 설정 파일만 필요한데 큰 config 파일을 일괄 적용하면 불필요한 설정 파일까지 포함된다.
(ConfigMap에 설정 파일이 합쳐져 있기 때문)
물론 ConfigMap을 각각 만들어도 상관없지만 추천할 만한 방법은 아니다.
대신에 k8s에서는 특정 ConfigMap만 사용할 수 있는 방법이 존재한다.
위의 Volume을 설정할 때 items를 추가해주면 된다.
- key : ConfigMap에 포함되어 있는 Key
- path : Volume에 저장되는 파일 이름
결과적으로 Container에서는 Mount 경로에서 설정 파일이 path로 보인다. 즉 path가 test.conf라면 Container에서 {Mount}/{path}로 접근 할 수 있다.
문제점이 있다. 바로 Mount 할 지점에 기존에 파일이 있을 경우이다. Mount가 되면 해당 Volume을 볼 수 있지만 그렇다면 기존 파일들은 어떻게 되는 것일까?
리눅스에서는 보통 파일이 사라지는 것이 아니라 숨겨진 파일로 살아만 있다. (즉, 숨겨지는 것 뿐만 아니라 접근이 되지 않는다.) 때문에 k8s에서는 Mount를 할 때 이를 회피할 수 있는 옵션이 있다.
subPath 옵션을 사용하는 것이다. 그렇기 때문에 Mount 지점을 파일로 하고 ConfigMap에서 필요한 파일만 가져온다. (전체 Volume을 가져오진 않는다.)
ConfigMap의 가장 큰 장점은 ConfigMap만 수정하면 관련된 모든 Container는 변경할 필요가 없다. (ConfigMap이 수정되면 Volume이 자동적으로 업데이트 되기 때문에)
물론 Container에서 새로운 환경 변수 값을 적용하기 위해서는 reload 과정이 필요하다. 그런데 Volume을 업데이트 해야하기 때문에 1분 정도 동기화 시간이 걸리기도 한다.
이러한 ConfigMap Update 분명 공수가 많이 들지 않는 좋은 방법이기는 하지만 고려해야 할 점은 Container의 Application이 과연 reload를 지원하느냐이다.
지원하지 않는다면 굳이 Application이 동작하는 동안에 ConfigMap Update를 할 필요가 없다. (멈추고 ConfigMap 수정 이후 재시작하는게 더 나을 수 있다.)
# nginx - tomcat 연동
[root@pororicom /]# vi /etc/nginx/conf.d/nginx.conf
upstream tomcat7 {
ip_hash;
server 127.0.0.1:8080;
# 주의 : docker 에서 사용시, 컨테이너의 아이피를 작성
# server 127.0.0.2:8080; 와 같이 여러개 추가시 자동으로 loadbalance가 적용되며
# , 이를 위한 nginx 사용이다. 옵션 weight = 5 로 특정서버에 가중치를 분할 할수 있다.
}
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/tomcat.access.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://tomcat7; * upstream 의 명칭을 작성
proxy_redirect off;
charset utf-8;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
저는 upstream으로 서버 2개를 정의해 주었는데 하나는 main서버고 하나는 backup서버입니다. proxy_pass http://tomcat 이 부분이 upstream tomcat과 같아야합니다. upstream tomcat1로 하였다면 proxy_pass http://tomcat1로 해주어야합니다.
'Kubernetes' 카테고리의 다른 글
[Project] 온프레미스 중간 프로젝트 (0) | 2023.02.17 |
---|---|
[미니프로젝트] Nginx 소스 Statefulset (0) | 2023.01.29 |
[미니프로젝트] - metal LB 사용하여 WordPress와 MySQL을 퍼시스턴트 볼륨에 배포 (with 시크릿) (1) | 2023.01.04 |
ingress (0) | 2023.01.04 |
secret (0) | 2023.01.04 |