Creating an Ingress in Kubernetes

Creating an Ingress in Kubernetes

Spring Application Deployed with Kubernetes

Step by step building an application using Spring Boot and deployed via Docker on Kubernetes with Helm

full course
  1. Setup: IDE and New Project
  2. Create the Data Repository
  3. Building a Service Layer
  4. Create a REST Controller
  5. Logging, Tracing and Error Handling
  6. Documentation and Code Coverage
  7. Database as a Service
  8. Containerize the Service With Docker
  9. Docker Registry
  10. Automated Build Pipeline
  11. Helm for Deployment
  12. Setting up a Kubernetes Cluster
  13. Automating Deployment (for CICD)
  14. System Design
  15. Messaging and Event Driven Design
  16. Web UI with React
  17. Containerizing our UI
  18. UI Build Pipeline
  19. Put the UI in to Helm
  20. Creating an Ingress in Kubernetes
  21. Simplify Deployment
  22. Conclusion and Review

We’ve got multiple service available for deployment now. Lets allow them to communicate internally and externally with the cluster. We’ll do that by creating an ingress.

Current State of Our Application

We’re using our services as nodeports which allows us to expose an external port that will map to the internal port used by the the application. From our helm configuration our services start up on their default port (spring=8080, nginx=80) but that gets mapped to port 80 internally. So if we were inside our cluster we could talk to customer manager directly by calling its service on port 80. When we’re external we have to use port 30002.

This works okay when we’re running externally on our development machine, but is terrible for production. For one, keeping track of the cluster IP and making sure that each service is calling the correct port can be a maintenance nightmare.

Using an Ingress

We’re going to install another component called an ingress which acts like an api gateway. This allows us to only talk to a single IP and port combination to access all components within our application. We can still access services directly via their external port (for testing, etc…) but the most important part is that our front-end application won’t need to know anything about where our services live and how to access them. The ingress takes care of that.

Creating an Ingress

Create a new git repository called medium-ingress. Clone that locally and in that repo create a directory called helm. In here use helm create medium-ingress to initialize the chart. We’re going to strip out all of the files since we really only need 3.

templates/ingress.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: medium-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: medium-example.com
      http:
        paths:
        - path: /
          backend:
            serviceName: medium-customer-manager-service
            servicePort: 80
        - path: /customer
          backend:
            serviceName: customer-medium-customer
            servicePort: 80

Chart.yaml

apiVersion: v1
name: medium-ingress
description: The ingress into the medium application

type: application
version: 0.1.0
appVersion: 1.16.0

values.yaml can be left empty

The important part is the ingress deployment descriptor. In here we’re creating the mapping of the request path to the internal kubernetes service name and port. I just realized that my names are not very clean and I should fix that but this will get us going.

Minikube Setup

We need to do some things first before we can deploy. Ingress is a definition, but it is actually implemented within the kubernetes cluster and there are lots of implementations to choose from. We’re going to use the basic ingress for minikube, but we need to install it first.

minikube addons enable ingress

verify the pod is running

kubectl get pods -n ingress-nginx

We also want to update our hosts file to add a mapping for medium-example.com to our minikube ip (which can be retrieved via minikube ip). This is partly for ease of use for us, but also important because the ingress controller uses the domain for mapping.

...
172.18.51.82 medium-example.com
# End of section

Update Frontend

We have one more minor change to make to our react frontend. Change helm/medium-customer-manager/values.yaml to stop calling the customer service via external port

config:
## Currently only supports file
type: file
## Contents of config in YAML
content: |-
    window.REACT_APP_CUSTOMER_HOST=''

Go ahead and commit this to kick off a build

git checkout -b ingress
git add .
git commit -m "updates for ingress"
git push
git checkout master
git merge ingress
git push

Deploy Ingress

use helm to install

helm install ingress helm/medium-ingress

and load up your page at http://medium-example.com/.

You can verify that its all working together in the logs as well if you review the application and ingress pod log instances.

Publish the Chart

We want to version this ingress and publish it as a chart because we’ll eventually pull all of these services under an umbrella chart in the future. First we need to create a pipeline.

In codefresh make a new build pipeline for this project called medium-ingress under the medium project. Make sure to add the helm repository under the environment variables setup. Then use this workflow for the pipeline:

version: "1.0"
stages:
  - "clone"
  - "helmpublish"
steps:
  Clone:
        title: "Cloning repository"
        type: "git-clone"
        repo: "https://github.com/brianrook/medium-ingress"
        revision: "master"
        stage: "clone"
  HelmChartGetVersion:
    title: Get Helm Chart Version
    stage: helmpublish
    image: codefresh/cfstep-helm
    working_directory: '/codefresh/volume/medium-ingress'
    environment:
      - CHART_PATH=helm/medium-ingress
      - CHART_NAME=medium-ingress
    commands:
      - export ACTION=auth
      - source /opt/bin/release_chart
      - helm repo add default ${{CF_CTX_CF_HELM_DEFAULT_URL}}
      - yq .version ${CHART_PATH}/Chart.yaml
      - export CURRENT_CHART_VERSION=`helm search default/${CHART_NAME} | awk 'FNR==2{print $2}' || yq .version ${CHART_PATH}/Chart.yaml`
      - echo $CURRENT_CHART_VERSION
      - cf_export NEW_CHART_VERSION=`echo "${CURRENT_CHART_VERSION}" | awk -F. '{$NF = $NF + 1;} 1' | sed 's/ /./g'`
      - echo $NEW_CHART_VERSION
  HelmChartUpdate:
    title: Update Helm Chart Version
    stage: helmpublish
    image: gksoftware/yq
    working_directory: '/codefresh/volume/medium-ingress'
    environment:
      - CHART_PATH=helm/medium-ingress
      - YAML_PATH=image.tag
    commands: 
      - echo $NEW_CHART_VERSION
      - yq w -i ${CHART_PATH}/Chart.yaml version ${NEW_CHART_VERSION}
      - echo $CF_SHORT_REVISION
      - yq w -i ${CHART_PATH}/values.yaml ${YAML_PATH} ${{CF_SHORT_REVISION}}
  HelmChartPush:
      title: Push Helm Chart to Chart Repository
      stage: helmpublish
      image: codefresh/cfstep-helm
      working_directory: '/codefresh/volume/medium-ingress'
      environment:
        - CHART_REF=helm/medium-ingress/
        - ACTION=push

Finally, make sure that this pipeline is triggered off push to master. Lets commit our changes and start a build

git checkout -b helm
git add .
git commit -m "ingress helm chart"
git push
git checkout master
git merge helm
git push

once that builds lets deploy all of our components

helm repo update
helm install customer codefresh/medium-customer
helm install cust-mgr codefresh/medium-customer-manager
helm install ingress codefresh/medium-ingress

And verify that everything works together.

0 comments on “Creating an Ingress in KubernetesAdd yours →

Leave a Reply

Your email address will not be published. Required fields are marked *