k8s之Ingress-nginx基本原理及部署实战

kubernetes服务暴露介绍

到目前为止,kubernetes总共有三种暴露服务的方式:

  • LoadBlancer Service
  • NodePort Service
  • Ingress

LoadBlancer Service

LoadBlancer Service是kubernetes结合云平台的组件,如国外的GCE,AWS,国内阿里云等等。使用它项使用的底层云平台申请创建负载均衡器来实现,对使用云平台的集群比较方便,但有局限,费用高。

NodePort Service

我们之前博文中暴露服务时,用的都是nodeport,实质上就是通过在集群的每个节点上暴露一个端口,然后将这个端口映射到某个具体的service来实现的,比较直观方便,虽然每个node的端口有很多(0~65535),但是由于安全和易用方面(服务多了就乱了,还有端口冲突问题)且对主机安全性存在一定风险(内网环境,问题不大),所以实际使用并不多,当然对于小规模的集群服务,还是比较不错的。

以上两种服务从各方面看似都不太理想,所以通过情况下,我们会通过Ingress对象来实现(安全,方便统一管理)。

Ingress概述

一,什么是Ingress?

在kubernetes集群中,我们知道service和pod的ip仅在集群内部访问。如果外部应用要访问集群内的服务,集群外部的请求需要通过负载均衡转发到service在Node上暴露的NodePort上,然后再由kube-proxy组件将其转发给相关的pod。

而Ingress就是为进入集群的请求提供路由规则的集合,通俗点就是提供外部访问集群的入口,将外部的HTTP或者HTTPS请求转发到集群内部service上。


流程图如上,其中Ingress代理的并不是pod的service,而是pod,之所以在配置的时候是配置的service,是为了通过service来获取所有pod的信息。
.

二,Ingress-nginx组成

Ingress-nginx一般由三个组件组成:

  • 反向代理负载均衡器
  • Ingress Controller
  • Ingress
1)反向代理负载均衡器:通常以service的port方式运行,接收并按照ingress定义的规则进行转发,常用的有nginx,Haproxy,Traefik等,本文中使用的就是nginx。
 2)ingress-nginx-Controller: 监听APIServer,根据用户编写的ingress规则(编写ingress的yaml文件),动态地去更改nginx服务的配置文件,并且reload重载使其生效,此过程是自动化的(通过lua脚本来实现)。
3)Ingress:将nginx的配置抽象成一个Ingress对象,当用户每添加一个新的服务,只需要编写一个新的ingress的yaml文件即可。

三,Ingress-nginx的工作原理

1)ingress controller通过和kubernetes api交互,动态的去感知集群中ingress规则变化。
2)然后读取它,按照自定义的规则,规则就是写明了那个域名对应哪个service,生成一段nginx配置。
3)在写到nginx-ingress-controller的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中。
4)然后reload一下使配置生效,以此达到分配和动态更新问题。

四,ingress-nginx解决了生产环境中哪些问题?

1)动态配置服务:
如果按照传统方式,当新增加一个服务时,我们可能需要在流量入口加一个反向代理指向我们新的服务,而使用ingress,只需要配置好ingress,当服务启动时,会自动注册到ingress当中,不需要额外的操作。

2)减少不必要的Port暴露(安全,端口容易管理)
我们知道部署k8s时,是需要关闭防火墙的,主要原因是k8s的很多服务会以nodeport方式映射出去,这样对于宿主机来说是非常的不安全的,而ingress可以避免这个问题,只需要将ingress自身服务映射出去,就可代理后端所有的服务,则后端服务不需要映射出去。

部署Ingress-nginx

本文通过以下配置示例来实践ingress-nginx:

在本文部署ingress-nginx中所有用到的docker镜像包,大家可以从我GitHub中进行下载,镜像包下载链接:https://github.com/sqm-sys/Ingress-nginx/releases

一,部署ingress-nginx前准备:

1,搭建私有仓库(registry),并push测试镜像(apache,tomcat)到仓库中

