kubernetes Srevice 定义资源清单

今天是2019-5-11,那么我们来看一下kubernetes Service 资源配置清单的书写。

在安装配置的时候我们设置service处于哪个模式,那么services的工作就在哪个模式( iptables  ipvs  userspace )----三种代理模式。

Service:

工作模式: userspace , iptables , ipvs 

Userspace: 1.1- 

Iptables: 1.10-

Ipvs: 1.11+  

 

那么下来我们看一下如何使用清单创建一个service资源:

和之前的类似 我们可以使用explian来查看service的定义,

[root@server1 ~]# kubectl explain svc

FIELDS:
   apiVersion    <string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#resources

   kind    <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds

   metadata    <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

   spec    <Object>
     Spec defines the behavior of a service.
     https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

   status    <Object>
     Most recently observed status of the service. Populated by the system.
     Read-only. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status


可以看到类似于之前的配置清单的书写,一共也是五个字段(apiVersion , kind , metadata, spec ,status --系统的状态,无须定义)

下来我们看一下重要的spec中的字段:[root@server1 ~]# kubectl explain svc.spec

  ports    <[]Object>        :   把哪个后端容器的端口建立成关联的关系

 selector    <map[string]string>  : 关联到哪个需要关联的容器中

   clusterIP    <string>   : 这个IP是集群自动分配的,如果想要固定的IP,那么就直接指定固定的地址,创建 之后无法改变

 type    <string>  : 有必要我们要指定一下type,那么type的类型一共有 : ExternalName, ClusterIP, NodePort, and LoadBalancer.

那么这个type是service的类型:一共有四种: 默认是 ClusterIP ,先要接入外部的IP是 NodePort , LoadBalancer 表示把k8s部署在虚拟机上,而虚拟机在云盘上,而云盘支持一键调用,自动触发在集群的外部创建一个负载均衡器,

1.  我们先来说clusterIP这种资源的Service的创建 。

在 svc.spec.ports  的文档中 发现有三种类型的端口:  nodePort    <integer>    外部节点的端口,在service的类型是nodePort才有用

port    <integer> -required-     : service暴露的端口                     targetPort    <string>  :  容器的端口 

在spec中的slector中有什么样的字段 :  selector <map[string]string>  :只支持等值的字段,不支持比较复杂的字段

给出清单定义中的内容:

apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: default
spec:
  selector:
    app: redis
    role: logstor
  clusterIP: 10.97.97.97
  type: ClusterIP
  ports:
  - port: 6379
    targetPort: 6379

