从 pod minikube kubernetes 中的容器公开端口
Expose port from container in a pod minikube kubernetes
我是 K8s 的新手,我将使用以下命令在 pod 中尝试使用 2 个容器 运行 的 minikube:
kubectl apply -f deployment.yaml
和这个 deployment.yml:
apiVersion: v1
kind: Pod
metadata:
name: site-home
spec:
restartPolicy: Never
volumes:
- name: v-site-home
emptyDir: {}
containers:
- name: site-web
image: site-home:1.0.0
ports:
- containerPort: 80
volumeMounts:
- name: v-site-home
mountPath: /usr/share/nginx/html/assets/quotaLago
- name: site-cron
image: site-home-cron:1.0.0
volumeMounts:
- name: v-site-home
mountPath: /app/quotaLago
我有一个共享卷,所以如果我明白我不能使用部署,只能使用 pods(也许是状态集?)
无论如何,我想从 pod site-home 中的容器 site-web 公开端口 80。
在官方文档中,我看到了这个部署:
kubectl expose deployment hello-node --type=LoadBalancer --port=8080
但我不能使用例如:
kubectl expose pod site-web --type=LoadBalancer --port=8080
有什么想法吗?
but I cannot use for example:
kubectl expose pod site-web --type=LoadBalancer --port=8080
当然可以,但是通过 LoadBalancer
Service
公开单个 Pod
没有多大意义。如果您有一个 Deployment
,它通常管理一组 Pods
,在这组 Pods
之间可以平衡实际负载,那么 LoadBalancer
就可以完成它的工作。但是,您仍然可以仅将其用于公开单个 Pod
.
请注意,您的容器公开端口 80
,而不是 8080
(container
规范中的 containerPort: 80
),因此您需要将其指定为 target-port
在你的Service
。您的 kubectl expose
命令可能如下所示:
kubectl expose pod site-web --type=LoadBalancer --port=8080 --target-port=80
如果您只向 kubectl expose
命令提供 --port=8080
标志,它会假定 target-port
的值与 --port
的值相同。您可以通过查看刚刚创建的服务轻松地自行检查它:
kubectl get svc site-web -o yaml
你会在 spec.ports
部分看到类似的内容:
- nodePort: 32576
port: 8080
protocol: TCP
targetPort: 8080
正确暴露你的Pod
(或Deployment
)后,即使用:
kubectl expose pod site-web --type=LoadBalancer --port=8080 --target-port=80
你会看到类似的东西:
- nodePort: 31181
port: 8080
protocol: TCP
targetPort: 80
发出 kubectl get services
后,您应该会看到类似的输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
site-web ClusterIP <Cluster IP> <External IP> 8080:31188/TCP 4m42s
如果您在浏览器中转到 http://<External IP>:8080
或 运行 curl http://<External IP>:8080
,您应该会看到您网站的前端。
请记住,此解决方案很有意义,并且可以在能够为您提供真正的负载平衡器的云环境中完全发挥作用。请注意,如果您在 Minikukbe 中声明此类 Service
类型,实际上它会创建 NodePort 服务,因为它无法为您提供真正的负载均衡器。因此,您的应用程序将在 30000-32767
范围内的随机 selected 端口上的节点(您的 Minikube VM)的 IP 地址上可用(在我的示例中,它是端口 31181
)。
关于您关于音量的问题:
I've a shared volume so if I understand I cannot use deployment but
only pods (maybe stateful set?)
是的,如果你想专门使用 EmptyDir volume, it cannot be shared between different Pods
(even if they were scheduled on the same node), it is shared only between containers within the same Pod
. If you want to use Deployment
you'll need to think about another storage solution such as PersistenetVolume。
编辑:
第一时间我没有注意到你命令中的错误:
kubectl expose pod site-web --type=LoadBalancer --port=8080
您试图公开不存在的 Pod
,因为您的 Pod
的名字是 site-home
,而不是 site-web
。 site-web
是您的其中一个容器的名称(在您的 site-home
Pod
中)。请记住:我们通过 Service
.
公开 Pod
,而不是 containers
I change 80->8080 but I always come to error:kubectl expose pod
site-home --type=LoadBalancer --port=8080 return:error: couldn't
retrieve selectors via --selector flag or introspection: the pod has
no labels and cannot be exposed
See 'kubectl expose -h'
for help
and examples.
这里的重点是:the pod has no labels and cannot be exposed
您的 Pod
似乎没有任何 labels
定义,因此 Service
可以 select 这个特定的 Pod
(或集群中其他 Pods
中具有相同标签的相似 Pods
的集合。您的 Pod
定义中至少需要一个标签。在 Pod
的 metadata
部分下添加简单标签 name: site-web
应该会有所帮助。它在您的 Pod
定义中可能看起来像这样:
apiVersion: v1
kind: Pod
metadata:
name: site-home
labels:
name: site-web
spec:
...
现在您甚至可以将此标签作为 select 或在您的服务中提供,但是如果您省略 --selector
标志,它应该会自动处理:
kubectl expose pod site-home --type=LoadBalancer --port=8080 --target-port=80 --selector=name=site-web
记住: 在 Minikube 中无法创建真正的负载均衡器,而不是 LoadBalancer
NodePort
类型将被创建。命令 kubectl get svc
将告诉您您的应用程序将在哪个端口(范围 30000-32767
)上可用。
and `kubectl expose pod site-web --type=LoadBalancer
--port=8080 return: Error from server (NotFound): pods "site-web" not found. Site-home is the pod, site-web is the container with the port
exposed, what's the issue?
如果您没有名称为 "site-web"
的 Pod
,您会收到这样的消息。在这里,您只是想暴露不存在的 Pod
.
If I exposed a port from a container the port is automatically exposed
also for the pod ?
是的,您在容器定义中定义了端口。您的 Pods
会自动公开其中 Containers
公开的所有端口。
我是 K8s 的新手,我将使用以下命令在 pod 中尝试使用 2 个容器 运行 的 minikube:
kubectl apply -f deployment.yaml
和这个 deployment.yml:
apiVersion: v1
kind: Pod
metadata:
name: site-home
spec:
restartPolicy: Never
volumes:
- name: v-site-home
emptyDir: {}
containers:
- name: site-web
image: site-home:1.0.0
ports:
- containerPort: 80
volumeMounts:
- name: v-site-home
mountPath: /usr/share/nginx/html/assets/quotaLago
- name: site-cron
image: site-home-cron:1.0.0
volumeMounts:
- name: v-site-home
mountPath: /app/quotaLago
我有一个共享卷,所以如果我明白我不能使用部署,只能使用 pods(也许是状态集?)
无论如何,我想从 pod site-home 中的容器 site-web 公开端口 80。 在官方文档中,我看到了这个部署:
kubectl expose deployment hello-node --type=LoadBalancer --port=8080
但我不能使用例如:
kubectl expose pod site-web --type=LoadBalancer --port=8080
有什么想法吗?
but I cannot use for example:
kubectl expose pod site-web --type=LoadBalancer --port=8080
当然可以,但是通过 LoadBalancer
Service
公开单个 Pod
没有多大意义。如果您有一个 Deployment
,它通常管理一组 Pods
,在这组 Pods
之间可以平衡实际负载,那么 LoadBalancer
就可以完成它的工作。但是,您仍然可以仅将其用于公开单个 Pod
.
请注意,您的容器公开端口 80
,而不是 8080
(container
规范中的 containerPort: 80
),因此您需要将其指定为 target-port
在你的Service
。您的 kubectl expose
命令可能如下所示:
kubectl expose pod site-web --type=LoadBalancer --port=8080 --target-port=80
如果您只向 kubectl expose
命令提供 --port=8080
标志,它会假定 target-port
的值与 --port
的值相同。您可以通过查看刚刚创建的服务轻松地自行检查它:
kubectl get svc site-web -o yaml
你会在 spec.ports
部分看到类似的内容:
- nodePort: 32576
port: 8080
protocol: TCP
targetPort: 8080
正确暴露你的Pod
(或Deployment
)后,即使用:
kubectl expose pod site-web --type=LoadBalancer --port=8080 --target-port=80
你会看到类似的东西:
- nodePort: 31181
port: 8080
protocol: TCP
targetPort: 80
发出 kubectl get services
后,您应该会看到类似的输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
site-web ClusterIP <Cluster IP> <External IP> 8080:31188/TCP 4m42s
如果您在浏览器中转到 http://<External IP>:8080
或 运行 curl http://<External IP>:8080
,您应该会看到您网站的前端。
请记住,此解决方案很有意义,并且可以在能够为您提供真正的负载平衡器的云环境中完全发挥作用。请注意,如果您在 Minikukbe 中声明此类 Service
类型,实际上它会创建 NodePort 服务,因为它无法为您提供真正的负载均衡器。因此,您的应用程序将在 30000-32767
范围内的随机 selected 端口上的节点(您的 Minikube VM)的 IP 地址上可用(在我的示例中,它是端口 31181
)。
关于您关于音量的问题:
I've a shared volume so if I understand I cannot use deployment but only pods (maybe stateful set?)
是的,如果你想专门使用 EmptyDir volume, it cannot be shared between different Pods
(even if they were scheduled on the same node), it is shared only between containers within the same Pod
. If you want to use Deployment
you'll need to think about another storage solution such as PersistenetVolume。
编辑:
第一时间我没有注意到你命令中的错误:
kubectl expose pod site-web --type=LoadBalancer --port=8080
您试图公开不存在的 Pod
,因为您的 Pod
的名字是 site-home
,而不是 site-web
。 site-web
是您的其中一个容器的名称(在您的 site-home
Pod
中)。请记住:我们通过 Service
.
Pod
,而不是 containers
I change 80->8080 but I always come to
error:kubectl expose pod site-home --type=LoadBalancer --port=8080 return:error: couldn't retrieve selectors via --selector flag or introspection: the pod has no labels and cannot be exposed
See'kubectl expose -h'
for help and examples.
这里的重点是:the pod has no labels and cannot be exposed
您的 Pod
似乎没有任何 labels
定义,因此 Service
可以 select 这个特定的 Pod
(或集群中其他 Pods
中具有相同标签的相似 Pods
的集合。您的 Pod
定义中至少需要一个标签。在 Pod
的 metadata
部分下添加简单标签 name: site-web
应该会有所帮助。它在您的 Pod
定义中可能看起来像这样:
apiVersion: v1
kind: Pod
metadata:
name: site-home
labels:
name: site-web
spec:
...
现在您甚至可以将此标签作为 select 或在您的服务中提供,但是如果您省略 --selector
标志,它应该会自动处理:
kubectl expose pod site-home --type=LoadBalancer --port=8080 --target-port=80 --selector=name=site-web
记住: 在 Minikube 中无法创建真正的负载均衡器,而不是 LoadBalancer
NodePort
类型将被创建。命令 kubectl get svc
将告诉您您的应用程序将在哪个端口(范围 30000-32767
)上可用。
and `kubectl expose pod site-web --type=LoadBalancer --port=8080 return: Error from server (NotFound): pods "site-web" not found. Site-home is the pod, site-web is the container with the port exposed, what's the issue?
如果您没有名称为 "site-web"
的 Pod
,您会收到这样的消息。在这里,您只是想暴露不存在的 Pod
.
If I exposed a port from a container the port is automatically exposed also for the pod ?
是的,您在容器定义中定义了端口。您的 Pods
会自动公开其中 Containers
公开的所有端口。