Kubernetes(k8s)的安全机制是围绕保护其API Server来设计的,主要包括认证(Authentication)、鉴权(Authorization)和准入控制(Admission Control)三个核心环节。下面分别对这三个环节进行详细说明:
1. 认证(Authentication)
kubeadm join ip:6443 --token --discovery-token-cacert-hash
# --token用于Apiserver识别kubelet是否合法
# --discovery-token-cacert-hash 用于kubelet确认apiServer发来的证书是否合法
[root@master ~]# cat /root/.kube/config
认证是确定访问者的身份是否合法的过程。Kubernetes支持多种认证方式,包括但不限于:
1.1 HTTP Token认证:
通过Token来识别合法用户。Token是一个复杂且难以模仿的字符串,每个Token对应一个用户名,存储在API Server能访问的文件中。客户端发起请求时,在HTTP Header中包含Token,API Server通过解码Token来验证用户身份。
1.2 HTTP Base认证:
通过用户名和密码的方式认证。用户名和密码通过Base64算法加密后,放在HTTP Request的Header中发送给服务端,服务端解码后验证用户名和密码。
1.3 HTTPS证书认证:
基于CA根证书签名的客户端身份认证方式。这是Kubernetes中最严格、最严谨的认证方式,通过双向TLS认证确保通信双方的身份安全。
此外,Kubernetes还使用kubeconfig文件来管理客户端的认证信息,包括CA证书、API Server地址、客户端证书和私钥等。
2. 鉴权(Authorization)
鉴权是确定请求方有哪些资源的权限的过程。Kubernetes API Server支持多种授权策略,包括:
2.1 RBAC(基于角色的访问控制):
通过定义角色(Role)和角色绑定(RoleBinding)来控制用户对资源的访问权限。RBAC是Kubernetes中最常用的授权模式,支持细粒度的权限控制。
2.2 ABAC(基于属性的访问控制):
通过定义策略文件来授予用户访问权限,策略文件中包含了用户属性、资源属性和操作属性等信息。
2.3 Node鉴权:
一种特殊用途的鉴权模式,专门对kubelet发出的API请求进行授权。kubelet必须使用一个凭证以表示它在system:nodes组中,用户名为system:node:。
2.4 Webhook模式:
通过调用外部HTTP/HTTPS服务来动态地决定用户的访问权限。
RBAC详解
在Kubernetes(k8s)中,RBAC(Role-Based Access Control,基于角色的访问控制)是一种授权机制,它允许管理员通过Kubernetes API来定义角色(Roles)和角色绑定(RoleBindings),从而控制用户对集群资源的访问权限。RBAC 提供了一种细粒度的访问控制方法,可以根据用户的角色来限制他们对集群资源的操作。
-
RBAC 的核心概念
- 角色(Role):
定义了一组权限,这些权限限定了对一组资源(如Pods、Services等)的操作(如GET、LIST、WATCH、CREATE、UPDATE、PATCH、DELETE等)。
角色是命名空间级别的,意味着一个角色只能被绑定到它所在的命名空间内的用户或服务账户上。 - 集群角色(ClusterRole):
与角色类似,但它是集群级别的,可以用于跨命名空间的资源,或者那些不特定于命名空间的资源(如节点)。 - 角色绑定(RoleBinding):
将角色绑定到一个或多个用户或服务账户上,从而控制这些用户或服务账户对命名空间内资源的访问权限。 - 集群角色绑定(ClusterRoleBinding):
将集群角色绑定到一个或多个用户或服务账户上,控制这些用户或服务账户对集群范围内资源的访问权限。
- 角色(Role):
-
使用 RBAC
在Kubernetes中,你可以通过YAML文件来定义角色、角色绑定、集群角色和集群角色绑定。例如,你可以创建一个角色,该角色允许对某个命名空间内的Pods进行读取操作,然后将这个角色绑定到一个特定的用户或服务账户上。
创建一个用户智能管理dev名字空间
步骤:创建证书 > 转换为kubeconfig文件 > 创建名字空间 > 角色绑定
[root@master ~]# cd /etc/kubernetes/pki/
[root@master pki]# ls
apiserver.crt apiserver-kubelet-client.key front-proxy-ca.key
apiserver-etcd-client.crt ca.crt front-proxy-client.crt
apiserver-etcd-client.key ca.key front-proxy-client.key
apiserver.key etcd sa.key
apiserver-kubelet-client.crt front-proxy-ca.crt sa.pub
[root@master pki]# vim devuser.json
[root@master pki]# cat devuser.json
{
"CN": "devuser",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
# 下载证书生成工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
coreOS json
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
[root@master pki]# cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /root/devuser.json | cfssljson -bare devuser
open /root/devuser.json: no such file or directory
Failed to parse input: unexpected end of JSON input
[root@master pki]# cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes devuser.json | cfssljson -bare devuser
2024/08/28 16:40:46 [INFO] generate received request
2024/08/28 16:40:46 [INFO] received CSR
2024/08/28 16:40:46 [INFO] generating key: rsa-2048
2024/08/28 16:40:46 [INFO] encoded CSR
2024/08/28 16:40:46 [INFO] signed certificate with serial number 454243441018666193052246696391790253434641005627
2024/08/28 16:40:46 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
#生成的文件
devuser.csr
devuser.json
devuser-key.pem #私钥
devuser.pem #证书
# 设置集群参数
export KUBE_APISERVER="https://10.0.17.100:6443"
kubectl config set-cluster kubernetes \
--certificate-authority=ca.crt \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=devuser.kubeconfig
Cluster "kubernetes" set.
#生成 devuser.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials devuser \
--client-certificate=devuser.pem \
--client-key=devuser-key.pem \
--embed-certs=true \
--kubeconfig=devuser.kubeconfig
User "devuser" set.
#设置上下文参数
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=devuser \
--namespace=dev \
--kubeconfig=devuser.kubeconfig
Context "kubernetes" created.
# 鉴权 权利绑定
# 创建dev命名空间
[root@master pki]# kubectl create ns dev
namespace/dev created
# kubectl create rolebinding devuser-admin-binding --clusterrole=admin --user=devuser --namespace=dev --dry-run -o yaml
kubectl create rolebinding devuser-admin-binding --clusterrole=admin --user=devuser --namespace=dev
[root@master pki]# kubectl create rolebinding devuser-admin-binding --clusterrole=admin --user=devuser --namespace=dev
rolebinding.rbac.authorization.k8s.io/devuser-admin-binding created
# 提前加载kubeconfig文件 生成用户信息
kubectl config use-context kubernetes --kubeconfig=devuser.kubeconfig
Switched to context "kubernetes".
#将devuser用户放在默认的调用路径下 验证权限的执行结果
[root@master .kube]# mv /root/.kube/config /root
[root@master .kube]# cp -a /etc/kubernetes/pki/devuser.kubeconfig /root/.kube/config
[root@master ~]# kubectl get pod
No resources found in dev namespace.
#证明现在使用devuser用户
[root@master ~]# kubectl get pod -n default
Error from server (Forbidden): pods is forbidden: User "devuser" cannot list resource "pods" in API group "" in the namespace "default"
# 配合linux用户账户使用权限
useradd dev
passwd dev
mkdir /home/dev/.kube
cp /etc/kubernetes/pki/devuser.kubeconfig /home/dev/.kube/config
chown -R dev:dev /home/dev/.kube/
#查看预设角色
[root@master pki]# kubectl get clusterrole
NAME CREATED AT
admin 2024-08-20T14:05:32Z
calico-cni-plugin 2024-08-27T14:02:54Z
calico-kube-controllers 2024-08-27T14:02:54Z
calico-node 2024-08-27T14:02:54Z
cluster-admin 2024-08-20T14:05:32Z
edit 2024-08-20T14:05:32Z
kubeadm:get-nodes 2024-08-20T14:05:34Z
system:aggregate-to-admin 2024-08-20T14:05:32Z
system:aggregate-to-edit 2024-08-20T14:05:32Z
system:aggregate-to-view 2024-08-20T14:05:32Z
system:auth-delegator 2024-08-20T14:05:32Z
system:basic-user 2024-08-20T14:05:32Z
system:certificates.k8s.io:certificatesigningrequests:nodeclient 2024-08-20T14:05:32Z
system:certificates.k8s.io:certificatesigningrequests:selfnodeclient 2024-08-20T14:05:32Z
system:certificates.k8s.io:kube-apiserver-client-approver 2024-08-20T14:05:32Z
system:certificates.k8s.io:kube-apiserver-client-kubelet-approver 2024-08-20T14:05:32Z
system:certificates.k8s.io:kubelet-serving-approver 2024-08-20T14:05:32Z
system:certificates.k8s.io:legacy-unknown-approver 2024-08-20T14:05:32Z
system:controller:attachdetach-controller 2024-08-20T14:05:32Z
system:controller:certificate-controller 2024-08-20T14:05:32Z
system:controller:clusterrole-aggregation-controller 2024-08-20T14:05:32Z
system:controller:cronjob-controller 2024-08-20T14:05:32Z
system:controller:daemon-set-controller 2024-08-20T14:05:32Z
system:controller:deployment-controller 2024-08-20T14:05:32Z
system:controller:disruption-controller 2024-08-20T14:05:32Z
system:controller:endpoint-controller 2024-08-20T14:05:32Z
system:controller:endpointslice-controller 2024-08-20T14:05:32Z
system:controller:endpointslicemirroring-controller 2024-08-20T14:05:32Z
system:controller:ephemeral-volume-controller 2024-08-20T14:05:32Z
system:controller:expand-controller 2024-08-20T14:05:32Z
system:controller:generic-garbage-collector 2024-08-20T14:05:32Z
system:controller:horizontal-pod-autoscaler 2024-08-20T14:05:32Z
system:controller:job-controller 2024-08-20T14:05:32Z
system:controller:legacy-service-account-token-cleaner 2024-08-20T14:05:32Z
system:controller:namespace-controller 2024-08-20T14:05:32Z
system:controller:node-controller 2024-08-20T14:05:32Z
system:controller:persistent-volume-binder 2024-08-20T14:05:32Z
system:controller:pod-garbage-collector 2024-08-20T14:05:32Z
system:controller:pv-protection-controller 2024-08-20T14:05:32Z
system:controller:pvc-protection-controller 2024-08-20T14:05:32Z
system:controller:replicaset-controller 2024-08-20T14:05:32Z
system:controller:replication-controller 2024-08-20T14:05:32Z
system:controller:resourcequota-controller 2024-08-20T14:05:32Z
system:controller:root-ca-cert-publisher 2024-08-20T14:05:32Z
system:controller:route-controller 2024-08-20T14:05:32Z
system:controller:service-account-controller 2024-08-20T14:05:32Z
system:controller:service-controller 2024-08-20T14:05:32Z
system:controller:statefulset-controller 2024-08-20T14:05:32Z
system:controller:ttl-after-finished-controller 2024-08-20T14:05:32Z
system:controller:ttl-controller 2024-08-20T14:05:32Z
system:coredns 2024-08-20T14:05:34Z
system:discovery 2024-08-20T14:05:32Z
system:heapster 2024-08-20T14:05:32Z
system:kube-aggregator 2024-08-20T14:05:32Z
system:kube-controller-manager 2024-08-20T14:05:32Z
system:kube-dns 2024-08-20T14:05:32Z
system:kube-scheduler 2024-08-20T14:05:32Z
system:kubelet-api-admin 2024-08-20T14:05:32Z
system:monitoring 2024-08-20T14:05:32Z
system:node 2024-08-20T14:05:32Z
system:node-bootstrapper 2024-08-20T14:05:32Z
system:node-problem-detector 2024-08-20T14:05:32Z
system:node-proxier 2024-08-20T14:05:32Z
system:persistent-volume-provisioner 2024-08-20T14:05:32Z
system:public-info-viewer 2024-08-20T14:05:32Z
system:service-account-issuer-discovery 2024-08-20T14:05:32Z
system:volume-scheduler 2024-08-20T14:05:32Z
view 2024-08-20T14:05:32Z
在Kubernetes中,您可以使用kubectl命令行工具来查看用户。Kubernetes本身不包含用户管理的功能,用户通常是在外部管理的(例如使用LDAP、Active Directory或其他身份认证系统),然后通过Kubernetes的身份认证插件进行集成。
如果您想要查看Kubernetes集群中的用户,您通常需要查看与用户相关的Service Accounts或者Roles和RoleBindings。Service Accounts用于为在Kubernetes中运行的Pods提供身份认证。Roles和RoleBindings用于定义用户或Service Accounts的权限。
以下是一些可以使用的kubectl命令:
- 查看所有Service Accounts:
kubectl get serviceaccounts --all-namespaces
- 查看特定命名空间的Roles和RoleBindings:
kubectl get roles --namespace <namespace>
kubectl get rolebindings --namespace <namespace>
- 查看Role或ClusterRole的详细信息,了解它授予的权限:
kubectl describe role <role-name> --namespace <namespace>
kubectl describe clusterrole <clusterrole-name>
- 查看RoleBinding或ClusterRoleBinding的详细信息,了解它们关联的用户或Service Accounts:
kubectl describe rolebinding <rolebinding-name> --namespace <namespace>
kubectl describe clusterrolebinding <clusterrolebinding-name>
请注意,这些命令提供的信息可能不会直接显示“用户”的概念,而是显示与用户权限相关的Service Accounts和角色绑定。实际的用户信息取决于您的身份认证系统和Kubernetes集群的配置。如果您使用的是外部的LDAP、OIDC等,您可能需要直接查询这些系统来管理用户。
# 定义一个角色
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" 表示核心API组
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
# 将角色绑定到一个用户
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: janedoe # 用户名
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
在上面的例子中,我们定义了一个名为pod-reader的角色,它允许对default命名空间内的Pods进行读取操作。然后,我们创建了一个名为read-pods的角色绑定,将pod-reader角色绑定到了用户janedoe上。这样,用户janedoe就只能对default命名空间内的Pods进行读取操作了。
Role 示例
Role定义了一组针对特定命名空间内资源的操作权限集合。以下是一个Role的示例,该Role允许在development命名空间中查看和列出Pods和Deployments:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: dev-readonly
rules:
- apiGroups: [""] # "" 表示核心API组
resources: ["pods", "deployments"]
verbs: ["get", "list", "watch"]
ClusterRole 示例
ClusterRole与Role类似,但作用范围是整个集群,包括所有命名空间以及那些不隶属于任何命名空间的集群级别资源。以下是一个ClusterRole的示例,该ClusterRole允许查看集群中的节点信息:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-viewer
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
RoleBinding 示例
RoleBinding将Role与一组用户、组或者服务账户关联起来,并且限制在某个特定命名空间内生效。以下是一个RoleBinding的示例,该RoleBinding将上面创建的dev-readonly角色绑定到用户alice上:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-user-binding
namespace: development
subjects:
- kind: User
name: alice
roleRef:
kind: Role
name: dev-readonly
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding 示例
ClusterRoleBinding类似于RoleBinding,但它将ClusterRole绑定到用户、组或服务账户上,并在整个集群范围内生效。以下是一个ClusterRoleBinding的示例,该ClusterRoleBinding将上面创建的cluster-viewer角色绑定到用户alice上:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-viewer-binding
subjects:
- kind: User
name: alice
roleRef:
kind: ClusterRole
name: cluster-viewer
apiGroup: rbac.authorization.k8s.io
通过以上示例,我们可以看到RBAC在Kubernetes中如何通过定义角色和角色绑定来精细控制不同用户或服务账户对集群资源的访问权限。这些定义可以通过kubectl命令行工具或Kubernetes API进行创建、查看和修改。
RBAC 提供了一种灵活且强大的方式来管理Kubernetes集群中的访问控制,使得管理员能够根据实际需要来定制权限策略。
常见预定角色
-
view ClusterRole
允许读取一个命名空间中的大多数资源,除了Role、 RoleBinding和 Secret -
editClusterRole
允许读取和修改 Secret。
但是,它也不允许查看或修改Role和RoleBinding,这是为了防止权限扩散。 -
adminClusterRole
一个命名空间中的资源的完全控制权是由 admin ClusterRole 赋予的。 有这个ClusterRole的主体可以读取和修改命名空间中的任何资源,除了ResourceQuota 和命名空间资源本身。edit和adminClusterRole之间的主要区别是能否在命名空间中查看和修改 Role 和 RoleBinding。 -
cluster-adminClusterRole
通过将cluster-adminClusterRole赋给主题,主体可以获得Kuberbnetes器群完全控制的权限
3. 准入控制(Admission Control)
准入控制是API Server的一个插件列表,用于在请求操作被持久化到etcd之前进行拦截和检查。准入控制器可以修改请求内容,或者根据预定义的策略决定是否允许该请求继续执行。Kubernetes提供了多种内置的准入控制器,如:
3.1 NamespaceLifecycle:
确保请求的资源在正确的命名空间中。
3.2 LimitRanger:
限制Pod可以使用的资源量。
3.3 ServiceAccount:
确保Pod在创建时自动设置ServiceAccount。
3.4 DefaultStorageClass:
为没有指定存储类的PersistentVolumeClaim设置默认的存储类。
此外,用户还可以编写自定义准入控制器或利用Webhook准入控制器与外部服务集成,以实现更为复杂的场景和业务逻辑。
综上所述,Kubernetes的安全机制通过认证、鉴权和准入控制三个环节,确保了集群内部和外部访问的安全性。这些机制共同协作,为Kubernetes集群提供了强大的安全保障。