问题描述
我想让2个在kubernetes上运行的应用程序使用入口资源指向同一端口中的每个应用程序。
我应该能够访问app1.localhost:8181/cxf
中的app1版本和app2.localhost:8181/cxf
中的app2版本
我将docker与kubernetes,MysqL和karaf一起使用kar。我正在本地(本地主机)进行测试。
我尝试了很多我在互联网上搜索过的内容,包括将ip +主机名添加到主机,但是没有运气。发生的是,它始终显示相同的应用程序,与我插入的主机名无关。
1:
我当时想也许我应该有2个节点?一个与MysqL和app1,另一个与MysqL和app2?因此,我可以访问app1.localhost/cxf
服务,而其他app2.localhost/cxf
服务……可能并没有多大意义……而且我读到我需要为此而使用kubeadm,而且没有在Windows上安装它的方法。我想我必须为此使用minikube吗?
2:
我应该不能创建另一个loadBalancer吗?我想要,所以选择器将在该loadBalancer中为app2,但是由于我已经拥有一个选择器,因此新选择器将保持<pending>
直到删除第一个选择器。
但是,当我安装nginx-ingress控制器时,它带有类型loadBalancer,并且如果我创建具有相同内容的Yaml,更改端口将起作用并且不会挂起...为什么?
3: 如果我有两个app1副本和两个app2副本,那么每个应用程序都应该有一个loadBalancer吗?
4: 我应该为MysqL包括loadBalancer吗?拥有MysqL副本有意义吗?
5: 自从我安装Nginx-controller以来,当我检查kubernetes仪表板时,它就会附带一个loadBalancer。可以编辑和添加我的karaf端口以公开服务吗?
请注意,我使用helm安装了Nginx ingress-controller,因为ingress-resource否则无法正常工作,至少那是我所读的内容。我为此使用头盔:https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/index.md#using-helm
注意:MysqL运行正常,因此我不会在此处发布yaml,因此不会太长。
这些是我的yaml:
apiVersion: v1
kind: Service
Metadata:
name: lb-service
spec:
type: LoadBalancer
selector:
app: app1
ports:
- protocol: TCP
name: app1
port: 3306
targetPort: 3306
- protocol: TCP
name: app1-8080
port: 8080
targetPort: 8080
- protocol: TCP
name: app1-8101
port: 8101
targetPort: 8101
- protocol: TCP
name: app1-8181
port: 8181
targetPort: 8181
status:
loadBalancer:
ingress:
- hostname: localhost
app1
:apiVersion: v1
kind: Service
Metadata:
name: app1-service
spec:
ports:
- port: 8101
selector:
app: app1
clusterIP: None
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
Metadata:
name: app1-deployment
spec:
selector:
matchLabels:
app: app1
replicas: 1
template:
Metadata:
labels:
app: app1
spec:
containers:
- name: app1
image: app1:latest
app2 :与app1相同,但版本不同(旧服务)
入口资源:(这是行不通的)
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
Metadata:
name: apps-ingress
#annotations:
#Nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: app1.localhost
http:
paths:
- path: /
backend:
serviceName: app1-service
servicePort: 8181
- host: app2.localhost
http:
paths:
- path: /
backend:
serviceName: app2-service
servicePort: 8181
哼,我在这里错过了一些东西...
感谢您的时间!
编辑:
我想我找到了问题,我现在正试图解决它。 好像ingress仅在http的端口80中起作用,而im使用cxf在端口8181和8080的皂服务中列出我的服务。 所以我想我必须暴露那些端口,我会很好吗?要尝试
edit 2:我尝试过,但是没有用,我遵循以下示例:https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/
该示例运行正常,但是当我更改入口以与我的应用程序一起使用时,它将无法正常工作。
我需要访问:8181 / cxf才能使我的应用正常工作,有什么办法可以做到这一点?
由于入口使用端口80,因此当我放置app1.localhost
时,它与app1.localhost:80
一样吗?事实是,我需要app1.localhost:8181/cxf
才能访问我的服务。但我想它将被翻译为:app1.localhost:80:8181/cxf
??
有人可以帮忙吗? :(
当我说端口8181时,我想我可以使用nodePort:
来使用另一个端口,这基本上就是端口转发权吗?但是如果这样做,就会出现问题,当我想部署第二个应用程序以访问app2.localhost
时,如果我放置相同的nodePort
,它将以错误结束,因为我希望端口相同,但是不同的主机名。
解决方法
回答帖子中的问题:
1:我当时想也许应该有2个节点?一个与mysql和app1,另一个与mysql和app2?因此,我可以在其中一个访问app1.localhost / cxf服务,而在另一个app2.localhost / cxf服务中……可能没有多大意义……而且我在读我需要为此而使用kubeadm,而且没有在Windows上安装它的方法。我想我必须为此使用minikube吗?
您不需要2个节点。您可以使用单节点Kubernetes安装(例如minikube
或Docker Desktop(带有Kubernetes)来生成app1
,app2
和mysql
。我将包含该指南,以揭露此答案末尾提到的示例应用程序。
关于kubeadm
:
kubeadm执行必要的操作,以使最小可行的群集启动并运行。从设计上讲,它只关心引导程序,而不关心配置机器。
简单地说,kubeadm
用于机器(裸机,VM)上的步骤来配置Kubernetes集群(假设已安装,配置了OS等)
小费!
minikube
使用kubeadm
设置其单节点群集。
2:我不能创建另一个loadBalancer吗?我想要,所以选择器将在该loadBalancer中为app2,但是由于我已经有一个选择器,因此新选择器将一直保留到删除第一个选择器为止。但是,当我安装nginx-ingress控制器时,它带有类型loadBalancer,并且如果我创建具有相同内容的Yaml,更改端口将起作用并且不会挂起...为什么?
我们将需要在此处区分两个术语:
-
类型为
-
服务-用于使用云提供商的负载平衡器在外部公开您的应用程序。在
minikube
或docker
之类的解决方案中,通常将其映射到VM的IP(minikube
)或计算机的本地主机(Docker) -
Ingress
资源-公开从群集外部到群集内服务的HTTP和HTTPS路由。流量路由受Ingress资源上定义的规则控制。
LoadBalancer
的根据我的经验,类型LoadBalancer
的服务主要使用Layer4
,其中Ingress
资源在Layer7
上运行。 LoadBalancer
不会根据Host
标头路由您的流量。它将根据您的服务和Deployment
的标签和选择器进行路由。 Ingress
资源旨在服务HTTP
/ HTTPS
流量。它将包含可根据Host
标头路由流量的工具。
这是公开您的应用程序的2种单独方法,应将其视为不同的方法。
提示!
nginx-ingress
使用类型LoadBalancer
的服务将流量路由到nginx-ingress-controller
。从那里对其进行分析并发送到特定的目的地(根据Ingress
资源)!
您在Pending
列中有External-IP
的事实可能与以下事实有关:LoadBalancer
类型的服务中使用的端口已被使用(port
参数)。
3:如果我有两个app1副本和两个app2副本,那么每个应用程序都应该有一个loadBalancer吗?
对于每个应用,您都需要一个LoadBalancer
。您的应用有多少个副本(甚至可以是100个)并不重要。根据前一句话:
-
app1
-类型LoadBalancer
的第一项服务 -
app2
-类型LoadBalancer
的第二项服务
在公开应用程序时,我试图像下面这样思考(它确实很简单):
- 我要暴露不是的流量
HTTP
/HTTPS
-类型为LoadBalancer
的服务 - 我要公开一些示例应用程序,我需要具有
Ingress
(基于Host
的路由,重写,SSL等)-Ingress
资源
免责声明!
在公开具有
LoadBalancer
资源的应用程序时,您无需使用类型为Ingress
的服务。
4:我应该包括用于MySQL的loadBalancer吗?拥有mysql副本有意义吗?
关于在Kubernetes中部署mysql有很多有用的指南。要使您的app1
和app2
访问mysql
窗格,您可以使用ClusterIP
或headlessService
类型的服务。 mysql
的多个副本肯定会提高多节点群集中的容错能力,但是它必须已经包含某种复制逻辑。
您可以通过以下链接阅读更多内容:
- Kubernetes.io: Docs: Defining a service
- Kubernetes.io: Docs: Headless services
- Kubernetes.io: Docs: Run replicated stateful application
5:因为当我安装nginx-controller时,当我检查kubernetes仪表板时,它附带了一个loadBalancer。可以编辑和添加我的karaf端口以公开服务吗?
专门为LoadBalancer
创建的在配置ingress-nginx-controller
时创建的类型ingress-nginx-controller
的服务。
如果您想公开karaf
,则可以选择:
- 根据您的
ingress-nginx-controller
资源的规范,用Ingress
对其进行曝光。 - 通过TCP/UDP services与
nginx-ingress-controller
进行公开(它将不具有Ingress
资源的功能): - 通过类型为
LoadBalancer
的另一种服务示例对其进行公开
本指南旨在与安装了Kubernetes的Docker Desktop
一起使用。
假设您要
我应该能够访问app1.localhost:8181 / cxf中的app1版本和app2.localhost:8181 / cxf中的app2版本
假设您的Docker桌面上有一个可用的Kubernetes实例,则需要遵循以下示例:
- 安装
nginx-ingress
- 生成
hello-one
示例应用程序以及与之相关的服务 - 生成
hello-two
示例应用程序以及与之相关的服务 - 编辑类型为
nginx-ingress
的{{1}}服务 - 创建并应用
LoadBalancer
资源 - 进行一些DNS更改
- 测试
安装Ingress
运行:
nginx-ingress
免责声明!
- 在基于Windows和Mac的环境中尝试执行此步骤时可能会有所不同
- 在
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.35.0/deploy/static/provider/cloud/deploy.yaml
实例上尝试执行此步骤时可能会有所不同
安装页面:
生成minikube
示例应用程序及其相关服务
这是hello-one
应用的定义:
hello-one
以下是apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-one
spec:
selector:
matchLabels:
app: hello-one
version: 1.0.0
replicas: 1
template:
metadata:
labels:
app: hello-one
version: 1.0.0
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-app:1.0" # <-- notice the 1.0
env:
- name: "PORT"
value: "50001"
应用的服务定义:
hello-one
生成apiVersion: v1
kind: Service
metadata:
name: hello-one-service
spec:
type: NodePort
selector:
app: hello-one
version: 1.0.0
ports:
- name: hello-one-port
protocol: TCP
port: 80
targetPort: 50001
示例应用程序及其相关服务
这是hello-two
应用的定义:
hello-two
以下是apps/v1
kind: Deployment
metadata:
name: hello-two
spec:
selector:
matchLabels:
app: hello-two
version: 2.0.0
replicas: 1
template:
metadata:
labels:
app: hello-two
version: 2.0.0
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-app:2.0" # <-- notice the 2.0
env:
- name: "PORT"
value: "50001"
应用的服务定义:
hello-two
编辑类型为apiVersion: v1
kind: Service
metadata:
name: hello-two-service
spec:
type: NodePort
selector:
app: hello-two
version: 2.0.0
ports:
- name: hello-two-port
protocol: TCP
port: 80
targetPort: 50001
的{{1}}服务
您将需要编辑nginx-ingress
类型LoadBalancer
的服务,以支持LoadBalancer
和nginx-ingress-controller
以外的端口。
-
80
负责布线的部分:
443
创建并应用$ kubectl edit service -n ingress-nginx ingress-nginx-controller
资源
您将需要使用以下 ports:
- name: http
nodePort: 32202
port: 80 # <-- CHANGE HERE FOR 8181!
protocol: TCP
targetPort: http
- name: https
nodePort: 31130
port: 443 # <-- CHANGE HERE FOR 8182!
protocol: TCP
targetPort: https
资源来访问您的应用程序,
-
Ingress
-
Ingress
hello-one.kubernetes.local:8181/cxf
免责声明!
此
hello-two.kubernetes.lcoal:8181/cxf
未配置apiVersion: extensions/v1beta1 kind: Ingress metadata: name: hello-ingress spec: rules: - host: hello-one.kubernetes.docker.internal http: paths: - path: / backend: serviceName: hello-one-service servicePort: hello-one-port - host: hello-two.kubernetes.docker.internal http: paths: - path: / backend: serviceName: hello-two-service servicePort: hello-two-port
路径。您可以在此处查找更多资源:
进行一些DNS更改
您将需要编辑主机的DNS设置以支持新创建的Ingress
名称。这部分取决于您使用的操作系统。要添加的行:
/cxf
测试
您可以通过host
或网络浏览器来测试设置:
-
127.0.0.1 hello-one.kubernetes.docker.internal 127.0.0.1 hello-two.kubernetes.docker.internal
curl
-
$ curl hello-one.kubernetes.docker.internal:8181
Hello,world!
Version: 1.0.0
Hostname: hello-one-696db54c4d-5fqt8