这是本系列文章中的第三篇,前两篇文章分别介绍了Kubernetes访问控制以及身份认证。本文将通过上手实践的方式,带你理解Kubernetes授权这一概念。
在文章正式开始之前,我们先快速回顾一下我们实操过程中的环境和场景。我们正在处理生产环境中的集群,其中每个部分都与命名空间相关联。现在,组里新来了一位同事叫Bob,我们在上篇教程中帮助Bob以engineering命名空间管理员的身份加入集群。并且他已经获得私钥以及签名证书来访问集群。
如果你还没有完成上述操作,请查看上篇教程,运行其中的命令以完成环境设置以及为Bob配置证书。
好,我们正式开始本篇教程。
现在我们要给Bob授权,以控制属于engineering命名空间的资源。
首先,我们要为kubectl创建一个上下文(context),方便它在不同的环境之间切换。
kubectl config set-context eng-context --cluster=minikube --namespace=engineering --user=bob
Context "eng-context" created.
上面的命令使用Bob在minikube集群中的凭据创建了一个指向engineering命名空间的新上下文。这会导致在?/ .kube / config文件中添加一个新的部分。
我们现在在engineering命名空间中创建一个简单的pod:
apiVersion: v1
kind: Pod
metadata:
name: myapp
namespace: engineering
labels:
app: myapp
spec:
containers:
- name: myapp
image: busybox
command: ["/bin/sh", "-ec", "while :; do echo ‘.‘; sleep 5 ; done"]
kubectl create -f myapp.yaml
pod/myapp created
kubectl get pods -n=engineering
NAME READY STATUS RESTARTS AGE
myapp 1/1 Running 0 89s
虽然您可以作为集群管理员在工程命名空间中创建和操作pod,但Bob甚至无法在同一名称空间中列出pod。
kubectl get pods --namespace engineering --as bob
Error from server (Forbidden): pods is forbidden: User "bob" cannot list resource "pods" in API group
为了使得Bob可以在engineering命名空间中访问资源,我们需要给他授权。这可以通过创建具有适当权限的角色然后将其绑定到用户Bob来完成。实质上,我们使用的是基于角色访问控制(RBAC)来允许Bob对engineering命名空间中的某些Kubernetes资源执行特定操作。
创建一个名为eng-reader的Kubernetes角色,允许其在engineering命名空间中列出pod。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: engineering
name: eng-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods", "services", "nodes"]
verbs: ["get", "watch", "list"]
kubectl create -f role.yaml
role.rbac.authorization.k8s.io/eng-reader created
kubectl get roles --namespace=engineering
NAME AGE
eng-reader 58s
注意,这一角色目前和Bob毫无关联。我们需要通过角色绑定将角色中指定的权限应用于Bob。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: eng-read-access
namespace: engineering
subjects:
- kind: User
name: bob # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: eng-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
kubectl create -f role-binding.yaml
rolebinding.rbac.authorization.k8s.io/eng-read-access created
kubectl get rolebindings --namespace=engineering
NAME AGE
eng-read-access 31s
让我们来检查一下Bob现在是否可以访问pod。
kubectl get pods --namespace engineering --as bob
NAME READY STATUS RESTARTS AGE
myapp 1/1 Running 0 11m
既然他现在已经关联了eng-reader角色,那么他就获得了pod列表的权限。
此时,Bob在集群中的访问权限依旧十分有限。他所能做的只是在engineering 命名空间中列出pod。这对Bob帮助不大。他想要检查集群中的节点数量,但是令他失望的是,他遇到了 forbidden error。
kubectl get nodes --as bob
Error from server (Forbidden): nodes is forbidden: User "bob" cannot list resource "nodes" in API group
在Kubernetes中角色和角色绑定既可以应用在命名空间层面也可以应用在集群层面。我们现在创建一个集群角色以及一个与Bob关联的角色绑定,以使他能够列出节点。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: cluster-node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "watch", "list"]
kubectl create -f cluster-role.yaml
clusterrole.rbac.authorization.k8s.io/cluster-node-reader created
kubectl get clusterroles cluster-node-reader
NAME AGE
cluster-node-reader 49s
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-cluster-nodes
subjects:
- kind: User
name: bob # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-node-reader
apiGroup: rbac.authorization.k8s.io
kubectl create -f cluster-role-binding.yaml
clusterrolebinding.rbac.authorization.k8s.io/read-cluster-nodes created
kubectl get clusterrolebindings read-cluster-nodes
NAME AGE
read-cluster-nodes 35s
public class ValuesController : ControllerBase
{
private readonly MyOptions _options1;
private readonly MyOptions _options2;
private readonly MyOptions _options3;
private readonly IConfiguration _configurationRoot;
public ValuesController(IConfiguration configurationRoot, IOptionsMonitor<MyOptions> options1, IOptionsSnapshot<MyOptions> options2,
IOptions<MyOptions>www.jintianxuesha.com options3 )
{
//IConfiguration(ConfigurationRoot)随着配置文件进行更新(需要IConfigurationProvider监听配置源的更改)
_configurationRoot www.chengsyl.cn= configurationRoot;
//单例,监听IConfiguration的IChangeToken,在配置源发生改变时,自动删除缓存
//生成新的Option实例并绑定,加入缓存
_options1 = options1.CurrentValue;
//scoped,每次请求重新生成Option实例并从IConfiguration获取数据进行绑定
_options2 = options2.Value;
//单例,从IConfiguration获取数据进行绑定,只绑定一次
_options3 = options3.Value;
}
}
二、源码解读
首先看看Configure扩展方法,方法很简单,通过DI注入了Options需要的依赖。这里注入了了三种访问强类型配置的方法所需的所有依赖,接下来我们按照这三种方法去分析源码。
public static IServiceCollection Configure<TOptions>(this IServiceCollection services, IConfiguration config) where TOptions : class
=> services.Configure<TOptions>www.hongyaoyuL.cn(Options.Options.DefaultName, config, _ =www.javachenglei.com > { });
public static IServiceCollection Configure<www.yuanhuapt.cn TOptions>(this IServiceCollection services, string name, IConfiguration config, Action<BinderOptions> configureBinder)
where TOptions : class
{
services.AddOptions(www.haishenyul.com);
services.AddSingleton<www.tongyayuLe.cn IOptionsChangeTokenSource<TOptions>>(new ConfigurationChangeTokenSource<TOptions>(name, config));
return services.AddSingleton<IConfigureOptions<TOptions>>(new NamedConfigureFromConfigurationOptions<TOptions>(name, config, configureBinder));
}
/// 为IConfigurationSection实例注册需要绑定的TOptions
public static IServiceCollection AddOptions(this IServiceCollection services)
{
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<www.jiuhaoyulept.com>), typeof(OptionsManager<>)));
//创建以客户端请求为范围的作用域
services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>)));
services.TryAdd(ServiceDescriptor.Singleton(typeof(www.pingguoyul.cn IOptionsMonitor<>), typeof(OptionsMonitor<>)));
services.TryAdd(ServiceDescriptor.Transient(typeof(IOptionsFactory<>), typeof(OptionsFactory<>)));
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitorCache<>), typeof(OptionsCache<>)));
return services;
现在,Bob已经设置为可以在集群中列出节点。
kubectl get nodes --as bob
NAME STATUS ROLES AGE VERSION
minikube Ready master 52m v1.15.2
本篇教程的目的是为了帮助你理解角色以及角色绑定如何在Kubernetes中工作的。在本系列下一篇文章中,我们将来看看service account,保持关注哟~
原文地址:https://www.cnblogs.com/qwangxiao/p/11426842.html