2. Kubernetes Ingress Controller的介绍
2.1 Kubernetes Ingress Controller部署
项目地址:https://github.com/kubernetes/ingress-nginx
安装文档地址: https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/docs/deploy/index.md
1)下载并修改配置文件
[root@master1 ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
#修改
210 prometheus.io/port: "10254"
211 prometheus.io/scrape: "true"
212 spec:
213 hostNetwork: true # 需要添加这句,使用主机网络
214 serviceAccountName: nginx-ingress-serviceaccount
2)应用配置文件
[root@master1 ~]# kubectl apply -f mandatory.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
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
limitrange/ingress-nginx created
注意镜像较大,可提前下载至集群node节点中。
3)验证部署结果,
[root@master1 ~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-77db54fc46-kwwkt 1/1 Running 0 89s
2.2 ingress-http案例
2.2.1 创建deployment
[root@master1 ~]# vim nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: ingress-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
应用YAML:
[root@master1 ~]# kubectl apply -f nginx.yml
deployment.extensions/nginx created
验证pod:
[root@master1 ~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-79654d7b8-nhxpm 1/1 Running 0 12s
nginx-79654d7b8-tp8wg 1/1 Running 0 13s
nginx-ingress-controller-77db54fc46-kwwkt 1/1 Running 0 11m
2.2.2 创建service
[root@master1 ~]# vim nginx-service.yml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: ingress-nginx
labels:
app: nginx
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx
应用YAML:
[root@master1 ~]# kubectl apply -f nginx-service.yml
service/nginx-service created
验证service:
[root@master1 ~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.2.115.144 <none> 80/TCP 5s
2.2.3 创建ingress
[root@master1 ~]# vim ingress-nginx.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx #自定义ingress名称
namespace: ingress-nginx
spec:
rules:
- host: www.daniel.com # 自定义域名
http:
paths:
- backend:
serviceName: nginx-service # 对应上面创建的service名称
servicePort: 80
应用YAML:
[root@master1 ~]# kubectl apply -f ingress-nginx.yaml
ingress.extensions/ingress-nginx created
验证ingress:
[root@master1 ~]# kubectl get ingress -n ingress-nginx
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-nginx <none> www.daniel.com 80 1m32s
描述查看ingress信息:
[root@master1 ~]# kubectl describe ingress ingress-nginx -n ingress-nginx
......
Rules:
Host Path Backends
---- ---- --------
www.daniel.com
nginx-service:80 (10.3.104.34:80,10.3.166.146:80) # 与下面查询的两个pod的IP对应
[root@master1 ~]# kubectl get pods -o wide -n ingress-nginx
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-79654d7b8-nhxpm 1/1 Running 0 18m 10.3.166.146 192.168.122.13 <none> <none>
nginx-79654d7b8-tp8wg 1/1 Running 0 18m 10.3.104.34 192.168.122.14 <none> <none>
nginx-ingress-controller-77db54fc46-kwwkt 1/1 Running 2 22h 192.168.122.13 192.168.122.13 <none> <none>
# 可以看到两个pod的IP正好对应ingress域名对应的IP
......
确认nginx-ingress-controller的podIP为192.168.122.13。
2.2.4 模拟客户端访问
1)确认nginx-ingress-controller的podIP,下面命令查询的结果为192.168.122.13
[root@master1 ~]# kubectl get pods -o wide -n ingress-nginx |grep ingress
nginx-ingress-controller-77db54fc46-kwwkt 1/1 Running 2 22h 192.168.122.13 192.168.122.13 <none> <none>
2)在集群之外任一主机中(我这里为hostos)添加上述域名与IP地址解析(模拟公网DNS)
[root@hostos ~]# vim /etc/hosts
192.168.122.13 www.daniel.com
3)准备pod内容器运行的web主页
[root@master1 ~]# kubectl get pods -n ingress-nginx
nginx-79654d7b8-nhxpm 1/1 Running 0 25m
nginx-79654d7b8-tp8wg 1/1 Running 0 25m
nginx-ingress-controller-77db54fc46-kwwkt 1/1 Running 2 38h
[root@master1 ~]# kubectl exec -it nginx-79654d7b8-nhxpm -n ingress-nginx -- /bin/sh
/ # echo "ingress web1" > /usr/share/nginx/html/index.html
/ # exit
[root@master1 ~]# kubectl exec -it nginx-79654d7b8-tp8wg -n ingress-nginx -- /bin/sh
/ # echo "ingress web2" > /usr/share/nginx/html/index.html
/ # exit
4)访问及结果展示
[root@hostos ~]# curl www.daniel.com
ingress web1
[root@hostos ~]# curl www.daniel.com
ingress web2
2.3 ingress-https案例
2.3.1 创建自签证书
[root@master1 ~]# mkdir ingress-https
[root@master1 ~]# cd ingress-https/
[root@master1 ingress-https]# openssl genrsa -out nginx.key 2048
[root@master1 ingress-https]# openssl req -new -x509 -key nginx.key -out nginx.pem -days 365
......
......
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:GD
Locality Name (eg, city) [Default City]:SZ
Organization Name (eg, company) [Default Company Ltd]:IT
Organizational Unit Name (eg, section) []:it
Common Name (eg, your name or your server's hostname) []:daniel
Email Address []:daniel@xxx.com
[root@master1 ingress-https]# ls
nginx.key nginx.pem
2.3.2 将证书创建成secret
[root@master1 ingress-https]# kubectl create secret tls nginx-tls-secret --cert=nginx.pem --key=nginx.key -n ingress-nginx
secret/nginx-tls-secret created
[root@master1 ingress-https]# kubectl get secrets -n ingress-nginx |grep nginx-tls-secret
nginx-tls-secret kubernetes.io/tls 2 38s
2.3.3 编排YAML创建资源
编辑:
[root@master1 ingress-https]# vim ingress-https.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx2
namespace: ingress-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- name: c1
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service2
namespace: ingress-nginx
labels:
app: nginx2
spec:
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
selector:
app: nginx2
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx2
namespace: ingress-nginx
spec:
tls:
- hosts:
- www.daniel2.com # 域名
secretName: nginx-tls-secret # 调用前面创建的secret
rules:
- host: www.daniel2.com # 域名
http:
paths:
- backend:
serviceName: nginx-service2 # 对应服务名
servicePort: 80
创建:
[root@master1 ingress-https]# kubectl apply -f ingress-https.yml
deployment.apps/nginx2 created
service/nginx-service2 created
ingress.extensions/ingress-nginx2 created
2.2.4 模拟客户端访问
[root@hostos ~]# vim /etc/hosts
192.168.122.13 www.daniel2.com 添加这行模拟DNS
[root@hostos ~]# firefox https://www.daniel2.com &
[1] 10892
2.4 ingress+nodeport服务
编辑YAML并创建:
[root@master1 ~]# vim ingress-nodeport.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx3
namespace: ingress-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx3
template:
metadata:
labels:
app: nginx3
spec:
containers:
- name: c1
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service3
namespace: ingress-nginx
labels:
app: nginx3
spec:
type: NodePort # NodePort类型服务
ports:
- port: 80
targetPort: 80
selector:
app: nginx3
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx3
namespace: ingress-nginx
spec:
rules:
- host: www.daniel3.com
http:
paths:
- backend:
serviceName: nginx-service3
servicePort: 80
创建:
[root@master1 ~]# kubectl apply -f ingress-nodeport.yml
service/nginx-service3 created
ingress.extensions/ingress-nginx3 created
ingress.extensions/ingress-nginx3 configured
查看:
[root@master1 ~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.2.115.144 <none> 80/TCP 22h
nginx-service2 ClusterIP 10.2.237.70 <none> 80/TCP,443/TCP 22h
nginx-service3 NodePort 10.2.75.250 <none> 80:26765/TCP 3m51s
可以看到,nginx-service3是nodeport类型
访问:
[root@hostos ~]# vim /etc/hosts
192.168.122.13 www.daniel3.com 添加这行模拟DNS
[root@hostos ~]# curl www.daniel3.com
2.5 假如使用多个 Ingress 控制器
你可以在集群中部署任意数量的 ingress 控制器(ingress 控制器是基于k8s集群全局的)。 创建 ingress 时,应该通过annotation字段,使用适当的 ingress.class 注解每个 Ingress 以表明在集群中如果有多个 Ingress 控制器时,应该使用哪个 Ingress 控制器。如果不定义 ingress.class,云提供商可能使用默认的 Ingress 控制器。
理想情况下,所有 Ingress 控制器都应满足此规范,但各种 Ingress 控制器的操作略有不同。所以,要确保你查看了 ingress 控制器的文档,以了解选择它的注意事项。
2.6 思考
原文链接:https://blog.youkuaiyun.com/qq_40208428/article/details/133947090
你有没有想过,当我们创建好一个ingress之后,这个路由规则它是怎么刷新到nginx服务中的?
ingress-nginx 实现原理
ingress-nginx主要有两部分组成 Ingress和Ingress-controller:
- Ingress: 是k8s的一种资源对象,用来描述一个路由请求的yaml文件,将Nginx的配置抽象成一个Ingress对象,每添加一个新的服务只需写一个新的Ingress的yaml文件即可
- Ingress-controller: 将新加入的Ingress转化成Nginx的配置文件并使之生效
Ingress-nginx简单的理解就是你原来需要改Nginx配置,然后配置各种域名对应哪个Service,现在变成每添加一个server就创建一个Ingress对象(yaml文件),不再需要去改Nginx,直接 部署yam就行了。Ingress Controller通过与Kubernetes API交互,动态感知集群中Ingress规则变化,然后读取他,按照他自己模板生成一段Nginx配置,再写到ingress-nginx-controller Pod里,最后reload 一下。
ingress具体的工作原理如下:
1)部署一个ingress资源对象,yaml文件写明了哪个域名对应k8s集群中的哪个service。
2)ingress contronler通过与k8s的api进行交互,动态的去感知k8s集群中ingress服务规则的变化,然后读取它,再根据ingress-controller中的nginx配置模板,生成一段对应的nginx配置。
3)把该配置动态的写到ingress-nginx-controller的pod里,该ingress-nginx-controller的pod里面运行着一个nginx服务,控制器会把生成的nginx配置写入到nginx的配置文件中,然后reload一下,使其配置生效,以此来达到域名分配置及动态更新的效果
4)浏览器请求先到ingress-nginx-controller 服务,然后按照定义的ingress规则,再将请求转发到k8s集群中对应的service。