如果读者按照前面的流程建好了服务,那么应该会有一个问题困扰,如何访问这个nginx服务呢?
首先查看服务的信息,执行命令kubectl describe pods static-web
Name: static-web
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: ip/ip
Start Time: Fri, 15 Jan 2021 15:50:16 +0800
Labels: role=myrole
Annotations: kubectl.kubernetes.io/
Status: Running
IP: ip
这里有两个ip
。一个是Node
的ip
,一个是自己的IP
。从我们之前的构建文件来看,暴露的端口是80
,所以我们用curl
来试试。
先使用Node
的ip
。你会发现,访问失败了。
再使用IP
,你会发现访问成功了。
换一个场景来看,我们使用集群外部的机器来访问,你会发现,两个IP都无法访问。
这就是一个非常蛋疼的点了。集群内部,可以正常访问,集群外部,无法访问。
但是我们很多时候,是需要在集群外部访问我们的服务。
常规的来说,外部访问k8s的流程是,请求到k8s
的service
或者,然后节点转发给Pods
。
为什么这么设计呢,官方的说法是:
创建和销毁 Kubernetes Pod 以匹配集群状态。 Pod 是非永久性资源。 如果你使用 Deployment 来运行你的应用程序,则它可以动态创建和销毁 Pod。 每个 Pod 都有自己的 IP 地址,但是在 Deployment 中,在同一时刻运行的 Pod 集合可能与稍后运行该应用程序的 Pod 集合不同。
这导致了一个问题: 如果一组 Pod(称为“后端”)为集群内的其他 Pod(称为“前端”)提供功能, 那么前端如何找出并跟踪要连接的 IP 地址,以便前端可以使用工作量的后端部分?
进入 Services。
所以想要外部来访问,我们就需要创建一个service
。
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
role: myrole
spec:
ports:
- name: nginx
port: 80
targetPort: 80
nodePort: 30002
selector:
role: myrole
type: NodePort
在客户端执行kubectl apply -f nginx-service.yaml
执行完毕后,就会创建一个service
,这个service
有一个selector
,通过selector
绑定标签为role: myrole
。然后指定nodePort
端口是30002
,表示node
对外暴露的端口是30002
,targetPort
是80
,表示30002
端口收到请求之后,把请求转发到绑定的Pods
的80
端口。
执行命令:kubectl get services
,可以看到这样的输出:
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort ip <none> 80:30002/TCP 3h7m
表示这个service
已经建立好了,并且80
端口和30002
端口做了映射。
这个时候,我们在集群外部再来请求,这个时候请求的是Node
的IP
和30002
端口。你会发现,请求成功了,返回了Nginx
的欢迎页面的html
代码
为了更方便的理解,我们这里还是以docker
对照来说明。
一开始,我们使用k8s创建一个nginx
服务,就类似用docker
起一个nginx
容器,正常起的nginx
容器,由于没有做端口映射,就会出现服务提供了80
端口,容器内部curl
是能正常访问的,但是外部无法访问的情况。
对于docker
来说,我们不需要创建service
,而是在启动容器的时候,使用-p 8000:80
参数,则会把宿主机的8000
端口映射到容器的80
端口。
同理,k8s
中的service
也提供了这样类似的功能(当然,service
提供的功能不止这些)。
当然,由于nginx
使用的http
是七层协议,还可以使用Ingress
来实现类似的功能。后续再来描述这块功能。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。