前言:在本章的内容中,注意一些域名的访问,要在自己的win中hosts文件中做映射欧

一、Service 的概念

Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略 – 通常称为微服务。 这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector

因为这三个pod都有 标签app=webapprole-frontend,所以都爱莫能助最上面的那个 svc,所以我们可以通过svc提供的ip和端口来访问内部的三个pod,后续如果pod的ip发生改变,或者增加减少pod,都会在svc中记录,我们不需要关系,目前svc只有一个轮询的算法。

Service能够提供负载均衡的能力,但是在使用上有以下限制

  • 只提供 4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的。(后续可以使用 igneress模块来满足七层)

二、Service 的类型

Service 在 K8s 中有以下四种类型

项目 Value
ClusterIp 默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP,即other-pod也在当前节点,可以通过当前节点的svc来访问nginx-deployment的三个pod
NodePort 在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 : NodePort 来访问该服务;但是这个nginx这个地方就需要我们自己做了,对于下面一个类型LoadBalancer可以花钱让云厂商提供,这也是这两者的区别了。
LoadBalancer 在 NodePort 的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到: NodePort;
ExternalName 把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持;

三、Service 的实现

VIP 和 Service 代理

在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。 kube-proxy 负责为 Service 实现了一种VIP(虚拟 IP)的形式,而不是 ExternalName 的形式。 在 Kubernetes v1.0 版本,代理完全在 userspace。在Kubernetes v1.1 版本,新增了 iptables代理,但并不是默认的运行模式。 从 Kubernetes v1.2 起,默认就是iptables 代理。 在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理
在 Kubernetes 1.14 版本开始默认使用 ipvs 代理在 Kubernetes v1.0 版本, Service 是 “4层”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了Ingress API(beta 版),用来表示 “7层”(HTTP)服务

即三种方式

  • 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 : 不排队调度

四、Service 类型实验

注意以下的实验的svc的实现,是根据你的svc的具体实现来处理的,比如下面的文章都是说使用iptables,如果你使用的是 ipvs ,那么把文章中对应的 iptables 的字段换成 ipvs,看文档即可

4.1、ClusterIP

clusterIP 主要在每个 node 节点使用 iptables(如这里换成ipvs),将发向 clusterIP 对应端口的数据,转发到 kube-proxy 中。然后 kube-proxy 自己内部实现有负载均衡的方法,并可以查询到这个 service 下对应 pod 的地址和端口,进而把数据转发给对应的 pod 的地址和端口


为了实现图上的功能,主要需要以下几个组件的协同工作:

  • apiserver

用户通过kubectl命令向apiserver发送创建service的命令,apiserver接收到请求后将数据存储到etcd中

  • kube-proxy

kubernetes的每个节点中都有一个叫做kube-porxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的iptables (如这里换成ipvs)规则中

  • iptables

使用NAT等技术将virtualIP的流量转至endpoint中

先创建deployment

vim svc-deployment.yaml

内容如下:

apiVersion: apps/v1
kind: Deployment # 类型
metadata:name: myapp-deploy  # 名称namespace: default
spec:replicas: 3 # 副本数selector:matchLabels:app: myapp  # 当前 deployment 只管理 标签为 app=myapp 和 release=stabel的podrelease: stabeltemplate:metadata:labels:app: myapp  # 为当前pod 设置 标签,不然无法被当前deployment 管理,以及后面的svc管理release: stabelenv: testspec:containers:- name: myappimage: wangyanglinux/myapp:v2imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80

创建svc,注意svc的标签选择,一定要匹配到对应的pod

vim svc.yaml

内容如下

apiVersion: v1
kind: Service
metadata:name: myapp # 这个svc的名称namespace: default
spec:type: ClusterIP  # 类型,这个类型只能集群内部访问selector:app: myapp  # 注意这里的标签选择,要能选择到前面的那些pod,不然这个svc就创建了个寂寞,没有可以映射的podrelease: stabelports:- name: httpport: 80targetPort: 80

查看svc

ipvsadm -Ln


2.702.691.66 就是那三个对应的pod地址

