Docker+K8s基础篇(五)


  • service资源介绍

    • A:service资源的工作特性
  • service的使用
    • A:service字段介绍
    • B:ClusterIP的简单使用
    • C:NodePort的简单使用
    • D:LoadBalancer和ExternalName
    • E:无头service

♣一:service资源介绍

A:service资源的工作特性:

kubernetes的service资源:
在整个k8s集群的节点中pods资源是最小的对象,这些对象是提供真正服务的重要组成部分,当我们需要通过外部进行访问的时候因各pod资源提供的访问端点是不一致的,我们就需要设定一个固定的访问端点来提供访问,这个访问端点,是存在pod至上和控制器之下的中间层,这个中间层将叫service,service会严格依赖k8s上的一个重要组件叫coredns(新版本)和kube-dns(老版本1.11之前的版本),所以我们在部署的时候必需要部署coredes或者kube-dns。
kubernetes要想给客户端提供网络功能,需要依赖于第三方方案,这种方案在新版本中可以通过cni(容器网络插件标准接口)来接入任何遵循这种标准的第三方方案,例如我们使用到的flannel。
kubernetes的三类ip地址:
1:node网络
2:pod网络
node和pod的地址是实际存在且配置了。
3:cluater(集群地址)或者叫做service地址,这种地址是虚拟的地址(virtual ip),这些地址没有出现在接口之上,仅仅只是出现在service的规则当中。
在每个节点之上都工作了kube-proxy组件,这个组件将会实时监视service资源中的变动信息,这个监视是由kube-proxy通过一种固有的方式(watch)请求方式来实现的,一旦service的资源发生变动,kube-proxy都要将其转换为当前节点之上的能够被service调度的规则之上(这个规则可能是iptables或者ipvs规则,取决于service的实现方式)
service的实现方式在k8s上有三种模型:

        
1:userspace(用户空间)
  当用户的访问请求会先到达service上,由service将其转换监听在某个套接字上的用户空间内的kube-proxy,接下来kube-proxy处理完成之后再转给service代理至这个service各个相          关联的pod之上,实现调度。

  这种模型效率不高,因为用户请求要进过工作在内核上的service转给工作各个“主机”之上用户空间的kube-proxy,kube-proxy将其封装成请求报文发送给内核空间的service资源,         有service的规则在调度至各个pod资源上。

        
2:iptabeles:
   当前用户请求直接请求service的IP,这个请求会被工作在本地内核空间中的service所截取,然后直接调度给相关联的pod,而整个调度都是基于iptables规则来完成的。

        
3:ipvs:
      和iptables一样,只不过规则换成了ipvs规则。
在配置k8s的时候设定k8s工作在什么模式之下,就会生成对应模式的规则,1.1之前默认是userspace,1.11默认使用的ipvs,如果ipvs没有激活,就会降级为iptables。
当集群中的pods资源发生了改变,这个信息会立马反应到apiservice之上,因为这个改变会直接存储在apiservice的ectd当中,这种变化也会立即触发kube-proxy并发送给service资源中将其转换为iptables或者ipvs规则,这些转换都是动态且实时的。

♣二:service的使用:

A:service字段介绍:

  1. [root@www kubeadm]# kubectl get svc
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 77m
  4. 在我们初始化集群的时候已然帮忙创建了一个名称叫kubernetesservice资源,这个资源很重要,是保证我们service和集群节点之间联系的,而且10.96.0.1是面向集群内部的地址。
  5. [root@www kubeadm]# kubectl explain svc 也是包含5个一级字段
  6. KIND: Service
  7. VERSION: v1
  8.  
  9. DESCRIPTION:
  10. Service is a named abstraction of software service (for example, mysql)
  11. consisting of local port (for example 3306) that the proxy listens on, and
  12. the selector that determines which pods will answer requests sent through
  13. the proxy.
  14.  
  15. FIELDS:
  16. apiVersion <string>
  17. APIVersion defines the versioned schema of this representation of an
  18. object. Servers should convert recognized schemas to the latest internal
  19. value, and may reject unrecognized values. More info:
  20. https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
  21.  
  22. kind <string>
  23. Kind is a string value representing the REST resource this object
  24. represents. Servers may infer this from the endpoint the client submits
  25. requests to. Cannot be updated. In CamelCase. More info:
  26. https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
  27.  
  28. metadata <Object>
  29. Standard object's metadata. More info:
  30. https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
  31.  
  32. spec <Object>
  33. Spec defines the behavior of a service.
  34. https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
  35.  
  36. status <Object>
  37. Most recently observed status of the service. Populated by the system.
  38. Read-only. More info:
  39. https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
  40.  
  41. [root@www kubeadm]# kubectl explain svc.spec.ports(ports是用于把那个端口和后端的容器端口建立关联关系)
  42. KIND: Service
  43. VERSION: v1
  44.  
  45. RESOURCE: ports <[]Object>
  46.  
  47. DESCRIPTION:
  48. The list of ports that are exposed by this service. More info:
  49. https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
  50.  
  51. ServicePort contains information on service's port.
  52.  
  53. FIELDS:
  54. name <string>
  55. The name of this port within the service. This must be a DNS_LABEL. All
  56. ports within a ServiceSpec must have unique names. This maps to the 'Name'
  57. field in EndpointPort objects. Optional if only one ServicePort is defined
  58. on this service.
  59.  
  60. nodePort <integer>
  61. The port on each node on which this service is exposed when type=NodePort
  62. or LoadBalancer. Usually assigned by the system. If specified, it will be
  63. allocated to the service if unused or else creation of the service will
  64. fail. Default is to auto-allocate a port if the ServiceType of this Service
  65. requires one. More info:
  66. https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
  67.  
  68. port <integer> -required- service的端口
  69. The port that will be exposed by this service.
  70.  
  71. protocol <string> node端口
  72. The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". Default
  73. is TCP.
  74.  
  75. targetPort <string> pods端口
  76. Number or name of the port to access on the pods targeted by the service.
  77. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If
  78. this is a string, it will be looked up as a named port in the target Pod's
  79. container ports. If this is not specified, the value of the 'port' field is
  80. used (an identity map). This field is ignored for services with
  81. clusterIP=None, and should be omitted or set equal to the 'port' field.
  82. More info:
  83. https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service
  84.  
  85. [root@www kubeadm]# kubectl explain svc.spec.selector (我们需要关联到哪些pods资源上)
  86. KIND: Service
  87. VERSION: v1
  88.  
  89. FIELD: selector <map[string]string>
  90.  
  91. DESCRIPTION:
  92. Route service traffic to pods with label keys and values matching this
  93. selector. If empty or not present, the service is assumed to have an
  94. external process managing its endpoints, which Kubernetes will not modify.
  95. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
  96. type is ExternalName. More info:
  97. https://kubernetes.io/docs/concepts/services-networking/service/
  98.  
  99. spec.clusterIP(指定固定的ip,创建之后无法改变)
  100.  
  101. [root@www kubeadm]# kubectl explain svc.spec.type (service的类型)
  102. KIND: Service
  103. VERSION: v1
  104.  
  105. FIELD: type <string>
  106.  
  107. DESCRIPTION:
  108. type determines how the Service is exposed. Defaults to ClusterIP. Valid
  109. options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
  110. "ExternalName" maps to the specified externalName. "ClusterIP" allocates a
  111. cluster-internal IP address for load-balancing to endpoints. Endpoints are
  112. determined by the selector or if that is not specified, by manual
  113. construction of an Endpoints object. If clusterIP is "None", no virtual IP
  114. is allocated and the endpoints are published as a set of endpoints rather
  115. than a stable IP. "NodePort" builds on ClusterIP and allocates a port on
  116. every node which routes to the clusterIP. "LoadBalancer" builds on NodePort
  117. and creates an external load-balancer (if supported in the current cloud)
  118. which routes to the clusterIP. More info:
  119. https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

service资源的字段介绍

svc.spec.type字段类型:

类型一共分为4种:
1:ExternalName(把集群外部的服务引入到集群内部直接使用);

2:ClusterIP;

3:NodePort(接入外部);

4:LoadBalancer(支持lbaas负载均衡的一键调度)

