k8s之nginx-ingress

一、Ingress 简介

在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,在Kubernetes 目前 提供了以下几种方案:

  • NodePort
  • LoadBalancer
  • Ingress

Ingress 可以解决什么问题

1.动态配置服务
  如果按照传统方式, 当新增加一个服务时, 我们可能需要在流量入口加一个反向代理指向我们新的k8s服务. 而如果用了Ingress, 只需要配置好这个服务, 当服务启动时, 会自动注册到Ingress的中, 不需要而外的操作.
2.减少不必要的端口暴露
  配置过k8s的都清楚, 第一步是要关闭防火墙的, 主要原因是k8s的很多服务会以NodePort方式映射出去, 这样就相当于给宿主机打了很多孔, 既不安全也不优雅. 而Ingress可以避免这个问题, 除了Ingress自身服务可能需要映射出去, 其他服务都不要用NodePort方式

二、Ingress工作原理

ngress 简单的理解就是你原来需要改 Nginx 配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yaml 创建,每次不要去改 Nginx 了,直接改 yaml 然后创建/更新就行了;那么问题来了:”Nginx 该怎么处理?”

Ingress Controller 这东西就是解决 “Nginx 的处理方式” 的;Ingress Controoler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取他,按照他自己模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最后 reload 一下,工作流程如下图:

nginx-ingress.png

实际上Ingress也是Kubernetes API的标准资源类型之一,它其实就是一组基于DNS名称(host)或URL路径把请求转发到指定的Service资源的规则。用于将集群外部的请求流量转发到集群内部完成的服务发布。我们需要明白的是,Ingress资源自身不能进行“流量穿透”,仅仅是一组规则的集合,这些集合规则还需要其他功能的辅助,比如监听某套接字,然后根据这些规则的匹配进行路由转发,这些能够为Ingress资源监听套接字并将流量转发的组件就是Ingress Controller。

三、部署Ingress

部署环境:centos-7.6
kubernetes-1.16.0
Docker version 19.03.4
nginx-ingress-controller-0.16.2
defaultbackend-1.4

1.准备Ingres镜像
把Igress所需镜像在nginx-ingress/docker_image目录的镜像到导入k8s的node节点或者导进harbor (镜像已打包好)
部署相关yaml文件和镜像请访问:链接: https://pan.baidu.com/s/1jBEJKQG4CuIo299JytKl0A 提取码: vhue

也可以通过官网下载最新yaml(网速比较慢)

wget  https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml 

下载后进入相关目录

[root@master-01 nginx-ingress]# tree 
.
├── docker_image(镜像)
│   ├── defaultbackend.tar.gz
│   └── nginx-ingress-controller_0.16.2.tar.gz
└── yaml(ingress配置文件)
    └── nginx-ingress.tar.gz

手动导入到要运行Ingress的node节点
导入方法

[root@jenkins ~]# cat nginx-ingress-controller:0.16.2.tar.gz | docker import - #导入nginx-ingress的控制器镜像
sha256:531e7aea5ce40a57e18d57bd2d1149e16972dfe9ab633bca8b58ae2df486fff7

[root@jenkins ~]# cat defaultbackend.tar.gz | docker import - #导入defaultbackend镜像
sha256:03ca9819157b3ff9daf7cb1a96b984a4eb7881d16ac3e2ff5d46c8b38729882c

检查镜像是否导进去

root@jenkins ~]# docker image ls
REPOSITORY                                                        TAG                 IMAGE ID            CREATED              SIZE
busybox                                                           latest              020584afccce        4 weeks ago          1.22MB
registry.aliyuncs.com/google_containers/kube-apiserver            v1.16.0             b305571ca60a        2 months ago         217MB
registry.aliyuncs.com/google_containers/kube-controller-manager   v1.16.0             06a629a7e51c        2 months ago         163MB
registry.aliyuncs.com/google_containers/kube-proxy                v1.16.0             c21b0c7400f9        2 months ago         86.1MB
registry.aliyuncs.com/google_containers/kube-scheduler            v1.16.0             301ddc62b80b        2 months ago         87.3MB
registry.aliyuncs.com/google_containers/etcd                      3.3.15-0            b2756210eeab        2 months ago         247MB
registry.aliyuncs.com/google_containers/coredns                   1.6.2               bf261d157914        3 months ago         44.1MB
quay.io/coreos/flannel                                            v0.11.0-amd64       ff281650a721        10 months ago        52.6MB
harbor-ali.ejoyst.com/k8s_img/nginx-ingress-controller            0.16.2              c5ac2be3012c        17 months ago        362MB
harbor-ali.ejoyst.com/k8s_img/defaultbackend                      1.4                 846921f0fe0e        2 years ago          4.84MB

2.准备yaml文件

解压nginx-ingress.tar.gz

[root@master-01 nginx-ingress]# cd yaml/
[root@master-01 yaml]# ls
nginx-ingress.tar.gz
[root@master-01 yaml]# tar xfz nginx-ingress.tar.gz 
[root@master-01 yaml]# ls
ingress  nginx-ingress.tar.gz
[root@master-01 yaml]# ls ingress/
01-configmap.yaml           03-default-backend.yaml       05-nginx-ingress-service.yaml.bak  myapp-pod-ingress.yaml
02-nginx-ingress-rbac.yaml  04-nginx-ingress-deploy.yaml  myapp-ingress.yaml

因为我是从自己搭建的harbor去拉取镜像的,如果是拉取本地镜像,需要根据需求修改一下几个地方
1.修改03-default-backend.yaml
注释一些行

 ...
 
 20  #     imagePullSecrets:
 21  #     - name: regsecret
 27         image: harbor-ali.abc.com/k8s_img/defaultbackend:1.4 改为k8s.gcr.io/k8s_img/defaultbackend:1

 44 #      nodeSelector: 
 45 #        node-label: "prod"
 ...

2.修改04-nginx-ingress-deploy.yaml 注释一下行

 ...
 25 #      imagePullSecrets:
 26 #      - name: regsecret
 29           image: harbor-ali.abc.com/k8s_img/nginx-ingress-controller:0.16.2 改为 image: k8s.gcr.io/nginx-ingress-controller:0.16.2 
 79 #      nodeSelector:
 80 #        node-label: "prod"
 ....

3.依次创建ingress的yaml

[root@master-01 ingress]# kubectl apply -f 01-configmap.yaml 
configmap/nginx-ingress-configuration created
configmap/nginx-ingress-tcp-services created
configmap/nginx-ingress-udp-services created

[root@master-01 ingress]# kubectl apply -f 02-nginx-ingress-rbac.yaml 
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

[root@master-01 ingress]# kubectl apply -f 03-default-backend.yaml 
deployment.apps/default-http-backend created
service/default-http-backend created

[root@master-01 ingress]# kubectl apply -f 04-nginx-ingress-deploy.yaml 
deployment.apps/nginx-ingress-controller created
service/nginx-ingress-service created

4.检查相关服务是否正常

[root@master-01 ingress]# kubectl get deploy -n kube-system
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
coredns                    2/2     2            2           14d
default-http-backend       1/1     1            1           2m27s
nginx-ingress-controller   1/1     1            1           2m21s

[root@master-01 ingress]# kubectl get svc -n kube-system
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
default-http-backend    ClusterIP   10.104.194.108           80/TCP                   3m25s
kube-dns                ClusterIP   10.96.0.10               53/UDP,53/TCP,9153/TCP   14d
nginx-ingress-service   NodePort    10.97.84.182             80:30080/TCP             3m20s  (30080为对外服务的端口)

浏览器访问ingress服务端口看是否正常,出现了一下404画面说明工作组件是正常的

image.png

部署已经完成了

四.Ingress应用实例

1.创建一个后端的应用实例myapp


[root@master-01 ingress]# ls
01-configmap.yaml           03-default-backend.yaml       05-nginx-ingress-service.yaml.bak  myapp-pod-ingress.yaml
02-nginx-ingress-rbac.yaml  04-nginx-ingress-deploy.yaml  myapp-ingress.yaml
[root@master-01 ingress]# 


[root@master-01 ingress]# cat myapp-pod-ingress.yaml 
apiVersion: v1
kind: Service
metadata:
  name: myapp-ingress
spec:
  selector:
    app: myapp
    release: canary
  ports:
  - name: http
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-ingress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      imagePullSecrets:     #本地拉镜像要注释
      - name: regsecret       #本地拉镜像要注释
      hostAliases:
        - ip: "10.1.1.5"
          hostnames:
          - "harbor-ali.abc.com"
      containers:
      - name: myapp
        image: "harbor-ali.abc.com/k8s_img/myapp:v1"     # 本地拉取镜像可改为(ikubernertes/myapp:v1)
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: 80
      nodeSelector:         # 本地拉取镜像可注释
        node-label: "test"   # 本地拉取镜像可注释
        
        

检查服务是否正常

[root@master-01 ingress]# kubectl apply -f myapp-pod-ingress.yaml
service/myapp-ingress created
deployment.apps/myapp-ingress created
[root@master-01 ingress]# kubectl get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1               443/TCP   14d
myapp           ClusterIP   None                    80/TCP    27h
myapp-ingress   ClusterIP   10.97.204.179           80/TCP    13s



[root@master-01 ingress]# kubectl get pod
NAME                                   READY   STATUS             RESTARTS   AGE

myapp-ingress-6c94846d6f-9vmfm         1/1     Running            0          34s

2.将myapp-ingress服务添加到ingress中

[root@master-01 ingress]# cat myapp-ingress.yaml 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-myapp
spec:
  rules:
  - host: myapp.ingress.com         #自定义域名,访问时记得配hosts解析
    http:
      paths:
      - path:
        backend:
          serviceName: myapp-ingress    #关联应用的service服务
          servicePort: 80               #服务暴露的端口

创建ingress

[root@master-01 ingress]# kubectl apply -f myapp-ingress.yaml 
ingress.extensions/ingress-myapp created
[root@master-01 ingress]# kubectl get ingress 
NAME            HOSTS               ADDRESS   PORTS   AGE
ingress-myapp   myapp.ingress.com             80      6s

  • 验证:
    在其他主机访问模拟外网访问ingress暴露的端口看是否可以访问到myapp服务,也可以在浏览器访问
[root@jenkins ~]# curl http://myapp.ingress.com:30080
Hello MyApp | Version: v1 | Pod Name

说明可以通过nginx-ingress暴露的30080端口代理访问到我们后端的pod应用

你可能感兴趣的:(k8s之nginx-ingress)