• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Deploying and Exposing Go Apps with Kubernetes Ingress, Part 2

Lomanu4 Оффлайн

Lomanu4

Команда форума
Администратор
Регистрация
1 Мар 2015
Сообщения
1,481
Баллы
155
In Part 1, we used Kubernetes Ingress to route traffic to two Go-based microservices based on specific paths. In this second part, we’ll explore advanced Ingress features.

Project Overview


In this part, we’ll build and deploy two updated Go-based services (API and Web) in the ~/k8s-learning/ingress/ingress-different-route directory. Unlike Part 1, where services handled specific paths (/api and /web), here both services respond to the root path (/). We’ll use Kubernetes Ingress with a rewrite rule to route /api to the API service and / to the Web service, ensuring clean URL handling.

Project Structure


We will build two services using Go:

  • An API service that responds to HTTP GET requests at the root path (/) with a JSON response.
  • A Web service that responds to HTTP GET requests at the root path (/) with an HTML response.

Then, we’ll containerize these services with Docker, set up a Kubernetes cluster using Kind, deploy the services, and configure Ingress with path rewriting to route traffic appropriately.

Tree Structure


Here’s the directory structure of the project:


k8s-learning/
└── ingress/
└── ingress-different-route/
├── api-service/
│ ├── Dockerfile
│ └── main.go
├── web-service/
│ ├── Dockerfile
│ └── main.go
└── k8s/
├── api-deployment.yaml
├── api-service.yaml
├── web-deployment.yaml
├── web-service.yaml
├── go-app-ingress.yaml
└── kind-cluster-config-with-ingress.yaml
API Service

To Initialize the Go Module for This Service, Run:


cd ~/k8s-learning/ingress/ingress-different-route/api-service
go mod init ingress-api-service-different

This command sets up the go module.

Developing the API with Go


The API service is a Go application that responds to HTTP GET requests at the root path (/) with a JSON response.


package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
)

func main() {
router := http.NewServeMux()
router.HandleFunc("GET /", apiHandler)
fmt.Println("API Service started at :8080")
log.Fatal(http.ListenAndServe(":8080", router))
}

func apiHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
w.WriteHeader(http.StatusNotFound)
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{
"message": "API Service",
})
}

Changes from Part 1:

  • The API now uses http.NewServeMux for routing, explicitly handling GET / instead of /api.
  • It returns a JSON response ({"message": "API Service"}) instead of HTML.
Dockerizing the API Service


The Dockerfile remains similar to Part 1 but uses the updated image name.


# Use the official Golang image to build the app
FROM golang:1.24-alpine as builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy the Go Modules files and download dependencies
COPY go.mod ./
RUN go mod tidy

# Copy the rest of the source code into the container
COPY . .

# Build the Go app
RUN go build -o api-service .

# Start a new stage from the official Alpine image
FROM alpine:latest

# Install necessary dependencies
RUN apk --no-cache add ca-certificates

# Set the Current Working Directory inside the container
WORKDIR /root/

# Copy the pre-built binary file from the builder stage
COPY --from=builder /app/api-service .

# Expose port 8080 for the API service
EXPOSE 8080

# Command to run the executable
CMD ["./api-service"]

Build and push the image:


cd ~/k8s-learning/ingress/ingress-different-route/api-service
docker build -t olymahmudmugdho/ingress-api-service-different:latest .
docker push olymahmudmugdho/ingress-api-service-different:latest
Web Service

To Initialize the Go Module for This Service, Run:


cd ~/k8s-learning/ingress/ingress-different-route/web-service
go mod init ingress-web-service-different

I am using Go 1.24.2.

Developing the Web Service with Go


The Web service responds to HTTP GET requests at the root path (/) with an HTML response.


package main

import (
"fmt"
"net/http"
)

func webHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
w.WriteHeader(http.StatusNotFound)
return
}
fmt.Fprintf(w, "<h1>Web Service</h1>")
}

func main() {
router := http.NewServeMux()
router.HandleFunc("GET /", webHandler)
fmt.Println("Web Service started at :8080")
http.ListenAndServe(":8080", router)
}

Changes from Part 1:

  • The Web service now handles GET / instead of /web, using http.NewServeMux.
  • The response remains HTML (<h1>Web Service</h1>).
Dockerizing the Web Service


The Dockerfile is identical to Part 1’s structure but uses the updated image name.


# Use the official Golang image to build the app
FROM golang:1.24-alpine as builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy the Go Modules files and download dependencies
COPY go.mod ./
RUN go mod tidy

# Copy the rest of the source code into the container
COPY . .

# Build the Go app
RUN go build -o web-service .

# Start a new stage from the official Alpine image
FROM alpine:latest

# Install necessary dependencies
RUN apk --no-cache add ca-certificates

# Set the Current Working Directory inside the container
WORKDIR /root/

# Copy the pre-built binary file from the builder stage
COPY --from=builder /app/web-service .

# Expose port 8080 for the Web service
EXPOSE 8080

# Command to run the executable
CMD ["./web-service"]

Build and push:


cd ~/k8s-learning/ingress/ingress-different-route/web-service
docker build -t olymahmudmugdho/ingress-web-service-different:latest .
docker push olymahmudmugdho/ingress-web-service-different:latest
Setting Up Kubernetes with KIND


The Kind cluster configuration remains identical to Part 1.


kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: kind-ingress

nodes:
- role: control-plane
image: kindest/node:v1.31.2
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP

- role: worker
image: kindest/node:v1.31.2

- role: worker
image: kindest/node:v1.31.2

Create the cluster:


kind create cluster --config k8s/kind-cluster-config-with-ingress.yaml

Verify:


kubectl get nodes
Installing the Ingress Controller


Deploy the NGINX Ingress controller, as in Part 1:


kubectl apply -f

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Check status:


kubectl get pods -n ingress-nginx
API Deployment Configuration


The API Deployment is similar to Part 1 but uses the new image.


apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: olymahmudmugdho/ingress-api-service-different:latest
ports:
- containerPort: 8080

Explanation: Creates a Deployment for the API service, ensuring one replica runs with the new Docker image, exposing port 8080.

Apply:


kubectl apply -f k8s/api-deployment.yaml
API Service Definition


The API Service is unchanged from Part 1.


apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP

Explanation: Exposes the API pods internally via a ClusterIP Service, mapping external port 80 to the container’s port 8080.

Apply:


kubectl apply -f k8s/api-service.yaml
Web Deployment Configuration


The Web Deployment is similar to Part 1 but uses the new image.


apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: olymahmudmugdho/ingress-web-service-different:latest
ports:
- containerPort: 8080

Explanation: Creates a Deployment for the Web service, ensuring one replica runs with the new Docker image.

Web Service Definition


The Web Service is unchanged from Part 1.


apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP

Explanation: Exposes the Web service internally.

Creating Ingress Resource (go-app-ingress.yaml)


The Ingress resource introduces a rewrite rule to handle the new routing logic.


apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: localhost
http:
paths:
- pathType: Prefix
path: /api
backend:
service:
name: api-service
port:
number: 80
- pathType: Prefix
path: /
backend:
service:
name: web-service
port:
number: 80

Detailed Explanation:

  • Metadata: The name: example-ingress identifies the Ingress resource. Consider renaming to go-app-ingress for consistency with Part 1.
  • Annotations: The nginx.ingress.kubernetes.io/rewrite-target: / rewrites incoming paths to / before forwarding to the backend services. This is critical since both services expect requests at /, but external requests use /api or /.
  • Spec.Rules: Defines routing rules for host: localhost.
  • Host: Set to localhost, suitable for local testing with Kind. In production, this would be a domain (e.g., example.com).
  • HTTP.Paths:
    • /api: Matches URLs starting with /api. The rewrite rule strips /api, forwarding the request as / to api-service on port 80.
    • /: Matches all other URLs (root path). The request is forwarded as / to web-service on port 80.
  • Backend: Specifies the target Service (api-service or web-service) and port (80).
  • pathType: Prefix: Ensures paths like /api/health match /api, but the rewrite rule normalizes them to /.

Changes from Part 1:

  • The Web service is now routed at / instead of /web.
  • The rewrite-target annotation handles path rewriting, allowing both services to operate at / internally.
  • This setup simplifies external URLs (e.g., localhost/ instead of localhost/web).

Apply:


kubectl apply -f k8s/go-app-ingress.yaml
Verifying Ingress Functionality


Ensure all components are running:


kubectl get deployments
kubectl get services
kubectl get ingress
kubectl describe ingress example-ingress
kubectl get pods -n ingress-nginx
Testing with cURL


Test the routing:


curl

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


# Expected output: {"message": "API Service"}

curl

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


# Expected output: "<h1>Web Service</h1>"

curl

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


# Expected output: 404 Not Found

If you face any problem, troubleshoot:

  • Check Ingress controller logs: kubectl logs -n ingress-nginx <pod-name>.
  • Ensure localhost resolves correctly in /etc/hosts or network settings.
  • Verify the rewrite rule is applied (kubectl describe ingress example-ingress).

Thanks for reading


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу