kubernetes之Service介绍

Service

Pod IP仅仅是集群内可见的虚拟IP,外部无法访问。
Pod IP会随着Pod的销毁而消失,当ReplicaSet对Pod进行动态伸缩时,Pod IP可能随时随地都会变化,这样对于我们访问这个服务带来了难度。
因此,Kubernetes中的Service对象就是解决以上问题的实现服务发现核心关键。

Service的类型

在Serivce定义时,我们需要指定spec.type字段,这个字段拥有四个选项:
● ClusterIP:默认值。给这个Service分配一个Cluster IP,它是Kubernetes系统自动分配的虚拟IP,因此只能在集群内部访问。
● NodePort:将Service通过指定的Node上的端口暴露给外部。通过此方法,访问任意一个NodeIP:nodePort都将路由到ClusterIP,从而成功获得该服务。
● LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 :NodePort。此模式只能在云服务器(AWS等)上使用。
● ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。需要 kube-dns 版本在 1.7 以上。

kubernetes之Service介绍_第1张图片

Service的代理

● userspace 代理模式
● iptables 代理模式
● ipvs 代理模式:

这种模式,kube-proxy 会监视 Kubernetes Service 对象和 Endpoints ,调用 netlink 接口以相应地创建 ipvs 规则并定期与 Kubernetes Service 对象和Endpoints 对象同步 ipvs 规则,以确保 ipvs 状态与期望一 致。访问服务时,流量将被重定向到其中一个后端 Pod 。与 iptables 类似,ipvs 于 netfilter 的 hook 功能,但使用哈希表作为底层数据结构并在内核空间中工作。这意 味着 ipvs 可以更快地重定向流量,并且在同步代理规则时具有更好的性能。此外,ipvs 为负载均衡算法提供了更多选项,例如:
rr :轮询调度
lc :最小连接数
dh :目标哈希
sh :源哈希
sed :最短期望延迟
nq : 不排队调度

kubernetes之Service介绍_第2张图片

ClusterIp

kubernetes之Service介绍_第3张图片

kubernetes之Service介绍_第4张图片

NodePort

kubernetes之Service介绍_第5张图片

Ingress
组成
ingress controller
  将新加入的Ingress转化成Nginx的配置文件并使之生效
ingress服务
  将Nginx的配置抽象成一个Ingress对象,每添加一个新的服务只需写一个新的Ingress的yaml文件即可
工作原理
1.ingress controller通过和kubernetes api交互,动态的去感知集群中ingress规则变化,
2.然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置,
3.再写到nginx-ingress-control的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,
4.然后reload一下使配置生效。以此达到域名分配置和动态更新的问题。

kubernetes之Service介绍_第6张图片

测试部署
官网:https://kubernetes.github.io/ingress-nginx/deploy/#quick-start
github:https://github.com/kubernetes/ingress-nginx/tree/nginx-0.30.0/deploy

kubernetes之Service介绍_第7张图片

$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml

$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

$ ll
总用量 12
-rw-r--r-- 1 root root 6637 9月  16 23:46 mandatory.yaml
-rw-r--r-- 1 root root  471 9月  16 23:36 service-nodeport.yaml
#修改mandatory.yaml修改kind为daemonset,ingress-controller镜像地址修改为阿里云地址,添加imagePullPolicy策略,并指定hostPort,将宿主机的80、443映射到容器的80与443
........
apiVersion: apps/v1
kind: DaemonSet
.............
spec:
  #replicas: 1
........
        - name: nginx-ingress-controller
          image: registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.30.0
          imagePullPolicy: IfNotPresent
........
       ports:
            - name: http
              containerPort: 80
              protocol: TCP
              hostPort: 80
            - name: https
              containerPort: 443
              protocol: TCP
              hostPort: 443
............


$ cat nginx-deployment.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx-service
spec:
  ports:
   - port: 80
     protocol: TCP
     targetPort: 80
  selector:
    app: nginx
   
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.sudytech.com:35000/library/nginx:1.15.9
        ports:
        - containerPort: 80
        
