k8s实践(12)--K8s service服务详解_kubernetes 中的service支持什么协议

除了使用kubectl expose命令创建Service,我们也可以通过配置文件定义Service,再通过kubectl create命令进行创建。
例如前面的webapp就用,我们可以设置一个Service:
webapp-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: webapp2
spec:
  ports:
  - port: 9082
    targetPort: 9081
  selector:
    app: webapp
Service定义中的关键字段是ports和selector。
本例中ports定义部分指定了Service所需的虚拟端口号为9082,由于与Pod容器端口号9081不一样,所以需要在通过targetPort来指定后端Pod的端口。
selector定义部分设置的是后端Pod所拥有的label: app=webapp

curl 192.168.22.2:9082

4)目前kubernetes提供了两种负载分发策略:RoundRobin和SessionAffinity

RoundRobin:轮询模式,即轮询将请求转发到后端的各个Pod上
    SessionAffinity:基于客户端IP地址进行会话保持的模式,第一次客户端访问后端某个Pod,之后的请求都转发到这个Pod上

默认是RoundRobin模式。

2.2 对Service定义文件中各属性的说明表

2.3 没有 selector 的 Service

Servcie 抽象了该如何访问 Kubernetes Pod,但也能够抽象其它类型的 backend,例如:

  • 希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库。
  • 希望服务指向另一个 Namespace 中或其它集群中的服务。
  • 正在将工作负载转移到 Kubernetes 集群,和运行在 Kubernetes 集群之外的 backend。

在任何这些场景中,都能够定义没有 selector 的 Service :

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

由于这个 Service 没有 selector,就不会创建相关的 Endpoints 对象。可以手动将 Service 映射到指定的 Endpoints:

kind: Endpoints
apiVersion: v1
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 1.2.3.4
    ports:
      - port: 9376

注意:Endpoint IP 地址不能是 loopback(127.0.0.0/8)、 link-local(169.254.0.0/16)、或者 link-local 多播(224.0.0.0/24)。

访问没有 selector 的 Service,与有 selector 的 Service 的原理相同。请求将被路由到用户定义的 Endpoint(该示例中为 1.2.3.4:9376)。

ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和 Endpoint。 相反地,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

当查询主机 my-service.prod.svc.CLUSTER时,集群的 DNS 服务将返回一个值为 my.database.example.com 的 CNAME 记录。 访问这个服务的工作方式与其它的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发。 如果后续决定要将数据库迁移到 Kubernetes 集群中,可以启动对应的 Pod,增加合适的 Selector 或 Endpoint,修改 Service 的 type。

2.4、service的类型

Kubernetes ServiceTypes 允许指定一个需要的类型的 Service,默认是 ClusterIP 类型。
Type 的取值以及行为如下:

1)ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。
2)NodePort:通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。
3)LoadBalancer:使用云提供商的负载均衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
4) ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。 没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。

2)通过设置nodePort映射到物理机,同时设置Service的类型为NodePort:

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  type:nodePort
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
      nodePort:30376

使用nodePort的缺点:

  1. 每个端口只能是一种服务
  2. 端口范围只能是 30000-32767
  3. 和节点node的 IP 地址紧密耦合。

(2)通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。

这种用法仅用于在公有云服务提供商的云平台上设置Service的场景。在下面的例子中, status.loadBalancer.ingress.ip设置的146.148.47.155为云服务商提供的负载均衡器的IP地址。对该Service的访问请求将会通过LoadBalancer转发到后端Pod上,负载分发的实现方式则依赖于云服务商提供的LoadBalancer的实现机制。

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
     nodePort: 19376
     clusterIP: 10.0.171.239
     loadBalancerIP: 78.11.24.19
     type: LoadBalancer
  status:
    LoadBalancer:
     ingress:
     -ip: 146.148.47.155

k8s中有3种IP地址:

Node IP: Node节点的IP地址,这是集群中每个节点的物理网卡的IP地址;
    Pod IP: Pod的IP地址,这是Docker Engine根据docker0网桥的IP地址段进行分配的,通常是一个虚拟的二层网络;
    Cluster IP:Service 的IP地址,这也是一个虚拟的IP,但它更像是一个“伪造”的IP地址,因为它没有一个实体网络对象,所以无法响应ping命令。它只能结合Service Port组成一个具体的通信服务端口,单独的Cluster IP不具备TCP/IP通信的基础。在k8s集群之内,Node IP网、Pod IP网与Cluster IP网之间的通信采用的是k8s自己设计的一种编程实现的特殊的路由规则,不同于常见的IP路由实现。

