使用Active Directory对Kubernetes仪表板用户进行身份验证

时间:2020-02-23 14:31:45  来源:igfitidea点击:

Kubernetes仪表板是基于Web的用户界面,允许用户轻松地与kubernetes集群进行交互。
它允许用户对应用程序以及群集进行管理,监视和故障排除。
在本教程中,我们已经研究了如何部署仪表板。
在本教程中,我们将探讨kubernetes仪表板与Active Directory的集成,以简化用户和密码管理。

Kubernetes支持两类用户:服务帐户:这是kubernetes支持的默认方法。
一个使用服务帐户令牌访问仪表板。
普通用户:群集中配置的任何其他身份验证方法。

为此,我们将使用一个名为Dex的项目。
Dex是由CoreOS完成的OpenID Connect提供程序。
它负责Kubernetes令牌和Active Directory用户之间的转换。

设置要求:

网络上需要Active Directory服务器的IP。
在我的情况下,该IP为172.16.16.16我们还将需要一个正常工作的Kubernetes集群。
该群集的节点应该能够与Active Directory IP通信。
看一下如何使用kubeadm或者rke创建一个kubernetes集群(如果还没有的话)。
我们还需要一个支持通配DNS输入的域名。
我将使用通配符DNS" * .kubernetes.mydomain.com"将外部流量路由到我的Kubernetes集群。

步骤1:在Kubernetes集群上部署Dex

我们首先需要创建一个名称空间,为dex创建一个服务帐户。
然后,在部署dex服务帐户之前,我们将为其配置RBAC规则。
这是为了确保应用程序具有适当的权限。
创建一个dex-namespace.yaml文件。

$vim dex-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: auth-system

2.为Dex创建名称空间。

$kubectl apply -f dex-namespace.yaml

3.创建一个dex-rbac.yaml文件。

$vim dex-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dex
  namespace: auth-system
--
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: dex
  namespace: auth-system
