k8s分享下-service 网络 卷

service

为什么需要Service?
因为直接通过pod的IP+port获取服务存在如下两个问题:
1)调用地址不稳定,pod可能出现故障,那么新的pod产生的IP和port都会发生变化
2)集群(多pod实例)场景无法自动实现负载均衡

service怎么解决的问题?
service本身有固定的Ip和port,且内部有负载均衡的实现,所以解决了上述问题

service的实例和创建
一个提供Web服务的RC:webapp-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
 name: webapp
spec:
 replicas: 2
 template:
  metadata:
   name: webapp
   labels:
    app: webapp
  spec:
   containers:
   - name: webapp
    image: tomcat
    ports:
    - containerPort: 8080
创建该RC kubectl create -f webapp-rc.yaml
获取Pod的Ip: kubectl get pods -l app=webapp -o yaml | grep podIP
通过Pod 的Ip和端口号直接访问服务 curl ip:8080

通过创建service,让客户端能够访问到两个Tomcat Pod的实例
方式1: kubectl expose rc webapp #通过kubectl expose实现
方式2: 定义并创建service:webapp-svc.yaml
apiVersion: v1
kind: Service
metadata:
 name: webapp
spec:
 ports:
 - port: 8081 #指定service的虚拟端口号
  targetPort: 8080 #对应到Pod容器的8080端口
 selector: 
  app: webapp #对应到拥有label(app=webapp)的Pod
kubectl create -f webapp-svc.yaml
kubectl get svc #对应端口 ip
访问service: curl ip:8081

service提供服务的实现原理:kube-proxy 组件,加上 iptables 来共同实现的。
一旦service被提交给 Kubernetes,那么 kube-proxy 就可以通过 Service 的 Informer 感知到这样一个 Service 对象的添加。而作为对这个事件的响应,它就会在宿主机上创建一条 iptables 规则。
经过该iptables 处理之后,访问 Service VIP 的 IP 包就已经变成了访问具体某一个后端 Pod 的 IP 包了。

service相关指令

获取svc列: kubectl get svc

获取某个svc对应的endpoints:kubectl get endpoints svcName 说明:service选中的pod称为其endpoints

获取svcName对应的service信息:kubectl get svc svcName
只有处于 Running 状态,且 readinessProbe 检查通过的 Pod,才会出现在 Service 的 Endpoints 列表里。并且,当某一个 Pod 出现问题时,Kubernetes 会自动把它从 Service 里摘除掉。

获取服务详情 :kubectl describe svc  svcName

k8s提供的负载均衡策略:
1)轮询模式,默认模式
2)会话模式:基于客户端IP地址进行的会话保持的模式,service.spec.sessionAffinity=ClientIP启用。


外部服务service

如系统需要将一个外部数据库作为后端服务进行连接。
1) 创建一个无label selector的service
apiVersion: v1
kind: Service
metadata:
 name: my-service
spec:
 ports:
 - protocol: TCP
  port: 80
  targetPort: 80
因为定义的service没有labelSelector,所以不会定义到任何Pod,需要手动创建一个和该service同名的Endpoint,用于指向实际的后端访问地址,
2) endPoint的配置文件内容如下:
kind: Endpoints
apiVersion: v1
metadat: 
 name: my-service #和上面service名称完全一致
subjects:
- address:
 - IP: 1.2.3.4
 ports:
 - port: 80
说明:上面没有标签选择器的Service建会被路由到用户手动定义的后端Endpoint上。

Headless Service

应用场景:
1)开发人员希望自己控制负载均衡的策略,不使用Service提供的默认负载均衡的功能。
2)应用程序希望知道属于同组服务的其他实例
原理:不为service设置clusterIp,仅通过Label selector将后端的Pod列表返回给调用的客户端。
下面是一个Hedaless Service定义实例:
apiVersion: v1
kind: Service
metadata:
 name: nginx
 labels:
  app: nginx
spec:
 ports:
 - port: 80
 clusterIP: None
 selector:
  app: nginx
说明:该service不再具有特定的clusterIp地址,对其进行访问会返回包含Label“app=nginx”的全部Pod列表。

集群外部访问Pod 

由于Pod和service的IP和port都是k8s集群范围内的虚拟概念,所以集群外的客户端无法访问。

Pod的两种实现方案:
1)设置容器级别的hostPort: 将容器应用的端口映射到物理机上
apiVersion: v1
kind: Pod
metadata:
 name: webapp
 labels:
  app: webapp
spec:
 containers:
 - name: webapp
  image: tomcat
  ports:
  - containerPort: 8080 #容器的端口
   hostPort: 8081 #物理机端口,通过物理机IP和该port可以访问
2)设置Pod级别的hostNetwork=true,将该Pod中所有容器的端口号都直接映射到物理机上。且默认hostPort等于containerPort
apiVersion: v1
kind: Pod
metadata:
 name: webapp
 labels:
  app: webapp
spec:
 hostNetwork: true 
 containers:
 - name: webapp
  image: tomcat
  ports:
  - containerPort: 8080 #容器的端口,自动映射到物理机8080的端口

集群外部访问Service

方式1:通过nodePort映射到物理机,同时设置service的类型为NodePort
通过node的物理Ip和暴露的nodePort暴露服务,但是没有办法进行负载均衡;
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  type: NodePort
  ports:
  - nodePort: 8080 #物理机Ip+端口可以访问服务
    targetPort: 80
    protocol: TCP
    name: http
  - nodePort: 443
    protocol: TCP
    name: https
  selector:
    run: my-nginx

说明:一般nodePort需要配合一些slb使用,达到负载均衡的效果。现在我们judge服务就是通过该方式实现的,存在的问题是如果增加节点,可能需要修改slb配置。

方式2: 1.7版本之后支持的一个新特性,叫作 ExternalName和externalIPs。
kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  type: ExternalName
  externalName: my.database.example.com

比如访问:此时可以直接访问my.database.example.com。

externalIPs实例:

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 9376
  externalIPs:
  - 80.11.12.10
80.11.12.10就是一个公有的Ip,在这里 Kubernetes 要求 externalIPs 必须是至少能够路由到一个 Kubernetes 的节点。

3 公有云上的 Kubernetes 服务。这时候,你可以指定一个 LoadBalancer 类型的 Service
如:
kind: Service
apiVersion: v1
metadata:
  name: example-service
spec:
  ports:
  - port: 8765
    targetPort: 9376
  selector:
    app: example
  type: LoadBalancer
在上述 LoadBalancer 类型的 Service 被提交后,Kubernetes 就会调用 CloudProvider 在公有云上为你创建一个负载均衡服务,并且把被代理的 Pod 的 IP 地址配置给负载均衡服务做后端。
kuebctl get svc :可以看到external-ip。我们就可以通过该ip+port来访问了。

4 ingress

由于每个LoadBalancer类别的Service 都要有一个负载均衡服务,所以这个做法实际上浪费成本,更希望看到 Kubernetes 为我内置一个全局的负载均衡器。然后,通过我访问的 URL,把请求转发给不同的后端 Service。

对应的就是Kubernetes 里的 Ingress 服务。
ingress对象的定义如下:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress
spec:
  tls:
  - hosts:
    - cafe.example.com
    secretName: cafe-secret
  rules:
  - host: cafe.example.com
    http:
      paths:
      - path: /tea
        backend:
          serviceName: tea-svc
          servicePort: 80
      - path: /coffee
        backend:
          serviceName: coffee-svc
          servicePort: 80
重点关注rules字段。
host:该Ingress对象的入口,即当用户访问 cafe.example.com 的时候,实际上访问到的是这个Ingress对象。
对应的值必须是一个标准的域名格式的字符串,而不能是 IP 地址。

path:定义具体规则,一个 path 都对应一个后端 Service,并且指明了对应的服务名称和端口。

实际的使用中,需要从社区里选择一个具体的 Ingress Controller,把它部署在 Kubernetes 集群里。
目前, Nginx、HAProxy、Envoy、Traefik 等,都已经为 Kubernetes 专门维护了对应的 Ingress Controller。

volume卷

有些应用是有状态的应用,如redis\mysql、文件存储服务,会涉及到数据存储,而容器空间会随着容器的销毁而回收,且容器之间不可以共享,所以就产生了卷。

可以这样理解卷:

一个特定的目录,该目录可以绕过容器的联合文件系统,并提供数据共享或持久化的功能。
卷可以在容器间共享和重用
对卷的修改立刻生效
对卷的修改不会对镜像产生任何影响

pod容器共享Volume
同一个pod中的多个容器能够共享Pod级别的存储卷Volume。即定义一个卷,然后将该卷挂在为多个容器的内部目录。
如下pod实例,pod-volume.yml内容如下:
apiVersion: v1
kind: Pod
metadata:
 name: volume-pod
spec:
 containers:
 - name: tomcat
  image: tomcat
  ports:
  - containerPort: 8080
  volumeMounts:
  - name: app-logs #使用名称为app-logs的卷
   mountPath: /usr/local/tomcat/logs #将卷挂载到该路径,这个路径是容器内的绝对路径
 - name: busybox
  image: busybox
  command: ["sh", "-c", "tail -f /logs/catalinz*.log"]
  volumeMounts:
  - name: app-logs
   mountPath: /logs
 volumse: #定义pod中的公共volume
 - name: app-logs #volume名称为app-logs
  emptyDir: {} #
说明:pod中定义了名称为app-logs的卷,然后应用到多个pod中。

emptyDir:k8s不显式声明宿主机目录的 Volume。所以,Kubernetes 也会在宿主机上创建一个临时目录,这个目录将来就会被绑定挂载到容器所声明的 Volume 目录上。此时并不关心卷定义在宿主机的哪个目录,主要是通过该目录,实现Pod中多个容器对卷的共享。

Kubernetes 也提供了显式的 Volume 定义,它叫作 hostPath。比如下面的这个 YAML 文件:
 ...   
    volumes:
      - name: nginx-vol
        hostPath: 
          path:  " /var/data"

上面两种卷都是基于宿主机目录的卷,是比较普通的卷,如果node出了问题或者 pod变换了node,都是可能出现问题的,有什么好的解决方案呢。

pv pvc storageClass

PV:PersistentVolume,“持久化 Volume”,指的就是这个宿主机上的目录,具备“持久性”。即:这个目录里面的内容,既不会因为容器的删除而被清理掉,也不会跟当前的宿主机绑定。这样,当容器被重启或者在其他节点上重建出来之后,它仍然能够通过挂载这个 Volume,访问到这些内容。比如一个 NFS 的挂载目录。

PVC : Pod 所希望使用的持久化存储的属性。
 

pvc定义
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: manual
  resources:
    requests:
      storage: 1Gi


pv定义:
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.244.1.4
    path: "/"


pod中使用pvc:
apiVersion: v1
kind: Pod
metadata:
  labels:
    role: web-frontend
spec:
  containers:
  - name: web
    image: nginx
    ports:
      - name: web
        containerPort: 80
    volumeMounts:
        - name: nfs
          mountPath: "/usr/share/nginx/html"
  volumes:
  - name: nfs
    persistentVolumeClaim:
      claimName: nfs #pvc名称
Pod创建之后,kubelet 就会把这个 PVC 所对应的 PV,也就是一个 NFS 类型的 Volume,挂载在这个 Pod 容器内的目录上。

pv和pvc的设计思想:
pvc:持久化存储的描述,类似“接口”
pv:持久化存储的实现部分,类似”实现类“
好处:作为开发者,我们只需要跟 PVC 这个“接口”打交道,而不必关心具体的实现是 NFS 还是 Ceph。

PVC 要真正被容器使用起来,就必须先和某个符合条件的 PV 进行绑定。
这里要检查的条件,包括两部分:
第一个条件,当然是 PV 和 PVC 的 spec 字段。比如,PV 的存储(storage)大小,就必须满足 PVC 的要求。
第二个条件,则是 PV 和 PVC 的 storageClassName 字段必须一样。这个机制我会在本篇文章的最后一部分专门介绍。