此模式会提供一个集群内部的虚拟IP(与Pod不在同一网段),以供集群内部的Pod之间通信使用。

headless service 需要将 spec.clusterIP 设置成 None。

因为没有ClusterIP,kube-proxy 并不处理此类服务,因为没有load balancing或 proxy 代理设置,在访问服务的时候回返回后端的全部的Pods IP地址,主要用于开发者自己根据pods进行负载均衡器的开发(设置了selector)。

三、Service 服务的VIP 和 Service 网络代理


1、Service 服务的VIP

在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。运行在每个Node上的kube-proxy进程其实就是一个智能的软件负载均衡器,它会负责把对Service的请求转发到后端的某个Pod实例上并在内部实现服务的负载均衡与会话保持机制。

Service不是共用一个负载均衡器的IP,而是被分配了一个全局唯一的虚拟IP地址,称为Cluster IP。在Service的整个生命周期内,它的Cluster IP不会改变

kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName 的形式。

在 Kubernetes v1.0 版本,代理完全在 userspace。
在 Kubernetes v1.1 版本,新增了 iptables 代理,但并不是默认的运行模式。
从 Kubernetes v1.2 起,默认就是 iptables 代理。
在 Kubernetes v1.0 版本,Service 是 “4层”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了 Ingress API(beta 版),用来表示 “7层”(HTTP)服务。

每当我们在k8s cluster中创建一个service,k8s cluster就会在–service-cluster-ip-range的范围内为service分配一个cluster-ip,比如:

通过 kubectl get ep可以看到对应Endpoints信息,即代理的pod。

另外,也可以将已有的服务以 Service 的形式加入到 Kubernetes 集群中来,只需要在创建 Service 的时候不指定 Label selector,而是在 Service 创建好后手动为其添加 endpoint。

2、service网络代理模式:

拥有三种代理模式:userspace、iptables和ipvs。

现在默认使用iptables,在1.8版本之后增加了ipvs功能。

1)早期 userspace 代理模式

client先请求serviceip,经由iptables转发到kube-proxy上之后再转发到pod上去。这种方式效率比较低。

这种模式,kube-proxy 会监视 Kubernetes master 对 Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会在本地 Node 上打开一个端口(随机选择)。 任何连接到“代理端口”的请求,都会被代理到 Service 的backend Pods 中的某个上面(如 Endpoints 所报告的一样)。 使用哪个 backend Pod,是基于 Service 的 SessionAffinity 来确定的。 最后,它安装 iptables 规则,捕获到达该 Service 的 clusterIP(是虚拟 IP)和 Port 的请求,并重定向到代理端口,代理端口再代理请求到 backend Pod。

网络返回的结果是,任何到达 Service 的 IP:Port 的请求,都会被代理到一个合适的 backend,不需要客户端知道关于 Kubernetes、Service、或 Pod 的任何信息。

默认的策略是,通过 round-robin 算法来选择 backend Pod。 实现基于客户端 IP 的会话亲和性,可以通过设置 service.spec.sessionAffinity 的值为 “ClientIP” (默认值为 “None”)。

2) 当前iptables 代理模式

client请求serviceip后会直接转发到pod上。这种模式性能会高很多。kube-proxy就会负责将pod地址生成在node节点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”)。

和 userspace 代理类似,网络返回的结果是,任何到达 Service 的 IP:Port 的请求,都会被代理到一个合适的 backend,不需要客户端知道关于 Kubernetes、Service、或 Pod 的任何信息。 这应该比 userspace 代理更快、更可靠。然而,不像 userspace 代理,如果初始选择的 Pod 没有响应,iptables 代理能够自动地重试另一个 Pod,所以它需要依赖 readiness probes

3)、ipvs代理方式

这种方式是通过内核模块ipvs实现转发,这种效率更高。

3、多端口 Service

很多 Service 需要暴露多个端口。对于这种情况,Kubernetes 支持在 Service 对象中定义多个端口。 当使用多个端口时,必须给出所有的端口的名称,这样 Endpoint 就不会产生歧义,例如:

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
    selector:
      app: MyApp
    ports:
      - name: http
        protocol: TCP
        port: 80
        targetPort: 9376
      - name: https
        protocol: TCP
        port: 443
        targetPort: 9377

