Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
1mb4dr committed Oct 8, 2020
0 parents commit 2f37838
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# python-app-with-azure-kubernetes
A demo python application used in blog Application Deployment on Azure Kubernetes Services.

This repo is used in the Medium blog [Application Deployment with Azure Kubernetes Service and Azure Pipelines](https://medium.com/faun/application-deployment-with-azure-kubernetes-service-and-azure-pipelines-a0bf43916746)

### Steps

**Create a resource group in Azure Subscription**<br>
`az group create -l southcentralus -n cloudorbit-resource-grp --subscription pay-as-you-go`

**Create Azure k8s cluster**<br>
`az aks create -g cloudorbit-resource-grp -n cloudobrit-cluster --node-vm-size Standard_B2s --node-count 2 --generate-ssh-keys`

**Create Azure Container Registry**<br>
`az acr create -g cloudorbit-resource-grp -n cloudorbit --sku Standard`

**Create Azure Pipelines**<br>
Follow the steps in the blog to create and setup Azure Pipeline via Azure DevOps console<br>

Once all done, we need to check the running pod, services and horizontal pod autoscaler<br>

**Authenticate your k8s cluster with cloud-shell**<br>
`az aks get-credentials -g cloudorbit-resource-grp -n cloudobrit-cluster`

**Get deployments**<br>
`kubectl -n dev get deployments`

**Get pods**<br>
`kubectl -n dev get pods`

**Get services**<br>
`kubectl -n dev get svc`

**Get Horizontal Pod Autoscaler**<br>
`kubectl -n dev get hpa`

**To check the app**<br>
`curl http://[external-ip]:5000`

**To describe pods specification and check logs**<br>
`kubectl -n dev describe pods [pod-name]`
`kubectl -n dev logs [pod-name]`

*We can scale our deployment manually as well as automatically. For automatic scaling, we have defined HPA in YAML which increases one replica of pod whenever the average traffic on the running pod goes beyond 80%. It will increase replica up to the max number we defined in YAML manifest that’s 3 in our case.*

**To manual scale**<br>
`kubectl -n dev scale deployment python-app --replicas=3`
`kubectl -n dev get deployment python-app`

**For interactive UI console of k8s cluster**<br>
`az aks browse -g cloudorbit-resource-grp -n cloudorbit-cluster`

**For entering into pods**<br>
`kubectl -n dev exec -it [pod-name] -- /bin/bash`
78 changes: 78 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Deploy to Azure Kubernetes Service
# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- master

resources:
- repo: self

variables:

# Container registry service connection established during pipeline creation
dockerRegistryServiceConnection: '43322574-036c-4786-83bd-e924f31a2a52'
imageRepository: 'pythonapp'
containerRegistry: 'cloudorbit.azurecr.io'
dockerfilePath: '**/Dockerfile'
tag: '$(Build.BuildId)'
imagePullSecret: 'cloudorbit429779af-auth'

# Agent VM image name
vmImageName: 'ubuntu-latest'


stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: Docker@2
displayName: Build and push an image to azure container registry
inputs:
command: buildAndPush
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
- upload: manifests
artifact: manifests

- stage: Deploy
displayName: Deploy stage
dependsOn: Build

jobs:
- deployment: Deploy
displayName: Deploy
pool:
vmImage: $(vmImageName)
environment: 'r4rohanpythonappwithazurekubernetes.dev'
strategy:
runOnce:
deploy:
steps:
- task: KubernetesManifest@0
displayName: Create imagePullSecret
inputs:
action: createSecret
secretName: $(imagePullSecret)
dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

- task: KubernetesManifest@0
displayName: Deploy to Kubernetes cluster
inputs:
action: deploy
manifests: |
$(Pipeline.Workspace)/manifests/app.yml
imagePullSecrets: |
$(imagePullSecret)
containers: |
$(containerRegistry)/$(imageRepository):$(tag)
52 changes: 52 additions & 0 deletions manifests/app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: python-app
labels:
name: python-app
spec:
replicas: 1
minReadySeconds: 60
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
name: python-app
spec:
containers:
- name: test
image: cloudorbit.azurecr.io/pythonapp
imagePullPolicy: Always

---
kind: Service
apiVersion: v1
metadata:
name: python-app
spec:
selector:
name: python-app
ports:
- name: port1
protocol: TCP
port: 5000
targetPort: 5000
type: LoadBalancer

---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: python-app
spec:
maxReplicas: 3
minReplicas: 1
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: python-app
targetCPUUtilizationPercentage: 80
16 changes: 16 additions & 0 deletions manifests/deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion : apps/v1beta1
kind: Deployment
metadata:
name: pythonapp
spec:
replicas: 1
template:
metadata:
labels:
app: pythonapp
spec:
containers:
- name: pythonapp
image: cloudorbit.azurecr.io/pythonapp
ports:
- containerPort: 5000
17 changes: 17 additions & 0 deletions manifests/nginx-ingress.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: 25m
spec:
rules:
- host: domain-name.com
http:
paths:
- path: /
backend:
serviceName: python-app
servicePort: 5000
10 changes: 10 additions & 0 deletions manifests/service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
kind: Service
metadata:
name: pythonapp
spec:
type: LoadBalancer
ports:
- port: 5000
selector:
app: pythonapp
7 changes: 7 additions & 0 deletions python-application/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM python:3.6
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . /app
EXPOSE 5000
CMD [ "python", "app.py" ]
11 changes: 11 additions & 0 deletions python-application/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from flask import Flask
app = Flask(__name__)


@app.route('/')
def hello():
return "Stay inside, stay safe and keep social distancing."

if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0',port=5000)
app.run(host='0.0.0.0')
1 change: 1 addition & 0 deletions python-application/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
flask

0 comments on commit 2f37838

Please sign in to comment.