kubernetes -- helm charts 开发: 12、详解提供外部访问的node port


1 kubernetes中的service


1.1 基础


含义: Service就是微服务,其他通过这个入口地址访问起背后的一组由Pod副本组成的集群实例。
原理: Service与其后端Pod副本集群之间通过Label Selector来实现无缝对接。服务之间通过
      TCP/IP通信。
与Pod关系: 每个Pod提供独立的Endpoint(Pod IP + ContainerPort)被访问,多个Pod副本组成一个集群来提供服务。
客户端:部署一个负载均衡器,为这组Pod开启一个对外的服务端口如8000端口,并将这些Pod的Endpoint列表加入到8000端口的转发列表中。通过负载均衡器的对外IP地址+服务端口访问此服务。
k8s的负载均衡器: 运行在每个Node上的kube-proxy进程是如那件副在均衡器,把
service ip: service创建就会被分配一个Cluster IP且不会改变。

1.2 Service写法

{{- if .Values.manifests.service_api }}
{{- $envAll := . }}
---
apiVersion: v1
kind: Service
metadata:
  name: {{ tuple "metering" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
spec:
  ports:
    - name: ce-api
      port: {{ .Values.network.api.port }}
    {{ if .Values.network.api.node_port.enabled }}
      nodePort: {{ .Values.network.api.node_port.port }}
    {{ end }}
  selector:
{{ tuple $envAll "ceilometer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
  {{ if .Values.network.api.node_port.enabled }}
  type: NodePort
  {{ end }}
{{- end }}


实际运行后的结果:
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2019-02-17T02:57:09Z
  name: ceilometer-api
  namespace: openstack
  resourceVersion: "4735"
  selfLink: /api/v1/namespaces/openstack/services/ceilometer-api
  uid: b78321c0-325f-11e9-9cf9-fa163e9d7468
spec:
  clusterIP: 10.233.9.63
  ports:
  - name: ce-api
    port: 8777       # 定义了Service的虚端口
    nodePort: 30777   # 注意: node port在30000-32767左右的范围,如果不在这个范围,会出错
    protocol: TCP
    targetPort: 8777  # targetPort提供改服务的容器所暴露的端口号,即具体业务进程在容器内的targetPory上提供TCP/IP接入,若没有指定targetPort,则targetPort和port相同

  selector:           # 指定拥有何种标签的pod实例属于这个service
    application: ceilometer
    component: api
    release_group: ceilometer
  sessionAffinity: None
  type: ClusterIP     #是虚拟IP,仅仅用于k8s Service这个对象,不能被Ping,是集群内部地址,无法在集群外部使用
status:
  loadBalancer: {}

分析:
targetPort: 提供改服务的容器所暴露的端口号,即具体业务进程在容器内的targetPory上提供TCP/IP接入,若没有指定targetPort,则targetPort和port相同
ClusterIP: 是虚拟IP,仅仅用于k8s Service这个对象,不能被Ping,是集群内部地址,无法在集群外部使用

2 kubernetes中的NodePort


2.1 NodePort基础 


问题: 一部分服务提供给k8s集群外部用户使用,用户如何访问?
作用: 采用NodePort,在Service定义做扩展即可。
样例:
apiVersion: v1
kind: Service
metadata:
  name: xxx
spec:
  type: NodePort
  ports:
    -port: 8080
     nodePort: 31002
selector:
  tier: frontend

其中nodePort:31002表明可以手动指定tomcat-service的NodePort为31002,
否则k8s会自动分配一个可用的端口。

2.2 NodePort原理


在k8s集群中的每个Node上为需要外部访问的Service开启一个对应的TCP监听端口,
外部系统只要用任意一个Node的IP地址+具体的NodePort端口号,即可访问此服务。
在任意Node上运行netstat命令,可以看到有NodePort端口被监听。
netstat -tlp|grep

但NodePort还没有完全解决外部访问Service的问题,比如负载均衡问题,
此时最好有一个负载均衡器,外部请求只需访问此负载均衡器的IP地址,
由负载均衡器负责转发到后面某个Node的NodePort上。

3 集群外部访问Pod或Service


Pod和Service是k8s自己的虚拟概念,集群外的客户无法访问到。
可以将Pod或Service的端口号映射到宿主机。
将Service的端口号映射到物理机,并设置Service的类型为NodePort。
注意:
由于要使用物理机的端口号,所以需要在防火墙上做好相应的配置,以使得
外部客户端能够访问该端口。

验证:
通过物理机的IP地址和nodePory端口访问服务:
curl :

因此还是访问的是服务。
对该服务的访问也将被负载分发到后端的多个Pod上。

4 Ingress


HTTP 7层路由机制。
Service的表现形式是: IP:Port。
即工作在TCP/IP层。
对基于HTTP的服务来说。
不同URL对应到不同后端服务或者虚拟服务器。
Ingress作用: 将不同URL的访问请求转发到后端不同的Service.
组成: k8s使用Ingress策略定义和具体的Ingress Controller。
原理: Ingress Controller基于Ingress规则将客户端请求直接转发到Service
    对应的后端Endpoint(即Pod)上。跳过kube-proxy功能
例子:
对 http://mywebsite.com/api的访问将被路由到后端名为 api的Service
对 http://mywebsite.com/web的访问将被路由到后端名为 web的Service
对 http://mywebsite.com/doc的访问将被路由到后端名为 doc的Service

5 总结


1) 为了实现k8s中的service被外部所能访问,可以通过添加node port来将用户访问该:的请求
通过iptables规则转发:,即转发到某个节点的端口上,然后利用node port本身的特性
转发到该节点上暴露该node port的容器服务中。
2) 一旦为service开启node port,则每个包含该service的节点上都会有该开启的node port。
3) 但是node port只是将请求转发到某一个node上的服务中,不能保证高可用。

参考:
kubernetes权威指南:从docker到kubernetes实践纪念版
 

你可能感兴趣的:(kubernetes)