在Kubernetes中,“自建账号”通常指管理员手动创建用于访问API Server的用户(区别于系统自动管理的Service Account)。Kubernetes的认证机制支持多种方式,最常用的包括客户端证书认证和静态令牌认证。以下是详细的实现步骤和说明:
一、认证概述
Kubernetes API Server的访问流程分为三步:认证(Authentication)→ 授权(Authorization)→ 准入控制(Admission Control)。
“自建账号”的核心是完成认证环节,即让API Server识别用户身份。认证通过后,还需通过RBAC(基于角色的访问控制)配置权限(授权),否则用户仅能“登录”但无操作权限。
二、客户端证书认证(推荐)
客户端证书认证是Kubernetes中最安全、最常用的方式(类似HTTPS双向认证)。流程为:生成用户证书 → 用集群CA签名 → 配置用户通过证书访问API Server。
步骤1:生成用户私钥和证书签名请求(CSR)
使用openssl工具生成用户私钥和CSR(证书签名请求),需指定用户名(CN)和所属组(O,可选)。
示例:创建一个名为dev-user、所属组为dev-group的用户
# 生成私钥(dev-user.key)
openssl genrsa -out dev-user.key 2048
# 生成CSR(dev-user.csr),CN为用户名,O为组(可多个,用逗号分隔)
openssl req -new -key dev-user.key -out dev-user.csr -subj "/CN=dev-user/O=dev-group"
步骤2:用集群CA签名证书
Kubernetes集群的CA证书和私钥默认存储在/etc/kubernetes/pki/(kubeadm部署),需用CA签名用户的CSR,生成可被API Server信任的证书。
# 用CA签名CSR,生成用户证书(dev-user.crt),有效期365天
openssl x509 -req -in dev-user.csr \
-CA /etc/kubernetes/pki/ca.crt \ # 集群CA证书
-CAkey /etc/kubernetes/pki/ca.key \ # 集群CA私钥
-CAcreateserial \
-out dev-user.crt \
-days 365
生成的dev-user.crt(证书)和dev-user.key(私钥)将用于用户认证。
步骤3:配置kubeconfig文件
用户通过kubeconfig文件管理集群、用户、认证信息。需将生成的证书配置到kubeconfig中。
# 1. 设置集群信息(指向API Server,信任CA)
kubectl config set-cluster kubernetes \
--server=https://<API-Server-IP>:6443 \ # 替换为API Server地址
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true # 将CA证书嵌入kubeconfig(避免依赖本地文件)
# 2. 设置用户信息(关联证书和私钥)
kubectl config set-credentials dev-user \
--client-certificate=./dev-user.crt \
--client-key=./dev-user.key \
--embed-certs=true # 嵌入用户证书和私钥
# 3. 设置上下文(绑定集群和用户)
kubectl config set-context dev-user-context \
--cluster=kubernetes \
--user=dev-user
# 4. 切换到该上下文
kubectl config use-context dev-user-context
此时,用户可通过该kubeconfig文件访问API Server(默认路径为~/.kube/config,或通过--kubeconfig指定)。
三、静态令牌认证(适合临时用户)
静态令牌认证通过预定义的令牌(Token)文件实现,API Server启动时加载该文件,用户通过在请求头中携带令牌认证。
缺点:令牌文件修改后需重启API Server才生效,适合临时用户。
步骤1:生成令牌并创建令牌文件
令牌是随机字符串(建议长度≥16字节),格式为CSV文件:token,username,useruid,"group1,group2"。
# 生成随机令牌(示例:z4f8t8...)
TOKEN=$(head -c 16 /dev/urandom | base64)
# 创建令牌文件(/etc/kubernetes/tokens.csv)
echo "${TOKEN},dev-user,10001,\"dev-group\"" > /etc/kubernetes/tokens.csv
步骤2:配置API Server加载令牌文件
需修改API Server的启动参数,指定令牌文件路径(kubeadm部署的集群,API Server配置在/etc/kubernetes/manifests/kube-apiserver.yaml)。
编辑kube-apiserver.yaml,在spec.containers.command中添加:
spec:
containers:
- command:
- kube-apiserver
- --token-auth-file=/etc/kubernetes/tokens.csv # 添加此行
# 其他参数...
volumeMounts:
- name: tokens # 挂载令牌文件到容器
mountPath: /etc/kubernetes/tokens.csv
readOnly: true
volumes:
- name: tokens # 定义宿主机路径
hostPath:
path: /etc/kubernetes/tokens.csv
type: File
保存后,kubelet会自动重启API Server Pod(无需手动重启)。
步骤3:用户通过令牌访问
用户可通过令牌在请求头中携带认证信息,或配置到kubeconfig:
# 配置kubeconfig的用户信息(使用令牌)
kubectl config set-credentials dev-user --token=${TOKEN}
# 后续步骤同证书认证(设置集群、上下文)
四、认证后的授权(RBAC配置)
认证仅验证用户身份,需通过RBAC配置权限(否则用户无任何操作权限)。示例:授予dev-user查看default命名空间Pod的权限。
# 1. 创建Role(定义权限)
kubectl create role pod-reader \
--namespace=default \
--verb=get,list,watch \
--resource=pods
# 2. 绑定Role到用户(授权)
kubectl create rolebinding dev-user-pod-reader \
--namespace=default \
--role=pod-reader \
--user=dev-user
五、各认证方式对比
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 客户端证书认证 | 安全(有效期可控)、无需重启 | 生成步骤稍复杂 | 长期用户、生产环境 |
| 静态令牌认证 | 配置简单 | 修改需重启API Server | 临时用户、测试环境 |
| Service Account | 自动管理(令牌自动轮换) | 仅用于Pod内进程访问 | 容器内应用访问API Server |
通过以上步骤,即可完成Kubernetes自建账号的认证配置。实际使用中,推荐优先选择客户端证书认证,并结合RBAC严格控制权限。
X509认证
1.创建出用户的私钥
# 创建放用户证书的目录
root@k8s-master01:~# cd /etc/kubernetes
root@k8s-master01:/etc/kubernetes# mkdir usercerts
root@k8s-master01:/etc/kubernetes# cd usercerts/
# 创建一个私钥
root@k8s-master01:/etc/kubernetes/usercerts# (umask 077; openssl genrsa -out darius.key 2048)
Generating RSA private key, 2048 bit long modulus (2 primes)
...........................................................+++++
.....................+++++
e is 65537 (0x010001)
2.基于私钥创建一个证书签署请求,此签署请求需要被k8s的CA所签署
# 生成证书签署请求,需要注意此处CN将会被做为用户名,O将会被作为组名使用
root@k8s-master01:/etc/kubernetes/usercerts# openssl req -new -key darius.key -out darius.csr -subj "/CN=darius/O=kubeusers"
root@k8s-master01:/etc/kubernetes/usercerts# ls
darius.csr darius.key
3.将用户的证书签署请求,使用k8s的CA签署成证书
# 签署时需要指定k8s CA的证书,CA的私钥,以及CA自己维护的序列号。
root@k8s-master01:/etc/kubernetes/usercerts# openssl x509 -req -days 3655 -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -in darius.csr -out darius.crt
Signature ok
subject=CN = darius, O = kubeusers
Getting CA Private Key
# 可以使用以下命令查看证书的详细信息
root@k8s-master01:/etc/kubernetes/usercerts# openssl x509 -in darius.crt -text -noout
自制kubeconfig文件尝试认证到k8s
1.设定集群信息
# 设定集群信息,需要指定集群名字,指定集群服务器地址,指定k8s的ca证书,最后指定生成的kubeconfig文件。
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config set-cluster kubernetes --server=https://kube-api:6443 --embed-certs --certificate-authority=/etc/kubernetes/pki/ca.crt --kubeconfig=/tmp/mykubeconfig
Cluster "kubernetes" set.
# 查看kubeconfig内信息
root@k8s-master01:/etc/kubernetes/usercerts# cat /tmp/mykubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1EY3hOVEEyTVRNek5Gb1hEVE14TURjeE16QTJNVE16TkZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTnZjCkc0NytMTUUydkxsNzJXNUpWYSt1S2VLY1htWVNFVjVXSmtCSkl4VjBZK0JkRExtb044WWxSWUdVaDVxTmxRRUQKOFhRSzgzOUNOUUl4ZGRSQWc3c1M4Z2I2SWdabGxCRXNobGRGb0JEcjNDUUlzMWxGMEFsVEFyV2RpK0NUbHdZYwpyYTRTREN6ZHVQUDZhdzFHWVBTNE9zOUtsUEpVZHpPMXRkUjdGNVBHVkY3SWpsWE1EMWc3NW1yL2d6NkgrcTVOCkN0S1UraFJ2WGd5QXN1TDY1TFlROUVEMyt1K0lJSE5xQWR4S1lXRkFmZ2tNT3Bqa0V3Z2xRWUUzenhWREdZR0EKdFI5clg5STNQUHF0UkkwWVdqb2EveGtxY1lhUTNRckhzU3ZBTjU5b2FyV3plS2xuMS8wWVdVeEd0cEZtdy92ZQpRMTYzYkVlc21YaDdSMERhMGhzQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZIWmV1cEFHdnZ4c0pkSHl5N3hTVUNoZFNGY1hNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFBTVUySkVrdU1QZ0ltSDlaSzk2OHRsY05HNVRsVFVseFVYRm9Uc1VTSWhyU1pycGhmRApKelBOTE5rcTJxMCtUV3ZTbHZxbzFyM2dLckhNWWZDY1AwTnFIU2VYVWNhaW1WeUhwUm12M3AzODBoTlJONnNyCkJZSmZ4RUE0aWJsWEpvYnNVR0tDcmdZeHk5SFJYbE9ud0QvMHdrTVVBZHFuSG90MlRPbGJZSVU3aUNTNklCajMKaWZLeHlGdkdDTWJ6NFhIY0xjajY4L3AzaC9VRDgxRjNGc2ZqdmV6L1A3Nk42L2hCL090TkhKK3pTWGVmdjJjcQpMUXBxYXA5aW9IUGZTVFpnTm5BUndSWUNaMW9DdmI0WitnbzdkQTROM3M2K3NOTUpYZFFERWkxb1dWeDVKUXgyClgzejNtY1hhZHROTVgwOEN0UHorTlQwZGZGOUNhaDVWMTkzWgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://kube-api:6443
name: kubernetes
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null
2.设定用户信息
# 设定用户信息时需要指定用户名,此处使用的x509认证,所以还需要指定用户的证书,用户的私钥,embed-certs表示是否将用户的证书信息嵌入kubeconfig文件,最后指定kubeconfig文件目录
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config set-credentials darius --client-certificate=darius.crt --client-key=darius.key --embed-certs=true --kubeconfig=/tmp/mykubeconfig
User "darius" set.
# 查看kubeconfig文件
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config view --kubeconfig=/tmp/mykubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://kube-api:6443
name: kubernetes
contexts: null
current-context: ""
kind: Config
preferences: {}
users:
- name: darius
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
3.设定用户和集群的关联关系
# 设定关联关系的名称,指定用户,指定集群,指定kubeconfig文件
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config set-context 'darius@kubernetes' --user=darius --cluster=kubernetes --kubeconfig=/tmp/mykubeconfig
Context "darius@kubernetes" created.
# 查看kubeconfig信息
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config view --kubeconfig=/tmp/mykubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://kube-api:6443
name: kubernetes
contexts:
- context: # context信息被建立
cluster: kubernetes
user: darius
name: darius@kubernetes
current-context: ""
kind: Config
preferences: {}
users:
- name: darius
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
4.设定当前使用的context
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config use-context darius@kubernetes --kubeconfig=/tmp/mykubeconfig
Switched to context "darius@kubernetes".
# 查看kubeconfig信息
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config view --kubeconfig=/tmp/mykubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://kube-api:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: darius
name: darius@kubernetes
current-context: darius@kubernetes # 当前使用的为darius@kubernetes
kind: Config
preferences: {}
users:
- name: darius
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
5.kubeconfig文件已经创建完毕,尝试使用此文件进行认证
root@k8s-master01:/etc/kubernetes/usercerts# kubectl get nodes --kubeconfig=/tmp/mykubeconfig
Error from server (Forbidden): nodes is forbidden: User "darius" cannot list resource "nodes" in API group "" at the cluster scope
# 认证已经没有问题,报错是因为用户没有权限导致的。