使用 ingress-nginx 暴露服务
ingress-nginx:
kubernetes暴露服务的方式:ClusterIP、NodePort、LoadBalancer、ingress
我对于这几种模式,简单的理解如下,
ClusterIP,集群内的应用都可以访问,集群外部无法访问。
NodePort,相信初学者接触的第一个对外暴露服务的方式就是NodePort方式,是kubernetes引导外部流量到pod最原始的方式,
Nodeport即在每个node上开放一个特定端口,对应到某个pod的端口,集群外部通过 nodeIP:NodePort的方式进行访问,
它的缺点也比较明显:
每个端口对应一种服务,
每个node上都需要开放NodePort端口,
默认端口范围30000-32767,可以修改,
如果某个node的ip地址发生变化,可能需要人工干预
LoadBalancer,是暴露服务到internet的标准方式,每个服务对应一个单独的IP地址,转发所有流量到对应的服务,可以转发任意类型的流量,
这种方式,最大的缺点就是每个暴露的服务都需要有自己的IP地址
Ingress
ingress事实上不是一种服务类型。它处于多个服务的前端,扮演着“智能路由”或者集群入口的角色。
ingress可能是暴露服务最强大,也是最复杂的方式,它的控制器有各种类型,包括 Google Cloud Load Balancer, Nginx,Contour,Istio,等等。它还有各种插件,比如 cert-manager(https://github.com/jetstack/cert-manager),它可以为你的服务自动提供 SSL 证书。
如果想用一个ip暴露多个服务,这些服务都使用相同的7层协议,比如http,那ingres将是最有用的。
接下来,我们对ingress-nginx进行测试,
一、部署
下载官方yaml文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.20.0/deploy/mandatory.yaml
更新yaml里面两处镜像地址,此处使用的是阿里的镜像仓库
image: registry.cn-hangzhou.aliyuncs.com/google_containers/defaultbackend:1.4 image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.23.0
部署nginx-ingress-controller
[k8s@k8s-m1 ingress]$ kubectl apply -f mandatory.yaml namespace/ingress-nginx created deployment.extensions/default-http-backend created service/default-http-backend 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.extensions/nginx-ingress-controller created
查看部署后的状态
#deployment状态 [k8s@k8s-m1 ingress]$ kubectl get deployment -n ingress-nginx NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE default-http-backend 1 1 1 1 7m nginx-ingress-controller 1 1 1 1 7m #pod状态 [k8s@k8s-m1 ingress]$ kubectl get pods -n ingress-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE default-http-backend-598df75c7d-ngfvs 1/1 Running 0 3m 172.60.75.2 k8s-m1 <none> nginx-ingress-controller-67954599b4-hbkfg 1/1 Running 0 3m 172.60.19.3 vm10-10-8-10ksccom <none> #svc状态 [k8s@k8s-m1 ingress]$ kubectl get svc -n ingress-nginx -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR default-http-backend ClusterIP 10.240.44.251 <none> 80/TCP 4m app.kubernetes.io/name=default-http-backend,app.kubernetes.io/part-of=ingress-nginx
default-http-backend是安装的一个默认后端,ClusterIP类型,可以在集群任意node访问,用于返回404结果
二、测试
[root@k8s-m2 ~]# curl http://10.240.44.251
default backend - 404
[root@k8s-m2 ~]# curl http://10.240.44.251/healthz
ok[root@k8s-m2 ~]#
到这里,说明ingress-nginx已经部署成功了。
以上是通过default-http-backend进行访问,并没有对集群外部暴露服务,
接下来继续,看看对外暴露服务的方式
三、通过nodeport的方式将服务暴露出去
下载nodePort模板
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
default backend - 404[k8s@k8s-m1 ingress]$ cat service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
- name: https
port: 443
targetPort: 443
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
#生效
[k8s@k8s-m1 ingress]$ kubectl create -f service-nodeport.yaml
查看svc状态
[k8s@k8s-m1 ingress]$ kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default-http-backend ClusterIP 10.240.13.114 <none> 80/TCP 44m ingress-nginx NodePort 10.240.82.29 <none> 80:8807/TCP,443:8956/TCP 40m nginx-1108 ClusterIP 10.240.31.31 <none> 80/TCP,1935/TCP 42m
创建一个应用
[k8s@k8s-m1 ingress]$ cat nginx-1.10.2.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-1108
labels:
app: nginx-1108
namespace: ingress-nginx
spec:
selector:
app: nginx-1108
ports:
- name: http80
port: 80
targetPort: 80
- name: rtmp1935
port: 1935
targetPort: 1935
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-1108
labels:
addonmanager.kubernetes.io/mode: Reconcile
namespace: ingress-nginx
spec:
template:
metadata:
labels:
app: nginx-1108
spec:
containers:
- name: my-nginx-1108
image: rtmp-nginx:1.10.8
imagePullPolicy: Never
command: ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
ports:
- containerPort: 80
创建ingress规则
# 域名方式访问,本次使用域名方式测试
nginx-ingress]# cat ingress-host-nginx-1.10.2.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: pand-ingress
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: www.test1.com
http:
paths:
- backend:
serviceName: nginx-1108
servicePort: 80
# url路径方式访问
nginx-ingress]# cat ingress-path-nginx-1.10.2.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /test1
backend:
serviceName: nginx-1108
servicePort: 80
使用ingress域名规则进行测试
[root@k8s-m2 ~]# curl http://10.240.82.29/
default backend - 404[
[root@k8s-m2 ~]# curl -H "Host: foo.bar.com" http://10.240.82.29/
successfully
[root@k8s-m2 ~]# curl -H "Host: foo.bar.com" http://nodePort+port/
successfully
四、通过hostNetwork的方式,对外暴露服务
修改mandatory.yaml,对nginx-ingress-controller添加hostNetwork: true,
hostNetwork是直接定义pod的网络方式,定义后,物理机ip就是nginx-ingress的ip,通过物理机ip直接访问nginx-ingress端口,将请求转发给后端pod
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
hostNetwork: true
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
zone: test_node
containers:
- name: nginx-ingress-controller
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.23.0
kubectl apply -f mandatory.yaml
查看pod所在物理机监听的端口,多了一个80端口,即nginx-ingress端口
tcp 0 0 10.10.8.11:2380 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8800 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8801 0.0.0.0:* LISTEN
测试
#通过物理机ip测试
[k8s@k8s-m1 ~]$ curl http://10.69.58.68/
default backend - 404