当前位置: 首页 > news >正文

惠山网页制作南沙网站建设优化

惠山网页制作,南沙网站建设优化,企业网站后台模板,自动设计logo的软件一、前言 本章节我们将了解K8S的相关网络概念#xff0c;包括K8S的网络通讯原理#xff0c;以及Service以及相关的概念#xff0c;包括Endpoint#xff0c;EndpointSlice#xff0c;Headless service#xff0c;Ingress等。 二、网络通讯原理和实现 同一K8S集群包括K8S的网络通讯原理以及Service以及相关的概念包括EndpointEndpointSliceHeadless serviceIngress等。 二、网络通讯原理和实现 同一K8S集群网络通信实现可以简化为以下几个模型Pod内容器之间的通信同一节点内Pod间的通信以及跨节点Pod的通信。 1、Pod内容器之间的通信 同一Pod内的容器是共享同一个网络命名空间的它们就像工作在同一台机器上可以使用localhost地址访问彼此的端口。其模型如下 我们来看下面实例其yaml文件如下 [rootk8s-master yaml]# cat network-pod.yaml apiVersion: v1 kind: Pod metadata:name: network-pod spec:containers:- name: busyboximage: busyboxcommand:- /bin/sh- -c- sleep 3000- name: nginximage: nginx:1.14.2ports:- containerPort: 80 该Pod包含两个容器busybox和nginx执行该文件创建Pod进入到 busybox容器访问nginx容器。 [rootk8s-master yaml]# kubectl exec -it network-pod -c busybox sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / # curl sh: curl: not found / # wget http://localhost Connecting to localhost (127.0.0.1:80) saving to index.html index.html 100% |******************************************************************************************************************************************| 612 0:00:00 ETA index.html saved / # cat index.html !DOCTYPE html html head titleWelcome to nginx!/title style ... 可以看到在busybox容器中访问http://localhost可以获取到ngnix的页面。 2、同一节点内Pod间的通信 其通信模型如下图所示: 同一节点Pod都关联到同一个网桥地址段相同从容器内发送的数据从eh0网络接口发出再从veth接口出来发送给网桥。网桥判断目标地址如果是同一个地址段再由网桥发送给节点内部的对应Pod。 同样看个实例我们将上面的Pod拆解为两个。 [rootk8s-master yaml]# cat network-busybox-pod.yaml apiVersion: v1 kind: Pod metadata:name: network-busybox-pod spec:containers:- name: busyboximage: busyboxcommand:- /bin/sh- -c- sleep 3000 [rootk8s-master yaml]# cat network-nginx-pod.yaml apiVersion: v1 kind: Pod metadata:name: network-nginx-pod spec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80 执行这两个文件创建Pod后进入busybox访问nginx(ip为10.244.36.80)。 [rootk8s-master yaml]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES network-busybox-pod 1/1 Running 0 20m 10.244.36.79 k8s-node1 none none network-nginx-pod 1/1 Running 0 19m 10.244.36.80 k8s-node1 none none [rootk8s-master yaml]# kubectl exec -it network-busybox-pod sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / # wget http://10.244.36.80 Connecting to 10.244.36.80 (10.244.36.80:80) saving to index.html index.html 100% |*****************************************************************************************************************************************************************************************| 612 0:00:00 ETA index.html saved 可以看到在busybox容器中访问http://10.244.36.80可以获取到ngnix的页面。 3、跨节点Pod间通信 其通信模型如下 当一个报文从一个节点容器发送到另一个节点容器报文先通过veth到网桥再到节点物理适配器通过网络传到其他节点的物理适配器在通过其网桥最终经过veth到达目标容器。这里需要有个前提pod 的IP地址 必须是唯一的 跨节点的网桥必须使用非重叠 地址段这个需要通过IP地址规划保证。 上面的实例中两个Pod都在k8s-node1节点上我们将上面的busybox的Pod调度到master节点上。删除busybox的Pod,并改写下yaml内容。 [rootk8s-master yaml]# cat network-busybox-pod.yaml apiVersion: v1 kind: Pod metadata:name: network-busybox-pod spec:containers:- name: busyboximage: busyboxcommand:- /bin/sh- -c- sleep 3000tolerations:- key: node-role.kubernetes.io/masteroperator: Existseffect: NoSchedule 执行该文件创建Pod可以看到新Pod调度到Master上 [rootk8s-master yaml]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES network-busybox-pod 1/1 Running 0 20s 10.244.235.202 k8s-master none none network-nginx-pod 1/1 Running 0 24m 10.244.36.80 k8s-node1 none none 进入该Pod访问nginx [rootk8s-master yaml]# kubectl exec -it network-busybox-pod sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / # wget http://10.244.36.80 Connecting to 10.244.36.80 (10.244.36.80:80) saving to index.html index.html 100% |*****************************************************************************************************************************************************************************************| 612 0:00:00 ETA index.html saved 可以看到在busybox容器中访问http://10.244.36.80可以获取到ngnix的页面。 三、Service Service是K8S的核心概念之一它是基于Pod上的业务网络层为同一组Pod提供统一的访问入口将请求负载转发到后端的Pod上其作用类似于业务网关。 1、Service创建 在创建Service之前我们先创建其后端应用该应用使用镜像tcy83/k8s-service-app,镜像java代码如下 Controller RequestMapping(/k8s) public class TestController {private static Integer appId;GetMapping(getServiceApp)ResponseBodypublic String getServiceApp(){return this this service app:generateAppId();}public static int generateAppId(){if(appId null){Random random new Random();appId random.nextInt(1000);}return appId;} } 解释下该段代码当访问/k8s/getServiceApp,返回一段字符串显示应用的appId该appId在首次访问时随机分配后续访问将保持不变以便区别不同的应用实例。 接下来就采用Deployment部署3个该应用的pod。其中yaml文件内容如下 apiVersion: apps/v1 kind: Deployment metadata:name: serviceapp-deploymentlabels:app: serviceapp-deployment spec:replicas: 3selector:matchLabels:app: serviceapp-deploytemplate:metadata:labels:app: serviceapp-deployspec:containers:- name: k8s-service-app image: tcy83/k8s-service-app:0.1 ports:- containerPort: 8080 创建完成后我们看下pod运行情况 [rootk8s-master yaml]# kubectl get pod -l appserviceapp-deploy -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES serviceapp-deployment-649c69c89d-2k2hm 1/1 Running 0 90m 10.244.36.78 k8s-node1 none none serviceapp-deployment-649c69c89d-h5s5g 1/1 Running 0 90m 10.244.36.119 k8s-node1 none none serviceapp-deployment-649c69c89d-sjv55 1/1 Running 0 90m 10.244.36.123 k8s-node1 none none 根据pod的ip和port能成功访问每一个应用。 [rootk8s-master ~]# curl http://10.244.36.78:8080/k8s/getServiceApp this this service app:400 [rootk8s-master ~]# curl http://10.244.36.119:8080/k8s/getServiceApp this this service app:204 [rootk8s-master ~]# curl http://10.244.36.123:8080/k8s/getServiceApp this this service app:813 接下来就是重点部分为这3个应用增加一个Service作为统一访问入口。 [rootk8s-master yaml]# cat service-app-sv.yaml apiVersion: v1 kind: Service metadata:name: service-app-service spec:type: ClusterIPselector:app: serviceapp-deployports:- port: 80targetPort: 8080 其中的属性我们稍后再分析先执行下service-app-sv.yaml [rootk8s-master yaml]# kubectl apply -f service-app-sv.yaml service/service-app-service created [rootk8s-master yaml]# kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 none 443/TCP 133d service-app-service ClusterIP 10.104.72.224 none 80/TCP 13s Service正常运行其集权内部访问IP为10.104.72.224访问下该Service [rootk8s-master yaml]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:400 [rootk8s-master yaml]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:204 [rootk8s-master yaml]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:400 [rootk8s-master yaml]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:400 [rootk8s-master yaml]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:813 可以看到通过Service能成功访问到后端的3个应用且有负载均衡效果。我们再扩容一个新的Pod看看。 [rootk8s-master ~]# kubectl scale deployment/serviceapp-deployment --replicas4 deployment.apps/serviceapp-deployment scaled [rootk8s-master ~]# kubectl get pod -l appserviceapp-deploy -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES serviceapp-deployment-649c69c89d-2k2hm 1/1 Running 0 12h 10.244.36.78 k8s-node1 none none serviceapp-deployment-649c69c89d-h5s5g 1/1 Running 0 12h 10.244.36.119 k8s-node1 none none serviceapp-deployment-649c69c89d-sjv55 1/1 Running 0 12h 10.244.36.123 k8s-node1 none none serviceapp-deployment-649c69c89d-txlt9 1/1 Running 0 88s 10.244.36.103 k8s-master none none 再访问Service地址 [rootk8s-master ~]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:303 [rootk8s-master ~]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:813 [rootk8s-master ~]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:400 [rootk8s-master ~]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:204 [rootk8s-master ~]# curl http://10.104.72.224:80/k8s/getServiceApp this this service app:400 可以看到新扩容的应用(appid303)已经加入到集群能通过Service访问到示意图如下 2、service原理分析 通过上面的实例我们了解了Service的具备统一访问入口的功能那么它是如何实现的呢 (1)属性分析 我们分析下Service的主要属性: type表示Service的类型目前支持ClusterIPNodePortLoadBalancerExternalName四种这四种类型的作用和用法我们在后面具体分析。Selector选择那些后端应用与该Service关联上面的例子如图所示 通过selector属性其值为Pod的label值这样所有标记为该label的Pod与该service关联起来。所以通过Service的标签选择器实现与Pod的关联。 ports即Service访问port以及后端应用的目标Port。 (2)Pod的访问 Service的IP实际上是VIP(虚拟IP)请求是如何转发到后端Pod的呢其流程如下 (1)Pod启动完成后由kubelet将各Pod的ip注册到master节点。 (2)Service发布完成后由Master分配ClusterIP并与后端Pod的ip建立映射关系存储到master节点。 (3)kube-proxy监听到变化后修改本地的iptabels写入clusterIp与Podip的映射关系。 (4)运行时当Client访问Service的ClientIp时由iptabels截获根据映射关系以及负载均衡策略转发到后端应用的Pod。 以上就是Service访问的iptabels的工作模式也是默认的工作模式该机制确保了Pod在扩缩容时通过修改iptabels快速响应服务实例的变化同时由内核区的iptabels进行寻址和负载也大大提升了效率。 在Pod实例扩容和缩容时及时的体现到iptabel的映射表上。 3、Service类型 前面介绍了Service有四种类型我们具体介绍下 (1)ClusterIP K8S为Service分配一个集群内部IP地址该 IP只能在集群内部访问这也是type的默认值。 前面创建的就是ClusterIP类型其示意图如下: 除了前面讲的通过IP访问服务service还默认分配一个域名其格式 为servicename.namespace.svc.clusterdomain上面例子service的域名:service-app-service.default.svc.cluster.local我们登录到集群中某个pod再访问该域名的地址 [rootk8s-master yaml]# kubectl exec -it nginx-deployment-86644697c5-96q8l -- /bin/sh # curl http://service-app-service.default.svc.cluster.local/k8s/getServiceApp this this service app:400 可以看到通过Service域名能正确访问应用。  (2)NodePort 如果要对外提供服务(非集群内访问)ClusterIP模式是无法满足此时需要采用NodePort它是ClusterIP的扩展在每个节点的开放一个本地静态端口端口范围:30000-32767该端口代理服务通过节点上的端口可以访问服务。示意图如下: 下面我们改写下service-app-sv.yaml将type修改为NodePort并在ports中添加nodePort:30001 [rootk8s-master yaml]# cat service-app-sv.yaml apiVersion: v1 kind: Service metadata:name: service-app-service spec:type: NodePortselector:app: serviceapp-deployports:- port: 80targetPort: 8080nodePort: 30001 创建Service后查看运行状态 [rootk8s-master yaml]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 none 443/TCP 137d service-app-service NodePort 10.110.47.22 none 80:30001/TCP 6m11s 此时我们就可以在公网上通过浏览器访问该服务 (3)LoadBalancer 公有云提供商一般提供负载均衡器向外部暴露服务外部负载均衡器可以将流量路由到自动创建的NodePort服务和ClusterIP服务上。示意图如下: 创建一个yaml文件service-app-loadbalancer-sv.yaml [rootk8s-master yaml]# cat service-app-loadbalancer-sv.yaml apiVersion: v1 kind: Service metadata:name: service-app-service spec:type: LoadBalancer selector:app: serviceapp-deployports:- port: 80targetPort: 8080 执行该文件并查看Service运行状态 [rootk8s-master yaml]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 none 443/TCP 141d service-app-service LoadBalancer 10.103.95.166 pending 80:32243/TCP 13m 已经自动分配了节点的32243端口并映射到service的80端口但是 EXTERNAL-IP一直处于pending状态这是因为我没有购买共有用的负载均衡服务购买后就会分配个负载均衡ip实现loadbalancer。 (4)ExternalName 这种类型一般是我们在使用外集群的服务时该服务暴露了DNS域名就可以在本集群创建一个Service并映射该域名那么就可以在本集群访问该service从而访问外集群的服务。示意图如下: 创建一个yaml文件映射为百度的域名。 [rootk8s-master yaml]# cat service-app-externalname-sv.yaml apiVersion: v1 kind: Service metadata:name: service-app-en-service spec:type: ExternalNameexternalName: www.baidu.com 执行完成后看下创建结果 [rootk8s-master yaml]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service-app-en-service ExternalName none www.baidu.com none 84m 当访问service-app-en-service.default.svc.cluster.local集群DNS服务返回CNAME记录其值为www.baidu.com。 为了验证下上面的结论我们在集群中部署dns工具pod镜像为dnsutils,其内容如下: [rootk8s-master yaml]# cat dnsutils-pod.yaml apiVersion: v1 kind: Pod metadata:name: dnsutils spec:containers:- name: dnsutilsimage: mydlqclub/dnsutils:1.3imagePullPolicy: IfNotPresentcommand: [sleep,3600] 执行成功后进入该pod内部使用nslookup命令看下该域名的解析 [rootk8s-master yaml]# kubectl exec -it dnsutils /bin/sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / # nslookup service-app-en-service.default.svc.cluster.local Server: 10.96.0.10 Address: 10.96.0.10#53service-app-en-service.default.svc.cluster.local canonical name www.baidu.com. www.baidu.com canonical name www.a.shifen.com. Name: www.a.shifen.com Address: 110.242.68.4 Name: www.a.shifen.com Address: 110.242.68.3 再ping下百度的域名 [rootk8s-master yaml]# ping www.baidu.com PING www.a.shifen.com (110.242.68.3) 56(84) bytes of data. 64 bytes from 110.242.68.3 (110.242.68.3): icmp_seq1 ttl52 time4.47 ms 64 bytes from 110.242.68.3 (110.242.68.3): icmp_seq2 ttl52 time4.45 ms 64 bytes from 110.242.68.3 (110.242.68.3): icmp_seq3 ttl52 time4.37 ms 可以看到上面确实是返回了百度域名的ip。 三、EndPoint 在上面的Pod访问模块中我们提到服务注册自己的ip到master节点在实际的实现过程中这些ip并不是一个物理列表而之后由Endpoint管理Service关联Endpoint。 我们先查下Endpoint列表 [rootk8s-master ~]# kubectl get endpoints NAME ENDPOINTS AGE kubernetes 192.168.16.4:6443 142d service-app-service 10.244.36.103:8080,10.244.36.119:8080,10.244.36.123:8080 1 more... 25h k8s集群中已经有了两个endpoint其中一个是和service相同名称其Endpoints就是pod的列表。这个Endpoint我们并没有显性的去创建而是在创建Service时k8s自动创建的。 那这种设计的好处是什么呢其实就是为了解耦Endpoint作为解耦层可以灵活应对pod的变化而Service不感知。 在一些实际工程中部署在K8S集群的应用需要连接外部的数据库或者另一个集群或者Namespace的服务作为服务的后端这种场景下就需要用到Endpoint。 下面我们来看一个Endpoint的使用实例如图所示 集群外部部署了一个mongdb数据库集群内部应用A需要连接该数据库由于集群导致的网络隔离无法直接访问。此时就是可以使用Service手动配置Endpoint实现。 其yaml内容如下: [rootk8s-master yaml]# cat mongodb_service.yaml apiVersion: v1 kind: Service metadata:name: mongodb-svc spec:ports:- port: 27017targetPort: 27017protocol: TCP --- kind: Endpoints apiVersion: v1 metadata:name: mongodb-svc subsets:- addresses:# 外部 mongodb IP- ip: 192.168.16.4ports:# mongodb 端口- port: 27017 首先我们创建了一个名为 mongodb-svc的service需要注意该service没有selector选择器也可以认为该service没有挂载后端服务其他的和上面的service没有区别。 接着又创建一个Endpoints其名称要为service一致(这里非常关键service与endpoints关联关系依赖name相同)在subsets中我们配置mongodb的ip(也可以是域名这里仅配置master库)和端口。 集群中的应用A就 可以通过访问该服务的域名来访问mongodb数据库了配置如下 spring:data:mongodb:uri: mongodb://ai_admin:123456mongodb-svc:27017/ai 四、Endpointslice 在大型集群中endpoint存在诸多限制 Pod数据限制一个服务对应一个Endpoint资源这意味着它需要为支持相应服务的每个Pod存储IP地址和端口网络端点Endpoint需要存储大量的ip和端口信息而存储在etcd中的对象的默认大小限制为1.5MB也就是最多能存储5000个pod的ip在大多数情况下是满足工程要求。但是在一些大型集群中数量超过这个限制就存在问题。更新代价大kube-proxy 会在每个节点上运行并监控 Endpoint 资源的任何更新如果 Endpoint 资源中有一个端口发生更改那么整个对象都会分发到 kube-proxy 的每个实例。如果service有5000个pod在3000个节点情况下每次更新将会跨节点发送 4.5GB 的数据(1.5M*3000)。再想象下如果5000个pod都滚动更新一次全部被替换那么传输的数据量将超过22TB这个是恐怖的数据。 为了解决以上的Endpoint存在的限制在是 Kubernetes 1.18 中引入的一个新的 API 对象EndpointSlice通过分片管理一组Endpoint这样将数据量以及更新的范围限制在一个分片内来解决以上两个问题。 EndPointSlice根据Endpoint所在Node的拓扑信息进行分片管理分为NodeZoneRegion三个级别如下图所示。 接下来我们看下K8s的EndpointSlice列表 [rootk8s-master ~]# kubectl get endpointslice NAME ADDRESSTYPE PORTS ENDPOINTS AGE service-app-service-bf5vr IPv4 8080 10.244.36.78,10.244.36.103,10.244.36.123 1 more... 5d18h 创建了以Endpoint名称为前缀的EndpointSlice。再来看下EndpointSlice的详情。 [rootk8s-master ~]# kubectl describe endpointslice service-app-service-bf5vr Name: service-app-service-bf5vr Namespace: default Labels: endpointslice.kubernetes.io/managed-byendpointslice-controller.k8s.iokubernetes.io/service-nameservice-app-service Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2023-03-26T10:29:05Z AddressType: IPv4 Ports:Name Port Protocol---- ---- --------unset 8080 TCP Endpoints:- Addresses: 10.244.36.78Conditions:Ready: trueHostname: unsetTargetRef: Pod/serviceapp-deployment-649c69c89d-2k2hmNodeName: k8s-node1Zone: unset- Addresses: 10.244.36.103Conditions:Ready: trueHostname: unsetTargetRef: Pod/serviceapp-deployment-649c69c89d-txlt9NodeName: k8s-node1Zone: unset- Addresses: 10.244.36.123Conditions:Ready: trueHostname: unsetTargetRef: Pod/serviceapp-deployment-649c69c89d-sjv55NodeName: k8s-node1Zone: unset- Addresses: 10.244.36.119Conditions:Ready: trueHostname: unsetTargetRef: Pod/serviceapp-deployment-649c69c89d-h5s5gNodeName: k8s-node1Zone: unset Events: none 我们来看下重要的属性参数 Labels的kubernetes.io/service-name表示关联的service名称。AddressType包括三种取值IPv4,IPv6,FQDN全限定域名Endpoints,列出的每个Endpoint的信息其中包括 AddressesEndpoint的IP地址 ConditionsEndpoint状态信息作为EndpointSlice的查询条件 Hostname在Endpoint中设置的主机名nostname TargetRefEndpoint对应的Pod名称 NodeName:所在的节点名 Zone所在的zone区 Topology拓扑信息为基于拓扑感知的服务路由提供数据。(需要设置服务拓扑key) 总之在大规模集群下EndpointSlice通过对Endpoint进行分片管理来实现降低Master和各Node之间的网络传输数据量及提高整体性能的目标。同时还支持围绕双栈网络和拓扑感知路由等新功能的创新。 五、Headless Service 在某些应用场景中我们仅希望Service实现服务发现即后端服务有改变能反映在端点列表但是不希望使用Service的服务路由功能即由业务获取列表后自定义服务的负载均衡策略决定需要连接具体哪个服务此时就可以使用Headless Service。一般应用在有状态服务中(在后续的Stateful控制器会介绍有状态服务类型)。 比如有一组根据userId字段进行分片的MySql分库当应用A读写用户信息时根据userId的分片策略决定路由到哪个分库。如下图所示 下面我们将前面的service-app-sv.yaml改造成Headless Service其yaml内如如下: [rootk8s-master yaml]# cat service-app-headless-sv.yaml apiVersion: v1 kind: Service metadata:name: service-app-headless-service spec:# clusterIp为None即为headless serviceclusterIP: Noneselector:app: serviceapp-deployports:- port: 80targetPort: 8080 该yaml中clusterIP:None即表示Headless Service。用前面创建的四个Pod模拟分库。执行完成后我们看下服务列表 [rootk8s-master yaml]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service-app-headless-service ClusterIP None none 80/TCP 7m11s 可以看到其cluster ip为None也就是该Service无法通过ip访问。前面我们介绍过每个Service都有一个默认域名Headless Service也不例外该Service的域名为service-app-headless-service.default.svc.cluster.local通过nslookup指令模拟应用A客户端获取Endpoint列表。 [rootk8s-master yaml]# kubectl exec -it dnsutils /bin/sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / # nslookup service-app-headless-service.default.svc.cluster.local Server: 10.96.0.10 Address: 10.96.0.10#53Name: service-app-headless-service.default.svc.cluster.local Address: 10.244.36.119 Name: service-app-headless-service.default.svc.cluster.local Address: 10.244.36.78 Name: service-app-headless-service.default.svc.cluster.local Address: 10.244.36.103 Name: service-app-headless-service.default.svc.cluster.local Address: 10.244.36.123可以看到应用A能正确获取后端应用IP列表后续可以自行决策如何负载连接哪个数据库分库。 六、Ingress 前面介绍的Service都是基于IP:Port模式即工作在四层TCP协议层。在工程实践中我们应用更多的是需要工作在七层Http/Https层的网关服务此时Service对象是无法满足。从1.1版本开始K8S提供Ingress对象通过配置转发策略将不同的URL请求转发到后端不同的Service上实现基于HTTP的路由机制。 其示意图如下 Ingress需要配合Ingress控制器一起使用。Ingress主要用来配置规则简单理解就是Ngnix上配置的转发规则抽象成Ingress对象使用yaml文件创建更改时仅更新yaml文件即可。而Ingress Controller是真正实现负载均衡能力它感知集群中Ingress规则变化然后读取他按照他自己模板生成一段 Nginx 配置再写到 Nginx Pod 里。 简单来讲Ingress是负责解决怎么处理的问题Ingress Controller根据处理的策略实现处理方式。 1、Ingress的配置规则 Ingress支持以下几种配置规则 (1)、转发到单个后端服务 这种比较简单对于Ingress Controller IP的访问都会转发到该后端服务上如下: apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: nginx spec:backend:serviceName: nginxservicePort: 8080 2、同一域名下不同URL路径被转发到不同的服务上 yaml内容如下在访问k8s.nginx.cn域名根据后面的path决定路由到对应的服务。 apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: nginx spec:rules:- host: k8s.nginx.cnhttp:paths:- path: /imagepathType: Prefixbackend:service:name: imageport:number: 80- path: /apppathType: Prefixbackend:service:name: webappport:number: 80 3、不同域名被转发到不同的服务上 yaml内容如下根据域名不同转发不同的后端Service。 apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: nginx spec:rules:- host: k8s.image.cnhttp:paths:- path: /pathType: Prefixbackend:service:name: imageport:number: 80- host: k8s.nginx.cnhttp:paths:- path: /pathType: Prefixbackend:service:name: nginxport:number: 80 4、不使用域名转发 这个实际是第一个的变种其yaml文件如下 apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: nginx spec:rules:http:paths:- path: /nginxbackend:serviceName: nginxservicePort: 8080 当访问ingress controller ip/nginx路径时转发到后端的nginx服务上。 2、案例实践  通过案例实践看下如何实现Ingres的配置转发功能。 (1)创建Ingress controller 首先我们创建Ingress Controller K8S目前支持AWSGCE和Nginx控制器我们这里使用K8s提供的Ngnix Controller 1.3.1版本 下载yaml文件后修改其中的controller镜像地址(原有的镜像地址国内无法访问)以及增加 hostNetwork: true(打通Cluster和node的网络)demo-1.3.1.yaml文件内容参见附件。 [rootk8s-master yaml]# kubectl apply -f demo-1.3.1.yaml namespace/ingress-nginx created serviceaccount/ingress-nginx created serviceaccount/ingress-nginx-admission created role.rbac.authorization.k8s.io/ingress-nginx created role.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx unchanged clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission unchanged rolebinding.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx unchanged clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission unchanged configmap/ingress-nginx-controller created service/ingress-nginx-controller created service/ingress-nginx-controller-admission created deployment.apps/ingress-nginx-controller created job.batch/ingress-nginx-admission-create created job.batch/ingress-nginx-admission-patch created ingressclass.networking.k8s.io/nginx unchanged validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission configured 执行该文件成功后可以看到在命名空间ingress-nginx下创建了一系列的对象。 [rootk8s-master yaml]# kubectl get pod,svc,ing,deploy -n ingress-nginx NAME READY STATUS RESTARTS AGE pod/ingress-nginx-admission-create-6sbrv 0/1 Completed 0 3m12s pod/ingress-nginx-admission-patch-dghkc 0/1 Completed 1 3m12s pod/ingress-nginx-controller-7dd587ccd5-8xr8j 1/1 Running 0 3m12sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/ingress-nginx-controller LoadBalancer 10.96.244.230 pending 80:32148/TCP,443:31937/TCP 3m12s service/ingress-nginx-controller-admission ClusterIP 10.107.184.217 none 443/TCP 3m12sNAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/ingress-nginx-controller 1/1 1 1 3m12s 其中Ingress Controller实际是一个Pod实现的这里就是 pod/ingress-nginx-controller-7dd587ccd5-8xr8j。 (2创建Deployment 接着我们创建后端应用Pod通过Nginx的镜像来模拟。 创建 命名空间为ns-ingress-test的NameSpace并创建所属该命名空间的Deploymentyaml内容如下: [rootk8s-master yaml]# cat ingress-pod.yaml apiVersion: v1 kind: Namespace metadata:name: ns-ingress-test --- apiVersion: apps/v1 kind: Deployment metadata:name: nginxnamespace: ns-ingress-testlabels:app: ingress-nginx spec:selector:matchLabels:app: ingress-nginxreplicas: 2template:metadata:labels:app: ingress-nginxspec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80 执行该文件后查看pod的运行状态完成了2个Pod的运行。 [rootk8s-master yaml]# kubectl get pods -n ns-ingress-test NAME READY STATUS RESTARTS AGE nginx-7d8856bf4f-cxnx8 1/1 Running 0 5m1s nginx-7d8856bf4f-hhk7x 1/1 Running 0 5m1s (3)创建Service 接下来创建访问该应用Pod的Service对象type为ClusterIP内容如下: [rootk8s-master yaml]# cat ingress-sv.yaml apiVersion: v1 kind: Service metadata:name: nginxnamespace: ns-ingress-test spec:ports:- port: 80targetPort: 80selector:app: ingress-nginxtype: ClusterIP 执行完成后检查Service状态 [rootk8s-master yaml]# kubectl get svc -n ns-ingress-test NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx ClusterIP 10.106.13.73 none 80/TCP 20s 到此为止我们通过Service的IP就可以访问下nginx了。 [rootk8s-master yaml]# curl 10.106.13.73:80 !DOCTYPE html html head titleWelcome to nginx!/title .... 可以看到访问正常说明Nginx应用运行正常。  (4)创建Ingress 这也是关键一步通过Ingress配置访问策略其yaml文件内容如下 [rootk8s-master yaml]# cat ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: nginxnamespace: ns-ingress-testannotations: kubernetes.io/ingress.class: nginx # 指定 Ingress Controller 的类型 spec:ingressClassName: nginxrules:- host: k8s.nginx.cnhttp:paths:- path: /pathType: Prefixbackend:service:name: nginxport:number: 80 这里较简单通过域名k8s.nginx.cn访问后端Service并指定ingressClassName为Ingress controller的名称。执行完成后看下Ingress的状态。 [rootk8s-master yaml]# kubectl get ingress -A NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE ns-ingress-test nginx nginx k8s.nginx.cn 80 20m (5)检测 到此为止我们就可以通过域名在外网访问服务了。在客户端windows的hosts文件中增加域名映射 xx.xx.xx.xx k8s.nginx.cn xx.xx.xx.xx为所在节点的公网IP配置完成后可以通过浏览器访问 七、总结 本章节介绍网络通讯的实现原理以及Service的相关核心概念 1、介绍了同一Pod内容器间同一节点不同Pod以及不同节点Pod的通讯原理和实现。 2、Service为同一组Pod提供统一的访问入口通过Selector选择同组PodService有四种类型分别为ClusterIP,NodePort,LoadBalancer,ExternalNamed。Service是通过iptabels记录虚拟IP与后端Pod IP的关系并实现流量的四层转发和负载。 3、EndpointEndpoint是管理后端应用的IP列表通过Endpoint实现Service与后端应用的解耦。通过Service手动配置Endpoint实现对集群外应用的访问。 4、Endpointslice在大规模集群中Endpoint存在性能上的限制Endpointslice通过分片管理降低Master和各Node之间的网络传输数据量及提高整体性能。 5、Headless Service是Service的一个变种采用ClusterIP:None标记一般应用于仅需要使用Service服务发现不需要服务路由的场景中。 6、IngressIngress可以实现七层路由的转发Ingress负责规则的配置而真正的流量转发则是由Ingress Controller实现。 附: K8S初级入门系列之一-概述 K8S初级入门系列之二-集群搭建 K8S初级入门系列之三-Pod的基本概念和操作 K8S初级入门系列之四-Namespace/ConfigMap/Secret K8S初级入门系列之五-Pod的高级特性 K8S初级入门系列之六-控制器(RC/RS/Deployment) K8S初级入门系列之七-控制器(Job/CronJob/Daemonset) K8S初级入门系列之八-网络 K8S初级入门系列之九-共享存储 K8S初级入门系列之十-控制器(StatefulSet) K8S初级入门系列之十一-安全 K8S初级入门系列之十二-计算资源管理 附件 demo-1.3.1.yaml文件内容 apiVersion: v1 kind: Namespace metadata:   labels:     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx   name: ingress-nginx --- apiVersion: v1 automountServiceAccountToken: true kind: ServiceAccount metadata:   labels:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx   namespace: ingress-nginx --- apiVersion: v1 kind: ServiceAccount metadata:   labels:     app.kubernetes.io/component: admission-webhook     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-admission   namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata:   labels:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx   namespace: ingress-nginx rules: - apiGroups:   -   resources:   - namespaces   verbs:   - get - apiGroups:   -   resources:   - configmaps   - pods   - secrets   - endpoints   verbs:   - get   - list   - watch - apiGroups:   -   resources:   - services   verbs:   - get   - list   - watch - apiGroups:   - networking.k8s.io   resources:   - ingresses   verbs:   - get   - list   - watch - apiGroups:   - networking.k8s.io   resources:   - ingresses/status   verbs:   - update - apiGroups:   - networking.k8s.io   resources:   - ingressclasses   verbs:   - get   - list   - watch - apiGroups:   -   resourceNames:   - ingress-controller-leader   resources:   - configmaps   verbs:   - get   - update - apiGroups:   -   resources:   - configmaps   verbs:   - create - apiGroups:   - coordination.k8s.io   resourceNames:   - ingress-controller-leader   resources:   - leases   verbs:   - get   - update - apiGroups:   - coordination.k8s.io   resources:   - leases   verbs:   - create - apiGroups:   -   resources:   - events   verbs:   - create   - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata:   labels:     app.kubernetes.io/component: admission-webhook     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-admission   namespace: ingress-nginx rules: - apiGroups:   -   resources:   - secrets   verbs:   - get   - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:   labels:     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx rules: - apiGroups:   -   resources:   - configmaps   - endpoints   - nodes   - pods   - secrets   - namespaces   verbs:   - list   - watch - apiGroups:   - coordination.k8s.io   resources:   - leases   verbs:   - list   - watch - apiGroups:   -   resources:   - nodes   verbs:   - get - apiGroups:   -   resources:   - services   verbs:   - get   - list   - watch - apiGroups:   - networking.k8s.io   resources:   - ingresses   verbs:   - get   - list   - watch - apiGroups:   -   resources:   - events   verbs:   - create   - patch - apiGroups:   - networking.k8s.io   resources:   - ingresses/status   verbs:   - update - apiGroups:   - networking.k8s.io   resources:   - ingressclasses   verbs:   - get   - list   - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:   labels:     app.kubernetes.io/component: admission-webhook     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-admission rules: - apiGroups:   - admissionregistration.k8s.io   resources:   - validatingwebhookconfigurations   verbs:   - get   - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata:   labels:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx   namespace: ingress-nginx roleRef:   apiGroup: rbac.authorization.k8s.io   kind: Role   name: ingress-nginx subjects: - kind: ServiceAccount   name: ingress-nginx   namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata:   labels:     app.kubernetes.io/component: admission-webhook     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-admission   namespace: ingress-nginx roleRef:   apiGroup: rbac.authorization.k8s.io   kind: Role   name: ingress-nginx-admission subjects: - kind: ServiceAccount   name: ingress-nginx-admission   namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:   labels:     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx roleRef:   apiGroup: rbac.authorization.k8s.io   kind: ClusterRole   name: ingress-nginx subjects: - kind: ServiceAccount   name: ingress-nginx   namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:   labels:     app.kubernetes.io/component: admission-webhook     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-admission roleRef:   apiGroup: rbac.authorization.k8s.io   kind: ClusterRole   name: ingress-nginx-admission subjects: - kind: ServiceAccount   name: ingress-nginx-admission   namespace: ingress-nginx --- apiVersion: v1 data:   allow-snippet-annotations: true kind: ConfigMap metadata:   labels:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-controller   namespace: ingress-nginx --- apiVersion: v1 kind: Service metadata:   labels:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-controller   namespace: ingress-nginx spec:   externalTrafficPolicy: Local   ipFamilies:   - IPv4   ipFamilyPolicy: SingleStack   ports:   - appProtocol: http     name: http     port: 80     protocol: TCP     targetPort: http   - appProtocol: https     name: https     port: 443     protocol: TCP     targetPort: https   selector:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx   type: LoadBalancer --- apiVersion: v1 kind: Service metadata:   labels:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-controller-admission   namespace: ingress-nginx spec:   ports:   - appProtocol: https     name: https-webhook     port: 443     targetPort: webhook   selector:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx   type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata:   labels:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-controller   namespace: ingress-nginx spec:   minReadySeconds: 0   revisionHistoryLimit: 10   selector:     matchLabels:       app.kubernetes.io/component: controller       app.kubernetes.io/instance: ingress-nginx       app.kubernetes.io/name: ingress-nginx   template:     metadata:       labels:         app.kubernetes.io/component: controller         app.kubernetes.io/instance: ingress-nginx         app.kubernetes.io/name: ingress-nginx     spec:       hostNetwork: true       containers:       - args:         - /nginx-ingress-controller         - --publish-service$(POD_NAMESPACE)/ingress-nginx-controller         - --election-idingress-controller-leader         - --controller-classk8s.io/ingress-nginx         - --ingress-classnginx         - --configmap$(POD_NAMESPACE)/ingress-nginx-controller         - --validating-webhook:8443         - --validating-webhook-certificate/usr/local/certificates/cert         - --validating-webhook-key/usr/local/certificates/key         env:         - name: POD_NAME           valueFrom:             fieldRef:               fieldPath: metadata.name         - name: POD_NAMESPACE           valueFrom:             fieldRef:               fieldPath: metadata.namespace         - name: LD_PRELOAD           value: /usr/local/lib/libmimalloc.so         image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.3.1         imagePullPolicy: IfNotPresent         lifecycle:           preStop:             exec:               command:               - /wait-shutdown         livenessProbe:           failureThreshold: 5           httpGet:             path: /healthz             port: 10254             scheme: HTTP           initialDelaySeconds: 10           periodSeconds: 10           successThreshold: 1           timeoutSeconds: 1         name: controller         ports:         - containerPort: 80           name: http           protocol: TCP         - containerPort: 443           name: https           protocol: TCP         - containerPort: 8443           name: webhook           protocol: TCP         readinessProbe:           failureThreshold: 3           httpGet:             path: /healthz             port: 10254             scheme: HTTP           initialDelaySeconds: 10           periodSeconds: 10           successThreshold: 1           timeoutSeconds: 1         resources:           requests:             cpu: 100m             memory: 90Mi         securityContext:           allowPrivilegeEscalation: true           capabilities:             add:             - NET_BIND_SERVICE             drop:             - ALL           runAsUser: 101         volumeMounts:         - mountPath: /usr/local/certificates/           name: webhook-cert           readOnly: true       dnsPolicy: ClusterFirst       nodeSelector:         kubernetes.io/os: linux       serviceAccountName: ingress-nginx       terminationGracePeriodSeconds: 300       volumes:       - name: webhook-cert         secret:           secretName: ingress-nginx-admission --- apiVersion: batch/v1 kind: Job metadata:   labels:     app.kubernetes.io/component: admission-webhook     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-admission-create   namespace: ingress-nginx spec:   template:     metadata:       labels:         app.kubernetes.io/component: admission-webhook         app.kubernetes.io/instance: ingress-nginx         app.kubernetes.io/name: ingress-nginx         app.kubernetes.io/part-of: ingress-nginx         app.kubernetes.io/version: 1.3.1       name: ingress-nginx-admission-create     spec:       hostNetwork: true       containers:       - args:         - create         - --hostingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc         - --namespace$(POD_NAMESPACE)         - --secret-nameingress-nginx-admission         env:         - name: POD_NAMESPACE           valueFrom:             fieldRef:               fieldPath: metadata.namespace         image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.3.0         imagePullPolicy: IfNotPresent         name: create         securityContext:           allowPrivilegeEscalation: false       nodeSelector:         kubernetes.io/os: linux       restartPolicy: OnFailure       securityContext:         fsGroup: 2000         runAsNonRoot: true         runAsUser: 2000       serviceAccountName: ingress-nginx-admission --- apiVersion: batch/v1 kind: Job metadata:   labels:     app.kubernetes.io/component: admission-webhook     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-admission-patch   namespace: ingress-nginx spec:   template:     metadata:       labels:         app.kubernetes.io/component: admission-webhook         app.kubernetes.io/instance: ingress-nginx         app.kubernetes.io/name: ingress-nginx         app.kubernetes.io/part-of: ingress-nginx         app.kubernetes.io/version: 1.3.1       name: ingress-nginx-admission-patch     spec:       hostNetwork: true       containers:       - args:         - patch         - --webhook-nameingress-nginx-admission         - --namespace$(POD_NAMESPACE)         - --patch-mutatingfalse         - --secret-nameingress-nginx-admission         - --patch-failure-policyFail         env:         - name: POD_NAMESPACE           valueFrom:             fieldRef:               fieldPath: metadata.namespace         image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.3.0         imagePullPolicy: IfNotPresent         name: patch         securityContext:           allowPrivilegeEscalation: false       nodeSelector:         kubernetes.io/os: linux       restartPolicy: OnFailure       securityContext:         fsGroup: 2000         runAsNonRoot: true         runAsUser: 2000       serviceAccountName: ingress-nginx-admission --- apiVersion: networking.k8s.io/v1 kind: IngressClass metadata:   labels:     app.kubernetes.io/component: controller     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: nginx spec:   controller: k8s.io/ingress-nginx --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata:   labels:     app.kubernetes.io/component: admission-webhook     app.kubernetes.io/instance: ingress-nginx     app.kubernetes.io/name: ingress-nginx     app.kubernetes.io/part-of: ingress-nginx     app.kubernetes.io/version: 1.3.1   name: ingress-nginx-admission webhooks: - admissionReviewVersions:   - v1   clientConfig:     service:       name: ingress-nginx-controller-admission       namespace: ingress-nginx       path: /networking/v1/ingresses   failurePolicy: Fail   matchPolicy: Equivalent   name: validate.nginx.ingress.kubernetes.io   rules:   - apiGroups:     - networking.k8s.io     apiVersions:     - v1     operations:     - CREATE     - UPDATE     resources:     - ingresses   sideEffects: None
http://www.zqtcl.cn/news/524976/

