Understanding ConfigMaps and Ingress in Kubernetes: A Beginner's Guide

sheak imransheak imran
6 min read

Hey folks! Today I want to share what I've learned about two super useful Kubernetes resources: ConfigMaps and Ingress. When I first started with Kubernetes, these concepts seemed a bit confusing, but they're actually pretty straightforward once you get the hang of them.

ConfigMaps: Keeping Your Configuration Separate

What is a ConfigMap?

A ConfigMap is simply a way to store configuration data separately from your application code. Think of it as a set of key-value pairs that your applications can use.

Why is this useful? Well, it follows a best practice called "configuration externalization" - basically keeping your config outside your code. This way:

  • You can change configuration without rebuilding your application

  • You can use the same application code with different configurations

  • You keep sensitive information out of your codebase

How ConfigMaps Work

ConfigMaps store data as key-value pairs, and your pods can access this data in several ways:

  1. As environment variables

  2. As command-line arguments

  3. As configuration files in a volume

Let's look at a simple example.

Example: Creating and Using a ConfigMap

First, let's create a ConfigMap:

yamlapiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DATABASE_URL: "mongodb://db-service:27017"
  MESSAGE: "Hello from ConfigMap!"
  app.properties: |
    color.background=blue
    color.foreground=white
    server.port=8080

In this example:

  • We've named our ConfigMap "app-config"

  • We've added some key-value pairs

  • We've even included a multi-line property file format

Now, let's see how to use this ConfigMap in a Pod:

yamlapiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app-container
    image: my-app:1.0
    env:
    - name: DB_URL
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: DATABASE_URL
    - name: GREETING
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: MESSAGE
    volumeMounts:
    - name: config-volume
      mountPath: /config
  volumes:
  - name: config-volume
    configMap:
      name: app-config

In this pod definition:

  1. We're creating environment variables (DB_URL and GREETING) using values from our ConfigMap

  2. We're also mounting the entire ConfigMap as a volume at /config so the application can read the properties file

When to Use ConfigMaps

Use ConfigMaps for:

  • Application configuration

  • Feature flags

  • Resource limits

  • Connection strings (non-sensitive)

  • Any configuration that might change between environments

Remember: Don't store sensitive data like passwords or API keys in ConfigMaps! Use Secrets instead for those.

Ingress: Managing External Access to Your Services

What is Ingress?

Ingress is how we manage external access to services in our Kubernetes cluster. Think of it as a smart router or a traffic controller at the edge of your cluster.

Without Ingress, we would need to create a separate LoadBalancer service for each application we want to expose. That gets expensive and hard to manage quickly!

How Ingress Works

For Ingress to work, you need two components:

  1. Ingress Resource: This is a Kubernetes object that defines the routing rules

  2. Ingress Controller: This is the actual implementation that makes the rules work (like NGINX, Traefik, or others)

The Ingress resource defines rules like:

  • Which hostnames should route to which services

  • Which paths should go where

  • Whether to use TLS/SSL

Example: Setting Up an Ingress

First, make sure you have an Ingress controller installed in your cluster. The most common is NGINX Ingress Controller.

Now, let's create an Ingress resource:

yamlapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80
  - host: blog.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: blog-service
            port:
              number: 80

This Ingress configuration does the following:

Adding TLS/SSL

Let's enhance our Ingress to use SSL:

yamlapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-secure-ingress
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls-secret
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

This requires creating a Secret with your SSL certificate:

yamlapiVersion: v1
kind: Secret
metadata:
  name: myapp-tls-secret
type: kubernetes.io/tls
data:
  tls.crt: base64_encoded_cert
  tls.key: base64_encoded_key

How It All Works Together

Here's a visual representation of how Ingress works:

                                      ┌────────────────┐
                                                      
                                  ┌───▶ frontend-service 
                                                     
                                     └────────────────┘
Internet    Ingress Controller  →┤   
                                     ┌────────────────┐
                                                     
                                  └───▶  api-service    
                                                      
                                      └────────────────┘

When to Use Ingress

Use Ingress when you need to:

  • Expose multiple services under the same IP address

  • Implement host or URL-based routing

  • Terminate SSL/TLS

  • Implement rewrite rules, rate limiting, or authentication

Putting It All Together: A Real-World Example

Let's see how ConfigMaps and Ingress work together in a simple web application:

  1. First, create a ConfigMap for your application settings:
yamlapiVersion: v1
kind: ConfigMap
metadata:
  name: web-config
data:
  DB_HOST: "postgres-service"
  DB_PORT: "5432"
  FEATURE_NEW_UI: "true"
  API_TIMEOUT: "30"
  1. Create your deployment using this ConfigMap:
yamlapiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-container
        image: mywebapp:1.2
        envFrom:
        - configMapRef:
            name: web-config
        ports:
        - containerPort: 8080
  1. Create a service to expose your deployment:
yamlapiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 8080
  type: ClusterIP
  1. Create an Ingress to expose your service to the internet:
yamlapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - mywebapp.example.com
    secretName: webapp-tls
  rules:
  - host: mywebapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

Now your application:

  • Gets its configuration from the ConfigMap

  • Is accessible from the internet via the domain mywebapp.example.com

  • Automatically redirects HTTP to HTTPS

Visualizing the Architecture

Here's what our complete setup looks like:

                                              ┌─────────────┐
                                                           
Internet  Ingress Controller  web-service   web-app Pod   ConfigMap
                                                           
                                              └─────────────┘

Best Practices

For ConfigMaps:

  • Keep configuration data separate from application code

  • Use clear, descriptive names for ConfigMap keys

  • Consider using a separate ConfigMap for each application or component

  • Don't store sensitive data in ConfigMaps

For Ingress:

  • Use annotations to customize behavior

  • Implement TLS for all production applications

  • Use path-based routing to organize your API endpoints

  • Consider using namespaces to separate different environments

Conclusion

ConfigMaps and Ingress are two powerful tools in the Kubernetes ecosystem that solve very different problems:

  • ConfigMaps help you separate configuration from code, making your applications more portable and easier to manage.

  • Ingress gives you a flexible way to route external traffic to your services, saving costs and providing advanced routing capabilities.

By mastering these two resources, you're well on your way to building flexible, maintainable applications on Kubernetes!

Happy containerizing!

0
Subscribe to my newsletter

Read articles from sheak imran directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

sheak imran
sheak imran

System Administrator FM Associates BD | Network Specialist | RHCE, RHCSA, RHCVA certified.