B:ClusterIP的简单使用:

  1. [root@www TestYaml]# cat redis-svc.yaml
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: redis
  6. namespace: default
  7. spec:
  8. selector:
  9. app: redis
  10. clusterIP: 10.98.98.98 (指定ip创建的时候需要注意网段和地址冲突问题)
  11. type: ClusterIP
  12. ports:
  13. - port: 6379
  14. targetPort: 6379
  15. [root@www TestYaml]# kubectl apply -f redis-svc.yaml
  16. service/redis created
  17. [root@www TestYaml]# kubectl get svc
  18. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  19. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 102m
  20. redis ClusterIP 10.98.98.98 <none> 6379/TCP 14s 可以看到redisip和端口是配置文件指定的ip和端口
  21. [root@www TestYaml]# kubectl describe svc redis
  22. Name: redis
  23. Namespace: default
  24. Labels: <none>
  25. Annotations: kubectl.kubernetes.io/last-applied-configuration:
  26. {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis","namespace":"default"},"spec":{"clusterIP":"10.98.98.98","...
  27. Selector: app=redis
  28. Type: ClusterIP
  29. IP: 10.98.98.98
  30. Port: <unset> 6379/TCP 指定的service端口
  31. TargetPort: 6379/TCP 指定的pod端口
  32. Endpoints: <none>
  33. Session Affinity: None
  34. Events: <none>
  35. 这里需要说明的是service不会直接到pod,而是需要进过中间层Endpoints的,Endpoints也是k8s上标准的对象,再由Endpoints关联至pods资源上。

ClusterIP案例

C:NodePort的简单使用:

  1. [root@www TestYaml]# cat NodePort.svc.yaml
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: myapp
  6. namespace: default
  7. spec:
  8. selector:
  9. app: myapp
  10. clusterIP: 10.99.99.99
  11. type: NodePort
  12. ports:
  13. - port: 8088
  14. targetPort: 8088
  15. nodePort: 30008 3000032767之间的都可以,默认是动态分配的
  16. [root@www TestYaml]# kubectl apply -f NodePort.svc.yaml
  17. service/myapp created
  18. [root@www TestYaml]# kubectl get svc
  19. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  20. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 125m
  21. myapp NodePort 10.99.99.99 <none> 8088:30008/TCP 22s service8088端口映射成node上的30008
  22. redis ClusterIP 10.98.98.98 <none> 6379/TCP 23m
  23. 通过此种方式创建的pod就可以在外部直接访问了,只不过要进过好几级转换,先是port,再是protocol,在转换到targetPort上。

NodePort案例

D:LoadBalancer和ExternalName:

        

如果购买了阿里云平台的环境虚拟机(带ibaas负载均衡服务),你在上面搭建了一共k8s的集群服务,k8s会自动去调用云平台的ibaas服务,用软件的方式去把用户的访问请求负载调度至后端的任意一个node节点上,在由节点上的service服务再负载调度至后端的任意一个pod之上,整个过程都是自动的,而且是两级负载均衡调度。

ExternalName:

我们在构建pods的时候本来就是层级关系的,例如db被tomcat访问,tomcat被nginx访问,这种被访问的形式本身就是一种client的存在,那如果是我们的nginx服务在集群外部的某台集群上,想nginx能访问到集群内部的tomcat就需要使用ExternalName,在创建yaml文件的时候ExternalName是一个真实有效且能被dns所解析的服务名,然后用户的访问请求走外部的nginx,nginx在发送请求报文给集群内部的nodeIP到service,有service调度到后端的pod(tomcat),pod在返回给service,最后返回到nginx上,实现访问,但是此种方式用的不多。

  1. [root@www kubeadm]# kubectl explain svc.spec.externalName externalName只能是类型为ExternalName的时候才有效)
  2. KIND: Service
  3. VERSION: v1
  4.  
  5. FIELD: externalName <string>
  6.  
  7. DESCRIPTION:
  8. externalName is the external reference that kubedns or equivalent will
  9. return as a CNAME record for this service. No proxying will be involved.
  10. Must be a valid RFC-1123 hostname (https://tools.ietf.org/html/rfc1123) and
  11. requires Type to be ExternalName.
  12. [root@www kubeadm]#

externalName字段说明

  1. [root@www kubeadm]# kubectl explain svc.spec.sessionAffinitysvc还支持sessionAffinity
  2. KIND: Service
  3. VERSION: v1
  4.  
  5. FIELD: sessionAffinity <string>
  6.  
  7. DESCRIPTION:
  8. Supports "ClientIP" and "None". Used to maintain session affinity. Enable
  9. client IP based session affinity. Must be ClientIP or None. Defaults to
  10. None. More info:
  11. https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
  12. 这里的session支持两种,一个是ClientIP,将来自同一个ip访问的请求始终调度到同一个pod上。
  13. None就是默认的随机调度。

sessionAffinity字段说明

E:无头service:

无头service,即值创建service的时候不指定clusterIP,此时用户的访问请求不再是访问clusterIP而是转而访问pod上的ip

  1. [root@www TestYaml]# kubectl explain svc.spec.clusterIP
  2. KIND: Service
  3. VERSION: v1
  4.  
  5. FIELD: clusterIP <string>
  6.  
  7. DESCRIPTION:
  8. clusterIP is the IP address of the service and is usually assigned randomly
  9. by the master. If an address is specified manually and is not in use by
  10. others, it will be allocated to the service; otherwise, creation of the
  11. service will fail. This field can not be changed through updates. Valid
  12. values are "None", empty string (""), or a valid IP address. "None" can be
  13. specified for headless services when proxying is not required. Only applies
  14. to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is
  15. ExternalName. More info:
  16. https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
  17. 在指定clusterIP的时候可以指定为none(格式是""即可)
  18. 案例:
  19. [root@www TestYaml]# cat NodePort.svc.yaml
  20. apiVersion: v1
  21. kind: Service
  22. metadata:
  23. name: myapp
  24. namespace: default
  25. spec:
  26. selector:
  27. app: myapp
  28. clusterIP: None 不指定ip
  29. ports:
  30. - port: 8088
  31. targetPort: 8088
  32. [root@www TestYaml]# kubectl get svc
  33. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  34. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 81m
  35. myapp ClusterIP None <none> 8088/TCP 9s 可以看到ipnone标记
  36. [root@www TestYaml]# kubectl get svc -n kube-system
  37. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  38. kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 83m 我们直接去解析corednsip就能直接看到pod ip的解析记录
  39. [root@www TestYaml]# dig -t A myapp.default.svc.cluster.local. @10.96.0.10 我们直接解析corednsip看看下解析记录
  40.  
  41. ; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> -t A myapp.default.svc.cluster.local. @10.96.0.10
  42. ;; global options: +cmd
  43. ;; Got answer:
  44. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60422
  45. ;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
  46. ;; WARNING: recursion requested but not available
  47.  
  48. ;; OPT PSEUDOSECTION:
  49. ; EDNS: version: 0, flags:; udp: 4096
  50. ;; QUESTION SECTION:
  51. ;myapp.default.svc.cluster.local. IN A
  52.  
  53. ;; ANSWER SECTION:
  54. myapp.default.svc.cluster.local. 5 IN A 10.244.2.9 可以看到这里有三个记录,ip分别是2.9,2.8,1.8
  55. myapp.default.svc.cluster.local. 5 IN A 10.244.2.8
  56. myapp.default.svc.cluster.local. 5 IN A 10.244.1.8
  57.  
  58. ;; Query time: 0 msec
  59. ;; SERVER: 10.96.0.10#53(10.96.0.10)
  60. ;; WHEN: 7 14 11:29:23 CST 2019
  61. ;; MSG SIZE rcvd: 201
  62.  
  63. [root@www TestYaml]# kubectl get pods -o wide
  64. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  65. myapp-9758dcb6b-hl957 1/1 Running 0 4m6s 10.244.2.8 www.kubernetes.node1.com <none> <none>
  66. myapp-9758dcb6b-z8rk6 1/1 Running 0 4m6s 10.244.2.9 www.kubernetes.node1.com <none> <none>
  67. myapp-9758dcb6b-zl5jt 1/1 Running 0 4m6s 10.244.1.8 www.kubernetes.node2.com <none> <none>
  68. 上面的2.9,2.8,1.8对应的ip就是podip,这样我们得出的结论就是当service没有clusterip的时候就会通过coredns来解析并转发到后端的pod之上。

无头service案例

service很好用,但是也是存在缺陷的,当面我们创建了service的时候,用户访问需要进行两级转换,如果是阿里云的lbaas则是两级调度,其实我们看到的是两级转换,但是落到ipvs或者iptebles之上就是四层调度。因为ipvs和iptables都是四层的,如果我们建立的是https服务的话,例如https对应的名称是myapp,那么你的每一个myapp都要配置成htpps的主机,因为ipvs或者iptables自身是无法卸载https会话的。
kubernetes还有一种引入外部流量的方式,叫ingress(是一种7层调度器)将外部的流量引入到内部来,但是也是无法脱离service的工作,必需要用pod7层功能的应用来调度,起能提供的应用有nginx,haprxoy等。在kubernetes之上应用比较多的是nginx,当然还有别的应用有各自相应的优势。

docker+k8s基础篇五的更多相关文章

  1. docker+k8s基础篇一

    Docker+K8s基础篇(一) docker的介绍 A:为什么是docker B:k8s介绍 docker的使用 A:docker的安装 B:docker的常用命令 C:docker容器的启动和操作 ...

  2. docker+k8s基础篇四

    Docker+K8s基础篇(四) pod控制器 A:pod控制器类型 ReplicaSet控制器 A:ReplicaSet控制器介绍 B:ReplicaSet控制器的使用 Deployment控制器 ...

  3. docker+k8s基础篇三

    Docker+K8s基础篇(三) kubernetes上的资源 A:k8s上的常用资源 Pod的配置清单 A:Pod上的清单定义 B:Pod创建资源的方法 C:spec下其它字段的介绍 Pod的生命周 ...

  4. docker+k8s基础篇二

    Docker+K8s基础篇(二) docker的资源控制 A:docker的资源限制 Kubernetes的基础篇 A:DevOps的介绍 B:Kubernetes的架构概述 C:Kubernetes ...

  5. 小白学Docker之基础篇

    系列文章: 小白学Docker之基础篇 小白学Docker之Compose 小白学Docker之Swarm PS: 以下是个人作为新手小白学习docker的笔记总结 1. docker是什么 百科上的 ...

  6. Docker之基础篇

    小白学Docker之基础篇   系列文章: 小白学Docker之基础篇 小白学Docker之Compose 小白学Docker之Swarm PS: 以下是个人作为新手小白学习docker的笔记总结 1 ...

  7. C#基础篇五值类型和引用类型

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P01M ...

  8. Hybrid APP基础篇(五)->JSBridge实现示例

    说明 JSBridge实现示例 目录 前言 参考来源 楔子 JS实现部分 说明 实现 Android实现部分 说明 JSBridge类 实现 Callback类 实现 Webview容器关键代码 实现 ...

  9. Python基础篇(五)

    bool用于判断布尔值的结果是True还是False >>> bool("a") True >>> bool(3) True >>& ...

随机推荐

  1. 异常检测(Anomaly detection): 异常检测算法(应用高斯分布)

    估计P(x)的分布--密度估计 我们有m个样本,每个样本有n个特征值,每个特征都分别服从不同的高斯分布,上图中的公式是在假设每个特征都独立的情况下,实际无论每个特征是否独立,这个公式的效果都不错.连乘 ...

  2. wiki with 35(dp+矩阵快速幂)

    Problem J. Wiki with 35Input file: standard input Time limit: 1 secondOutput file: standard output M ...

  3. SpringBoot学习(五)RSocket和Security

    一.RSocket RSocket是一个用于字节流传输的二进制协议.它通过在单个连接上传递异步消息来支持对称交互模型,主要支持的通讯层包括 TCP, WebSockets和Aeron(UDP). RS ...

  4. 文件搜索命令find

    1.路径加文件名搜索(find): 查找的是etc目录下的以init为名字的文件. 加通配符后为模糊搜索,只要文件名中含有init即可. 查找etc目录下以init开头的七位文件名. 2.搜索时不区分 ...

  5. Bzoj 1927: [Sdoi2010]星际竞速(网络流)

    1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec Memory Limit: 259 MB Description 10年一度的银河系赛车大赛又要开始了.作为全银河最盛大 ...

  6. 【loj2552】【CTSC2018】假面

    题目 有\(n\)个敌方单位,初始生命值分别为\(m_1,\cdots,m_n\) : 假面可以释放\(Q\)个技能: $op = 0  ,  id , u , v $ 表示对\(id\)号敌人有\( ...

  7. 在windows环境下可以裁剪.jpg格式的图片

    发现在windows操作系统下,可以利用图片编辑器裁剪.jpg格式的尺寸大小.其四方有四个推子.可以移动.注意点击右方的“确定”按钮.

  8. Redis BGSAVE因为内存不足 fork 失败导致目标 Redis 无法访问的问题

    中秋的时候正在外面愉快的在外卖喝着咖啡玩电脑......突发 redis 报警从 sentry 应用端曝出的错误 MISCONF Redis is configured to save RDB sna ...

  9. javascript加密之md5加密

    原作地址:JavaScriptMd5 修改备用:JavaScriptMd5.rar

  10. office2010安装不了提示已经安装32位的了怎么办

    1.打开控制面板,查看是否有安装的程序没有拆卸,如果没有继续往下看,如果有直接拆卸掉,再进行下面的步骤. 2.首先打开注册列表.按下win+R键即可打开,输入regedit,也可以在开始菜单中搜索re ...