ArgoCD, Grafana KeyCloak 로그인 연동하기

dongdorrong·2024년 6월 29일
0

Kubernetes

목록 보기
5/5

Grafana와 ArgoCD를 배포해서 사용 중인데 개별로 사용자 관리를 하는 것이 불필요하다고 생각이 들었습니다.
점점 회사에 사람들이 많아지는 중이고, 그럴 때마다 각각 관리를 하는 건 매우 비효율적이라고 판단했습니다.
마침 KeyCloak으로 kube-apiserver에 대한 접근 제어를 사용하고 있었는데,
비슷한 방식으로 애드온에 대한 계정 관리도 가능하지 않을까 싶었습니다.
마침 구글링을 해보니 몇 가지 사례들이 있었고, 제가 운영하는 리소스에도 적용하면서 그 과정을 정리해보려고 합니다.

ArgoCD

1. KeyCloak 재설치

먼저 ArgoCD 구성을 변경하기에 앞서서 KeyCloak 재설치를 먼저 진행했습니다.
ArgoCD OIDC 설정 중에 logoutURL이라는 속성을 추가할 수 있는데, ArgoCD에서 로그아웃 하면 KeyCloak에서도 세션이 끊어지게 되도록 설정할 수 있습니다.
KeyCloak에서 로그아웃 동작을 수행할 수 있는 REST API 명세에 맞게 logoutURL을 작성해야 하는데, 기존에 사용 중이었던 KeyCloak의 버전은 17.0.1-legacy이라 버전이 너무 낮아 적절한 REST API 값을 맞춰 넣는 것이 힘들었습니다.

~ helm search repo keycloak
NAME                    CHART VERSION   APP VERSION     DESCRIPTION                                       
bitnami/keycloak        21.4.4          24.0.5          Keycloak is a high performance Java-based ident...
codecentric/keycloak    18.4.4          17.0.1-legacy   Open Source Identity and Access Management For ...
codecentric/keycloakx   2.3.0           22.0.4          Keycloak.X - Open Source Identity and Access Ma...

codecentric에서 제공하는 keycloak 헬름 차트를 쓰고 있었는데, 이번에 bitnami keycloak 차트를 사용해서 24.0.5 버전으로 재설치하게 되었습니다.

2. ArgoCD OIDC 적용

공식 문서를 참고하면 대부분의 설정을 하실 수 있는데, 저는 ArgoCD를 Helm Chart로 배포했기 때문에 Configuring ArgoCD OIDC 부분에서 사용한 것과 같이 직접 Configmap과 Secret을 수정하는 방식이 아닌, values.yaml에 속성을 수정해서 재배포 했습니다.

...
...
configs:
  cm:
    url: https://argocd.example.com
    oidc.config: |
      name: Keycloak
      issuer: https://keycloak.exmaple.com/realms/exmaple
      clientID: example
      clientSecret: $oidc.keycloak.clientSecret
      requestedScopes: ["openid", "profile", "email", "groups"]
      logoutURL: https://keycloak.example.com/realms/example/protocol/openid-connect/logout?id_token_hint={{token}}&post_logout_redirect_uri=https://argocd.example.com
...
...
  secret:
    extra:
      oidc.keycloak.clientSecret: ********************************
...
...
  rbac:
    policy.csv: |
      g, argocd-admin, role:admin
      g, argocd-member, role:readonly
...
...
  • example이라고 대체한 키워드에는 운영하시는 조건에 맞는 도메인과 realm, client로 수정해 주셔야 합니다.
  • configs.secret.extra.oidc.keycloak.clientSecret에 적혀있는 ******************************** 대신 KeyCloak 콘솔 내부에서 Client의 Credentials 탭에서 client secret을 생성하고 대입하면 됩니다.
  • configs.rbac.policy.csv은 ArgoCD 운영 정책에 맞게 KeyCloak에서 그룹을 생성하고, 해당 그룹에 맞게 권한을 부여해 주시면 됩니다. 제 경우에는 ArgoCD의 admin 권한을 갖는 argocd-admin 그룹과, readonly 권한을 갖는 argocd-member 그룹을 KeyCloak에서 생성했습니다.
  • logoutURL을 적용하지 않을 경우, ArgoCD에서 로그아웃을 하더라도 KeyCloak에서 세션이 유지되고 있기 때문에 다시 로그인할 수 있기는 합니다. 이 부분은 KeyCloak에서 세션 유지 시간을 어떻게 가져가시는지에 따라 다를 수 있을 것 같습니다.

Grafana

Grafana Labs 공식 문서에 가이드가 잘 나와있어서 참고를 했고 내용에 따라 진행하면 대부분의 설정은 진행할 수 있지만 몇 가지 특이점이 있어서 내용을 작성했습니다.

auth.generic_oauth

가이드를 참고해서 values.yaml을 수정하고 배포했더니 오류가 발생했습니다.

Sensitive key 'auth.generic_oauth.client_secret' should not be defined explicitly in values. Use variable expansion instead. You can disable this client-side validation by changing the value of assertNoLeakedSecrets.

grafana 차트의 helper를 사펴보니 아래와 같은 코멘트를 볼 수 있었습니다.
values.yaml에 평문으로 데이터를 넣지 못하게 막혀 있었습니다.

...
...
{{/*
    Checks whether the user is attempting to store secrets in plaintext
    in the grafana.ini configmap
*/}}
{{/* grafana.assertNoLeakedSecrets checks for sensitive keys in values */}}
...
...

구글링을 해보니 환경 변수로 처리가 가능해서 values.yaml을 수정해서 배포했습니다.

# kube-prometheus-stack/values.yaml
...
...
# 오류 발생
grafana:
  grafana.ini:
    auth.generic_oauth:
      enabled: true
      name: Keycloak
      allow_sign_up: true
      client_id: grafana-client
      client_secret: ********************************
      scopes: openid email profile offline_access roles
      email_attribute_path: email
      login_attribute_path: username
      name_attribute_path: full_name
      auth_url: https://keycloak.example.com/realms/example/protocol/openid-connect/auth
      token_url: https://keycloak.exmaple.com/realms/example/protocol/openid-connect/token
      api_url: https://keycloak.example.com/realms/example/protocol/openid-connect/userinfo
      role_attribute_path: contains(roles[*], 'admin') && 'Admin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer'
      signout_redirect_url: https://keycloak.example.com/realms/example/protocol/openid-connect/logout?post_logout_redirect_uri=https%3A%2F%2Fhttps://grafana.example.com%2Flogin
...
...

# 개선
...
...
grafana:
  env:
    GF_SERVER_DOMAIN: "https://grafana.example.com"
    GF_SERVER_ROOT_URL: "https://grafana.example.com"
    GF_AUTH_GENERIC_OAUTH_ENABLED: "true"
    GF_AUTH_GENERIC_OAUTH_NAME: "Keycloak"
    GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP: "true"
    GF_AUTH_GENERIC_OAUTH_CLIENT_ID: "grafana-client"
    GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: "********************************"
    GF_AUTH_GENERIC_OAUTH_SCOPES: "openid email profile offline_access roles"
    GF_AUTH_GENERIC_OAUTH_AUTH_URL: "https://keycloak.example.com/realms/example/protocol/openid-connect/auth"
    GF_AUTH_GENERIC_OAUTH_TOKEN_URL: "https://keycloak.example.com/realms/example/protocol/openid-connect/token"
    GF_AUTH_GENERIC_OAUTH_API_URL: "https://keycloak.example.com/realms/example/protocol/openid-connect/userinfo"
    GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH: "contains(roles[*], 'admin') && 'Admin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer'"
    GF_AUTH_SIGNOUT_REDIRECT_URL: 'https://keycloak.example.com/realms/example/protocol/openid-connect/logout?post_logout_redirect_uri=https://grafana.example.com/login&client_id=grafana-client'
...
...

signout_redirect_url

ArgoCD와 마찬가지로 로그아웃을 하면 KeyCloak의 세션도 끊어지도록 설정하고 싶었습니다.
Grafana 변수에도 GF_AUTH_SIGNOUT_REDIRECT_URL에 대해 적용을 했는데 KeyCloak 세션이 끊어지지 않는 문제가 있었는데요.
Grafana에 대한 Client 설정을 할 때, Valid post logout redirect URIs를 적용해주었더니 해결되었습니다.

Client scopes

공식 문서만 참고해서 연동하게 되면 모든 사용자에게 Viewer 권한이 할당되는 것을 볼 수 있었습니다.

여러 가지 방법을 시도해 보면서 제가 해결한 방법은 Dedicated scopes에 'roles'라는 객체를 새로 추가하고, 모든 옵션을 활성화시켜주었더니 사용자에게 적절한 권한이 할당되었습니다.

레퍼런스

https://honglab.tistory.com/265#fromHistory
https://kmaster.tistory.com/77
https://ksr930.tistory.com/277
https://enginnersnack.tistory.com/16

profile
DevOps 엔지니어 / 열심히 해서 잘하자

2개의 댓글

comment-user-thumbnail
2024년 10월 31일

안녕하세요. 글 잘 읽었습니다.
혹시 argoCD에서 로그아웃해도 grafana에서 로그아웃 잘 이루어지시나요?

1개의 답글