4、 选择自己的 IP 地址

在 Service 创建的请求中,可以通过设置 spec.clusterIP 字段来指定自己的集群 IP 地址。 比如,希望替换一个已经已存在的 DNS 条目,或者遗留系统已经配置了一个固定的 IP 且很难重新配置。 用户选择的 IP 地址必须合法,并且这个 IP 地址在 service-cluster-ip-range CIDR 范围内,这对 API Server 来说是通过一个标识来指定的。 如果 IP 地址不合法,API Server 会返回 HTTP 状态码 422,表示值不合法。

service为何使用vip而不是不使用 round-robin DNS?

一个不时出现的问题是,为什么我们都使用 VIP 的方式,而不使用标准的 round-robin DNS,有如下几个原因:

  • 长久以来,DNS 库都没能认真对待 DNS TTL、缓存域名查询结果
  • 很多应用只查询一次 DNS 并缓存了结果.
  • 就算应用和库能够正确查询解析,每个客户端反复重解析造成的负载也是非常难以管理的

我们尽力阻止用户做那些对他们没有好处的事情,如果很多人都来问这个问题,我们可能会选择实现它。

四、服务发现和DNS


Kubernetes 支持2种基本的服务发现模式 —— 环境变量和 DNS。

1、环境变量

当 Pod 运行在 Node 上,kubelet 会为每个活跃的 Service 添加一组环境变量。 它同时支持 Docker links兼容 变量(查看 makeLinkVariables)、简单的 {SVCNAME}_SERVICE_HOST 和 {SVCNAME}_SERVICE_PORT 变量,这里 Service 的名称需大写,横线被转换成下划线。

举个例子,一个名称为 “redis-master” 的 Service 暴露了 TCP 端口 6379,同时给它分配了 Cluster IP 地址 10.0.0.11,这个 Service 生成了如下环境变量:

REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11

这意味着需要有顺序的要求 —— Pod 想要访问的任何 Service 必须在 Pod 自己之前被创建,否则这些环境变量就不会被赋值。DNS 并没有这个限制。

2、DNS

一个可选(尽管强烈推荐)集群插件 是 DNS 服务器。 DNS 服务器监视着创建新 Service 的 Kubernetes API,从而为每一个 Service 创建一组 DNS 记录。 如果整个集群的 DNS 一直被启用,那么所有的 Pod 应该能够自动对 Service 进行名称解析。

例如:

Service为:webapp,Namespace 为: “my-ns”。 它在 Kubernetes 集群为 “webapp.my-ns” 创建了一条 DNS 记录。

1)在同一个集群(名称为 “my-ns” 的 Namespace 中)内的 Pod 应该能够简单地通过名称查询找到 “webapp”。

2)在另一个 Namespace 中的 Pod 必须限定名称为 “webapp.my-ns”。 这些名称查询的结果是 Cluster IP。

Kubernetes 也支持对端口名称的 DNS SRV(Service)记录。 如果名称为 “webapp.my-ns” 的 Service 有一个名为 “http” 的 TCP 端口,可以对 “_http._tcp.webapp.my-ns” 执行 DNS SRV 查询,得到 “http” 的端口号。

Kubernetes DNS 服务器是唯一的一种能够访问 ExternalName 类型的 Service 的方式。 更多信息可以查看https://guisu.blog.csdn.net/article/details/93501650

五、集群外部访问服务


k8s集群外如何访问集群内的服务,主要方式有:hostPort或hostNetwork、NodePort、Ingress

1、hostPort或hostNetwork

hostPort和hostNetwork 放在首位是因为大家很容易忽略它们,它们也可让集群外访问集群内应用,

hostNetwork 用法:
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec: 
      nodeSelector:      # node节点选择器
        role: master     # node节点标签(Label)
      hostNetwork: true  # 使用node节点网络
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 8080

重点在和containers平级的hostNetwork: true,表示pod使用宿主机网络,配合nodeSelector,把pod实例化在固定节点,如上,我给mater节点加上标签role: master,通过nodeSelector,nginx就会实例化在master节点,这样就可以通过master节点的ip和8080端口访问这个nginx了。

hostPort用法:
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec: 
      nodeSelector:      # node节点选择器
        role: master     # node节点标签(Label)
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 8080
          hostPort: 80                #重点

