为什么要有ingress, 或者他解决了什么问题
Kubernetes提供了三种类型的Services:
ClusterIP: 为Service分配虚拟地址,但是该地址只能在Kubernetes集群内部中访问,这也是Services的默认类型
NodePort: 在ClusterIP基础上将服务绑定到集群节点的指定端口上,可以通过:NodePort访问Service。
LoadBalancer:在NodePort的基础上使用外部的负载均衡服务,通过该负载均衡服务来访问集群内部的Services,实际上经过了两层转发。
Ingress就是一系列的转发规则集合,通过它可以将集群内部的Service暴露给公网。它也是可操作的REST对象,可以通过API方便的创建一个Ingress对象:
Prepare Ingress Controller
Backend deployment and service
- Prepare deployment.yaml file
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: default-http-backend
labels:
k8s-app: default-http-backend
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissable as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
image: gcr.io/google_containers/defaultbackend:1.0
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
- Prepare service yaml file
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
namespace: default
labels:
k8s-app: default-http-backend
spec:
ports:
- port: 80
targetPort: 8080
selector:
k8s-app: default-http-backend
- Create the default backend deployment and service by executing these commands:
$ kubectl create -f nginx-default-backend-deployment.yaml
$ kubectl create -f nginx-default-backend-service.yaml
Creating the Ingress Controller Nginx Deployment and Service
1.Create deployment yaml file
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
labels:
k8s-app: nginx-ingress-controller
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: nginx-ingress-controller
spec:
# hostNetwork makes it possible to use ipv6 and to preserve the source
# IP correctly regardless of docker configuration.
# However, it is not a hard dependency of the nginx-ingress-controller
# itself, and it may cause issues if port 10254 already is taken on
# the host.
# Since hostPort is currently broken on CNI
# (https://github.com/kubernetes/kubernetes/issues/31307), we have to
# use hostNetwork where CNI is used, like with kubeadm.
# hostNetwork: true
terminationGracePeriodSeconds: 60
containers:
- image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.10
name: nginx-ingress-controller
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 1
ports:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --update-status=false
- Create service yaml file
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress-controller
namespace: default
labels:
k8s-app: nginx-ingress-controller
spec:
type: LoadBalancer
ports:
- port: 80
nodePort: 30021
name: http
- port: 443
nodePort: 30022
name: https
selector:
k8s-app: nginx-ingress-controller
- Create the nginx ingress controller deployment and service by executing these commands:
$ kubectl create -f nginx-ingress-controller-deployment.yaml
$ kubectl create -f nginx-ingress-controller-service.yaml
Deploy demo service
- Creating the docker-hello-world Service Definition
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: docker-hello-world
labels:
app: docker-hello-world
spec:
replicas: 3
template:
metadata:
labels:
app: docker-hello-world
spec:
containers:
- name: docker-hello-world
image: scottsbaldwin/docker-hello-world:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: docker-hello-world-svc
spec:
selector:
app: docker-hello-world
ports:
- port: 8088
targetPort: 80
type: ClusterIP
- Create this new deployment and service:
kubectl create -f hello-world-ingress.yaml
- Create the file ingress.yaml and populate it with this code:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-world-ing
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: hello.docker.svc
http:
paths:
- backend:
serviceName: docker-hello-world-svc
servicePort: 8088
- Create the ingress resource:
kubectl create -f ingress.yaml
- Test the service ingress:
[test@demotest demo1]$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
hello-world-ing hello.docker.svc 80 6h
example-service-ing hello.k8s.svc 80 1h
[test@demotest demo2]$ curl -H "Host:hello.docker.svc" http://129.146.156.124/
<h1>Hello webhook world from: docker-hello-world-5866dbffbc-f4frr</h1>
Q&A
- Q: Did not see reference from the demo service’ section, how do they find out the ingress controller you created and also what if there are multiple ingress controllers?
A: User can specify “–ingress-class” to define ingress class names to route through this controller when creating ingress controller. Please see https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/cli-arguments.md:
–ingress-class: Name of the ingress class this controller satisfies. The class of an Ingress object is set using the annotation “kubernetes.io/ingress.class”. All ingress classes are satisfied if this parameter is left empty.
And in this example, we didn’t specify this parameter for ingress controller, so all the igress classes can be routed through this controller.
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --update-status=false
For multiple ingress controllers, you can refer to https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/multiple-ingress-controllers
To designate that a particular Ingress resource must be handled only by the NGINX or NGINX Plus controller, add the following annotation along with the value to the Ingress resource:
kubernetes.io/ingress.class: “nginx”
In this case other Ingress controllers will ignore that Ingress.
To summarize, the NGINX or NGINX Plus controller will handle an Ingress resource, if one of the following is true:
The annotation is not present in the resource
The annotation is present and its value is either the nginx or the empty string
Any other value of the annotation, for example, gce, makes the NGINX or NGINX Plus controller ignore the Ingress resource.
And the key point per my understanding is that
1). define “–ingress-class” in ingress controller resource.
2). define “kubernetes.io/ingress.class:” annotation in ingress resource.
附录: Nginx 介绍
Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现。
-
正向代理:
正向代理最大的特点是客户端非常明确要访问的服务器地址。
正向代理的用途:
(1)访问原来无法访问的资源,如Google
(2) 可以做缓存,加速访问资源
(3)对客户端访问授权,上网进行认证
(4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息 -
反向代理:
反向代理,“它代理的是服务端”,主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息。
反向代理的作用:
(1)保证内网的安全,通常将反向代理作为公网访问地址,Web服务器是内网
(2)负载均衡,通过反向代理服务器来优化网站的负载。
Nginx 配置文件
nginx.conf文件结构
... #全局块
events{} #events块
http{ #http块
... #http全局块
server{ #server块
... #server全局块
location [/]{ #location块
...
}
}
}
全局块:nginx服务器的配置信息
events块:主要影响nginx服务器与用户的网络连接,
http块:代理缓存和日志定义绝大多数功能和第三方模块的配置可以放这
server块:每个server相当于一台虚拟主机,它内部可以有多台主机联合提供服务,一起对外提供在逻辑上关系密切的一组服务
location:基于nginx服务器接收到的请求字符串,对除虚拟主机名之外的字符串进行匹配,对特定的请求进行处理
举例:
状态监控模块: