Не удается получить ответ от Express API в k8s-Skaffold от Postman
Попытаться сделать что-то, что должно быть довольно простым: запустить модуль Express и получить localhost:5000/
который должен ответить Hello World!
.
- Я установил
ingress-nginx
для Docker для Mac и minikube- Обязательно:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
- Докер для Mac:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml
- minikube:
minikube addons enable ingress
- Обязательно:
- я бегу
skaffold dev --tail
- Он распечатывает
Example app listening on port 5000
, так что очевидно работает - Перейдите к
localhost
а такжеlocalhost:5000
и получите сообщение об ошибке "Не удалось получить ответ" - Также попробовал
minikube ip
который192.168.99.100
и испытать те же результаты
Не совсем уверен, что я здесь делаю не так. Код и конфиги ниже. Предложения?
index.js
// Import dependencies
const express = require('express');
// Set the ExpressJS application
const app = express();
// Set the listening port
// Web front-end is running on port 3000
const port = 5000;
// Set root route
app.get('/', (req, res) => res.send('Hello World!'));
// Listen on the port
app.listen(port, () => console.log(`Example app listening on port ${port}`));
skaffold.yaml
apiVersion: skaffold/v1beta15
kind: Config
build:
local:
push: false
artifacts:
- image: sockpuppet/server
context: server
docker:
dockerfile: Dockerfile.dev
sync:
manual:
- src: '**/*.js'
dest: .
deploy:
kubectl:
manifests:
- k8s/ingress-service.yaml
- k8s/server-deployment.yaml
- k8s/server-cluster-ip-service.yaml
ingress-service.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /?(.*)
backend:
serviceName: server-cluster-ip-service
servicePort: 5000
server-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: server-deployment
spec:
replicas: 3
selector:
matchLabels:
component: server
template:
metadata:
labels:
component: server
spec:
containers:
- name: server
image: sockpuppet/server
ports:
- containerPort: 5000
сервер-кластер-ip-service.yaml
apiVersion: v1
kind: Service
metadata:
name: server-cluster-ip-service
spec:
type: ClusterIP
selector:
component: server
ports:
- port: 5000
targetPort: 5000
Dockerfile.dev
FROM node:12.10-alpine
EXPOSE 5000
WORKDIR "/app"
COPY ./package.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]
Выход из describe
$ kubectl describe ingress ingress-service
Name: ingress-service
Namespace: default
Address:
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
localhost
/ server-cluster-ip-service:5000 (172.17.0.7:5000,172.17.0.8:5000,172.17.0.9:5000)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-service","namespace":"default"},"spec":{"rules":[{"host":"localhost","http":{"paths":[{"backend":{"serviceName":"server-cluster-ip-service","servicePort":5000},"path":"/"}]}}]}}
kubernetes.io/ingress.class: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 16h nginx-ingress-controller Ingress default/ingress-service
Normal CREATE 21s nginx-ingress-controller Ingress default/ingress-service
Выход из kubectl get po -l component=server
$ kubectl get po -l component=server
NAME READY STATUS RESTARTS AGE
server-deployment-cf6dd5744-2rnh9 1/1 Running 0 11s
server-deployment-cf6dd5744-j9qvn 1/1 Running 0 11s
server-deployment-cf6dd5744-nz4nj 1/1 Running 0 11s
Выход из kubectl describe pods server-deployment
: Заметил, что Host Port: 0/TCP
. Возможно проблема?
Name: server-deployment-6b78885779-zttns
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/10.0.2.15
Start Time: Tue, 08 Oct 2019 19:54:03 -0700
Labels: app.kubernetes.io/managed-by=skaffold-v0.39.0
component=server
pod-template-hash=6b78885779
skaffold.dev/builder=local
skaffold.dev/cleanup=true
skaffold.dev/deployer=kubectl
skaffold.dev/docker-api-version=1.39
skaffold.dev/run-id=c545df44-a37d-4746-822d-392f42817108
skaffold.dev/tag-policy=git-commit
skaffold.dev/tail=true
Annotations: <none>
Status: Running
IP: 172.17.0.5
Controlled By: ReplicaSet/server-deployment-6b78885779
Containers:
server:
Container ID: docker://2d0aba8f5f9c51a81f01acc767e863b7321658f0a3d0839745adb99eb0e3907a
Image: sockpuppet/server:668dfe550d93a0ae76eb07e0bab900f3968a7776f4f177c97f61b18a8b1677a7
Image ID: docker://sha256:668dfe550d93a0ae76eb07e0bab900f3968a7776f4f177c97f61b18a8b1677a7
Port: 5000/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 08 Oct 2019 19:54:05 -0700
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-qz5kr (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-qz5kr:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-qz5kr
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/server-deployment-6b78885779-zttns to minikube
Normal Pulled 7s kubelet, minikube Container image "sockpuppet/server:668dfe550d93a0ae76eb07e0bab900f3968a7776f4f177c97f61b18a8b1677a7" already present on machine
Normal Created 7s kubelet, minikube Created container server
Normal Started 6s kubelet, minikube Started container server
1 ответ
Хорошо, теперь разобрались.
Это сводится к типу используемой службы: ClusterIP
.
ClusterIP: предоставляет службу на внутреннем IP-адресе кластера. Выбор этого значения делает службу доступной только изнутри кластера. Это ServiceType по умолчанию.
Если я хочу подключиться к модулю или развертыванию напрямую извне кластера (что-то вроде Postman, pgAdmin и т. Д.), И я хочу сделать это с помощью службы, я должен использоватьNodePort
:
NodePort: предоставляет службу на каждом IP-адресе узла на статическом порте (NodePort). Служба ClusterIP, к которой будет выполнять маршрутизацию служба NodePort, создается автоматически. Вы сможете связаться со службой NodePort извне кластера, запросив
<NodeIP>
:<NodePort>
.
Итак, в моем случае, если я хочу продолжить использование службы, я бы изменил свой манифест службы на:
apiVersion: v1
kind: Service
metadata:
name: server-cluster-ip-service
spec:
type: NodePort
selector:
component: server
ports:
- port: 5000
targetPort: 5000
nodePort: 31515
Обязательно установите вручную nodePort: <port>
в противном случае это случайность и боль в использовании.
Тогда я получу minikube
IP с minikube ip
и подключитесь к модулю с помощью 192.168.99.100:31515
.
На этом этапе все работало, как ожидалось.
Но это означает наличие отдельных наборов разработки (NodePort
) и производство (ClusterIP
), что, вероятно, совершенно нормально. Но я хочу, чтобы мои манифесты оставались как можно ближе к производственной версии (т.е.ClusterIP
).
Есть несколько способов обойти это:
- Используя что-то вроде Kustomize, где вы можете установить base.yaml, а затем иметь наложения для каждой среды, где он просто изменяет соответствующую информацию, избегая манифестов, которые в основном дублируются.
С помощью
kubectl port-forward
. Я думаю, что это тот путь, по которому я пойду. Таким образом, я могу сохранить свой единственный набор производственных манифестов, но когда я хочу выполнить QA Postgres с помощью pgAdmin, я могу:kubectl port-forward services/postgres-cluster-ip-service 5432:5432
Или для админки и почтальона:
kubectl port-forward services/server-cluster-ip-service 5000:5000
Я играю с этим через ingress-service.yaml
с помощью nginx-ingress
, но пока это не работает. Буду обновлять, когда сделаю. Но для меня,port-forward
Кажется, это правильный путь, поскольку у меня может быть только один набор производственных манифестов, которые мне не нужно изменять.
Skaffold Port-Forwarding
Это даже лучше для моих нужд. Добавляя это в конецskaffold.yaml
и в основном то же самое, что и kubectl port-forward
без привязки терминала или двух:
portForward:
- resourceType: service
resourceName: server-cluster-ip-service
port: 5000
localPort: 5000
- resourceType: service
resourceName: postgres-cluster-ip-service
port: 5432
localPort: 5432
Тогда беги skaffold dev --port-forward
.