Playground for Django enabled apps
Setup
- django-admin startproject library (Use the django-admin tool to create the project folder, basic file templates, and project management script (manage.py).)
- cd library
-
Postgres database setup CREATE DATABASE library; CREATE USER TEST WITH ENCRYPTED PASSWORD 'test123'; \du grant all privileges on database library to test; $ psql
-
If you have unapplied migrations, Run 'python manage.py migrate' to apply them. DJANGO_SETTINGS_MODULE=locallibrary.settings_dev python3 manage.py migrate
-
Run Server On a dev machine run your Django app with: DJANGO_SETTINGS_MODULE=locallibrary.settings_dev python3 manage.py runserver
On a prod machine run as if you just had settings.py and nothing else.
gcloud auth login (Ensure you are logged in using credentials for your GCP account)
gcloud auth application-default login
gcloud init
gcloud sql instances describe library
pip3 install psycopg2-binary
gcloud services enable sqladmin
curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
chmod +x cloud_sql_proxy
./cloud_sql_proxy -instances="library-259506:asia-south1:library"=tcp:3306
WARNING: python manage.py makemigrations (for first time only)
python manage.py migrate (apply migrations in case of changes)
python3 manage.py createsuperuser
pip3 freeze > requirements.txt
python manage.py collectstatic
gcloud app deploy
Assumption: https://console.cloud.google.com/apis/api/container.googleapis.com/overview Ensure kubernetes engine api is enabled Instructions: https://cloud.google.com/python/django/kubernetes-engine
a) gcloud services enable sqladmin b) wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy c) chmod +x cloud_sql_proxy
d) gcloud sql instances describe [YOUR_INSTANCE_NAME] e) ensure all settings are uptodate with the new connection name f) ./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:5432
Remember to create the json file that has your private key lib-service created
- config check g) Ensure library.yaml file refers to the proper sql connection names for cloudsqlproxy h) Note: The one difference between GKE and appengine, is that the static folder needs to be created on cloud storage $gsutil mb gs://gcslibrarybucket
Creating gs://gcslibrarybucket/... $gsutil defacl set public-read gs://gcslibrarybucket Setting default object ACL on gs://gcslibrarybucket/... (if not done, python manage.py collectstatic) Upload the static content to Cloud Storage: $gsutil rsync -R static/ gs://[YOUR_GCS_BUCKET]/static
In library/settings.py, set the value of STATIC_URL to the following URL, replacing [YOUR_GCS_BUCKET] with your bucket name: for GKE STATIC_URL = 'http://storage.googleapis.com/[YOUR_GCS_BUCKET]/static/'
- Creating a Kubernetes Engine cluster gcloud container clusters create library --num-nodes 4
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS librarymgr asia-south1-b 1.13.11-gke.14 34.93.220.39 n1-standard-1 1.13.11-gke.14 3 RUNNING Now that you have created a cluster, you can deploy a containerized application to it.
- Get authentication credentials for the cluster, make sure kubectl is configured to interact with the right cluster $ gcloud container clusters get-credentials library
Fetching cluster endpoint and auth data. $ kubeconfig entry generated for library
- Deploying a containerized web application Package your app into a Docker container image $ gcloud components install kubectl
Make sure the application is packaged as a Docker image, using the Dockerfile that contains instructions on how the image is built.
- Setup cloud SQL - You need several secrets to enable your GKE app to connect with your Cloud SQL instance kubectl delete secret cloudsql-oauth-credentials kubectl create secret generic cloudsql-oauth-credentials --from-file=credentials.json='/Users/sramakrishnan/work/django/django-playground/credentials/library-259506-b97067527626.json'
secret/cloudsql-oauth-credentials created
Important step $kubectl create secret generic cloudsql --from-literal=username=test --from-literal=password=test123
- Retrieve the public Docker image for the Cloud SQL proxy. $docker pull b.gcr.io/cloudsql-docker/gce-proxy:1.05
Verify your build with
$docker system prune (cleanup the space) $docker container ls -a $docker container rm (if you want to remove images) $docker system prune -a (to cleanup all unused + cache etc)
- Configure Docker to use gcloud as a credential helper, so that you can push the image to Container Registry:
$gcloud auth configure-docker
The following settings will be added to your Docker config file located at [/Users/sramakrishnan/.docker/config.json]: { "credHelpers": { "gcr.io": "gcloud", "us.gcr.io": "gcloud", "eu.gcr.io": "gcloud", "asia.gcr.io": "gcloud", "staging-k8s.gcr.io": "gcloud", "marketplace.gcr.io": "gcloud" } }
- Push the docker image: You create your Docker image and push it to a registry before referring to it in a Kubernetes pod. Kubernetes has native support for the Google Container Registry (GCR), when running on Google Compute Engine (GCE). The kubelet will authenticate to GCR using the instance’s Google service account. T
$ kubectl create deployment libary --image=gcr.io/library-259506/library:latest
deployment.apps/libary created OR $docker push gcr.io/library-259506/library
Test your docker image $docker run -p 8000:8000 -i -t /<Docker-Image_name>
- Create the GKE resource: $ kubectl create -f ./library.yaml deployment.extensions/library created service/library created
Track the status of the deployment: $kubectl get deployments
- After the resources are created, there are three polls pods on the cluster. Check the status of your pods: $ kubectl get pods
debugging kubectl logs [YOUR_POD_ID] $ kubectl logs [YOUR_POD_ID] -p $ kubectl describe pods [library-7f7977fdfc-cvlph] Crashloop backoff error: https://managedkube.com/kubernetes/pod/failure/crashloopbackoff/k8sbot/troubleshooting/2019/02/12/pod-failure-crashloopbackoff.html kubectl apply -f ./library.yaml kubectl get events --sort-by=.metadata.creationTimestamp
Check the state of cluster: $kubectl get nodes
Check logs in kubectl: $sudo systemctl status kubectl
- After the pods are ready, you can get the public IP address of the load balancer: $kubectl get services library
For incremental updates to yur Dockerfile $ docker build -t gcr.io/library-259506/library . $ docker push gcr.io/library-259506/library $ kubectl apply -f ./library.yaml
Delete the Service: This step will deallocate the Cloud Load Balancer created for your Service: $kubectl delete service hello-web
Delete the container cluster: This step will delete the resources that make up the container cluster, such as the compute instances, disks and network resources. $gcloud container clusters delete hello-cluster
https://medium.com/@BennettGarner/deploying-a-django-application-to-google-app-engine-f9c91a30bd35 and https://cloud.google.com/python/django/appengine
https://cloud.google.com/python/django/appengine
https://stackoverflow.com/questions/10664244/django-how-to-manage-development-and-production-settings https://stackoverflow.com/questions/1626326/how-to-manage-local-vs-production-settings-in-django
-
app.yaml reference https://cloud.google.com/appengine/docs/standard/python/config/appref
-
Top reasons for GKE issues https://kukulinski.com/10-most-common-reasons-kubernetes-deployments-fail-part-1/
-
Kubernetes Cheat Sheet https://kubernetes.io/docs/reference/kubectl/cheatsheet/#deleting-resources
-
IF you check in credentials by mistake, how to undo using bfg tool https://help.github.com/en/github/authenticating-to-github/removing-sensitive-data-from-a-repository