Question: Is it possible to broadcast events to all replicas of a target?
oEscal opened this issue · 5 comments
For instance, imagine I have a Trigger whose subscriber is a Knative Service. It seems that the expected behavior is that when there is a new event, it is sent to one of the replicas of that Service. However, would it be possible to send that event to all replicas of that Service?
the way I would do it is to have an init container in your subscriber service creating a pod-specific trigger with subscriber uri: <pod_ip>
, for example:
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
name: <pod_name>
namespace: <pod_namespace>
ownerReferences: # This configures garbage collection, when the pod is deleted the trigger will be deleted
- apiVersion: v1
kind: Pod
name: <pod_name>
uid: <pod_uid>
controller: true
blockOwnerDeletion: false
spec:
broker: my-broker
subscriber:
uri: http://<pod_ip>:<your_subscriber_pod_port>
you can inject the various variables <pod_ip>
, <pod_name>
into the init container environment variables using the k8s downward API: https://kubernetes.io/docs/concepts/workloads/pods/downward-api/#downwardapi-fieldRef
For example: (I didn't check the syntax but it should give you an idea)
apiVersion: apps/v1
kind: Deployment
metadata:
name: subscriber-deployment
spec:
selector:
matchLabels:
app: subscriber
template:
metadata:
labels:
app: subscriber
spec:
serviceAccountName: <service_account> # Ensure this service account has permissions to create Knative triggers
initContainers:
- name: init-trigger
image: bitnami/kubectl:latest
command:
- sh
- -c
- |
cat <<EOF | kubectl apply -f -
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
name: $(POD_NAME)
namespace: $(POD_NAMESPACE)
ownerReferences:
- apiVersion: v1
kind: Pod
name: $(POD_NAME)
uid: $(POD_UID)
controller: true
blockOwnerDeletion: false
spec:
broker: my-broker
subscriber:
uri: http://$(POD_IP):80
EOF
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_UID
valueFrom:
fieldRef:
fieldPath: metadata.uid
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
containers:
- name: subscriber
image: nginx
ports:
- containerPort: 80
This way each pod (instance) will get all events from the broker my-broker
in addition, I'd wait for the created trigger to become ready in the init container
kubectl wait triggers.eventing.knative.dev --for=condition=Ready=true -n $(POD_NAMESPACE) $(POD_NAME) --timeout=20m
With a Knative Service that scales from 0 might not be possible though, as the real receiver when scaling from 0 to 1 needs to be the activator https://github.com/knative/serving/blob/main/docs/scaling/SYSTEM.md
Closing this issue for now, re-open in case the above doesn't work for you