k8s笔记18--快速入门ingress和ingress controller
- 1 介绍
- 2 部署 ingress-nginx controller
- 3 测试
- 4 注意事项
- 5 说明
1 介绍
Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。
为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。当controller运行后,每次新增一个 ingress 资源,都会在cotroller 的nginx 配置 nginx.conf 中新增记录,告诉nginx 将请求转发指定的服务中。
当前有很多中ingress controller, 很多云厂商也会定制 一些自己的控制器,本文基于最经典的 ingress-nginx controller 来做相关实验,具体包括部署controller、测试ingress 实例,以及解决常见注意事项。
2 部署 ingress-nginx controller
在 github.com/kubernetes/ingress-nginx/tree/main/deploy/static/provider/baremetal 中找到自己需要的版本,然后 kubectl apply 即可。
$ kubectl apply -f deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
部署成功后,会拉起一个controller的pod和对应的 svc,如下所示:
xghome:~/.kube$ kubectl -n ingress-nginx get deploy,svc
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 3h36m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller NodePort 10.108.105.39 <none> 80:30080/TCP,443:30443/TCP 3h36m
service/ingress-nginx-controller-admission ClusterIP 10.105.5.181 <none> 443/TCP 3h36m
此外还会创建一个 IngressClass, 后续新建ingress 的时候需要指定 ingressClassName
xghome:~/.kube$ kubectl get IngressClass
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none>
3 测试
- 准备一个基础镜像 py:hostname
Dockerfile
FROM python:3.8-slim
RUN pip3 install Flask==2.1.2
RUN mkdir -p /home
WORKDIR /home
USER
- app.py
from flask import Flask
app = Flask(__name__)
def get_hostname():
hostname = ''
with open('/etc/hostname', 'r') as f:
line = f.readline()
hostname = line.replace('\n', '')
return hostname
@app.route('/')
@app.route('/<service>')
def hello_world(service=None): # put application's code here
hostname = get_hostname()
if service is None:
return f'Hello {hostname}\n'
else:
return f'Hello {hostname}, from {service}\n'
if __name__ == '__main__':
app.run(port=80, host="0.0.0.0")
- 打包镜像
docker build -t py:hostname .
- 部署服务test01 和 test02
test01.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test01
name: test01
spec:
replicas: 1
selector:
matchLabels:
app: test01
template:
metadata:
labels:
app: test01
spec:
containers:
- image: py:hostname
name: test01
---
apiVersion: v1
kind: Service
metadata:
labels:
app: test01
name: test01
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app:
- test02.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test02
name: test02
spec:
replicas: 1
selector:
matchLabels:
app: test02
template:
metadata:
labels:
app: test02
spec:
containers:
- image: py:hostname
name: test02
---
apiVersion: v1
kind: Service
metadata:
labels:
app: test02
name: test02
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app:
- 部署 ingress
test-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test
spec:
ingressClassName: nginx
rules:
- host: "test.xg.com"
http:
paths:
- pathType: Prefix
path: "/test01"
backend:
service:
name: test01
port:
number: 80
- host: "test.xg.com"
http:
paths:
- pathType: Prefix
path: "/test02"
backend:
service:
name: test02
port:
number: 80
- 前端测试
如下图, test01 刚好进入到test01 的pod中,/test02 刚好进入到test02 的pod中,测试符合预期 - 注意:
这里配置 nginx-ingress-controller 的 80端口为30080, 因此此处需要加上30080, 若在ingress controller 的外层加一个lb, 那么直接访问lb的ip即可。
此时 test.xg.com 直接指向nginx controller的ip。若需要实现局域网|PC虚拟机之间的dns,可以参考ubuntu小技巧27–基于dnsmasq快速搭建局域网dns服务器
4 注意事项
- 笔者自己的服务器上没有专用的 lb, 因此直接将服务的域名指向 controller 的 ip; 实际项目中一般都会有专用 lb,lb 会对接到ingress controller 的多个节点,配置域名的时候直接指向 lb 的 ip 即可。
- 使用个创建的ingress controller时候需要指定 ingressClassName, 或者配置默认的 IngressClass --在 annotations 中新增 ingressclass.kubernetes.io/is-default-class: “true”。
5 说明
软件环境:
ubuntu server 18.04
k8s 1.23.6
ingress controller v1.2.0
参考文档:
Kubernetes 文档/概念/服务、负载均衡和联网/IngressKubernetes 文档/概念/服务、负载均衡和联网/Ingress控制器ngress-nginx/master/deploy/static/mandatory.yamlnginx-0.30.0/deploy/static/mandatory.yamlgithub ingresskubernetes 创建ingress不生效ubuntu小技巧27–基于dnsmasq快速搭建局域网dns服务器