如果系统里并没有合适的 PV 跟它定义的 PVC 绑定,那会发生什么?
Pod 的启动就会报错。
然后如果创建了符合条件的PV,Kubernetes 能够再次完成 PVC 和 PV 的绑定操作,从而启动 Pod。

实现原理:k8s存在一个Volume Controller,查看当前每一个PVC,是不是已经处于 Bound(已绑定)状态。如果不是,那它就会遍历所有的、可用的 PV,并尝试将其与这个“单身”的 PVC 进行绑定。


PV 对象,又是如何变成容器里的一个持久化存储的呢?
容器的 Volume,其实就是将一个宿主机上的目录,跟一个容器里的目录绑定挂载在了一起。
“持久化 Volume”,指的就是这个宿主机上的目录,具备“持久性”,既不会因为容器的删除而被清理掉,也不会跟当前的宿主机绑定。这样,当容器被重启或者在其他节点上重建出来之后,它仍然能够通过挂载这个 Volume,访问到这些内容。
所以 hostPath 和 emptyDir 类型的 Volume不是持久化的。
持久化 Volume 的实现,往往依赖于一个远程存储服务,比如:远程文件存储(比如,NFS、GlusterFS)、远程块存储(比如,公有云提供的远程磁盘)等等。

以远程块存储为实例看pv实现原理
1)kubelet为Pod在宿主机上创建Volume目录,路径:
/var/lib/kubelet/pods//volumes/kubernetes.io~/
2)将 远程块存储 挂载到pod所在的宿主机
以Google Cloud 的 Persistent Disk为例,调用如下api:
$ gcloud compute instances attach-disk <虚拟机名字> --disk <远程磁盘名字>
3)格式化这个磁盘设备,然后将它挂载到宿主机指定的挂载点上,这个挂载点就是步骤一中volume的宿主机目录
4)kubelet 只要把这个 Volume 目录通过 CRI 里的 Mounts 参数,传递给 Docker;类似执行如下指令:
$ docker run -v /var/lib/kubelet/pods//volumes/kubernetes.io~/:/<容器内的目标目录> 我的镜像 ...


StorageClass

一个大规模的 Kubernetes 集群里很可能有成千上万个PVC,这就意味着运维人员必须得事先创建出成千上万个 PV。浪费资源,且难以维护。

Kubernetes为我们提供了一套可以自动创建PV的机制,即:Dynamic Provisioning,核心,在于一个名叫 StorageClass 的 API 对象。

storageClass的对象定义包含两部分:
第一,PV 的属性。比如,存储类型、Volume 的大小等等。
第二,创建这种 PV 需要用到的存储插件。比如,Ceph 等等。
Kubernetes 就能够根据用户提交的 PVC,找到一个对应的 StorageClass 了。然后,Kubernetes 就会调用该 StorageClass 声明的存储插件,创建出需要的 PV。

实例如下:sc.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: block-service
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
provisioner 字段的值是:kubernetes.io/gce-pd,这正是 Kubernetes 内置的 GCE PD 存储插件的名字。
parameters 字段,就是 PV 的参数。比如:上面例子里的 type=pd-ssd,指的是这个 PV 的类型是“SSD 格式的 GCE 远程磁盘”。

创建StorageClass
$ kubectl create -f sc.yaml

PVC 里指定要使用的 StorageClass 名字,pvc定义如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim1
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: block-service
  resources:
    requests:
      storage: 30Gi
Google Cloud 为例。当我们通过 kubectl create 创建上述 PVC 对象之后,Kubernetes 就会调用 Google Cloud 的 API,创建出一块 SSD 格式的 Persistent Disk。然后,再使用这个 Persistent Disk 的信息,自动创建出一个对应的 PV 对象。

有了 Dynamic Provisioning 机制,运维人员只需要在 Kubernetes 集群里创建出数量有限的 StorageClass 对象就可以了。当开发人员提交了包含 StorageClass 字段的 PVC 之后,Kubernetes 就会根据这个 StorageClass 创建出对应的 PV。

pod pv pvc storageClass之间的关系如下图:

k8s分享下-service 网络 卷_第1张图片

