1 - 예제: Java 마이크로서비스 구성하기

1.1 - MicroProfile, 컨피그맵(ConfigMaps) 및 시크릿(Secrets)을 사용하여 구성 외부화(externalizing)

이 튜토리얼에서는 마이크로서비스의 구성을 외부화하는 방법과 이유를 알아본다. 특히, 쿠버네티스 컨피그맵과 시크릿을 사용하여 환경 변수를 설정한 다음 MicroProfile Config를 이용한 사용 방법을 배운다.

시작하기 전에

쿠버네티스 컨피그맵 및 시크릿 생성하기

쿠버네티스에서 도커 컨테이너에 대한 환경 변수를 설정하는 방법에는 Dockerfile, kubernetes.yml, 쿠버네티스 컨피그맵 및 쿠버네티스 시크릿이 있다. 이 튜토리얼에서는 사용자의 마이크로서비스에 값을 주입하기 위한 환경 변수를 설정하기 위해 후자의 두 가지를 사용하는 방법에 대해 배운다. 컨피그맵 및 시크릿을 사용할 때의 이점 중 하나는 여러 다른 컨테이너에 대해 서로 다른 환경 변수에 할당되는 것을 포함하여, 여러 컨테이너에서 다시 사용할 수 있다는 것이다.

컨피그맵은 기밀이 아닌 키-값 쌍을 저장하는 API 오브젝트이다. 대화형 튜토리얼에서는 컨피그맵을 사용하여 애플리케이션의 이름을 저장하는 방법을 배운다. 컨피그맵에 대한 자세한 정보는 여기에서 문서를 찾을 수 있다.

시크릿은 키-값 쌍을 저장하는 데도 사용되지만, 기밀/민감한 정보를 위한 것이며 Base64 인코딩을 사용하여 저장된다는 점에서 컨피그맵과 다르다. 따라서 시크릿은 자격 증명, 키 및 토큰과 같은 항목을 저장하는 데 적합한 선택이 된다. 이 내용은 대화형 튜토리얼에서 수행할 것이다. 시크릿에 대한 자세한 내용은 여기에서 문서를 찾을 수 있다.

코드로부터 구성 외부화

구성은 일반적으로 환경에 따라 변경되기 때문에, 외부화된 애플리케이션 구성(externalized application configuration)은 유용하다. 이를 이루기 위해, Java의 CDI(콘텍스트와 의존성 주입) 및 MicroProfile Config를 사용한다. MicroProfile Config는 클라우드 네이티브 마이크로서비스를 개발하고 배포하기 위한 개방형 Java 기술 세트인 MicroProfile의 기능이다.

CDI는 느슨하게 결합된 협업 빈(beans)을 통해 애플리케이션을 어셈블할 수 있는 표준 종속성 주입(standard dependency injection) 기능을 제공한다. MicroProfile Config는 애플리케이션, 런타임 및 환경을 포함한 다양한 소스에서 구성 속성을 가져오는 표준 방법을 앱과 마이크로서비스에 제공한다. 소스의 정의된 우선순위에 따라 속성은 애플리케이션이 API를 통해 접근할 수 있는 단일 속성 집합으로 자동 결합된다. 대화형 튜토리얼에서는 CDI와 MicroProfile을 함께 사용하여 쿠버네티스 컨피그맵 및 시크릿을 통한 외부 제공 속성을 검색하고 애플리케이션 코드에 삽입한다.

많은 오픈 소스 프레임워크와 런타임이 MicroProfile Config를 구현하고 지원한다. 대화형 튜토리얼을 통해 클라우드 네이티브 앱과 마이크로서비스를 빌드하고 실행하기 위한 유연한 오픈 소스 Java 런타임인 Open Liberty를 사용하게 될 것이다. 그러나, 모든 MicroProfile 호환 런타임을 대신 사용할 수 있다.

목적

  • 쿠버네티스 컨피그맵 및 시크릿 생성
  • MicroProfile Config를 사용하여 마이크로서비스 구성 주입

예제: MicroProfile, 컨피그맵 및 시크릿을 사용하여 구성 외부화

대화형 튜토리얼 시작

1.2 - 대화형 튜토리얼 - Java 마이크로서비스 구성하기

터미널 화면을 조작하려면, 데스크톱/태블릿 버전을 사용하기 바란다.

2 - 컨피그맵을 사용해서 Redis 설정하기

이 페이지에서는 컨피그맵(ConfigMap)을 사용해서 Redis를 설정하는 방법에 대한 실세계 예제를 제공하고, 컨피그맵을 사용해서 파드 설정하기 태스크로 빌드를 한다.

목적

  • Redis 설정값으로 컨피그맵을 생성한다.
  • 생성된 컨피그맵을 마운트하고 사용하는 Redis 파드를 생성한다.
  • 설정이 잘 적용되었는지 확인한다.

시작하기 전에

쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.

버전 확인을 위해서, 다음 커맨드를 실행 kubectl version.

실세상 예제: 컨피그맵을 사용해서 Redis 설정하기

