基于k8s的RBAC体系的X509文件认证

106次阅读
没有评论
  • 认证授权案例,要求如下:
    • 1.以你自己的英文名生成证书文件,并生成对应的kubeconfig文件;
    • 2.可以使用该kubeconfig文件部署若依服务;
    • 3.要求在worker233节点进行服务的部署;

一、K8s 官方标准 CSR 签发(比 openssl 签发更规范)

流程就是:

  1. 生成用户私钥 → 生成 csr 文件 → base64 编码
  2. 创建CertificateSigningRequest(CSR)资源
  3. kubectl approve 签发
  4. 导出证书 → 生成 kubeconfig
  5. RBAC 授权
  6. 部署若依到 worker233 (10.0.0.233)

二、用户名:luzhiwei

1. 创建工作目录

mkdir -p /manifests/auth/lzw

2. 生成 luzhiwei 私钥 + CSR 文件

生成私钥

root@master231:/manifests/auth/lzw# openssl genrsa -out luzhiwei.key 2048

生成证书请求文件(CN=luzhiwei 用户名)

root@master231:/manifests/auth/lzw# openssl req -new -key luzhiwei.key -out luzhiwei.csr -subj "/CN=luzhiwei/O=devpos"

3. 对 CSR 做 BASE64 编码(用于 CSR 资源清单)

root@master231:/manifests/auth/lzw# cat luzhiwei.csr | base64 | tr -d '\n';echo

把输出的一长串字符串复制下来,等下要放进 yaml 里的 <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">request:</font> 字段。

4. 创建 CSR 资源清单

核心目的:生成一个 Kubernetes 证书签名请求(CSR)资源配置文件,让 Kubernetes 集群能识别、处理刚才生成的用户证书申请,最终给用户签发合法的集群访问证书。 

root@master231:/manifests/auth/lzw#
cat > csr-luzhiwei.yaml << EOF 
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: luzhiwei-csr
spec:
  # 粘贴上面 base64 编码后的内容
  request: 【这里粘贴你刚刚生成的base64字符串】
  signerName: kubernetes.io/kube-apiserver-client
   # 过期时间1天
  expirationSeconds: 86400 
  usages:
  - client auth
EOF

5. 创建 CSR 请求

root@master231:/manifests/auth/lzw# kubectl apply -f csr-luzhiwei.yaml

root@master231:/manifests/auth/lzw# kubectl get csr

显示 <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">Pending</font> 正常。

6. 服务端手动签发证书

root@master231:/manifests/auth/lzw# kubectl certificate approve luzhiwei-csr

root@master231:/manifests/auth/lzw# kubectl get csr

显示 <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">Approved,Issued</font> 成功!

7. 从 CSR 中导出 luzhiwei 证书

root@master231:/manifests/auth/lzw# kubectl get csr luzhiwei-csr -o jsonpath='{.status.certificate}' | base64 -d > luzhiwei.crt

root@master231:/manifests/auth/lzw#tree .

.

├── csr-luzhiwei.yaml

├── luzhiwei.crt

├── luzhiwei.csr

└── luzhiwei.key

0 directories, 4 files

8. 为X509数字证书的用户生成kubeconfig

— luzhiwei.kubeconfig(API Server:10.0.0.231)

因为要在 233worker 节点鉴权,所以将证书文件拷贝到 233 节点 【也可以直接在 233 节点生成】

root@master231:/manifests/auth/lzw#scp -rp luzhiwei.* 10.0.0.233:/root/lzw/ruoyi
root@10.0.0.233's password: 
luzhiwei.crt                                                                                                                        100% 1115   734.4KB/s   00:00    
luzhiwei.csr                                                                                                                        100%  911   639.9KB/s   00:00    
luzhiwei.key                                                                                                                        100% 1704     1.0MB/s   00:00    
root@master231:/manifests/auth/lzw#

1 准备证书
root@worker233:~/lzw/ruoyi#tree .
.
├── luzhiwei.crt
├── luzhiwei.csr
└── luzhiwei.key
0 directories, 3 files
root@worker233:~/lzw/ruoyi#
为X509数字证书的用户生成kubeconfig
# 先定义 APISERVER 变量
root@worker233:~/lzw/ruoyi#  APISERVER=https://10.0.0.231:6443

