问题描述
我正在尝试从 EKS fargate pod 连接到在“假节点”上运行的 kubelet。
例如,我有两个 Nginx pod,其 IP 为 10.0.0.1
和 10.0.0.2
,托管在两个具有相同 IP 的假节点 10.0.0.1
和 10.0.0.2
中。
从 pod 10.0.0.1
我可以正确运行 10.0.0.2
:
curl -X GET https://10.0.0.2:10250/stats/summary --header "Authorization: Bearer $TOKEN" --insecure
{
"node": {
"nodeName": "fargate-ip-10.0.0.2.us-east-2.compute.internal","systemContainers": [
{
"name": "pods","startTime": "2021-03-02T11:21:55Z",[...]
-
但是,如果我尝试卷曲同一个主机
10.0.0.1:10250
,我的连接会被拒绝。 -
对第二个 pod 执行相同操作会导致相反的结果,我可以查询
10.0.0.1
而不是10.0.0.2
。 -
请注意,如果我卷曲端口 80,则 Nginx 会正确响应,因此当从 pod 本身连接时,网络似乎无法理解主机可以响应请求
-
此外,我知道我可以通过代理 (
curl -X GET https://172.20.0.1:443/api/v1/nodes/fargate-ip-10-0-0-1.us-east-2.compute.internal/stats/summary --header "Authorization: Bearer $TOKEN" --insecure
),但由于某些限制,这在我的场景中不可行
解决方法
因此,在 AWS Fargate 上,Pod 和关联的节点共享 IP 地址:
$ kubectl get pods -o=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
foo 1/1 Running 0 94m 192.168.152.183 fargate-ip-192-168-152-183.eu-central-1.compute.internal <none> <none>
$
$ kubectl get nodes -o=wide fargate-ip-192-168-152-183.eu-central-1.compute.internal
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
fargate-ip-192-168-152-183.eu-central-1.compute.internal Ready <none> 92m v1.18.9-eks-866667 192.168.152.183 <none> Amazon Linux 2 4.14.209-160.339.amzn2.x86_64 containerd://1.4.1
如果查看 pod 上的路由表,您会发现以下内容:
$ kubectl exec -i -t foo -- ip r get 192.168.152.183
local 192.168.152.183 dev lo src 192.168.152.183 uid 0
cache <local>
$
$ kubectl exec -i -t foo -- ip r get 192.168.152.20 # Notice different IP address.
192.168.152.20 dev eth0 src 192.168.152.183 uid 0
cache
因此,如果您尝试从 Pod 内访问您自己的 IP 地址,流量将通过容器本地的网络堆栈流动,而 kubelet 无法访问。
从外部访问时,您首先访问运行 kubelet
的底层主机操作系统。我想那时有一些魔法,它将流量转发到容器。
Fargate 不允许运行特权容器或添加 CAP_SYS_ADMIN
功能,因此无法通过覆盖路由表来绕过本地堆栈。
我不知道是否有其他方法可以以非特权方式做到这一点。