아래 단계를 통해서, 컨피그맵에 저장된 데이터를 사용하는 Redis 캐시를 설정한다.

우선, 비어 있는 설정으로 컨피그맵을 생성한다.

cat <<EOF >./example-redis-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: example-redis-config
data:
  redis-config: ""
EOF

위에서 생성한 컨피그맵을 Redis 파드 매니페스트와 함께 적용한다.

kubectl apply -f example-redis-config.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/pods/config/redis-pod.yaml

Redis 파드 매니페스트의 내용을 검토하고 다음의 사항을 염두에 둔다.

  • config 라는 이름의 볼륨은 spec.volumes[1] 에 의해서 생성된다.
  • spec.volumes[1].items[0] 내부의 keypathconfig 볼륨에 redis.conf 라는 파일명으로 지정된 example-redis-config 컨피그맵의 redis-config 키를 노출시킨다.
  • 그리고 config 볼륨은 spec.containers[0].volumeMounts[1] 에 의해서 /redis-master 에 마운트된다.

이 내용은 위의 example-redis-config 컨피그맵의 data.redis-config 내부 데이터를 파드 안에 있는 /redis-master/redis.conf 파일의 내용으로 노출시키는 순효과(net effect)를 낸다.

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis:5.0.4
    command:
      - redis-server
      - "/redis-master/redis.conf"
    env:
    - name: MASTER
      value: "true"
    ports:
    - containerPort: 6379
    resources:
      limits:
        cpu: "0.1"
    volumeMounts:
    - mountPath: /redis-master-data
      name: data
    - mountPath: /redis-master
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        name: example-redis-config
        items:
        - key: redis-config
          path: redis.conf

생성된 오브젝트를 확인한다.

kubectl get pod/redis configmap/example-redis-config

다음의 결과를 볼 수 있다.

NAME        READY   STATUS    RESTARTS   AGE
pod/redis   1/1     Running   0          8s

NAME                             DATA   AGE
configmap/example-redis-config   1      14s

example-redis-config 컨피그맵의 redis-config 키를 공란으로 둔 것을 기억하자.

kubectl describe configmap/example-redis-config

redis-config 키가 비어 있는 것을 확인할 수 있다.

Name:         example-redis-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
redis-config:

kubectl exec 를 사용하여 파드에 접속하고, 현재 설정 확인을 위해서 redis-cli 도구를 실행한다.

kubectl exec -it redis -- redis-cli

maxmemory 를 확인한다.

127.0.0.1:6379> CONFIG GET maxmemory

기본값인 0을 볼 수 있을 것이다.

1) "maxmemory"
2) "0"

유사하게, maxmemory-policy 를 확인한다.

127.0.0.1:6379> CONFIG GET maxmemory-policy

이것도 기본값인 noeviction 을 보여줄 것이다.

1) "maxmemory-policy"
2) "noeviction"

이제 example-redis-config 컨피그맵에 몇 가지 설정값을 추가해 본다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: example-redis-config
data:
  redis-config: |
    maxmemory 2mb
    maxmemory-policy allkeys-lru    

갱신된 컨피그맵을 적용한다.

kubectl apply -f example-redis-config.yaml

컨피그맵이 갱신된 것을 확인한다.

kubectl describe configmap/example-redis-config

방금 추가한 설정값을 확인할 수 있을 것이다.

Name:         example-redis-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
redis-config:
----
maxmemory 2mb
maxmemory-policy allkeys-lru

설정이 적용되었는지 확인하려면, kubectl exec 를 통한 redis-cli 로 Redis 파드를 다시 확인한다.

kubectl exec -it redis -- redis-cli

maxmemory 를 확인한다.

127.0.0.1:6379> CONFIG GET maxmemory

기본값인 0을 볼 수 있을 것이다.

1) "maxmemory"
2) "0"

유사하게, maxmemory-policy 도 기본 설정인 noeviction 을 보여줄 것이다.

127.0.0.1:6379> CONFIG GET maxmemory-policy

위의 명령은 다음을 반환한다.

1) "maxmemory-policy"
2) "noeviction"

파드는 연관된 컨피그맵에서 갱신된 값을 인지하기 위해서 재시작이 필요하므로 해당 설정값이 변경되지 않은 상태이다. 파드를 삭제하고 다시 생성한다.

kubectl delete pod redis
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/pods/config/redis-pod.yaml

이제 마지막으로 설정값을 다시 확인해 본다.

kubectl exec -it redis -- redis-cli

maxmemory 를 확인한다.

127.0.0.1:6379> CONFIG GET maxmemory

이것은 이제 갱신된 값인 2097152를 반환한다.

1) "maxmemory"
2) "2097152"

유사하게, maxmemory-policy 도 갱신되어 있다.

127.0.0.1:6379> CONFIG GET maxmemory-policy

이것은 원하는 값인 allkeys-lru 를 반환한다.

1) "maxmemory-policy"
2) "allkeys-lru"

생성된 자원을 삭제하여 작업을 정리한다.

kubectl delete pod/redis configmap/example-redis-config

다음 내용