Kubernetes - 入口/服务/LB
Kubernetes - Ingress / Service / LB
我是 K8s 的新手,这是我第一次尝试掌握它。我正在尝试使用此 deployment.yml:
设置基本的 Nodejs Express API
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: api
spec:
replicas: 1
template:
metadata:
labels:
app: api
spec:
containers:
- image: registry.gitlab.com/<project>/<app>:<TAG>
imagePullPolicy: Always
name: api
env:
- name: PORT
value: "8080"
ports:
- containerPort: 8080
hostPort: 80
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 1
imagePullSecrets:
- name: registry.gitlab.com
正在通过 gitlab-ci 部署。这是有效的,我已经设置了一个服务来公开它:
apiVersion: v1
kind: Service
metadata:
name: api-svc
labels:
app: api-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: api
type: LoadBalancer
但我一直在研究入口,以便为可能的多项服务提供单一入口点。我一直在阅读 Kubernetes 指南,我阅读了这个 Kubernetes Ingress Example,这是我创建的 ingress.yml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
spec:
backend:
serviceName: api-svc
servicePort: 80
但这没有用,当我访问从入口生成的外部 IP 地址时,我只有 502 个错误页面。
谁能指出我正确的方向,我做错了什么或者我错过了什么?我在上面的示例 link 中看到有一个 nginx-rc.yml ,我完全按照示例中的方式部署了它,并且已创建但仍然没有从端点获得任何信息。 API 可从服务外部 IP 访问。
非常感谢
看起来您正在向端口 80
公开您的服务,但您的容器正在向 8080
公开,因此对服务的任何请求都将失败。
此外,请查看示例入口资源 (https://github.com/nginxinc/kubernetes-ingress/blob/master/examples/complete-example/cafe-ingress.yaml),您还需要定义在入口控制器被命中时路由哪些主机/路径。 (即 example.foo.com --> api-svc)
我又看了一遍,我想我明白了。
为了让 Ingress 在 GCE 上工作,您需要将后端服务定义为 NodePort
而不是 ClusterIP 或 LoadBalancer。
此外,您还需要确保对 /
的 http 健康检查有效(您会看到 Google L7 负载均衡器在 url 上对您的服务产生了相当大的影响)和那么它就可用了。
以为我会 post 我的工作 deployment/service/ingress
因此,经过大量努力使它工作后,这是我用来使它工作的方法:
部署
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: backend-api-v2
spec:
replicas: 2
template:
metadata:
labels:
app: backend-api-v2
spec:
containers:
- image: registry.gitlab.com/<project>/<app>:<TAG>
imagePullPolicy: Always
name: backend-api-v2
env:
- name: PORT
value: "8080"
ports:
- containerPort: 8080
livenessProbe:
httpGet:
# Path to probe; should be cheap, but representative of typical behavior
path: /healthz
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 5
imagePullSecrets:
- name: registry.gitlab.com
服务
apiVersion: v1
kind: Service
metadata:
name: api-svc-v2
labels:
app: api-svc-v2
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 31810
protocol: TCP
name: http
selector:
app: backend-api-v2
入口
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: api.foo.com
http:
paths:
- path: /v1/*
backend:
serviceName: api-svc
servicePort: 80
- path: /v2/*
backend:
serviceName: api-svc-v2
servicePort: 80
正如@Tigraine 指出的那样,需要注意的重要一点是该服务使用的是 type: NodePort
而不是 LoadBalancer
,我还定义了一个 nodePort,但我相信如果您保留它,它会创建一个出去。
它将对任何不符合规则的路由使用 default-http-backend
这是 GKE 在 kube-system
命名空间中运行的默认容器。因此,如果我访问 http://api.foo.com/bob
,我会得到默认响应 default backend - 404
。
希望对您有所帮助
我是 K8s 的新手,这是我第一次尝试掌握它。我正在尝试使用此 deployment.yml:
设置基本的 Nodejs Express APIapiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: api
spec:
replicas: 1
template:
metadata:
labels:
app: api
spec:
containers:
- image: registry.gitlab.com/<project>/<app>:<TAG>
imagePullPolicy: Always
name: api
env:
- name: PORT
value: "8080"
ports:
- containerPort: 8080
hostPort: 80
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 1
imagePullSecrets:
- name: registry.gitlab.com
正在通过 gitlab-ci 部署。这是有效的,我已经设置了一个服务来公开它:
apiVersion: v1
kind: Service
metadata:
name: api-svc
labels:
app: api-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: api
type: LoadBalancer
但我一直在研究入口,以便为可能的多项服务提供单一入口点。我一直在阅读 Kubernetes 指南,我阅读了这个 Kubernetes Ingress Example,这是我创建的 ingress.yml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
spec:
backend:
serviceName: api-svc
servicePort: 80
但这没有用,当我访问从入口生成的外部 IP 地址时,我只有 502 个错误页面。
谁能指出我正确的方向,我做错了什么或者我错过了什么?我在上面的示例 link 中看到有一个 nginx-rc.yml ,我完全按照示例中的方式部署了它,并且已创建但仍然没有从端点获得任何信息。 API 可从服务外部 IP 访问。
非常感谢
看起来您正在向端口 80
公开您的服务,但您的容器正在向 8080
公开,因此对服务的任何请求都将失败。
此外,请查看示例入口资源 (https://github.com/nginxinc/kubernetes-ingress/blob/master/examples/complete-example/cafe-ingress.yaml),您还需要定义在入口控制器被命中时路由哪些主机/路径。 (即 example.foo.com --> api-svc)
我又看了一遍,我想我明白了。
为了让 Ingress 在 GCE 上工作,您需要将后端服务定义为 NodePort
而不是 ClusterIP 或 LoadBalancer。
此外,您还需要确保对 /
的 http 健康检查有效(您会看到 Google L7 负载均衡器在 url 上对您的服务产生了相当大的影响)和那么它就可用了。
以为我会 post 我的工作 deployment/service/ingress
因此,经过大量努力使它工作后,这是我用来使它工作的方法:
部署
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: backend-api-v2
spec:
replicas: 2
template:
metadata:
labels:
app: backend-api-v2
spec:
containers:
- image: registry.gitlab.com/<project>/<app>:<TAG>
imagePullPolicy: Always
name: backend-api-v2
env:
- name: PORT
value: "8080"
ports:
- containerPort: 8080
livenessProbe:
httpGet:
# Path to probe; should be cheap, but representative of typical behavior
path: /healthz
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 5
imagePullSecrets:
- name: registry.gitlab.com
服务
apiVersion: v1
kind: Service
metadata:
name: api-svc-v2
labels:
app: api-svc-v2
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 31810
protocol: TCP
name: http
selector:
app: backend-api-v2
入口
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: api.foo.com
http:
paths:
- path: /v1/*
backend:
serviceName: api-svc
servicePort: 80
- path: /v2/*
backend:
serviceName: api-svc-v2
servicePort: 80
正如@Tigraine 指出的那样,需要注意的重要一点是该服务使用的是 type: NodePort
而不是 LoadBalancer
,我还定义了一个 nodePort,但我相信如果您保留它,它会创建一个出去。
它将对任何不符合规则的路由使用 default-http-backend
这是 GKE 在 kube-system
命名空间中运行的默认容器。因此,如果我访问 http://api.foo.com/bob
,我会得到默认响应 default backend - 404
。
希望对您有所帮助