Python API and MySQL Helm Chart
This Helm chart simplifies the deployment of a Python Flask API and a MySQL database on Kubernetes. The Python API serves a list of people stored in the MySQL database, demonstrating a basic web application architecture. To extend this project we will package the application artifacts as a Helm chart for deployment into a kubernetes clusters.
The Helm chart directory structure is organized as follows:
/myapp/
.
├── Chart.yaml
├── charts
├── templates
│ ├── api-deployment.yaml
│ ├── api-service.yaml
│ ├── mysql-deployment.yaml
│ └── mysql-service.yaml
└── values.yaml
Prerequisites
Before you begin, ensure you have the following installed:
- Kubernetes cluster (e.g., minikube, kind, or a cloud-managed Kubernetes service)
- Helm (version 3.x)
Create a New Helm Chart
Create a new Helm chart (boilerplate) in your project directory. Helm charts are the packages that Helm uses to deploy applications on compute resources such as kubernetes.
helm create myapp
Python API Deployment: This template configures the deployment of the Python API application. It uses values from the values.yaml
file to set various properties like the deployment name, replica count, container image, and ports.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.api.name }}
spec:
selector:
matchLabels:
app: {{ .Values.api.name }}
replicas: {{ .Values.api.replicaCount }}
template:
metadata:
labels:
app: {{ .Values.api.name }}
spec:
containers:
- name: {{ .Values.api.name }}
image: {{ .Values.api.image.repository }}:{{ .Values.api.image.tag }}
ports:
- containerPort: {{ .Values.api.port }}
env:
- name: DB_HOST
value: {{ .Values.api.dbHost }}
- name: DB_USER
value: {{ .Values.api.dbUser }}
- name: DB_PASSWORD
value: {{ .Values.api.dbPassword }}
- name: DB_DATABASE
value: {{ .Values.api.dbDatabase }}
Python API Service: This template configures the Kubernetes Service for the Python API. It sets the service name and maps the port from the service to the container.
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.api.serviceName }}
spec:
type: ClusterIP
selector:
app: {{ .Values.api.name }}
ports:
- port: {{ .Values.api.servicePort }}
targetPort: {{ .Values.api.port }}
MySQL Deployment: This deployment template is for the MySQL database. It includes environment variables like the root password pulled from the values.yaml
.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.mysql.name }}
spec:
replicas: {{ .Values.mysql.replicaCount }}
selector:
matchLabels:
app: {{ .Values.mysql.name }}
template:
metadata:
labels:
app: {{ .Values.mysql.name }}
spec:
containers:
- name: mysql
image: "{{ .Values.mysql.image.repository }}:{{ .Values.mysql.image.tag }}"
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "{{ .Values.mysql.rootPassword }}"
MySQL Service: This service template creates a Kubernetes Service for MySQL, specifying the necessary ports and selectors.
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.mysql.serviceName }}
spec:
selector:
app: {{ .Values.mysql.name }}
ports:
- protocol: TCP
port: 3306
targetPort: 3306
type: ClusterIP
Here is an example segment from a values.yaml
that should correspond to the templates:
api:
name: python-api
replicaCount: 1
image:
repository: mahlomojats/python-api
tag: latest
port: 5000
dbHost: mysql-service
dbUser: root
dbPassword: password
dbDatabase: people_db
serviceName: python-api-service
servicePort: 5000
mysql:
name: mysql
replicaCount: 1
image:
repository: mahlomojats/sample-mysql
tag: latest
rootPassword: password
serviceName: mysql-service
These steps complete the chart for us, and we can no proceed to publish this chart to our repositories for consumption. The chart can be use as part of your CICD pipeline and delivered to the respective compute resources. Below is an overview of what a typical installation would look like.
Installation
1. Clone the Repository
If the chart is hosted in a Git repository, clone it locally:
git clone [repository-url]
cd [repository-name]/myapp
2. Install the Helm Chart
Use Helm to deploy the chart to your Kubernetes cluster:
helm install myapp-release ./myapp
Replace `myapp-release` with a name of your choice for your deployment.
Configuration
The `values.yaml` file contains the configurable parameters and their default values. You can edit this file to change the default configuration or specify the settings directly through the Helm install command using the `--set` flag.
Example Configuration
mysql:
name: mysql
replicaCount: 1
image:
repository: mysql
tag: "5.7"
rootPassword: "securepassword"
api:
name: python-api
replicaCount: 1
image:
repository: python-api
tag: "latest"
port: 5000
Customize Configuration at Installation
To customize the configuration at the time of installation, use the `--set` flag:
helm install myapp-release ./myapp \
--set mysql.rootPassword="newpassword",api.image.tag="v2"
Accessing the Application
After installing the Helm chart, you can forward the ports to access the Python API locally:
kubectl port-forward service/python-api-service 5000:5000
Then, visit `http://localhost:5000/` in your browser to access the API.
Upgrades and Rollbacks
To upgrade your release after modifying the chart or `values.yaml`:
helm upgrade myapp-release ./myapp
To rollback an upgrade:
helm rollback myapp-release
Uninstallation
To uninstall/delete the deployment:
helm uninstall myapp-release