Skip to content

Latest commit

 

History

History
523 lines (438 loc) · 10.7 KB

File metadata and controls

523 lines (438 loc) · 10.7 KB

Setting Up the Foundation: Kubernetes Manifests

Creating the Deployment Manifests

helm repo add ingress-nginx \
  https://kubernetes.github.io/ingress-nginx
# Create a folder for the Kubernetes deployment files
mkdir -p $HOME/RestQR/deploy/kubernetes

# Create a values file for the Ingress controller
cat <<EOF >$HOME/RestQR/deploy/kubernetes/ingress-values.yaml
controller:
  service:
    type: LoadBalancer
EOF
helm upgrade \
  --install \
  ingress-nginx \
  ingress-nginx/ingress-nginx \
  --values $HOME/RestQR/deploy/kubernetes/ingress-values.yaml
# 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
cat <<EOF >$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
cat <<EOF >$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
# Run this only if you don't have the config.json file
mkdir -p $HOME/.docker && cat <<EOF >$HOME/.docker/config.json
{
  "auths": {
    "registry.gitlab.com": {
      "auth": "$(echo -n "$GITLAB_USERNAME:$GITLAB_API_TOKEN" | base64 -w 0)"
    }
  }
}
EOF
cat <<EOF >$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
cat <<EOF >$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
cat <<EOF >$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
cat <<EOF >$HOME/RestQR/deploy/kubernetes/qr-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: qr-config
  namespace: default
data:
  MENU_BASE_URL: "http://menu.$INGRESS_IP.sslip.io/menu/"
EOF
cat <<EOF >$HOME/RestQR/deploy/kubernetes/qr-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: qr
  namespace: default
  labels:
    app: qr
spec:
  selector:
    app: qr
  ports:
    - protocol: TCP
      port: 5001
      targetPort: 5001
EOF
# Deploy the GitLab Registry secret
kubectl apply -f \
  $HOME/RestQR/deploy/kubernetes/gitlab-registry-secret.yaml

# Deploy the menu service
kubectl apply -f \
  $HOME/RestQR/deploy/kubernetes/menu-secret.yaml
kubectl apply -f \
  $HOME/RestQR/deploy/kubernetes/menu-service.yaml
kubectl apply -f \
  $HOME/RestQR/deploy/kubernetes/menu-deployment.yaml

# Deploy the qr service
kubectl apply -f \
  $HOME/RestQR/deploy/kubernetes/qr-config.yaml
kubectl apply -f \
  $HOME/RestQR/deploy/kubernetes/qr-deployment.yaml
kubectl apply -f \
  $HOME/RestQR/deploy/kubernetes/qr-service.yaml
# Add the Bitnami repository
helm repo add bitnami \
  https://charts.bitnami.com/bitnami
cat <<EOF >$HOME/RestQR/deploy/kubernetes/postgresql-values.yaml
global:
  imagePullSecrets:
    - name: gitlab-registry-secret
  security:
    allowInsecureImages: true

auth:
  existingSecret: menu-postgres-secret
  # Custom PostgreSQL user for the menu service
  username: menu-user  
  # Database name for the menu service
  database: menu-database
  secretKeys:
    # Key for the PostgreSQL admin password
    adminPasswordKey: postgres-password
    # Key for the PostgreSQL custom user password
    userPasswordKey: menu-password    

primary:
  persistence:
    enabled: true
    size: 8Gi 
  extendedConfiguration: |
    listen_addresses = '*'
    max_connections = 200    

image:
  registry: $GITLAB_REGISTRY_URL
  repository: menu-postgresql
  tag: v0.1.0

service:
  type: ClusterIP
  ports:
    postgresql: 5432

architecture: "standalone"    
EOF
# Create a secret for the PostgreSQL instance
cat <<EOF >$HOME/RestQR/deploy/kubernetes/postgresql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: menu-postgres-secret
type: Opaque
data:
  postgres-password: $(echo -n "postgres-password" | base64 -w 0)
  menu-password: $(echo -n "menu-password" | base64 -w 0)  
EOF

# Apply the secret
kubectl apply \
  -f $HOME/RestQR/deploy/kubernetes/postgresql-secret.yaml
