SMALL

일반적인 환경에서 Spring Boot Application을 띄우는 경우 이외에,

Kubernetes 환경에 Spring Boot Application을 띄우는 경우에 해당 Application에 대한 정보를 모니터링하고 싶은 경우에 사용하는 방법을 알아보도록 하자.

 

아래와 같은 목차로 설명하도록 하겠다.

  • Kubernetes 환경 리소스 생성
  • SpringBootAppliation 설정 ( Server, Client)
  • Dockerimage 생성
  • Kubernetes ( Deployment, Service ) 생성

 

출처 : https://youtu.be/Ql1Gnz4L_-c?t=1500

Kubernetes 환경 리소스 생성

먼저 Spring Boot Admin의 Server에서 Kubernetes관련 정보를 수집할 수 있는 권한이 필요하다.

이에 해당하는 Role, ServiceAccount, RoleBinding 관련 리소스를 생성해보자.

 

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: {user_ns}
  name: admin
rules:
  - apiGroups: ["", "extensions", "apps"]
    resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
    verbs: ["get", "list", "watch"]

 

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin

 

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: admin
  namespace: {user_ns}
subjects:
- kind: ServiceAccount
  name: admin
  apiGroup: ""
roleRef:
  kind: Role
  name: admin
  apiGroup: ""

해당 리소스들의 관계는 Kubernetes 리소스 관련 control을 할 수 있는 Role (권한)이 있고,

해당 권한과 ServiceAccount를 Binding해주는 RoleBinding이 있다.

RoleBinding을 통해서 특정 ServiceAccount는 Kubernetes 리소스를 control 하는 Role을 가지게 된다.

추후에 Kubernetes Deployment를 생성할때 해당 ServiceAccount 정보를 기입하면 해당 Deployment는 Role을 가질 수 있게 된다. 

 

SpringBootAppliation 설정 (Server)

 

pom.xml ( dependency 설정 ) 

		<dependency>
			<groupId>de.codecentric</groupId>
			<artifactId>spring-boot-admin-starter-server</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-kubernetes</artifactId>
		</dependency>

 

application.yml( spring boot 설정 )

spring:
  cloud:
    kubernetes:
      discovery:
        service-labels:
          type: spring-boot #해당 label이 붙은 k8s 리소스만의 정보만 조회 가능
  boot:
    admin:
      monitor:
        status-interval: 3s
        status-lifetime: 3s

 

Spring Main Application 

@SpringBootApplication
@EnableAdminServer
@EnableScheduling
@EnableDiscoveryClient // !!
public class SbaK8sServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(SbaK8sServerApplication.class, args);
	}

}

 

SpringBootAppliation 설정 (Client)

 

pom.xml ( dependency 설정 ) 

		<dependency>
			<groupId>de.codecentric</groupId>
			<artifactId>spring-boot-admin-starter-client</artifactId>
		</dependency>

 

application.yml( spring boot 설정 )

server:
  port: 8082

management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always

 

Dockerimage 생성

Kubernetes에 Pod를 띄우기 위해서는 Dockerimage를 생성하여 Deployment에 해당 정보를 넣어주어야한다.

여기서는 자세하게 다루지 않고, 생성하기 위한 명령어들만 간단하게 공유하도록 하겠다.

 # client
 docker build -t sba-client:v1 ./
 docker push sba-client:v1
 # server
 docker build -t sba-server:v1 ./
 docker push sba-server:v1

 

Kubernetes  Spring Boot Admin Server( Deployment, Service ) 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: {user_ns}
  name: admin-pod
  labels:
    type: spring-boot
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: admin
    spec:
      serviceAccountName: admin
      containers:
        - image: {sba-server_image_name}
          name: admin
          env:
            - name: management.endpoints.web.exposure.include
              value: "*"
            - name: management.endpoint.health.show-details
              value: "always"
          ports:
            - containerPort: 8080
          resources: {}
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: 8080
            initialDelaySeconds: 10
            timeoutSeconds: 2
            periodSeconds: 5
            failureThreshold: 5
          livenessProbe:
            httpGet:
              path: /actuator/health
              port: 8080
            initialDelaySeconds: 20
            timeoutSeconds: 2
            periodSeconds: 8
            failureThreshold: 5
      restartPolicy: Always
  selector:
    matchLabels:
      app: admin

 

apiVersion: v1
kind: Service
metadata:
  namespace: {user_ns}
  name: admin-service
  labels:
    type: spring-boot
spec:
  type: NodePort
  ports:
    - name: "http"
      port: 8080
      targetPort: 8080
  selector:
    app: admin

 

Kubernetes Client ( Deployment, Service ) 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: {user_ns}
  name: {user_pod_name}
  labels:
    type: spring-boot
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: {user_pod_name}
    spec:
      containers:
        - image: {user_image_name}
          name: {user_pod_name}
          env:
            - name: management.endpoints.web.exposure.include
              value: "*"
            - name: management.endpoint.health.show-details
              value: "always"
          ports:
            - containerPort: 8082
          resources: {}
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: 8082
            initialDelaySeconds: 10
            timeoutSeconds: 2
            periodSeconds: 5
            failureThreshold: 5
          livenessProbe:
            httpGet:
              path: /actuator/health
              port: 8082
            initialDelaySeconds: 20
            timeoutSeconds: 2
            periodSeconds: 8
            failureThreshold: 5
      restartPolicy: Always
  selector:
    matchLabels:
      app: {user_pod_name}

Service에 대한 내용은 Spring Boot Admin Server와 동일하다. ( port 정보만 중복되지 않도록 바꾸어주면 된다)

 

