Xác thực trong Kubernetes bằng GitHub OAuth và Dex

Tôi giới thiệu với bạn hướng dẫn tạo quyền truy cập vào cụm Kubernetes bằng Dex, dex-k8s-authenticator và GitHub.

Xác thực trong Kubernetes bằng GitHub OAuth và Dex
Meme địa phương từ cuộc trò chuyện Kubernetes bằng tiếng Nga trong Telegram

Giới thiệu

Chúng tôi sử dụng Kubernetes để tạo môi trường năng động cho nhóm phát triển và QA. Vì vậy, chúng tôi muốn cấp cho họ quyền truy cập vào cụm cho cả bảng thông tin và kubectl. Không giống như OpenShift, vanilla Kubernetes không có xác thực gốc, vì vậy chúng tôi sử dụng các công cụ của bên thứ ba cho việc này.

Trong cấu hình này, chúng tôi sử dụng:

  • dex-k8s-xác thực  — ứng dụng web để tạo cấu hình kubectl
  • Dex - Nhà cung cấp kết nối OpenID
  • GitHub - đơn giản vì chúng tôi sử dụng GitHub trong công ty của mình

Chúng tôi đã thử sử dụng Google OIDC, nhưng thật không may, chúng tôi thất bại để bắt đầu với các nhóm, vì vậy việc tích hợp với GitHub khá phù hợp với chúng tôi. Nếu không ánh xạ nhóm, sẽ không thể tạo chính sách RBAC dựa trên nhóm.

Vì vậy, quy trình ủy quyền Kubernetes của chúng tôi hoạt động như thế nào dưới dạng trình bày trực quan:

Xác thực trong Kubernetes bằng GitHub OAuth và Dex
quy trình ủy quyền

Chi tiết hơn một chút và từng điểm một:

  1. Người dùng đăng nhập vào dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-authenticator chuyển tiếp yêu cầu tới Dex (dex.k8s.example.com)
  3. Dex chuyển hướng đến trang đăng nhập GitHub
  4. GitHub tạo thông tin ủy quyền cần thiết và gửi lại cho Dex
  5. Dex chuyển thông tin nhận được tới dex-k8s-authenticator
  6. Người dùng nhận được mã thông báo OIDC từ GitHub
  7. dex-k8s-authenticator thêm mã thông báo vào kubeconfig
  8. kubectl chuyển mã thông báo tới KubeAPIServer
  9. KubeAPIServer trả lại quyền truy cập vào kubectl dựa trên mã thông báo đã chuyển
  10. Người dùng có quyền truy cập từ kubectl

Các hành động chuẩn bị

Tất nhiên, chúng tôi đã cài đặt cụm Kubernetes (k8s.example.com) và cũng được cài đặt sẵn HELM. Chúng tôi cũng có một tổ chức trên GitHub (super-org).
Nếu bạn không có HELM, hãy cài đặt nó rất đơn giản.

Đầu tiên chúng ta cần thiết lập GitHub.