# 1. 配置集群
root@worker233:~/lzw/ruoyi#  kubectl config set-cluster k8s-cluster \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \
  --embed-certs=true \
  --server=${APISERVER} \
  --kubeconfig=luzhiwei.kubeconfig

# 2. 配置用户
root@worker233:~/lzw/ruoyi#  kubectl config set-credentials luzhiwei \
  --client-certificate=luzhiwei.crt \
  --client-key=luzhiwei.key \
  --embed-certs=true \
  --kubeconfig=luzhiwei.kubeconfig

查看用户列表
root@worker233:~/lzw/ruoyi#  kubectl config get-users --kubeconfig=luzhiwei.kubeconfig
NAME
luzhiwei

# 3. 配置上下文
root@worker233:~/lzw/ruoyi# kubectl config set-context luzhiwei@k8s-cluster \
  --cluster=k8s-cluster \
  --user=luzhiwei \
  --namespace=ruoyi \
  --kubeconfig=luzhiwei.kubeconfig

# 4. 切换默认上下文
root@worker233:~/lzw/ruoyi#  kubectl config use-context luzhiwei@k8s-cluster --kubeconfig=luzhiwei.kubeconfig

执行完验证(看看是否生成成功)

root@worker233:~/lzw/ruoyi#kubectl config view --kubeconfig=luzhiwei.kubeconfig
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.0.0.231:6443
  name: k8s-cluster
contexts:
- context:
    cluster: k8s-cluster
    namespace: ruoyi
    user: luzhiwei
  name: luzhiwei@k8s-cluster
current-context: luzhiwei@k8s-cluster
kind: Config
preferences: {}
users:
- name: luzhiwei
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

测试权限(验证证书是否可用)

root@worker233:~/lzw/ruoyi#kubectl get pods --kubeconfig=luzhiwei.kubeconfig
No resources found in ruoyi namespace.
root@worker233:~/lzw/ruoyi#

三、RBAC 授权 [ 让 luzhiwei 能部署若依 ]

1.未授权前测试

~/.kube/config   #这是系统默认配置文件。
root@worker233:~/lzw/ruoyi#cp luzhiwei.kubeconfig ~/.kube/config

当前节点的默认 kubectl 身份 → 切换成 luzhiwei
从此以后,你直接敲:
kubectl get pods

就等价于:
kubectl get pods --kubeconfig=luzhiwei.kubeconfig

root@worker233:~/lzw/ruoyi#kubectl config view --kubeconfig=luzhiwei.kubeconfig
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.0.0.231:6443
  name: k8s-cluster
contexts:
- context:
    cluster: k8s-cluster
    namespace: ruoyi
    user: luzhiwei
  name: luzhiwei@k8s-cluster
current-context: luzhiwei@k8s-cluster
kind: Config
preferences: {}
users:
- name: luzhiwei
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

未授权发现被拒绝访问

root@worker233:~/lzw/ruoyi#kubectl get role --kubeconfig=luzhiwei.kubeconfig -n ruoyi
Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden: User "luzhiwei" cannot list resource "roles" in API group "rbac.authorization.k8s.io" in the namespace "ruoyi"

2. 去 master 节点 执行:

1. 创建命名空间

kubectl create namespace ruoyi

2. 创建 Role [ 声明式 ]

cat > ruoyi-role.yaml <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: ruoyi
  name: deploy-ruoyi
rules:
# 核心工作负载权限
- apiGroups: [""]
  resources: ["pods","pods/log","services","configmaps","secrets","persistentvolumeclaims","events","namespaces"]
  verbs: ["get","list","watch","create","update","patch","delete"]

# 容器调试权限(exec、日志、端口转发)
- apiGroups: [""]
  resources: ["pods/exec","pods/portforward"]
  verbs: ["create"]

# Apps 资源
- apiGroups: ["apps"]
  resources: ["deployments","replicasets","statefulsets","daemonsets"]
  verbs: ["get","list","watch","create","update","patch","delete"]

# 网络资源
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses","ingresses/status"]
  verbs: ["get","list","watch","create","update","patch","delete"]

# RBAC 查看权限(你需要的)
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["roles","rolebindings"]
  verbs: ["get","list","watch"]

# 任务/定时任务
- apiGroups: ["batch"]
  resources: ["jobs","cronjobs"]
  verbs: ["get","list","watch","create","update","patch","delete"]
EOF

kubectl apply -f ruoyi-role.yaml

