我对 kubernetes 还很陌生。我需要一些关于如何访问部署在集群中的应用程序的建议。
我有一个包含 Django 应用程序和 Gunicorn 的 docker 镜像来运行 .wsgi。我使用此镜像在包含 3 个节点的集群中部署容器(用于学习 k8s 的环境,1 个主节点 2 个从节点)。如果我使用 nodePort 公开服务并使用 curl <node'sIP>:[port],从未包含的服务器到集群,我就可以访问该应用程序。
但现在我想要一个单一的入口点,它可以与任何副本连接。
我考虑过创建另一台机器,不将其包含在安装了 Nginx 或 HAproxy 的集群中,但我找不到如何将外部反向代理与 kubernetes 服务连接起来的任何解决方案。
您能给我提供更好的解决方案,或者建议我如何继续我的想法吗?
答案1
总结
在类似的托管 Kubernetes 集群中GKE
,EKS
您AKS
可以向云提供商请求服务的 IP 地址。
例如,Virtualbox
使用创建的 Kubernetes 集群 都需要额外的工具才能获取服务。kubespray
kubeadm
External-IP
您可以在非云提供商管理的集群中使用metallb
。External-IP
请查看官方网站:
在这种情况下,公开应用程序的步骤如下:
- 部署应用程序 pod
- 创建
service
附加到 Pod 的 - 部署
metallb
并配置 - 通过以下方式公开应用程序:
- 创建类型服务
LoadBalancer
- 创建
Ingress
资源
- 创建类型服务
免责声明!
创建
Ingress
资源需要Ingress
控制器。我已在下面附上其中一个控制器的链接。
metallb
我在下面提供了一个示例和更多解释,说明如何使用和在 Virtualbox 中创建的集群中公开您的应用程序nginx-ingress-controller
。
这是一个示例,展示了如何在 Virtualbox 中创建的 Kubernetes 集群上公开应用程序:
metallb
nginx-ingress-controller
我把这个答案分为两部分:
- 虚拟盒
- Kubernetes
虚拟盒
在 Virtualbox 中创建时,VM's
您可以通过多种方式配置网络。其中一些是:
Bridged networking
- 将你的 Kubernetes 集群连接到物理网络Host-only
- 允许单个适配器连接到节点,主机允许网络连接。此解决方案需要另一个可访问 Internet 的适配器或连接相同Host-only
网络适配器的网关(例如 PfSense)。
此示例使用客户端和 3 个带有Bridged
适配器的节点:
client
IP 地址:192.168.0.2
master
IP 地址:192.168.0.117
worker1
IP 地址:192.168.0.118
worker2
IP 地址:192.168.0.119
为了确保此示例在主机之外有效,我使用了同一网络中的另一台设备。
请确保节点之间具有完全连接,并且您的主机对它们具有完全访问权限。
Kubernetes
假设:
- 集群配置正确并可以访问互联网
- 您拥有该集群的完全访问权限
- 您可以从任何其他主机“ping”每个节点
- 你的 pod 在你选择的端口上响应请求(例如
8000
)
脚步:
- 使用以下方式创建一个 Pod
gunicorn
gunicorn
为pod创建服务定义- 部署
Metallb
- 使用以下类型的服务公开应用程序
LoadBalancer
- 公开带有
Ingress
资源的应用程序
使用以下方式创建一个 Podgunicorn
我用的是下面部署定义创建一个响应请求的 pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: gunicorn
spec:
selector:
matchLabels:
app: gunicorn
replicas: 1
template:
metadata:
labels:
app: gunicorn
spec:
containers:
- name: gunicorn
image: ubuntu
command:
- sleep
- "infinity"
我使用了ubuntu
我将要进入的图像exec
并运行以下命令:
$ apt update && apt install -y python3 python3-pip
$ pip3 install gunicorn
我使用的示例代码myapp.py
:
def app(environ, start_response):
data = b"Hello, World!\n"
start_response("200 OK", [
("Content-Type", "text/plain"),
("Content-Length", str(len(data)))
])
return iter([data])
$ gunicorn -w 1 -b 0.0.0.0 myapp:app &
上面的例子基于:
完成这些步骤后你的 pod 应该会在端口上做出8000
响应Hello, World!
。
gunicorn
为pod创建服务定义
pod的服务定义gunicorn
:
apiVersion: v1
kind: Service
metadata:
name: gunicorn-service
spec:
selector:
app: gunicorn
ports:
- name: gunicorn-port
port: 8000
targetPort: 8000
type: NodePort
部署Metallb
遵循官方Metallb
文档:Metallb.universe.tf:安装:
- 编辑以将模式从
kube-proxy
更改为:strictARP
false
true
$ kubectl edit configmap -n kube-system kube-proxy
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
$ kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)
您还需要添加一个configMap
来告诉metallb
他可以为服务分配哪些 IP 地址:
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.0.240-192.168.0.250
请具体看以下部分:
addresses:
- 192.168.0.240-192.168.0.250
请确保该地址范围不与网络中使用的任何地址重叠,并且与节点和客户端位于同一网络中。
此后,您应该能够创建LoadBalancer
获取 IP 地址的服务类型。
使用以下类型的服务公开应用程序LoadBalancer
您应该能够运行:
$ kubectl expose deployment gunicorn --type=LoadBalancer --port=8000
输出$ kubectl get services
应该显示:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gunicorn LoadBalancer 10.233.43.104 192.168.0.240 8000:32591/TCP 3s
gunicorn-service NodePort 10.233.34.96 <none> 8000:30862/TCP 73s
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 23h
如您所见,gunicorn
服务具有的,EXTERNAL-IP
其192.168.0.240
位于的 IP 池中metallb
。
本例中使用的物理网络是
192.168.0.0/24
您可以运行:curl 192.168.0.240:8000
并获得:Hello, World!
公开带有Ingress
资源的应用程序
Ingress
在公开应用程序之前,您需要部署控制器。您可以nginx-ingress-controller
通过运行以下命令进行部署:
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml
该Ingress
控制器将附加一个服务类型LoadBalancer
,这将是入口点针对该请求。
您可以通过调用以下命令获取其 IP 地址$ kubectl get svc -n ingress-nginx
:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.233.52.8 192.168.0.241 80:31380/TCP,443:30066/TCP 29m
ingress-nginx-controller-admission ClusterIP 10.233.37.255 <none> 443/TCP 29m
以下是Ingress
将流量从控制器路由到你的 pod 的定义:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gunicorn-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host:
http:
paths:
- path: /
backend:
serviceName: gunicorn-service
servicePort: gunicorn-port
应用后,您应该能够:
curl 192.168.0.241
并得到以下回应gunicorn