helm upgrade --install \
  menu \
  bitnami/postgresql \
  -f $HOME/RestQR/deploy/kubernetes/postgresql-values.yaml
cat <<EOF >$HOME/RestQR/deploy/kubernetes/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: restqr-ingress
  annotations:
    # Ensures that all requests are rewritten to the root path
    nginx.ingress.kubernetes.io/rewrite-target: /  
spec:
  # Specifies that the Ingress will be managed by the NGINX Ingress Controller
  ingressClassName: nginx  
  # List of rules
  rules:
  # Defines the hostname for the menu service
  - host: menu.$INGRESS_IP.sslip.io  
    http:
      paths:
      # Matches all requests under this path
      - path: /  
        # Ensures all subpaths are included
        pathType: Prefix  
        backend:
          service:
            # Redirects traffic to the menu service
            name: menu  
            port:
              # Specifies the port the menu service is listening on
              number: 5000  
  # Defines the hostname for the QR service
  - host: qr.$INGRESS_IP.sslip.io  
    http:
      paths:
      - path: / 
        pathType: Prefix
        backend:
          service:
            # Redirects traffic to the QR service
            name: qr
            port:
              # Specifies the port the QR service is listening on
              number: 5001  
EOF
kubectl apply \
  -f $HOME/RestQR/deploy/kubernetes/ingress.yaml
kubectl rollout restart deployment menu
kubectl rollout restart deployment qr
# Restaurant ID 1 (Italian Restaurant)
curl -X POST -H "Content-Type: application/json" -d '{
    "menu": [
        {
            "name": "Pizza Carbonara",
            "price": 10
        },
        {
            "name": "Pasta Bolognese",
            "price": 8
        },
        {
            "name": "Tiramisu",
            "price": 5
        }
    ]
}' http://menu.$INGRESS_IP.sslip.io/menu/1

# Restaurant ID 2 (Japanese Restaurant)
curl -X POST -H "Content-Type: application/json" -d '{
    "menu": [
        {
            "name": "Sushi",
            "price": 15
        },
        {
            "name": "Sashimi",
            "price": 12
        },
        {
            "name": "Miso Soup",
            "price": 3
        }
    ]
}' http://menu.$INGRESS_IP.sslip.io/menu/2

# QR code for the Italian Restaurant
curl http://qr.$INGRESS_IP.sslip.io/qr/1 \
  -o /tmp/qr-italian.png

# QR code for the Japanese Restaurant
curl http://qr.$INGRESS_IP.sslip.io/qr/2 \
  -o /tmp/qr-japanese.png
# Start a local server to view the QR codes in the background
python3 -m http.server \
  8000 --directory /tmp \
  > /dev/null 2>&1 &
echo "http://$(curl -s ifconfig.me):8000/qr-italian.png"
echo "http://$(curl -s ifconfig.me):8000/qr-japanese.png"
echo "http://menu.$INGRESS_IP.sslip.io/menu/1"
echo "http://menu.$INGRESS_IP.sslip.io/menu/2"

Ignoring Sensitive Data from SCM

cat <<EOF >>$HOME/RestQR/.gitignore
# Ignore the menu secret file
menu-secret.yaml
EOF
cat <<EOF >>$HOME/RestQR/.gitignore
# Ignore the PostgreSQL secret file
postgresql-secret.yaml
EOF
cd $HOME/RestQR
git add .
git commit -m "Kubernetes YAML, Helm values, and ignored sensitive files"
git push origin main

Rewriting the Git History to Remove Sensitive Data

cd $HOME/RestQR

# Install git-filter-repo on your machine
# Deactivate the virtual environment if you are using one
deactivate
# Launch the installation
pip install \
  git-filter-repo \
  --break-system-packages

# To complete remove the file from the repository history, 
# you need to run the following command:
git-filter-repo \
  --invert-paths \
  --path deploy/kubernetes/menu-secret.yaml \
  --force

# The above command removes the origin, re-add it using the following command:
git remote add origin \
  git@$GITLAB_INSTANCE:$GITLAB_GROUP/$GITLAB_PROJECT

# Push the changes to the repository
git push origin --force --all
git push origin --force --tags