Gateway API
Делаю:
2026.02.06
https://www.youtube.com/watch?v=q76XVCTDZCY
https://github.com/marcel-dempers/docker-development-youtube-series/tree/master/kubernetes/gateway-api
We need a Kubernetes cluster
$ kind create cluster --name gatewayapi --image kindest/node:v1.35.0
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gatewayapi-control-plane NotReady control-plane 11s v1.35.0
Gateway API CRDs
$ kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental-install.yaml
This will install (Stable Channel):
- Gateway Classes:
kubectl get gatewayclass - Gateways:
kubectl get gateway - HTTP Routes:
kubectl get httproute
These APIs are part of the Experimental Channel:
- TLS Routes:
kubectl get tlsroute - TCP Routes:
kubectl get tcproute - UDP Routes:
kubectl get udproute
Note: Gateway API is very new, and all of the above is subject to change quite rapidly </br>
Setup some example applications
1) Приложение на python
2) Приложение на go
3) Фронт приложение которое умеет делать запросы к go приложени.
The following will deploy a deployment, service and require configMap and secret for the applications to work.
$ cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: python-deploy
labels:
app: python-app
spec:
selector:
matchLabels:
app: python-app
replicas: 2
template:
metadata:
labels:
app: python-app
spec:
containers:
- name: python-app
image: aimvector/python:1.0.0
imagePullPolicy: Always
ports:
- containerPort: 5000
---
kind: Service
apiVersion: v1
metadata:
name: python-svc
spec:
selector:
app: python-app
ports:
- protocol: TCP
port: 5000
targetPort: 5000
type: ClusterIP
EOF
$ cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-deploy
labels:
app: go-app
spec:
selector:
matchLabels:
app: go-app
replicas: 2
template:
metadata:
labels:
app: go-app
spec:
containers:
- name: go-app
image: aimvector/golang:1.0.0
imagePullPolicy: Always
ports:
- containerPort: 5000
volumeMounts:
- name: secret-volume
mountPath: /secrets/
- name: config-volume
mountPath: /configs/
volumes:
- name: secret-volume
secret:
secretName: go-secret
- name: config-volume
configMap:
name: go-config
---
apiVersion: v1
kind: Secret
metadata:
name: go-secret
type: Opaque
data:
secret.json: ewogICAgImFwaV9rZXkiIDogInNvbWVzZWNyZXRnb2VzaGVyZSIKfQo=
---
apiVersion: v1
kind: ConfigMap
metadata:
name: go-config
data:
config.json: |
{
"environment" : "dev"
}
---
kind: Service
apiVersion: v1
metadata:
name: go-svc
spec:
selector:
app: go-app
ports:
- protocol: TCP
port: 5000
targetPort: 5000
type: ClusterIP
EOF
$ cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: web-app
labels:
app: web-app
data:
# The index.html file that NGINX will serve
index.html: |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CORS Demo Client</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; background-color: #f0f4f8; }
.container { background: white; padding: 30px; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); max-width: 600px; margin: auto; }
h1 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
button { background-color: #3498db; color: white; padding: 10px 15px; border: none; border-radius: 6px; cursor: pointer; margin-top: 15px; font-weight: bold; transition: background-color 0.3s; }
button:hover { background-color: #2980b9; }
pre { background-color: #ecf0f1; padding: 15px; border-radius: 6px; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word; }
.status-ok { color: green; font-weight: bold; }
.status-error { color: red; font-weight: bold; }
</style>
</head>
<body>
<div class="container">
<h1>Client-Side CORS Demonstration</h1>
<button onclick="fetchData()">Make CORS Request</button>
<h2>Result:</h2>
<p>Status: <span id="status">Waiting...</span></p>
<pre id="output"></pre>
</div>
<script>
async function fetchData() {
const apiEndpoint = 'http://example-app.com/api/go';
const statusElement = document.getElementById('status');
const outputElement = document.getElementById('output');
statusElement.textContent = 'Fetching...';
outputElement.textContent = 'Request sent to ' + apiEndpoint;
try {
// This public API allows CORS, so the fetch should succeed.
const response = await fetch(apiEndpoint);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.text();
statusElement.innerHTML = '<span class="status-ok">SUCCESS (CORS Allowed)</span>';
outputElement.textContent = data;
} catch (error) {
// If the API did NOT allow CORS, this catch block would activate,
// often showing a generic "Failed to fetch" error in the console.
statusElement.innerHTML = '<span class="status-error">FAILURE (Check Browser Console for CORS Error)</span>';
outputElement.textContent = 'Error during fetch: ' + error.message;
console.error("CORS Request Error:", error);
}
}
</script>
</body>
</html>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web-app
spec:
replicas: 1
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: nginx-web
image: nginx:stable-alpine
ports:
- containerPort: 80
volumeMounts:
- name: html-volume
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
volumes:
- name: html-volume
configMap:
name: web-app
defaultMode: 0644
---
apiVersion: v1
kind: Service
metadata:
name: web-app
labels:
app: web-app
spec:
type: ClusterIP
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
name: http
EOF
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
go-deploy-5449f5df89-2mhss 1/1 Running 0 35s
go-deploy-5449f5df89-jswnq 1/1 Running 0 35s
python-deploy-5fc58df78c-px8jx 1/1 Running 0 40s
python-deploy-5fc58df78c-qlmvs 1/1 Running 0 40s
web-app-679f5b5857-qw8r9 1/1 Running 0 26s
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
go-svc ClusterIP 10.96.167.54 <none> 5000/TCP 58s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8m3s
python-svc ClusterIP 10.96.218.1 <none> 5000/TCP 63s
web-app ClusterIP 10.96.236.255 <none> 80/TCP 49s
Create test Domains
We also need to imagine we have a domain called example-app.com , so let’s set that up on our hosts file
$ echo "127.0.0.1 example-app.com" | sudo tee -a /etc/hosts
$ echo "127.0.0.1 example-app-go.com" | sudo tee -a /etc/hosts
$ echo "127.0.0.1 example-app-python.com" | sudo tee -a /etc/hosts