「走进k8s」Kubernetes1.15.1的service(25)

上节课说了job 和 定时的job,其实这个应用场景很少,之前也说了pod,deployment,pod的生命周期。也了解了pod的生命是有限的,死亡过后就不会复活了。rc和deployment可以动态的创建和销毁pod,我们的每个pod都有自己的ip地址,但是如果pod重新启动后ip地址就会发生变化,因为重建了,就会重新分配ip,这样就会带来一个问题:后端的微服务集合为前端的集合提供API服务,前端把ip地址写死了,结果后端挂了,但是通过自动扩缩容又起起来了,但是ip非常可能发生了变化,导致前端也无法正常的访问,这如何解决呢?引入一个名词service。

(一)service

  • ① 场景解决

对于后端的服务ip发生变化,为了解决,可能在前端请求后端之前,增加一个nginx或者apache反向代理,每次让前端访问nginx,当后端的ip发生变化的时候,修改nginx的配置就可以了。每次都要修改也挺麻烦的,nginx有个属性upstream选项,可以动态的配置访问地址,可以通过后端每次重启的服务进行服务的注册,nginx获取注册后的ip地址然后动态的让前端请求进行转向到新的ip上,这样就可以解决了。 服务注册:一般zookeeper,consul,在k8s里面是etcd。

既然需要中间件,那是不是k8s里面也有一个对象可以充当这个对象,是的,那就是service。

  • ② service定义

每个 Pod 本身会带著一或多个不等的标志在身上,当 Service 指定存取某些特定的标志时,Label Selector 会根据 Pod 身上自带的标籤进行分组,并回传 Service 所要求的 Pod 资讯。
下图右边共有三种分别为黄、绿、蓝色的 Pod,正代表着集群内有三种不同的 Pod 群组,当今天收到使用者请求时,便会将请求送至对应的蓝色群组内的其中一个 Pod 进行处理。

  • ③ service存在的意思

Service 作为中介层,避免使用者和 Pod 进行直接连线,除了让我们服务维持一定弹性能够选择不同的 Pod 来处理请求外,某种程度上避免裸露无谓的 Port 而导致资安问题。另外,也体现出云服务架构设计中一个非常重要的观念:
对于使用者而言,仅需知道有人会处理他们的请求,而毋须知道实际上处理的人是谁。

  • ④ service的官网

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#service-v1-core

(二)k8s中的三种IP

(三)service

  • ① 源码

先创建一组deployment-demo-nginx,生成pod,跟service进行关联。

nginx-deploy.yaml

---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    app: nginx-demo
spec:
  replicas: 3
  revisionHistoryLimit: 15
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: nginxweb

demo-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: demoservice
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: nginxweb

demo-service.yaml 中的 spec.selector.app 对应的是 nginx-deploy.yaml 中template。metadata.labels.app 名称必须一致。他们通过这样来对应。下面还有个80端口也是对应的一种方式。

  • ② 执行yaml

nginx-deploy.yaml
demo-service.yaml

vi  nginx-deploy.yaml

vi demo-service.yaml

kubectl apply -f nginx-deploy.yaml
kubectl apply -f demo-service.yaml

查看service情况。Endpoints就是service会持续的监听这个selector。

kubectl get svc

kubectl describe svc demoservice

targetPort 不光可以设置成端口,也可以设置成一个字符串。我进行了字符串的对应 nginxweb。 如果其他的pod的名称也叫 app= nginx, service 也会进行匹配。

  • ③ 进入一个pod尝试访问service

上边service的ip :10.107.50.167

kubectl run -it testservice --image=busybox /bin/sh
wget -q -O- 10.107.50.167

service 提供的服务其实指向的deployment对应的pod,pod内部是nginx。 直接访问service的服务其实就是指向的某个nginx。

(四)service

在Kubernetes集群中,每个Node会运行一个kube-proxy进程, 负责为Service实现一种 VIP(虚拟 IP,就是我们上面说的clusterIP)的代理形式,现在的Kubernetes中默认是使用的iptables这种模式来代理。这种模式,kube-proxy会监视Kubernetes master对 Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会添加上 iptables 规则,从而捕获到达该 Service 的 clusterIP(虚拟 IP)和端口的请求,进而将请求重定向到 Service 的一组 backend 中的某一个个上面。 对于每个 Endpoints 对象,它也会安装 iptables 规则,这个规则会选择一个 backend Pod。 默认的策略是,随机选择一个 backend。 我们也可以实现基于客户端 IP 的会话亲和性,可以将 service.spec.sessionAffinity 的值设置为 “ClientIP” (默认值为 “None”)。 另外需要了解的是如果最开始选择的 Pod 没有响应,iptables 代理能够自动地重试另一个 Pod,所以它需要依赖 readiness probes。

  1. Client 访问service,service访问pod节点,如果第一次访问的pod1,通过亲和性下次还是访问pod1
  2. Client访问pod2没有响应,iptables会自动重试到另一个pod上边去,可能是pod1或者pod3,根据设计的策略来。
  3. pod1,pod2,pod3,如果少了一个pod2,肯定也是apiserver操作导致的,kube-proxy他会实时的监听apiserver。api 通知 porxy 移除 pod2。

(五)Service 类型

  • ① ClusterIP

默认模式,只能在集群内部访问。

  • ② NodePort

在每个节点上都监听一个同样的端口号(30000-32767),ClusterIP和路由规则会自动创建。集群外部可以访问:联系到集群内部服务,可以配合外部负载均衡使用(我现在公司用的就是这个模式配合阿里云的SLB)。

该端口将通过 Service 的 spec.ports[*].nodePort 字段被指定,如果不指定的话会自动生成一个端口。

kubectl get svc

请求节点地址:http://192.168.86.100:31298/
http://192.168.86.101:31298/ 都可以进行访问

  • ③ LoadBalancer

要配合支持公有云负载均衡使用比如GCE、AWS。其实也是NodePort,只不过会把:自动添加到公有云的负载均衡当中。

  • ③ ExternalName

创建一个dns别名指到service name上,主要是防止service name发生变化,要配合dns插件使用。

PS:基本上service就讲解完毕了,了解下service的原理和对应的service的类型。其实Service的内容远远不止这些,这些是一些比较常用的功能,如果在平时用到可以参考一下。

>>原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!
>>原文链接地址:「走进k8s」Kubernetes1.15.1的service(25)
上一篇: 下一篇:

发表评论

电子邮件地址不会被公开。 必填项已用*标注