相关文章:

  • 可拖拽 网站建设如何做自媒体和网站签约赚点击
  • 做网站选哪个语言怎么登录百度app
  • 国发网站建设网站优化主要优化哪些地方
  • 快速微信网站开发定制网站建设费用预算
  • 网站制作叫什么知名网站建设制作
  • 网络营销网站建设公司h5应用
  • 网站开发合同要上印花税吗南江红鱼洞水库建设管理局网站
  • 疏通下水道网站怎么做wordpress 恢复初始化
  • 电脑商业网站怎的做软文推广渠道
  • 自己做网站需要买什么如何做微信商城网站
  • 有了网站开发app是不是更容易自建网站管理
  • 网站将要准备建设的内容有哪些做外贸有效的网站
  • 网站设计博客网站内容添加
  • 网站建站行业新闻微盟开店怎么收费
  • 网站的建设参考文献郑州网站建设中国建设建设银行
  • 重庆那些公司的网站是网易做的电信100m光纤做网站
  • 网站怎么设计产品营销策略包括哪些内容
  • 天元建设集团有限公司破产重组河源seo排名
  • 网站权重什么意思seo的搜索排名影响因素有
  • 建设报名系统是正规网站吗计算机培训班出来好找工作吗
  • 网站上的文章用秀米可以做吗宁波外客网络科技有限公司
  • 网站底部导航代码成品视频直播软件推荐哪个好一点ios
  • 上海电商网站开发公司垫江网站建设价格
  • 门户网站建设存在问题与不足商城网站开发项目文档
  • wordpress建站方便吗wordpress加入海报功能
  • 网站名称注册保护2018wordpress主题
  • 类似享设计的网站企业信息系统公示
  • 如何学习网站开发酒店网站源码
  • 怎么用nas做网站服务器WordPress云虚拟空间
  • 网站设计 ipad企业品牌推广宣传方案