Docker与Kubernetes云原生kubernetes以及运维开发系列

在kubernetes集群中配置RBAC

2019-12-01  本文已影响0人  cjzhao

简介

本文将介绍Kubernetes基于角色的访问控制(RBAC)API对象,以及两个常见的用例(创建具有受限访问权限的用户、POD内通过service account访问api)。在本文的最后,您应该具有足够的知识来在集群中使用RBAC策略。

从Kubernetes 1.6版本起,系统默认启用RBAC策略。 RBAC策略对于正确管理群集至关重要,因为它们使您可以根据用户及其在组织中的角色来指定允许的操作类型。包括:

the server does not allow access to the requested resource

本文将向您展示如何使用RBAC,以便您可以正确处理此类问题。

准备工作

为了充分的了解本文,建议您有一套完整的Kubernetes环境,并能按我们的步骤完成整个过程,环境要求如下:

minikube start --extra-config=apiserver.Authorization.Mode=RBAC

RBAC API 对象

Kubernetes的一项基本功能是其所有资源都是模型化的API对象,该对象允许进行CRUD(创建,读取,更新,删除)操作。 资源包括:

这些资源上可能的操作示例如下:

在更高级别上,资源与API Group(API组)相关联(例如,Pod属于核心API group,而Deployment属于apps API group)。 有关所有可用资源,操作和API组的更多信息,请查看官方Kubernetes API参考

为了在Kubernetes中管理RBAC,除了资源和操作外,我们还需要理解以下概念:

您可以在Kubernetes官方文档中找到每个API元素的示例。

示例1: 创建一个新的用户,从远程访问kubernetes集群

在此示例中,我们将为“开发组(development)”的"cjzhao"用户创建一个独享的命名空间(cjns),并从远程服务器访问集群,主要包括以下对象:

我们将添加必要的RBAC策略,以便用户cjzhao仅在cjns命名空间内即可完全管理deployment(即使用kubectl run命令)。 最后,我们将测试这些策略以确保它们按预期工作。

创建namespace

执行kubectl create命令创建命名空间(以admin用户身份):

kubectl create namespace cjns

创建用户凭证(User Credentials)

Kubernetes没有用于用户帐户的API。 这里我们使用OpenSSL证书(更多的认证方式请参见Kubernetes官方文档)来管理身份验证,具体步骤如下:

在kubernetes管控节点(或管理员机器)上执行下面操作

openssl genrsa -out cjzhao.key 2048
openssl req -new -key cjzhao.key -out cjzhao.csr -subj "/CN=cjzhao/O=development"
openssl x509 -req -in cjzhao.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out cjzhao.crt -days 500

在新的机器上执行下面操作

//配置集群
kubectl config set-cluster MyK8sCluster --server=https://your_server_ip:6443 --certificate-authority=./ca.crt
//配置用户信息
kubectl config set-credentials cjzhao --client-certificate=./cjzhao.crt --client-key=./cjzhao.key
//配置上文(将用户和集群绑定)
kubectl config set-context cjzhao-context --cluster=yourcluster --namespace=cjns --user=cjzhao

配置完成后执行如下命令:

kubectl config use-context cjzhao-context

kubectl get pods

您将看到会报下面的错:

Error from server (Forbidden): pods is forbidden: User "cjzhao" cannot list resource "pods" in API group "" in the namespace "cjns"

创建用户角色来管理Deployments

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: cjns
  name: deployment-manager
rules:
  - apiGroups: \["", "extensions", "apps"\]
    resources: \["deployments", "replicasets", "pods"\]
    verbs: \["get", "list", "watch", "create", "update", "patch", "delete"\] \# You can also use \["\*"\]

使用kubectl create命令在集群中创建Role:

kubectl create -f role-deployment-manager.yaml

将用户cjzhao和角色绑定

使用以下内容创建一个rolebinding-deployment-manager.yaml文件。 在此文件中,我们将角色绑定到cjns命名空间内的用户cjzhao:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: deployment-manager-binding
  namespace: cjns
subjects:
  - kind: User
    name: cjzhao
    apiGroup: ""
roleRef:
  kind: Role
  name: deployment-manager
  apiGroup: ""

通过运行kubectl create命令部署RoleBinding:

kubectl create -f rolebinding-deployment-manager.yaml

测试RBAC规则

在新的机器上执行下面的命令创建一个deployment:

kubectl create deployment --image nginx myng

执行下面的命令查看创建结果:

kubectl get pods

可以看到正在运行的pod。

为了验证cjzhao的权限是否是限定在cjns命名空间,我们执行下面的命令:

kubectl get pods -n default

结果如下:

Error from server (Forbidden): pods is forbidden: User "cjzhao" cannot list resource "pods" in API group "" in the namespace "default"

说明相关的用户权限配置成功。

示例2: 通过Service Account从集群内的POD访问kubernetes Api

POD内的进程可以通过Service Account直接访问Kubernetes API接口,本示例我们将通过kubernetes java sdk调用api接口。

Java client SDK的相关代码见:https://github.com/kubernetes-client/java/

本示例我们将调用API返回当前namesapce的pod信息。

Java程序

本示例使用的是Spring boot,使用jib打包为容器镜像。请根据您的具体情况自由发挥,只要能把您的java程序打包容器镜像都可以。
程序代码如下:

package cn.devincloud.demo.k8sjavaclient.controller;

import java.io.IOException;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import io.kubernetes.client.ApiClient;
import io.kubernetes.client.ApiException;
import io.kubernetes.client.Configuration;
import io.kubernetes.client.apis.CoreV1Api;
import io.kubernetes.client.models.V1Pod;
import io.kubernetes.client.models.V1PodList;
import io.kubernetes.client.util.ClientBuilder;

@RestController
public class PodController {

    @GetMapping("/pods")
    private List<String> getPods() throws IOException, ApiException{
        ApiClient client = ClientBuilder.cluster().build();
        Configuration.setDefaultApiClient(client);

        // the CoreV1Api loads default api-client from global configuration.
        CoreV1Api api = new CoreV1Api();

        // invokes the CoreV1Api client
        V1PodList list = api.listNamespacedPod("cjns", null, null, null, null, null, null, null, null, null);
        return list.getItems().stream().map(new Function<V1Pod,String>(){
            @Override
            public String apply(V1Pod t) {
                return t.getMetadata().getName();
            }
        }).collect(Collectors.toList());
    }
}

创建Service Account

在cjns命名空间创建一个Service Account: javaclient-svc-account

apiVersion: v1
kind: ServiceAccount
metadata:
  name: javaclient-svc-account
  namespace: cjns

绑定角色

我们的客户端需要读取cjns命名空间的pod,所有可以直接将Service Account:javaclient-svc-account与示例1中的deployment-manager角色绑定即可。

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: k8sjavaclient-rbac
  namespace: cjns
subjects:
  - kind: ServiceAccount
    name: javaclient-svc-account
    namespace: cjns
roleRef:
  kind: Role
  name: deployment-manager
  apiGroup: rbac.authorization.k8s.io

部署应用测试

apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8sjavaclient
spec:
  selector:
    matchLabels:
      app: k8sjavaclient
  template:
    metadata:
      labels:
        app: k8sjavaclient
    spec:
      serviceAccountName: javaclient-svc-account
      containers:
      - name: k8sjavaclient
        image: kube.gwunion.cn/cj/k8sjavaclient
        ports:
          - containerPort: 8080

kubernetes默认为将Service Acccount: default 绑定到POD,本例中,我们在cjns命名空间内,default账号没有分配相关访问api权限,所以在POD的定义时,需要指定serviceAccountName为我们上面创建的javaclient-svc-account

本文到此结束,喜欢的点赞。

上一篇下一篇

猜你喜欢

热点阅读