Kubernetes-Ingress资源详解


NGINX Ingress controller can be installed via Helm using the chart from the project repository. To install the chart with the release name ingress-nginx:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install my-release ingress-nginx/ingress-nginx

 

什么是 Ingress?

通常情况下,service 和 pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 通过边缘路由器 (edge router) 将其转发给相关的 Pod 或者丢弃。如下图所示

 
internet
|
------------
[Services]

而 Ingress 就是为进入集群的请求提供路由规则的集合,如下图所示

image-20190316184154726

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

#阿里云称之为ingress路由!在 Kubernetes 集群中,主要用于接入外部请求到k8s内部,Ingress是授权入站连接到达集群服务的规则集合,为您提供七层负载均衡能力。git地址:https://github.com/kubernetes/Ingress-nginx

 

Service缺点

#定义service以后,尤其是NodePort集群访问,需要经过2级转换调度,而且是4层调度,无论是iptables还是ipvs。4调度自身无法实现卸载https会话。

#ingress----k8s还有一种引入集群外部流量的方式,叫ingress。基于7层调度器。利用7层pod,将外部流量引入到内部。

 

Service 有四种类型:

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

  • NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 <NodeIP>:NodePort 来访问该服务。如果 kube-proxy 设置了 --nodeport-addresses=10.240.0.0/16(v1.10 支持),那么仅该 NodePort 仅对设置在范围内的 IP 有效。

  • LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 <NodeIP>:NodePort

  • ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。需要 kube-dns 版本在 1.7 以上。

 

Ingress支持的调度方式

1、url路径映射调度: location /aa ; location /bb。可以参考nginx。

2、主机调度:l例如server aaa; server bbb

 

Ingress类型:1、url映射 2、虚拟主机

 
 
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 端口。

 

API 版本对照表

Kubernetes 版本

Extension 版本

v1.5-v1.17

extensions/v1beta1

v1.8+

networking.k8s.io/v1beta1

 

Ingress 类型

根据 Ingress Spec 配置的不同,Ingress 可以分为以下几种类型:

单服务 Ingress

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

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

 


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

多服务的 Ingress

路由到多服务的 Ingress 即根据请求路径的不同转发到不同的后端服务上,比如

 
foo.bar.com -> 178.91.123.132 -> / foo    s1:80
                                 / bar    s2:80

 

可以通过下面的 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

 


使用 kubectl create -f 创建完 ingress 后:

 
$ kubectl get ing
NAME      RULE          BACKEND   ADDRESS
test      -
          foo.bar.com
          /foo          s1:80
          /bar          s2:80

 

虚拟主机 Ingress

虚拟主机 Ingress 即根据名字的不同转发到不同的后端服务上,而他们共用同一个的 IP 地址,如下所示

foo.bar.com --|                 |-> foo.bar.com s1:80
              | 178.91.123.132  |
bar.foo.com --|                 |-> bar.foo.com s2:80

 

下面是一个基于 Host header 路由请求的 Ingress:

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

 


注:没有定义规则的后端服务称为默认后端服务,可以用来方便的处理 404 页面。

TLS Ingress

TLS Ingress 通过 Secret 获取 TLS 私钥和证书 (名为 tls.crttls.key),来执行 TLS 终止。如果 Ingress 中的 TLS 配置部分指定了不同的主机,则它们将根据通过 SNI TLS 扩展指定的主机名(假如 Ingress controller 支持 SNI)在多个相同端口上进行复用。

定义一个包含 tls.crttls.key 的 secret:

 
apiVersion: v1
data:
  tls.crt: base64 encoded cert
  tls.key: base64 encoded key
kind: Secret
metadata:
  name: testsecret
  namespace: default
type: Opaque

 


Ingress 中引用 secret:

 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: no-rules-map
spec:
  tls:
    - secretName: testsecret
  backend:
    serviceName: s1
    servicePort: 80

 


注意,不同 Ingress controller 支持的 TLS 功能不尽相同。 请参阅有关 nginxGCE 或任何其他 Ingress controller 的文档,以了解 TLS 的支持情况。

更新 Ingress

可以通过 kubectl edit ing name 的方法来更新 ingress:

 
$ kubectl get ing
NAME      RULE          BACKEND   ADDRESS
test      -                       178.91.123.132
          foo.bar.com
          /foo          s1:80
$ kubectl edit ing test

 

这会弹出一个包含已有 IngressSpec yaml 文件的编辑器,修改并保存就会将其更新到 kubernetes API server,进而触发 Ingress Controller 重新配置负载均衡:

 
spec:
  rules:
  - host: foo.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 get ing
NAME      RULE          BACKEND   ADDRESS
test      -                       178.91.123.132
          foo.bar.com
          /foo          s1:80
          bar.baz.com
          /foo          s2:80

 

当然,也可以通过 kubectl replace -f new-ingress.yaml 命令来更新,其中 new-ingress.yaml 是修改过的 Ingress yaml。

Ingress-controller:(提供特定功能的pod,nginx-ingress-controller-pod):提供接入外部流量的特定pod。例如有3个节点,在这3个节点打上污点,在每个上面运行特定的daemonset pod,实现外部流量接入,为后面pod提供7层调度。众多控制器都是master节点的controllermanager的子件运行的。而ingree controller自己独立运行,通常是一组pod资源。具有7层代理功能。

 

支持的代理工具:nginx、Traefik、Evoy(微服务)、HAproxy

 

watch:Service始终watch着后端pod变化。只要pod发生变化,api-server立刻检测到。

 

Ingress

实现原理:

1、正常是用service去调度后面的适配label的pods,当pods增加,因为有labels,会自动识别后端添加的pods,如果用nginx怎么实现?把nginx运行在pod里面,配置文件在pod内部。这种pod叫ingress controller随时观察着后端的pod的改变。ingress controler自己没有这种能力,借助于service去实现。所以nginx-ingress-controller后端还得建立service。这种service仅仅帮忙分类后端的pods资源。pods的配置在nignx里upstream面。service不会进行调度,仅仅分组。因此可以使用headless service,直接调度至后端pods。关键pods变化,怎么自动nginx的upstream以及其他配置,这种就通过ingress路由实现!

2、ingress需要建一个前端接入层,前端有可能是虚拟主机nginx配置的server,或者是location url映射,同时也要定义一个后端upstream-server。 upstream有几个主机。通过service来获取的。

3、ingress有个特点:作为资源来讲,直接通过编辑注入到nginx-ingress-controller,并保存为nginx的配置文件。而且ingress一旦发现service 后端的pods改变,ingress直接注入更新nginx配置文件,而且需要重载配置文件(traefik支持自动重载)。

 

实现ingress步骤(7层调度):

1、第一步:部署一个nginx-ingress-controller-pod。部署一个特殊pod。

2、第二部:给nginx-ingress-controller-pod创建前端service1。用来接入外部请求!

3、创建nginx-ingress-controller-pod后端service2,以及service关联的pods。

4、创建ingress、自动实现路由规则,自动实现service2自动注入到nginx-ingress-controller-pod规则(nginx.conf)

5、总结就是首先部署外部请求<------ingress-service<-----nginx-ingress-controller-pod<--------ingress<------service(headless、daemonset)<------pods

 

Ingress原理图

原理:外部负载均衡器externalLB请求调至到 nodeport 里面service服务--->调度到内部pod(ingress controller里面)----->根据ingree定义,是虚拟主机,还是url代理---->假设是主机名,一组主机名对应后端的pod资源pod1,pod2,pod3。pod怎么分组通过service进行分组。才能被ingress引用。

先安装ingress controller pod。然后定义ingress。再定义pod生成service。

动态生效pod一变化,service就变化,service一变化,ingress就变化,ingreess一变化就注入到ingress controller里面。实时动态。

 


 

 

例子1(定义nginx-ingress-controller-pod) 3大步骤!

1、创建ingress-controller

#查看ingress帮助文档

[root@node-001 ingress]# kubectl explain ingress.spec

 

#查看虚拟主机调度规则

[root@node-001 ingress]# kubectl explain ingress.spec.rules.host

 

#查看路径url映射调度规则

[root@node-001 ingress]# kubectl explain ingress.spec.rules.http.paths 

#查看路径url映射调度规则

 

#查看url映射调用的后端主机规则(后端是通过service关联一组后端pod)

[root@node-001 ingress]# kubectl explain ingress.spec.backend.servicename 

#查看后端service后端的哪些pod,因为ingress backend后端就是根据service知道哪些pod资源。一旦pods变化,service就变化,service变化,ingress就变化,ingress一变化就注入到ingress-controller.

 

#tls字段: 配置ingress-controller虚拟机主机、或者url代理成https,需要用!!!!配置在ingress-controller相当于向后端代理时候,卸载了ssl会话。

