在K8s集群部署Dex认证

Dex是一个开源的第三方身份认证系统,简化了与已有身份提供者或其他认证服务进行认证的开发流程,Dex将检查身份的过程对项目开发者隐藏,使得开发者只需要关注、控制认证业务进行的客体,无需亲自管理身份认证的各项细节 环境 OS:Debian-12.10.0-amd64 Kubernetes:v1.28.0 kubectl:v1.28.2 Helm:v3.17.3 master机已安装Git,已部署LDAP服务器 开发者没有备案的域名,无法进行DNS A解析,只能使用自签名证书 获取dex-k8s-authenticator Dex本身是可以直接使用的,但是如果想要将Dex部署至K8s集群中并提供友好的可视页面,则需要部署dex-k8s-authenticator(之后简称DKA) 执行:git clone https://github.com/mintel/dex-k8s-authenticator.git克隆该Git仓库,仓库的charts/路径中已经存在Dex和DKA的Chart文件,因此无需再单独克隆获取Dex文件 ficn@master:~$ git clone https://github.com/mintel/dex-k8s-authenticator.git ficn@master:~$ cd dex-k8s-authenticator/ ficn@master:~/dex-k8s-authenticator$ ls charts/ dex dex-k8s-authenticator README.md 运行Dex和DKA 执行: helm inspect values charts/dex > dex-values.yaml helm inspect values charts/dex-k8s-authenticator > dka-values.yaml 这两个指令目的是根据Dex和DKA的原始Chart生成各自的新values文件,用于之后覆盖原配置 接下来就对这两个values文件进行修改 Dex # sudo vi dex-values.yaml # Default values for dex # Deploy environment label, e.g. dev, test, prod global: deployEnv: dev replicaCount: 1 image: repository: dexidp/dex tag: v2.37.0 pullPolicy: IfNotPresent env: - name: KUBERNETES_POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace service: type: NodePort port: 5556 nodePort: 30000 # For nodeport, specify the following: # type: NodePort # nodePort: <port-number> tls: create: false ingress: enabled: false annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" path: / hosts: - dex.example.com tls: [] # - secretName: dex.example.com # hosts: # - dex.example.com rbac: # Specifies whether RBAC resources should be created create: true serviceAccount: # Specifies whether a ServiceAccount should be created create: true # The name of the ServiceAccount to use. # If not set and create is true, a name is generated using the fullname template name: resources: {} nodeSelector: {} tolerations: [] affinity: {} # Configuration file for Dex # Certainly secret fields can use environment variables # config: |- issuer: http://192.168.92.128:30000 storage: type: kubernetes config: inCluster: true web: http: 0.0.0.0:5556 # If enabled, be sure to configure tls settings above, or use a tool # such as let-encrypt to manage the certs. # Currently this chart does not support both http and https, and the port # is fixed to 5556 # # https: 0.0.0.0:5556 # tlsCert: /etc/dex/tls/tls.crt # tlsKey: /etc/dex/tls/tls.key 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 # Remember you can have multiple connectors of the same 'type' (with different 'id's) # If you need e.g. logins with groups for two different Microsoft 'tenants' connectors: # These may not match the schema used by your LDAP server # https://github.com/coreos/dex/blob/master/Documentation/connectors/ldap.md - type: ldap id: ldap name: LDAP config: host: 192.168.92.128:389 insecureNoSSL: true startTLS: false bindDN: cn=admin,dc=example,dc=com bindPW: "647252" userSearch: # Query should be "(&(objectClass=inetorgperson)(cn=<username>))" baseDN: ou=People,dc=example,dc=com filter: "(objectClass=inetorgperson)" username: cn # DN must be in capitals idAttr: DN emailAttr: mail nameAttr: cn preferredUsernameAttr: cn groupSearch: # Query should be "(&(objectClass=groupOfUniqueNames)(uniqueMember=<userAttr>))" baseDN: ou=Group,dc=example,dc=com filter: "" # DN must be in capitals userAttr: DN groupAttr: member nameAttr: cn # The 'name' must match the k8s API server's 'oidc-client-id' staticClients: - id: my-cluster name: "my-cluster" secret: "pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok" redirectURIs: - http://192.168.92.128:30001/callback enablePasswordDB: True staticPasswords: - email: "[email protected]" # bcrypt hash of the string "password" hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" username: "admin" userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" # You should not enter your secrets here if this file will be stored in source control # Instead create a separate file to hold or override these values # You need only list the environment variables you used in the 'config' above # You can add any additional ones you need, or remove ones you don't need # envSecrets: # GitHub GITHUB_CLIENT_ID: "override-me" GITHUB_CLIENT_SECRET: "override-me" # Google (oidc) GOOGLE_CLIENT_ID: "override-me" GOOGLE_CLIENT_SECRET: "override-me" # Microsoft MICROSOFT_APPLICATION_ID: "override-me" MICROSOFT_CLIENT_SECRET: "override-me" # LDAP LDAP_BINDPW: "123456" 如上所示: ...

