kubernetes学习笔记七(服务发现)

kubernetes学习笔记七(服务发现)

Scroll Down

Tips:

自己初学的时候,有时候会搞混 Deployment 、SVC 匹配标签的字段,这里标记一下

Deployment 匹配 pod 标签的字段是matchLabels,yaml中spec.selector.matchLabels
SVC 匹配 pod 标签的字段是selector,yaml中spec.selector

Service概念

Kubernetes以Pod作为应用部署的最小单位。kubernetes会根据Pod的声明对其进行调度,包括创建、销毁、迁移、水平伸缩等,因此Pod 的IP地址不是固定的,不方便直接采用Pod 的 IP 对服务进行访问。

为解决该问题,Kubernetes提供了Service资源,Service对提供同一个服务的多个Pod进行聚合。一个Service提供一个虚拟的Cluster IP,后端对应一个或者多个提供服务的Pod。在集群中访问该Service时,采用Cluster IP即可,Kube-proxy负责将发送到Cluster IP的请求转发到后端的Pod上。

Kube-proxy是运行在每个节点上的go应用程序,支持三种工作模式:userspace,iptables,ipvs

Kubernetes Service 定义了一个pod的逻辑分组,一种可以访问Pod组的策略--通常被称为微服务。Service通过指定的一组Label Selector而匹配到这组Pod

也就是说,在Kubernetes中,每个节点都安装了kube-proxy,kube-proxy通过kubernetes中固有的watch请求方法持续监听apiserver。一旦有service资源发生变动(增删改查)kube-proxy可以及时转化为能够调度到后端Pod节点上的规则,这个规则可以是iptables也可以是ipvs,取决于service实现方式

serviceexample.jpg

如图所示,Deployment定义了3个副本数目的一组应用程序Pod,这组Pod有着一组指定Label Selector。同时还存在一个Service通过特定的标签app=webapp、role=frontend所匹配到这组Frontend v1 Pod,所以匹配到的Pod的信息就会被写入到svc当中。当客户端访问的时候,就通过SVC以RR的调度方式( svc到pod的调度方式有且仅有一个RR算法 )来访问到这组Pod中的其中一个Pod。而且如果后期SVC匹配的Pod意外死掉了,Deployment根据副本数目创建出来的新的Pod就会被自动更新到SVC的负载策略中(同时也就是说只要被SVC的label Selector匹配的到的Pod,不管是意外退出、滚动更新、水平扩容,都会被更新到svc的负载策略中,并不会对上一层的服务造成影响)。

CoreDNS作用:

Tips:
FQDN:(Fully Qualified Domain Name)完全合格域名/全称域名,是指主机名加上全路径,全路径中列出了序列中所有域成员。全域名可以从逻辑上准确地表示出主机在什么地方,也可以说全域名是主机名的一种完全表示形式。从全域名中包含的信息可以看出主机在域名树中的位置。

完全合格域名(FQDN):点结尾的域名,

例如bbs.cnblogs.com.就是一个完全合格域名。在一般的网络应用中,我们可以省略完全合格域名最右侧的点,但DNS对这个点不能随便省略。因为这个点代表了DNS的根,有了这个点,完全合格域名就可以表达为一个绝对路径,例如bbs.cnblogs.com.就可以表示为DNS根下的com子域下cnblogs.com域中一个名为bbs的主机。如果DNS发现一个域名不是以点结尾的完全合格域名,就会把这个域名加上当前的区域名称作为后缀,让其满足完全合格域名的形式需求。例如DNS会把域名bbs处理为bbs.blogs.com.

