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

Tel*_*uar 2 yaml kubernetes 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

kubectl 描述 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>
Run Code Online (Sandbox Code Playgroud)

从上面我假设我应该能够从 http://192.168.40.74:9012访问 minIO 控制台,但这是不可能的。

错误信息:

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
Run Code Online (Sandbox Code Playgroud)

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

moo*_*tte 7

K3S集群初始配置

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

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

    curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC='--write-kubeconfig-mode=644' sh -
    
    Run Code Online (Sandbox Code Playgroud)
  2. 验证它是否有效:

    k8s kubectl get nodes -o wide
    
    Run Code Online (Sandbox Code Playgroud)
  3. 要添加工作节点,应在工作节点上运行以下命令:

    curl -sfL https://get.k3s.io | K3S_URL=https://control-plane:6443 K3S_TOKEN=mynodetoken sh -
    
    Run Code Online (Sandbox Code Playgroud)

K3S_URL控制平面 URL(带有 IP 或 DNS)在哪里

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

sudo cat /var/lib/rancher/k3s/server/node-token
Run Code Online (Sandbox Code Playgroud)

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

$ 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
Run Code Online (Sandbox Code Playgroud)

复制和测试

我通过以下方式创建了一个基于nginx图像的简单部署:

$ k3s kubectl create deploy nginx --image=nginx
Run Code Online (Sandbox Code Playgroud)

并曝光了它:

$ k3s kubectl expose deploy nginx --type=LoadBalancer --port=8080 --target-port=80
Run Code Online (Sandbox Code Playgroud)

这意味着nginxpod 中的容器正在侦听端口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
Run Code Online (Sandbox Code Playgroud)

服务可以在 IP 或ANDlocalhost端口上访问。8080NodePort

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

回答第二个问题-负载均衡器

rancher k3s官方文档中关于LoadBalancer来看,使用的是Klipper负载均衡器。来自他们的 github 存储库:

这是 klipper 中集成服务负载均衡器的运行时映像。这是通过为每个服务负载均衡器使用主机端口并设置 iptables 将请求转发到集群 IP 来实现的。

服务负载均衡器的工作原理来看

K3s 创建一个控制器,为服务负载均衡器创建一个 Pod,它是一个 Service 类型的 Kubernetes 对象。

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

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

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

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

例如,我创建了第二个部署nginx-two并将其暴露在 port 上8090,您可以看到来自两个不同部署的两个 pod 以及充当负载均衡器的四个 pod(请注意名称 -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>
Run Code Online (Sandbox Code Playgroud)

两种服务具有相同的EXTERNAL-IPs:

$ k3s kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP               PORT(S)          AGE
nginx        LoadBalancer   10.43.169.6    10.186.0.17,10.186.0.18   8080:31762/TCP   50m
nginx-two    LoadBalancer   10.43.118.82   10.186.0.17,10.186.0.18   8090:31780/TCP   4m44s
Run Code Online (Sandbox Code Playgroud)