@codedependant/kubernetes-leader-election
v1.0.1
Published
Leader election for kubernetes using leases
Maintainers
Readme
Kubernetes Leader Election
Leader election for kubernetes using leases
Installation
npm install @codedpendant/kubernetes-leader-election -- saveExports
Events
- (Object) - Named events that are emitted from elector instances
Elector
- (Class) Elector - Elector instances configured with the same lease name will form a coordination group in which one, and only one elector instance can be considered the leader
Classes
Extends: EventEmitter
Elector(options)
Arguments
- (optional)
options(Object): Configuration options for the elector- (optional)
auto_closeBoolean: If true, the elector will try to stop itself when theSIGINTandSIGTERMsignals are sent to the process- default: true
- (optional)
identityString: A unique name for the elector used to claim leadership. THe name of the kubernetes pod is generally safe.- default: elector-{{hostname}}-{{process-id}}
- (optional)
lease_nameString: The name of the kubernetes lease the electors will manage.- default:
nodejs-leader-election
- default:
- (optional)
logObject: A logger instance that implements the abstract-logging interface. pino is recommended. - (optional)
namespaceString: The namespace the elector should be constrained to- default: default
- (optional)
renew_interval_msNumber: The frequency at which the leader will attempt to renew its lease- default: 10000
- (optional)
lease_duration_secNumber: The amount of time assigned to the active lease. After which it is considered expired and the election process will start again- default: 20 (Calculated as (2 * renew_interval_ms) / 1000)
- (optional)
wait_for_leadershipBoolean: Iftrue, when the start() method is called, the elector will wait for a leader to be elected.- default: false
- (optional)
Properties
- current_leader Boolean - Indicates if the elector instance is currently the leader
- lease_name String - The name of the kubernetes lease resources that is being managed
- identity String - The unique name of the elector instance
- namespace String - the kubernetes namespaces the elector is currently bound to
Methods
start(): Promise<void>
stop(): Promise<void>
Usage
The elector instance depends entirely on the kubernetes API. As such, if it cannot determine
that it is running in a kubernetes environment, It will not attempt to interact with the
api and it will assume leadership. Generally useful for development when not running in kubernetes.
When created, the elector will check for the environment variable KUBERNETES_SERVICE_HOST to
make this determination
const {Elector, EVENTS} = require('@codedependant/kubernetes-leader-election')
const elector = new Elector({
lease_name: 'my-application-lease'
, auto_close: false
, identity: process.env.POD_NAME || `my-application-${process.pid}`
})
elector.on(EVENTS.LEADERSHIP_ACQUIRED, (evt) => {
// handle becoming the leader
importantFunction(evt)
})
elector.on(EVENTS.LEADERSHIP_LOST, () => {
// Handle not being the leader
importantFunction(evt)
})
process.on('SIGINT', onSignal)
process.on('SIGTERM', onSignal)
async importantFunction(...args) {
if (!elector.current_leader) {
console.log(`I'm not the leader. Nothing to do`)
return
}
// Do something important that only the leader can do
console.log('Important work has been done')
}
function onSignal(signal) {
elector.log.info('received signal %s', signal)
elector.stop()
}
elector.start()Kubernetes RBAC
To allow your application to manage leases, set up the appropriate RBAC configuration in Kubernetes. This involves creating a ServiceAccount, Role, and a RoleBinding or ClusterRoleBinding to grant the necessary permissions.
Below is an example of the minimal setup required
Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubernetes-election
namespace: defaultRole
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: lease-manager
namespace: default
rules:
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- deleteRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: lease-manager-binding
namespace: default
subjects:
- kind: ServiceAccount
name: kubernetes-election
namespace: default
roleRef:
kind: Role
name: lease-manager
apiGroup: rbac.authorization.k8s.ioExample Deployment
Once this is in place, any deployment or pod that makes use of this package should leverage the previously defined service account. It is highly recommended to make use of the pod name as the elector instance's identity
apiVersion: apps/v1
kind: Deployment
metadata:
name: elector
labels:
app: elector
spec:
selector:
matchLabels:
app: elector
template:
metadata:
labels:
app: elector
spec:
serviceAccountName: kubernetes-election
containers:
- name: application
image: your-node-application:latest
command:
- node
args:
- 'index.js'
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name