This repository has been archived by the owner on Sep 14, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an example for built-in pods controller
- Loading branch information
Sergey Vasilyev
committed
Jun 18, 2019
1 parent
d3e23ab
commit 125c5d0
Showing
2 changed files
with
86 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Kopf example for built-in resources | ||
|
||
Kopf can also handle the built-in resources, such as Pods, Jobs, etc. | ||
|
||
In this example, we take control all over the pods (namespaced/cluster-wide), | ||
and allow the pods to exist for no longer than 30 seconds -- | ||
either after creation or after the operator restart. | ||
|
||
For no specific reason, just for fun. Maybe, as a way of Chaos Engineering | ||
to force making the resilient applications (tolerant to pod killing). | ||
|
||
However, the system namespaces (kube-system, etc) are explicitly protected -- | ||
to prevent killing the cluster itself. | ||
|
||
Start the operator: | ||
|
||
```bash | ||
kopf run example.py --verbose | ||
``` | ||
|
||
Start a sample pod: | ||
|
||
```bash | ||
kubectl run -it --image=ubuntu expr1 -- bash -i | ||
# wait for 30s | ||
``` | ||
|
||
Since `kubectl run` creates a Deployment, not just a Pod, | ||
a new pod will be created every 30 seconds. Observe with: | ||
|
||
```bash | ||
kubectl get pods --watch | ||
``` | ||
|
||
*Please note that Kopf puts a finalizer on the managed resources, | ||
so the pod deletion will be blocked unless the operator is running | ||
(to remove the finalizer). This will be made optional in #24.* | ||
|
||
Cleanup in the end: | ||
|
||
```bash | ||
$ kubectl delete deployment expr1 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import asyncio | ||
|
||
import kopf | ||
import pykube | ||
|
||
TIMEOUT = 30 | ||
tasks = {} # dict{namespace: dict{name: asyncio.Task}} | ||
|
||
|
||
@kopf.on.resume('', 'v1', 'pods') | ||
@kopf.on.create('', 'v1', 'pods') | ||
async def pod_in_sight(namespace, name, logger, **kwargs): | ||
if namespace.startswith('kube-'): | ||
return | ||
else: | ||
task = asyncio.create_task(pod_killer(namespace, name, logger)) | ||
tasks.setdefault(namespace, {}) | ||
tasks[namespace][name] = task | ||
|
||
|
||
@kopf.on.delete('', 'v1', 'pods') | ||
async def pod_deleted(namespace, name, **kwargs): | ||
if namespace in tasks and name in tasks[namespace]: | ||
task = tasks[namespace][name] | ||
task.cancel() # it will also remove from `tasks` | ||
|
||
|
||
async def pod_killer(namespace, name, logger): | ||
try: | ||
logger.info(f"=== Pod killing happens in {TIMEOUT}s.") | ||
await asyncio.sleep(TIMEOUT) | ||
logger.info(f"=== Pod killing happens NOW!") | ||
|
||
api = kopf.get_pykube_api() | ||
pod = pykube.Pod.objects(api, namespace=namespace).get_by_name(name) | ||
pod.delete() | ||
|
||
except asyncio.CancelledError: | ||
logger.info(f"=== Pod killing is cancelled!") | ||
|
||
finally: | ||
if namespace in tasks and name in tasks[namespace]: | ||
del tasks[namespace][name] |