May 23, 2025

测试K8s集群内部联通性

设置集群时,有时需要测试集群内部Pod之间的连通性,或是测试DNS服务是否正常 可以使用kubectl run命令来创建一个Pod,并指定Pod名称、镜像以及命名空间 例如,创建一个busybox镜像,目的是测试kube-authen命名空间下的Pod是否能ping通、DNS服务是否生效: kubectl run ping-test --image=busybox -n kube-authen -it -- sh 以上命令的含义是:在kube-authen命名空间内创建一个镜像为busybox的Pod,Pod名称为ping-test,创建后立刻打开一个交互式终端 在终端内即可进行ping测试或是nslookup测试 有时仅需要进行临时测试,测试完毕后需要立刻删除Pod,那么可以执行指令: kubectl run ping-test --image=busybox -n kube-authen -it --rm -- ping google.com 这里的--rm参数意为“会话结束后自动删除Pod” 注意 如果仅创建了busybox的Pod而没有指定运行命令,例如kubectl run ping-test --image=busybox -n kube-authen,则会导致Pod无限重启,原因是: 在未指定命令的情况下,busybox使用默认入口点,默认行为是启动shell,但启动shell后没有可执行的命令,于是shell自动退出,这表现为容器进程退出,K8s即认为容器启动失败并进行自动重启,如此不断循环,产生CrashLoopBackOff错误

April 16, 2025

将Go服务部署至K8s提供Webhook认证

以之前构建完成的Webhook工程为例,将此Go应用部署至k8s中并指定为认证服务器 构建镜像 在工程根目录创建Dockerfile: FROM alpine:3.17 WORKDIR /app # 复制已编译好的二进制文件(此处hook-demo为已构建的Go应用) COPY hook-demo /app/ # 设置可执行权限 RUN chmod +x /app/hook-demo # 暴露服务端口 EXPOSE 9999 # 运行应用 CMD ["/app/hook-demo"] 在Dockerfile所在目录中,运行sudo docker build -t webhook-auth:v1.0 . 完成后检查: ficn@master:~/k8s-webhook-auth$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE webhook-auth v1.0 536c17b2a66c 13 seconds ago 31.8MB alpine 3.17 775f483016a7 7 months ago 7.08MB Pod与Service部署 创建deploy-webhook.yaml: # ~/deploy/deploy-webhook.yaml apiVersion: apps/v1 kind: Deployment metadata: name: webhook-auth namespace: kube-authen # 命名空间 labels: app: webhook-auth spec: replicas: 1 # 本地开发环境,使用单个副本 selector: matchLabels: app: webhook-auth template: metadata: labels: app: webhook-auth spec: containers: - name: webhook-auth image: webhook-auth:v1.0 # 本地镜像名称 imagePullPolicy: Never # 强制使用本地镜像,不尝试从远程拉取 ports: - containerPort: 9999 # webhook实际端口 name: http 创建service-webhook.yaml: ...

April 10, 2025

构建基于Webhook的LDAP认证环境

