zoukankan      html  css  js  c++  java
  • 六,k8s集群service资源

    Service简介

    service的基本说明:
    Service 是作用于客户端可服务端(Pod)之间,作为一个固定的中间层
    主要依赖于kubernetes中的DNS服务,1.11版本之前用的是kube-dns
    而之后的版本使用的CoreDNS服务。
    

    在kubernetes中有三种网络:

    1. node network
    2. pod network
    3. cluster network (service network/virtual IP) 集群IP/虚拟IP,实质就是iptables中的规则
    

    kube-proxy通过watch监视api service 有关Service的变动

    kubernetes有三种代理模式:
    1. userspace    1.1 之前(过于麻烦,需要经过iptables两次)
    2. iptables     1.10 之前
    3. ipvs         1.11 之后(如果ipvs没被激活,会降级至iptables)
    

    ipvs模型示意图

    Service 类型
    ExternalName    # 关联集群外部的一个服务,用于集群内部有需求访问的资源通过Service去访问。
    ClusterIP       # 默认,配置一个集群IP,仅用于集群内部使用
    NodePort        # 集群外部,可与外部通信
    LoadBalancer    # 把集群环境部署在云环境中,而云环境也支持LB
    Headless Service  #无头service
    ExternelName  #把集群外部的服务映射给集群内部使用, 是一个FQDN的名称,一个CNAME名称,这个CNAM指向公网的FQDN
    

    ClusterIP

    工作原理:提供一个集群内的虚拟IP以供pod使用

    示意图:

    ClusterIP 实测

    [root@master manifests]# cat svc-redis.yaml 
    apiVersion: v1
    kind: Service       # 指定类型
    metadata:
      name: redis
      namespace: default
    spec:
      selector:         # 标签选择器
        app: redis
        role: logstor
      clusterIP: 10.97.97.97    # 这里的clusterIP 可以手动指定IP,如果不指定,则会自动获取一个IP
      type: ClusterIP
      ports:
      - port: 6379              # 这里的端口表示Service暴露的端口
        targetPort: 6379        # 这里表示匹配到的Pod 端口
    

    创建

    [root@master manifests]# kubectl apply -f svc-redis.yaml 
    service/redis created
    [root@master manifests]# kubectl get svc -o wide
    NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE   SELECTOR
    kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP    15d   <none>
    redis        ClusterIP   10.97.97.97   <none>        6379/TCP   5s    app=redis,role=logstor        # 这里可以看出已经匹配到了对应的Pod
    [root@master manifests]# kubectl describe svc redis
    Name:              redis
    Namespace:         default
    Labels:            <none>
    Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                         {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis","namespace":"default"},"spec":{"clusterIP":"10.97.97.97","...
    Selector:          app=redis,role=logstor
    Type:              ClusterIP
    IP:                10.97.97.97
    Port:              <unset>  6379/TCP
    TargetPort:        6379/TCP
    Endpoints:         10.244.1.24:6379 ##endpoints是存在于service和pod之间的
    Session Affinity:  None
    Events:            <none>
    [root@master manifests]# kubectl get pods -o wide
    NAME                           READY   STATUS    RESTARTS   AGE     IP            NODE                NOMINATED NODE   READINESS GATES
    myapp-ds-8tvmc                 1/1     Running   0          5h34m   10.244.1.25   node03.kubernetes   <none>           <none>
    myapp-ds-cs2hw                 1/1     Running   0          5h33m   10.244.3.27   node01.kubernetes   <none>           <none>
    myapp-ds-f2pp8                 1/1     Running   0          5h34m   10.244.2.20   node02.kubernetes   <none>           <none>
    redis-5c998b644f-wnzrd         1/1     Running   0          5h59m   10.244.1.24   node03.kubernetes   <none>           <none>       # 这里redis的Pod 和刚刚创建svc匹配的Pod的IP地址相同
    

    资源记录:

    SVC_NAME.NSNAME.DEMAIN.LTD.
    
    svc.cluster.local. 集群默认后缀
    

    手动测试集群内创建的DNS解析:

    按照上面的记录,资源解析记录为: redis.default.svc.cluster.local.

    进入到其中一台Pod中尝试解析:

    [root@master manifests]# kubectl exec -it myapp-ds-8tvmc -- /bin/sh
    / # nslookup redis.default.svc.cluster.local.
    nslookup: can't resolve '(null)': Name does not resolve
    
    Name:      redis.default.svc.cluster.local.
    Address 1: 10.97.97.97 redis.default.svc.cluster.local
    

    Headless(无头service)

    Headless Service也是一种Service,但不同的是会定义spec:clusterIP: None,也就是不需要Cluster IP的Service。

    头Service区别是 ClusterIP 为空,而解析到的Service 直接是后端的Pod的IP地址

    [root@master manifests]# cat myapp-svc-headless.yaml 
    apiVersion: v1
    kind: Service
    metadata:
      name: myapp-svc
      namespace: default
    spec:
      selector:
        app: myapp
        release: canary
      clusterIP: "None"     # 这里定义为None即可
      ports:
      - port: 80
        targetPort: 80
        NodePort: #节点端口,可以不指定,会自动分配
    [root@master manifests]# kubectl apply -f myapp-svc-headless.yaml 
    service/myapp-svc created
    [root@master manifests]# kubectl get svc
    NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
    kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        16d
    myapp        NodePort    10.99.99.99   <none>        80:30080/TCP   17h
    myapp-svc    ClusterIP   None          <none>        80/TCP         3s
    redis        ClusterIP   10.97.97.97   <none>        6379/TCP       18h
    

    下面手动解析测试:

    [root@master manifests]# dig -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
    
    ; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52484
    ;; flags: qr aa rd; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1
    ;; WARNING: recursion requested but not available
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ;; QUESTION SECTION:
    ;myapp-svc.default.svc.cluster.local. IN    A
    
    ;; ANSWER SECTION:
    myapp-svc.default.svc.cluster.local. 30 IN A    10.244.1.20
    myapp-svc.default.svc.cluster.local. 30 IN A    10.244.3.23
    myapp-svc.default.svc.cluster.local. 30 IN A    10.244.3.22     # 这里解析的是匹配到的后端的Pod地址
    myapp-svc.default.svc.cluster.local. 30 IN A    10.244.2.16
    myapp-svc.default.svc.cluster.local. 30 IN A    10.244.2.15
    
    ;; Query time: 1 msec
    ;; SERVER: 10.96.0.10#53(10.96.0.10)
    ;; WHEN: Fri Jul 26 10:04:24 CST 2019
    ;; MSG SIZE  rcvd: 319
    [root@master manifests]# kubectl get pods -o wide -l app=myapp
    NAME                           READY   STATUS    RESTARTS   AGE   IP            NODE                NOMINATED NODE   READINESS GATES
    myapp-deploy-f4db5d79c-7hnfg   1/1     Running   0          46h   10.244.2.16   node02.kubernetes   <none>           <none>
    myapp-deploy-f4db5d79c-85hpm   1/1     Running   0          46h   10.244.3.22   node01.kubernetes   <none>           <none>
    myapp-deploy-f4db5d79c-b9h4s   1/1     Running   0          46h   10.244.2.15   node02.kubernetes   <none>           <none>
    myapp-deploy-f4db5d79c-tm9mt   1/1     Running   0          46h   10.244.1.20   node03.kubernetes   <none>           <none>
    myapp-deploy-f4db5d79c-xp8t6   1/1     Running   0          46h   10.244.3.23   node01.kubernetes   <none>           <none>
    

    而解析有头的Service 则是Service自己的地址:

    [root@master manifests]# dig -t A myapp.default.svc.cluster.local. @10.96.0.10
    
    ; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> -t A myapp.default.svc.cluster.local. @10.96.0.10
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14743
    ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
    ;; WARNING: recursion requested but not available
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ;; QUESTION SECTION:
    ;myapp.default.svc.cluster.local. IN    A
    
    ;; ANSWER SECTION:
    myapp.default.svc.cluster.local. 30 IN  A   10.99.99.99
    
    ;; Query time: 0 msec
    ;; SERVER: 10.96.0.10#53(10.96.0.10)
    ;; WHEN: Fri Jul 26 10:05:33 CST 2019
    ;; MSG SIZE  rcvd: 107
    

    NodePort

    工作原理:用来对集群外暴露service, 你可以通过访问集群内的每个NodeIP:NodePort的方式访问到对应的service后端的Endpoint

    示意图:

    NodePod实测

     apiVersion: v1
     kind: Service
     metadata:
         name: myapp
         namespace: default
     spec:
         selector:
             app: myapp
             release: canary
         clusterIP: 10.99.99.99
         type: NodePort
         ports:
         - port: 80
           targetPort: 80
           #nodePort: 30080 nodePort可以自己指定, 如果没有指定, k8s会自动生成一个端口, 指定的好处是便于记忆, 坏处是容易冲突
    
    

    kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"ClientIP"}}' #会话亲和性,同一个client的访问调度到同一个pod
    kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"None"}}' #修改完会立即生效

  • 相关阅读:
    oracle函数 MAX([distinct|all]x)
    oracle函数 MAX([distinct|all]x)
    oralce函数 count(*|[distinct|all]x)
    oracle函数 VARIANCE([distinct|all]x)
    oralce函数 STDDEV([distinct|all]x)
    oracle函数 SUM([distinct|all]x)
    oralcle函数 AVG([distinct|all]x)
    oracle函数 lag()和lead()
    oracle函数 ROW_NUMBER()
    Linux性能测试 netstat命令
  • 原文地址:https://www.cnblogs.com/peng-zone/p/11593423.html
Copyright © 2011-2022 走看看