전체 목차

 

어플리케이션을 운영하다 보면 로그를 확인해야 할 경우가 자주 생깁니다.

 

1. 로그 확인

kubectl logs <pod name> 로 특정 pod의 로그를 확인 할 수 있습니다.

먼저 pod name 을 확인합니다.

PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi> kubectl get pods -o wide
NAME                                   READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
hello-kubernetes-api-989745789-7ptxq   1/1     Running   0          22m   10.244.1.40   node1   <none>           <none>
hello-kubernetes-api-989745789-gw8mr   1/1     Running   0          51m   10.244.3.26   node2   <none>           <none>
hello-kubernetes-api-989745789-q7rrj   1/1     Running   0          22m   10.244.2.46   node3   <none>           <none>
nginx-bf5d5cf98-pxjh7                  1/1     Running   0          22h   10.244.1.38   node1   <none>           <none>
nginx-bf5d5cf98-qwlwj                  1/1     Running   0          22h   10.244.2.44   node3   <none>           <none>
nginx-bf5d5cf98-v547z                  1/1     Running   0          22h   10.244.3.23   node2   <none>           <none>
PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi>

 

PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi> kubectl logs hello-kubernetes-api-989745789-7ptxq

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v4.0.1)

2026-01-21 12:02:33.113 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] g.h.api.HelloKubernetesApplication - Starting HelloKubernetesApplication v0.0.1-SNAPSHOT using Java 21.0.9 with PID 1 (/app/app.jar started by root in /app)
2026-01-21 12:02:33.124 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] g.h.api.HelloKubernetesApplication - No active profile set, falling back to 1 default profile: "default"
2026-01-21 12:02:35.383 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.s.boot.tomcat.TomcatWebServer - Tomcat initialized with port 8080 (http)
2026-01-21 12:02:35.418 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
2026-01-21 12:02:35.426 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.a.catalina.core.StandardService - Starting service [Tomcat]
2026-01-21 12:02:35.427 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/11.0.15]
2026-01-21 12:02:35.526 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.s.b.w.c.s.WebApplicationContextInitializer - Root WebApplicationContext: initialization completed in 2210 ms
2026-01-21 12:02:36.396 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
2026-01-21 12:02:36.438 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.s.boot.tomcat.TomcatWebServer - Tomcat started on port 8080 (http) with context path '/'
2026-01-21 12:02:36.469 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] g.h.api.HelloKubernetesApplication - Started HelloKubernetesApplication in 4.821 seconds (process running for 5.861)
2026-01-21 12:05:09.450 [http-nio-8080-exec-1] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-01-21 12:05:09.451 [http-nio-8080-exec-1] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2026-01-21 12:05:09.455 [http-nio-8080-exec-1] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.s.web.servlet.DispatcherServlet - Completed initialization in 2 ms
2026-01-21 12:05:09.517 [http-nio-8080-exec-1] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-7ptxq)
PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi>

node1 에서 실행되고 있는 hello-kubernetes-api 의 로그가 잘 보여지고 있습니다.

 

여러 노드의 모든 hello-kubernetes-api 의 로그를 실시간으로 보려면 -f 옵션(tail -f 와 동일)을 주고, --prefix 옵션을 주면 어떤 pod에서 발생한 로그인지도 구분 할 수 있습니다.

PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi> kubectl logs -l app=hello-kubernetes-api -f --prefix
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 11:58:42.198 [http-nio-8080-exec-9] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 11:58:49.747 [http-nio-8080-exec-10] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 11:58:55.944 [http-nio-8080-exec-1] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 11:59:04.494 [http-nio-8080-exec-4] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 12:05:01.801 [http-nio-8080-exec-5] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 12:05:02.665 [http-nio-8080-exec-6] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 12:05:03.586 [http-nio-8080-exec-7] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 12:05:04.613 [http-nio-8080-exec-8] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 12:05:14.546 [http-nio-8080-exec-9] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-gw8mr/hello-kubernetes-api] 2026-01-21 12:05:15.674 [http-nio-8080-exec-10] [INFO ] [node2:hello-kubernetes-api-989745789-gw8mr] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-gw8mr)
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:01:51.419 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.s.b.w.c.s.WebApplicationContextInitializer - Root WebApplicationContext: initialization completed in 2167 ms
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:01:52.219 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:01:52.255 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.s.boot.tomcat.TomcatWebServer - Tomcat started on port 8080 (http) with context path '/'
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:01:52.283 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] g.h.api.HelloKubernetesApplication - Started HelloKubernetesApplication in 4.726 seconds (process running for 5.764)
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:05:21.898 [http-nio-8080-exec-1] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:05:21.899 [http-nio-8080-exec-1] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:05:21.903 [http-nio-8080-exec-1] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.s.web.servlet.DispatcherServlet - Completed initialization in 4 ms
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:05:21.953 [http-nio-8080-exec-1] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-q7rrj)
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:05:41.249 [http-nio-8080-exec-2] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-q7rrj)
[pod/hello-kubernetes-api-989745789-q7rrj/hello-kubernetes-api] 2026-01-21 12:05:42.058 [http-nio-8080-exec-3] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-q7rrj)
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:02:35.426 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.a.catalina.core.StandardService - Starting service [Tomcat]
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:02:35.427 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/11.0.15]
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:02:35.526 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.s.b.w.c.s.WebApplicationContextInitializer - Root WebApplicationContext: initialization completed in 2210 ms
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:02:36.396 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:02:36.438 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.s.boot.tomcat.TomcatWebServer - Tomcat started on port 8080 (http) with context path '/'
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:02:36.469 [main] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] g.h.api.HelloKubernetesApplication - Started HelloKubernetesApplication in 4.821 seconds (process running for 5.861)
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:05:09.450 [http-nio-8080-exec-1] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:05:09.451 [http-nio-8080-exec-1] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:05:09.455 [http-nio-8080-exec-1] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] o.s.web.servlet.DispatcherServlet - Completed initialization in 2 ms
[pod/hello-kubernetes-api-989745789-7ptxq/hello-kubernetes-api] 2026-01-21 12:05:09.517 [http-nio-8080-exec-1] [INFO ] [node1:hello-kubernetes-api-989745789-7ptxq] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-7ptxq)

 

 

2. 로그를 pod 외부에 영구 저장

쿠버네티스 클러스터의 pod로 배포한 어플리케이션의 경우 컨테이너가 재시작되면 내부 로그파일은 사라집니다.

스토리지 운영 측면에서는 편리하지만 spring-boot 레거시 운영 개념에서는 때로는 지난 로그를 확인해야 할 때도 있습니다.

(쿠버네티스 클러스터로 운영하려면 중요한 로그는 별도의 DB나 S3 같은 공유 스토리지에 저장하는 것이 좋을 것 같습니다.)

hello-kubernetes-api 앱의 로그를 pod 내부가 아닌 외부의 node별 디렉토리에 각각 저장해 보도록 하겠습니다.

 

hello-kubernates-api 앱을 수정합니다.

2.1. 의존성 추가

logback를 사용하기 위해 Rombok 의존성을 추가 합니다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webmvc'
    
    // Lombok 추가
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

 

2.2. deployment.yaml 파일 수정

어플리케이션을 외부에 저장하기 위해 볼룸을 생성하고 pod 외부의 node의 절대 경로로 지정합니다.

여기서는 /var/log/hello-k8s 하위에 저장되도록 하겠습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-kubernetes-api
  template:
    metadata:
      labels:
        app: hello-kubernetes-api
    spec:
      containers:
      - name: hello-kubernetes-api
        image: basscraft/hello-kubernetes-api:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        # 1. 환경 변수 주입 (Logback에서 사용)
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        # 2. 볼륨 마운트 (컨테이너 내부 경로)
        volumeMounts:
        - name: log-volume
          mountPath: /logs
      # 3. 볼륨 정의 (호스트 경로)
      volumes:
      - name: log-volume
        hostPath:
          path: /var/log/hello-k8s  # 노드에 생성될 로그 디렉토리
          type: DirectoryOrCreate
---
apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes-api-service
spec:
  selector:
    app: hello-kubernetes-api
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: NodePort

 

2.3. logback-spring.xml 생성

resource 디렉토리에 logback-spring.xml 파일을 생성하고 어플리케이션 로그를 콘솔 및 파일로 출력하도록 간단하게 설정했습니다.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 환경 변수 가져오기 (없으면 UNKNOWN) -->
    <springProperty scope="context" name="NODE_NAME" source="NODE_NAME" defaultValue="UNKNOWN_NODE"/>
    <springProperty scope="context" name="POD_NAME" source="POD_NAME" defaultValue="UNKNOWN_POD"/>

    <!-- 로그 파일 경로 (컨테이너 내부) -->
    <property name="LOG_FILE" value="/logs/app.log"/>

    <!-- 1. 콘솔 출력 Appender -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] [%property{NODE_NAME}:%property{POD_NAME}] %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 2. 파일 출력 Appender (Rolling 정책 적용) -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] [%property{NODE_NAME}:%property{POD_NAME}] %logger{36} - %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 날짜별로 로그 파일 분리 및 압축 -->
            <fileNamePattern>/logs/app.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
            <!-- 30일간 보관 -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- 로깅 레벨 설정 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

 

2.4. HelloController.java 수정

콘트롤러 클래스 상단에 logback 을 사용하기 위해 @Slf4j 를 추가하고 return 전에 동일한 내용을 log로 남기는 코드를 한줄 추가 했습니다.

@Slf4j
@RestController
public class HelloController {

    @GetMapping("/")
    public String hello() {
        String podName = System.getenv("HOSTNAME");
        if (podName == null || podName.isEmpty()) {
            try {
                podName = java.net.InetAddress.getLocalHost().getHostName();
            } catch (java.net.UnknownHostException e) {
                podName = "unknown";
            }
        }
        log.info("Hello from Spring Boot on Hybrid K8s!!! (Running on " + podName + ")"); /* log 추가 */
        return "Hello from Spring Boot on Hybrid K8s!!! (Running on " + podName + ")";
    }
}

 

최종 프로젝트 구조는 아래와 같습니다.

 

3. 빌드

일반적인 환경에서는 docker build ..., docker push ... 으로 진행하면 되지만

본 글에서 이용하는 쿠버네티스 클러스터는 멀티 아키텍처 (amd54, arm64) 이기 때문에 빌드와 배포를 동시에 하도록 합니다.

참고 : 쿠버네티스 클러스터 #5 Spring boot 어플리케이션 배포 챕터의 2. 빌드 항목을 참고 하세요.

 

도커가 push 명령으로 배포할 컨텍스트를 선택합니다.

PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi> kubectl config get-contexts
CURRENT   NAME                          CLUSTER          AUTHINFO           NAMESPACE
          docker-desktop                docker-desktop   docker-desktop     
*         kubernetes-admin@kubernetes   kubernetes       kubernetes-admin

kubernetes-admin@kubernetes 로 잘 선택(*)되어 있습니다.

 

멀티 아키텍처 환경이므로 buildx 엔진을 이용해서 linux/amd64, linux/arm64 를 각각 빌드하고 push까지 한번에 해야 합니다.

PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi> docker buildx build --platform linux/amd64,linux/arm64 -t basscraft/hello-kubernetes-api:latest --push .

 

 

4. 배포

위에서 수정한 deployment.yaml 파일을 이용해 배포합니다.

PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi> kubectl apply -f deployment.yaml
deployment.apps/hello-kubernetes-api configured
service/hello-kubernetes-api-service unchanged
PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi>

 

이후 기존 pod를 삭제 합니다.

PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi> kubectl delete pod -l app=hello-kubernetes-api
pod "hello-kubernetes-api-78dd74b6cd-xzrtw" deleted from default namespace
pod "hello-kubernetes-api-989745789-fk6kj" deleted from default namespace
PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi>

기존 pod를 삭제하는 이유는 어플리케이션 재시작과 같은 개념으로 생각하시면 됩니다. pod를 삭제하면, kubelet 프로세스가  이를 감지하고 containerd를 통해 새로운 이미지를 다시 내려받아서 pod를 가동하게 됩니다.

 

실제 운영 에서는 강제 종료 보다는 graceful 하는 것이 더 안전합니다.

$ kubectl rollout restart deployment hello-kubernetes-api

이 방식은 서비스를 중단시키지 않고 하나씩 새로운 pod를 띄우고 기존 pod를 죽이는 rollout 방식입니다.

 

서비스가 모두 잘 살아났는지 확인하고 svc 명령으로 실행되는 포트번호를 확인합니다.

PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi> kubectl get pods -o wide
NAME                                   READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
hello-kubernetes-api-989745789-7ptxq   1/1     Running   0          22m   10.244.1.40   node1   <none>           <none>
hello-kubernetes-api-989745789-gw8mr   1/1     Running   0          51m   10.244.3.26   node2   <none>           <none>
hello-kubernetes-api-989745789-q7rrj   1/1     Running   0          22m   10.244.2.46   node3   <none>           <none>
nginx-bf5d5cf98-pxjh7                  1/1     Running   0          22h   10.244.1.38   node1   <none>           <none>
nginx-bf5d5cf98-qwlwj                  1/1     Running   0          22h   10.244.2.44   node3   <none>           <none>
nginx-bf5d5cf98-v547z                  1/1     Running   0          22h   10.244.3.23   node2   <none>           <none>
PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi> kubectl get svc                              
NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
hello-kubernetes-api-service   NodePort    10.105.75.244    <none>        80:32311/TCP   2d
kubernetes                     ClusterIP   10.96.0.1        <none>        443/TCP        3d22h
nginx                          NodePort    10.102.162.252   <none>        80:31098/TCP   3d21h
PS C:\Users\user\Projects\k8sTest\HelloKubernates\api\HelloKubernetesApi>

 

포트 번호를 확인하고 브라우저에서 각 노드별로 잘 실행 되는지 확인합니다.

http://192.168.2.101:32311

http://192.168.2.102:32311

http://192.168.2.103:32311

 

5. 로그 확인

각 노드에 SSH로 접속해서 /var/log/hello-k8s/app.log 가 존재하는지 spring boot 에서 남기는 로그가 잘 남는지 확인합니다.

basscraft@node3:~$ cd /var/log
basscraft@node3:/var/log$ ls -al
README            auth.log               cloud-init.log  dmesg.0     dmesg.4.gz  journal    pods     ubuntu-advantage-apt-hook.log
alternatives.log  bootstrap.log          containers      dmesg.1.gz  dpkg.log    kern.log   private  ufw.log
apport.log        btmp                   dist-upgrade    dmesg.2.gz  faillog     landscape  syslog   unattended-upgrades
apt               cloud-init-output.log  dmesg           dmesg.3.gz  hello-k8s   lastlog    sysstat  wtmp
bbasscraft@node3:/var/log$ cd hello-k8s/
basscraft@node3:/var/log/hello-k8s$ dir
app.log
basscraft@node3:/var/log/hello-k8s$ tail -f app.log
2026-01-21 12:01:51.345 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.a.catalina.core.StandardService - Starting service [Tomcat]
2026-01-21 12:01:51.346 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/11.0.15]
2026-01-21 12:01:51.419 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.s.b.w.c.s.WebApplicationContextInitializer - Root WebApplicationContext: initialization completed in 2167 ms
2026-01-21 12:01:52.219 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
2026-01-21 12:01:52.255 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.s.boot.tomcat.TomcatWebServer - Tomcat started on port 8080 (http) with context path '/'
2026-01-21 12:01:52.283 [main] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] g.h.api.HelloKubernetesApplication - Started HelloKubernetesApplication in 4.726 seconds (process running for 5.764)
2026-01-21 12:05:21.898 [http-nio-8080-exec-1] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-01-21 12:05:21.899 [http-nio-8080-exec-1] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2026-01-21 12:05:21.903 [http-nio-8080-exec-1] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] o.s.web.servlet.DispatcherServlet - Completed initialization in 4 ms
2026-01-21 12:05:21.953 [http-nio-8080-exec-1] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-q7rrj)
2026-01-21 12:05:41.249 [http-nio-8080-exec-2] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-q7rrj)
2026-01-21 12:05:42.058 [http-nio-8080-exec-3] [INFO ] [node3:hello-kubernetes-api-989745789-q7rrj] g.h.api.controller.HelloController - Hello from Spring Boot on Hybrid K8s!!! (Running on hello-kubernetes-api-989745789-q7rrj)

 

정상적으로 로그가 남고 있습니다.

 

주의.

실무에서 로그를 외부에 영구 저장하는 경우 반드시 일자별 롤링이 잘 되는지, 오래 지난 로그는 운영 정책을 세워서 압축 또는 별도의 백업 공간에 보관해야 합니다.

위 logback 설정에서 30후게 삭제 되도록 했지만, 실제로 30일 후에 삭제 되는지 확해야 합니다.

관리를 하지 않는경우 물리적 디스크 용량이 부족해서 서비스에 문제가 생기는 경우가 생각보다 자주 있습니다.

 

추천하는 방법

Logrotate 같은 프로그램을 설치하고 쉘 스크립트로 아래 같은 룰을 정해서 관리 하도록 작성 해 놓으면 편리합니다.

  • 현재일자 -n 일 까지의 로그 : 압축후 원본 삭제
  • 현재일자 -n 개월 까지의 로그 : 별도의 디스크에 소산 보관

끝.

+ Recent posts