root@master231:/manifests/auth/lzw#kubectl get role -n ruoyi
NAME           CREATED AT
deploy-ruoyi   2026-04-21T16:40:41Z

【授权用户并绑定角色】

root@master231:/manifests/auth/lzw# cat > rbac-lzw.yaml << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: ruoyi
  name: deploy-ruoyi
rules:
# 核心工作负载权限
- apiGroups: [""]
  resources: ["pods","pods/log","services","configmaps","secrets","persistentvolumeclaims","events","namespaces"]
  verbs: ["get","list","watch","create","update","patch","delete"]

# 容器调试权限(exec、日志、端口转发)
- apiGroups: [""]
  resources: ["pods/exec","pods/portforward"]
  verbs: ["create"]

# Apps 资源
- apiGroups: ["apps"]
  resources: ["deployments","replicasets","statefulsets","daemonsets"]
  verbs: ["get","list","watch","create","update","patch","delete"]

# 网络资源
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses","ingresses/status"]
  verbs: ["get","list","watch","create","update","patch","delete"]

# RBAC 查看权限
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["roles","rolebindings"]
  verbs: ["get","list","watch"]

# 任务/定时任务
- apiGroups: ["batch"]
  resources: ["jobs","cronjobs"]
  verbs: ["get","list","watch","create","update","patch","delete"]

---
# 绑定用户 luzhiwei
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: luzhiwei-ruoyi
  namespace: ruoyi
subjects:
- kind: User
  # 你的证书用户名
  name: luzhiwei
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: deploy-ruoyi
  apiGroup: rbac.authorization.k8s.io
EOF

root@master231:/oldboyedu/manifests/auth/lzw# 
kubectl apply -f rbac-lzw.yaml 

授权之后检查权限

root@worker233:~/lzw/ruoyi#kubectl get role --kubeconfig=luzhiwei.kubeconfig -n ruoyi
NAME           CREATED AT
deploy-ruoyi   2026-04-21T16:40:41Z
root@worker233:~/lzw/ruoyi#

四、在 worker 节点部署若依

root@worker233:~/lzw/ruoyi# cat ruoyi-role-luzhiwei.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-cnf
  namespace: ruoyi
