Skip to content

Latest commit

 

History

History
151 lines (131 loc) · 4.57 KB

File metadata and controls

151 lines (131 loc) · 4.57 KB

k8s的Service、DNS与服务发现

kubernetes之所以需要service

  • Pod的IP不固定
  • 一组Pod实例之间负载均衡的需求
apiVersion: v1
kind: Service
metadata:
  name: hostnames
spec:
  selector:
    app: hostnames
  ports:
  - name: default
    protocol: TCP
    port: 80
    targetPort: 9376

这个 Service 的 80 端口,代理的是 Pod 的 9376 端口

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hostnames
spec:
  selector:
    matchLabels:
      app: hostnames
  replicas: 3
  template:
    metadata:
      labels:
        app: hostnames
    spec:
      containers:
      - name: hostnames
        image: k8s.gcr.io/serve_hostname
        ports:
        - containerPort: 9376
          protocol: TCP

这个应用的作用,就是每次访问 9376 端口时,返回它自己的 hostname。

Service 是由kube-proxy组件,加上iptables共同实现的

举个例子,对于我们前面创建的名叫 hostnames 的 Service 来说,一旦它被提交给 Kubernetes,那么 kube-proxy 就可以通过 Service 的 Informer 感知到这样一个 Service 对象的添加。而作为对这个事件的响应,它就会在宿主机上创建这样一条 iptables 规则(你可以通过 iptables-save 看到它)

在大规模集群里,我非常建议你为 kube-proxy 设置–proxy-mode=ipvs 来开启这个功能。它为 Kubernetes 集群规模带来的提升,还是非常巨大的。

外界连通Service

如何从外部(Kubernetes 集群之外),访问到 Kubernetes 里创建的 Service

最常用的是NodePort

apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  type: NodePort
  ports:
  - nodePort: 8080 #外部访问
    targetPort: 80
    protocol: TCP
    name: http
  - nodePort: 443 #外部访问
    protocol: TCP
    name: https
  selector:
    run: my-nginx

如果你不显式地声明 nodePort 字段,Kubernetes 就会为你分配随机的可用端口来设置代理

在nodePort模式下,关于端口的有三个参数,port, nodePort, targetPort。 如果如下定义,(请张老师指出是否有理解偏差)

spec:
  type: NodePort
  ports:
    - name: http
      port: 8080 # 集群内访问端口
      nodePort: 30080 # 集群外访问
      targetPort: 80 # 代理的Pod的端口
      protocol: TCP

则svc信息如下,(注意下面无targetPort信息,只是ClustorPort与NodePort,注意后者为Nodeport) ingress-nginx ingress-nginx NodePort 10.105.192.34 8080:30080/TCP,8443:30443/TCP 28m

则可访问的组合为

  1. clusterIP + port: 10.105.192.34:8080
  2. 内网IP/公网ip + nodePort: 172.31.14.16:30080。(172.31.14.16我的aws局域网ip.)

30080为nodePort也可以在iptables-save中映证。 还有,就是port参数是必要指定的,nodePort即使是显式指定,也必须是在指定范围内。

(在三板斧中也问过张老师如何使用nodePort打通外网的问题,一并谢谢了)

Service与Ingress

暴露服务的三种方式

  • NodePort

将服务的类型设置成NodePort-每个集群节点都会在节点上打 开 一 个端口, 对于NodePort服务, 每个集群节点在节点本身(因此得名叫 NodePort)上打开一个端口,并将在该端口上接收到的流量重定向到基础服务。 该服务仅在内部集群 IP 和端口上才可访间, 但也可通过所有节点上的专用端 口访问。

  • LoadBalane

将服务的类型设置成LoadBalance, NodePort类型的一 种扩展,这使得 服务可以通过一个专用的负载均衡器来访问, 这是由Kubernetes中正在运行 的云基础设施提供的。 负载均衡器将流量重定向到跨所有节点的节点端口。 客户端通过负载均衡器的 IP 连接到服务。

  • Ingress

创建一 个Ingress资源, 这是一 个完全不同的机制, 通过一 个IP地址公开多 个服务,就是一个网关入口,和springcloud的网关zuul、gateway类似.

Ingress

全局的、为了代理不同后端 Service 而设置的负载均衡服务,就是 Kubernetes 里的 Ingress 服务。

Ingress 的功能其实很容易理解:所谓 Ingress,就是 Service 的“Service”

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress
spec:
  tls:
  - hosts:
    - cafe.example.com
    secretName: cafe-secret
  rules:
  - host: cafe.example.com
    http:
      paths:
      - path: /tea
        backend:
          serviceName: tea-svc
          servicePort: 80
      - path: /coffee
        backend:
          serviceName: coffee-svc
          servicePort: 80