负载均衡器外部IP与K3s集群中节点的内部IP相同

时间:2021-07-14 12:39:14

标签: kubernetes yaml minio kubernetes-service k3s

我已经使用以下方法在 k3s 集群中设置了一个服务:

apiVersion: v1
kind: Service
metadata:
  name: myservice
  namespace: mynamespace
  labels:
    app: myapp
spec:
  type: LoadBalancer
  selector:
    app: myapp
  ports:
  - port: 9012 
    targetPort: 9011 
    protocol: TCP
<块引用>

kubectl get svc -n mynamespace

NAME            TYPE           CLUSTER-IP      EXTERNAL-IP                                PORT(S)          AGE
minio           ClusterIP      None            <none>                                     9011/TCP         42m
minio-service   LoadBalancer   10.32.178.112   192.168.40.74,192.168.40.88,192.168.40.170   9012:32296/TCP   42m
<块引用>

kubectl describe svc myservice -n mynamespace

Name:                     myservice
Namespace:                mynamespace
Labels:                   app=myapp
Annotations:              <none>
Selector:                 app=myapp
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.32.178.112
IPs:                      10.32.178.112
LoadBalancer Ingress:     192.168.40.74, 192.168.40.88, 192.168.40.170
Port:                     <unset>  9012/TCP
TargetPort:               9011/TCP
NodePort:                 <unset>  32296/TCP
Endpoints:                10.42.10.43:9011,10.42.10.44:9011
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

我从上面假设我可以从以下位置访问 minIO 控制台: http://192.168.40.74:9012 但这是不可能的。

错误信息:

<块引用>

curl: (7) 无法连接到 192.168.40.74 端口 9012:连接 超时

此外,如果我执行

<块引用>

kubectl get node -o wide -n mynamespace

NAME           STATUS   ROLES                  AGE     VERSION        INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION       CONTAINER-RUNTIME
antonis-dell   Ready    control-plane,master   6d      v1.21.2+k3s1   192.168.40.74    <none>        Ubuntu 18.04.1 LTS               4.15.0-147-generic   containerd://1.4.4-k3s2
knodeb         Ready    worker                 5d23h   v1.21.2+k3s1   192.168.40.88   <none>        Raspbian GNU/Linux 10 (buster)   5.4.51-v7l+          containerd://1.4.4-k3s2
knodea         Ready    worker                 5d23h   v1.21.2+k3s1   192.168.40.170   <none>        Raspbian GNU/Linux 10 (buster)   5.10.17-v7l+         containerd://1.4.4-k3s2

如上所示,节点的 INTERNAL-IP 与负载均衡器的 EXTERNAL-IP 相同。我在这里做错了吗?

1 个答案:

答案 0 :(得分:3)

K3S集群初始配置

为了重现环境,我按照以下步骤创建了一个双节点 k3s 集群:

  1. 在所需的主机上安装 k3s 控制平面:

    curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC='--write-kubeconfig-mode=644' sh -
    
  2. 验证它是否有效:

    k8s kubectl get nodes -o wide
    
  3. 要添加工作节点,应在工作节点上运行此命令:

    curl -sfL https://get.k3s.io | K3S_URL=https://control-plane:6443 K3S_TOKEN=mynodetoken sh -
    

其中 K3S_URL 是控制平面 URL(带有 IP 或 DNS)

K3S_TOKEN 可以通过以下方式获得:

sudo cat /var/lib/rancher/k3s/server/node-token

您应该有一个正在运行的集群:

$ k3s kubectl get nodes -o wide
NAME           STATUS   ROLES                  AGE   VERSION        INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
k3s-cluster    Ready    control-plane,master   27m   v1.21.2+k3s1   10.186.0.17   <none>        Ubuntu 18.04.5 LTS   5.4.0-1046-gcp   containerd://1.4.4-k3s2
k3s-worker-1   Ready    <none>                 18m   v1.21.2+k3s1   10.186.0.18   <none>        Ubuntu 18.04.5 LTS   5.4.0-1046-gcp   containerd://1.4.4-k3s2

复制和测试

我基于 nginx 映像创建了一个简单的部署:

$ k3s kubectl create deploy nginx --image=nginx

并暴露它:

$ k3s kubectl expose deploy nginx --type=LoadBalancer --port=8080 --target-port=80

这意味着 pod 中的 nginx 容器正在侦听端口 80,并且 service 可在集群内的端口 8080 上访问:

$ k3s kubectl get svc -o wide
NAME         TYPE           CLUSTER-IP    EXTERNAL-IP               PORT(S)          AGE   SELECTOR
kubernetes   ClusterIP      10.43.0.1     <none>                    443/TCP          29m   <none>
nginx        LoadBalancer   10.43.169.6   10.186.0.17,10.186.0.18   8080:31762/TCP   25m   app=nginx

服务可通过 IP 或 localhost 和端口 8080NodePort 访问。

+ 考虑到您收到的错误 curl: (7) Failed to connect to 192.168.40.74 port 9012: Connection timed out 表示服务已配置,但没有正确响应(不是来自入口的 404 或 connection refused)。

回答第二个问题 - Loadbalancer

rancher k3s official documentation about LoadBalancer 开始,使用 Klipper Load Balancer。来自他们的 github 仓库:

<块引用>

这是集成服务负载均衡器的运行时映像 快船。这是通过为每个服务负载使用一个主机端口来实现的 平衡器并设置 iptables 将请求转发到集群 知识产权。

来自how the service loadbalancer works

<块引用>

K3s 创建一个控制器,为服务负载创建一个 Pod 平衡器,它是一种服务的 Kubernetes 对象。

对于每个服务负载均衡器,都会创建一个 DaemonSet。守护进程集 在每个节点上创建一个带有 svc 前缀的 pod。

Service LB 控制器侦听其他 Kubernetes 服务。后 它找到一个服务,它使用一个为服务创建一个代理 Pod 所有节点上的 DaemonSet。这个 Pod 成为另一个的代理 服务,例如,请求到达节点上的 8000 端口 可以路由到端口 8888 上的工作负载。

如果 Service LB 运行在具有外部 IP 的节点上,它使用 外部IP。

换句话说,是的,预计负载均衡器与主机的 internal-IP 具有相同的 IP 地址。 k3s 集群中每个具有负载均衡器类型的服务在每个节点上都有自己的 daemonSet,用于为初始服务提供直接流量。

例如我创建了第二个部署 nginx-two 并将其暴露在端口 8090 上,您可以看到有来自两个不同部署的两个 Pod 和充当负载均衡器的四个 Pod(请注意名称 - {{ 1}} 开头):

svclb

两个服务具有相同的$ k3s kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-6799fc88d8-7m4v4 1/1 Running 0 47m 10.42.0.9 k3s-cluster <none> <none> svclb-nginx-jc4rz 1/1 Running 0 45m 10.42.0.10 k3s-cluster <none> <none> svclb-nginx-qqmvk 1/1 Running 0 39m 10.42.1.3 k3s-worker-1 <none> <none> nginx-two-6fb6885597-8bv2w 1/1 Running 0 38s 10.42.1.4 k3s-worker-1 <none> <none> svclb-nginx-two-rm594 1/1 Running 0 2s 10.42.0.11 k3s-cluster <none> <none> svclb-nginx-two-hbdc7 1/1 Running 0 2s 10.42.1.5 k3s-worker-1 <none> <none>

EXTERNAL-IP