1. 사용자가 Bearer token으로 쿠버네티스 API 서버에게 인증을 요청합니다.
2. API 서버에서 사전에 정의된 Webhook 서버로 TokenReview라는 json 이벤트 객체와 함께 REST 요청을 보냅니다.
3. Webhook 인증 서버에서는 자체적인 인증 솔루션을 이용하여 사용자를 인증합니다.
4. Webhook 인증 서버에서 API 서버로 TokenReview을 응답하는데 그 안에 인증결과(status)가 포함됩니다.
5. API 서버에서 인증 결과를 확인하여 사용자에게 응답합니다.
{
"kind": "TokenReview",
"apiVersion": "authentication.k8s.io/v1beta1",
"metadata": {
"creationTimestamp": null
},
"spec": {
"token": "$BEARER_TOKEN"
}
}
{
"kind": "TokenReview",
"apiVersion": "authentication.k8s.io/v1beta1",
"metadata": {
"creationTimestamp": null
},
"spec": {
"token": "$BEARER_TOKEN"
},
"status": { # 응답 객체
"authenticated": true, # 사용자 인증 성공 여부
"user": {
"username": "user1", # 사용자 이름
"uid": "user1", #쿠버네티스 인식 식별자
"groups": [ "system:masters" ] #쿠버네티스 그룹
}
}
}
# API 서버 설정 파일
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
# -----[kube-apiserver.yaml]------
- kube-apiserver
- --allow-privileged=true
- --authorization-mode=Node,RBAC
# .....
- --authentication-token-webhook-config-file=/etc/kubernetes/pki/webhook.yaml
# --------------------------------
# /etc/kubernetes/pki/webhook.yaml
apiVersion: v1
kind: Config
clusters:
- name: flask-auth
cluster:
server: https://127.0.0.1:5000
insecure-skip-tls-verify: true
users:
- name: kube-apiserver
contexts:
- context:
cluster: flask-auth
user: kube-apiserver
name: auth
current-context: auth
from flask import Flask, request, jsonify
import pprint
import requests
from requests.auth import HTTPBasicAuth
app = Flask(__name__)
@app.route('/', methods=['POST'])
def auth():
tokenReview = request.json
# 인증 결과 (외부 인증)
tokenReview['status'] = external_auth(tokenReview)
pprint.pprint(tokenReview)
# API 서버로 json 응답
return jsonify(tokenReview)
# 외부 인증 시스템
def external_auth(tokenReview):
try:
user, pw = tokenReview['spec']['token'].split(':')
ret = requests.get('https://httpbin.org/basic-auth/user1/pass1', auth=HTTPBasicAuth(user, pw))
status = {}
status['authenticated'] = ret.status_code == 200
status['user'] = {
'username': user,
'uid': user,
'groups': ['system:masters']
}
except:
status = {}
status['authenticated'] = False
return status
if __name__ == '__main__':
app.run(host= '0.0.0.0', port=5000, debug=True)
external_auth(tokenReview)함수에서 외부 인증 서버에 인증을 요청 하는 구조
Test
kubectl get pod -n kube-system --token user1:pass1
# 성공!
kubectl get pod -n kube-system --token user1:pass2
# 인증 실패