ingress
通常情况下,service 和 pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 service 在 Node 暴露的 NodePort 上,然后再由 kube-proxy 通过边缘路由器 (edge router) 将其转发给相关的 Pod 或者丢弃 : inter --> ingress --> services
Ingress公开了从群集外部到群集内 services 的HTTP和HTTPS路由,但Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开给 Internet 时,通常使用以下类型的服务 Service.Type=NodePort 或者 Service.Type=LoadBalancer.
- 访问流程 客户端 --> 负载均衡 --> k8s nodes --> services --> 调度器pod (https) --> pod
- 通过pod共享网络名称空间(Network), 此时就变成了 客户端 --> 负载 --> nodes(https) --> pod
Ingress Controller
为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器, Kubernetes 作为一个项目,目前支持和维护 GCE 和 nginx 控制器, 而微服务比较倾向于Envoy
一个独立运行的应用程序或一组pod资源,它通常就是一个应用程序,其拥有着七层代理能力和调度能力 , 目前来讲K8s上选择有三种(Nginx, Traefik ,Envoy)
使用多个 Ingress 控制器
创建 ingress 时,应该使用适当的 ingress.class
注解每个 ingress 以表明在集群中如果有多个 ingress 控制器时,应该使用哪个 ingress 控制器,如果不定义 ingress.class
,云提供商可能使用默认的 ingress 控制器
Ingress资源
定义一个Ingress时,直接定义一个Ingress,如何建立一个前端 (虚拟主机\url映射)、或一个后端(upstream), Ingress通过services得到upstream有几个主机, Ingress做为一个资源可以通过边界注入到Ingress controller中并保存为配置文件,一旦Ingress发现service选定的后端资源的pod发生改变, 这个改变一定会即时反映到Ingress中,ingress会即时注入到前端调度器的pod中(upstream),还能触发pod主容器中的进程重载配置文件;
service 对后端某一个特定资源分类, ingress基于这个分类识别出有多少个pod,ip地址是什么,并且把地址反映的结果生成配置文件,动态注入到配置文件中,最终在触发pod主容器重载配置文件, 如Envoy当监听到配置文件发生改变时会自动重载,而nginx就会显得有些不足;
参数说明
# 一旦pod资源发生变化, service就会跟着变化, 之后ingress就会变化而后就会注入到配置文件中..
spec.backend: # 关连的后端pod, 定义后端有哪几个主机
serviceName: # 指明哪个service的名称
servicePort: # 指明后端service相关连的端口
spec.rules: # 定义规则
host # 主机调度, 1、使用虚拟主机进行代理,通过外网访问主机
http # 服务调度
paths: # 调度的路径
backend: # 后端
serviceName: # service名称
servicePort # service端口
path: # 前端 1、定义虚拟路径 默认"/"
spec.tls: # 只有打算把ingress虚拟主机通过Urls配置成https的时候使用
名称空间
# 创建名称空间 kubectl create namespace name
# 删除 kubectl delete ns/name # 如果删除名称空间, 属于该名称空间的资源都会被删除
# 查看 kubectl get ns
ingress-nginx
方式一: client --> service(nodeport) --> ingress --> (service仅提供分类) --> pods
-
前端访问
xx.xiong.com:30080
-
最前端service定义NodePort服务, 名称空间(ingress-nginx)选择器
selector选择ingress-nginx的lables
-
定义后端pod以及 分类无头service服务 类型为
clusterIP
, 该service仅用于给ingress提供分类 -
定义ingress资源 名称空间ingress-nginx, 使用
kubectl get ns
查看, 定义hosts以及backend -
使用到的命令
# 查看 ingress-nginx pod kubectl get pods -n ingress-nginx
# 查看详细信息 kubectl describe pods -n ingress-nginx
# 创建ymal kubectl apply -f xx.yaml
# 查看svc kubectl get svc 或 -n ingres-nginx
# 查看详细 kubectl describe svc -n ingress-nginx svcname
- 名称空间: ingress-nginx地址, 官方ingress文档
安装
-
方式一 0.23之前
yaml 说明 configmap.yaml 提供configmap可以在线更行nginx的配置 default-backend.yaml 提供一个缺省的后台错误页面 404 namespace.yaml 创建一个独立的命名空间 ingress-nginx rbac.yaml 创建对应的role rolebinding 用于rbac tcp-services-configmap.yaml 修改L4负载均衡配置的configmap udp-services-configmap.yaml 修改L4负载均衡配置的configmap with-rbac.yaml 将deployment修改为 daemonSet 使其ingress-nginx运行于宿主机的网络名称中, 需要确保宿主机80与443端口没有被使用 service-nodeport 指定nginx的80端口和443端口 # for file in configmap.yaml default-backend.yaml namespace.yaml rbac.yaml tcp-services-configmap.yaml udp-services-configmap.yaml with-rbac.yaml service-nodeport.yaml;do # wget https://raw.githubusercontent.com/fungitive/kubernetes/master/ingress-nginx/$file # done
-
0.25 版本
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml
# 对外提供服务
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.2/deploy/static/mandatory.yaml
# 先wget, 然后将image修改为阿里的 image: quay-mirror.qiniu.com/kubernetes-ingress-controller/nginx-ingress-controller:0.26.2
# 或者
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
- name: https
port: 443
targetPort: 443
nodePort: 30443
selector: # 选择器用 pods --show-labels查看
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
生成名称空间
]# kubectl apply -f namespace.yaml
]# kubectl apply -f .
# 上面两步不执行,这里使用 0.25版本,直接apply -f
# 当执行完之后就会下载一个ingress-nginx
]# kubectl get pods -n ingress-nginx --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-ingress-controller-788649c74c-nj6qv 1/1 Running 0 37m app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx,pod-template-hash=788649c74c
Pulling image "quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0"
查看名称空间
注: Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或者 Service.Type=LoadBalancer 类型的服务。
- 名称空间 ingress-nginx
]# kubectl describe ns ingress-nginx
Name: ingress-nginx # ingress-nginx labels
Labels: app.kubernetes.io/instance=ingress-nginx
app.kubernetes.io/name=ingress-nginx
Annotations: Status: Active
-
查看名称空间–pod
]# kubectl describe -n ingress-nginx pod ingress-nginx-controller-6f969cf6cd-v6f65 Name: nginx-ingress-controller-788649c74c-nj6qv Namespace: ingress-nginx Priority: 0 Node: slave2/192.168.2.222 Start Time: Thu, 23 Apr 2020 16:14:33 +0800 Labels: app.kubernetes.io/name=ingress-nginx app.kubernetes.io/part-of=ingress-nginx IP: 10.244.2.88 # 版本号 Pulling image "quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.xxx.xx"
API版本对应
Kubernetes 版本 | Extension 版本 |
---|---|
v1.5-v1.17 | extensions/v1beta1 |
v1.8+ | networking.k8s.io/v1beta1 |
单url-demo
流程说明: 前端svc(nodeport) --> ingress-nginx --> ingress --> svc --> endporint --> pod
创建前端svc(nodeport)
]# cat client-ingress-one.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-svc
namespace: ingress-nginx
spec:
type: NodePort # 格式需要是 NodePort, Ingress不直接提供对外服务
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
- name: https
port: 443
targetPort: 443
nodePort: 31443
clusterIP: ""
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
# 流程: svc --> endpoint --> pod(ingress-nginx)[podIP:podPort]
]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-svc NodePort 10.102.221.75 <none> 80:30080/TCP 26m
]# kubectl describe svc -n ingress-nginx ingress-svc
Name: ingress-svc
Namespace: ingress-nginx
Labels: <none>
Annotations: Selector: app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx
Type: NodePort
IP: 10.102.221.75
Port: http 80/TCP
TargetPort: 80/TCP
NodePort: http 30080/TCP
Endpoints: 10.244.2.120:80
External Traffic Policy: Cluster
]# kubectl get endpoints -n ingress-nginx ingress-svc
NAME ENDPOINTS AGE
ingress-svc 10.244.2.120:80 27m
创建后端svc(CluetrIP)
单域名,前提准备, 生成几个后端被代理的应用 service --> pod, service仅用于给ingress提供分类
]# cat my-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: default
labels:
name: my-service
spec:
selector:
name: my-deploy
type: ClusterIP # ClusterIP|LoadBalancer
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-ingress-pod
spec:
replicas: 3
selector:
matchLabels:
name: my-deploy
template:
metadata:
labels:
name: my-deploy
spec:
containers:
- name: my-deploy
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
# 流程: svc --> endpoint --> pod(ingress-nginx)[podIP:podPort]
]# kubectl get endpoints # 后端的endpoints资源
NAME ENDPOINTS AGE
my-service 10.244.1.124:80,10.244.1.127:80,10.244.2.121:80 174m
创建ingress资源
]# cat first-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: first-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
#ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: test.xiong.com
http: # http协议 定义外边访问的http路径
paths: # 使用路径定义
- path: / # 映射的后端url, 不定义就是/
backend: # 映射的后端由 test service生成, 代理的端口为80
serviceName: my-service
servicePort: 80
]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
first-ingress <none> test.xiong.com 80 179m
]# kubectl describe ingress
Name: first-ingress
Namespace: default
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
test.xiong.com / my-service:80 (10.244.1.124:80,10.244.1.127:80,10.244.2.121:80)
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /
ingress-nginx(pod内)状态
]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-67754f4878-gpf4b 1/1 Running 0 18m
]# kubectl exec -it -n ingress-nginx nginx-ingress-controller-67754f4878-gpf4b -- /bin/bash
server {
server_name test.xiong.com ;
listen 80 ;
listen 443 ssl http2 ;
set $proxy_upstream_name "-";
location / {
set $namespace "default";
set $ingress_name "first-ingress";
set $service_name "my-service";
set $service_port "80";
set $location_path "/";
}
}
访问
修改/etc/hosts文件
将node节点添加域名, 或直接在dns中解析
本地机器访问: dns中解析或 hosts中文件中临时配置
]# cat /etc/hosts
192.168.2.221 test.xiong.com
192.168.2.222 test.xiong.com
]# for ((i=0;i<=5;i++));do curl http://test.xiong.com:30080/hostname.html;done
my-ingress-pod-6df97496d9-t5d5d
my-ingress-pod-6df97496d9-jh4nb
my-ingress-pod-6df97496d9-7vnn8
多域名-demo
u1.xiong.com -- | |-> u1.xiong.com u1-xiong-com:80
| 域名:30080 |
u1.xiong.com -- | |-> u2.xiong.com u2-xiong-com:80
# 结构为 NodePort(svc)[ingress-nginx-controller] --> ingress --> ClusterIp(svc)(deployment)
# 访问是 ingress的hosts主机名或 /路径 如 u1.xiong.com:NodePort
ingress资源
]# cat ingress-one.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: u.xiong.com
namespace: default
annotations:
nginx.ingress.kubernetes.io: two-nginx
spec:
rules:
- host: u1.xiong.com
http:
paths:
- backend:
serviceName: u1-xiong-com
servicePort: 80
path: /
- host: u2.xiong.com
http:
paths:
- backend:
serviceName: u2-xiong-com
servicePort: 80
path: /
后端pod及services
apiVersion: v1
kind: Service
metadata:
name: u1-xiong-com
namespace: default
spec:
type: ClusterIP
selector:
app: u1.xiong.com
release: qa
ports:
- port: 80
protocol: TCP
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: u1-xiong-com
namespace: default
labels:
app: u1.xiong.com
release: qa
spec:
replicas: 2
selector:
matchLabels:
app: u1.xiong.com
release: qa
template:
metadata:
name: u1-xiong-com
namespace: default
labels:
app: u1.xiong.com
release: qa
spec:
containers:
- name: u1-xiong-com
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 3
httpGet:
port: http
path: /index.html
状态查看
]# kubectl describe ingress u.xiong.com
Name: u.xiong.com
Namespace: default
Address: 10.105.25.214
Rules:
Host Path Backends
---- ---- --------
u1.xiong.com / u1-xiong-com:80 (10.244.1.92:80,10.244.2.99:80)
u2.xiong.com / u2-xiong-com:80 (10.244.1.93:80,10.244.2.100:80)
Annotations: nginx.ingress.kubernetes.io: two-nginx
https
-
生成证书
]# openssl genrsa -out nginx.key 4096
-
自签证书
]# openssl req -new -x509 -key nginx.key -out nginx.crt
-
secret资源 创建secret 指定crt, 指定key
]# kubectl create secret tls tls-ingress-nginx --cert=tls.crt --key=tls.key
secret/tls-ingress-nginx created
- 查看secret资源
]# kubectl get secret
NAME TYPE DATA AGE
tls-ingress-nginx kubernetes.io/tls 2 5s
]# kubectl describe secret tls-ingress-nginx
Name: tls-ingress-nginx
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.crt: 1980 bytes
tls.key: 3243 bytes
- 配置 tls
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-xiong-com
namespace: default # 名称空间放在default中
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- tls.xiong.com # 定义主机
secretName: tls-ingress-nginx # 这里为secret定义的名称
rules:
- host: t1.xiong.com # 定义地址
http:
paths:
- path: /
backend:
serviceName: u1-xiong-com
servicePort: 80
- host: t2.xiong.com # 定义地址
http:
paths:
- path: /
backend:
serviceName: u2-xiong-com
servicePort: 80
- 访问
# 在主机上加上hosts, 通过浏览器访问: https://nginx.xiong.com:31443
iong.com # 定义主机
secretName: tls-ingress-nginx # 这里为secret定义的名称
rules:
- host: t1.xiong.com # 定义地址
http:
paths:
- path: /
backend:
serviceName: u1-xiong-com
servicePort: 80
- host: t2.xiong.com # 定义地址
http:
paths:
- path: /
backend:
serviceName: u2-xiong-com
servicePort: 80
6. 访问
```bash
# 在主机上加上hosts, 通过浏览器访问: https://nginx.xiong.com:31443