######################################################################################################

原理注解:

把nginx作为ingress-controller-pod

github地址:https://github.com/kubernetes/ingress-nginx/

#第一步:创建名称空间

#yum install git -y

https://github.com/kubernetes/ingress-nginx/blob/master/deploy/static/namespace.yaml

或者直接用命令创建:#kubectl create namespace dev #kubectl get namespace

#第二步:需要用到里面的configmap.yaml,存储卷的时候后面讲,主要用来从外部注入配置

#第三步:rbac.yaml 用来定义角色、授权。必要时让ingress controller达到不了的名称空间。用kube安装的k8s默认启用,必须要设置。

#第四步:接着设置with-rbac.yaml. 说明introller controller部署时候带上rbac部署。

#第五步: 配置tcp-service-configmap.yaml。 新版本貌似没有这个文件

[root@node-001 ingress-nginx]# git clone https://github.com/kubernetes/ingress-nginx.git

#把git文件先下载个备份保存一下。

######################################################################################################

 

下载nginx-ingress-controller相关的yaml清单(不行,手动下载)

[root@k8s-master ~]# mkdir ingress-nginx [root@k8s-master ~]# cd ingress-nginx/ [root@k8s-master ingress-nginx]# for file in namespace.yaml configmap.yaml rbac.yaml with-rbac.yaml ;do wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/$file;done

#会有几个下载不了,有可能版本不匹配。注意这边是raw格式的yaml所以下载地址不是github下载地址开头的!

 

查看实际下载了哪些文件(一般下载4个即可)

[root@mater01 ingress]# ll

total 344

-rw-r--r-- 1 root root 75231 Jan 14 18:13 configmap.yaml

-rw-r--r-- 1 root root 70461 Jan 14 18:13 namespace.yaml

-rw-r--r-- 1 root root 103826 Jan 14 18:13 rbac.yaml

-rw-r--r-- 1 root root 90993 Jan 14 18:13 with-rbac.yaml

 

首先创建ingress-nginx名称空间再批量其他yaml操作

[root@node-001 ingress-nginx]# kubectl apply -f namespace.yaml #会创建一个ingress-nginx名称空间

namespace/ingress-nginx created

 

批量根据清单rbac等等(因为kubeadm安装的k8s默认启用了rbac)

[root@node-001 ingress-nginx]# kubectl apply -f ./

#直接apply当前目录,全部自动创建。自动引入目录下所有的yaml文件

#会自动下载nginx安装pods

configmap/nginx-configuration created

configmap/tcp-services created

configmap/udp-services created

namespace/ingress-nginx unchanged

serviceaccount/nginx-ingress-serviceaccount created

clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created

role.rbac.authorization.k8s.io/nginx-ingress-role created

rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created

clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created

deployment.apps/nginx-ingress-controller created

 

#查看自动安装的nginx-ingress-controller-pod

[root@node-001 ingress-nginx]# kubectl get pods -n ingress-nginx

NAME READY STATUS RESTARTS AGE

nginx-ingress-controller-568867bf56-q2pt2 1/1 Running 0 70s

 

#查看nginx-ingress-controller-pod是否成功

[root@node-001 ~]# kubectl get pods -n ingress-nginx

NAME READY STATUS RESTARTS AGE

nginx-ingress-controller-568867bf56-q2pt2 1/1 Running 0 5d4h

 #注意点:部署在裸机上面,需要额外加上service-Nodeport,虽然内部可以访问,不然外网没有介入。因为前面原理图前面还需要加个service,当然第二种方式,ingress-controller设置为daemonset 设置hostnetwork字段共享节点网络。

 

2、创建service和后端关联的pods

首先部署后端的底层服务service以及pods

[root@node-001 ingress]# cd /opt/manifests/ingress/

[root@node-001 ingress]# vim deploy-demo.yaml #创建ingress---->后面service---->deployment(pods)

apiVersion: v1

kind: Service #给底层pod定义一个service。这个service必须为无头服务,不然无法直接解析对应节点的ip地址。不然得到的是clusterip。往ingress-controller注入会有问题。奇怪的是这边也可以。

metadata:

name: myapp

namespace: default

spec:

selector:

app: myapp

release: canary

ports:

- name: http

port: 80 #service启动端口

targetPort: 80 #pod的端口

---

apiVersion: apps/v1 #上面一定要三个横线分割!