hostNetwork相比多了映射能力,可以把容器端口映射为node节点不同端口,hostPort,当然也需要nodeSelector来固定节点,不然每次创建,节点不同,ip也会改变

访问方式:nodeSelector所选节点ip:hostPort, 如上:role=Master标签节点Ip:80

2、NodePort

NodePort是最常见的提供集群外访问的方式之一,该方式使用Service提供集群外访问:

通过设置nodePort映射到物理机,同时设置Service的类型为NodePort:

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  type:nodePort
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
      nodePort:30376

访问方式:集群内任意节点ip加nodePort所配端口号,如上:集群内任一节点ip:30376,即可访问服务了。

使用nodePort的缺点:

  1. 每个端口只能是一种服务
  2. 端口范围只能是 30000-32767
  3. 和节点node的 IP 地址紧密耦合。

在本机可以访问nodePort, 其他服务器无法问题,例如node 172.16.1.23上可以访问curl 172.16.1.23:30018,但是在服务器172.16.1.21上无法访问:


解决的办法是:
cat > /etc/sysctl.d//etc/sysctl.conf <<EOF
net.ipv4.ip_forward=1
EOF
sysctl -p

具体原因:vendor libnetwork @1861587 by sanimej · Pull Request #28257 · moby/moby · GitHub

如果net.ipv4.ip_forward=1参数是由Docker所设置,则iptables的FORWARD会被设置为DORP策略。如果是由用户设置net.ipv4.ip_forward=1参数,则用户可能会进行某些意图需要FORWARD为ACCEPT策略,这时候Docker就不会去修改FORWARD策略。

3、LoadBalancer

通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。

这种用法仅用于在公有云服务提供商的云平台上设置Service的场景。在下面的例子中, status.loadBalancer.ingress.ip设置的146.148.47.155为云服务商提供的负载均衡器的IP地址。对该Service的访问请求将会通过LoadBalancer转发到后端Pod上,负载分发的实现方式则依赖于云服务商提供的LoadBalancer的实现机制。

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
     nodePort: 19376
     clusterIP: 10.0.171.239
     loadBalancerIP: 78.11.24.19
     type: LoadBalancer
  status:
    LoadBalancer:
     ingress:
     -ip: 146.148.47.155

4、Ingress

可以简单理解为部署了一个nginx服务,该服务使用hostNetwork或hostPort方式提供集群外访问,再根据配置的路由规则,路由的集群内部各个service。

根据前面对Service的使用说明,我们知道Service的表现形式为IP:Port,即工作在TCP/IP层,而对于基于HTTP的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟服务器,这些应用层的转发机制仅通过kubernetes的Service机制是无法实现的。kubernetes V1.1版本中新增的Ingress将不同URL的访问请求转发到后端不同的Service,实现HTTP层的业务路由机制。在kubernetes集群中,Ingress的实现需要通过Ingress的定义与Ingress Controller的定义结合起来,才能形成完整的HTTP负载分发功能。

1)、创建Ingress Controller

使用Nginx来实现一个Ingress Controller,需要实现的基本逻辑如下:
     a)监听apiserver,获取全部ingress的定义
    b)基于ingress的定义,生成Nginx所需的配置文件/etc/nginx/nginx.conf
    c)执行nginx -s relaod命令,重新加载nginx.conf文件,写个脚本。

通过直接下载谷歌提供的nginx-ingress镜像来创建Ingress Controller:
文件nginx-ingress-rc.yaml
apiVersion: v1
kind: ReplicationController
matadata:
  name: nginx-ingress
  labels:
    app: nginx-ingress
spec:
  replicas: 1
  selector:
    app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
    spec:
      containers:
      - image: gcr.io/google_containers/nginx-ingress:0.1
        name: nginx
        ports:
        - containerPort: 80
          hostPort: 80
这里,Nginx应用配置设置了hostPort,即它将容器应用监听的80端口号映射到物理机,以使得客户端应用可以通过URL地址“http://物理机IP:80”来访问该Ingress Controller
#kubectl create -f nginx-ingress-rc.yaml
#kubectl get pods

2)、定义Ingress

为mywebsite.com定义Ingress,设置到后端Service的转发规则:
apiVersion: extensions/vlbeta1
kind: Ingress
metadata:
  name: mywebsite-ingress
spec:
  rules:
  - host: mywebsite.com
    http:
      paths:
      - path: /web
        backend:
          serviceName: webapp
          servicePort: 80

