kubernetes - Webhook

우야·2021년 6월 4일
0

Webhook이란?

  • 특정 이벤트가 발생하면, 사전에 정의된 web url로 이벤트 정보와 함께 요청을 보내어서 처리되게함

Webhook 인증 서버를 통한 사용자 인증

  • kubernetes api서버에도 인증 처리를 위한 Webhook을 구현할 수 있는 메커니즘이 존재
  • Authenticate 이벤트가 발생하면, 이벤트 객체(정보)는 사용자가 전송한 토큰이다.


1. 사용자가 Bearer token으로 쿠버네티스 API 서버에게 인증을 요청합니다.
2. API 서버에서 사전에 정의된 Webhook 서버로 TokenReview라는 json 이벤트 객체와 함께 REST 요청을 보냅니다.
3. Webhook 인증 서버에서는 자체적인 인증 솔루션을 이용하여 사용자를 인증합니다.
4. Webhook 인증 서버에서 API 서버로 TokenReview을 응답하는데 그 안에 인증결과(status)가 포함됩니다.
5. API 서버에서 인증 결과를 확인하여 사용자에게 응답합니다.

요청시 : TokenReview

  • $BEARER_TOKEN에는 사용자가 전송한 Bearer Token
  • 사용자가 인증을 위해 전송한 Bearer Token이 Webhook 인증 서버로 전달되어 해당값이 유효한지 확인한다.
{
  "kind": "TokenReview",
  "apiVersion": "authentication.k8s.io/v1beta1",
  "metadata": {
    "creationTimestamp": null
  },
  "spec": {
    "token": "$BEARER_TOKEN"
  }
}

응답시 : TokenReview + status

{
  "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 server 설정

  • 사용자로부터 API서버로 인증 요청이 들어오면, 이벤트를 인증서버로 보내야하는 설정이다.
  • --authentication-token-webhook-config-file 옵션과 설정 파일을 정의하여 value에 매칭한다.
# 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

  • local의 5000포트에 flast-auth 외무 인증 서버와 중개하는 중개 서버를 구성하겠다.
# /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
    # 인증 실패
profile
Fullstack developer

0개의 댓글