前面介绍了在k8s集群内部访问Service,但是在真实的应用场景中,我们是需要外部也能访问。对于此:k8s 提供了多种类型的Service,默认是ClusterIP。这里,在介绍两种可以外部访问service的方式。
NodePort
创建namespace:ns-nginx.yml 内容如下:
apiVersion: v1
kind: Namespace
metadata:
name: ns-nginx
labels:
name: ns-nginx
创建我们的应用:nginx.yml 内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment1
namespace: ns-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-demo
image: nginx:1.14.0
ports:
- containerPort: 80
image.png
创建我们的service:svc-nginx.yml 内容如下:
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: ns-nginx
labels:
app: nginx
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
app: nginx
image.png
k8s 依然会给 svc-nginx 分配一个ClusterIP,不同的是PORT(s) 为 80:30226,80 是ClusterIP 监听的端口,而30226 则是节点上监听的端口。k8s 会从30000-32767 中分配一个可用的端口,每个节点都会监听此端口然后将请求转发给Service。
curl 节点的 192.168.48.20:30226 成功,说明NodePort 工作正常。
我们来探究下k8s是如何将 <NodeIP>:<NodePort> 映射至Pod中的呢?
与ClusterIP 一样,也是借助了 iptables,与 ClusterIP 相比:每个节点的iptables 中都增加了如下规则:
-A KUBE-NODEPORTS -p tcp -m comment --comment "ns-nginx/svc-nginx" -m tcp --dport 30226 -j KUBE-EXT-S6ZOMIZSEZAENALW
:KUBE-EXT-S6ZOMIZSEZAENALW - [0:0]
-A KUBE-EXT-S6ZOMIZSEZAENALW -m comment --comment "masquerade traffic for ns-nginx/svc-nginx external destinations" -j KUBE-MARK-MASQ
-A KUBE-EXT-S6ZOMIZSEZAENALW -j KUBE-SVC-S6ZOMIZSEZAENALW
规则的含义是:访问当前节点的30226端口请求会应用 KUBE-EXT-S6ZOMIZSEZAENALW 规则, KUBE-EXT-S6ZOMIZSEZAENALW 规则在前面已经解析过了。这样就完成了,整个负载均衡过程。
LoadBalancer
TODO
网友评论