반응형
nginx 예제
/demo/deploy/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello World
</body>
</html>
/demo/config/demo.conf
server {
listen 81;
server_name localhost;
location / {
root /deploy;
index index.html index.htm;
}
}
webserver.yml
apiVersion: v1
kind: Service
metadata:
name: webserver-service
spec:
type: NodePort
ports:
- name: http80
protocol: TCP
port: 80
targetPort: 80
nodePort: 30080 # 30000-32767 사이값, 설정값 없으면 랜덤으로 지정
- name: http81
protocol: TCP
port: 81
targetPort: 81
nodePort: 30081
selector:
app: webserver-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: webserver-deploy
spec:
replicas: 1
selector:
matchLabels:
app: webserver-app
strategy:
type: RollingUpdate # Recreate/RollingUpdate(default)
revisionHistoryLimit: 10 # 10(default)
template:
metadata:
labels:
app: webserver-app
env: dev
spec:
containers:
- name: nginx-container
image: nginx:1.17.9
ports:
- containerPort: 80
- containerPort: 81
volumeMounts:
- name: deploy
mountPath: /deploy
- name: demo-conf
mountPath: /etc/nginx/conf.d/demo.conf
volumes:
- name: deploy
hostPath:
path: /demo/deploy
type: Directory
- name: demo-conf
hostPath:
path: /demo/config/demo.conf
type: File
실행
kubectl apply -f webserver.yml
테스트
curl http://localhost:30080
curl http://localhost:30081
spring boot 예제
DemoController
@Slf4j
@RestController
public class DemoController {
@Value("${server.machine-id}")
private String machineId;
@GetMapping("/api/v1/health")
public String health() {
log.info("health");
return "OK";
}
@GetMapping("/api/v1/machine_id")
public String getMachineId() {
log.info("machineId : {}", machineId);
return machineId;
}
}
infra/Dockerfile
FROM amazoncorretto:17.0.9 AS gradle_cache
COPY gradle /workspace/gradle
COPY gradlew build.gradle.kts settings.gradle.kts /workspace/
WORKDIR /workspace
RUN ./gradlew clean build || true
FROM amazoncorretto:17.0.9 AS gradle_builder
COPY --from=gradle_cache /root/.gradle /root/.gradle
COPY . /workspace
WORKDIR /workspace
RUN ./gradlew clean bootJar -x test
FROM amazoncorretto:17.0.9
COPY --from=gradle_builder /workspace/build/libs/*.jar /app/app.jar
이미지 빌드
docker build -t demo/demo-api:v1 -f infra/Dockerfile .
infra/demo-api.yml
apiVersion: v1
kind: Service
metadata:
name: demo-api-service
spec:
type: NodePort
ports:
- name: http
protocol: TCP
port: 8080 # pod가 실제로 expose한 포트. == targetPort
nodePort: 30080 # 30000-32767 사이값, 설정값 없으면 랜덤으로 지정
selector:
app: demo-api
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: demo-api
spec:
replicas: 3
selector:
matchLabels:
app: demo-api
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app: demo-api
env: dev
spec:
containers:
- name: was
image: demo/demo-api:v1
command:
- /bin/sh
- -c
- |
POD_INDEX=$(echo $POD_NAME | awk -F '-' '{print $NF}')
java -jar -Dserver.port=8080 -Dserver.machine-id=$POD_INDEX -Dspring.profiles.active=dev /app/app.jar
ports:
- name: was-port
containerPort: 8080 # 컨테이너가 expose한 포트를 명시. 명시하는 역할만 할 뿐 expose 포트를 변경하진 않음.
env:
- name: TZ
value: Asia/Seoul
- name: POD_NAME # demo-api-{index}
valueFrom:
fieldRef:
fieldPath: metadata.name
startupProbe:
httpGet:
path: /api/v1/health
port: was-port
initialDelaySeconds: 0 # pod가 실행된 이후 대기 시간 (default: 0)
periodSeconds: 5 # 해당 시간 만큼 대기 후 반복 (default: 10)
timeoutSeconds: 5 # 타임아웃 (default: 1)
successThreshold: 1 # 시도가 실패한 후 성공한 것으로 간주되는 최소 연속 성공. (default: 1)
failureThreshold: 1 # 시도가 실패한 후 실패한 것으로 간주되는 최소 연속 실패.
volumeMounts:
- name: was-logs
mountPath: /logs
volumes:
- name: was-logs
hostPath:
path: /home/ubuntu/demo-api/logs
type: DirectoryOrCreate
리소스 적용
kubectl apply -f infra/demo-api.yml
테스트
curl localhost:30080/api/v1/machine_id
nginx + spring boot 예제
설명
- 한 pod 안에 여러 container(nginx, spring boot)를 포함하는 예제
- 일반 url로 접근시 nginx로 서비스, /api/* url로 접근시 spring boot로 서비스
- 한 pod 안에서는 container간에 localhost로 통신이 가능함
example.jar
- 노드 경로 : /home/docker/mount/deploy/example.jar
index.html
- 노드 경로 : /home/docker/mount/deploy/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello World
</body>
</html>
nginx.conf
- 노드 경로 : /home/docker/mount/config/nginx.conf
user nginx;
worker_processes 1;
error_log /home/nginx/logs/error.log debug;
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][$time_local][$status][$request][$http_referer][$http_user_agent]';
access_log /home/nginx/logs/access.log main;
sendfile on;
keepalive_timeout 65;
upstream api {
server localhost:8080;
}
server {
listen 80;
location /api {
proxy_pass http://api;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /home/nginx/deploy;
index index.html index.htm;
}
}
}
webserver.yml
apiVersion: v1
kind: Service
metadata:
name: webserver-service
spec:
type: ClusterIP
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
externalIPs:
- 192.168.99.102 # minikube 노드 IP, 테스트를 위해 지정, 실제 Kubernetes LoadBalancer에서는 지정할 필요 없음
selector:
app: webserver
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: webserver-deploy
spec:
replicas: 2
selector:
matchLabels:
app: webserver
strategy:
type: RollingUpdate # Recreate/RollingUpdate(default)
revisionHistoryLimit: 10 # 10(default)
template:
metadata:
labels:
app: webserver
env: dev
spec:
containers:
- name: springboot-container
image: openjdk:11.0.6
ports:
- containerPort: 8080
volumeMounts:
- name: mount
mountPath: /mount
command:
- /bin/sh
- -c
- |
mkdir -p /home/springboot/deploy
cp /mount/deploy/example.jar /home/springboot/deploy/
java -jar /home/springboot/deploy/example.jar
- name: nginx-container
image: nginx:1.17.9
ports:
- containerPort: 80
volumeMounts:
- name: mount
mountPath: /mount
command:
- /bin/sh
- -c
- |
mkdir -p /home/nginx/deploy /home/nginx/logs
cp /mount/deploy/index.html /home/nginx/deploy/
cp /mount/config/nginx.conf /etc/nginx/
nginx -g 'daemon off;'
volumes:
- name: mount
hostPath:
path: /home/docker/mount
type: Directory
리소스 반영
kubectl apply -f webserver.yml
리소스 반영 확인
kubectl get service,deploy,pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 82m
service/webserver-service ClusterIP 10.104.147.208 192.168.99.102 80/TCP 113s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/webserver-deploy 2/2 2 2 113s
NAME READY STATUS RESTARTS AGE
pod/webserver-deploy-565bbdf84d-gbpg8 2/2 Running 0 113s
pod/webserver-deploy-565bbdf84d-q7h5k 2/2 Running 0 113s
확인
- nginx
- http://192.168.99.102
- springboot
- http://192.168.99.102/api/messages
MySQL 예제
mysql.yml
apiVersion: v1
kind: Service
metadata:
name: mysql-cluster-ip-service
spec:
type: LoadBalancer
ports:
- port: 3306
targetPort: 3306
externalIPs:
- 192.168.99.102 # minikube 노드 IP, 테스트를 위해 지정, 실제 Kubernetes LoadBalancer에서는 지정할 필요 없음
selector:
app: mysql
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /home/docker/mount/data # node 디렉토리
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
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:5.6
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: "123456"
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql # pod 디렉토리
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
참고
- https://velog.io/@pa324/쿠버네티스-mysql-설치-6bjxv4dcoa
반응형
'Development > Kubernetes' 카테고리의 다른 글
[Kubernetes] Helm 설치 (0) | 2020.12.29 |
---|---|
[Kubernetes] Service (0) | 2020.12.29 |
[Kubernetes] 명령어 (0) | 2020.12.29 |
[Kubernetes] Minikube 설치 (0) | 2020.12.29 |
[Kubernetes] 단일 클러스터 구성하기 (0) | 2020.12.29 |