一、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 一下,工作流程如下图:
实际上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 <none> 80/TCP 3m25s
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 14d
nginx-ingress-service NodePort 10.97.84.182 <none> 80:30080/TCP 3m20s (30080为对外服务的端口)
浏览器访问ingress服务端口看是否正常,出现了一下404画面说明工作组件是正常的
部署已经完成了
四.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 <none> 443/TCP 14d
myapp ClusterIP None <none> 80/TCP 27h
myapp-ingress ClusterIP 10.97.204.179 <none> 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 | <a href="hostname.html">Pod Name</a>
说明可以通过nginx-ingress暴露的30080端口代理访问到我们后端的pod应用