Skip to main content
Version: 1.6.0

Use Cases

Introduction

Yunikorn offers a range of features, including advanced capabilities like hierarchical resource queues, access control lists, resource limits, preemption, priority, and placement rules for managing your cluster. This page presents a real-world scenario to demonstrate the practical application of these features.

We will now introduce the various functions and configurations of Yunikorn in sequence.

The following will be included in this article:

  • Access control with ACL
  • Placement of different users
  • Limit usable resources on a queue level
  • Preemption and priority scheduling with fencing

Prerequisite

Before configuring yunikorn-config, we need to create users using Authentication and RBAC from Kubernetes.

To create the necessary users for the example, you can download the create_user.sh script directly from yunikorn-k8shim under deployment/examples/authz/k8s-api-access.

Here are the users we need to create:

usergroup
adminadmin
suegroup-a
bobgroup-a
kimgroup-b
yonogroup-b
anonymousanonymous

After the user is created, the pod can be obtained by the following command to confirm the creation is successful:

kubectl --context=sue-context get pod

When you are done testing, you can run ./remove-user.sh in the folder to delete all users.


Partition and Queue Configuration

In this use case, we configure the cluster for two purposes - system management and multi-tenancy, with two groups of tenants. Below is the queue configuration:

  • Root
    • system
    • tenants
      • group-a
      • group-b
kind: ConfigMap
metadata:
name: yunikorn-configs
namespace: yunikorn
apiVersion: v1
data:
queues.yaml: |
partitions:
- name: default
queues:
- name: root
queues:
- name: system
- name: tenants
queues:
- name: group-a
- name: group-b

See the documentation on Partition and Queue Configuration for more information.


User/Group Resolution & ACL

In a multi-tenant environment, we want each user's workload to be independent from one another, with tenants restricted to using specific queues.

In Yunikorn, there are two steps to manage users:

  1. The Admission Controller resolves the username and group and adds the user's informantion to the Annotation.
  2. Yunikorn compares whether the user is in the ACL of a specific queue to determine whether the user has permission to deploy applications on that queue.

Explanation of Configuration

In the following example, we configure the configuration based on the following:

usergroupQueue allowed to put
adminadminsystem
suegroup-aroot.tenants.group-a
bobgroup-aroot.tenants.group-a
kimgroup-broot.tenants.group-b
yonogroup-broot.tenants.group-b
anonymousanonymousx

In this configuration, we allow users in the admin group to use the system queue by setting adminacl: admin for the root.system queue. We also allow the group-a and group-b groups to use their respective queues (root.tenants.group-a and root.tenants.group-b) by setting adminacl: group-a and adminacl: group-b for each queue, respectively.

Configuration for testing :

kind: ConfigMap
metadata:
name: yunikorn-configs
namespace: yunikorn
apiVersion: v1
data:
admissionController.accessControl.externalGroups: "admin,group-a,group-b"
queues.yaml: |
partitions:
- name: default
queues:
- name: root
queues:
- name: system
adminacl: " admin"
- name: tenants
queues:
- name: group-a
adminacl: " group-a"
- name: group-b
adminacl: " group-b"

Testing

In this test scenario, we utilize three users to create a Pod, but the access control list restricts each user to create Pods only in the allowed queue.

Among these users, one is named Sue and belongs to the group-a. Whenever Sue tries to create a Pod, the admission controller will first add the user's name and group to the Pod's annotation:

Annotations:      
...
yunikorn.apache.org/user.info: {"user":"sue","groups":["group-a","system:authenticated"]}
...

The scheduler will then determine whether to allow or block the user's pod based on the access control list of the assigned queue.

Here are the results for different users assigned to different queues. You can use the YAML file we provide to test :

user, groupAssign queueresultYAML filename
sue, group-aroot.tenants.group-acreatednginx-1.yaml
sue, group-aroot.tenants.group-bblockednginx-1.yaml
kim, group-broot.tenants.group-ablockednginx-2.yaml
kim, group-broot.tenants.group-bcreatednginx-2.yaml
anonymous, anonymousroot.tenants.group-ablockednginx-3.yaml
anonymous, anonymousroot.tenants.group-bblockednginx-3.yaml

See the documentation on User & Group Resolution or ACLs for more information.


Placement of different users

To simplify the user's experience, the scheduler can dynamically assign the application to a queue and create a new queue if necessary. By setting up the placement rules properly, the user won't need to specify the queue to run their application on.

Explanation of Configuration

Yunikorn offers extensive support for placement rules, allowing users to assign queues based on the namespace or username of the Pod, or to create queues based on user specifications.

Let's take the "admin" user as an example to explain the configuration. We want the scheduler to create a new queue based on the queue provided by the "admin":

placementrules:
- name: provided
create: true

To further restrict users and provide different placement rules for different users, we need to use filter since the previous configuration cannot achieve this.

Additionally, we want to separate the system and tenant queues, and for queues created by the admin, we want them to be under the system queue. To do so, we use the parent attribute.

To allow the queue to be designated as a parent, we need to set parent: true in the parent queue.

Finally, we extend the configuration as follows:

placementrules:
- name: provided
create: true
parent: # Specify the parent of the created queue as root.system
name: fixed
value: root.system
filter: # Only admin is allowed to use the rule
type: allow
users:
- admin
groups:
- admin

In the following example, we configure the configuration based on the following:

groupplacement rulefixed parent
adminprovidedroot.system
group-ausernameroot.tenants.group-a
group-bnamespaceroot.tenants.group-b

Configuration for testing :

kind: ConfigMap
metadata:
name: yunikorn-configs
namespace: yunikorn
apiVersion: v1
data:
admissionController.accessControl.externalGroups: "admin,group-a,group-b"
queues.yaml: |
partitions:
- name: default
placementrules:
- name: provided
create: true
parent:
name: fixed
value: root.system
filter:
type: allow
users:
- admin
groups:
- admin
- name: user
create: true
filter:
type: allow
groups:
- group-a
parent:
name: fixed
value: root.tenants.group-a
- name: tag
value: namespace
create: true
filter:
type: allow
groups:
- group-b
parent:
name: fixed
value: root.tenants.group-b
queues:
- name: root
queues:
- name: system
adminacl: " admin"
parent: true # Let the queue be designated as the parent queue
- name: tenants
parent: true
queues:
- name: group-a
adminacl: " group-a"
parent: true
- name: group-b
adminacl: " group-b"
parent: true

Testing

In this test example, we use three users to verify all the placement rules.

The following results are generated when creating a Pod according to different rules. You can use the YAML file we provide for testing:

placement ruleuser, groupprovide queuenamespaceExpected to be placed onYAML filename
providedadmin, adminroot.system.high-priorityroot.system.high-prioritynginx-admin.yaml
providedadmin, adminroot.system.low-priorityroot.system.low-prioritynginx-admin.yaml
usernamesue, group-aroot.tenants.group-a.suenginx-sue.yaml
tag (value: namespace)kim, group-bdevroot.tenants.group-b.devnginx-kim.yaml
tag (value: namespace)kim, group-btestroot.tenants.group-b.testnginx-kim.yaml

See the documentation on App Placement Rules for more information.


Limit usable resources on a queue level

To avoid unfair resource usage, we can limit and reserve the amount of resources per queue.

Explanation of Configuration

In the following example, we configure the configuration based on the following:

queueguaranteedmax
memory(G)vcorememory(G)vcore
rootxx15.616
root.system2266
root.tenants2248
root.tenants.group-a1124
root.tenants.group-b1124

Configuration for testing :

kind: ConfigMap
metadata:
name: yunikorn-configs
namespace: yunikorn
apiVersion: v1
data:
admissionController.accessControl.externalGroups: "admin,^group-$"
queues.yaml: |
partitions:
- name: default
queues:
- name: root
queues:
- name: system
adminacl: " admin"
resources:
guaranteed:
{memory: 2G, vcore: 2}
max:
{memory: 6G, vcore: 6}
- name: tenants
resources:
guaranteed:
{memory: 2G, vcore: 2}
max:
{memory: 4G, vcore: 8}
queues:
- name: group-a
adminacl: " group-a"
resources:
guaranteed:
{memory: 1G, vcore: 1}
max:
{memory: 2G, vcore: 4}
- name: group-b
adminacl: " group-b"
resources:
guaranteed:
{memory: 1G, vcore: 1}
max:
{memory: 2G, vcore: 4}

