- 认证授权案例,要求如下:
- 1.以你自己的英文名生成证书文件,并生成对应的kubeconfig文件;
- 2.可以使用该kubeconfig文件部署若依服务;
- 3.要求在worker233节点进行服务的部署;
一、K8s 官方标准 CSR 签发(比 openssl 签发更规范)
流程就是:
- 生成用户私钥 → 生成 csr 文件 → base64 编码
- 创建
CertificateSigningRequest(CSR)资源 - kubectl approve 签发
- 导出证书 → 生成 kubeconfig
- RBAC 授权
- 部署若依到 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 标准声明式证书签发:
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 旧用户冲突
正文完