data:
  my.cnf: |
    [mysqld]
    skip-host-cache
    skip-name-resolve
    datadir=/var/lib/mysql
    socket=/var/run/mysqld/mysqld.sock
    secure-file-priv=/var/lib/mysql-files
    user=mysql
    pid-file=/var/run/mysqld/mysqld.pid
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    
    [client]
    socket=/var/run/mysqld/mysqld.sock
    default-character-set=utf8mb4
    !includedir /etc/mysql/conf.d/

  ry_20260319.sql: |
    -- ----------------------------
    -- 1、部门表
    -- ----------------------------
    drop table if exists sys_dept;
    create table sys_dept (


---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-mysql-server
  namespace: ruoyi
spec:
  replicas: 1
  selector:
    matchLabels:
      apps: db
  template: 
    metadata:
      labels:
         apps: db
    spec:
      nodeName: worker233
      volumes:
      - name: datetime
        hostPath:
          path: /etc/localtime
      - name: mycnf
        configMap:
          name: my-cnf
          items:
          - key: my.cnf
            path: my.cnf
          - key: quartz.sql
            path: quartz.sql
          - key: ry_20260319.sql
            path: ry_20260319.sql
      containers:
      - name: db
        image: harbor250.luzhiwei.com/luzhiwei-db/mysql:8.0.36-oracle
        volumeMounts:
        - name: datetime
          mountPath: /etc/localtime
        - name: mycnf
          subPath: my.cnf
          mountPath: /etc/my.cnf
        - name: mycnf
          subPath: quartz.sql
          mountPath: /docker-entrypoint-initdb.d/quartz.sql
        - name: mycnf
          subPath: ry_20260319.sql
          mountPath: /docker-entrypoint-initdb.d/ry_20260319.sql
        env:
        - name: MYSQL_DATABASE
          value: ry
        - name: MYSQL_USER
          value: linux102
        - name: MYSQL_PASSWORD
          value: oldboyedu
        - name: MYSQL_ALLOW_EMPTY_PASSWORD
          value: "yes"
        args:
        - --character-set-server=utf8mb4
        - --collation-server=utf8mb4_unicode_ci
        - --default-authentication-plugin=mysql_native_password

        # MySQL 健康探针
        readinessProbe:
          exec:
            command: ["mysqladmin", "ping", "-h", "localhost"]
          # 60秒后再开始检查(给足初始化时间)
          initialDelaySeconds: 60
          # 每10秒查一次
          periodSeconds: 10
          # 连续失败10次才判定失败(非常宽松)
          failureThreshold: 10        
        livenessProbe:
          exec:
            command: ["mysqladmin", "ping", "-h", "localhost"]
          # 120秒后才开始存活检查
          initialDelaySeconds: 90
          periodSeconds: 20
          failureThreshold: 10

---
apiVersion: v1
kind: Service
metadata:
  name: svc-db
  namespace: ruoyi
spec:
  selector:
    apps: db
  ports:
  - port: 3306

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-ruoyi
  namespace: ruoyi
spec:
  replicas: 1
  selector:
    matchLabels:
      apps: ruoyi
  template: 
    metadata:
      labels:
         apps: ruoyi
    spec:
      nodeName: worker233
      # 关键:强制等待 MySQL 就绪
      initContainers:
      - name: wait-for-mysql-ready
        image: harbor250.luzhiwei.com/busy-1.28/busybox:1.28.4
        command:
        - sh
        - -c
        - |
          until nc -z svc-db 3306; do sleep 2; done
          sleep 30
      containers:
      - name: ruoyi
        image: harbor250.luzhiwei.com/luzhiwei-ruoyi/ruoyi-single:v0.1
        env:
        - name: SPRING_DATASOURCE_URL
          value: "jdbc:mysql://svc-db:3306/ry?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai"
        - name: SPRING_DATASOURCE_USERNAME
          value: "luzhiwei"
        - name: SPRING_DATASOURCE_PASSWORD
          value: "luzhiwei"
        # 宽松探针,不做多余检查
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 60
          periodSeconds: 10
          failureThreshold: 5
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 70
          periodSeconds: 30
          failureThreshold: 5

---
apiVersion: v1
kind: Service
metadata:
  name: svc-ruoyi
  namespace: ruoyi
spec:
  type: LoadBalancer
  selector:
    apps: ruoyi
  ports:
  - port: 80 

用 luzhiwei 身份部署

root@worker233:~/lzw/ruoyi#kubectl apply -f  ruoyi-role-luzhiwei.yaml --kubeconfig=luzhiwei.kubeconfig
configmap/my-cnf created
deployment.apps/deploy-mysql-server created
service/svc-db created
deployment.apps/deploy-ruoyi created
service/svc-ruoyi created
root@worker233:~/lzw/ruoyi#

五、验证(最终验收命令)

kubectl get all -n ruoyi -o wide --kubeconfig=luzhiwei.kubeconfig
基于k8s的RBAC体系的X509文件认证

K8s 标准声明式证书签发

1. 生成用户私钥与证书签名请求
2. 创建 CertificateSigningRequest 资源
3. 管理员执行 kubectl certificate approve 完成签发
4. 导出证书生成 kubeconfig
5. 通过 RBAC 授权用户部署权限

你报错,是因为当前 shell 环境里还带着旧的 KUBECONFIG 环境变量 / 旧配置!不是文件没删,是 kubectl 还在读取冲突的配置!

root@worker233:~/lzw/ruoyi#kubectl -s https://10.0.0.231:6443 --client-key luzhiwei.key --client-certificate luzhiwei.crt --insecure-skip-tls-verify get nodes
Error in configuration: 
* client-cert-data and client-cert are both specified for jiege. client-cert-data will override.
* client-key-data and client-key are both specified for jiege; client-key-data will override

你只需要在 worker233 节点 执行这一条命令(直接复制)

unset KUBECONFIG && rm -f ~/.kube/config && kubectl --kubeconfig=/dev/null -s https://10.0.0.231:6443 --client-key luzhiwei.key --client-certificate luzhiwei.crt --insecure-skip-tls-verify get nodes

这条命令做了 3 件事(保证 100% 不冲突)

1. unset KUBECONFIG:清空环境变量(最关键!)
2. rm -f ~/.kube/config:删除残留配置
3. --kubeconfig=/dev/null:强制 kubectl 不读取任何配置文件→ 彻底杜绝 jiege 旧用户冲突

正文完
 0
评论(没有评论)