4.2、headless(一种特殊的 clusterIp)

创建,至于deployment 采用4.1中的的即可

vim svc-none.yaml

具体内容如下:

piVersion: v1
kind: Service
metadata:name: myapp-headlessnamespace: default
spec:selector:app: myappclusterIP: "None"  # 只有这里和 clusterIP 类型不同ports: - port: 80targetPort: 80


我们每创建一个svc,都会在k8s的coredns中记录

kubectl ge pod -n kube-system -o wide

# 对 svcname.namespece.svc.cluster.local. 使用 10.224.0.7(选择10.244.0.6也行看上面截图,二个ip选一个)来解析
dig -t A myapp-headless.default.svc.cluster.local. @10.224.0.7

解析结果如下,意思就是我们也可以进行域名访问(em…感觉不是那么的靠谱,好像不是这个意思,哈哈哈哈

4.3、node port

一个pod可以对应多个 svc,即你可以通过一号svc访问这个pod,也可以根据二号svc来访问它,M-N(多对多)的关系。
至于deployment 采用4.1中的的即可

vim nodeport.yaml

内容如下

apiVersion: v1
kind: Service
metadata:name: myappnamespace: default
spec:type: NodePortselector:app: myapp # 当然这个标签的意义还是需要选择的对应的pod,不然这个svc下面是空的,没啥意义release: stabelports:- name: httpport: 80targetPort: 80


外网访问,并且是所有的节点都开放了这个端口,都可以访问



通过查看svc 的ipvs(这里使用的实现是ipvs)的路由规则也是能看出来的

ipvsadm -Ln

4.4、LoadBalancer

loadBalancer 和 nodePort 其实是同一种方式。区别在于 loadBalancer 比 nodePort 多了一步,就是可以调用 cloud provider 去创建 LB 来向节点导流,所以需要云供应商来提供,花钱。

4.4、ExternalName

这种类型的 Service 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容( 例如:hub.atguigu.com )。ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。这样一旦你在k8s集群内部访问xxx就会访问到外部的 hub.atguigu.com(可以参考前面的几种类型的图示说明),意义就是把外部的流量引入到k8s内部,且当外部地址改变时,不需要在k8s内部应用的地方一个一个的去改,而内部只需要引用这个svc的名称,通过这个名称来访问,发生改变时修改这个svc的配置文件即可,其它都不需要动

创建

vim ex.yaml

具体内容

kind: Service
apiVersion: v1
metadata:name: my-service-1 # 我们直 svc 一旦创建,集群内部就可以根据 svc的名称访问namespace: default
spec:type: ExternalNameexternalName: hub.atguigu.com # 外部服务的域名,当然你也可以换成ip


当查询主机 my-service-1.defalut.svc.cluster.local (SVC_NAME.NAMESPACE.svc.cluster.local )时,集群的DNS 服务将返回一个值 my.database.example.com 的 CNAME 记录。访问这个服务的工作方式和其他的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发

# 对 svcname.namespece.svc.cluster.local. 使用 10.224.0.7(选择10.244.0.6也行看上面截图,二个ip选一个)来解析
dig -t A my-service-1.default.svc.cluster.local. @10.224.0.7

五、Service 增强之七层代理 Ingress

Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx
Ingress-Nginx 官方网站:https://kubernetes.github.io/ingress-nginx/


大致来说就是,我们写配置文件,它帮我们在nginx的conf文件中补充。

5.1、前置环境部署

如果有疑问,也可以看看网上其它的文章 https://blog.csdn.net/zhangjunli/article/details/107545984 这个还不错。

ingress-nginx的部署方式有多种,本文介绍nodeport方式(还有DaemonSet等等方式,这个上网搜索一下这个部署的文章就有很详细的说了,这里就不展开了),下面都是可以选择的方案
总的来说我们前置的条件需要部署2个,一个官方的 ingress-nginx,另一个是官方的 svc(方式有很多,这里采用nodePort方式),这个两个官方都提供的模板yaml文件

1、下载mandatory.yaml文件:

wget https://raw.githubusercontent.com/kubernetes/ingressnginx/master/deploy/static/mandatory.yaml

然后修改文件中的镜像:registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.25.1 改为阿里云的,这样下载会快很多,而且可能国外的你下载不了。

#部署
kubectl apply -f mandatory.yaml

查看,注意,它创建在 ingress-nginx的名称空间中,如果想更改也可以,修改那个yaml文件,修改就行。

2、编辑service-nodeport.yaml(nodeport方式需要额外使用这个文件)
创建 ingress的node port 模式的svc ,下载,部署

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.3/deploy/static/provider/baremetal/deploy.yamlkubectl apply -f deploy.yaml

查看,注意它也创建在 ingress-nginx的名称空间中,后面这个端口31345就是后面我们访问的端口(域名加上端口),而对于https来说就是后面的31802

5.2、自己的服务(一个ingress对应一个我们的svc)

上面前置准备已经做好,那么接下来我们就可以部署自己的了,先部署一套如下

1、创建自己的 deployment 和 svc

vim ingress.http.yaml

内容如下,注意一个yaml文件里面可以有多个类型的控制器pod,或者非控制器pod,只要以---分割即可,这样可以让其他开发人员知道这两个组件是一起的,后续删除的时候,也可以根据文件删除。

apiVersion: extensions/v1beta1
kind: Deployment  # 先创建一个deployment
metadata:name: nginx-dm
spec:replicas: 2template:metadata:labels:name: nginx  # 标签意义就不再重复说了spec:containers:- name: nginximage: wangyanglinux/myapp:v1imagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service   # 再创建一个自己的 svc
metadata:name: nginx-svc
spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx  # 管理上面的pod


2、配置后端程序的ingress

这个ingress就是会管理我们自己的svc和外部域名的关联的

vim ingress1.yaml

内容如下, 注意这里的kind是 ingress 的类型欧

apiVersion: extensions/v1beta1
kind: Ingress  # 注意这里是 ingress 的类型欧
metadata:name: nginx-test
spec:rules:- host: www1.atguigu.comhttp:paths:- path: /backend:serviceName: nginx-svc  # 说明外部访问 www1.atguigu.com 就是访问内部我们上面定义的那个 nginx-svc(前面定义的我们自己那个svc的名称)servicePort: 80

3、访问

  • 注意这里的域名是我们前面配置的,而且不要忘记防护墙以及win的host域名解析欧
  • 域名访问的时候需要加上端口,这个端口是我们前置准备里面的那个nodePort暴露的端口

5.3、自己的服务(一个ingress对应多个我们的svc)

这中模式,就是对上面的5.2的一个加强而已,其实k8s也就是会在nginx里面多做一个域名的分流而已。

1、创建我们的一套服务(deployment1 和 svc1)

vim deploment1.yaml

内容如下,注意欧这里的标签名称不能等下和后面的第二套管理混淆了,不能一样,这个不用解释了把。

apiVersion: extensions/v1beta1
kind: Deployment  # 先创建一个deployment
metadata:name: deployment1   # 名称为 deployment1
spec:replicas: 2template:metadata:labels:name: nginx1  # 标签意义就不再重复说了spec:containers:- name: nginximage: wangyanglinux/myapp:v1imagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service   # 再创建一个自己的 svc
metadata:name: svc-1
spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx1  # 管理上面的pod

创建

2、创建我们的二套服务(deployment2 和 svc2)

vim deploment2.yaml

内容如下,注意欧这里的标签名称不能等下和后面的第一套管理混淆了,不能一样

apiVersion: extensions/v1beta1
kind: Deployment  # 先创建一个deployment
metadata:name: deployment2   # 名称为 deployment2
spec:replicas: 2template:metadata:labels:name: nginx2  # 标签意义就不再重复说了spec:containers:- name: nginximage: wangyanglinux/myapp:v2imagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service   # 再创建一个自己的 svc
metadata:name: svc-2
spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx2  # 管理上面的pod

第二个svc以及下面关联的 deployment

3、创建ingress来管理上面的两套
这个ingress就是会管理我们自己的svc和外部域名的关联的

vim ingress-two.yaml

内容如下, 注意这里的kind是 ingress 的类型欧

apiVersion: extensions/v1beta1
kind: Ingress  # 注意这里是 ingress 的类型欧
metadata:name: nginx-test
spec:rules:- host: www1.atguigu.comhttp:paths:- path: /backend:serviceName: svc-1  # 说明外部访问 www1.atguigu.com 就是访问内部我们上面定义的那个 svc-1(前面定义的第一套我们自己那个svc的名称)servicePort: 80- host: www2.atguigu.comhttp:paths:- path: /backend:serviceName: svc-2  # 说明外部访问 www2.atguigu.com 就是访问内部我们上面定义的那个 svc-2(前面定义的第二套我们自己那个svc的名称)servicePort: 80

查看


其实这个ingress 就是帮忙我们在nginx增加映射分流关系。

5.4、配置https

1、创建一套我们的体系(即deployment 和 svc),这里以3为代号,前面的是1和2

apiVersion: extensions/v1beta1
kind: Deployment  # 先创建一个deployment
metadata:name: deployment3   # 名称为 deployment3
spec:replicas: 2template:metadata:labels:name: nginx3  # 标签意义就不再重复说了spec:containers:- name: nginximage: wangyanglinux/myapp:v3imagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service   # 再创建一个自己的 svc
metadata:name: svc-3
spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx3  # 管理上面的pod

查看我们的体系

2、创建 ingress
创建证书,以及 cert 存储方式

# 创建证书 openssl req -x509 -sha256 -nodes -days 有效天数 -newkey rsa:2048 -keyout 输出文件 -out 输出证书 -subj "/CN=nginxsvc/O=nginxsvc"
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
# 生成  kubectl create secret tls 类型(这个很重要,后面我们配置ingress的时候,类型指定要和这个一样) --key 上面生成的key --cert 上面生成的crt
kubectl create secret tls tls-secret --key tls.key --cert tls.crt

ingress的内容

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: nginx-test
spec:tls:- hosts:- www3.aiguigu.comsecretName: tls-secret # 注意这个类型跟上面 kubectl 的那个说的类型必须一致rules:- host: www3.aiguigu.comhttp:paths:- path: /backend:serviceName: svc3servicePort: 80

查看,注意这里是https即443,所以我们访问的端口就是后面的31802

3、结果

5.5、http的验证

其实这里的http验证,就是nginx的验证,我们配置的就是nginx,也是因为我们选择的ingress的ingx的实现。

1、生成用户和密码凭证

# 下载nginx的基础验证的模块 httpd
yum -y install httpd
# 使用htpasswd生成证书  htpasswd -c 证书文件 用户名(后面会让你输入密码)
htpasswd -c auth foo
# 使用这个证书文件 kubectl create secret generic basic-auth --from-file=上面生成的证书文件
kubectl create secret generic basic-auth --from-file=auth

2、创建ingress
这里就不再创建一套我们的体系了,我们可以用前面的 svc1的体系,注意svc1的体系是80即http的是没有https的欧

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: ingress-with-auth # 这个ingress的名称annotations:nginx.ingress.kubernetes.io/auth-type: basicnginx.ingress.kubernetes.io/auth-secret: basic-authnginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
spec:rules:- host: auth.atguigu.com # 访问的域名http:paths:- path: /backend:serviceName: svc-1 # 使用svc-1的体系servicePort: 80

查看

5.6、Nginx 进行重写

意思我们可以把nginx的一些配置规则,放到yaml文件里面,k8s的ingress会帮我们写入它创建的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 定义Controller必须重定向的应用程序根,如果它在’/'上下文中 字符串
nginx.ingress.kubernetes.io/use-regex 指示Ingress上定义的路径是否使用正则表达式 布尔

示例,当访问 www4.atguigu.com 时 跳转到 http://www.baidu.com

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: nginx-testannotations:nginx.ingress.kubernetes.io/rewrite-target: http://www.baidu.com
spec:rules:- host: www4.atguigu.com http:paths:- path: /backend:serviceName: ngin

(五)k8sservice相关推荐

  1. 五分钟搭建一个基于BERT的NER模型

    BERT 简介 BERT是2018年google 提出来的预训练的语言模型,并且它打破很多NLP领域的任务记录,其提出在nlp的领域具有重要意义.预训练的(pre-train)的语言模型通过无监督的学 ...

  2. Spring Data JPA 五分钟快速入门和实践

    Spring Data JPA(类似于Java Web 中的 DAO) 操作声明持久层的接口(Repository) 三个核心接口: CrudRepository PagingAndSortingRe ...

  3. 操作系统学习笔记 第五章:文件管理(王道考研)

    本文章基于网课: 2019 王道考研 操作系统 考试复习推荐资料:操作系统复习总结 - 百度文库 (baidu.com) 需要相关电子书的可以关注我的公众号BaretH后台回复操作系统 第一章:操作系 ...

  4. 王道考研 计算机网络笔记 第五章:传输层

    本文基于2019 王道考研 计算机网络: 2019 王道考研 计算机网络 个人笔记总结 第一章:王道考研 计算机网络笔记 第一章:概述&计算机网络体系结构 第二章:王道考研 计算机网络笔记 第 ...

  5. TVM性能评估分析(五)

    TVM性能评估分析(五) Figure 3. A futher speed up with operator fusion Table 1. Performance issue of cuBLAS' ...

  6. AlexeyAB DarkNet YOLOv3框架解析与应用实践(五)

    AlexeyAB DarkNet YOLOv3框架解析与应用实践(五) RNNs in Darknet 递归神经网络是表示随时间变化的数据的强大模型.为了更好地介绍RNNs,我强烈推荐Andrej K ...

  7. 大数据调度平台Airflow(五):Airflow使用

    目录 Airflow使用 一.Airflow调度Shell命令 1.首先我们需要创建一个python文件,导入需要的类库 2.实例化DAG 3.定义Task 4.设置task依赖关系 5.上传pyth ...

  8. 2021年大数据ELK(五):Elasticsearch中的核心概念

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 Elasticsearch中的核心概念 一.索引 index 二 ...

  9. 2021年大数据Kafka(五):❤️Kafka的java API编写❤️

    全网最详细的大数据Kafka文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 Kafka的java API编写 一.生产者代码 第一步: ...

最新文章

  1. 海量数据处理之蓄水池抽样算法
  2. 数据库查询近七天的数据
  3. 如何在Node.js(Javascript)中等待,我需要暂停一段时间?
  4. 5!(简单的了解for循环与递归的区别)
  5. 【MPS最佳实践】媒体工作流转码
  6. GPU Gems 1: Chapter 22. Color Controls
  7. 【iOS】Swift3 Swift2 String转int,从TextField里面获取Int类型的数值
  8. 3dtiles加载调度原理分析
  9. Microsoft SQL Server数据库学习(一)
  10. win10 家庭版 升级专业版
  11. onload 属性的作用
  12. 这项镜头贴膜技术背后,藏着让VR变轻巧的秘密
  13. ribbon类同层次图
  14. 击碎“基因决定论”和“1万小时理论”认知误区!这本书告诉你怎么快速成长!
  15. CTS fail 问题总结
  16. 物 理 学 简 介(一)
  17. 今日睡眠质量记录75
  18. 面试问题1:谈谈你对加班的看法
  19. kubernetes flannel 网络
  20. 游戏建模三大软件:3Dmax、Maya、zbrush 应该如何学才好?

热门文章

  1. 《Multiple UAV exploration of an unknown region》翻译
  2. 2022年山东省职业院校技能大赛高职组 “软件测试”赛项竞赛任务书
  3. mysql5.5 和mysql8区别
  4. 树莓派+motion安装摄像头实现远程监控
  5. 互联网的下岗潮马上要来
  6. Phoenix Salted Table
  7. 你连这些都不会,怎么过的网络面试?
  8. WebService系列之SSL异常handshake failure处理方法
  9. C/C++的指针与数组
  10. 西班牙馅饼 ECNU3528 java