Kubernetes中外部客户端访问Pod的⼏种⽅式
kubernetes集上运⾏的pod,在集内访问是很容易的,最简单的,可以通过pod的ip来访问,也可以通过对应的svc来访问,但在集外,由于kubernetes集的pod ip地址是内部⽹络地址,因此从集外是访问不到的。
为了解决这个问题,kubernetes提供了如下⼏个⽅法。
hostNetwork
hostPort
service NodePort
hostNetwork: true
hostNetwork为true时,容器将使⽤宿主机node的⽹络,因此,只要知道容器在哪个node上运⾏,从集外以 node-ip + port 的⽅式就可以访问容器的服务。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
hostNetwork: true
containers:
- name: nginx
image: nginx
pod启动后,如下,可以看到pod的ip地址与node节点的地址是⼀致的
[root@localhost ~]# kubectl get pods -o wide nginx
NAME    READY  STATUS    RESTARTS  AGE    IP              NODE      NOMINATED NODE
nginx  1/1    Running  0          8m2s  192.168.10.10  minikube  <none>
[root@localhost ~]# kubectl get nodes -o wide
NAME      STATUS  ROLES    AGE  VERSION  INTERNAL-IP    EXTERNAL-IP  OS-IMAGE                KERNEL-VERSION          CONTAINER-RUNTIME minikube  Ready    master  11d  v1.12.1192.168.10.10  <none>        CentOS Linux 7 (Core)  3.10.0-957.el7.x86_64  docker://17.12.1-ce
可以通过curl或者浏览器直接访问node节点的地址,即可以访问到nginx的服务
[root@localhost ~]# curl 192.168.10.10
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
.
.....
</html>
[root@localhost ~]#
hostNetwork的优点是直接使⽤宿主机的⽹络,只要宿主机能访问,Pod就可以访问;但缺点也是很明显的:
易⽤性:Pod漂移到其他node上,访问时需要更换ip地址。解决⽅法是将Pod绑定在某⼏个node上,并在这⼏个node上运⾏
keepalived以漂移vip,从⽽客户端可以使⽤vip+port的⽅式来访问。
易⽤性:Pod间可能出现端⼝冲突,造成Pod⽆法调度成功。
安全性:Pod可以直接观察到宿主机的⽹络。
hostPort
hostPort的效果与hostNetwork类似,hostPort是直接将容器的端⼝与所调度的节点上的端⼝进⾏映射,
这样⽤户就可以通过宿主机的IP加上映射到绑定主机的端⼝来访问Pod了
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80    #pod容器指定的端⼝
hostPort: 9090        #映射到node主机的端⼝
pod启动后如下,可以看到,pod的ip地址是内部⽹络ip,与宿主机node的ip不同;与hostNetwork⼀样,也可以通过node ip + pod port访问,此处的访问port地址为,pod容器端⼝映射到node主机的端⼝地址
[root@localhost ~]# kubectl get pods -o wide nginx
NAME    READY  STATUS    RESTARTS  AGE  IP          NODE      NOMINATED NODE
nginx  1/1    Running  0          57s  172.17.0.2  minikube  <none>
[root@localhost ~]#
可以curl访问,也可以浏览器访问
[root@localhost ~]# curl -I 192.168.10.10:9090
HTTP/1.1200 OK
Server: nginx/1.19.2
Date: Tue, 01 Sep 202009:56:16 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 11 Aug 202014:50:35 GMT
Connection: keep-alive
ETag: "5f32b03b-264"
Accept-Ranges: bytes
[root@localhost ~]#
hostPort的优缺点与hostNetwork类似,因为它们都是使⽤了宿主机的⽹络资源。hostPort相对hostNetwork的⼀个优点是,hostPort不需要提供宿主机的⽹络信息,但其性能不如hostNetwork,因为需要经过iptables的转发才能到达Pod。
service NodePort
与hostPort、hostNetwork只是Pod的配置不同,NodePort是⼀种service,其使⽤的是宿主机node上的
端⼝号,从集外以任意node的ip + nodePort 来访问Pod的服务。
NodePort 在 kubenretes ⾥是⼀个⼴泛应⽤的服务暴露⽅式。Kubernetes中的service默认情况下都是使⽤的ClusterIP这种类型,这样的service会产⽣⼀个ClusterIP,这个IP只能在集内部访问,要想让外部能够直接访问service,需要将service type修改为 nodePort。apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx
spec:
type: NodePort
ports:
-
name: nginx
port: 80
nodePort: 30000
selector:
name: nginx
svc 配置中的nodePort,即为访问服务时,宿主机的端⼝号。可以在配置⽂件中指定(当然不能与其他nodePort类型的svc冲突),也可以不配置,由k8s来分配。
创建上述Pod和service后,如下,查看pod和svc的相关信息,我们可以通过宿主机的ip地址+noePort来访问pod的服务
[root@localhost ~]# kubectl get pods -o wide nginx
NAME    READY  STATUS    RESTARTS  AGE    IP          NODE      NOMINATED NODE
nginx  1/1    Running  0          5m47s  172.17.0.2  minikube  <none>
[root@localhost ~]#
[root@localhost ~]# kubectl get svc -o wide nginx
NAME    TYPE      CLUSTER-IP      EXTERNAL-IP  PORT(S)        AGE    SELECTOR
nginx  NodePort  10.96.116.150  <none>        80:30000/TCP  5m58s  name=nginx
[root@localhost ~]#
nodeselector[root@localhost ~]# kubectl get nodes -o wide
NAME      STATUS  ROLES    AGE  VERSION  INTERNAL-IP    EXTERNAL-IP  OS-IMAGE                KERNEL-VERSION          CONTAINER-RUNTIME minikube  Ready    master  11d  v1.12.1192.168.10.10  <none>        CentOS Linux 7 (Core)  3.10.0-957.el7.x86_64  docker://17.12.1-ce
[root@localhost ~]#
[root@localhost ~]# curl -I 192.168.10.10:30000
HTTP/1.1200 OK
Server: nginx/1.19.2
Date: Tue, 01 Sep 202010:14:12 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 11 Aug 202014:50:35 GMT
Connection: keep-alive
ETag: "5f32b03b-264"
Accept-Ranges: bytes
[root@localhost ~]#
集外就可以使⽤kubernetes任意⼀个节点的IP加上30000端⼝访问该服务了。kube-proxy会⾃动将流量以round-robin的⽅式转发给该service的每⼀个pod。
这种服务暴露⽅式,⽆法让你指定⾃⼰想要的应⽤常⽤端⼝,不过可以在集上再部署⼀个反向代理作为流量⼊⼝
service的作⽤体现在两个⽅⾯,对集内部,它不断跟踪pod的变化,更新endpoint中对应pod的对象,提供了ip不断变化的pod的服务发现机制,对集外部,他类似负载均衡器,可以在集内外部对pod进⾏访问。但是,单独⽤service暴露服务的⽅式,在实际⽣产环境中不太合适:
ClusterIP的⽅式只能在集内部访问。
NodePort⽅式的话,测试环境使⽤还⾏,当有⼏⼗上百的服务在集中运⾏时,NodePort的端⼝管理是灾难。
LoadBalance⽅式受限于云平台,且通常在云平台部署ELB还需要额外的费⽤。
————————————————
LoadBalancer、Ingress可以实现pod的外⽹访问,后续在做整理...

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。