#运行registry私有仓库:
[[email protected] ~]# docker run  -d --name registry --restart=always -p 5000:5000 -v /data/registry:/var/lib/registry registry
#修改docker配置文件:
[[email protected] ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H unix:// --insecure-registry 172.16.1.30:5000
#拷贝修改后的docker配置文件到集群其他节点中:
[[email protected] ~]# scp /usr/lib/systemd/system/docker.service  node01:/usr/lib/systemd/system/
[[email protected] ~]# scp /usr/lib/systemd/system/docker.service  node02:/usr/lib/systemd/system/
#集群中所有主机重新加载进程,并重启docker服务:
[[email protected] ~]# systemctl daemon-reload
[[email protected] ~]# systemctl restart docker
#push测试镜像至私有仓库:
[[email protected] ~]# docker push 172.16.1.30:5000/apache:v1
[[email protected] ~]# docker push 172.16.1.30:5000/tomcat:v1 

2,创建namespace
#创建yaml文件:

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-test
#创建并查看namespace:
[[email protected] ~]# kubectl create -f ns.yaml
namespace/ingress-nginx created
[[email protected]ter ~]# kubectl  get ns
NAME              STATUS   AGE
default           Active   92d
ingress-test     Active   4s

3,创建deployment及service资源进行测试
1)创建httpd及service资源:

[[email protected] ~]# mkdir ingress-nginx
[[email protected] ~]# cd ingress-nginx/
[[email protected] ingress-nginx]# vim httpd.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: httpd
  namespace: ingress-test
spec:
  replicas: 3
  template:
    metadata:
      labels:
        name: httpd
    spec:
      containers:
      - name: httpd
        image: 172.16.1.30:5000/apache:v1  #镜像从私有仓库中进行拉取
---
apiVersion: v1
kind: Service
metadata:
  name: httpd-svc
  namespace: ingress-test
spec:
  type: NodePort
  selector:
    name: httpd
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 32134

2)创建tomcat及service资源:

[[email protected] ingress-nginx]# vim tomcat.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: tomcat
  namespace: ingress-test
spec:
  replicas: 3
  template:
    metadata:
      labels:
        name: tomcat
    spec:
      containers:
      - name: tomcat
        image: 172.16.1.30:5000/tomcat:v1
---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
  namespace: ingress-test
spec:
  type: NodePort
  selector:
    name: tomcat
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
    nodePort: 32135

#创建以上两个应用,并查看是否创建成功:

[[email protected] ingress-nginx]# kubectl create -f  httpd.yaml
deployment.extensions/httpd created
service/httpd-svc create
[[email protected] ingress-nginx]# kubectl create -f tomcat.yaml
deployment.extensions/tomcat created
service/tomcat-svc created



3)测试外部通过nodeport方式能否访问到集群内部应用:

可以看到通过nodeport暴露的方式是没有问题的,但是到该种方式在大规模的集群服务中,有很大的缺陷,所以接下来通过ingress-nginx进行实现。

二,创建ingress-nginx

1)GitHub上下载yaml文件的网页链接:https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/index.md

进入后显示以下页面:


#注意:网页上完整的命令是直接执行该yaml文件,我们先不要执行,先将该yaml文件下载到本地主机上。(复制命令即可)

[[email protected] ingress-nginx]# wget  https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.28.0/deploy/static/mandatory.yaml
[[email protected] ingress-nginx]# ls
httpd.yaml  mandatory.yaml  tomcat.yaml

2)修改yaml文件:
[[email protected] ingress-nginx]# vim mandatory.yaml
#添加以下字段:

hostNetwork: true
如果使用此网络参数,那么pod中运行的应用程序可以直接使用node节点端口,这样node节点主机所在的网络的其他主机,都可以通过访问到此应用程序。
nodeSelector:
设置节点标签选择器,指定在哪台节点上运行。(保持默认即可,让它自己选择,当然大家也可以自定义标签并选择运行对应的node)
.
上面镜像包的版本可能会经常的更新,我用的是当前最新版本0.28.0,大家可以根据自己想用的版本进行下载。

注意:因为默认yaml文件中指定下载地址是国外的镜像,由于国内网络环境限制,我们不能直接从google的镜像站下载镜像,所以大家可以通过以下方式进行下载:
[[email protected] ingress-nginx]# docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.28.0

3)导入镜像包-将nginx-ingress-controller.0.28.0镜像包导入集群中的各个节点:

[[email protected] ~]# docker load < nginx-ingress-controller.0.28.0.tar
[[email protected] ~]# docker images | grep nginx-ingress
registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller   0.28.0              61de39f77f45        7 days ago          305MB

//在master上执行该yaml文件:

//查看ingress-nginx pod是否运行:
[[email protected] ingress-nginx]# kubectl get pod -n ingress-nginx  -o wide
NAME                                        READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-ingress-controller-685985b5b8-8mzjc   1/1     Running   0          43s   172.16.1.32   node02   <none>           <none>

4)创建ingress规则(YAML文件)
yaml文件内容如下:

[[email protected] ingress-nginx]# vim ingress-rule.yaml
apiVersion: extensions/v1beta1
kind: Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  namespace: ingress-test
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: ingress.test.com   #后端应用通过该域名进行访问
    http:
      paths:
      - path: /   #apache的网页根目录:/
        backend:
          serviceName: httpd-svc
          servicePort: 80
      - path: /tomcat   #tomcat的网页更目录:/tomcat
        backend:
          serviceName: tomcat-svc
          servicePort: 8080

创建该规则就是用于分别代理后端的apache和tomcat服务。

//创建ingress,并查看绑定信息:
[[email protected] ingress-nginx]# kubectl create -f ingress-rule.yaml
ingress.extensions/test-ingress created
[[email protected] ingress-nginx]# kubectl get ingresses. -n ingress-test
NAME           HOSTS              ADDRESS   PORTS   AGE
test-ingress   ingress.test.com             80      17s

#查看describe查看详细信息(确保成功绑定后端得到apache和tomcat服务)


##进入ingress容器查看nginx的配置文件:

[[email protected] ingress-nginx]# kubectl exec  -it -n ingress-nginx nginx-ingress-controller-685985b5b8-8mzjc  /bin/sh
/etc/nginx $ cat nginx.conf


通过查看nginx配置文件,我们可以清楚的知道之前所说的ingress-controller会根据我们编写的ingress规则(代理后端应用),动态的去更改nginx的配置文件。

5)通过域名访问集群内的服务

##当前我们需要知道ingress运行在那个node上:
[[email protected] ingress-nginx]# kubectl get pod -o wide -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-ingress-controller-685985b5b8-8mzjc   1/1     Running   0          31m   172.16.1.32   node02   <none>           <none>

在windows主机上将node02的ip地址添加到hosts文件中,做域名解析:

修改路径:C:\Windows\System32\drivers\etc\hosts(需要给予修改权限)
172.16.1.32 ingress.test.com  #添加该条内容

##访问httpd:

##访问tomcat:

6)创建ingress的service资源对象:
虽然上面通过ingress已经能够代理后端的应用了,但是我们可以发现只能通过指定运行节点的地址来做域名解析(访问网页),不能通过集群中的其他节点来访问,如果该节点挂掉了,则会导致ingress无法代理后端的应用,所以我们需要为ingress创建service资源。

GitHub上为我们提供了YAML文件:

##我们将其下载到本地:

[[email protected] ingress-nginx]# wget  https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.28.0/deploy/static/provider/baremetal/service-nodeport.yaml
[[email protected] ingress-nginx]# cat service-nodeport.yaml   #不需要我们做修改,这里只是查看下内容
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

//我们创建该service资源对象:

[[email protected] ingress-nginx]# kubectl create -f service-nodeport.yaml
service/ingress-nginx created
[[email protected] ingress-nginx]# kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.101.206.247   <none>        80:30842/TCP,443:32550/TCP   20s

#可以看到nodeport为我们映射出http和https的随机端口30842/32550。我们通过此端口,就可指定集群中任意一台节点的地址都可以代理后端的应用,即使集群中某一节点宕机也不会影响外部通过域名访问。

##访问apache:

##访问tomcat


此时在windows主机中的host文件中,随便绑定集群中的任意节点的ip地址,都是可以进行解析网页的(大家可自己测试),从而解决了我们之前所担心的问题,相比于之前nodeport方式,证明ingress可以解决不必要的port暴露,只需要映射ingress的端口,就可以代理后端所有的应用,从而满足了我们的需求。

.

三,基于虚拟主机的ingress

搭建虚拟主机的目的:实现以不同的域名访问同一个web界面
本文就仅基于上面的httpd服务,我们为该服务绑定两个不同的域名来访问:
##修改ingress规则文件(完整的yaml配置如下)

apiVersion: extensions/v1beta1
kind: Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  namespace: ingress-test
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: ingress.test.com
    http:
      paths:
      - path: /
        backend:
          serviceName: httpd-svc
          servicePort: 80
      - path: /tomcat
        backend:
          serviceName: tomcat-svc
          servicePort: 8080
  - host: ingress.test2.com   #只需要在rules字段下添加另一个host字段即可,这里只实现httpd的,如果有需求可以添加上tomcat的。
    http:
      paths:
      - path: /
        backend:
          serviceName: httpd-svc   #注意,serviceName所有虚拟主机必须保持一致
          servicePort: 80

//创建新的虚拟主机并查看:

[[email protected] ingress-nginx]# kubectl apply -f  ingress-rule.yaml
ingress.extensions/test-ingress configured
[[email protected] ingress-nginx]# kubectl get ingresses. -n ingress-test
NAME           HOSTS                                ADDRESS          PORTS   AGE
test-ingress   ingress.test.com,ingress.test2.com   10.101.206.247   80      83m

//通过不同的域名进行访问httpd网页:

因为我们没有搭建dns服务器,所以需要在windows hosts文件将新的域名进行绑定(地址可以绑定集群中任意一台node):
172.16.1.31 ingress.test.com
172.16.1.32 ingress.test2.com



至此,实现了多个不同域名能够同时访问后端的应用。
.

四,基于HTTPS的Ingress(443端口)

通过部署ingress后,我们不必按照常规的,为后端所有的pod都颁发一个证书,只需为ingress代理的域名颁发证书就能够实现。

1)创建CA证书:

[[email protected] HTTPS]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"  #参数可根据需求自定义
Generating a 2048 bit RSA private key
..............................+++
..+++
writing new private key to ‘tls.key‘
-----

#创建完成后,会在当前目录下生成密钥和证书文件:

[[email protected] HTTPS]# ls
tls.crt  tls.key

2)创建deployment,service,ingress资源:(以nginx服务来实践)
[[email protected] HTTPS]# vim nginx-ingress2.yaml
#完整的yaml文件内容如下:

apiVersion: extensions/v1beta1    #创建deployment
kind: Deployment
metadata:
  name: web
  namespace: ingress-test
spec:
  template:
    metadata:
      labels:
        name: test-web
    spec:
      containers:
      - name: web
        image: 172.16.1.30:5000/nginx:v1  #私有仓库中的镜像(已提供)
---
apiVersion: v1    #创建service,关联上述deployment
kind: Service
metadata:
  name: web-svc
  namespace: ingress-test
spec:
  selector:
    name: test-web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: extensions/v1beta1  #创建ingress规则
kind: Ingress
metadata:
  name: test-ingress2
  namespace: ingress-test
spec:
  tls:          #为域名颁发证书
    - hosts:
      - ingress.nginx.com
      secretName: tls-secret
  rules:
    - host: ingress.nginx.com
      http:   #注意,此处字段为http,不支持https
        paths:
        - path: /
          backend:
            serviceName: web-svc
            servicePort: 80
##创建基于https的ingress服务(nginx):
[[email protected] HTTPS]# kubectl create -f  nginx-ingress2.yaml
deployment.extensions/web created
service/web-svc created
ingress.extensions/test-ingress2 created

##查看ingress资源和映射的service端口:

[[email protected] HTTPS]# kubectl get pod -n ingress-test | grep web
web-74cf864c58-rnvpx      1/1     Running   0          24s

[[email protected] HTTPS]# kubectl get ingresses. -n ingress-test
NAME            HOSTS                                ADDRESS          PORTS     AGE
test-ingress    ingress.test.com,ingress.test2.com   10.101.206.247   80        127m
test-ingress2   ingress.nginx.com                    10.101.206.247   80, 443   5m32s
#可以看到新创建的ingress提供了80和443端口
//查看ingress的service映射的端口
[[email protected] HTTPS]# kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.101.206.247   <none>        80:30842/TCP,443:32550/TCP   86m

3)通过ingress代理的443端口访问nginx服务:

#在hosts文件中绑定域名:
172.16.1.32 ingress.nginx.com

#访问网址:https://ingress.nginx.com:32550/

基于HTTPS的ingress服务成功实现,至此,ingress-nginx部署完成。。。。。。。

原文地址:https://blog.51cto.com/13972012/2469368

时间: 2024-10-03 07:12:53

k8s之Ingress-nginx基本原理及部署实战的相关文章

K8s Ingress Nginx 支持 Socket.io