이번 포스팅의 내용을 대략적으로 보면 기본적으로 Kubernetes의 리소스를 사용하기 위한 설정이 대부분이었던 것 같다.

핵심으로는 Kubernetes환경에서 Spring Boot Admin을 사용하기 위해서 해야 하는 Application에 설정해야 하는 부분에 집중하면 될 것 같다. 

(Server에서 Client를 찾을 수 있도록 Applicaiton에 설정을 추가해주는 부분)

LIST
SMALL

Kubernetes는 구글에서 공개한 리눅스 컨테이너 관리 시스템 (Docker Orchestrator)

 

kubernetes cluster를 설치하기 위해서는 우선 두 개 이상의 환경이 필요하다. 

각각의 환경에는 ubuntu가 깔려있는 경우에 설명을 진행하도록 하겠다. (18.04_x64이상의 버전이어야 가능한 것으로 알고 있다) 

  • Master
  • Worker ( 1개 이상)

 

3가지의 part로 나누어 설명하도록 하겠다

  • Master, Worker 모두에 해당되는 부분

  • Master에만 해당되는 부분

  • Worker에만 해당되는 부분


Master, Worker 모두에 해당되는 부분

패키지를 최신화, ssh를 설치, reboot 

  • sudo apt-get update
  • sudo apt-get upgrade -y
  • sudo apt-get install ssh -y
  • Reboot

( root 계정에서 명령어를 수행하는 경우에는 sudo를 생략가능)

( apt-get(Advanced Packaging Tool)은 우분투(Ubuntu)를 포함한 데비안(Debian) 계열의 리눅스에서 쓰이는 패키지 관리 명령어 도구 )

( update는 설치된 패키지의 최신 버전이 있는지 확인, upgrade는 최신 버전으로 업그레이드 수행) 

 

 

Docker 설치 (Docker-CE :Community Edition)

(개인 개발자나 작은 팀이 도커를 시작할 때나 컨테이너 기반의 앱들을 실험할 때 적합)

  • sudo apt-get install apt-transport-https ca-certificates curl software-properties-common -y
  • curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  • sudo apt-key fingerprint 0EBFCD88
  • sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  • sudo apt-get update
  • sudo apt-get install docker-ce -y
  • systemctl enable docker.service

모든 명령어를 수행한 이후에 systemctl status docker 명령으로 active(runnning) 상태인지 확인

 

Kubernetes 설치

( swapoff 가상 메모리 사용을 비활성화하는 옵션) (kubernetes에서는 가상 메모리 사용 비활성화가 필수라 한다) 

모든 명령어를 수행한 이후에 kubectl version 명령어를 통해 설치 버전이 확인 가능하다.


Master에만 해당되는 부분

Docker Registry 구축

Docker Image 저장소를 Master노드에 구축

위에서는 docker를 설치했고, 이를 바탕으로 docker image들이 저장되는 registry를 구축해야 한다. 

  • sudo docker pull registry:latest
  • sudo docker run --name registry -d -p 5000:5000 --restart=always registry
  • /etc/docker 경로에 daemon.json 파일 생성하여 아래 내용 추가
    • { "insecure-registries":["<master-node-IP>:5000"] }
  • systemctl restart docker

모든 명령어를 수행한 이후에 curl -X GET http://<master-node-IP>:5000/v2/_catalog 명령어를 통해 registry가 정상 설치되었는지 확인

 

Kubernetes Cluster 생성

  • kubeadm init --apiserver-advertise-address <master-node-IP> 

설치하는데 몇 분 정도 걸린다.

설치가 완료되면 위와 같은 로그가 발생한다. 

  • 초록색 상자에 해당하는 명령어를 수행해주어야 한다
    • mkdir –p $HOME/.kube
    • sudo cp –I /etc/kubernetes/admin.conf $HOME/.kube/config
    • sudo chown $(id –u):$(id –g) $HOME/.kube/config
    • export KUBECONFIG=$HOME/.kube/config (환경변수 설정) 
  • 파란색 상자에 해당하는 부분은 따로 저장해 놓는다 (나중에 Worker에서 join 할 때 필요한 명령어이다) 

kubectl get node와 kubectl get pod --all-namespaces -o wide 명령으로 node 및 pod의 정상 동작을 확인합니다.

node : NotReady

pod : 네트워크 설치 전이므로 coredns pod Pending

총 5개의 pod가 정상적으로 Runing 된 부분을 확인 후 다음 스탭 진행 (기다리는데 시간이 꽤 걸렸던 걸로 기억) 

 

Kubernetes CNI 설치

CNI는 Master와 Work node의 네트워크 내부 통신을 위한 네트워크 인터페이스

kubectl get node와 kubectl get pod --all-namespaces -o wide 명령으로 node 및 pod의 정상 동작을 확인합니다.

위에서 pending상태였던 coredns pod가 Running으로 상태가 바뀌고 Node의 상태도 ready이어야 한다.

(기다리는데 시간이 꽤 걸렸던 걸로 기억) 


Worker에만 해당되는 부분

Kubernetes Cluster Join

Worker 노드들을 Kubernetes Cluster에 join 합니다. 

Master노드에서 저장한 join 명령을 Worker에서 수행합니다. 

  • kubeadm join <master-node-IP>:6443 --token (...생략...) ...26e623138a

명령어를 수행한 이후에 Master 노드에서 kubectl get nodes 명령을 수행하여 Worker 노드가 join 됨을 확인합니다.

 

 

설치 완료! 

 

LIST

+ Recent posts