我已经在 Ubuntu Linux 实例上使用 kubeadm、裸机设置了 Kubernetes。这些是 GCE 上的实例,但我没有使用特定的 GKE 本机集群服务。每个实例(作为节点)都有一个静态的外部 IPv4 地址。我正在尝试使用入口将服务提供给外部。我尝试过 MetalLB 或端口转发,但无法使其工作。前者似乎需要按需委托地址,而我没有。
是否有推荐的方法使 LoadBalancing 与静态外部 IP 一起工作?
答案1
我认为这个问题的根本原因是Firewall configuration
。您可以通过几种方式连接到集群。下面我将为您提供NodePort
方法示例。
假设有一个正确配置的 Kubernetes 集群(使用CNI
,Docker,库贝德引导、污点等等)。
您可以使用以下示例来生成hello-app
响应您的流量的 pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-1
spec:
replicas: 1
selector:
matchLabels:
key: application-1
template:
metadata:
labels:
key: application-1
spec:
containers:
- name: hello1
image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
使用NodePort
服务类型。
您正在使用 GCE 实例,因此您的 VM 已经具有静态ExternalIP
。
Hello-app
已在上一步中部署,现在您需要使用service
类型公开它NodePort
apiVersion: v1
kind: Service
metadata:
name: service-one
spec:
type: NodePort
selector:
key: application-1
ports:
- port: 80
targetPort: 8080
默认情况下,防火墙会阻止未列入白名单的端口上的传入请求。您需要创建一条规则,允许流量进入特定端口(即31085
)。有关详细信息,请查看配置防火墙规则。
您可以按照以下路径进行操作:
Navigation Menu
> VPC Network
> Firewall
> Create Firewall Rule
。
您可以创建一条规则来允许:
NodePort
例如单端口31085
- 全范围
30000-32767
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 50m
service-one NodePort 10.110.184.238 <none> 80:31085/TCP 5m53s
要访问你的集群,你可以使用
$ curl 外部节点 IP:节点端口
$ curl 35.246.148.237:31085
Hello, world!
Version: 1.0.0
Hostname: deployment-1-77ddb77d56-v5826
如果您不为此创建 FirewallRule NodePort
,则 curl 输出将是:
curl: (7) Failed to connect to 35.246.148.237 port 31085: Connection refused
使用Ngin 入口控制器作为裸机考虑
使用时Nginx Ingress
可以使用:
- 通过 NodePort 服务
- 主机网络
您可以使用以下方式部署 Nginx BareMetal:
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.2/deploy/static/provider/baremetal/deploy.yaml
它将创建Nginx service
为NodePort
类型。它与以前的方法非常相似,但不同之处在于您的服务可以是ClusterIP
和NodePort
类型。
您可以使用此方法应用 Ingress 来公开多个服务。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /one
backend:
serviceName: service-one
servicePort: 80
- path: /two
backend:
serviceName: service-two
servicePort: 80
$ kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service-one ClusterIP 10.106.21.3 <none> 80/TCP 2m4s
default service-two ClusterIP 10.105.161.86 <none> 80/TCP 2m2s
ingress-nginx ingress-nginx-controller NodePort 10.110.149.194 <none> 80:31337/TCP,443:30417/TCP 6m31s
ingress-nginx ingress-nginx-controller-admission ClusterIP 10.98.15.73 <none> 443/TCP 6m31s
### Output:
$ curl 35.246.148.237:31337/one
Hello, world!
Version: 1.0.0
Hostname: deployment-1-77ddb77d56-v5826
curl 35.246.148.237:31337/two
Hello, world!
Version: 2.0.0
Hostname: deployment-2-fb984955c-8pfls