#创建ingress服务
$ cat ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
spec:
  rules:
    - host: www.aaa.com
      http:
        paths:
          - backend:
              serviceName: nginx-service
              servicePort: 80
            path: /
#serviceName对应nginx-deployment.yaml文件中Service的标签
#做本地测试即可
https部署测试
#自签发证书,可以使用下面的语句,也可以阅读自制https的博客
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/O=aaa/CN=*.aaa.com"

$ ll
总用量 8
-rw-r--r-- 1 root root 1131 9月  19 16:30 tls.crt
-rw-r--r-- 1 root root 1704 9月  19 16:30 tls.key

#导入证书文件到k8s secret(注意这边的nginx-test要和下面ingress.yaml文件中tls相对应)
$ kubectl create secret tls nginx-test --cert=tls.crt --key=tls.key
$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
nginx-test            kubernetes.io/tls                     2      53m

#创建https的ingrss.yaml文件
$ cat ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false" #是否开启强制跳转,true/false,默认开启
spec:
  tls:
  - hosts: 
    - www.aaa.com
    secretName: nginx-test
  #- hosts: 多域名配置
  # - www.bbb.com
  # secretName: nginx-bbb
  rules:
    - host: www.aaa.com
      http:
        paths:
          - backend:
              serviceName: nginx-service
              servicePort: 80
            path: /
   # - host: www.bbb.com
   #   http:
   #     paths:
   #      - backend:
   #          serviceName: nginx-service
   #          servicePort: 80
   #        path: /         
访问原理
Ingress-nginx与Service之间通过匹配serviceName绑定
Service相当于给外界提供访问pod的端口,如果不采用ingress-nginx,那么是由kube-proxy实现4层代理,只能通过ip访问,所以由NodePort的类型将端口暴露。如果采用ingress-nginx相当于在Service前面加了一层代理,访问会先经过ingress-nginx,这样Service的类型就不需要变更为NodePort,    
Nginx重写
名称 描述
nginx.ingress.kubernetes.io/rewrite-target 必须重定向流量的目标 URI
nginx.ingress.kubernetes.io/ssl-redirect 指示位置部分是否只能通过 SSL 访问(当 Ingress 包含证书时默认为 True) 布尔
nginx.ingress.kubernetes.io/force-ssl-redirect 即使 Ingress 未启用 TLS,也强制重定向到 HTTPS 布尔
nginx.ingress.kubernetes.io/app-root 定义控制器在/上下文中必须重定向的应用程序根
nginx.ingress.kubernetes.io/use-regex 指示在 Ingress 上定义的路径是否使用正则表达式 布尔
kubernetes之Service介绍_第8张图片

Pod与Service关联

两者之间通过标签关联,spec.template.metadata.labels为pod打上名为mediaplus-main的标签,Service的spec.selector需要与spec.template.metadata.labels值一致

apiVersion: v1
kind: Service
metadata:
  name: mediaplus-main
  labels:
    app: mediaplus-main
spec:
..............
  selector:
    app: mediaplus-main
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mediaplus-main
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mediaplus-main
  template:
    metadata:
      labels:
        app: mediaplus-main
    spec:
      containers:
        - name: mediaplus-main

Service与Ingress关联

Service只能实现四层代理 传输层,基于IP和端口
Ingress可以实现七层代理 应用层,基于应用协议转发,例如http协议
Ingress与Service之间通过匹配serviceName绑定,metadata.labels为Service打上mediaplus-main的标签,spec.rules.backend.serviceName的值需要与mediaplus-main保持一致

apiVersion: v1
kind: Service
metadata:
  name: mediaplus-main
  labels:
    app: mediaplus-main
spec:
..............
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  tls:
    - secretName: sign-secret
  rules:
.........
          - backend:
              serviceName: mediaplus-main
              servicePort: 3000
            path: /  

你可能感兴趣的:(kubernetes内容,kubernetes,运维)