较新版本的 Minikube 不允许 Pods 使用他们自己的服务
Newer versions of Minikube don't allow Pods to use their own Services
我有一个 Pod,它偶尔需要通过自己的主机名来调用自己。我有一个 Deployment 设置,最终创建 Pod 和一个 Service。我可以使用集群中不同 Pod 的服务名称,但 Pod 无法使用其主机名调用自身。这适用于 Minikube v0.17.1 和 Kubernetes 版本 1.5.3,但升级 Minikube 或 Kubernetes 版本似乎会破坏事情。这也适用于我们部署的/服务器版本的 Kubernetes。
在我的 Pod/服务设置中是否有我需要考虑的变化?我该如何克服这个问题?
事情应该如何运作
运行 Minikube 版本 0.17.1:
启动 Minikube:
$ minikube start
Starting local Kubernetes cluster...
Starting VM...
SSH-ing files into VM...
Setting up certs...
Starting cluster components...
Connecting to cluster...
Setting up kubeconfig...
Kubectl is now configured to use the cluster.
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"08e099554f3c31f6e6f07b448ab3ed78d0520507", GitTreeState:"clean", BuildDate:"2017-01-12T04:57:25Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"windows/amd64"}
Server Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.3", GitCommit:"029c3a408176b55c30846f0faedf56aae5992e9b", GitTreeState:"clean", BuildDate:"1970-01-01T00:00:00Z", GoVersion:"go1.7.3", Compiler:"gc", Platform:"linux/amd64"}
$ minikube version
minikube version: v0.17.1
部署最小测试图像(下面的 yaml 定义):
kubectl apply -f deploy_python.yaml
执行 python2 图像,并验证与 python 图像的连接:
$ kubectl exec -it python2-1281934109-k015g bash
root@python2-1281934109-k015g:/# curl python:12345 --connect-timeout 10
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".dockerenv">.dockerenv</a></li>
<li><a href="bin/">bin/</a></li>
<li><a href="boot/">boot/</a></li>
<li><a href="dev/">dev/</a></li>
<li><a href="etc/">etc/</a></li>
<li><a href="home/">home/</a></li>
<li><a href="lib/">lib/</a></li>
<li><a href="lib64/">lib64/</a></li>
<li><a href="media/">media/</a></li>
<li><a href="mnt/">mnt/</a></li>
<li><a href="opt/">opt/</a></li>
<li><a href="proc/">proc/</a></li>
<li><a href="root/">root/</a></li>
<li><a href="run/">run/</a></li>
<li><a href="sbin/">sbin/</a></li>
<li><a href="srv/">srv/</a></li>
<li><a href="sys/">sys/</a></li>
<li><a href="tmp/">tmp/</a></li>
<li><a href="usr/">usr/</a></li>
<li><a href="var/">var/</a></li>
</ul>
<hr>
</body>
</html>
执行 python 图像并验证与自身的连接:
$ kubectl exec -it python-2555691705-5j0f9 bash
root@python-2555691705-5j0f9:/# curl python:12345 --connect-timeout 10
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".dockerenv">.dockerenv</a></li>
<li><a href="bin/">bin/</a></li>
<li><a href="boot/">boot/</a></li>
<li><a href="dev/">dev/</a></li>
<li><a href="etc/">etc/</a></li>
<li><a href="home/">home/</a></li>
<li><a href="lib/">lib/</a></li>
<li><a href="lib64/">lib64/</a></li>
<li><a href="media/">media/</a></li>
<li><a href="mnt/">mnt/</a></li>
<li><a href="opt/">opt/</a></li>
<li><a href="proc/">proc/</a></li>
<li><a href="root/">root/</a></li>
<li><a href="run/">run/</a></li>
<li><a href="sbin/">sbin/</a></li>
<li><a href="srv/">srv/</a></li>
<li><a href="sys/">sys/</a></li>
<li><a href="tmp/">tmp/</a></li>
<li><a href="usr/">usr/</a></li>
<li><a href="var/">var/</a></li>
</ul>
<hr>
</body>
</html>
这是成功的。通过创建 Deployment 和 Service,我可以从集群中的任何其他 Pod 向引用的 Pod 发出请求。
它在较新版本中的工作方式
(停止并删除 运行 Minikube。)
启动 Minikube,指定 Kubernetes 版本 1.7.0:
$ minikube start --kubernetes-version=v1.7.0
Starting local Kubernetes cluster...
Starting VM...
SSH-ing files into VM...
Downloading localkube binary
137.48 MB / 137.48 MB [============================================] 100.00% 0s
Setting up certs...
Starting cluster components...
Connecting to cluster...
Setting up kubeconfig...
Kubectl is now configured to use the cluster.
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"08e099554f3c31f6e6f07b448ab3ed78d0520507", GitTreeState:"clean", BuildDate:"2017-01-12T04:57:25Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"windows/amd64"}
Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-06-30T10:17:58Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
部署最小测试图像(下面的 yaml 定义):
$ kubectl apply -f deploy_python.yaml
service "python" created
deployment "python" created
deployment "python2" created
执行 python 2 图像,并验证与 python 图像的连接:
$ kubectl exec -it python2-380393367-ztgkq bash
root@python2-380393367-ztgkq:/# curl python:12345 --connect-timeout 10
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".dockerenv">.dockerenv</a></li>
<li><a href="bin/">bin/</a></li>
<li><a href="boot/">boot/</a></li>
<li><a href="dev/">dev/</a></li>
<li><a href="etc/">etc/</a></li>
<li><a href="home/">home/</a></li>
<li><a href="lib/">lib/</a></li>
<li><a href="lib64/">lib64/</a></li>
<li><a href="media/">media/</a></li>
<li><a href="mnt/">mnt/</a></li>
<li><a href="opt/">opt/</a></li>
<li><a href="proc/">proc/</a></li>
<li><a href="root/">root/</a></li>
<li><a href="run/">run/</a></li>
<li><a href="sbin/">sbin/</a></li>
<li><a href="srv/">srv/</a></li>
<li><a href="sys/">sys/</a></li>
<li><a href="tmp/">tmp/</a></li>
<li><a href="usr/">usr/</a></li>
<li><a href="var/">var/</a></li>
</ul>
<hr>
</body>
</html>
执行到 python 图像并尝试连接到自身:
$ kubectl exec -it python-2168884431-gls2j bash
root@python-2168884431-gls2j:/# curl python:12345 --connect-timeout 10
curl: (28) Connection timed out after 10000 milliseconds
yaml 文件,deploy_python.yaml:
---
apiVersion: v1
kind: Service
metadata:
name: python
spec:
selector:
app: python
ports:
- port: 12345
targetPort: 12345
name: http
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: python
labels:
app: python
spec:
replicas: 1
template:
metadata:
labels:
app: python
spec:
containers:
- image: python
name: python
command: ["python"]
args: ["-m", "http.server", "12345" ]
ports:
- containerPort: 12345
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: python2
labels:
app: python2
spec:
replicas: 1
template:
metadata:
labels:
app: python2
spec:
containers:
- image: python
name: python2
command: ["python"]
args: ["-m", "http.server", "12345" ]
ports:
- containerPort: 12345
这是较新版本的 kubernetes / minikube 中的一个已知错误,正在此处进行跟踪:
https://github.com/kubernetes/kubernetes/issues/20475
当前接受的解决方法 (https://github.com/kubernetes/kubernetes/issues/20475#issuecomment-190995739) 是通过 ssh 进入您的 minikube 虚拟机和 运行 一个特定的 ip link 命令。
minikube ssh
sudo ip link set docker0 promisc on
我已经测试了这个解决方法,它似乎对我有用。
我有一个 Pod,它偶尔需要通过自己的主机名来调用自己。我有一个 Deployment 设置,最终创建 Pod 和一个 Service。我可以使用集群中不同 Pod 的服务名称,但 Pod 无法使用其主机名调用自身。这适用于 Minikube v0.17.1 和 Kubernetes 版本 1.5.3,但升级 Minikube 或 Kubernetes 版本似乎会破坏事情。这也适用于我们部署的/服务器版本的 Kubernetes。
在我的 Pod/服务设置中是否有我需要考虑的变化?我该如何克服这个问题?
事情应该如何运作
运行 Minikube 版本 0.17.1:
启动 Minikube:
$ minikube start
Starting local Kubernetes cluster...
Starting VM...
SSH-ing files into VM...
Setting up certs...
Starting cluster components...
Connecting to cluster...
Setting up kubeconfig...
Kubectl is now configured to use the cluster.
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"08e099554f3c31f6e6f07b448ab3ed78d0520507", GitTreeState:"clean", BuildDate:"2017-01-12T04:57:25Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"windows/amd64"}
Server Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.3", GitCommit:"029c3a408176b55c30846f0faedf56aae5992e9b", GitTreeState:"clean", BuildDate:"1970-01-01T00:00:00Z", GoVersion:"go1.7.3", Compiler:"gc", Platform:"linux/amd64"}
$ minikube version
minikube version: v0.17.1
部署最小测试图像(下面的 yaml 定义):
kubectl apply -f deploy_python.yaml
执行 python2 图像,并验证与 python 图像的连接:
$ kubectl exec -it python2-1281934109-k015g bash
root@python2-1281934109-k015g:/# curl python:12345 --connect-timeout 10
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".dockerenv">.dockerenv</a></li>
<li><a href="bin/">bin/</a></li>
<li><a href="boot/">boot/</a></li>
<li><a href="dev/">dev/</a></li>
<li><a href="etc/">etc/</a></li>
<li><a href="home/">home/</a></li>
<li><a href="lib/">lib/</a></li>
<li><a href="lib64/">lib64/</a></li>
<li><a href="media/">media/</a></li>
<li><a href="mnt/">mnt/</a></li>
<li><a href="opt/">opt/</a></li>
<li><a href="proc/">proc/</a></li>
<li><a href="root/">root/</a></li>
<li><a href="run/">run/</a></li>
<li><a href="sbin/">sbin/</a></li>
<li><a href="srv/">srv/</a></li>
<li><a href="sys/">sys/</a></li>
<li><a href="tmp/">tmp/</a></li>
<li><a href="usr/">usr/</a></li>
<li><a href="var/">var/</a></li>
</ul>
<hr>
</body>
</html>
执行 python 图像并验证与自身的连接:
$ kubectl exec -it python-2555691705-5j0f9 bash
root@python-2555691705-5j0f9:/# curl python:12345 --connect-timeout 10
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".dockerenv">.dockerenv</a></li>
<li><a href="bin/">bin/</a></li>
<li><a href="boot/">boot/</a></li>
<li><a href="dev/">dev/</a></li>
<li><a href="etc/">etc/</a></li>
<li><a href="home/">home/</a></li>
<li><a href="lib/">lib/</a></li>
<li><a href="lib64/">lib64/</a></li>
<li><a href="media/">media/</a></li>
<li><a href="mnt/">mnt/</a></li>
<li><a href="opt/">opt/</a></li>
<li><a href="proc/">proc/</a></li>
<li><a href="root/">root/</a></li>
<li><a href="run/">run/</a></li>
<li><a href="sbin/">sbin/</a></li>
<li><a href="srv/">srv/</a></li>
<li><a href="sys/">sys/</a></li>
<li><a href="tmp/">tmp/</a></li>
<li><a href="usr/">usr/</a></li>
<li><a href="var/">var/</a></li>
</ul>
<hr>
</body>
</html>
这是成功的。通过创建 Deployment 和 Service,我可以从集群中的任何其他 Pod 向引用的 Pod 发出请求。
它在较新版本中的工作方式
(停止并删除 运行 Minikube。)
启动 Minikube,指定 Kubernetes 版本 1.7.0:
$ minikube start --kubernetes-version=v1.7.0
Starting local Kubernetes cluster...
Starting VM...
SSH-ing files into VM...
Downloading localkube binary
137.48 MB / 137.48 MB [============================================] 100.00% 0s
Setting up certs...
Starting cluster components...
Connecting to cluster...
Setting up kubeconfig...
Kubectl is now configured to use the cluster.
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"08e099554f3c31f6e6f07b448ab3ed78d0520507", GitTreeState:"clean", BuildDate:"2017-01-12T04:57:25Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"windows/amd64"}
Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-06-30T10:17:58Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
部署最小测试图像(下面的 yaml 定义):
$ kubectl apply -f deploy_python.yaml
service "python" created
deployment "python" created
deployment "python2" created
执行 python 2 图像,并验证与 python 图像的连接:
$ kubectl exec -it python2-380393367-ztgkq bash
root@python2-380393367-ztgkq:/# curl python:12345 --connect-timeout 10
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".dockerenv">.dockerenv</a></li>
<li><a href="bin/">bin/</a></li>
<li><a href="boot/">boot/</a></li>
<li><a href="dev/">dev/</a></li>
<li><a href="etc/">etc/</a></li>
<li><a href="home/">home/</a></li>
<li><a href="lib/">lib/</a></li>
<li><a href="lib64/">lib64/</a></li>
<li><a href="media/">media/</a></li>
<li><a href="mnt/">mnt/</a></li>
<li><a href="opt/">opt/</a></li>
<li><a href="proc/">proc/</a></li>
<li><a href="root/">root/</a></li>
<li><a href="run/">run/</a></li>
<li><a href="sbin/">sbin/</a></li>
<li><a href="srv/">srv/</a></li>
<li><a href="sys/">sys/</a></li>
<li><a href="tmp/">tmp/</a></li>
<li><a href="usr/">usr/</a></li>
<li><a href="var/">var/</a></li>
</ul>
<hr>
</body>
</html>
执行到 python 图像并尝试连接到自身:
$ kubectl exec -it python-2168884431-gls2j bash
root@python-2168884431-gls2j:/# curl python:12345 --connect-timeout 10
curl: (28) Connection timed out after 10000 milliseconds
yaml 文件,deploy_python.yaml:
---
apiVersion: v1
kind: Service
metadata:
name: python
spec:
selector:
app: python
ports:
- port: 12345
targetPort: 12345
name: http
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: python
labels:
app: python
spec:
replicas: 1
template:
metadata:
labels:
app: python
spec:
containers:
- image: python
name: python
command: ["python"]
args: ["-m", "http.server", "12345" ]
ports:
- containerPort: 12345
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: python2
labels:
app: python2
spec:
replicas: 1
template:
metadata:
labels:
app: python2
spec:
containers:
- image: python
name: python2
command: ["python"]
args: ["-m", "http.server", "12345" ]
ports:
- containerPort: 12345
这是较新版本的 kubernetes / minikube 中的一个已知错误,正在此处进行跟踪:
https://github.com/kubernetes/kubernetes/issues/20475
当前接受的解决方法 (https://github.com/kubernetes/kubernetes/issues/20475#issuecomment-190995739) 是通过 ssh 进入您的 minikube 虚拟机和 运行 一个特定的 ip link 命令。
minikube ssh
sudo ip link set docker0 promisc on
我已经测试了这个解决方法,它似乎对我有用。