kind: Deployment

metadata:

name: myapp-deploy

namespace: default

spec:

replicas: 3

selector:

matchLabels:

app: myapp

release: canary

template:

metadata:

labels:

app: myapp

release: canary

spec:

containers:

- name: myapp

image: ikubernetes/myapp:v2

ports:

- name: http

containerPort: 80

查看后端pods、service、ingress-controller-pod

[root@node-001 manifests]# kubectl get pods -n ingress-nginx -w

NAME READY STATUS RESTARTS AGE

nginx-ingress-controller-568867bf56-q2pt2 1/1 Running 0 3h12m

[root@node-001 ingress]# kubectl get service

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20d

myapp ClusterIP 10.111.24.58 <none> 80/TCP 101s #ingress后端的service已经创建成功(原理详见上面的图片!)

 

在指定名称中,查看pods详细信息

[root@node-001 manifests]# kubectl describe pods nginx-ingress-controller-568867bf56-q2pt2 -n ingress-nginx

 小知识:不想一个个创建pods、service、ingress-contoller怎么办?直接用官网的mandatory.yaml直接安装

https://github.com/kubernetes/ingress-nginx/blob/master/deploy/static/mandatory.yaml

 

3、创建nginx-ingress-controller-pod前面一层service(不然ingrss-controller没法接入外部请求流量)

核心原理:就是把nginx-ingress-controller-pod,这个特殊pod前面再定义一个service,例如前后端分离,前端接口直接调用这个service实现后端接口访问,这步骤很关键!

#部署Service:ingress-controller(nginx)前端的service,确保外部可以访问

 

下载清单文件

#wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/baremetal/service-nodeport.yaml

手动创建ning-ingree-service清单(不能下载的话)!并修改一下!(创建ingress-nginx前面的service)

#vim service-nodeport.yaml

[root@mater01 ingress]# cat service-nodeport.yaml

apiVersion: v1

kind: Service

metadata:

name: ingress-nginx

namespace: ingress-nginx

spec:

type: NodePort #service-ingree类型为NodePort

ports:

- name: http

port: 80 #定义nginx-ingress-controller-pod前面的service端口是80

targetPort: 80 #nginx-ingress-pod端口

protocol: TCP

nodePort: 30080 #指定serice-ingress端口300080,不然随机分配!注意这个service端口会在k8s所有集群机器开启!

- name: https

port: 443 #service端口是443

targetPort: 443 #pod端口,但是这边没有指定节点端口,所以service节点端口随机分配30000~32767?

protocol: TCP

nodePort: 30443 #指定service端口30443不然随机分配!注意这个service端口会在k8s所有集群机器开启!

selector:

app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx

#注意这个selector特别重要!不然创建的这个service无法把前面创建的ingress-nginx-pod匹配做为endpoints!怎么写(describe pod看一下)看下面!

 

查看selector怎么写?查看ingress-nginx这个pod是否正常运行!

[root@mater01 ingress]# kubectl get pods -n ingress-nginx

NAME READY STATUS RESTARTS AGE

nginx-ingress-controller-948ffd8cc-jqp2h 1/1 Running 0 4h8m

 

查看ingress-nginx-pod的详细信息

[root@mater01 ingress]# kubectl describe pod nginx-ingress-controller-948ffd8cc-jqp2h -n ingress-nginx

Name: nginx-ingress-controller-948ffd8cc-jqp2h

Namespace: ingress-nginx

Priority: 0

Node: node02/172.19.72.234

Start Time: Wed, 15 Jan 2020 10:46:09 +0800

Labels: app.kubernetes.io/name=ingress-nginx #这边是ingress-ninx的pod的标签信息,把这个信息写到前面创建service的slector清单里面去!这步骤很重要!否则创建的service-ingress-nginx无法匹配到ingress-nginx-pod!

app.kubernetes.io/part-of=ingress-nginx

pod-template-hash=948ffd8cc

 

查看创建的ingress-nginx前面的service服务

[root@mater01 ingress]# kubectl get svc -n ingress-nginx

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

ingress-nginx NodePort 10.101.71.230 <none> 80:30080/TCP,443:30443/TCP 2m23s

#这边可以看到service类型为nodeport。端口容器内端口80映射主机端口为30080和30443端口

 

查看ingress-nginx前面的service是否正常,以及这个service是否匹配到后端的ingress-nginx-pod!