本文章所描述的各操作最终目的是将Webhook服务接入Kubernetes集群的认证流程中 LDAP安装 对于Ubuntu,使用apt安装命令:apt-get install -y slapd ldap-utils 安装过程中会出现交互式界面,可以在其中配置管理员密码(不重要,接下来会再次配置) 安装后,slapd服务即开始执行,此时运行dpkg-reconfigure slapd命令,对slapd服务再次进行配置 如果提示未找到dpkg-reconfigure命令,则执行sudo apt install debconf进行安装,若已安装,则可能是dpkg-reconfigure未被配置到PATH中,可以临时使用绝对路径:sudo /usr/sbin/dpkg-reconfigure slapd 配置界面将再次出现,在其中设置: 属性 配置 Omit configuration No DNS domain example.com Organization name orgldap Administrator password 647252 Remove database No Move old database Yes 初始设置完成后,在终端输入sudo slapcat命令即可查看条目: ficn@master:~$ sudo slapcat dn: dc=example,dc=com objectClass: top objectClass: dcObject objectClass: organization o: orgldap dc: example structuralObjectClass: organization entryUUID: 8056974e-a31a-103f-8e78-156a6f1ed35c creatorsName: cn=admin,dc=example,dc=com createTimestamp: 20250401075602Z entryCSN: 20250401075602.540676Z#000000#000#000000 modifiersName: cn=admin,dc=example,dc=com modifyTimestamp: 20250401075602Z 增加条目 创建组织 创建文件base.ldif,设置三个条目,分别为组织管理者、人员组织单位以及组的组织单位 ...

April 2, 2025

Docker环境下安装AList过程与心得

最近在树莓派上使用Docker部署了AList作为个人云盘使用,同时AList还支持整合各大网盘资源,可以极大方便我管理自己的网盘资源,在这里记录一下部署的过程,供之后参考 Docker环境安装 在Linux环境中安装Docker非常方便,直接下载即可。我的树莓派是基于Debian的系统所以直接安装即可,没有遇到什么问题,注意国内网络需要在/etc/docker/daemon.json配置一下镜像源。 docker有效镜像源持续更新网站:Docker/DockerHub 国内镜像源/加速列表(2月15日更新-长期维护) 对于Windows系统,安装Docker的步骤相对比较复杂,参考文章:Windows 11:Docker Desktop 安装和配置指南,因为我是在树莓派上安装的AList,所以有关Windows系统部署AList的过程不在本文讨论中 安装完成后,执行systemctl status docker检查Docker服务是否正常运行 外接硬盘配置 为了能让AList担当个人云盘的功能,我在树莓派外部设置了一个1TB的机械硬盘用于存储数据,硬盘插在硬盘盒上,通过USB线与树莓派连接 连接硬盘后,命令sudo fdisk -l可以查看硬盘的相关信息 在Linux中连接一个硬盘后,一些图形化的系统可以自动挂载硬盘,我的树莓派系统也可以自动挂载,但默认挂载点是在/media的,我不想让它挂载在这个地方,于是决定手动挂载 创建目录:/mnt/1TB_disk作为指定挂载点,然后进行挂载: sudo mount /dev/sda1 /mnt/1TB_disk 挂载完成后,命令lsblk -f可以查看硬盘的文件系统类型、UUID等信息: FICN@FICN:~ $ lsblk -f NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS sda └─sda1 exfat 1.0 67AF-3F5B 926.7G 1% /mnt/1TB_disk 但这样的话,每次连接硬盘时都需要手动挂载一次,很麻烦,所以可以使用autofs实现自动将连接的硬盘挂载至指定目录,当一段时间不使用硬盘资源时,autofs也会自动取消硬盘挂载 autofs自动挂载 sudo apt-get install autofs下载autofs,然后systemctl enable autofs、systemctl start autofs启动服务,创建/etc/auto.master添加: /mnt /etc/auto.disk --timeout=60 最后创建/etc/auto.disk并设置: 1TB_disk -fstype=exfat,raw,noatime :/dev/disk/by-uuid/67AF-3F5B 这里指定了硬盘文件系统类型为exfat,并使用UUID来指定需要被挂载的硬盘,这两个都是之前执行lsblk -f命令获得的信息 如此配置后,硬盘将被自动挂载至/mnt/1TB_disk目录 最后还要禁用系统原有的自动挂载服务:systemctl stop fstab、systemctl disable fstab ...

February 17, 2025