k8s学习(六)-- 服务发现

学习目标:掌握svc原理及其构建方式

一、service概念

  A、kubernetes定义了这样一种抽象:一个pod的逻辑分组,一种可以访问他们的策略---通常称为微服务。这一组pod能够被service访问到,通常是通过Label Selector

 

  B、service提供负载均衡的能力,但是使用上有以下限制:

    1. 只提供4层负载均衡能力,而没有7层,但是有时我们需要更多的匹配规则来转发请求,这点上4层负载均衡是不支持的。

  C、类型

    1. ClusterIp:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP

    2. NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样可以通过 NodeIP:NodePort来访问该服务。

    3. LoadBalancer: 在NodePort基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到NodeIp:NodePort

    4. ExternalName: 把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有kubernetes 1.7或更高版本才支持

  D、架构图

    

 

二、VIP和Service代理

  A、在Kubernetes集群中,每个Node运行一个kube-proxy进程。kube-proxy负责为service实现一种vip形式,而不是externalName的形式。在kubernetes v1.0版本中,代理完全在userspace。在kubernetes v1.1版本中,新增了iptables代理,但并不是默认的运行模式。从kubernetes v1.2版本起,默认就是iptables代理。在kubernetes v1.8.0-beta.0中,添加了ipvs代理。在kubernetes v1.14版本开始默认使用ipvs代理。在kubernetes  v1.0版本,service是“4层”(TCP/UDP)概念。在kubernetes v1.1版本,新增了ingress API(beta版),用来表示“7层”(HTTP)服务。

三、ClusterIP

  A、clusterIP主要在每个node节点使用iptables,将发向clusterIP对应端口的数据,转发到kube-proxy中。然后kube-proxy自己内部实现有负载均衡的方法,并且可以查询到这个service下对应pod的地址和端口,进而把数据转发给对应pod的地址和窗口

  B、工作流程

    1. apiserver:用户通过kubectl命令向apiserver发送创建service的命令,apiserver接收到请求后将数据存储在etcd中

    2. kube-proxy:kubernetes的每个节点中都有一个叫做kube-proxy的进程,这个进程负责感知service和pod的变化,将变化的信息写入本地的iptables

    3. iptables:使用NAT等技术将virtualIP的流量转至endpoint中

  C、例子

    1. 创建deployment

      apiVersion: extensions/v1beta1
      kind: Deployment
      metadata:
        name: myapp-deploy
        namespace: default
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: myapp
            release: stable
        template:
          metadata:
            labels:
              app: myapp
              release: stable
              env: test
          spec:
            containers:
            - name: myapp
              image: hub.atguigu.com/library/myapp:v1
              imagePullPolicy: IfNotPresent
              ports:
              - name: http
                containerPort: 80

    2. 创建service

      apiVersion: v1
      kind: Service
      metadata:
        name: myapp
        namespace: default
      spec:
        type: ClusterIP
        selector:
          app: myapp
          release: stable
        ports:
        - name: http
          port: 80
          targetPort: 80

四、Headless Server

  A、有时不需要或者不想要负载均衡,以及单独的service IP。遇到这种情况,可以通过指定Cluster IP(spec.clusterIP)的值为“None”来创建Headless Service。这类service并不会分配cluster IP,kube-proxy不会处理它们,而且平台也不会为它们进行负载均衡和路由。

  B、例子

  apiVersion: v1
  kind: Service
  metadata:
    name: myapp-headless
    namespace: default
  spec:
    selector:
      app: myapp
    clusterIP: "None"
    ports:
    - port: 80
      targetPort: 80

五、NodePort

  A、NodePort的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy,然后由kube-proxy进一步给到对应的pod

  B、 例子 

  apiVersion: v1
  kind: Service
  metadata:
    name: myapp
    namespace: default
  spec:
    type: NodePort
    selector:
      app: myapp
      release: stable
    ports:
      - name: http
        port: 80
        targetPort: 80

六、LoadBalancer

  A、LoadBalancer和nodePort其实是同一种方式,区别在于loadBalancer比nodePort多了一步,就是可以调用cloud provider去创建LB来向节点导流

七、ExternalName

  A、这种类型的Service通过返回CANME和它的值,可以将服务映射到externalName字段的内容。ExternalName Service是service的特例,它没有selector,也没有任何的端口和Endpoin。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。

  B、例子

  apiVersion: v1
  kind: Service
  metadata:
    name: my-service-1
    namespace: default
  spec:
    type: ExternalName
    externalName: hub.atguigu.com

八、Ingress实现七层代理

  A、

 

  B、例子

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: nginx-dm
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            name: nginx
        spec:
          containers:
            - name: nginx
              image: hub.atguigu.com/library/myapp:v1
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-svc
    spec:
    ports:
      - port: 80
        targetPort: 80
        protocol: TCP
    selector:
      name: nginx

    ---

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: nginx-test
    spec:
      rules:
        - host: www1.atguigu.com
          http:
          paths:
            - path: /
              backend:
              serviceName: nginx-svc
              servicePort: 80

  C、Ingress HTTPS代理访问

    1. 创建证书,以及cert存储方式

      a. openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"

      b. kubectl create secret tls tls-secret --key tls.key --cert tls.crt

    2. 例子

      apiVersion: extensions/v1beta1
      kind: Deployment
      metadata:
        name: deployment3
      spec:
        replicas: 2
        template:
          metadata:
            labels:
              name: nginx3
          spec:
            containers:
              - name: nginx3
                image: wangyanglinux/myapp:v3
                imagePullPolicy: IfNotPresent
                ports:
                - containerPort: 80
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: svc3
      spec:
        ports:
          - port: 80
            targetPort: 80
            protocol: TCP
        selector:
          name: nginx3

      ---

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: https-ingress
      spec:
        tls:
          - hosts:
            - www3.atguigu.com
          secretName: tls-secret
        rules:
          - host: www3.atguigu.com
            http:
            paths:
              - path: /
                backend:
                serviceName: svc3
                servicePort: 80

  D、nginx 进行BasicAuth

    1. yum -y install httpd

    2. htpasswd -c auth foo

    3. kubectl create secret generic basic-auth --from-file=auth

    4. 

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: ingress-with-auth
      annotations:
        nginx.ingress.kubernetes.io/auth-type: basic
        nginx.ingress.kubernetes.io/auth-secret: basic-auth
        nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
      spec:
        rules:
          - host: auth.atguigu.com
            http:
            paths:
              - path: /
                backend:
                serviceName: svc1
                servicePort: 80

  E、Nginx进行重写

    1.  一些annotations

      a.  nginx.ingress.kubernetes.io/rewrite-target(必须重定向流量的目标)

      b. nginx.ingress.kubernetes.io/ssl-redirect(指示位置部分是否仅可访问SSL(当Ingress包含证书时默认为true))

      c. nginx.ingress.kubernetes.io/force-ssl-redirect(及时ingress未启用TLS,也强制重定向到HTTPS)

      d. nignx.ingress.kubernetes.io/app-root(定义controller必须重定的应用程序根,如果它在'/'上下文中)

      e. nginx.ingress.kubernetes.io/use-regex(指示ingress上定义的路径是否使用正则表达式)

    2. 例子

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: nginx-test
        annotations:
          nginx.ingress.kubernetes.io/rewrite-target: https://www3.atguigu.com:32333
      spec:
        rules:
          - host: re.atguigu.com
            http:
            paths:
            - path: /
              backend:
              serviceName: svc1
              servicePort: 80

 

 

posted on 2019-11-26 10:23  DjanFey  阅读(367)  评论(0编辑  收藏  举报

导航