嗨,我正在学习 kubernetes,但在公开服务时遇到了麻烦。我想将流量从 HAProxy 路由到我的集群。我正在使用自己的裸机服务器。
编辑:我还创建了一个入口控制器。
现在,当我描述我的入口时,我可以看到工作机器的 IP 地址,但我仍然不知道
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
如何访问我的 pod……
示例配置:
部署.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache
labels:
app: apache-test
spec:
replicas: 1
selector:
matchLabels:
app: apache-test
template:
metadata:
labels:
app: apache-test
spec:
containers:
- name: apache
image: httpd
ports:
- containerPort: 80
服务.yaml
apiVersion: v1
kind: Service
metadata:
name: apache-test-service
spec:
selector:
app: apache-test
ports:
- protocol: TCP
port: 80
targetPort: 80
name: http
入口文件
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: apache-test-ingress
spec:
rules:
- host: apache-test.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: apache-test-service
port:
number: 80
怎么了?
描述入口:
Name: apache-test-ingress
Namespace: default
Address: 192.168.6.72
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
apache-test
/ apache-test-service:80 (10.44.0.1:80)
Annotations: <none>
Events: <none>
描述服务:
Name: apache-test-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=apache-test
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.104.63.167
IPs: 10.104.63.167
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.44.0.1:80
Session Affinity: None
Events: <none>
描述控制器:
Name: ingress-nginx-controller-55bc4f5576-vpsgb
Namespace: ingress-nginx
Priority: 0
Node: kubernetes-node02/192.168.6.72
Start Time: Sun, 16 May 2021 16:47:26 +0200
Labels: app.kubernetes.io/component=controller
app.kubernetes.io/instance=ingress-nginx
app.kubernetes.io/name=ingress-nginx
pod-template-hash=55bc4f5576
Annotations: <none>
Status: Running
IP: 10.36.0.1
IPs:
IP: 10.36.0.1
Controlled By: ReplicaSet/ingress-nginx-controller-55bc4f5576
Containers:
controller:
Container ID: docker://7daf566a039aba0d06f856b0adcc03659423ec2462c33d9a79f820b58dfcbf98
Image: k8s.gcr.io/ingress-nginx/controller:v0.46.0@sha256:52f0058bed0a17ab0fb35628ba97e8d52b5d32299fbc03cc0f6c7b9ff036b61a
Image ID: docker-pullable://k8s.gcr.io/ingress-nginx/controller@sha256:52f0058bed0a17ab0fb35628ba97e8d52b5d32299fbc03cc0f6c7b9ff036b61a
Ports: 80/TCP, 443/TCP, 8443/TCP
Host Ports: 0/TCP, 0/TCP, 0/TCP
Args:
/nginx-ingress-controller
--election-id=ingress-controller-leader
--ingress-class=nginx
--configmap=$(POD_NAMESPACE)/ingress-nginx-controller
--validating-webhook=:8443
--validating-webhook-certificate=/usr/local/certificates/cert
--validating-webhook-key=/usr/local/certificates/key
State: Running
Started: Sun, 16 May 2021 16:47:28 +0200
Ready: True
Restart Count: 0
Requests:
cpu: 100m
memory: 90Mi
Liveness: http-get http://:10254/healthz delay=10s timeout=1s period=10s #success=1 #failure=5
Readiness: http-get http://:10254/healthz delay=10s timeout=1s period=10s #success=1 #failure=3
Environment:
POD_NAME: ingress-nginx-controller-55bc4f5576-vpsgb (v1:metadata.name)
POD_NAMESPACE: ingress-nginx (v1:metadata.namespace)
LD_PRELOAD: /usr/local/lib/libmimalloc.so
Mounts:
/usr/local/certificates/ from webhook-cert (ro)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-ftnfs (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
webhook-cert:
Type: Secret (a volume populated by a Secret)
SecretName: ingress-nginx-admission
Optional: false
kube-api-access-ftnfs:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Burstable
Node-Selectors: kubernetes.io/os=linux
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
POD 的日志没有显示任何内容...来自入口控制器的日志:
I0516 14:47:28.871207 8 flags.go:208] "Watching for Ingress" class="nginx"
W0516 14:47:28.871287 8 flags.go:213] Ingresses with an empty class will also be processed by this Ingress controller
W0516 14:47:28.872068 8 client_config.go:614] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
I0516 14:47:28.872594 8 main.go:241] "Creating API client" host="https://10.96.0.1:443"
I0516 14:47:28.887394 8 main.go:285] "Running in Kubernetes cluster" major="1" minor="21" git="v1.21.0" state="clean" commit="cb303e613a121a29364f75cc67d3d580833a7479" platform="linux/amd64"
I0516 14:47:29.768986 8 main.go:105] "SSL fake certificate created" file="/etc/ingress-controller/ssl/default-fake-certificate.pem"
I0516 14:47:29.772688 8 main.go:115] "Enabling new Ingress features available since Kubernetes v1.18"
W0516 14:47:29.775841 8 main.go:127] No IngressClass resource with name nginx found. Only annotation will be used.
I0516 14:47:29.793896 8 ssl.go:532] "loading tls certificate" path="/usr/local/certificates/cert" key="/usr/local/certificates/key"
I0516 14:47:29.829161 8 nginx.go:254] "Starting NGINX Ingress controller"
I0516 14:47:29.848934 8 event.go:282] Event(v1.ObjectReference{Kind:"ConfigMap", Namespace:"ingress-nginx", Name:"ingress-nginx-controller", UID:"0cf6bc98-71b3-4387-a535-7d3dcb956fc8", APIVersion:"v1", ResourceVersion:"401441", FieldPath:""}): type: 'Normal' reason: 'CREATE' ConfigMap ingress-nginx/ingress-nginx-controller
I0516 14:47:30.936661 8 event.go:282] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"apache-test-ingress", UID:"6e3c5757-28cf-4a68-be98-827fd69ee86f", APIVersion:"networking.k8s.io/v1beta1", ResourceVersion:"400092", FieldPath:""}): type: 'Normal' reason: 'Sync' Scheduled for sync
I0516 14:47:31.030103 8 nginx.go:296] "Starting NGINX process"
I0516 14:47:31.030266 8 leaderelection.go:243] attempting to acquire leader lease ingress-nginx/ingress-controller-leader-nginx...
I0516 14:47:31.030658 8 nginx.go:316] "Starting validation webhook" address=":8443" certPath="/usr/local/certificates/cert" keyPath="/usr/local/certificates/key"
I0516 14:47:31.031274 8 controller.go:146] "Configuration changes detected, backend reload required"
I0516 14:47:31.040799 8 leaderelection.go:253] successfully acquired lease ingress-nginx/ingress-controller-leader-nginx
I0516 14:47:31.041189 8 status.go:84] "New leader elected" identity="ingress-nginx-controller-55bc4f5576-vpsgb"
I0516 14:47:31.054203 8 status.go:204] "POD is not ready" pod="ingress-nginx/ingress-nginx-controller-55bc4f5576-vpsgb" node="kubernetes-node02"
I0516 14:47:31.129614 8 controller.go:163] "Backend successfully reloaded"
I0516 14:47:31.129922 8 controller.go:174] "Initial sync, sleeping for 1 second"
I0516 14:47:31.130053 8 event.go:282] Event(v1.ObjectReference{Kind:"Pod", Namespace:"ingress-nginx", Name:"ingress-nginx-controller-55bc4f5576-vpsgb", UID:"16d9fca9-8ac9-4fc1-be40-056540857035", APIVersion:"v1", ResourceVersion:"401513", FieldPath:""}): type: 'Normal' reason: 'RELOAD' NGINX reload triggered due to a change in configuration
I0516 14:48:31.054140 8 status.go:284] "updating Ingress status" namespace="default" ingress="apache-test-ingress" currentValue=[] newValue=[{IP:192.168.6.72 Hostname: Ports:[]}]
I0516 14:48:31.067947 8 event.go:282] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"apache-test-ingress", UID:"6e3c5757-28cf-4a68-be98-827fd69ee86f", APIVersion:"networking.k8s.io/v1beta1", ResourceVersion:"401625", FieldPath:""}): type: 'Normal' reason: 'Sync' Scheduled for sync
描述POD
Name: apache-67487b7c8b-8jbgb
Namespace: default
Priority: 0
Node: kubernetes-node01/192.168.6.71
Start Time: Sun, 16 May 2021 15:13:07 +0200
Labels: app=apache-test
pod-template-hash=67487b7c8b
Annotations: <none>
Status: Running
IP: 10.44.0.1
IPs:
IP: 10.44.0.1
Controlled By: ReplicaSet/apache-67487b7c8b
Containers:
apache:
Container ID: docker://70e4e3c4e01dffa11aa3c945f297e2cf3bc8af249c8d900c8aa30381ce7f56e6
Image: httpd
Image ID: docker-pullable://httpd@sha256:e4c2b93c04762468a6cce6d507d94def02ef4dc285278d0d926e09827f4857db
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sun, 16 May 2021 15:13:10 +0200
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-c8dfx (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-c8dfx:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
编辑:我用了一个入口控制器:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.46.0/deploy/static/provider/baremetal/deploy.yaml
答案1
总结
80
不要使用/端口,而应使用与类型443
关联的端口Service
NodePort
您在Ingress controller
配置过程中创建的。
$ kubectl get services -n
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.233.39.209 <none> 80:30983/TCP,443:32636/TCP 4h30m
ingress-nginx-controller-admission ClusterIP 10.233.54.211 <none> 443/TCP 4h30m
在这个例子中,您应该使用您的一个 IP 地址Nodes
和相应的端口(当尝试从外部连接它时):
curl http://IP_ADDRESS:30983
或者curl -v -k https://IP_ADDRESS:32636
解释
YAML
重点关注您使用的清单部分:
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
annotations:
labels:
<-- REDACTED -->
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: NodePort # <-- IMPORTANT
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
当您应用整个清单时,您就创建了一个Service
类型NodePort
。
引用官方文档:
NodePort
:通过静态端口( )在每个节点的 IP 上公开服务NodePort
。服务路由ClusterIP
到的服务NodePort
会自动创建。您可以NodePort
通过请求 ,从集群外部联系服务<NodeIP>:<NodePort>
。--Kubernetes.io:文档:概念:服务网络:服务:发布服务服务类型
类型节点端口
如果将此
type
字段设置为NodePort
,Kubernetes 控制平面将从标志指定的范围内分配一个端口(默认值:30000-32767)。每个节点将该端口(每个节点上的端口号相同)代理到您的服务中。您的服务在其字段--service-node-port-range
中报告分配的端口。.spec.ports[*].nodePort
这NodePort
是控制器的入口点Ingress
。您需要向其端口发送请求以联系控制器Ingress
(然后Ingress
控制器会相应地将流量路由到Ingress
资源)。
您可以通过调用(前面提到过)来检查应该将流量发送到哪个端口:
$ kubectl get services -n
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.233.39.209 <none> 80:30983/TCP,443:32636/TCP 4h30m
ingress-nginx-controller-admission ClusterIP 10.233.54.211 <none> 443/TCP 4h30m
在此示例中,其应如下所示:
curl http://IP_ADDRESS:30983
为了HTTP
curl -v -k https://IP_ADDRESS:32636
为了HTTPS
如果您想Nginx Ingress
在端口上公开您的控制器80
/443
您可以选择使用以下Service
类型:LoadBalancer
Metallb
将允许您创建一个可供分配Service
类型的IP 地址池LoadBalancer
。
附注!
请记住,对于
Ingress
您指定的资源,您应该发送带有 的请求,Host: apache-test.com
否则您将获得404
。出于测试目的,您可以设置:
- host:
代替:- host: apache-test.com
解决问题的以下部分:
现在,当我描述我的入口时,我可以看到工作机器的 IP 地址,但我仍然不知道
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
如何访问我的 pod……
这不会限制您连接的能力,Services
因为当流量与资源中的任何规则不匹配时,这是一个发送流量的资源Ingress
。
其他资源: