zoukankan      html  css  js  c++  java
  • k8s学习-Service

    4.4、Service

    可能会用到ipvs,先安装:

    yum install -y openssl openssl-devel popt popt-devel libnl-devel kenel-devel
    yum install -y ipvsadm
    

    4.4.1、概念

    说明

    kubernetes的Service(简称svc)定义了一种抽象,一个Pod的逻辑分组,一种可以访问他们的策略,通过Label Selector选择对应的一组Pod。简单来说就是服务发现;

    类型

    1. ClusterIp:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP。
    2. NodePort:在ClusterIP的基础上为Service在每太机器上绑定一个端口,这样通过NodePort来访问该服务。
    3. LoadBalance:在NodePort的基础上,借助cloud provider创建一个外部负载均衡器。并将请求转发到NodePort
    4. ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,只有>=kubernetes1.7的版本才支持。

    结构图:

    代理的分类

    1)namespace

    频繁的和kubeproxy交互,性能不高。

    2)iptables

    使用iptables继续转发,提高了性能。

    3)ipvs

    在该模式下kube-proxy会监视kubernetes的Service对象和Endpoints,调用netlink接口已以响应的创建ipvs规则并定期与Service对象和Endpoints对象同步ipvs规则,以确保ipvs状态与期望一致。访问服务时,流量将被定重定向到其中一个后端Pod。

    与iptables类似,ipvs于netfilter的hook功能,但使用哈希表作为底层数据结构并在内核空间中工作。这意味着ipvs可以更快的重定向流量,并且在同步代理规则时具有更好的性能。此外ipvs为负载均衡算法做出了更多的选项:

    • rr:轮询调度
    • lc:最小连接
    • dn:目标哈希
    • sh:源哈希
    • sed:最短期望延迟
    • nq:不排队调度

    4.4.2、使用

    ClusterIp

    clusterIp在每个node节点使用iptables,将发向clusterIp对饮端口的数据转发到kube-proxy中,然后kube-proxy自己内部实现由负载均衡的方法,并且可以查询到这个service下对应的pod地址和端口,然后把数据转发给这个pod的地址和端口;

    • apiServer用户通过kubectl命令想apiServer发送创建service的命令,apiserver接收到请求后将数据存储到etcd中
    • kube-proxy kubernetes的每个节点中都有一个kube-proxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入到本地的iptables规则中
    • iptables使用NAT等技术将virtualIP的流量转至endpoint中
    测试
    mkdir -p /usr/local/docker/kubernetes/plugins/test/service/clusterip
    cd /usr/local/docker/kubernetes/plugins/test/service/clusterip
    

    1)创建deployment

    vim myapp-deploy.yml

    apiVersion: apps/v1
    kind: Deployment # 类型为Deployment
    metadata:
      name: myapp-deploy
      namespace: default
    spec:
      replicas: 3 # 副本数 3
      selector:
        matchLabels:
          app: myapp
          release: stabel
      template:
        metadata: # 必须和上面定义的label匹配
          labels:
            app: myapp
            release: stabel
            env: test
        spec:
          containers:
          - name: myapp
            image: habor-repo.com/library/nginx:v1
            imagePullPolicy: IfNotPresent # 如果本地没有才拉取
            env: # 容器添加环境变量(这里没用,只是有这个功能)
            - name: GET_HOST_FROM
              value: dns
            ports:
            - name: http # 端口的名字定义为 http
              containerPort: 80 # 容器的端口
    

    2)创建service

    vim myapp-service.yml

    apiVersion: v1
    kind: Service # 类型为 Service
    metadata:
      name: myapp
      namespace: default
    spec:
      type: ClusterIP # service类型为 ClusterIP
      selector: # 这里的labels匹配上面的 matchLabels 用来发现deployment
        app: myapp
        release: stabel
      ports:
      - name: http # 端口的名字定义为 http
        port: 8000 # 暴露的svc外部端口
        targetPort: 80 # 容器内部端口
    
    # 创建 deployment
    kubectl apply -f myapp-deploy.yml
    kubectl get deploy
    kubectl get pod
    
    # 创建 svc
    kubectl apply -f myapp-service.yml
    kubectl get svc
    
    # 通过 curl 访问 svc 的ip:8000负载均衡访问
    

    HeadlessService

    和ClusterIP一样只不过不会暴露service的IP和端口,只能通过域名方式访问:

    测试

    vim myapp-headless-service.yml

    apiVersion: v1
    kind: Service # 类型为 Service
    metadata:
      name: myapp-headless
      namespace: default
    spec:
      clusterIP: "None" # 表示为一个headless服务
      selector: # 这里的labels匹配上面的 matchLabels 用来发现deployment
        app: myapp
        release: stabel
      ports:
      - name: http # 端口的名字定义为 http
        port: 80 # 容器内部端口
        targetPort: 8000 # 暴露的svc外部端口
    
    # 创建 svc
    kubectl apply -f myapp-headless-service.yml
    # 查看 svc 发现为 None 
    [root@k8s-master clusterip]# kubectl get svc
    NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP    2d5h
    myapp            ClusterIP   10.101.230.183   <none>        8000/TCP   5m13s
    myapp-headless   ClusterIP   None             <none>        80/TCP     5s
    
    # 查看 dns 任意找一个,例如: coredns-bccdc95cf-m4jg5   10.244.0.16
    kubectl get pod -n kube-system -o wide
    
    # 通过headless自带的域名解析访问
    yum install -y bind-utils
    # 使用 dig 命令指定dns域名解析
    # service名.命名空间.集群域名(默认svc.cluster.local)
    dig -t A myapp-headless.default.svc.cluster.local @10.244.0.16
    
    

    NodePort

    在每个节点上开启一个端口,将该端口的流量导入kube-proxy,然后由kube-proxy进一步给对应的pod

    vim nodeport.yml

    apiVersion: v1
    kind: Service # 类型为 Service
    metadata:
      name: myapp-nodeport
      namespace: default
    spec:
      type: NodePort # service类型为 NodePort
      selector: # 这里的labels匹配上面的 matchLabels 用来发现deployment
        app: myapp
        release: stabel
      ports:
      - name: http # 端口的名字定义为 http
        port: 9000 # 暴露的svc外部端口
        targetPort: 80 # 容器内部端口
    
    kubectl apply -f nodeport.yml
    
    # 查看 svc
    [root@k8s-master clusterip]# kubectl get svc
    NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
    kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP          2d5h
    myapp            ClusterIP   10.101.230.183   <none>        8000/TCP         34m
    myapp-headless   ClusterIP   None             <none>        80/TCP           29m
    myapp-nodeport   NodePort    10.106.39.25     <none>        9000:31714/TCP   6s
    
    # 访问
    # 9000:31714/TCP 9000 是这个service自己ip的端口,31714是每个节点上暴露的端口
    curl 10.106.39.25:9000
    curl k8s-master:31714
    curl k8s-node1:31714
    curl k8s-node2:31714
    

    LoadbBlancer

    和nodeport其实是同一种,只不过添加了负载均衡的功能。这个是收费的功能。

    ExternalName

    将服务映射到externalName字段(可以是域名或者IP)。ExternalName是Service的特例,他没有selector,也没有定义任何的端口和Endpoint。相当于将外部流量导入到内部。

    vim external-name.yml

    apiVersion: v1
    kind: Service # 类型为 Service
    metadata:
      name: myapp-external-name
      namespace: default
    spec:
      type: ExternalName # service类型为 ExternalName
      externalName: habor-repo.com
    
    kubectl apply -f external-name.yml
    
    # 查看
    kubectl get svc
    
    # 查看 dns 任意找一个,例如: coredns-bccdc95cf-m4jg5   10.244.0.16
    kubectl get pod -n kube-system -o wide
    
    # 测试域名解析 
    dig -t A myapp-external-name.default.svc.cluster.local @10.244.0.16
    
  • 相关阅读:
    PTA 7-29 修理牧场(Huffman树)
    全网最详细最好懂 PyTorch CNN案例分析 识别手写数字
    【Python Deap库】遗传算法/遗传编程 进化算法基于python DEAP库深度解析讲解
    【比较】遗传算法GA和遗传编程GP有什么不同?
    【python(deap库)实现】GEAP 遗传算法/遗传编程 genetic programming +
    【比较】粒子群算法PSO 和 遗传算法GA 的相同点和不同点
    【遗传编程/基因规划】Genetic Programming
    【经典大数据竞赛科普】泰坦尼克灾难 到底是个什么东西
    【Python代码】TSNE高维数据降维可视化工具 + python实现
    【python代码】 最大流问题+最小花费问题+python(ortool库)实现
  • 原文地址:https://www.cnblogs.com/bartggg/p/12996919.html
Copyright © 2011-2022 走看看