Testing

In the following example, we restrict root.tenants.group-a to use a maximum of {memory: 2G, vcore: 4} resources.

When group-A is deployed in root.tenants.group-a and the required resources exceed the limit, the remaining pods will be blocked.

The results of deploying Pods in different queues are shown below. You can use the YAML file we provide for testing.

user, groupResource Limits for Destination Queuesrequest resources for each replicasreplicaresultYAML filename
admin, admin{memory: 6G, vcore: 6}{memory: 512M, vcore: 250m}1run all replicanginx-admin.yaml
sue, group-A{memory: 2G, vcore: 4}{memory: 512M, vcore: 500m}5run 3 replica (4 replica will exceed the resource limit)nginx-sue.yaml

See the documentation on Partition and Queue Configuration #Resources for more information.


Preemption & Priority scheduling with fencing

YuniKorn supports priority scheduling, where priorities can be assigned to each task and also to each queue.

This section demonstrates how to configure priority in a queue. If you want to configure the priority of each task, you can learn more about it from document Pod Priority and Preemption on Kubernete .

Explanation of Configuration

In the following example, we configure the configuration based on the following:

queueoffset
root
root.system
root.system.high-priority1000
root.system.normal-priority0
root.system.low-priority-1000
root.tenants0 (fenced)
root.tenants.group-a20 (fenced)
root.tenants.group-b5 (fenced)

By default, all priorities are globally scoped, which means that all high-priority queues will be served first. However, we can also limit the priority to certain queues.

The following configuration sets up a fence to ensure that the priorities of the root.tenants queues (and their sub-queues) are evaluated internally.

kind: ConfigMap
metadata:
name: yunikorn-configs
namespace: yunikorn
apiVersion: v1
data:
queues.yaml: |
partitions:
- name: default
queues:
- name: root
properties:
application.sort.policy: fifo # default value: fifo
application.sort.priority: enabled # default value: enable
queues:
- name: system
adminacl: " admin"
queues:
- name: high-priority
properties:
priority.offset: "1000"
- name: normal-priority
properties:
priority.offset: "0"
- name: low-priority
properties:
priority.offset: "-1000"
- name: tenants
properties:
priority.policy: "fence"
queues:
- name: group-a
adminacl: " group-a"
properties:
priority.offset: "20"
- name: group-b
adminacl: " group-b"
properties:
priority.offset: "5"

Testing

Case 1: priority

In the first test, we deploy an equal number of Pods with identical resource requests to three queues with different priorities. Without any priorities, we would expect to see an equal number of Pods deployed to each queue.

However, with priorities and limited resources, the high-priority queue can deploy all of its Pods, the medium-priority queue can deploy some Pods, and the low-priority queue won't be able to deploy any Pods until resources are released by the high-priority queue.

In the following tests, we run the environment with a node resource limit of {memory:16GB, vcore:16}. Note that results will vary based on the environment, and you can modify the YAML file we provide to achieve similar results.

queueoffset# of deploy apps# of apps accept by yunikornYAML filename
root.system.low-priority100088system.yaml
root.system.normal-priority085system.yaml
root.system.high-priority-100080system.yaml

Case 2: priority-fenced

In the second test, we deploy the same number of Pods with the same resource requests to three different priority queues. However, this time, two queues are configured with a fence.

While scheduling the task. Even though root.tenants.group-a has a higher priority than the other two queues, the scheduler will still execute root.system.normal first, which is in the global scope. Then, the scheduler will compare priorities within the local scope of root.tenants.

For the following tests, we run them in an environment with node resources of {memory:16GB, vcore:16}. The results will vary in different environments, but you can obtain similar results by modifying the YAML file we provide.

queueoffset# of deploy apps# of apps accept by yunikornYAML filename
root.system.normal-priority0 (global)77nginx-admin.yaml
root.tenants.group-a20 (fenced)76nginx-sue.yaml
root.tenants.group-b5 (fenced)70nginx-kim.yaml

See the documentation on App & Queue Priorities for more information.