Setting Up the Foundation: Kubernetes Manifests
Creating the Deployment Manifests
After pushing the Docker images to the container registry, we can now deploy our two microservices to the cluster. We will start by creating the deployment manifests for the menu service.
Before creating the deployment manifests, we need to have an external access point to the cluster. We can use an Nginx Ingress controller for this purpose. Start by installing it using Helm.
Add the Ingress Nginx repository:
helm repo add ingress-nginx \
https://kubernetes.github.io/ingress-nginx
Create a values file for the Ingress Nginx controller:
# Create a folder for the Kubernetes deployment files
mkdir -p $HOME/RestQR/deploy/kubernetes
# Create a values file for the Ingress controller
cat <$HOME/RestQR/deploy/kubernetes/ingress-values.yaml
controller:
service:
type: LoadBalancer
EOF
Install the controller:
helm upgrade \
--install \
ingress-nginx \
ingress-nginx/ingress-nginx \
--values $HOME/RestQR/deploy/kubernetes/ingress-values.yaml
Get the external IP address of the Ingress controller and export it as an environment variable:
# Wait for the external IP address to be assigned
while true; do
INGRESS_IP=$(kubectl get svc ingress-nginx-controller \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')
if [[ -n "$INGRESS_IP" ]]; then
break
fi
sleep 2
done
# Export the Ingress IP address as an environment variable
echo "export INGRESS_IP=$INGRESS_IP" >> ~/.bashrc
source ~/.bashrc
Let's move to the application. Create a file called menu-deployment.yaml using the following command:
cat <$HOME/RestQR/deploy/kubernetes/menu-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
# Name of the Deployment
name: menu
labels:
# Label to identify the application
app: menu
spec:
# Number of desired pod replicas (1 instance of the menu service)
replicas: 1
selector:
matchLabels:
# Ensures that the Deployment manages pods with this label
app: menu
template:
metadata:
labels:
# Label assigned to the pod created by this template
app: menu
spec:
containers:
# Name of the container inside the pod
- name: menu
# Image location from GitLab Container Registry
image: $GITLAB_REGISTRY_URL/menu-service:v0.1.0
# Always pull the image from the registry
imagePullPolicy: Always
ports:
# The application inside the container listens on port 5000
- containerPort: 5000
env:
# Environment variable for database connection
- name: DATABASE_URL
valueFrom:
secretKeyRef:
# Reference to the Kubernetes secret containing the database URL
name: menu-secret
# The specific key inside the secret
key: DATABASE_URL
# Image Pull Secret for GitLab Container Registry authentication
imagePullSecrets:
# Kubernetes secret containing GitLab credentials
- name: gitlab-registry-secret
EOF
The above manifest defines a Deployment for the menu service. It specifies that the Deployment should manage one pod with the menu label. The pod runs a container with the menu-service image from the GitLab Container Registry. The container listens on port 5000 and has an environment variable called DATABASE_URL that references a Kubernetes secret called menu-secret. The secret contains the database URL. To pull the image from the GitLab Container Registry, the manifest specifies an image pull secret called gitlab-registry-secret. As you may have noticed, we have not created the secrets yet. We will do this in the next steps.
To create a Secret for the database URL, use the following command:
cat <$HOME/RestQR/deploy/kubernetes/menu-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: menu-secret
type: Opaque
data:
DATABASE_URL: $(echo -n "postgresql://menu-user:menu-password@menu-postgresql:5432/menu-database" | base64 -w 0)
EOF
The above manifest creates a Secret called menu-secret with the database connection string encoded using base64. The connection string contains the username menu-user, password menu-password, and database name menu-database. The database is running on the menu-postgresql service on port 5432. The connection string is in the format postgresql://username:password@hostname:port/database.
We also need to create the pull secret for the GitLab Container Registry. Before doing this, make sure you have the GitLab credentials in a file called config.json in the .docker folder in your home directory (cat $HOME/.docker/config.json). If you don't have this file, you can create it by running the following command:
# Run this only if you don't have the config.json file
mkdir -p $HOME/.docker && cat <$HOME/.docker/config.json
{
"auths": {
"registry.gitlab.com": {
"auth": "$(echo -n "$GITLAB_USERNAME:$GITLAB_API_TOKEN" | base64 -w 0)"
}
}
}
EOF
Now create the pull secret for the GitLab Container Registry:
cat <$HOME/RestQR/deploy/kubernetes/gitlab-registry-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: gitlab-registry-secret
namespace: default
labels:
app: menu
annotations:
kubernetes.io/service-account.name: gitlab-registry-secret
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: $(cat $HOME/.docker/config.json | base64 -w 0)
EOF
We need to create a service for the menu service to expose it to other services in the cluster. Create a file called menu-service.yaml in the RestQR/menu/kube folder:
cat <$HOME/RestQR/deploy/kubernetes/menu-service.yaml
apiVersion: v1
kind: Service
metadata:
name: menu
namespace: default
labels:
app: menu
spec:
selector:
app: menu
ports:
- protocol: TCP
port: 5000
targetPort: 5000
EOF
We will now create the deployment manifests for the qr service. Start by creating a file called qr-deployment.yaml in the RestQR/deploy/kubernetes folder:
cat <$HOME/RestQR/deploy/kubernetes/qr-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: qr
namespace: default
labels:
app: qr
spec:
replicas: 1
selector:
matchLabels:
app: qr
template:
metadata:
labels:
app: qr
spec:
containers:
- name: qr
image: $GITLAB_REGISTRY_URL/qr-service:v0.1.0
imagePullPolicy: Always
ports:
- containerPort: 5001
env:
- name: MENU_BASE_URL
valueFrom:
configMapKeyRef:
name: qr-config
key: MENU_BASE_URL
imagePullSecrets:
- name: gitlab-registry-secret
EOF
Same as the menu service, the above manifest defines a Deployment for the qr service. It specifies that the Deployment should manage one pod with the qr label. The pod runs a container with the qr-service image from the GitLab Container Registry. The container listens on port 5001. To pull the image from the GitLab Container Registry, the manifest specifies an image pull secret called gitlab-registry-secret. The container has an environment variable called MENU_BASE_URL that references a ConfigMap called qr-config. We will now create the ConfigMap:
cat <$HOME/RestQR/deploy/kubernetes/qr-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: qr-config
namespace: default
data:DevSecOps in Practice
A Hands-On Guide to Operationalizing DevSecOps at ScaleEnroll now to unlock current content and receive all future updates for free. Your purchase supports the author and fuels the creation of more exciting content. Act fast, as the price will rise as the course nears completion!
