ISFJ 개발자의 이야기

Istio Keycloak 인증 연동 본문

Cloud/Kubernetes

Istio Keycloak 인증 연동

ISFJ 개발자의 이야기 2025. 9. 29. 10:54

이번 블로그에서는 Istio에 Keycloak 인증을 연동하는 글을 작성해보려합니다.

아키텍처는 아래와 같이 구성됩니다.

Istio & Keycloak 인증 연동 아키텍처를 구축하기 위해서는 아래의 순서를 따라야합니다.

 

1. EKS Cluster 구성 및 Keycloak 구성

2. Keyclaok 콘솔에서 환경 설정

3. Keyclaok 인증 Deployment 설정

 

EKS Cluster 구성 및 Keycloak 구성

EKS Cluster와 ACM이 생성되어있다는 전제로 진행합니다.

우선 Keycloak 구성을 위해 필요한 환경변수를 설정해줘야합니다.

EKS_CLUSTER_NAME="<CLUSTER_NAME>" # Change Your EKS Cluster Name
ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
CLUSTER_OIDC=$(aws eks describe-cluster --name $EKS_CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | cut -c 9-100)

 

다음으로 EBS CSI Driver를 Keycloak이 사용하기에 구성을 해줍니다.

cat << EOF > aws-ebs-csi-driver-trust-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/OIDC"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "OIDC:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}
EOF

 

sed -i "s|ACCOUNT_ID|$ACCOUNT_ID|g" aws-ebs-csi-driver-trust-policy.json
sed -i "s|OIDC|$CLUSTER_OIDC|g" aws-ebs-csi-driver-trust-policy.json

 

aws iam create-role --role-name AmazonEKS_EBS_CSI_DriverRole --assume-role-policy-document file:///home/ec2-user/aws-ebs-csi-driver-trust-policy.json

 

aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy --role-name AmazonEKS_EBS_CSI_DriverRole

 

eksctl create addon --name aws-ebs-csi-driver --cluster $EKS_CLUSTER_NAME --service-account-role-arn arn:aws:iam::$ACCOUNT_ID:role/AmazonEKS_EBS_CSI_DriverRole --force

 

kubectl patch storageclass gp2 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

 

EBS CSI Driver 구성을 끝마쳤다면 이제 Keycloak을 Helm으로 설치해줘야합니다. 

cat << EOF > values.yaml
auth:
  adminUser: admin
  adminPassword: admin

proxy: edge
EOF

 

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install keycloak -n keycloak bitnami/keycloak --create-namespace -f values.yaml --version 15.1.8

 

다음으로 AWS Load Balancer Controller를 이용해서 Keycloak을 외부로 노출시켜줘야합니다. Helm으로 설치를 진행하겠습니다.

curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.13.0/docs/install/iam_policy.json

 

aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json

 

