diff --git a/deploy/k8s/Makefile b/deploy/k8s/Makefile new file mode 100644 index 0000000..a16bb4c --- /dev/null +++ b/deploy/k8s/Makefile @@ -0,0 +1,78 @@ +.PHONY: config volumes services deployments +.DEFAULT_GOAL := help + +all: namespace config deploy assets + +namespace: ## Create the platform namespace + kubectl create -f namespace.yml + +config: ## Create configmap objects + kubectl create configmap nginx-config --from-file=../env/nginx --namespace=openedx + kubectl create configmap mysql-config --from-env-file=../env/mysql/auth.env --namespace=openedx + kubectl create configmap openedx-settings-lms --from-file=../env/openedx/settings/lms --namespace=openedx + kubectl create configmap openedx-settings-cms --from-file=../env/openedx/settings/cms --namespace=openedx + kubectl create configmap openedx-config --from-file=../env/openedx/config --namespace=openedx + kubectl create configmap openedx-scripts --from-file=../env/openedx/scripts --namespace=openedx + +volumes: ## Create volumes + kubectl create -f volumes/ --recursive=true --namespace=openedx +deployments: ## Create deployments + kubectl create -f deployments/ --recursive=true --namespace=openedx +services: ## Create services + kubectl create -f services/ --recursive=true --namespace=openedx +deploy: volumes services deployments + +upgrade: down deploy + +down: ## Delete all non-persistent objects + kubectl delete -f services/ --recursive=true --namespace=openedx + kubectl delete -f deployments/ --recursive=true --namespace=openedx + +delete: + # TODO ask question to make sure user reaaaaaaally want to do this + kubectl delete namespace openedx + + +##################### Databases + +databases: provision-databases migrate #provision-oauth2 ## Bootstrap databases +provision-databases: ## Create necessary databases and users + @$(MAKE) lms-exec COMMAND="bash /openedx/scripts/provision.sh" +provision-oauth2: ## Create users for SSO between services + @$(MAKE) lms-exec COMMAND="bash /openedx/scripts/oauth2.sh" +migrate: migrate-openedx #migrate-forum $(extra_migrate_targets) ## Perform all database migrations +migrate-openedx: ## Perform database migrations on LMS/CMS + @$(MAKE) lms-exec COMMAND="bash -c 'dockerize -wait tcp://mysql:3306 -timeout 20s && ./manage.py lms --settings=tutor.production migrate'" + #@$(MAKE) cms-exec COMMAND="bash -c 'dockerize -wait tcp://mysql:3306 -timeout 20s && ./manage.py cms --settings=tutor.production migrate'" + #$(MAKE) reindex-courses +#migrate-forum: ## Perform database migrations on discussion forums + #$(DOCKER_COMPOSE_RUN) forum bash -c "bundle exec rake search:initialize && \ + #bundle exec rake search:rebuild_index" +#migrate-notes: ## Perform database migrations for the Notes service + #$(DOCKER_COMPOSE_RUN) notes ./manage.py migrate +#migrate-xqueue: ## Perform database migrations for the XQueue service + #$(DOCKER_COMPOSE_RUN) xqueue ./manage.py migrate +#reindex-courses: ## Refresh course index so they can be found in the LMS search engine + #$(DOCKER_COMPOSE_RUN) cms ./manage.py cms reindex_course --all --setup + +##################### Assets + +assets: + $(MAKE) pod-exec APP=nginx COMMAND="rm -rf /var/www/openedx/staticfiles" + kubectl cp openedx/openedx:/openedx/staticfiles openedx/nginx:/var/www/openedx/staticfiles + +##################### Various commands + +lms-shell: ## Launch a shell inside an lms pod + @$(MAKE) lms-exec COMMAND=bash +lms-exec: ## Execute a command inside an lms pod: make lms-exec COMMAND="..." + @$(MAKE) pod-exec APP=lms COMMAND=$(COMMAND) +pod-exec: ## Execute a command inside an arbitrary pod: make pod-exec APP=appname COMMAND="..." + kubectl exec -n openedx -it $$(kubectl get pods -n openedx --selector=app=$(APP) -o name | head -1 | cut -d '/' -f 2) -- $(COMMAND) + +ESCAPE =  +help: ## Print this help + @grep -E '^([a-zA-Z_-]+:.*?## .*|######* .+)$$' Makefile \ + | sed 's/######* \(.*\)/\n $(ESCAPE)[1;31m\1$(ESCAPE)[0m/g' \ + | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[33m%-30s\033[0m %s\n", $$1, $$2}' + diff --git a/deploy/k8s/deployments/ingress.yml b/deploy/k8s/deployments/ingress.yml new file mode 100644 index 0000000..5b69d04 --- /dev/null +++ b/deploy/k8s/deployments/ingress.yml @@ -0,0 +1,15 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: ingress +spec: + rules: + - host: overhang.io + http: + paths: + - backend: + serviceName: nginx + servicePort: 80 + - backend: + serviceName: nginx + servicePort: 443 diff --git a/deploy/k8s/deployments/lms.yml b/deploy/k8s/deployments/lms.yml new file mode 100644 index 0000000..03dd41b --- /dev/null +++ b/deploy/k8s/deployments/lms.yml @@ -0,0 +1,46 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: lms +spec: + replicas: 1 + selector: + matchLabels: + app: lms + template: + metadata: + labels: + app: lms + spec: + containers: + - name: lms + image: regis/openedx:latest + ports: + - containerPort: 8000 + volumeMounts: + - mountPath: /openedx/edx-platform/lms/envs/tutor/ + name: settings-lms + - mountPath: /openedx/edx-platform/cms/envs/tutor/ + name: settings-cms + - mountPath: /openedx/config + name: config + - mountPath: /openedx/scripts + name: scripts + - mountPath: /openedx/data + name: data + volumes: + - name: settings-lms + configMap: + name: openedx-settings-lms + - name: settings-cms + configMap: + name: openedx-settings-cms + - name: config + configMap: + name: openedx-config + - name: scripts + configMap: + name: openedx-scripts + - name: data + persistentVolumeClaim: + claimName: lms-data diff --git a/deploy/k8s/deployments/memcached.yml b/deploy/k8s/deployments/memcached.yml new file mode 100644 index 0000000..d696953 --- /dev/null +++ b/deploy/k8s/deployments/memcached.yml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: memcached +spec: + replicas: 1 + selector: + matchLabels: + app: memcached + template: + metadata: + labels: + app: memcached + spec: + containers: + - name: memcached + image: memcached:1.4.38 + ports: + - containerPort: 11211 diff --git a/deploy/k8s/deployments/mongodb.yml b/deploy/k8s/deployments/mongodb.yml new file mode 100644 index 0000000..cb81e78 --- /dev/null +++ b/deploy/k8s/deployments/mongodb.yml @@ -0,0 +1,26 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mongodb +spec: + replicas: 1 + selector: + matchLabels: + app: mongodb + template: + metadata: + labels: + app: mongodb + spec: + containers: + - name: mongodb + image: mongo:3.2.16 + command: ["mongod", "--smallfiles", "--nojournal", "--storageEngine", "wiredTiger"] + ports: + - containerPort: 27017 + volumeMounts: + - mountPath: /data/db + name: data + volumes: + - name: data + emptyDir: {} diff --git a/deploy/k8s/deployments/mysql.yml b/deploy/k8s/deployments/mysql.yml new file mode 100644 index 0000000..f92a561 --- /dev/null +++ b/deploy/k8s/deployments/mysql.yml @@ -0,0 +1,32 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mysql +spec: + replicas: 1 + selector: + matchLabels: + app: mysql + template: + metadata: + labels: + app: mysql + spec: + containers: + - name: mysql + image: mysql:5.6.36 + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + configMapKeyRef: + name: mysql-config + key: MYSQL_ROOT_PASSWORD + ports: + - containerPort: 3306 + volumeMounts: + - mountPath: /var/lib/mysql + name: data + volumes: + - name: data + persistentVolumeClaim: + claimName: mysql diff --git a/deploy/k8s/deployments/nginx.yml b/deploy/k8s/deployments/nginx.yml new file mode 100644 index 0000000..27bdb20 --- /dev/null +++ b/deploy/k8s/deployments/nginx.yml @@ -0,0 +1,34 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx +spec: + replicas: 1 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:latest + volumeMounts: + - mountPath: /etc/nginx/conf.d/ + name: config + - mountPath: /openedx/data/lms + name: data + ports: + - containerPort: 80 + name: http-port + - containerPort: 443 + name: https-port + volumes: + - name: config + configMap: + name: nginx-config + - name: data + persistentVolumeClaim: + claimName: lms-data diff --git a/deploy/k8s/namespace.yml b/deploy/k8s/namespace.yml new file mode 100644 index 0000000..efd7187 --- /dev/null +++ b/deploy/k8s/namespace.yml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: openedx diff --git a/deploy/k8s/services/memcached.yml b/deploy/k8s/services/memcached.yml new file mode 100644 index 0000000..26678e3 --- /dev/null +++ b/deploy/k8s/services/memcached.yml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: memcached +spec: + type: NodePort + ports: + - port: 11211 + protocol: TCP + selector: + app: memcached diff --git a/deploy/k8s/services/mongodb.yml b/deploy/k8s/services/mongodb.yml new file mode 100644 index 0000000..3b64098 --- /dev/null +++ b/deploy/k8s/services/mongodb.yml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: mongodb +spec: + type: NodePort + ports: + - port: 27017 + protocol: TCP + selector: + app: mongodb diff --git a/deploy/k8s/services/mysql.yml b/deploy/k8s/services/mysql.yml new file mode 100644 index 0000000..6a5ee86 --- /dev/null +++ b/deploy/k8s/services/mysql.yml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: mysql +spec: + type: NodePort + ports: + - port: 3306 + protocol: TCP + selector: + app: mysql diff --git a/deploy/k8s/services/nginx.yml b/deploy/k8s/services/nginx.yml new file mode 100644 index 0000000..2ef2f3f --- /dev/null +++ b/deploy/k8s/services/nginx.yml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: nginx +spec: + type: NodePort + ports: + - port: 80 + protocol: TCP + name: http + targetPort: http-port + - port: 443 + protocol: TCP + name: https + targetPort: https-port + selector: + app: nginx diff --git a/deploy/k8s/services/openedx.yml b/deploy/k8s/services/openedx.yml new file mode 100644 index 0000000..e24e2f7 --- /dev/null +++ b/deploy/k8s/services/openedx.yml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: openedx +spec: + type: NodePort + ports: + - port: 8000 + protocol: TCP + selector: + # TODO different services and names for lms/cms + app: openedx diff --git a/deploy/k8s/volumes/lms-data-pvc.yml b/deploy/k8s/volumes/lms-data-pvc.yml new file mode 100644 index 0000000..429af39 --- /dev/null +++ b/deploy/k8s/volumes/lms-data-pvc.yml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: lms-data +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi diff --git a/deploy/k8s/volumes/mysql-pvc.yml b/deploy/k8s/volumes/mysql-pvc.yml new file mode 100644 index 0000000..46a7f10 --- /dev/null +++ b/deploy/k8s/volumes/mysql-pvc.yml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mysql +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi diff --git a/docs/k8s.rst b/docs/k8s.rst new file mode 100644 index 0000000..189c779 --- /dev/null +++ b/docs/k8s.rst @@ -0,0 +1,45 @@ +.. _k8s: + +Kubernetes deployment +===================== + +With the same docker images we created for :ref:`single server deployment ` and :ref:`local development `, we can launch an Open edX platform on Kubernetes. Always in 1 click, of course :) + +:: + + _ _ __ _ + __ _| |_ __ | |__ __ _ / _| ___ __ _| |_ _ _ _ __ ___ + / _` | | '_ \| '_ \ / _` | | |_ / _ \/ _` | __| | | | '__/ _ \ + | (_| | | |_) | | | | (_| | | _| __/ (_| | |_| |_| | | | __/ + \__,_|_| .__/|_| |_|\__,_| |_| \___|\__,_|\__|\__,_|_| \___| + |_| + +Kubernetes deployment is currently an alpha feature, and we are hard at work to make it 100% reliable 🛠️ If you are interested in deploying Open edX to Kubernetes, please get in touch! Your input will be much appreciated. + +Requirements +------------ + +In the following, we assume you have a working Kubernetes platform. For a start, you can run Kubernetes locally inside a VM with Minikube. Just follow the `official documentation `_. + +Start Minikube:: + + minikube start + +Ingress addon must be installed:: + + minikube addons enable ingress + +At any point, access a UI to view the state of the platform with:: + + minikube dashboard + +In the following, all commands should be run inside the ``deploy/k8s`` folder:: + + cd deploy/k8s + +Quickstart +---------- + +Launch the platform on k8s in 1 click:: + + make all