Ingress 及 Ingress Controller 简介 Ingress:是k8s 资源对象,用于对外暴露服务,该资源对象定义了不同主机名(域名)及 URL 和对应后端 Service(k8s Service)的绑定,根据不同的路径路由 http 和 https 流量. Ingress Contoller:是一个pod服务,封装了一个Web前端负载均衡器,同时在其基础上实现了动态感知Ingress 并根据Ingress的定义动态生成前端web负载均衡器的配置文件,比如Nginx Ingre

k8s之ingress方向代理pod

Ingress controller Nginx -->后来改造 Traefik -->也是用于微服务 Envoy  -->微服务 Ingress资源 目前使用0.17.1版本ingress-nginx ingress定义  后端pod发生变化,service就变化,service变化ingress就发生变化,ingress再把变化注入到ingress-nginx-controller主容器的nginx的backend反向代理配置且重载配置文件使之能够动态改变反向代理配置 kubectl

.Net Core 在 Linux-Centos上的部署实战教程(一)

原文:.Net Core 在 Linux-Centos上的部署实战教程(一) pa我是在VS2017上写好项目然后来部署的,我的宗旨能截图就少BB 服务器系统: Asp.Net Core版本: 1.往服务器安装.net core 2.1 https://www.microsoft.com/net/download/linux-package-manager/centos/sdk-current 微软官方文档介绍 添加dotnet产品Feed 在安装.NET之前,您需要注册Microsoft密钥,

《跟菜鸟学Cisco UC部署实战》-视频课程-学习投资

有朋友,有学生,问到学习投资些什么,注意:投资可重复利用!就看你怎么用!!! 所以,我写下此博文,目的为了更方便学员学习! 一.在线培训(直播): 1. 学费: 8168元. (目前没开班,如果需要培训大纲,培训计划,请联系QQ:学无止境 3313395633 ) 2. 1条电话初装费 初装费:150元(大约)+31元/月,测试后可以,如果不用,请停机保号,停机保号:5元/月. 3. 1条宽带 默认大家都能上网,不用单独投资! 4. 语音网关 680元(老师为购买此组合,本课程中使用此组合! 一

web服务器配置及nginx和mysql部署

nginx 编译安装方法: mkdir -p /home/oldboy/tools cd /home/oldboy/tools wget http://nginx.org/download/nginx-1.8.1.tar.gz    ########或者 rz 上传本地的nginx包 2.安装pcre yum install pcre-devel -y                      ########依赖包 3.安装openssl yum install openssl-devel  

Exchange Server2013 系列七:客户端访问服务器高可用性部署实战

杜飞 在前面的文章中我们介绍了客户端访问服务器的高可用性技术,从这篇文章开始,我们就来看一个详细的高可用性部署方案. 首先,看一下我们的服务器列表: 编号 服务名 IP地址 功能 1 HYV01 IP:10.41.3.6 \16  网关:10.41.1.254 宿主机 2 HYV02 IP:10.41.4.6 \16  网关:10.41.1.254 宿主机 3 DF-DC01 IP:10.41.4.210\16 网关:10.41.1.254 DNS:10.41.4.210   10.41.4.2

我在编写《微软System Center 2012 R2私有云部署实战》中应用的一些小技巧

相信很多同学在处理超大文件,比如几万字.几十万字的文章中,需要图文混排.而图文混排可能会涉及到对图片编号和描述.比如我在<微软System Center 2012 R2私有云部署实战>中,就需要频繁的对章节.图片进行编号.更悲剧的是,有时候写了很多章,一个章节几百张图,需要在某一个位置插一张图,这个时候就需要对后面的图片编号全部重新排列. 这酸爽,干一次绝对不想干第二次.老实说,我在一开始其实也是没把这个当回事的,所以每一字都是自己打出来的,没有在处理word文档的时候 用到一些自动化的手段,

《跟菜鸟学Cisco UC部署实战》-让您学了更菜

<跟菜鸟学Cisco UC部署实战> 链接:http://pan.baidu.com/s/1c25GQLq   密码:f4zu 咨询: Cisco 菜鸟:3313395633

《大企业云桌面部署实战》公开课

作者:学 无 止 境 QQ 交 流 群:454544014      ****************************************************************************************************** 方式:QQ直播(QQ讨论群) 收费:免费 (欢迎报名,请联系QQ群) 服务:提供<大企业云桌面部署实战>整个线下课程的讲解.不提供:课件,视频,技术支持. 星期:每周三 时间:20:30-22:30 纪律:请各位学员自觉遵