eksctl create iamserviceaccount \
    --cluster=skills-eks-cluster \
    --namespace=kube-system \
    --name=aws-load-balancer-controller \
    --attach-policy-arn=arn:aws:iam::${ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
    --override-existing-serviceaccounts \
    --region ap-northeast-2 \
    --approve

 

helm repo add eks https://aws.github.io/eks-charts
helm repo update eks
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=$EKS_CLUSTER_NAME \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller

 

다음으로 아래의 ingress 코드를 이용해서 Keycloak을 외부로 노출시켜주면 됩니다. 

서브넷에는 아래의 태그가 있어야합니다.

 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: keycloak-ingress
  namespace: keycloak
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/healthcheck-path: /realms/master
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/certificate-arn: <ACM_ARN>
    alb.ingress.kubernetes.io/ssl-redirect: '443'
    
spec:
  defaultBackend:
    service:
      name: keycloak
      port:
        number: 80

 

Keyclaok 콘솔에서 환경 설정

우선 Realm을 설정해줘야합니다.

 

 

다음으로 Client를 생성해줍니다.

 

 

 

 

  • <IstioDNS>/oauth2/callback

 

다음으로 Identity Providers를 구성해줍니다.

 

 

 

 

아래의 URL을 참고하시면 됩니다.

 

마지막으로 User를 생성해주면 됩니다.

 

 

 

Keyclaok 인증 Deployment 설정

이제 다시 EKS로 돌아와서 아래의 절차를 따라서 구성하면됩니다.

kubectl label namespace default istio-injection=enabled --overwrite

 

kubectl create ns oauth2-proxy

 

아래의 코드를 참고해서 Secret을 구성해줍니다.

apiVersion: v1
kind: Secret
metadata:
  name: oauth2-proxy
  namespace: oauth2-proxy
stringData:
  # change this to your Keycloak Realm Client Id 
  OAUTH2_PROXY_CLIENT_ID: ""
  # change this to your Keycloak Client Secret 
  OAUTH2_PROXY_CLIENT_SECRET: ""
  # Generate by command: openssl rand -base64 32 | tr -- '+/' '-_'
  OAUTH2_PROXY_COOKIE_SECRET: ""

 

다음으로 아래의 코드를 참고해서 인증을 진행하는 OAtuh Proxy Deployment를 생성해줍니다. 도메인은 변경해줘야 합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: oauth2-proxy
  namespace: oauth2-proxy
spec:
  selector:
    matchLabels:
      app: oauth2-proxy
  template:
    metadata:
      labels:
        app: oauth2-proxy
    spec:
      containers:
      - name: oauth2-proxy
        image: quay.io/oauth2-proxy/oauth2-proxy:v7.2.1
        args:
        - --provider=oidc
        - --oidc-issuer-url=https://keycloak-k8s.kro.kr/realms/istio-ingress # Change Here 
        - --profile-url=https://keycloak-k8s.kro.kr/realms/istio-ingress/protocol/openid-connect/userinfo # Change Here
        - --validate-url=https://keycloak-k8s.kro.kr/realms/istio-ingress/protocol/openid-connect/userinfo # Change Here
        - --set-authorization-header=true
        - --http-address=0.0.0.0:4180
        - --pass-host-header=true
        - --reverse-proxy=true
        - --auth-logging=true
        - --cookie-httponly=true
        - --cookie-refresh=4m
        - --cookie-secure=false
        - --email-domain="*"
        - --pass-access-token=true
        - --pass-authorization-header=true
        - --request-logging=true
        - --set-xauthrequest=true
        - --silence-ping-logging=true
        - --skip-provider-button=true
        - --skip-auth-strip-headers=false
        - --ssl-insecure-skip-verify=true
        - --standard-logging=true
        - --upstream="static://200"
        - --whitelist-domain=".keycloak-k8s.kro.kr,.cluster.local" # Change Here
        env:
        - name: OAUTH2_PROXY_CLIENT_ID
          valueFrom:
            secretKeyRef:
              name: oauth2-proxy
              key: OAUTH2_PROXY_CLIENT_ID
        - name: OAUTH2_PROXY_CLIENT_SECRET
          valueFrom:
            secretKeyRef:
              name: oauth2-proxy
              key: OAUTH2_PROXY_CLIENT_SECRET
        - name: OAUTH2_PROXY_COOKIE_SECRET
          valueFrom:
            secretKeyRef:
              name: oauth2-proxy
              key: OAUTH2_PROXY_COOKIE_SECRET
        resources:
          requests:
            cpu: 10m
            memory: 100Mi
        ports:
        - containerPort: 4180
          protocol: TCP
        readinessProbe:
          periodSeconds: 3
          httpGet:
            path: /ping
            port: 4180

 

apiVersion: v1
kind: Service
metadata:
  name: oauth2-proxy
  namespace: oauth2-proxy
spec:
  selector:
    app: oauth2-proxy
  ports:
  - name: http
    port: 4180

 

다음으로 아래의 명령어를 이용해서 Istio를 설치 및 구성 해줍니다.

curl -L https://istio.io/downloadIstio | sh -
cd istio-1.27.0
export PATH=$PWD/bin:$PATH

 

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: oauth2-proxy
  namespace: istio-system
spec:
  profile: default
  meshConfig:
    extensionProviders:
      - name: oauth2-proxy
        envoyExtAuthzHttp:
          service: oauth2-proxy.oauth2-proxy.svc.cluster.local
          port: 4180
          timeout: 1.5s
          includeHeadersInCheck: ["authorization", "cookie"]
          headersToUpstreamOnAllow: ["x-forwarded-access-token", "authorization", "path", "x-auth-request-user", "x-auth-request-email", "x-auth-request-access-token"]
          headersToDownstreamOnDeny: ["content-type", "set-cookie"]
  values:
    gateways:
      istio-ingressgateway:
        serviceAnnotations:
          service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
          service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"

 

 istioctl install -f istio-conf.yaml --skip-confirmation
 # istioctl upgrade -f istio-conf.yaml

 

이제 인증 성공시 접속할 nginx app을 생성해줍니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-app
spec:
  selector:
    app: nginx-app
  ports:
  - port: 80
    targetPort: 80

 

마지막으로 Gateway, VirtualService, AuthorizationPolicy를 생성해줍니다.

apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: nginx-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

 

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: nginx-vs
spec:
  hosts:
  - "*"
  gateways:
  - nginx-gateway
  http:
  - route:
    - destination:
        host: nginx-app
        port:
          number: 80

 

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: nginx-authz
spec:
  selector:
    matchLabels:
      app: nginx-app
  action: CUSTOM
  provider:
    name: oauth2-proxy
  rules:
  - to:
    - operation:
        methods: ["GET","POST"]

 

Result

아래의 사진과 같이 Istio DNS로 접속을 시도 할려고 하면 Keycloak 인증 페이지가 뜨게 됩니다.

 

인증 성공 시 아래의 사진과 같이 nginx 페이지를 볼 수 있습니다.

 

이것으로 Istio & Keycloak 인증 연동 구성 글을 마치겠습니다. 감사합니다!

 

참고

https://malwareanalysis.tistory.com/310

 

istio keycloak 인증 연동 - 작성중단

업무로서 istio를 사용하지 않아서.. 공부를 중단합니다. ㅜ.ㅜ 목차 서비스 메시는 무엇일까?: https://malwareanalysis.tistory.com/280 Istio아키텍처: https://malwareanalysis.tistory.com/304 envoy proxy 체험: https://malwa

malwareanalysis.tistory.com

https://www.keycloak.org/securing-apps/oidc-layers

 

Securing applications and services with OpenID Connect

Use OpenID Connect with Keycloak to secure applications and services.

www.keycloak.org