K8s中资源的全局FQDN格式:
svc_name.namespace_name.Domain.LTD.
Domain.LTD. = svc.cluster.local.     #这是k8s集群默认的域名。
svc_name.namespace_name.svc.cluster.local
CoreDNS可以把Service Name(的FQDN)解析成Cluste IP,所以当管理员为Deployment/RS/多个Pod添加一个Cluster IP类型的Service之后,client端就可以通过该Cluster IP访问到Deployment下的Pod,也可以通过该Service Name访问到Deployment下的Pod。而访问Service Name的时候,CoreDNS是会将Service Name解析成该Service对应的Cluster IP,进而通过负载均衡转发到后端的单个/多个Endpoint端点(一个Endpoint端点对应的就是后端一个Pod的IP:Port)。

CoreDNS仅能将Service的Name解析为对应的Cluster IP,做不到将Deployment/Pod的Name解析为其对应的IP

这是因为请看下面Service工作原理

Service 工作原理:

k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,据此创建与Service同名的endpoint对象,当Pod 地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到那个Pod进行访问的地址。(至于转发到哪个节点的Pod,由负载均衡kube-proxy起初就决定好的)

① endpoint是k8s集群中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址

② 只有当service配置selector(选择器),endpoint controller才会自动创建对应的endpoint对象,否则,不会生成endpoint对象

③ 在k8s集群中创建webapp的service,就会生成一个同名的endpoint对象,endpoint就是service关联的Pod的ip地址和端口

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

默认只提供4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的。

( 后期可以通过 Ingress添加7层的负载均衡能力,后面详细讲 )

Service类型

ClusterIp:默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP

NodePort( 常见的暴露k8s内部服务的方式 ):在 ClusterIP 的基础上为 Service 在每台机器节点上绑定一个端口,这样就可以通过: NodePort 来访问该服务。访问节点的 IP + 特定端口就会访问到SVC绑定的端口,进而以rr的调度算法访问到Pod的端口上 ,并且每一台机器节点上都是这样的流程,在集群多节点前加一个负载均衡器(nginx/LVS+keeplived等)的话就实现了一定程度的高可用,如下图

servicenodeport.png

nodeport_targetport.jpg

nodeport_port.jpg

nodeport_nodeport.jpg

nodeport_selector.png

LoadBalancer:在NodePort的基础上,借助云服务商(Cloud Provider) 创建一个外部负载均衡器,并将请求转发到 NodePort ( LoadBalancer 与 Nodeport( 有负载均衡器的情形下 )的区别就是,LoadBalancer 的负载均衡器是云服务商所提供的 )

serviceLoadBalancer.jpg

ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。在这种模式下,k8s集群内如果想访问外部的服务,只用去访问svc即可,外部服务后期如果更改了IP,只用更新svc的配置即可。只有 kubernetes 1.7 或更高版本的 kube-dns 才支持

serviceexternalname.jpg

SVC的实现原理:

svc 的实现需要这么几个组件的配合,首先ApiServer通过kube-proxy来负责监听所有的Service、Endpoint端点信息,而kube-proxy则监听Service 所指定Label Selector匹配到的Pod的信息,将其写入到 svc 中,而其实 SVC 就是通过 iptables 来实现的,也就是把kube-proxy监测到pod的信息写入到iptables 规则中。当客户端访问SVC的时候,其实访问的就是iptables规则,然后iptables规则就根据RR算法将流量调度到后端的Pod上。

整个过程其实就是:apiserver通过监控kube-proxy实现服务的更新、端点的维护,kube-proxy将规则写入到iptables,而iptables实现将客户端流量调度到具体的pod

servicetheory.jpg

VIP 和 Service 代理分类简介

在 Kubernetes 集群中,每个worker Node 都会运行一个kube-proxy进程,kube-proxy负责为Service实现了一个VIP(虚拟 IP)的形式,而不是ExternalName( k8s内部访问集群外部服务的形式 )的形式。在 Kubernetes v1.0 版本,kube-proxy 代理只有 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)服务

Service代理模式的分类说明

Service代理模式总览

![service](https://www.ishells.cn/upload/2021/10/service-7169e3c4f8dc49f0ae9ed97b9e496545.png

userspace 模式其实就是直接通过kube-proxy 将数据包转发到后端 Pods,kube-proxy 在这里起到了路由规则下发、包转发规则、负载均衡的功能,由于 kube-proxy 是运行在用户空间的,会存在用户空间和内核空间的频繁切换,这对性能影响很大,所以后面默认就换成 iptables 了。

iptables 基于 netfilter 实现,所有操作都在内核空间相比基于 kube-proxy 直接做转发和负载均衡在性能上得到很大的提升。这里 kube-proxy 只是起到设置 iptables 的规则作用。

另一个是 IPVS, IPVS 在性能上比 iptables 更进一步,底层和 iptables 一样是基于 netfilter ,但IPVS 基于hash tabels来存储网络转发规则相比于 iptables 这种线性 O(n) 的算法要快很多

① userspace代理模式

service-userspace

userspace代理模式下,client pod如果想要访问Server Pod( 就好比LNMP中的php想要访问mysql ),首先需要访问到 Service IP,再由实际的 iptables 访问到kube-proxy,再由kube-proxy访问到具体的Server pod。这种代理模式下,kube-proxy的压力是比较大的。

② iptables代理模式

serviceiptables.jpg

在 iptables 的这种模式下,不需要kube-proxy去进行流量的调度了,client pod 的访问,直接就被 iptables 经过RR算法调度到某个server pod上

③ ipvs代理模式

什么是IPVS?

IPVS (IP Virtual Server,IP虚拟服务器)是基于Netfilter的、作为linux内核的一部分实现传输层负载均衡的技术,通常称为第4层LAN交换。

IPVS集成在LVS(Linux Virtual Server)中,它在主机中运行,并在真实服务器集群前充当负载均衡器。IPVS可以将对TCP/UDP服务的请求转发给后端的真实服务器,并使真实服务器的服务在单个IP地址上显示为虚拟服务。因此IPVS天然支持Kubernetes Service。

由于ipvs 无法提供包过滤、SNAT、masquared(伪装)等功能。因此在某些场景(如Node Port的实现)下还是要与iptables搭配使用,ipvs 将使用ipset来存储需要DROP或masquared的流量的源或目标地址,以确保 iptables 规则的数量是恒定的。假设要禁止上万个IP访问我们的服务器,则用iptables的话,就需要一条一条地添加规则,会在iptables中生成大量的规则;但是使用ipset的话,只需要将相关的IP地址(网段)加入到ipset集合中即可,这样只需要设置少量的iptables规则即可实现目标。

为什么选择IPVS

随着kubernetes使用量的增长,其资源的可扩展性变得越来越重要。特别是对于使用kubernetes运行大型工作负载的开发人员或者公司来说,service的可扩展性至关重要。

kube-proxy是为service构建路由规则的模块,之前依赖iptables来实现主要service类型的支持,比如(ClusterIP和NodePort)。但是iptables很难支持上万级的service,因为iptables纯粹是为防火墙而设计的,并且底层数据结构是内核规则的列表。

kubernetes早在1.6版本就已经有能力支持5000多节点,这样基于iptables的kube-proxy就成为集群扩容到5000节点的瓶颈。举例来说,如果在一个5000节点的集群,我们创建2000个service,并且每个service有10个pod,那么我们就会在每个节点上有至少20000条iptables规则,这会导致内核非常繁忙。

基于IPVS的集群内负载均衡就可以完美的解决这个问题。IPVS是专门为负载均衡设计的,并且底层使用哈希表这种非常高效的数据结构,几乎可以允许无限扩容

IPVS vs. Iptables区别

IPVS模式和IPTABLES模式之间的差异如下:

  • IPVS为大型集群提供了更好的可扩展性和性能。(规则的存储方式使用的数据结构更高效)
  • IPVS支持比iptables更复杂的负载平衡算法(最小负载,最少连接,位置,加权等)。
  • IPVS支持服务器健康检查和连接重试等。

此外,ipvs 为负载均衡算法提供了更多选项,例如:

✦ rr 轮询调度

✦ lc最小连接数

✦ dh目标哈希

✦ sh源哈希

✦ sed最短期望延迟

✦ nq不排队调度

注意:ipvs模式假定在运行kube-proxy之前已经在节点上都安装了IPVS内核模块,当kube-proxy以ipvs代理模式启动时,kube-proxy将验证节点上是否安装了IPVS模块,如果未安装,则kube-proxy回退iptables代理模式

service-ipvs

ClusterIP说明与演示

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

servicecluster.png

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

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

kube-proxy,kubernetes的每个woker节点中都有一个kube-porxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的iptables规则中

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

1、apiserver 先将信息写入到 etcd数据库中, kube-proxy检测 etcd数据库中信息的变化,得到变化的信息后会将信息写入到本地(每一个woker节点都会有自己的kube-proxy进程,所以说是本地)的 iptables/ipvs/userspace中

clusterIP 演示:

apiVersion: apps/v1
kind: Deployment
metadata:  
  name: myapp-deploy
  namespace: default
spec:  
  replicas: 3 
  selector: 
    matchLabels: 
      app: myapp   
      release: stabel 
  template:   
    metadata:   
      labels:      
        app: myapp   
        release: stabel   
        env: test  
    spec:    
      containers:    
      - name: myapp
        image: nginx 
        imagePullPolicy: IfNotPresent   
        ports:    
        - name: http      
          containerPort: 80

# 创建完deployment之后,是可以直接通过pod的ip进行集群内访问的
# 但是这样的方式太过繁琐,且如果pod意外停止,新创建的Pod的IP的也是会发生改变的,所以接下来创建一个svc

① 首先创建一个Deployment,副本数为3

apply_deployment_1.png

apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  type: ClusterIP
  selector:
    app: myapp
    release: stabel
  ports:
  - name: http
    port: 80
    targetPort: 80
# 创建完service之后,可以结合本地的环境,查看是否有相应的转发规则
# ipvsadm -Ln / iptables -t nat -nvL 
# 如果创建的 service 通过 selector 设定的标签与后端的pod关联起来了,就可以通过访问svc直接访问后端的pod了

② 创建完Deployment之后创建一个Service ClusterIP:

apply_service_clusterIP.jpg

③ 修改nginx镜像的default.index文件,测试访问ClusterIP

edit_pod_index.jpg

visit_1.jpg

visit_2.jpg

Headless Service:

有时不需要或不想要负载均衡以及单独的 Service IP ,遇到这种情况,可以通过指定 ClusterIP(spec.clusterIP) 的值为 “None” 来创建 Headless Service 。这类 Service 并不会分配 Cluster IP, kube-proxy 不会处理它们,而且平台也不会为它们指定负载均衡和路由

Headless Service 不会被分配Cluster IP(集群内部IP),

apiVersion: v1
kind: Service
metadata:  
  name: myapp-headless
  namespace: default
spec:  
  selector: 
    app: myapp  
  clusterIP: "None" 
  ports: 
  - port: 80 
    targetPort: 80
# svc创建之后会被写入到coreDNS中,写入的格式就是  " SVC名称.名称空间.域名. "
# 域名默认是 " svc.cluster.local. "
# 然后我们就可以通过下面的方式来访问Headless SVC
# dig -t a SVC名称.名称空间.域名. @dns

CoreDNS作用:

Tips:
FQDN:(Fully Qualified Domain Name)完全合格域名/全称域名,是指主机名加上全路径,全路径中列出了序列中所有域成员。全域名可以从逻辑上准确地表示出主机在什么地方,也可以说全域名是主机名的一种完全表示形式。从全域名中包含的信息可以看出主机在域名树中的位置。

完全合格域名(FQDN):点结尾的域名,

例如bbs.cnblogs.com.就是一个完全合格域名。在一般的网络应用中,我们可以省略完全合格域名最右侧的点,但DNS对这个点不能随便省略。因为这个点代表了DNS的根,有了这个点,完全合格域名就可以表达为一个绝对路径,例如bbs.cnblogs.com.就可以表示为DNS根下的com子域下cnblogs.com域中一个名为bbs的主机。如果DNS发现一个域名不是以点结尾的完全合格域名,就会把这个域名加上当前的区域名称作为后缀,让其满足完全合格域名的形式需求。例如DNS会把域名bbs处理为bbs.blogs.com.

K8s中资源的全局FQDN格式:
svc_name.namespace_name.Domain.LTD.
Domain.LTD. = svc.cluster.local.     #这是k8s集群默认的域名。

CoreDNS 会把Service( Kubernetes的FQDN )解析成Cluster IP,所以当管理员为Deployment等控制器添加一个Cluster IP类型的Service之后,client端既可以通过该Cluster IP访问到Deployment下的Pod,也可以通过该Service FQDN访问到Deployment下的Pod。而访问Service FQDN的时候,CoreDNS是会将Service FQDN解析成该Service对应的Cluster IP,进而通过负载均衡转发到后端的单个/多个Endpoint端点(一个Endpoint端点对应的就是后端一个Pod的IP:Port)。

CoreDNS能将Service的Name解析为对应的Cluster IP,做不到将Deployment/Pod的Name解析为其对应的IP。倒是可以为Pod定义一个Headless Service,因为Headless Service没有Cluster IP,所以CoreDNS中Headless Service对应的解析就直接是后端对应的Pod IP

CoreDNS的记录格式(来源coreDNS Github):

一个Pod可以对应多个svc,而一个svc也可以对应多个pod,也就是说它们之间的对应关系是n对m的

NodePort:

nodePort 的原理在于在 node 上开了一个端口,将向该端口的流量导入到 kube-proxy,然后由 kube-proxy 进一步到给对应的 pod

apiVersion: v1
kind: Service
metadata:  
  name: myapp  
  namespace: default
spec:  
  type: NodePort  
  selector:    
    app: myapp    
    release: stabel  
  ports:  
  - name: http
    port: 80 
    targetPort: 80

apply_NodePort.jpg

brower_visit.jpg

查询流程:

# iptables -t nat -nvL

LoadBanlance:

客户端只用访问到云供应商的负载均衡器,流量从该负载均衡器指向k8s集群的NodePort(worker node),由NodePort指向后端的Pod

ExternalName:

externalName SVC是比较特殊的不使用Label Seclector的一个SVC

    这个模式是为了将外部的服务引入k8s集群内部,比如将外部读写分离的mysql集群引入集群内部。首先需要知道的是,每创建一个svc就会在k8s的coreDNS中添加一条解析记录,该值格式为svc_name.namespace_name.svc.cluster.local.,而Externalname SVC的工作流程是,当客户端访问到 svc_name.namespace_name.svc.cluster.local.这条解析的时候,流量会被导向yaml资源清单中定义的externalName上,从而将流量指向集群外对应的服务上。

externalName其实就相当于在coreDns中加了一个Cname解析

问:

集群外的服务如何以externalName指定的字段向k8s集群提供服务的?

传统svc仅支持四层代理,并不支持七层代理,如果要用到七层代理,那就需要用到ingress

Ingress负载网络:

    在通常情况下,service和pod的IP仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到service在节点暴露的NodePort上,然后再由kube-proxy将其转发给相关的Pod。而Ingress就是为进入集群的请求提供路由规则的集合。

    Ingress可以给service提供集群外部访问的URL、负载均衡、SSL、HTTP路由等。为了配置这些Ingress规则,集群管理员需要部署一个IngressController,它监昕Ingress和service的变化,并根据规则配置负载均衡并提供访问入口。

    为什么需要Ingress,因为在对外访问的时候,NodePort类型需要在外部搭建额外的负载均衡,而LoadBalancer要求kubernetes必须跑在特定的云服务提供商上面。

    Ingress的实现方案有很多,例如Ingress-nginx、Ingress-Haproxy等

    定义一个Ingress如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata: 
  name: test-ingress
spec: 
  rules: 
  - http: 
      paths: 
      - path: /testpath
        backend: 
          serviceName: test
          servicePort: 80 

每个Ingress都需要配置rules,目前Kubernetes仅支持http规则。上面的示例表示请求/testpath时转发到服务test的80端口中。根据IngressSpec配置的不同,Ingress可以分为以下几种类型.

1、单服务Ingress

单服务Ingress即该Ingress仅指定一个没有任何规则的后端服务

apiVersion: extensions/v1beta1
kind: Ingress
metadata: 
  name: test-ingress 
spec: 
  backend:
    serviceName: testsvc 
    servicePort: 80

单服务还可以通过设置Service.Type=NodePort或者Service.Type=LoadBalancer来对外暴露

2、多服务Ingress

路由到多服务的Ingress即根据请求路径的不同转发到不同的后端服务上,比如可以通过下面的Ingress来定义:

apiVersion: extensions/v1beta1
kind: Ingress 
metadata: 
  name: test 
spec: 
  rules:
  - host: foo.bar.com 
    http: 
      paths: 
      - path: /foo 
        backend: 
          serviceName: s1
          servicePort: 80 
      - path: /bar
        backend: 
          serviceName: s2 
          servicePort: 80

上面例子中,如果访问的是/foo,则路由转发到s1服务,如果是/bar则转发到s2服务

3、虚拟主机Ingress

虚拟主机,Ingress即根据名字的不同转发到不同的后端服务上,而它们共用同一个IP地址,基于Hostheader路由请求的Ingress如下:

aiVersion: extensions/v1beta1
kind: Ingress 
metadata: 
  name: test
spec: 
  rules:
  - host: foo.bar.com
    http: 
      paths: 
      - backend:
          serviceName: s1
          servicePort: 80
  - host: bar.foe.com 
    http: 
      paths: 
      - backend: 
          serviceName: s2
          servicePort: 80

根据不同的域名路由到不同的后端服务

4、更新Ingress

可以通过kubectl edit ingress_name 的方法来更新Ingress

# kubectl edit  Ingress名称 -f yaml

这条命令会使用编辑器打开一个已有Ingress的yaml定义文件,修改并保存就会将其更新到KubemetesAPI server,进而触发IngressController重新配置负载均衡

spec: 
  rules:
  - host: foe.bar.com
    http:
      paths:
      - backend:
          serviceName: s1 
          servicePort: 80
        path: /foo
  - host: bar.baz.com
    http:
      paths: 
      - backend:
          serviceName: s2
          servicePort: 80
        path: /foo

当然,也可以使用kubectl replace - f new_ingress.yaml来更新,ingress的yaml文件可以由命令kubectl get Resources_Type Name -o yaml获得

Ingress HTTP代理访问
deployment、Service、Ingress Yaml文件

apiVersion: extensions/v1beta1
kind: Deployment
metadata:  
  name: nginx-dm
spec:  
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: ishells/myapp:v1
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-test
spec:
  rules:
    - host: www1.test.com
      http:
        paths:
        - path: /
          backend:
            serviceName: nginx-svc
            servicePort: 80

Ingress HTTPS代理访问
创建证书、以及cert存储方式

# 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 tls-secret --key tls.key --cert tls.crt

deployment、Service、Ingress Yaml文件:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-test
spec:
  tls:
    - hosts:
      - foo.bar.com
      secretName: tls-secret
  rules:
    - host: foo.bar.com
      http:
        paths:
        - path: /
          backend:
            serviceName: nginx-svc
            servicePort: 80

Nginx进行BasicAuth

# yum -y install httpd
# htpasswd -c auth foo
# kubectl create secret generic basic-auth --from-file=auth
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-with-auth
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
spec:
  rules:
  - host: foo2.bar.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80