[root@mater01 ingress]# kubectl describe svc ingress-nginx -n ingress-nginx

Name: ingress-nginx

Namespace: ingress-nginx

Labels: <none>

Annotations: kubectl.kubernetes.io/last-applied-configuration:

{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"ingress-nginx","namespace":"ingress-nginx"},"spec":{"ports":[{"na...

Selector: app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx

Type: NodePort

IP: 10.103.42.166

Port: http 80/TCP

TargetPort: 80/TCP

NodePort: http 30080/TCP

Endpoints: 10.244.2.6:80 #这边可以看到service成功匹配到后端的ingress-nginx的pod!

Port: https 443/TCP

TargetPort: 443/TCP

NodePort: https 30443/TCP

Endpoints: 10.244.2.6:443

Session Affinity: None

External Traffic Policy: Cluster

Events: <none>

 

查看状态

[root@node-001 ~]# kubectl get pods -o wide --show-labels -n ingress-nginx

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS

nginx-ingress-controller-568867bf56-q2pt2 1/1 Running 0 5d4h 10.244.1.91 node-002 <none> <none> app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx,pod-template-hash=568867bf56

 

查看service-ingress-nginx

[root@node-001 ingress]# kubectl get svc -n ingress-nginx

NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

ingress-nginx ingress-nginx NodePort 10.103.231.49 <none> 80:30080/TCP,443:30443/TCP 48s

#30080端口是service-ingress-nginx的端口,因为前面创建service-ingress-nginx指定service类型为NodePort,端口指定为30080 30443。注意这个端口只要是servic端口!会在集群所有机器开启。

[root@node-001 ingress]# netstat -tunlp|grep 30080

tcp6 0 0 :::30080 :::* LISTEN 3329/kube-proxy

[root@node-001 ingress]# netstat -tunlp|grep 30443

tcp6 0 0 :::30443 :::* LISTEN 3329/kube-proxy

 

在外部IE浏览器尝试访问service-ingress-nginx

访问方式:IP:30080 IP:30443

此时应该是404 ,调度器是正常工作的,但是后端服务没有关联

谷歌浏览器访问: 192.168.100.180:30080

default backend -404 #因为没有定义规则,后端调度没有配置!所以是失败的。

 实验到此总结:第一步创建nginx-ingress-controller-pod、第二步创建nginx-ingress-controller-pod前面的service-ingress-nginx,指定service类型为Nodeport类型。第三步创建底层deploument-pods、第四步配置ingress路由规则全部打通!

 

4、配置ingress路由规则导入。

创建ingress清单
#用ingress自动把pods转换为nginx的配置文件(例如加到upstream里面)。
#核心:利用注解信息annotations标注用的是nginx作为ingress-controller,因为除了nginx还有envoy、traefic等!
--------------------------------------------------------------------------------
[root@mater01 ingress]# kubectl explain ingress #查看定义帮助文档!不会的话百度!!
[root@k8s-master ingress]# vim ingress-myapp.yaml
apiVersion: extensions/v1beta1 #api版本
kind: Ingress #清单类型
metadata: #元数据
name: ingress-myapp #定义ingress的名称
namespace: default #定义ingress路由所属名称空间,注意要和deployment和要发布的service一个名称空间!
annotations: #标注我们用的是nginx,不是envoy、traefic等,核心代码。
kubernetes.io/ingress.class: "nginx" #这个很重要!核心配置,表示前面用的ingress-controller是nginx!才能生成规则!#kubernetes.io是前缀 ingress.class是键名 nginx是数值。表示我们用的ingress-controller是nginx,这样才能自动生成nginx规则!
spec: #下面定义规则!
rules: #定义后端转发的规则。# kubectl explain ingress.spec
- host: myapp.dayu.com 使用第一种,虚拟主机来做!nginx有两种一种是虚拟主机,一种是URL映射!通过域名进行转发#需要确保,在互联网外部能解析这个主机名字!解析的结果能达到前面的nodeport-service。
http: #利用http定义前后端路径!
paths: #查看帮助文档:# kubectl explain ingress.spec.rules.http.paths
- path: #配置域名访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"
backend: #指定后端服务。
serviceName: myapp #ingress后端的service名字!
servicePort: 80 #ingress-后端service的端口是80 # kubectl describe svc myapp,Endpoints: 10.244.1.10:80,10.244.1.9:80,10.244.2.9:80 这个三个pod作为upstream的后端!

 

创建ingress路由 

[root@k8s-master ingress]# kubectl apply -f ingress-myapp.yaml

[root@k8s-master ingress]# kubectl get ingress

#查看ingress服务 NAME HOSTS ADDRESS PORTS AGE ingress-myapp myapp.dayu.com 80 46s

 

查看ingress信息

[root@node-001 ingress]# kubectl get ingress -A

NAMESPACE NAME HOSTS ADDRESS PORTS AGE

default ingress-myapp myapp.dayu.com 10.103.231.49 80 16m

[root@node-001 ingress]# kubectl describe ingress ingress-myapp

Name: ingress-myapp

Namespace: default

Address: 10.103.231.49

Default backend: default-http-backend:80 (<none>)

Rules:

Host Path Backends

---- ---- --------

myapp.dayu.com #主机名

myapp:80 (10.244.1.95:80,10.244.1.96:80,10.244.1.97:80) #后端提供pod服务地址!

Annotations:

kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-myapp","namespace":"default"},"spec":{"rules":[{"host":"myapp.dayu.com","http":{"paths":[{"backend":{"serviceName":"myapp","servicePort":80},"path":null}]}}]}}

kubernetes.io/ingress.class: nginx #ingress前面的类别用的是nginx,不是envoy、traefic!

 

#(ingress路由创建完成,会自动配置ingress-nginx配置文件)

#进入ingress-controller-pod的nginx,查看nginx配置文件

[root@mater01 ingress]# kubectl get pods -A|grep ingress-nginx

ingress-nginx nginx-ingress-controller-948ffd8cc-jqp2h 1/1 Running 0 2d

[root@node-001 ingress]# kubectl exec -n ingress-nginx -it nginx-ingress-controller-568867bf56-q2pt2 -- /bin/sh

$ ls

fastcgi_params mime.types nginx.conf template

geoip modsecurity opentracing.json

lua modules owasp-modsecurity-crs

$ cat nginx.conf

xxxx 这个nginx配置文件

 

修改linux主机、以及windows主机hosts

[root@mater01 ~]# vim /etc/hosts

192.168.100.180 myapp.dayu.com

192.168.100.181 myapp.dayu.com

 

浏览器chrome浏览器输入:myapp.dayu.com:30080 或者http://myapp.dayu.com:30080/hostname.html

实验到此成功结束!


 

 例子2(实战tomcat)

每个node拉取镜像

[root@node-001 ingress]# docker pull tomcat:8.5.34-jre8-alpine

#去dockerhub.com下载容器:hub.docker.com

 

创建Service和Pod配置文件

[root@node-001 ingress]# vim tomcat-deploy.yaml

apiVersion: v1

kind: Service #这个service必须为无头服务,不然无法解析对应节点的ip地址。

metadata:

name: tomcat

namespace: default

spec:

selector:

app: tomcat

release: canary

ports:

- name: http

port: 8080 #这边是service的8080端口映射后端tomcat-pod的8080,但是这个是service层面的,只是cluster ip层级的。用来被ingress规则所识别有哪些后端pod,哪些端口。

targetPort: 8080

- name: ajp

port: 8009

targetPort: 8009

---

apiVersion: apps/v1 #--- 三个横线表示分割

kind: Deployment

metadata:

name: tomcat-deploy

namespace: default

spec:

replicas: 3

selector:

matchLabels:

app: tomcat

release: canary

template:

metadata:

labels:

app: tomcat

release: canary

spec:

containers:

- name: tomcat

image: tomcat:8.5.34-jre8-alpine

ports:

- name: http

containerPort: 8080

- name: ajp

containerPort: 8009

 

创建Pods以及Service

[root@node-001 ingress]# kubectl apply -f tomcat-deploy.yaml

service/tomcat created

 

检查tomcat是否跑在8080端口

[root@node-001 ingress]# kubectl exec -it tomcat-deploy-56c494fc77-cm6f5 -- /bin/sh

[root@node-001 ingress]# kubectl exec -it tomcat-deploy-56c494fc77-cm6f5 -- netstat -tunlp

/usr/local/tomcat # netstat -tunlp

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name

tcp 0 0 :::8080 :::* LISTEN 1/java

tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 1/java

tcp 0 0 :::8009

 

创建ingress路由规则(基于域名)

[root@node-001 ingress]# vim ingress-tomcat.yaml

apiVersion: extensions/v1beta1 #ingress-api版本 #kubcectl explian ingress

kind: Ingress #清单类型是ingress路由

metadata:

name: ingress-tomcat #ingress路由的名称

namespace: default #所属名称空间,要和后端发布的service属于同一名称之中。

annotations: #注解信息,说明下面用到的是nginx不是其他的才能转换为ingress-contorller规则

kubernetes.io/ingress.class: "nginx" #说明ingress-controller用的是nginx,这样才能生成匹配规则。

spec: #定义ingress规则

rules: #定义后端转发的规则

- host: tomcat.dayu.com #通过域名进行转发

http:

paths:

- path: #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"

backend: #配置ingress后端的service服务

serviceName: tomcat #后端service暴露的名字,ingress通过这个service去关联后端pods。

servicePort: 8080 #后端service端口!ingree默认是80.怎么再暴露一个8009,再定义一个path。也就是说 访问nginx 的80。 nginx反向代理到service的8080端口。

创建ingress规则

[root@node-001 ingress]# kubectl apply -f ingress-tomcat.yaml

ingress.extensions/ingress-myapp configured

[root@node-001 ingress]#

[root@node-001 ingress]# kubectl get ingress -A

NAMESPACE NAME HOSTS ADDRESS PORTS AGE

default ingress-myapp tomcat.dayu.com 80 7s

[root@node-001 ingress]# kubectl describe -n default ingress ingress-tomcatp

 

查看路由规则

[root@mater01 ingress]# kubectl get ingress -A

NAMESPACE NAME HOSTS ADDRESS PORTS AGE

default ingress-myapp myapp.dayu.com 10.103.42.166 80 20m

 

k8s节点所有linux主机添加hosts解析

[root@mater01 ~]# vim /etc/hosts

192.168.100.180 tomcat.dayu.com

192.168.100.181 tomcat.dayu.com

 

本地windows电脑添加hosts添加解析

192.168.100.180 myapp.dayu.com tomcat.dayu.com

 

windows打开浏览器输入C:\windows\System32\drivers\etc

tomcat.dayu.com:30080 #nginx服务暴露的端口

 

或者直接在linux机器执行

[root@mater01~]# curl tomcat.dayu.com:30080

[root@mater01~]# curl tomcat.dayu.com:30443

#因为创建ingress-nginx-service暴露的是30080端口!

[root@mater01 ingress]# kubectl get svc -A|grep ingress-nginx

ingress-nginx ingress-nginx NodePort 10.103.42.166 <none> 80:30080/TCP,443:30443/TCP 44h

 可以登录nginx-pod查看ngin-conf生成的规则,只要ingress已创建,直接映射进去了。


 

 

例子3(实战tomcat配置https证书)

#创建 自签证书,然后把证书转换为secreat,加载到pod里面去!

创建证书

[root@node-001 ingress]# openssl genrsa -out tls.key 2048

Generating RSA private key, 2048 bit long modulus

................+++

..+++

e is 65537 (0x10001)

[root@node-001 ingress]# ls

deploy-demo.yaml ingress-myapp.yaml ingress-nginx ingress-tomcat.yaml service-nodeport.yaml tls.key tomcat-demo.yaml tomcat-pod.yaml

[root@node-001 ingress]#

[root@node-001 ingress]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=tomcat.dayu.com

[root@node-001 ingress]# ls

deploy-demo.yaml ingress-myapp.yaml ingress-nginx ingress-tomcat.yaml service-nodeport.yaml tls.crt tls.key tomcat-demo.yaml tomcat-pod.yaml

[root@node-001 ingress]#

#注意证书不能直接贴到nginx里面。需要转换成特殊格式。secreat,screat可以注入到k8s,被k8s引用。

[root@node-001 ingress]# kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key

secret/tomcat-ingress-secret created

 

查看目前的secret

[root@node-001 ingress]# kubectl get secret

NAME TYPE DATA AGE

default-token-xd2gw kubernetes.io/service-account-token 3 26d

tomcat-ingress-secret kubernetes.io/tls 2 18s #已经被创建。

 

查看tomcat的secret

[root@node-001 ingress]# kubectl describe secret tomcat-ingress-secret

Name: tomcat-ingress-secret

Namespace: default

Labels: <none>

Annotations: <none>

Type: kubernetes.io/tls

Data

====

tls.key: 1679 bytes

tls.crt: 1289 bytes

[root@node-001 ingress]#

 

把tls配置进去

[root@node-001 ingress]# kubectl explain ingress.spec.tls

[root@node-001 ingress]# cp ingress-tomcat.yaml ingress-tomcat-tls.yaml

[root@node-001 ingress]# vim ingress-tomcat-tls.yaml

apiVersion: extensions/v1beta1 #api版本

kind: Ingress #清单类型

metadata: #元数据

name: ingress-tomcat-tls #ingress的名称

namespace: default #所属名称空间,和要发布的service属于同一名称之中。

annotations: #注解信息,说明下面用到的是nginx不是其他的。才能转换为ingress-contorller对应匹配的规则

kubernetes.io/ingress.class: "nginx" #说明ingress-controller用的是nginx,这样才能生成匹配规则。

spec: #规格

tls:

- hosts:

- tomcat.dayu.com #把哪个主机做成tls。

secretName: tomcat-ingress-secret #通过命令查看: kubectl get secret

rules: #定义后端转发的规则

- host: tomcat.dayu.com #通过域名进行转发

http:

paths:

- path: #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"

backend: #配置后端服务

serviceName: tomcat #后端service暴露的名字

servicePort: 8080 #后端service端口

 

应用tls

[root@node-001 ingress]# kubectl apply -f ingress-tomcat-tls.yaml

ingress.extensions/ingress-tomcat-tls created

 

查看ingress详细

[root@node-001 ingress]# kubectl get ingress

NAME HOSTS ADDRESS PORTS AGE

ingress-tomcat tomcat.dayu.com 10.103.231.49 80 80m

ingress-tomcat-tls tomcat.dayu.com 10.103.231.49 80, 443 40s

[root@node-001 ingress]# kubectl describe ingress

Events:

Type Reason Age From Message

---- ------ ---- ---- -------

Normal CREATE 53s nginx-ingress-controller Ingress default/ingress-tomcat-tls

Normal UPDATE 49s nginx-ingress-controller Ingress default/ingress-tomcat-tls

 

进入ingress-nginx命名空间的pod,查看

[root@node-001 ingress]# kubectl exec -it -n ingress-nginx nginx-ingress-controller-568867bf56-q2pt2 -- /bin/sh

$ ls

fastcgi_params geoip lua mime.types modsecurity modules nginx.conf opentracing.json owasp-modsecurity-crs template

$ cat nginx.conf

xxxxxx

server {

server_name tomcat.dayu.com ;

listen 80 ;

listen [::]:80 ;

listen 443 ssl http2 ;

listen [::]:443 ssl http2 ;

set $proxy_upstream_name "-";

ssl_certificate_by_lua_block {

certificate.call()

}

# PEM sha: c8b9956633fbec541a874a74ff309f8477b4d0f4

ssl_certificate /etc/ingress-controller/ssl/default-fake-certificate.pem;

ssl_certificate_key /etc/ingress-controller/ssl/default-fake-certificate.pem;

xxxxxx

 

打开浏览器访问试下

https://tomcat.dayu.com:30443/ nginx映射的端口

igress实验到此结束!

$ kubectl get ing
NAME RULE BACKEND ADDRESS
test - 178.91.123.132
foo.bar.com
/foo s1:80
bar.baz.com
/foo s2:80
 
 
 
 
 
 
[root@master ~]# cat mandatory.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: udp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: nginx-ingress-role
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
    spec:
      terminationGracePeriodSeconds: 300
      serviceAccountName: nginx-ingress-serviceaccount
      nodeSelector:
        kubernetes.io/os: linux
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            allowPrivilegeEscalation: true
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            runAsUser: 101
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown

---

apiVersion: v1
kind: LimitRange
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  limits:
  - min:
      memory: 90Mi
      cpu: 100m
    type: Container

 

[root@master ~]# kubectl apply -f https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yamlerror: error parsing https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yaml: error converting YAML to JSON: yaml: line 124: mapping values are not allowed in this context[root@master ~]# wget https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yaml--2020-08-19 13:55:58--  https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yamlResolving github.com (github.com)... 13.229.188.59Connecting to github.com (github.com)|13.229.188.59|:443... connected.HTTP request sent, awaiting response... 200 OKLength: unspecified [text/html]Saving to: ‘mandatory.yaml’
    [    <=>                                                                                                                       ] 156,495      175KB/s   in 0.9s
2020-08-19 13:56:03 (175 KB/s) - ‘mandatory.yaml’ saved [156495]
[root@master ~]#

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM