前面我们使用Helm在Kubernetes中部署了生产可用的Pulsar集群,并将集群接入到Prometheus监控系统。

作为Pulsar集群的管理员,将这套生产可用的Pulsar集群交付给开发使用时,还需要做好租户和命名空间划分和创建,用户角色和权限配置。 本节将根据实践介绍一下Pulsar集群管理员如何做这些工作的。

我们部署Pulsar集群时开启了基于非对称秘钥(asymmetric)的JWT认证,需要使用私钥为客户端应用的普通用户创建Token,将Token分发给客户端应用。 Pulsar的权限统一在命名空间级别进行管理,在为普通用户创建好Token后,需要在命名空间的级别上对用户角色进行授权。

JWT Token管理

pulsar manager中提供了一个token管理的页面,但是Pulsar官方的Helm Chart部署的pulsar manager,目前还不支持开启了非对称秘钥(asymmetric)的JWT认证的pulsar集群。 如果尝试在这个页面创建token的话,会报错。这是因为需要在pulsar manager的配置application.properties中设置:

1
2
3
jwt.broker.token.mode=PRIVATE
jwt.broker.public.key=file:///path/broker-public.key
jwt.broker.private.key=file:///path/broker-private.key

而当前2.7.13版本的pulsar-helm-chart还不支持对这个配置文件进行定制,同时也不支持以PRIVATE_KEY环境变量的形式进行配置。

在部署pulsar时,用于创建和验证token的非对称密钥对,以名称为pulsar-token-asymmetric-key Secret被创建到了K8S中。因此,可以放弃使用pulsar manager来管理token,改使用pulsar命令行工具的形式。 使用pulsar-helm-chart部署pulsar时,为我们在k8s集群中部署了SatefulSet pulsar-toolset的Pod,这个里面提供了用于管理pulsar的命令行空间pulsarpulsar-admin等,但遗憾的是并没有将Secret pulsar-token-asymmetric-key中的PRIVATE私钥以文件的形式挂载到Pod中,同时pulsar-helm-chart当前也不支持这块的定制配置。

只好再手动部署一个pulsar-admin-toolset,通过手动编写一个k8s deployment的manifest文件来部署pulsar-admin-toolset,并将 pulsar-token-asymmetric-key私钥挂载到Pod中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
kind: Deployment
apiVersion: apps/v1
metadata:
  name: pulsar-admin-toolset
  namespace: pulsar
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pulsar
      component: admin-toolset
      release: pulsar
  template:
    metadata:
      labels:
        app: pulsar
        cluster: pulsar
        component: admin-toolset
        release: pulsar
    spec:
      volumes:
        - name: token-private-key
          secret:
            secretName: pulsar-token-asymmetric-key
            items:
              - key: PRIVATEKEY
                path: private.key
            defaultMode: 420
        - name: client-token
          secret:
            secretName: pulsar-token-admin
            items:
              - key: TOKEN
                path: client/token
            defaultMode: 420
      containers:
        - name: pulsar-toolset
          image: harbor.example.com/library/apachepulsar/pulsar-all:2.7.4
          command:
            - sh
            - '-c'
          args:
            - >
              bin/apply-config-from-env.py conf/client.conf;
              bin/apply-config-from-env.py conf/bookkeeper.conf;

              sleep 10000000000              
          envFrom:
            - configMapRef:
                name: pulsar-toolset
          resources:
            limits:
              cpu: '2'
              memory: 1Gi
            requests:
              cpu: 100m
              memory: 256Mi
          volumeMounts:
            - name: token-private-key
              readOnly: true
              mountPath: /pulsar/token-private-key
            - name: client-token
              readOnly: true
              mountPath: /pulsar/tokens
          imagePullPolicy: IfNotPresent
      nodeSelector:
        node-role.kubernetes.io/pulsar: pulsar
      securityContext: {}
      imagePullSecrets:
        - name: regsecret
      tolerations:
        - key: dedicated
          operator: Equal
          value: pulsar
          effect: NoSchedule

私钥被以文件/pulsar/token-private-key/private.key的形式挂载到了POD的容器中,这样集群管理员就可以进入到容器中执行下面的命令创建Token:

1
bin/pulsar tokens create --private-key file:///pulsar/token-private-key/private.key --subject <userrolename>

bin/pulsr/tokens create命令的具体参数如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    create      Create a new token
      Usage: create [options]
        Options:
          -e, --expiry-time
            Relative expiry time for the token (eg: 1h, 3d, 10y). (m=minutes) 
            Default: no expiration
          -pk, --private-key
            Pass the private key for signing the token. This can either be: 
            data:, file:, etc..
          -sk, --secret-key
            Pass the secret key for signing the token. This can either be: 
            data:, file:, etc..
          -a, --signature-algorithm
            The signature algorithm for the new key pair.
            Default: RS256
            Possible Values: [NONE, HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512]
        * -s, --subject
            Specify the 'subject' or 'principal' associate with this token

注意,可以使用-e指定token失效时间,但一般为应用创建的token会设置为永久有效,但如果设置了永久有效,则分发出去的某个用户角色(subject)的token是无法撤回的。 如果确实需要撤回,则只能将这个用户角色(subject)在pulsar相关租户和命名空间中的权限删除,这样这个token虽然还是可以通过认证,但是却无权进行相关操作了。

授权管理

解决了Token创建的问题,来看一下授权管理,Pulsar的权限统一在命名空间级别进行管理,在为普通用户创建好Token后,需要在命名空间的级别上对用户角色进行授权。

例如,我们使用下面的命令为用户角色foo创建了token。

1
bin/pulsar tokens create --private-key file:///pulsar/token-private-key/private.key --subject 

可以使用下面的命令为用户角色foo进行授权:

1
bin/pulsar-admin namespaces grant-permission tenant1/namespace1 --actions produce,consume --role foo

这样用户角色foo就在tenant1/namespace1这个命名空间下具有produceconsume的权限了,客户端应用程序可以使用foo的token访问这个命名空间下的topic。

可以使用下面的命令查看命名空间下的所有授权:

1
bin/pulsar-admin namespaces permissions tenant1/namespace1

可以使用下面的命令收回某个用户角色在某个命名空间下的授权:

1
bin/pulsar-admin namespaces revoke-permission tenant1/namespace1 --role foo

除了使用pulsar-admin外,还可以在pulsar-manager中的namespace管理页面中的POLICES中配置授权。

参考