Đi tới trang cài đặt tổ chức, (https://github.com/organizations/super-org/settings/applications) và tạo một ứng dụng mới (Ứng dụng OAuth được ủy quyền):
Xác thực trong Kubernetes bằng GitHub OAuth và Dex
Tạo một ứng dụng mới trên GitHub

Điền vào các trường với các URL cần thiết, ví dụ:

  • URL trang chủ: https://dex.k8s.example.com
  • URL gọi lại ủy quyền: https://dex.k8s.example.com/callback

Hãy cẩn thận với các liên kết, điều quan trọng là không để mất dấu gạch chéo.

Để phản hồi biểu mẫu đã hoàn thành, GitHub sẽ tạo Client ID и Client secret, hãy giữ chúng ở nơi an toàn, chúng sẽ hữu ích cho chúng tôi (ví dụ: chúng tôi sử dụng Vault để lưu trữ bí mật):

Client ID: 1ab2c3d4e5f6g7h8
Client secret: 98z76y54x32w1

Chuẩn bị bản ghi DNS cho tên miền phụ login.k8s.example.com и dex.k8s.example.com, cũng như chứng chỉ SSL để xâm nhập.

Hãy tạo chứng chỉ SSL:

cat <<EOF | kubectl create -f -
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: cert-auth-dex
  namespace: kube-system
spec:
  secretName: cert-auth-dex
  dnsNames:
    - dex.k8s.example.com
  acme:
    config:
    - http01:
        ingressClass: nginx
      domains:
      - dex.k8s.example.com
  issuerRef:
    name: le-clusterissuer
    kind: ClusterIssuer
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: cert-auth-login
  namespace: kube-system
spec:
  secretName: cert-auth-login
  dnsNames:
    - login.k8s.example.com
  acme:
    config:
    - http01:
        ingressClass: nginx
      domains:
      - login.k8s.example.com
  issuerRef:
    name: le-clusterissuer
    kind: ClusterIssuer
EOF
kubectl describe certificates cert-auth-dex -n kube-system
kubectl describe certificates cert-auth-login -n kube-system

Nhà phát hành cụm có tiêu đề le-clusterissuer đã tồn tại, nhưng nếu chưa, hãy tạo nó bằng HELM:

helm install --namespace kube-system -n cert-manager stable/cert-manager
cat << EOF | kubectl create -f -
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: le-clusterissuer
  namespace: kube-system
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: le-clusterissuer
    http01: {}
EOF

Cấu hình máy chủ KubeAPI

Để kubeAPIServer hoạt động, bạn cần định cấu hình OIDC và cập nhật cụm:

kops edit cluster
...
  kubeAPIServer:
    anonymousAuth: false
    authorizationMode: RBAC
    oidcClientID: dex-k8s-authenticator
    oidcGroupsClaim: groups
    oidcIssuerURL: https://dex.k8s.example.com/
    oidcUsernameClaim: email
kops update cluster --yes
kops rolling-update cluster --yes

Chúng tôi sử dụng đá để triển khai các cụm, nhưng cách này hoạt động tương tự đối với người quản lý cụm khác.

Cấu hình Dex và trình xác thực dex-k8s

Để Dex hoạt động, bạn cần có chứng chỉ và khóa từ Kubernetes master, hãy lấy nó từ đó:

sudo cat /srv/kubernetes/ca.{crt,key}
-----BEGIN CERTIFICATE-----
AAAAAAAAAAABBBBBBBBBBCCCCCC
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
DDDDDDDDDDDEEEEEEEEEEFFFFFF
-----END RSA PRIVATE KEY-----

Hãy sao chép kho lưu trữ dex-k8s-authenticator:

git clone [email protected]:mintel/dex-k8s-authenticator.git
cd dex-k8s-authenticator/

Bằng cách sử dụng các tệp giá trị, chúng ta có thể cấu hình linh hoạt các biến cho biểu đồ HELM.

Hãy mô tả cấu hình cho Dex:

cat << EOF > values-dex.yml
global:
  deployEnv: prod
tls:
  certificate: |-
    -----BEGIN CERTIFICATE-----
    AAAAAAAAAAABBBBBBBBBBCCCCCC
    -----END CERTIFICATE-----
  key: |-
    -----BEGIN RSA PRIVATE KEY-----
    DDDDDDDDDDDEEEEEEEEEEFFFFFF
    -----END RSA PRIVATE KEY-----
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
  path: /
  hosts:
    - dex.k8s.example.com
  tls:
    - secretName: cert-auth-dex
      hosts:
        - dex.k8s.example.com
serviceAccount:
  create: true
  name: dex-auth-sa
config: |
  issuer: https://dex.k8s.example.com/
  storage: # https://github.com/dexidp/dex/issues/798
    type: sqlite3
    config:
      file: /var/dex.db
  web:
    http: 0.0.0.0:5556
  frontend:
    theme: "coreos"
    issuer: "Example Co"
    issuerUrl: "https://example.com"
    logoUrl: https://example.com/images/logo-250x25.png
  expiry:
    signingKeys: "6h"
    idTokens: "24h"
  logger:
    level: debug
    format: json
  oauth2:
    responseTypes: ["code", "token", "id_token"]
    skipApprovalScreen: true
  connectors:
  - type: github
    id: github
    name: GitHub
    config:
      clientID: $GITHUB_CLIENT_ID
      clientSecret: $GITHUB_CLIENT_SECRET
      redirectURI: https://dex.k8s.example.com/callback
      orgs:
      - name: super-org
        teams:
        - team-red
  staticClients:
  - id: dex-k8s-authenticator
    name: dex-k8s-authenticator
    secret: generatedLongRandomPhrase
    redirectURIs:
      - https://login.k8s.example.com/callback/
envSecrets:
  GITHUB_CLIENT_ID: "1ab2c3d4e5f6g7h8"
  GITHUB_CLIENT_SECRET: "98z76y54x32w1"
EOF

Và đối với trình xác thực dex-k8s:

cat << EOF > values-auth.yml
global:
  deployEnv: prod
dexK8sAuthenticator:
  clusters:
  - name: k8s.example.com
    short_description: "k8s cluster"
    description: "Kubernetes cluster"
    issuer: https://dex.k8s.example.com/
    k8s_master_uri: https://api.k8s.example.com
    client_id: dex-k8s-authenticator
    client_secret: generatedLongRandomPhrase
    redirect_uri: https://login.k8s.example.com/callback/
    k8s_ca_pem: |
      -----BEGIN CERTIFICATE-----
      AAAAAAAAAAABBBBBBBBBBCCCCCC
      -----END CERTIFICATE-----
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
  path: /
  hosts:
    - login.k8s.example.com
  tls:
    - secretName: cert-auth-login
      hosts:
        - login.k8s.example.com
EOF

Cài đặt Dex và dex-k8s-xác thực:

helm install -n dex --namespace kube-system --values values-dex.yml charts/dex
helm install -n dex-auth --namespace kube-system --values values-auth.yml charts/dex-k8s-authenticator

Hãy kiểm tra chức năng của các dịch vụ (Dex sẽ trả về mã 400 và dex-k8s-authenticator sẽ trả về mã 200):

curl -sI https://dex.k8s.example.com/callback | head -1
HTTP/2 400
curl -sI https://login.k8s.example.com/ | head -1
HTTP/2 200

cấu hình RBAC

Chúng tôi tạo ClusterRole cho nhóm, trong trường hợp của chúng tôi có quyền truy cập chỉ đọc:

cat << EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-read-all
rules:
  -
    apiGroups:
      - ""
      - apps
      - autoscaling
      - batch
      - extensions
      - policy
      - rbac.authorization.k8s.io
      - storage.k8s.io
    resources:
      - componentstatuses
      - configmaps
      - cronjobs
      - daemonsets
      - deployments
      - events
      - endpoints
      - horizontalpodautoscalers
      - ingress
      - ingresses
      - jobs
      - limitranges
      - namespaces
      - nodes
      - pods
      - pods/log
      - pods/exec
      - persistentvolumes
      - persistentvolumeclaims
      - resourcequotas
      - replicasets
      - replicationcontrollers
      - serviceaccounts
      - services
      - statefulsets
      - storageclasses
      - clusterroles
      - roles
    verbs:
      - get
      - watch
      - list
  - nonResourceURLs: ["*"]
    verbs:
      - get
      - watch
      - list
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create"]
EOF

Hãy tạo cấu hình cho ClusterRoleBinding:

cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: dex-cluster-auth
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-read-all
subjects:
  kind: Group
  name: "super-org:team-red"
EOF

Bây giờ chúng tôi đã sẵn sàng để thử nghiệm.

Kiểm tra

Tới trang đăng nhập (https://login.k8s.example.com) và đăng nhập bằng tài khoản GitHub của bạn:

Xác thực trong Kubernetes bằng GitHub OAuth và Dex
Trang đăng nhập

Xác thực trong Kubernetes bằng GitHub OAuth và Dex
Trang đăng nhập được chuyển hướng đến GitHub

Xác thực trong Kubernetes bằng GitHub OAuth và Dex
 Thực hiện theo các hướng dẫn được tạo để có quyền truy cập

Sau khi sao chép và dán từ trang web, chúng ta có thể sử dụng kubectl để quản lý tài nguyên cụm của mình:

kubectl get po
NAME                READY   STATUS    RESTARTS   AGE
mypod               1/1     Running   0          3d

kubectl delete po mypod
Error from server (Forbidden): pods "mypod" is forbidden: User "[email protected]" cannot delete pods in the namespace "default"

Và nó hoạt động, tất cả người dùng GitHub trong tổ chức của chúng tôi có thể xem tài nguyên và đăng nhập vào nhóm, nhưng họ không có quyền thay đổi chúng.

Nguồn: www.habr.com

Thêm một lời nhận xét