반응형

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

+ Recent posts