keycloak 관련 내용이긴한데, 이미지가 keycloak일 뿐 k8s 공부라서 해당 카테고리에 적는다.
keycloak을 k8s로 실행하기 위한 내용들은 아래 링크에서 참고했다.
https://engineering.vendavo.com/keycloak-deployment-with-distributed-cache-43f72995674d
23년 8월 글인데, 벌써 keycloak에서는 이런 점들을 업데이트하고 k8s 환경에서 실행할 수 있도록 가이드를 바꿔놨다. 아래 글들은 k8s를 keycloak을 통해서 공부하는데에만 참고하고, 실제 keycloak의 k8s에서의 실행은 아래 문서를 참고하도록 한다.
https://www.keycloak.org/getting-started/getting-started-kube
1. minikube 설치
아래 링크에서 설치할 수 있다.
https://minikube.sigs.k8s.io/docs/start/?arch=%2Fmacos%2Farm64%2Fstable%2Fbinary+download
설치 자체는
brew install minikube
라고만 하면 되는데, k8s와 관련된 내용들이 문서로 잘 정리되어 있어서 링크에 직접 들어가서 잠깐 읽어보면 좋다. 잘 쓴 글이라 잘 이해된다.
minikube는 k8s 테스트를 위해 로컬환경에서 실행하는 VM이라고 생각하면 된다.
minikube를 실행해본다.
minikube start
2. 이미지 만들기
그리고 나서 이 내부에 이미지를 빌드해야한다. 참고 문서에 보면, infinispan이 네트워크상의 다른 keycloak/infinispan 인스턴스들을 조회하기 위해서 JGroups 라이브러리를 사용하는데 Keycloak의 기본 Docker image는 k8s 환경에서의 JGroup provider를 제공하지 않기 때문에 jgroup-k8s를 포함한 자체적인 이미지를 빌드해서 사용해야한다고 한다.
다음과 같은 스크립트 파일을 만들고 실행한다.
#!/bin/bash
JGROUPS_KUBERNETES_VERSION=2.0.1.Final
curl -L -o jgroups-kubernetes-$JGROUPS_KUBERNETES_VERSION.jar \
https://repo1.maven.org/maven2/org/jgroups/kubernetes/jgroups-kubernetes/$JGROUPS_KUBERNETES_VERSION/jgroups-kubernetes-$JGROUPS_KUBERNETES_VERSION.jar
그럼 jgroups-kubernetes-2.0.1.Final.jar 파일이 생성된다. 이후 아래와 같은 multi stage Dockerfile을 만든다.
FROM quay.io/keycloak/keycloak:21.1.2 as builder
ENV JGROUPS_KUBERNETES_VERSION 2.0.1.Final
COPY jgroups-kubernetes-$JGROUPS_KUBERNETES_VERSION.jar /opt/keycloak/providers/
COPY cache-ispn.xml /opt/keycloak/conf/cache-ispn.xml
RUN /opt/keycloak/bin/kc.sh build
FROM quay.io/keycloak/keycloak:21.1.2
COPY --from=builder /opt/keycloak/ /opt/keycloak/
WORKDIR /opt/keycloak
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]
여기서 infinispan을 위한 cache-ispn.xml 파일을 providers/ 디렉토리에 COPY 해주는 것을 확인할 수 있다. 이 파일에 jgroups 관련 내용을 작성하여 쿠버네티스가 label을 통해 다른 pod들을 네트워크상에서 찾을 수 있도록 해주어야한다. 다음과 같이 cache-ispn.xml 파일을 작성한다.
<jgroups xmlns="http://jgroups.org/schema/jgroups-4.2.xsd">
<stack name="tcp-k8s" extends="tcp">
<org.jgroups.protocols.kubernetes.KUBE_PING
port_range="1"
namespace="${kubeping_namespace:default}"
labels="${kubeping_label:app.kubernetes.io/name=keycloak}"
stack.position="MPING"
stack.combine="REPLACE"
/>
</stack>
</jgroups>
그리고 로컬의 docker image와 minikube 환경에서의 docker image는 다르다. 따라서 아래와 같이 명령어를 입력하여 minikube의 현재 쉘 세션을 minikube의 docker 환경으로 전환해야한다. 그리고 나서 이미지를 빌드한다.
eval $(minikube docker-env)
docker build . -t keycloak:jgroup-k8s
3. deployment 파일 작성
이미지를 기반으로 pod을 여러 개 띄우기 위해서 다음과 같은 deployment 파일을 작성한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
labels:
app: keycloak
spec:
replicas: 3 # 세 개의 Pod 생성
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: keycloak:jgroup-k8s
ports:
- containerPort: 8080
env:
- name: KEYCLOAK_USER
value: "admin" # 관리자 사용자 설정
- name: KEYCLOAK_PASSWORD
value: "admin" # 관리자 비밀번호 설정
- name: DB_VENDOR
value: "h2" # 내장 H2 데이터베이스 사용 (생산 환경에서는 별도의 DB 사용 권장)
command:
- "/opt/keycloak/bin/kc.sh"
- "start-dev"
deployment를 반영하기 위해 kubectl을 사용한다. kubectl은 쿠버네티스용 CLI 도구 명령어이며, ctl은 controller의 약자이다.
kubectl apply -f keycloak-deployment.yaml
4. service 파일 작성
service는 minikube에서 실행 중인 pod 집합에 대해 접근하기 위해 정적 IP 주소를 제공해준다. Pod의 라이프사이클에 상관없이 pod이 재시작 또는 재생성되더라도 항상 동일한 IP로 외부에서 접근할 수 있도록 해준다. 다음과 같이 service 파일을 작성한다.
apiVersion: v1
kind: Service
metadata:
name: keycloak-service
spec:
selector:
app: keycloak
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
그리고 서비스를 실행한다.
minikube service keycloak-service
다음과 같이 localhost의 특정 포트가 keycloak pod 3개를 위한 loadBalancer 주소로 연결된 것을 확인할 수 있다.
5. 확인
kubectl get pods
pod들의 정보를 확인해보면 실행되는 pod들이 있는 것을 볼 수 있다.
'Programming-[Infra] > Kubernetes' 카테고리의 다른 글
쿠버네티스 인 액션: ch5. 서비스 (0) | 2024.11.22 |
---|---|
쿠버네티스 인 액션: ch4. 레플리케이션과 그 밖의 컨트롤러: 관리되는 파드 배포 (1) | 2024.11.21 |
쿠버네티스 인 액션: ch3. 파드: 쿠버네티스에서 컨테이너 실행 (0) | 2024.11.20 |
쿠버네티스 인 액션: ch2. 도커와 쿠버네티스 소개 (2) | 2024.11.18 |
[작성중] keycloak k8s 배포 (0) | 2024.10.23 |