회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
*KubeCon + Cloud Native North America 2023에서 발표한 <Beyond Passwords: Keycloak's Contributions to IAM(Identity and Access Management) + Security>를 정리한 글입니다. 발표 내용을 3회로 나누어 발행합니다. 1부에서는 키클락에 대한 기능 소개와 이점에 대해 살펴보았습니다. 2부에서는 키클락을 구성하기 위해 실행해야 할 사전 작업을 알아보고, 이번 3부에서는 키클락을 사용하여 EKS, GKE와 같은 관리형 쿠버네티스 클러스터를 통합인증 하여 관리하는 방법에 대해 살펴봅니다. 발표 자료는 KubeCon NA 2023 홈페이지에서 다운받으실 수 있습니다.
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
*KubeCon + Cloud Native North America 2023에서 발표한 <Beyond Passwords: Keycloak's Contributions to IAM(Identity and Access Management) + Security>를 정리한 글입니다. 발표 내용을 3회로 나누어 발행합니다. 1부에서는 키클락에 대한 기능 소개와 이점에 대해 살펴보았습니다. 2부에서는 키클락을 구성하기 위해 실행해야 할 사전 작업을 알아보고, 이번 3부에서는 키클락을 사용하여 EKS, GKE와 같은 관리형 쿠버네티스 클러스터를 통합인증 하여 관리하는 방법에 대해 살펴봅니다. 발표 자료는 KubeCon NA 2023 홈페이지에서 다운받으실 수 있습니다.
1부: 신원확인, 통합인증관리 오픈소스 ‘키클락’을 알아보자
2부: 키클락 구성을 위한 기나긴 사전 작업 한번에 보기
3부: 키클락을 활용한 통합 인증 실습하기
이번 3부에서 살펴볼 내용은 다음과 같습니다.
우리는 사전 준비 작업을 통해서 GKE 클러스터를 비롯해 키클락을 배포하고 키클락에서 인증을 진행하기 위한 설정을 모두 완료하였습니다. 다음으로, GKE 클러스터에 접근 시 키클락 통합 인증을 적용해보겠습니다.
먼저 현재 디렉터리에 위치한 1-3.clientconfig-gke-keycloak-w-oidc.yaml에 대해 알아보겠습니다.
1-3.clientconfig-gke-keycloak-w-oidc.yaml은 사전 준비 작업에서 GKE 클러스터를 생성할 때 추가로 입력한 --enable-identity-service으로 만들어진 구글 클라우드에 커스텀 오브젝트입니다. 이 파일 내부에는 OIDC 인증을 위한 파라미터를 설정할 수 있습니다.
oidc:
clientSecret: ...
clientID: k8s-auth
cloudConsoleRedirectURI: https://console.cloud.google.com/kubernetes/oidc
extraParams: resource=token-groups-claim
groupPrefix: '-'
groupsClaim: groups
issuerURI: https://oncloud-1.site/realms/kubernetes
kubectlRedirectURI: http://localhost:8000
scopes: openid
userClaim: preferred_username
userPrefix: '-'
internalServer: ""
name: hj-keycloak-oncloud-1-gke
이와 같은 파라미터에 대한 설명은 다음과 같이 정리할 수 있습니다.
위에 설정에 필요한 client secret은 kubernetes Realm - Client - k8s-auth - credentials 탭에 있는 Client secret을 복사하면 됩니다.
값을 올바르게 채워넣었다면 kubectl replace -f 1-3.clientconfig-gke-keycloak-w-oidc.yaml로 변경합니다.
root@k8s:~# kubectl replace -f 1-3.clientconfig-gke-keycloak-w-oidc.yaml
clientconfig.authentication.gke.io/default replaced
GKE 이외의 AWS, Azure, Alibaba 등 다양한 클라우드 공급자들이 제공하는 관리형 쿠버네티스가 있지만, 국내에서 가장 많이 사용되는 AWS의 EKS 클러스터를 추가 배포하고 통합 인증을 구성하겠습니다.
OIDC 기능이 추가된 EKS를 배포하기 위해서는 2-1.deploy-eks-env-only.sh 스크립트를 실행하면 됩니다. 이 스크립트는 EKS를 관리하는 eksctl로 EKS 클러스터를 생성합니다. 이때 필요한 EKS 클러스터의 설정은 같은 위치에 있는 eksctl-config 디렉터리 아래의 keycloak-w-oidc.yaml에 정의되어 있습니다. EKS 클러스터에 적용될 키클락 통합 인증 부분은 다음과 같습니다.
identityProviders:
- name: keycloak
type: oidc
issuerUrl: https://oncloud-1.site/realms/kubernetes
clientId: k8s-auth
usernameClaim: preferred_username
usernamePrefix:
groupsClaim: groups
코드를 보았을 때 usernameClaim으로 사용자 이름을 식별하고 groupsClaim을 통해서 group 정보를 식별하는 것을 확인할 수 있습니다. 또 키클락에 대한 인증 타입은 oidc이며 issuerUrl에는 GKE 구성과 동일하게 키클락에 접속 URL을 기입하고 있습니다.
다음으로는 OIDC 통합 인증을 수행할 때 마주할 수 있는 불편함을 해결하기 위해서 새로운 명령어인 kubelogin을 만들게 된 이야기를 하도록 하겠습니다.
테스트를 위한 사전 준비 작업과 OIDC 기능을 포함하는 EKS와 GKE를 구성하였습니다. 이제 남은 것은 ‘통합 인증을 통해서 로그인을 진행하면되나?’ 라는 생각이 드실 수 있겠지만, 아직은 통합 인증을 수행할 수 없습니다.
그 이유는 EKS와 GKE의 쿠버네티스 인증 방식은 OIDC를 이용하는 것은 같지만, 이때 사용되는 명령어와 명령어 구조가 다르기 때문입니다.
EKS는 kubectl과 같은 명령이 실행될 때 kubectl oidc-login get-token 명령어로 JWT를 키클락으로부터 전달받아서 인증하는 방식이고, GKE는 kubectl oidc login 명령으로 인증이 된 별도의 컨텍스트(context)를 생성해서 쿠버네티스 통합 인증을 진행하는 방식입니다. 클러스터 인증 명령어가 다르기 때문에 명령어를 두 개 써야 하는 문제가 발생하였습니다. 이를 효과적으로 해결하기 위해서 현재 설정 값에 따라 다르게 동작하는 새로운 명령어를 만들게 되었습니다. 이 명령어가 kubelogin 입니다.
아이디어는 이렇습니다. 현재 컨텍스트 이름 안에 gke라는 값이 있다면 해당 클러스터를 gke로 판별하여서 컨텍스트를 생성하도록 조치하고, 그 이외에는 kubectl oidc-login get-token 명령을 통해 JWT를 발급받아서 인증을 처리하게 하는 방식입니다. 그렇게 작성된 코드는 다음과 같습니다.
#!/usr/bin/env bash
function kubelogin() {
local vendor="$(cat ~/.kube/config | grep current-context | cut -d ':' -f2 | grep gke)"
if [ "$vendor" != "" ]; then
kubectl oidc login --cluster="hj-keycloak-oncloud-1-gke" --login-config="/Users/mz01-hj/.keycloak/config"
else
kubectl oidc-login get-token \
--oidc-issuer-url=https://oncloud-1.site/realms/kubernetes \
--oidc-client-id=k8s-auth \
--oidc-client-secret=6qfWVLJ91PrGABqqXD613ScVk6j2Qw1d
fi
}
kubelogin
셸 스크립트를 통해서 간략하게 작성하다 보니 하드코딩되어 있는 부분이 많습니다. 따라서 구글 클라우드에서 다른 GKE 클러스터를 사용하게 되었을 때 발생하는 예외 상황에는 대응이 안 되어 있습니다. 그리고 키클락 클라이언트 시크릿이 변경될 때마다 값을 매번 업데이트 해야하는 불편함이 있습니다.
매번 업데이트해야 하는 불편함을 해결하기 위해서 kubelogin을 생성하는 kubelogin-installer.sh스크립트를 만들었습니다.
# declare variable.
DOMAIN_NAME=oncloud-1
CLIENT_SECRET=6qfWVLJ91PrGABqqXD613ScVk6j2Qw1d
# keycloak-login-config
rm -rf ~/.keycloak ; mkdir ~/.keycloak
kubectl get clientconfig --context=hj-keycloak-${DOMAIN_NAME}-gke -n kube-public default -o yaml > ~/.keycloak/config
rm -rf /usr/local/bin/kubelogin
cat > "/usr/local/bin/kubelogin.tmp" <<'EOF'
#!/usr/bin/env bash
function kubelogin() {
local vendor="$(cat ~/.kube/config | grep current-context | cut -d ':' -f2 | grep gke)"
if [ "$vendor" != "" ]; then
kubectl oidc login --cluster="hj-keycloak-${DOMAIN_NAME}-gke" --login-config="/Users/mz01-hj/.keycloak/config"
else
kubectl oidc-login get-token \
--oidc-issuer-url=https://${DOMAIN_NAME}.site/realms/kubernetes \
--oidc-client-id=k8s-auth \
--oidc-client-secret=${CLIENT_SECRET}
fi
}
kubelogin
EOF
vendor='$vendor' DOMAIN_NAME=$DOMAIN_NAME CLIENT_SECRET=$CLIENT_SECRET envsubst < /usr/local/bin/kubelogin.tmp >> /usr/local/bin/kubelogin
rm /usr/local/bin/kubelogin.tmp
sudo chmod 755 "/usr/local/bin/kubelogin"
echo "kubelogin installed successfully"
kubelogin-installer.sh는 DOMAIN_NAME 이나 CLIENT_SECRET과 같은 값을 환경변수로 load 시켜서 kubelogin 셸 스크립트를 실행이 가능한 경로에 작성하는 방식입니다.
이제 테스트를 위한 모든 설정을 마쳤으니 EKS와 GKE에 대해서 인증/인가 실습을 진행하도록 하겠습니다.
어느 것을 먼저 해도 상관은 없지만, GKE는 새로 컨텍스트를 만들기 때문에 EKS를 먼저 하는 것이 좀 더 무난하게 실습할 수 있습니다. 따라서 EKS에 대한 인증/인가를 우선 실습하도록 하겠습니다.
1. EKS에 대한 인증/인가 실습
EKS 클러스터에 인증/인가 실습을 위해서 EKS 디렉터리로 이동하도록 하겠습니다.
root@k8s:~/IaC/Keycloak/oncloud-1.site# tree EKS
EKS
├── 1.clusterrolebinding-4-devops-group-as-admin.yaml
├── 2-oncloud-1.swtich-ctx-hoon-to-soojin.sh
└── 3.set-cred-4-oidc-user.sh
0 directories, 3 files
첫 번째로 먼저 kubectl get pods 로 쿠버네티스 파드가 조회되는지 확인합니다.
eksctl로 EKS를 생성한 경우 최초에는 관리자 권한이 담긴 사용자이기 때문에 조회가 가능합니다. EKS 통합 인증의 경우 현재 상태에서 인가는 키클락을 통해서 진행되고 그다음 사용자로부터 쿠버네티스에 대한 인가는 RBAC을 통해서 이뤄집니다. 따라서 현재 디렉터리에 있는 1.clusterrolebinding-4-devops-group-as-admin.yaml을 적용해서 키클락 통합 인증을 통해 접속한 사용자들이 kubectl을 사용할 수 있도록 하겠습니다. 1.clusterrolebinding-4-devops-group-as-admin.yaml 은 쿠버네티스 클러스터 관리자 권한을 group이 devops 인 사람에게 부여하겠다는 내용을 담고 있습니다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: oidc-group-cluster-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: devops
이렇게 클러스터롤바인딩으로 인가에 대한 부분을 설정하였습니다.
두 번째로 새로운 사용자로 EKS에 kubectl 사용이 가능한지 확인하기 위해서 새로운 사용자로 전환해야합니다. 현재 디렉터리에 위치한 2-oncloud-1.swtich-ctx-hoon-to-soojin.sh 으로 새로운 컨텍스트를 만들고 사용자를 변경하겠습니다.
이 셸 스크립트는 aws 명령을 통해서 EKS에 새로운 사용자로 접속할 수 있는 컨텍스트를 생성하는 명령입니다. 컨텍스트가 생성되고 새로운 컨텍스트로 변경된 후에 다시 kubectl get pods 명령을 입력한다면, 다음과 같이 새로운 컨텍스트에 대해서 인증하지 않아 에러가 발생합니다.
root@k8s:~# kubectl get pod
error: You must be logged in to the server (Unauthorized)
세 번째로, 키클락을 이용한 통합인증 진행을 위해서3.set-cred-4-oidc-user.sh셸 스크립트를 실행합니다. 3.set-cred-4-oidc-user.sh는 oidc-user라는 새로운 kubectl의 사용자를 만들고 kubelogin을 kubectl을 사용할 때마다 호출하도록 설정하는 내용의 스크립트입니다. 이를 통해서 키클락을 통한 JWT를 명령 실행 마다 받을 수 있고 인증이 가능하게 처리됩니다.
#!/usr/bin/env bash
kubectl config set-credentials oidc-user \
--exec-api-version=client.authentication.k8s.io/v1beta1 \
--exec-command=kubelogin
위 내용이 실제로는 아래와 같이 처리됩니다. 아래와 같은 현재 EKS를 포함한 온프레미스에 위치한 대부분의 쿠버네티스에 적용할 수 있는 통합 인증 설정입니다.
kubectl oidc-login get-token \
--oidc-issuer-url=https://oncloud-1.site/realms/kubernetes \
--oidc-client-id=k8s-auth \
--oidc-client-secret=[시크릿]
셸 스크립트를 실행하여 oidc-user라는 사용자를 만들었다면, kubectl get pods -A --user=oidc-user 명령을 통해서 다시 쿠버네티스 파드를 조회해보겠습니다. 해당 명령어를 입력하였을 때 터미널에 결과가 나타나지 않고 다음과 같은 웹 브라우저가 나타납니다. 이때 키클락에 대한 로그인 화면이 나타나는데, 여기서 우리는 Google 버튼을 눌러서 구글 로그인으로 인증을 진행해 보겠습니다.
Google 버튼을 선택했을 때 이미 브라우저 상에 연결된 이메일 계정이 있다면, 해당 이메일로 인증 메일이 발송되었으니 이메일을 확인해달라는 안내 문구가 나타납니다. (만약 없다면 이메일을 선택하는 메시지가 나옵니다.)
실제로 사용하는 메일 서비스에 메일함을 확인하였을 때 아래와 같은 인증 메일이 온 것을 확인할 수 있습니다. 여기서Link to e-mail address verification을 누르면 터미널에서 실행했던 명령 결과가 나타납니다. 즉 이 과정을 통해서 EKS에서의 키클락 인증이 완료되고, 인증 완료된 그룹 devops의 권한으로 파드 조회 결과를 확인할 수 있게 된 것입니다.
위와 같은 흐름을 생동감 있게 표현하면 다음과 같이 처리가 되는 것입니다.
GKE 환경에서의 인증/인가를 테스트하기 위해서 상위 디렉터리에 위치한 GKE 디렉터리로 이동합니다.
root@k8s:~/IaC/Keycloak/oncloud-1.site# tree GKE
GKE
├── 1.clusterrolebinding-4-devops-group-as-admin-NOTWORK.yaml
├── 2-hoon.clusterrolebinding-4-devops-user-as-admin.yaml
└── 2-soojin.clusterrolebinding-4-devops-user-as-admin.yaml
앞에서 말씀드린 것처럼 GKE의 경우 EKS와 다른 쿠버네티스 클러스터와 다르게 통합 인증을 위한 컨텍스트를 생성해야 합니다. 그래서 컨텍스트를 생성하기 위해 먼저 지금의 EKS 컨텍스트에서 GKE 컨텍스트로 이동이 필요합니다. 이는 kubectx 명령 또는 kubectl config use-context를 사용하면 바로 전환이 가능합니다.
지금 컨텍스트가 GKE로 변경되었다면, 여기서 kubelogin 명령어를 입력하도록 하겠습니다. 입력하게 되면 다음 브라우저 화면이 나타나면서 인증되었다고 나타납니다.
터미널에는 다음과 같은 메시지가 출력됩니다.
2023/10/30 19:11:46 Started webserver on localhost: 8000.
2023/10/30 19:11:46 Attempting to open http://127.0.0.1:8000/login in default browser.
2023/10/30 19:11:47 OIDC Authentication successful.
인증이 완료되었다고 나타남과 동시에 새로운 컨텍스트가 생성되고, 지금 컨텍스트가 변경된 것을 확인할 수 있습니다. 위 과정을 생동감 있게 표현하면 다음과 같습니다.
현재 상태에서 GKE 클러스터에 kubectl get pods 를 입력한다면, 다음과 같은 에러가 나타납니다.
root@k8s:# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "hj@mz.co.kr" cannot list resource "pods" in API group in the namespace "default"
이는 키클락을 통해서 인증은 완료되었지만 쿠버네티스 RBAC을 통해서는 인가가 되지 않아서 발생하는 에러입니다. 이 문제는 GKE 클러스터에 어드민 컨텍스트로 다시 돌아가 클러스터롤바인딩을 적용해주면 해결 됩니다. 적용할 클러스터롤바인딩은 2-hoon.clusterrolebinding-4-devops-user-as-admin.yaml 입니다.
root@k8s:# kubectl apply -f
2-hoon.clusterrolebinding-4-devops-user-as-admin.yaml
<노트>
EKS와 동일하게 그룹을 사용하지 않는 이유는 이 글을 작성하는 시점에서 구글 GKE에서 JWT로부터 그룹에 대한 필드를 가져오는 기능이 정상동작하지 않고 있기 때문에 실습에서는 부득이하게 개인에 RBAC 인가 처리를 진행하고 있습니다. 따라서 이 부분은 향후 바꿀 수 있습니다.
</노트>
다음으로 kubectx로 <클러스터이름>-<클러스터이름-anthos-default-user>와 같은 이름 형식을 사용하는 GKE 컨텍스트로 이동합니다. 이동하였다면 다시 kubectl get pods 를 입력해보겠습니다.
root@k8s:# kubectl get pods
NAME READY STATUS RESTARTS AGE
keycloak-0 1/1 Running 0 85m
keycloak-postgresql-0 1/1 Running 0 85m
키클락을 통한 인증이 완료된 사용자가 이제는 kubectl get pods를 통해서 파드를 확인할 수 있는 것을 알아봤습니다.
지금까지의 실습을 통해서 키클락을 이용한 쿠버네티스 통합 인증을 구성하고 서로 다른 클라우드에 배포된 쿠버네티스 클러스터에 인증/인가를 진행 했습니다. 정리를 위해서 키클락 통합 인증으로 얻을 수 있는 이점을 요약하도록 하겠습니다.
첫 번째는 단순하게 EKS, GKE 뿐만 아니라 온프레미스 쿠버네티스 클러스터를 비롯해 SAML과 OIDC를 지원하는 다른 오픈소스 앱들에서도 통합 인증을 구성할 수 있다는 장점이 있습니다.
두 번째로는 대부분 Okta와 Onelogin과 같은 솔루션을 사용하실 수 있지만 법령 상의 규제로 SaaS를 사용할 수 없는 금융권 및 공공기관에서 오픈소스를 활용해 내부 조직에 인증 사업자(IdP)를 구성하실 수 있습니다.
세 번째로는 인증과 인가에 대한 설정을 중앙에서 관리할 수 있다는 점입니다. 조직이 커지면 커질수록 사용자를 관리하고 권한을 부여하는 일들이 굉장히 힘든 일이 될 수 있는데, 키클락을 Realm과 Role로 사용자들에 대한 관리를 효율적으로 할 수 있다는 점입니다.
긴 글을 읽어주셔서 감사합니다.
관련 레퍼런스 사이트
요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.