K8S-Demo集群实践03:准备集群各组件间HTTPS通讯需要的x509证书

K8S-Demo集群证书配置

  • 这里一次准备好集群内部通讯需要的所有证书
  • 你可以跳过本篇,在后续部署过程中需要相应证书的时候再创建

一、安装证书生产工具CFSSL

  • 本案例使用CloudFlare的PKI工具集cfssl创建所有证书
  • CSR:Certificate Signing Request 证书签名请求文件
[root@master1 ~]# mkdir -p /opt/install/soft/cfssl
[root@master1 ~]# cd /opt/soft/cfssl
[root@master1 cfssl]# wget https://github.com/cloudflare/cfssl/releases/download/v1.4.1/cfssl_1.4.1_linux_amd64
[root@master1 cfssl]# mv cfssl_1.4.1_linux_amd64 /opt/k8s/bin/cfssl
[root@master1 cfssl]# wget https://github.com/cloudflare/cfssl/releases/download/v1.4.1/cfssljson_1.4.1_linux_amd64
[root@master1 cfssl]# mv cfssljson_1.4.1_linux_amd64 /opt/k8s/bin/cfssljson
[root@master1 cfssl]# wget https://github.com/cloudflare/cfssl/releases/download/v1.4.1/cfssl-certinfo_1.4.1_linux_amd64
[root@master1 cfssl]# mv cfssl-certinfo_1.4.1_linux_amd64 /opt/k8s/bin/cfssl-certinfo
[root@master1 cfssl]# chmod +x /opt/k8s/bin/*
  • 获取缺省配置,可以根据需要在这个基础上修改
[root@master1 ~]# cd /opt/install/cert
[root@master1 cert]# cfssl print-defaults config > ca-config.json
[root@master1 cert]# cfssl print-defaults csr > ca-csr.json

二、创建根证书

  • CA(Certificate Authority)是自签名的根证书,用来签名其它证书
  • 如果没有特殊说明,后续操作均在master1节点上执行
  • 证书临时存放目录 /opt/install/cert

1、创建根证书配置文件 ca-config.json

