- Đăng vào
Thiết lập SSO cho Kuberentes dashboard dùng Oauth2 Proxy
Giới thiệu
Bài viết này sẽ giới thiệu cách mà mình thiết lập để có thể đăng nhập vào Kubernetes Dashboard bằng phương thức SSO.
Kubernetes dashboard
Kubernetes dashboard ứng dụng WebUI cho phép chúng ta quản lý cluster của mình một cách trực quan. Trên thị trường có nhiều app tương tự như Open lens,... Tuy nhiên mình thấy K8s Dashboard là đủ trong phạm vi học tập, nghiên cứu.
Để deploy dashboard lên cluster thì khá đơn giản, chỉ cần
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
Chi tiết hơn bạn có thể đọc thêm Deploying the Dashboard UI
Azure AD OIDC
Trong ví dụ này mình sử dụng OIDC của Azure AD. Điều kiện đầu tiên là bạn phải đăng ký app trên Azure AD, chi tiết có thể xem hướng dẫn này Quickstart: Register an application with the Microsoft identity platform. Các thông tin quan trọng cần phải lưu ý:
- Application (client) ID:
<Client-ID>
- Client secret:
<Client secret>
- Directory (tenant) ID:
<Tenant-ID>
- Redirect URIs:
https://your-dashboard-domain.com/oauth2/callback
Lưu ý:
Để biết cách thiết lập 1 App trên Azure AD vui lòng xem thêm tại bài viết Thiết lập Jenkins SSO dùng Azure AD
OAuth2 Proxy
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: oauth2-proxy
name: oauth2-proxy
namespace: kubernetes-dashboard
spec:
selector:
matchLabels:
app.kubernetes.io/name: oauth2-proxy
template:
metadata:
labels:
app.kubernetes.io/name: oauth2-proxy
spec:
containers:
- args:
- --provider=oidc
- --azure-tenant=<Tenant-ID> # Azure AD OAuth2 Proxy application Tenant ID
- --cookie-name=_proxycookie # this can be any name of your choice which you would like OAuth2 Proxy to use for the session cookie
- --email-domain=*
- --upstream=file:///dev/null
- --http-address=0.0.0.0:4180
- --oidc-issuer-url=https://sts.windows.net/<Tenant-ID>/
- --set-xauthrequest=true
- --pass-access-token=true
- --set-authorization-header=true
env:
- name: OAUTH2_PROXY_CLIENT_ID
valueFrom:
secretKeyRef:
name: proxy-secrets
key: OAUTH2_PROXY_CLIENT_ID
- name: OAUTH2_PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: proxy-secrets
key: OAUTH2_PROXY_CLIENT_SECRET
- name: OAUTH2_PROXY_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: proxy-secrets
key: OAUTH2_PROXY_COOKIE_SECRET
image: quay.io/oauth2-proxy/oauth2-proxy:v7.4.0
imagePullPolicy: Always
name: oauth2-proxy
ports:
- containerPort: 4180
protocol: TCP
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
Với manifest ở trên, có 3 thông tin chúng ta nên để ở dạng Secrets:
OAUTH2_PROXY_CLIENT_ID
OAUTH2_PROXY_CLIENT_SECRET
OAUTH2_PROXY_COOKIE_SECRET
: có thể tạo bằng lệnh sau:python -c 'import secrets,base64; print(base64.b64encode(base64.b64encode(secrets.token_bytes(16))));'
kubectl -n kubernetes-dashboard create secret generic proxy-secrets \
--from-literal=OAUTH2_PROXY_CLIENT_ID='<Client-ID>' \
--from-literal=OAUTH2_PROXY_CLIENT_SECRET='<Client-secret>' \
--from-literal=OAUTH2_PROXY_COOKIE_SECRET='<cookie-secret>'
Sau khi đã khởi tạo được các secrets thì chúng ta tiến hành deploy Oauth2 proxy
kubectl -n kubernetes-dashboard apply -f oauth2-proxy-deployment.yaml
Service
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: oauth2-proxy
name: oauth2-proxy
namespace: kubernetes-dashboard
spec:
ports:
- name: http
port: 4180
protocol: TCP
targetPort: 4180
selector:
app.kubernetes.io/name: oauth2-proxy
Deploy service cho oauth2-proxy
kubectl apply -f oauth2-proxy-service.yaml
Ingress
Ở đây mình dùng ingress-nginx
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: azure-auth-oauth2
namespace: kubernetes-dashboard
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=https://$host$request_uri$is_args$args"
nginx.ingress.kubernetes.io/auth-response-headers: 'Authorization'
# Proxy Authentication header to Dashboard
nginx.ingress.kubernetes.io/configuration-snippet: |
auth_request_set $token $upstream_http_authorization;
proxy_set_header Authorization $token;
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: nginx
rules:
- host: your-dashboard-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 443
tls:
- hosts:
- your-dashboard-domain.com
secretName: ssl-your-dashboard-domain
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-buffer-size: "64k"
nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
name: oauth2-proxy
namespace: kubernetes-dashboard
spec:
ingressClassName: nginx
rules:
- host: your-dashboard-domain.com
http:
paths:
- path: /oauth2
pathType: Prefix
backend:
service:
name: oauth2-proxy
port:
number: 4180
tls:
- hosts:
- your-dashboard-domain.com
secretName: ssl-your-dashboard-domain
Ở line số 7 và 28 là cấu hình ssl của domain, chi tiết có thể xem thêm bài viết Tạo chứng chỉ Let’s Encrypt trên Kubernetes
Để deploy
kubectl apply -f dashboard-ingress.yaml
Kubernetes API Server
Bước tiếp theo chúng ta sẽ cấu hình kube API server để cho phép authentication qua OIDC
sudo nano /etc/kubernetes/manifests/kube-apiserver.yaml
...
- --oidc-issuer-url=https://sts.windows.net/<Tenant-ID>/
- --oidc-client-id=<client-id>
- --oidc-username-claim=email
- --oidc-groups-claim=groups
Lưu nó lại và Kuberbetes cluster sẽ tự load config mới.
RBAC
Cuối cùng, chúng ta sẽ phân quyền cho account login bằng OIDC
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
namespace: kubernetes-dashboard
- apiGroup: rbac.authorization.k8s.io
kind: User
name: "my-email@company.com"
kubectl apply -f oidc-user.yaml