[root@server1 ~]# kubectl apply -f redis-svc.yaml
service/redis created
[root@server1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP    7d
redis        ClusterIP   10.97.97.97   <none>        6379/TCP   8s       那么这个端口就是定义的端口   :  979797

[root@server1 ~]# 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","ports":[{"por...
Selector:          app=redis,role=logstor
Type:              ClusterIP
IP:                10.97.97.97
Port:              <unset>  6379/TCP
TargetPort:        6379/TCP
Endpoints:         10.244.2.62:6379          这个后端的pod的地址
Session Affinity:  None
Events:            <none>

 

那么service是不会直接到Pod的,service会直接到endpoints资源,那么endpoints就是地址+端口 ,然后再由endpoints关联到后端的pod,只不过我们再理解的时候就好像是service直接被pod关联了,那么我们可以手动的创建endpoints 。

 

资源记录:   SVC_NS_NAME.DOMAIN.LTD.         集群默认的域名是 : svc.cluster.local    默认的格式:redis.default.svc.cluster.local

 

下来我们要创建一个NodePort类型的service资源,怎么创建? 思路: 我们只要在之前的资源配置中修改type就可以了:

下面是nodePort的资源的定义清单:   注: 注意:node'port的端口,这个端口不能是节点上已经存在的端口,否则会覆盖

apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  selector:
    app: myapp
  clusterIP: 10.99.99.99
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080

[root@server1 ~]# kubectl apply -f myapp-svc.yaml
service/myapp created
[root@server1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        7d
myapp        NodePort    10.99.99.99   <none>        80:30080/TCP   6s
redis        ClusterIP   10.97.97.97   <none>        6379/TCP       15m
[root@server1 ~]# kubectl describe svc myapp
Name:                     myapp
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"myapp","namespace":"default"},"spec":{"clusterIP":"10.99.99.99","ports":[{"nod...
Selector:                 app=myapp
Type:                     NodePort
IP:                       10.99.99.99
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.1.66:80,10.244.1.67:80,10.244.1.69:80 + 2 more...
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

下来我们在集群之外的节点上对我们的集群中的service对象的实例进行测试 :

[root@loaclhost kiosk]# while true; do curl http://172.25.254.1:30080/hostname.html  ; sleep 1; done
myapp-deploy-69b47bc96d-gzlrk
myapp-deploy-69b47bc96d-92vkp
myapp-deploy-69b47bc96d-gzlrk
myapp-deploy-69b47bc96d-s4qlh
myapp-deploy-69b47bc96d-57vph
myapp-deploy-69b47bc96d-92vkp
myapp-deploy-69b47bc96d-x97jg
myapp-deploy-69b47bc96d-gzlrk

.....................

除此之外我们还可以对我们service中的pod做滚动更新;

 

下来我们说一下另一种类型的LoadBalancer :   下面我们简单的说一下它的原理  :

比如说: 你再阿里云上买了四个虚拟主机 ,在四个虚拟主机上部署了k8s集群,这个集群可以于底层的公有云交互,能够调度底层的iaaps,调度的时候能够请求外部的节点, 那么在其中的三个pod中会对外开放一个端口,这个三个节点的端口上提供相应的服务,他们会自动通过底层的iaas的负载均衡器的时候自动的去连接,那么客户通过外部的阿里云的客户端访问的时候,会先访问内部的负载均衡器,那么由负载均衡器调度到相应的node节点上 ,nodeport需要把请求转发给service,再由service由集群内部负载至pod对象上,这是一个两级的负载均衡。

 

第四种的资源类型 : ExternalName   

作用: 用于在集群中实现搭建一个服务,这个service的服务的端点并不是本地的pod,那么将这个service关联到外部的客户端,那么在pod通过service访问外部的服务的时候,外部的服务先提交给nodeIP ,再由nodeIP转交给service,再由service转交给pod,那么pod就可以访问外部的服务了,这叫: 外部名称服务

externalName : 是一个name,而且很关键这个name必须被DNS解析 ,所以这个externalname 引用的时候,场景不太多 ,在其中的字段中也有支持的,  比如说是: 当k8s 内部的某个域名需要向根域名服务器解析的时候,可以使用这个方法来和外部的服务交互。

 

在service spec的字段中有个: SsssionAffinity 字段 ,默认情况下是基于源IP,是基于IPTABLES来进行调度的 ,如果我们要定义成ClientIP则表示我们要把来自同一个客户端的请求始终调度到同一个后端pod上去 。

那么我们下来演示一下效果,以path的方式对内部的资源进行添加 :

[root@server1 ~]# kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"ClientIP"}}'
service/myapp patched

[root@server1 ~]# kubectl describe svc myapp
Name:                     myapp
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"myapp","namespace":"default"},"spec":{"clusterIP":"10.99.99.99","ports":[{"nod...
Selector:                 app=myapp
Type:                     NodePort
IP:                       10.99.99.99
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.1.66:80,10.244.1.67:80,10.244.1.69:80 + 2 more...
Session Affinity:         ClientIP
External Traffic Policy:  Cluster
Events:                   <none>

在更改完成以后我们发现在来自同一个客户端的ip时候来自同一个后端的pod对象

[root@server1 ~]# while true ; do curl http://172.25.254.1:30080/hostname.html; sleep 1; done
myapp-deploy-69b47bc96d-x97jg
myapp-deploy-69b47bc96d-x97jg
myapp-deploy-69b47bc96d-x97jg
myapp-deploy-69b47bc96d-x97jg
myapp-deploy-69b47bc96d-x97jg
myapp-deploy-69b47bc96d-x97jg

那么除了ClientIP   我们更改成为 NONE

[root@server1 ~]# kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"None"}}'
service/myapp patched

那么None的效果就是在后端的任意的pod中随机的选择相应的pod资源进行访问。

那么service中还有一种类型成为  headlist :  无头

那么之前在service解析的时候,service_name : 其实就是Cluster  IP 是自动生成的,那么除此之外我们还可以手动的指定,那么无头就意味着没有service_name  即不手动的指定,也不自动的生成,那么service就会向pod去解析,解析为pod 的IP ---pod IP ,直达后面的pod 。

我们来看一下这个参数的效果: [root@server1 ~]# vim myapp-headless.yaml

apiVersion: v1
kind: Service
metadata:
  name: myapp-headless
  namespace: default
spec:
  selector:
    app: myapp
  clusterIP:   None                 将ClusterIP的地址直接指明为空,即表示 headless
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080

那么无头的解析的时候通常会有很多的,pod后端的地址,那么有头的解析的时候通常是固定的指定的地址 ,

我在使用dig 的时候系统报错了 : 如下:   如果dig 在正确的则可以看到相应的pod解析的地址

[root@server1 ~]# dig -t A myapp-svc.default.svc.cluster.local. @10.96.0.10

; <<>> DiG 9.9.4-RedHat-9.9.4-37.el7 <<>> -t A myapp-svc.default.svc.cluster.local. @10.96.0.1
;; global options: +cmd
;; connection timed out; no servers could be reached

上述的错误我们已经成功的解决了,如果有和我的情况相同的同仁们可以参考:

https://blog.csdn.net/qq_42339633/article/details/90112854

那么在解析后的service就是后端的地址的IP拉 : 我们来看一下

[root@server1 ~]#  dig -t A myapp-svc.default.svc.cluster.local. @10.96.0.10

; <<>> DiG 9.9.4-RedHat-9.9.4-37.el7 <<>> -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39381
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; 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. 5 IN A    10.244.1.70
myapp-svc.default.svc.cluster.local. 5 IN A    10.244.1.71
myapp-svc.default.svc.cluster.local. 5 IN A    10.244.1.73
myapp-svc.default.svc.cluster.local. 5 IN A    10.244.2.65
myapp-svc.default.svc.cluster.local. 5 IN A    10.244.2.66

;; Query time: 1 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Sat May 11 18:44:54 CST 2019
;; MSG SIZE  rcvd: 319

那么我们还可以使用nslookup在pod内部对名称进行解析:

[root@server1 ~]# kubectl exec -it redis-5b5d6fbbbd-bfs6j -- /bin/sh
/data # 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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值