这个Ingress的定义说明对目标http://mywebsite.com/web的访问将被转发到kubernetes的一个Service上 webapp:80

创建该Ingress
#kubectl create -f Ingress.yaml

#kubectl get ingress
NAME |Hosts |Address |Ports |Age
mywebsite-ingress |mywebsite.com |80 |17s

创建后登陆nginx-ingress Pod,查看自动生成的nginx.conf内容

3)访问http://mywebsite.com/web
我们可以通过其他的物理机对其进行访问。通过curl --resolve进行指定
#curl --resolve mywebsite.com:80:192.169.18.3 mywebsite.com/web

3)、使用Ingress 场景

Ingress 可能是暴露服务的最强大方式,但同时也是最复杂的。Ingress 控制器有各种类型,包括 Google Cloud Load BalancerNginxContourIstio,等等。它还有各种插件,比如 cert-manager,它可以为你的服务自动提供 SSL 证书。
如果你想要使用同一个 IP 暴露多个服务,这些服务都是使用相同的七层协议(典型如 HTTP),那么Ingress 就是最有用的。如果你使用本地的 GCP 集成,你只需要为一个负载均衡器付费,且由于 Ingress是“智能”的,你还可以获取各种开箱即用的特性(比如 SSL,认证,路由,等等)。

5、总结各方式利弊

hostPorthostNetwork直接使用节点网络,部署时节点需固定,访问ip也固定(也可以用host),端口为正常端口

nodeport方式部署时不要求固定节点,可通过集群内任一ip进行访问,就是端口为30000以上,很多时候由于公司安全策略导致不能访问。

LoadBalancer依赖于云服务商提供的LoadBalancer的实现机制。

ingress需要额外安装ingress模块,配置路由规则,且仅能通过所配置域名访问,配置好域名后,可以直接对外提供服务,和传统的nginx作用类似

六、Headless Service


**1、定义:**有时不需要或不想要负载均衡,以及单独的Service IP。遇到这种情况,可以通过指定Cluster IP(spec.clusterIP)的值为“None”来创建Headless Service。

2、和普通Service相比:

对这类Headless Service并不会分配Cluster IP,kube-proxy不会处理它们,而且平台也不会为它们进行负载均衡和路由。

它会给一个集群内部的每个成员提供一个唯一的DNS域名来作为每个成员的网络标识,集群内部成员之间使用域名通信。

3、无头服务管理的域名是如下的格式:$(service_name).$(k8s_namespace).svc.cluster.local。其中的"cluster.local"是集群的域名,除非做了配置,否则集群域名默认就是cluster.local

因此选项spec.clusterIP允许开发人员自由的寻找他们自己的方式,从而降低与Kubernetes系统的耦合性。应用仍然可以使用一种自注册的模式和适配器,对其他需要发现机制的系统能够很容易的基于这个API来构建。

因为没有load balancing或 proxy 代理设置,在访问服务的时候回返回后端的全部的Pods IP地址,主要用于开发者自己根据pods进行负载均衡器的开发(设置了selector)。

DNS如何实现自动配置,依赖于Service时候定义了selector。

(1)编写headless service配置清单

vim myapp-svc-headless.yaml

apiVersion: v1
kind: Service
metadata:
  name: myapp-headless
  namespace: default
spec:
  selector:
    app: myapp
    release: canary
  clusterIP: “None” #headless的clusterIP值为None
  ports:
  - port: 80
    targetPort: 80

(2)创建headless service

kubectl apply -f myapp-svc-headless.yaml

[root@k8s-master mainfests]# kubectl get svc
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes       ClusterIP   10.96.0.1                443/TCP        36d
myapp            NodePort    10.101.245.119           80:30080/TCP   1h
myapp-headless   ClusterIP   None                     80/TCP         5s
redis            ClusterIP   10.107.238.182           6379/TCP       2h

(3)使用coredns进行解析验证
[root@k8s-master mainfests]# dig -t A myapp-headless.default.svc.cluster.local. @10.96.0.10

; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> -t A myapp-headless.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62028
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myapp-headless.default.svc.cluster.local. IN A

;; ANSWER SECTION:
myapp-headless.default.svc.cluster.local. 5 IN A 10.244.1.18
myapp-headless.default.svc.cluster.local. 5 IN A 10.244.1.19

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值