rules:
- apiGroups: ["dex.coreos.com"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["apiextensions.k8s.io"]
  resources: ["customresourcedefinitions"]
  verbs: ["create"]
--
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: dex
  namespace: auth-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: dex
subjects:
- kind: ServiceAccount
  name: dex
  namespace: auth-system

4.创建Dex的权限。

$kubectl apply -f dex-rbac.yaml

5.创建一个dex-configmap.yaml文件。
确保相应地修改颁发者URL,重定向URI,客户端密码和Active Directory配置。

$vim dex-configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: dex
  namespace: auth-system
data:
  config.yaml: |
    issuer: https://auth.kubernetes.mydomain.com/
    web:
      http: 0.0.0.0:5556
    frontend:
      theme: custom
    telemetry:
      http: 0.0.0.0:5558
    staticClients:
    - id: oidc-auth-client
      redirectURIs:
      - https://kubectl.kubernetes.mydomain.com/callback
      - http://dashtest.kubernetes.mydomain.com/oauth2/callback
      name: oidc-auth-client
      secret: secret
    connectors:
    - type: ldap
      id: ldap
      name: LDAP
      config:
        host: 172.16.16.16:389
        insecureNoSSL: true
        insecureSkipVerify: true
        bindDN: ldapadmin
        bindPW: 'KJZOBwS9DtB'
        userSearch:
          baseDN: OU=theitroad departments,DC=theitroad ,DC=net
          username: sAMAccountName
          idAttr: sn
          nameAttr: givenName
          emailAttr: mail
        groupSearch: 
          baseDN: CN=groups,OU=theitroad,DC=theitroad,DC=net 
          userMatchers:
          - userAttr: sAMAccountName
            groupAttr: memberOf
          nameAttr: givenName                   
    oauth2:
      skipApprovalScreen: true
    storage:
      type: kubernetes
      config:
        inCluster: true

6.配置敏捷。

$kubectl apply -f dex-configmap.yaml

7.创建dex-deployment.yaml文件。

$vim dex-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: dex
  name: dex
  namespace: auth-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dex
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: dex
        revision: "1"
    spec:
      containers:
      - command:
        - /usr/local/bin/dex
        - serve
        - /etc/dex/cfg/config.yaml
        image: quay.io/dexidp/dex:v2.17.0
        imagePullPolicy: IfNotPresent
        name: dex
        ports:
        - containerPort: 5556
          name: http
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc/dex/cfg
          name: config
        - mountPath: /web/themes/custom/
          name: theme          
      dnsPolicy: ClusterFirst
      serviceAccountName: dex
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: config.yaml
            path: config.yaml
          name: dex
        name: config
      - name: theme
        emptyDir: {}

8.部署敏捷。

$kubectl apply -f dex-deployment.yaml

9.创建一个dex-service.yaml文件。

$vim dex-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: dex
  namespace: auth-system
spec:
  selector:
    app: dex
  ports:
  - name: dex
    port: 5556
    protocol: TCP
    targetPort: 5556

10.为Dex部署创建服务。

$kubectl apply -f dex-service.yaml

11.创建一个dex-ingress秘密。
确保群集的证书数据在指定的位置,或者更改此路径以指向它。
如果群集中安装了证书管理器,则可以跳过此步骤。

$kubectl create secret tls dex --key /data/Certs/kubernetes.mydomain.com.key --cert /data/Certs/kubernetes.mydomain.com.crt -n auth-system

12.创建一个dex-ingress.yaml文件。
相应地更改主机参数和证书颁发者名称。

$vim dex-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: dex
  namespace: auth-system
  annotations:
    kubernetes.io/tls-acme: "true"
    ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  tls:
  - secretName: dex
    hosts:
    - auth.kubernetesuat.mydomain.com
  rules:
  - host: auth.kubernetes.mydomain.com
    http:
      paths:
      - backend:
          serviceName: dex
          servicePort: 5556

13.为Dex服务创建入口。

$kubectl apply -f dex-ingress.yaml

等待几分钟,直到证书管理员为Dex生成证书。
我们可以通过浏览到以下网址检查Dex是否已正确部署:https://auth.kubernetesuat.mydomain.com/.well-known/openid-configuration

步骤2:将Kubernetes API配置为以OpenID Connect提供程序的身份访问Dex

接下来,我们将研究如何为RKE和Kubeadm集群配置API服务器。
要启用OIDC插件,我们需要在API服务器上配置几个标志,如下所示:A。
RKE群集1.
SSH到rke节点。

$ssh Hyman@theitroad

2.编辑Kubernetes API配置。
添加OIDC参数并相应地修改发行者URL。

$sudo vim ~/Rancher/cluster.yml
    kube-api:
      service_cluster_ip_range: 10.43.0.0/16
      # Expose a different port range for NodePort services
      service_node_port_range: 30000-32767
      extra_args:
        # Enable audit log to stdout
        audit-log-path: "-"
        # Increase number of delete workers
        delete-collection-workers: 3
        # Set the level of log output to debug-level
        v: 4
#ADD THE FOLLOWING LINES 
        oidc-issuer-url: https://auth.kubernetes.mydomain.com/   
        oidc-client-id: oidc-auth-client
        oidc-ca-file: /data/Certs/kubernetes.mydomain.com.crt
        oidc-username-claim: email
        oidc-groups-claim: groups
      extra_binds:
        - /data/Certs:/data/Certs ##ENSURE THE WILDCARD CERTIFICATES ARE PRESENT IN THIS FILE PATH IN ALL MASTER NODES

3.一旦运行RKE UP,Kubernetes API将自行重启。

$rke up

B.KUBEADM集群1.
SSH到节点。

$ssh Hyman@theitroad

2.编辑Kubernetes API配置。
添加OIDC参数并相应地修改发行者URL。

$sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml
...
    command:
    - /hyperkube
    - apiserver
    - --advertise-address=10.10.40.30 
#ADD THE FOLLOWING LINES:
... 
    - --oidc-issuer-url=https://auth.kubernetes.mydomain.com/
    - --oidc-client-id=oidc-auth-client
##ENSURE THE WILDCARD CERTIFICATES ARE PRESENT IN THIS FILE PATH IN ALL MASTER NODES: 
    - --oidc-ca-file=/etc/ssl/kubernetes/kubernetes.mydomain.com.crt    
    - --oidc-username-claim=email
    - --oidc-groups-claim=groups
...
  1. Kubernetes API将自行重启。

步骤3:部署Oauth2代理并配置kubernetes仪表板入口

1.为Oauth2代理生成一个机密。

python -c 'import os,base64; print base64.urlsafe_b64encode(os.urandom(16))'

2.复制生成的密码,并在下一步中将其用于OAUTH2_PROXY_COOKIE_SECRET值。
创建一个oauth2-proxy-deployment.yaml文件。
相应地修改OIDC客户端密码,OIDC颁发者URL和Oauth2代理cookie密码。

$vim oauth2-proxy-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    k8s-app: oauth2-proxy
  name: oauth2-proxy
  namespace: auth-system
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: oauth2-proxy
  template:
    metadata:
      labels:
        k8s-app: oauth2-proxy
    spec:
      containers:
      - args:
        - --cookie-secure=false
        - --provider=oidc
        - --client-id=oidc-auth-client
        - --client-secret=** **** *****
        - --oidc-issuer-url=https://auth.kubernetes.mydomain.com/
        - --http-address=0.0.0.0:8080
        - --upstream=file:///dev/null
        - --email-domain=*
        - --set-authorization-header=true
        env:
        # docker run -ti --rm python:3-alpine python -c 'import secrets,base64; print(base64.b64encode(base64.b64encode(secrets.token_bytes(16))));'
        - name: OAUTH2_PROXY_COOKIE_SECRET
          value: ** **** *****
        image: sguyennet/oauth2-proxy:header-2.2
        imagePullPolicy: Always
        name: oauth2-proxy
        ports:
        - containerPort: 8080
          protocol: TCP

4.部署Oauth2代理。

$kubectl apply -f oauth2-proxy-deployment.yaml

5.创建一个oauth2-proxy-service.yaml文件。

$vim oauth2-proxy-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: oauth2-proxy
  name: oauth2-proxy
  namespace: auth-system
spec:
  ports:
  - name: http
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    k8s-app: oauth2-proxy

6.为Oauth2代理部署创建服务。

$kubectl apply -f oauth2-proxy-service.yaml

7.创建一个dashboard-ingress.yaml文件。
相应地修改仪表板URL和主机参数。

$vim dashboard-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kube-system
  annotations:
          nginx.ingress.kubernetes.io/auth-url: "https://dashboard.kubernetes.mydomain.com/oauth2/auth"
          nginx.ingress.kubernetes.io/auth-signin: "https://dashboard.kubernetes.mydomain.com/oauth2/start?rd=https://$host$request_uri$is_args$args"
          nginx.ingress.kubernetes.io/secure-backends: "true"
          nginx.ingress.kubernetes.io/configuration-snippet: |
            auth_request_set $token $upstream_http_authorization;
            proxy_set_header Authorization $token;
spec:
  rules:
  - host: dashboard.kubernetes.mydomain.com
    http:
      paths:
      - backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
        path: /

8.为仪表板服务创建入口。

$kubectl apply -f dashboard-ingress.yaml

9.创建一个kubernetes-dashboard-external-tls入口密码。
确保群集的证书数据在指定的位置,或者更改此路径以指向它。
如果使用证书管理器,请跳过此步骤。

$kubectl create secret tls kubernetes-dashboard-external-tls --key /data/Certs/kubernetes.mydomain.com.key --cert /data/Certs/kubernetes.mydomain.com.crt -n auth-system

10.创建一个oauth2-proxy-ingress.yaml文件。
相应地修改证书管理器颁发者和主机参数。

$vim oauth2-proxy-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/tls-acme: "true"
    ingress.kubernetes.io/force-ssl-redirect: "true"
  name: oauth-proxy
  namespace: auth-system
spec:
  rules:
  - host: dashboard.kubernetes.mydomain.com
    http:
      paths:
      - backend:
          serviceName: oauth2-proxy
          servicePort: 8080
        path: /oauth2
  tls:
  - hosts:
    - dashboard.kubernetes.mydomain.com
    secretName: kubernetes-dashboard-external-tls

10.为Oauth2代理服务创建入口。

$kubectl apply -f oauth2-proxy-ingress.yaml

11.创建角色绑定。

$kubectl create rolebinding <username>-rolebinding-<namespace> --clusterrole=admin --user=<username> -n <namespace>
e.g
kubectl create rolebinding mkemei-rolebinding-default --clusterrole=admin Hyman@theitroad -n default 
//Note that usernames are case sensitive and we need to confirm the correct format before applying the rolebinding.

12.等待几分钟,然后浏览至https://dashboard.kubernetes.mydomain.com.13.
用Active Directory用户登录。

如下所示:Hyman @ theitroad应该能够查看和修改默认名称空间。