在这个体系中:
PVC 描述的,是 Pod 想要使用的持久化存储的属性,比如存储的大小、读写权限等。
PV 描述的,则是一个具体的 Volume 的属性,比如 Volume 的类型、挂载目录、远程存储服务器地址等。
而 StorageClass 的作用,则是充当 PV 的模板。并且,只有同属于一个 StorageClass 的 PV 和 PVC,才可以绑定在一起。还有是指定 PV 的 Provisioner(存储插件)。这时候,如果你的存储插件支持 Dynamic Provisioning 的话,Kubernetes 就可以自动为你创建 PV 了。

网络

容器中的网络:

1)宿主机和容器之间的网络是通的。
2)同一宿主机上的容器之间网络是通的

那被隔离的容器进程之间如何网络如何交互呢?

先看几个基础概念:
网卡:负责监听局域网中的每一个传输的数据帧,通过帧中携带的mac地址来确定消息是否是发送到自己的物理地址(mac地址)
交换机:交换机根据数据的目的物理地址获取对应网段所在端口,仅仅将数据转发到该端口;而不是全部。
网桥:内部维护了物理地址的路由表,当数据在网段上传输时,会查看数据的目的物理地址,如果属于本网段则忽略,由网卡处理;否则先看在路由表中是否有目的物理地址对应的条目,如果有则直接转发到对应的物理地址所在网段,否则转发到除源网段之外的所有网段。
Veth Pair 设备:它被创建出来后,总是以两张虚拟网卡(Veth Peer)的形式成对出现的。并且,从其中一个“网卡”发出的数据包,可以直接出现在与它对应的另一张“网卡”上,哪怕这两个“网卡”在不同的 Network Namespace 里。

1)Docker 项目会默认在宿主机上创建一个名叫 docker0 的网桥

2)创建容器时,然后使用Veth Pair虚拟出来两张虚拟网卡。其中一张在宿主机上,并插在了docker0上;另一张在容器内作为容器的网卡eth0

网络连接过程:容器1请求 -->容器1eth0 → 宿主机上的另一张虚拟网卡(对应容器1eth0)→docker0 →宿主机的网卡eth0  或 虚拟网卡2(对应容器2eth0) ->容器2的eth0

主要原理:docker通过Veth Pair 设备 + 宿主机网桥的方式,实现了跟同其他容器的数据交换。

如图所示

k8s分享下-service 网络 卷_第2张图片

docker exec -it nginx-1 /bin/bash

docker 中的 networking
容器之间网络的连接方式。
以上面的web应用容器连接redis容器为实例。
1 创建一个网络
docker network create app
docker network inspect app
docker network ls #获取当前系统中的所有网络。
docker network rm  network名称#删除一个docker网络

2 在app网络下创建名为db的redis新容器
docker run -d --net=app --name db mazhen/redis
--net=app:新容器在app网络中运行


k8s中的网络

以集群的方式直接连通:
受到上面docker0网桥的启发,如果通过软件的方式,创建一个整个集群“公用”的网桥,然后把集群里的所有容器都连接到这个网桥上,就可以相互通信。
如图:

k8s分享下-service 网络 卷_第3张图片


构建这种容器网络的核心在于:我们需要在已有的宿主机网络上,再通过软件构建一个覆盖在已有宿主机网络之上的、可以把所有容器连通在一起的虚拟网络。所以,这种技术就被称为:Overlay Network(覆盖网络),目前主流的实现方案是flannel。

flannel实现原理:在宿主机上创建了一个特殊的设备,每个宿主机的docker0网桥与该设备之间通过IP转发进行协作。同时该设备维护了容器ip与宿主机ip之间的对应关系。

维护方式:子网,由 Flannel 管理的容器网络里,一台宿主机上的所有容器,都属于该宿主机被分配的一个“子网”,而这些子网与宿主机的对应关系,正是保存在 Etcd 当中。
 

如图所示flannel原理图

k8s分享下-service 网络 卷_第4张图片

总结:网络插件真正要做的事情,则是通过某种方法,把不同宿主机上的特殊设备连通,从而达到容器跨主机通信的目的。


