diff --git a/examples/notebooks/README.md b/examples/notebooks/README.md new file mode 100644 index 000000000..d4f0cf382 --- /dev/null +++ b/examples/notebooks/README.md @@ -0,0 +1,12 @@ +Jupyter Notebooks for Kubernetes +================================ + +This is a set of Jupyter notebooks to learn the Kubernetes API in Python. + +Launch the deployment and create the service. + +``` +kubectl create -f docker/jupyter.yml +``` + +Open your browser on the jupyter service and go through the notebooks. diff --git a/examples/notebooks/create_deployment.ipynb b/examples/notebooks/create_deployment.ipynb new file mode 100644 index 000000000..c7423f306 --- /dev/null +++ b/examples/notebooks/create_deployment.ipynb @@ -0,0 +1,80 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from kubernetes import client, config" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "client.Configuration().host=\"http://localhost:8080\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "extensions = client.ExtensionsV1beta1Api()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "body = extensions.V1beta1Deployment()\n", + "namespace = \"default\"\n", + "\n", + "deployment = client.V1beta1Deployment()\n", + "deployment.metadata = client.V1ObjectMeta(name=\"jupyter\")\n", + "spec = client.V1beta1DeploymentSpec()\n", + "spec.template = client.V1PodTemplateSpec()\n", + "spec.template.metadata = client.V1ObjectMeta()\n", + "spec.template.spec = client.V1PodSpec()\n", + "\n", + "\n", + "extensions.create_namespaced_deployment(namespace, body)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/examples/notebooks/create_pod.ipynb b/examples/notebooks/create_pod.ipynb new file mode 100644 index 000000000..e774b0732 --- /dev/null +++ b/examples/notebooks/create_pod.ipynb @@ -0,0 +1,345 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "How to start a Pod\n", + "==================\n", + "\n", + "In this notebook, we show you how to create a single container Pod.\n", + "\n", + "Start by importing the Kubernetes module\n", + "-----------------------------------------" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from kubernetes import client, config" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you are using a proxy, you can use the _client Configuration_ to setup the host that the client should use. Otherwise read the kubeconfig file." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "config.load_incluster_config()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pods are a stable resource in the V1 API group. Instantiate a client for that API group endpoint." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "v1=client.CoreV1Api()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [], + "source": [ + "pod=client.V1Pod()\n", + "spec=client.V1PodSpec()\n", + "pod.metadata=client.V1ObjectMeta(name=\"busybox\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this example, we only start one container in the Pod. The container is an instnace of the _V1Container_ class. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "container=client.V1Container()\n", + "container.image=\"busybox\"\n", + "container.args=[\"sleep\", \"3600\"]\n", + "container.name=\"busybox\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The specification of the Pod is made of a single container in its list." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "spec.containers = [container]\n", + "pod.spec = spec" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get existing list of Pods, before the creation of the new Pod." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "172.17.0.6 default jupyter\n" + ] + } + ], + "source": [ + "ret = v1.list_namespaced_pod(namespace=\"default\")\n", + "for i in ret.items:\n", + " print(\"%s %s %s\" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You are now ready to create the Pod." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'metadata': {'annotations': None,\n", + " 'cluster_name': None,\n", + " 'creation_timestamp': u'2017-04-01T23:30:48Z',\n", + " 'deletion_grace_period_seconds': None,\n", + " 'deletion_timestamp': None,\n", + " 'finalizers': None,\n", + " 'generate_name': None,\n", + " 'generation': None,\n", + " 'labels': None,\n", + " 'name': 'busybox',\n", + " 'namespace': 'default',\n", + " 'owner_references': None,\n", + " 'resource_version': '26551',\n", + " 'self_link': '/api/v1/namespaces/default/pods/busybox',\n", + " 'uid': '3c6a0821-1733-11e7-877c-0800277d3a21'},\n", + " 'spec': {'active_deadline_seconds': None,\n", + " 'containers': [{'args': ['sleep', '3600'],\n", + " 'command': None,\n", + " 'env': None,\n", + " 'image': 'busybox',\n", + " 'image_pull_policy': 'Always',\n", + " 'lifecycle': None,\n", + " 'liveness_probe': None,\n", + " 'name': 'busybox',\n", + " 'ports': None,\n", + " 'readiness_probe': None,\n", + " 'resources': {'limits': None, 'requests': None},\n", + " 'security_context': None,\n", + " 'stdin': None,\n", + " 'stdin_once': None,\n", + " 'termination_message_path': '/dev/termination-log',\n", + " 'tty': None,\n", + " 'volume_mounts': [{'mount_path': '/var/run/secrets/kubernetes.io/serviceaccount',\n", + " 'name': 'default-token-x47xb',\n", + " 'read_only': True,\n", + " 'sub_path': None}],\n", + " 'working_dir': None}],\n", + " 'dns_policy': 'ClusterFirst',\n", + " 'host_ipc': None,\n", + " 'host_network': None,\n", + " 'host_pid': None,\n", + " 'hostname': None,\n", + " 'image_pull_secrets': None,\n", + " 'node_name': None,\n", + " 'node_selector': None,\n", + " 'restart_policy': 'Always',\n", + " 'security_context': {'fs_group': None,\n", + " 'run_as_non_root': None,\n", + " 'run_as_user': None,\n", + " 'se_linux_options': None,\n", + " 'supplemental_groups': None},\n", + " 'service_account': 'default',\n", + " 'service_account_name': 'default',\n", + " 'subdomain': None,\n", + " 'termination_grace_period_seconds': 30,\n", + " 'volumes': [{'name': 'default-token-x47xb'}]},\n", + " 'status': {'conditions': None,\n", + " 'container_statuses': None,\n", + " 'host_ip': None,\n", + " 'message': None,\n", + " 'phase': 'Pending',\n", + " 'pod_ip': None,\n", + " 'reason': None,\n", + " 'start_time': None}}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v1.create_namespaced_pod(namespace=\"default\",body=pod)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get list of Pods, after the creation of the new Pod. Note the newly created pod with name \"busybox\"" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "None default busybox\n", + "172.17.0.6 default jupyter\n" + ] + } + ], + "source": [ + "ret = v1.list_namespaced_pod(namespace=\"default\")\n", + "for i in ret.items:\n", + " print(\"%s %s %s\" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Delete the Pod\n", + "--------------\n", + "\n", + "You refer to the Pod by name, you need to add its namespace and pass some _delete_ options." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'code': None,\n", + " 'details': None,\n", + " 'message': None,\n", + " 'metadata': {'resource_version': '26556',\n", + " 'self_link': '/api/v1/namespaces/default/pods/busybox'},\n", + " 'reason': None,\n", + " 'status': \"{u'phase': u'Pending', u'conditions': [{u'status': u'True', u'lastProbeTime': None, u'type': u'Initialized', u'lastTransitionTime': u'2017-04-01T23:30:48Z'}, {u'status': u'False', u'lastTransitionTime': u'2017-04-01T23:30:48Z', u'reason': u'ContainersNotReady', u'lastProbeTime': None, u'message': u'containers with unready status: [busybox]', u'type': u'Ready'}, {u'status': u'True', u'lastProbeTime': None, u'type': u'PodScheduled', u'lastTransitionTime': u'2017-04-01T23:30:48Z'}], u'containerStatuses': [{u'restartCount': 0, u'name': u'busybox', u'image': u'busybox', u'imageID': u'', u'state': {u'waiting': {u'reason': u'ContainerCreating'}}, u'ready': False, u'lastState': {}}], u'startTime': u'2017-04-01T23:30:48Z', u'hostIP': u'192.168.99.100'}\"}" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v1.delete_namespaced_pod(name=\"busybox\", namespace=\"default\", body=client.V1DeleteOptions())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/examples/notebooks/docker/Dockerfile b/examples/notebooks/docker/Dockerfile new file mode 100644 index 000000000..49fe5532f --- /dev/null +++ b/examples/notebooks/docker/Dockerfile @@ -0,0 +1,7 @@ +FROM nbgallery/jupyter-alpine:latest + +RUN pip install git+https://github.com/kubernetes-incubator/client-python.git + +ENTRYPOINT ["/sbin/tini", "--"] +CMD ["jupyter", "notebook", "--ip=0.0.0.0"] + diff --git a/examples/notebooks/docker/jupyter.yml b/examples/notebooks/docker/jupyter.yml new file mode 100644 index 000000000..a3c214122 --- /dev/null +++ b/examples/notebooks/docker/jupyter.yml @@ -0,0 +1,36 @@ +apiVersion: v1 +kind: Service +metadata: + name: jupyter + labels: + app: jupyter +spec: + ports: + - port: 80 + name: http + targetPort: 8888 + selector: + app: jupyter + type: NodePort +--- +apiVersion: v1 +kind: Pod +metadata: + name: jupyter + labels: + app: jupyter +spec: + containers: + - name: jupyter + image: skippbox/jupyter:0.0.3 + ports: + - containerPort: 8888 + protocol: TCP + name: http + volumeMounts: + - mountPath: /root + name: notebook-volume + volumes: + - name: notebook-volume + gitRepo: + repository: "https://github.com/kubernetes-incubator/client-python.git" diff --git a/examples/notebooks/test.ipynb b/examples/notebooks/test.ipynb new file mode 100644 index 000000000..9f7aa6b83 --- /dev/null +++ b/examples/notebooks/test.ipynb @@ -0,0 +1,104 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from kubernetes import client, config" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "config.load_incluster_config()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "v1=client.CoreV1Api()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "default\n", + "kube-system\n", + "kubeless\n" + ] + } + ], + "source": [ + "for ns in v1.list_namespace().items:\n", + " print ns.metadata.name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} +