[root@master1 ~]# cd /opt/install/cert
[root@master1 cert]# cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "k8s-demo-server": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      },
      "k8s-demo-client": {
        "usages": [
            "signing",
            "key encipherment",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF
  • expiry: “87600h”:证书有效期设置为10年
  • signing:表示该证书可用于签名其它证书(生成的 ca.pem 证书中 CA=TRUE)
  • key encipherment:秘钥加密
  • server auth:表示client可以用该该证书对server提供的证书进行验证
  • client auth:表示server可以用该该证书对client提供的证书进行验证

2、创建证书签名请求文件 ca-csr.json

[root@master1 ~]# cd /opt/install/cert
[root@master1 cert]# cat > ca-csr.json <<EOF
{
  "CN": "k8s-demo-ca",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [{
    "C" : "CN",
    "ST": "GuangDong",
    "L" : "ShenZhen",
    "O" : "k8s-demo",
    "OU": "jason@vip.qq.com"
  }],
  "ca": {
    "expiry": "87600h"
  }
}
EOF
  • CN :Common Name,kube-apiserver从证书中提取该字段作为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法
  • C :国家
  • ST :州,省
  • L : 地区,城市
  • O :Organization,组织名,公司名称,kube-apiserver从证书中提取该字段作为请求用户所属的组 (Group)
  • OU :组织内部单位名称,部门名称
  • 不同证书csr文件的CN、O、C、ST、L、OU组合必须不同,否则可能出现PEER’S CERTIFICATE HAS AN INVALID SIGNATURE错误

3、生成CA 根证书及私钥

[root@master1 ~]# cd /opt/install/cert
[root@master1 cert]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca
[root@master1 cert]# ls
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem

4、分发证书

[root@master1 ~]# cd /opt/install/cert
[root@master1 cert]# for node_ip in ${ALL_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p /opt/k8s/etc/cert"
    scp ca*.pem ca-config.json root@${node_ip}:/opt/k8s/etc/cert
  done

三、生成集群管理员admin的证书(kubectl->kube-apiserver)

1、准备证书签名请求文件 kub

<think> 我们面对的问题是:在Kubernetes集群中,Jenkins服务账户(位于命名空间`kube-devops`,名为`jenkins-admin`)尝试部署应用到命名空间`k8s-cicd-dev`时,出现了RBAC权限不足的错误。具体错误信息是: ``` from server for: "deploy/cicd-demo-dev.yaml": deployments.apps "k8s-cicd-demo" is forbidden: User "system:serviceaccount:kube-devops:jenkins-admin" cannot get resource "deployments" in API group "apps" in the namespace "k8s-cicd-dev": RBAC: clusterrole.rbac.authorization.k8s.io "jenkins-admin" not found ``` 错误的关键点: 1. 错误表明在命名空间`k8s-cicd-dev`中,对资源`deployments`(属于API组`apps`)执行`get`操作被禁止。 2. 错误还提到集群角色`jenkins-admin`未找到。 根据错误信息,我们可以推断: - Jenkins使用的服务账户`jenkins-admin`在命名空间`kube-devops`中。 - 该服务账户需要被授予在目标命名空间`k8s-cicd-dev`中操作部署(deployments)的权限。 解决方案思路: 1. 创建一个合适的角色(Role)或集群角色(ClusterRole),定义我们需要的权限(例如,对`apps` API组中的`deployments`资源的操作权限)。 2. 将这个角色绑定(RoleBinding)或集群角色绑定(ClusterRoleBinding)到服务账户`jenkins-admin`上,并指定目标命名空间(`k8s-cicd-dev`)。 由于错误信息中提到了一个集群角色`jenkins-admin`未被找到,我们可以选择: - 创建一个名为`jenkins-admin`的集群角色(ClusterRole)并绑定它(但注意,集群角色是集群范围的,可能权限过大)。 - 或者,更安全的方式是创建一个角色(Role)在目标命名空间`k8s-cicd-dev`中,然后将其绑定到服务账户`jenkins-admin`(服务账户在另一个命名空间`kube-devops`中,因此我们需要使用RoleBinding,并且指定服务账户的命名空间)。 但是,由于服务账户`jenkins-admin`位于命名空间`kube-devops`,而目标资源在命名空间`k8s-cicd-dev`,所以我们需要使用RoleBinding在目标命名空间`k8s-cicd-dev`中绑定服务账户(需要指定服务账户的命名空间)或者使用ClusterRoleBinding(绑定集群角色到服务账户,这样权限是集群范围的,但通常我们不需要那么大的权限)。 推荐做法(按最小权限原则): 1. 在目标命名空间`k8s-cicd-dev`中创建一个角色(Role),该角色具有操作部署(deployments)的必要权限(如create, get, update, delete等)。 2. 在目标命名空间`k8s-cicd-dev`中创建一个角色绑定(RoleBinding),将上一步创建的角色绑定到服务账户`jenkins-admin`(来自命名空间`kube-devops`)。 具体步骤: 步骤1:创建角色(Role)在命名空间`k8s-cicd-dev`中,定义对部署(deployments)资源的权限。 ```yaml # jenkins-admin-role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: k8s-cicd-dev # 目标命名空间 name: jenkins-deploy-role rules: - apiGroups: ["apps"] # API组 resources: ["deployments"] # 资源类型 verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 操作权限,根据实际需要调整 ``` 步骤2:创建角色绑定(RoleBinding),将上述角色绑定到服务账户`jenkins-admin`(注意:服务账户在命名空间`kube-devops`中)。 ```yaml # jenkins-admin-rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: jenkins-admin-rolebinding namespace: k8s-cicd-dev # 目标命名空间(与Role相同) subjects: - kind: ServiceAccount name: jenkins-admin # 服务账户名称 namespace: kube-devops # 服务账户所在的命名空间 roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: jenkins-deploy-role # 之前创建的Role名称 ``` 步骤3:应用这两个YAML文件。 ``` kubectl apply -f jenkins-admin-role.yaml kubectl apply -f jenkins-admin-rolebinding.yaml ``` 这样,服务账户`jenkins-admin`在命名空间`k8s-cicd-dev`中就有了操作部署的权限。 另外,如果Jenkins需要在多个命名空间中部署应用,那么在每个命名空间中重复上述步骤可能很繁琐。此时,可以考虑使用集群角色(ClusterRole)和集群角色绑定(ClusterRoleBinding)。但是,由于错误信息中提到的集群角色`jenkins-admin`不存在,如果我们想要使用集群角色,可以创建它并绑定到服务账户。 集群角色和集群角色绑定的方式如下: 创建集群角色: ```yaml # jenkins-admin-clusterrole.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: # 因为是集群角色,所以不需要namespace name: jenkins-admin rules: - apiGroups: ["apps"] resources: ["deployments"] verbs: ["*"] # 这里使用*表示所有操作,也可以根据需要指定 ``` 创建集群角色绑定(将集群角色绑定到服务账户,并指定命名空间): ```yaml # jenkins-admin-clusterrolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: jenkins-admin-clusterrolebinding subjects: - kind: ServiceAccount name: jenkins-admin namespace: kube-devops # 服务账户所在的命名空间 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: jenkins-admin # 集群角色的名称 ``` 注意:集群角色绑定(ClusterRoleBinding)会将权限授予整个集群,因此服务账户`jenkins-admin`将拥有在所有命名空间中对部署的操作权限。请根据安全策略决定是否使用。 由于最初错误提示是找不到集群角色`jenkins-admin`,可能之前的配置尝试绑定一个集群角色,但是该集群角色不存在。因此,我们可以选择创建这个集群角色并绑定,或者改为使用命名空间级别的角色(如上面第一种方法)。 根据错误上下文,我建议使用第一种方法(命名空间级别的角色),因为更符合最小权限原则。但如果Jenkins确实需要在多个命名空间部署,则使用集群角色更方便。 请根据实际需求选择方案。 最后,在Jenkins中,确保你在使用Kubernetes配置文件或者插件配置时,指定了正确的服务账户(即`jenkins-admin`)和命名空间(`kube-devops`)。 相关问题: 1. 如何检查Kubernetes中的RBAC权限配置是否正确? 2. 在Kubernetes中,如何为服务账户授予多个命名空间的访问权限? 3. 集群角色(ClusterRole)和角色(Role)的主要区别是什么? 4. 如何在Jenkins中配置Kubernetes插件以使用特定的服务账户? </think> ### Kubernetes RBAC权限错误解决方案:Jenkins服务账户权限配置详解 #### 错误诊断与核心问题 在Kubernetes集群中出现的错误: `User "system:serviceaccount:kube-devops:jenkins-admin" cannot get resource "deployments" in API group "apps" in the namespace "k8s-cicd-dev"` 根本原因是: 1. **RBAC权限不足**:Jenkins服务账户`jenkins-admin`缺少操作部署资源的权限 2. **ClusterRole缺失**:系统找不到指定的`jenkins-admin`集群角色 3. **命名空间隔离**:服务账户位于`kube-devops`命名空间,但需要操作`k8s-cicd-dev`命名空间的资源 权限关系公式: $$\text{权限} = \begin{cases} \text{服务账户} & \rightarrow \text{jenkins-admin} \\ \text{目标操作} & \rightarrow \text{deployments} \\ \text{命名空间} & \rightarrow \text{k8s-cicd-dev} \end{cases}$$ #### 完整解决方案(分步骤) ##### 步骤1:创建专用ClusterRole ```yaml # jenkins-clusterrole.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: jenkins-deploy-role # 使用明确的角色名称 rules: - apiGroups: ["apps"] resources: ["deployments", "statefulsets", "daemonsets"] # 扩展部署相关权限 verbs: ["get", "list", "watch", "create", "update", "delete"] - apiGroups: [""] resources: ["pods", "pods/log", "services", "configmaps"] verbs: ["*"] # 开放必要资源权限 ``` ##### 步骤2:创建RoleBinding绑定命名空间 ```yaml # jenkins-rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: jenkins-deploy-binding namespace: k8s-cicd-dev # 指定目标命名空间 subjects: - kind: ServiceAccount name: jenkins-admin namespace: kube-devops # 服务账户所在命名空间 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: jenkins-deploy-role # 匹配ClusterRole名称 ``` ##### 步骤3:应用配置并验证 ```bash # 应用RBAC配置 kubectl apply -f jenkins-clusterrole.yaml kubectl apply -f jenkins-rolebinding.yaml # 验证权限 kubectl auth can-i create deployments \ --as=system:serviceaccount:kube-devops:jenkins-admin \ -n k8s-cicd-dev # 应返回 "yes" ``` #### 关键配置说明 1. **最小权限原则** - 精确限定`apps` API组中的`deployments`资源权限 - 避免使用`ClusterRoleBinding`防止权限过度扩散[^2] 2. **跨命名空间授权** ```mermaid graph LR A[jenkins-admin服务账户] -->|RoleBinding| B(k8s-cicd-dev命名空间) B --> C[deployments资源] ``` 3. **权限验证公式** $$ \text{有效权限} = \frac{\text{ClusterRole权限} \cap \text{RoleBinding范围}}{\text{目标命名空间}} $$ #### Jenkins集成配置 在Jenkins Kubernetes插件配置中: 1. 指定服务账户名称:`jenkins-admin` 2. 设置命名空间:`kube-devops` 3. 添加容器模板时声明命名空间: ```groovy podTemplate( containers: [...], namespace: 'k8s-cicd-dev' // 指定构建目标命名空间 ) ``` #### 相关问题 1. 如何限制Jenkins服务账户只能访问特定命名空间? 2. Kubernetes中ClusterRole和Role的主要区别是什么? 3. 当Jenkins需要部署到多个命名空间时,RBAC应该如何配置? 4. 如何审计Kubernetes中的RBAC权限分配情况? [引用说明] 本文RBAC配置方案参考了Kubernetes官方授权模型[^1],并结合了Jenkins在Kubernetes中的最佳实践[^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值