k8s 网络模型与 CNI 网络插件
在 Kubernetes 环境里,docker中的docker0 网桥被替换成了 CNI 网桥。
如图

k8s分享下-service 网络 卷_第5张图片

主要原因包括两个方面:

一方面,Kubernetes 项目并没有使用 Docker 的网络模型(CNM),所以它并不希望、也不具备配置 docker0 网桥的能力;
另一方面,这还与 Kubernetes 如何配置 Pod,也就是 Infra 容器的 Network Namespace 密切相关。

再看看:

再想想:

为什么使用k8s?

实例演示

tomcat-dep.yaml定义:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-tomcat
  labels:
    app: demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: tomcat
        image: docker.io/tomcat:8.5-jre8
        ports:
        - containerPort: 801
        volumeMounts:
            - name: app-logs
              mountPath: "/usr/local/tomcat/logs/"
      volumes:
      - name: app-logs
        hostPath:
          path: "/home/logs/xeslog/tomcat/"

tomcat-svc.yaml定义
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
spec:
  type: LoadBalancer
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    app: demo

执行命令:
kubectl apply -f fileName 
新建或者更新,k8s会自动处理

获取创建某个pod对应的yaml
kubectl get pod podName -o yaml

kubectl exec demo-tomcat-78bd579ffc-2rv66 -it /bin/bash
#获取命名空间下所有容器组(Pod)信息
kubectl -n namespaceName get pods      

进入某个容器
kubectl --namespace=default exec -it demo-tomcat-7df6949bc7-4x8mf --container tomcat -- sh

mazhen@mazhendeMacBook-Pro .kube % kubectl get svc
NAME         TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP      172.21.0.1            443/TCP          133d
tomcat-svc   LoadBalancer   172.21.7.41   8.142.13.86   8080:32739/TCP   16h

说明:
8080是loadbalancer生成的负载均衡对应的端口
32739是机器对应的端口
所以最终上面的服务有两种访问方式:
curl 8.142.13.86:8080 
或 nodeIP:32739

kubctl delete svc svcName

#如果通过deployment创建pod,那删除pod必须通过deployment
kubectl get deployment
kubectl delete deployment hostnames


端口之间的对应关系
容器port ---> pod的port
pod定义中containerPort: 80
说明:k8s中pod是最小粒度,且其中的容器共用pod的网络空间,
即pod和容器拥有共同的端口、ip等网络信息
所以pod的端口即使容器的端口

pod的port ---> service的port
service中的定义:
spec:
 ports:
 - port: 8080 #service对外提供的端口
   targetPort: 8080 #对应到pod的8080端口
   name: web #对应的服务名称
   protocol: TCP #网络类型


service的port --> node的port
spec:
 type: NodePort
 ports: 
 - port: 8080
  targetPort: 8080
  nodePort: 8081 #物理机Ip+端口可以访问服务
此时可以通过node的ip+node的port访问单个节点的服务

node的port --> slb的port
slb配置多个node的ip和port进行负载均衡

为什么用k8s,解决了什么问题??
k8s基于容器,所以首先是容器带来的好处:
资源隔离,避免资源的相互影响,
基于资源规划更加充分的利用资源
镜像这种搭积木的方式,便于运维和自动化

k8s带来的好处:
解决容器编排的问题
pod或节点的故障表现出来的可靠性
流量变化时的自动缩放
节点不够时的灵活扩充,优化资源配置
资源调度能力
横向扩容方便

有了k8s为基础,可以使用云原生生态,比如istio、prometeus

isito相关的服务治理:
vs 服务路由(灰度等) 重定向 重写 重试 流量镜像 故障注入 跨域资源共享
描述的是满足什么条件的流量被那个后端处理。类似于根据路径去匹配方法,是更开放的martch条件。
dr 负载均衡 连接池 异常点检查 tls
描述的是这个请求到达某个后端后怎么去处理,是方法内的处理逻辑。所以负载均衡、熔断策略在这里
se 外部服务管理
gateway 外部服务访问

跨域资源共享:通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。
serviceEntry:网格内外的服务也像网格内的服务一样管理。

你可能感兴趣的:(k8s,网络,kubernetes,docker)