在前面如何配置阿里云容器服务K8S Ingress Controller使用私网SLB一文中描述了如何调整阿里云容器服务Kubernetes集群中默认的Nginx Ingress Controller配置使用私网SLB实例,文中提到的两种模式基本可以满足大部分需求场景,但对于一些特殊场景,比如集群内有部分公网服务需要通过公网Ingress方式来对外暴露提供访问,但是又有部分内网服务仅仅只希望对同VPC内非Kubernetes集群内的服务提供访问,而又不允许能被公网访问到,对此我们完全可以通过部署两套独立的Nginx Ingress Controller服务,其前端绑定不同网络类型的SLB实例来满足这类需求场景。
下面我们以此场景来说明如何在阿里云容器服务Kubernetes集群中同时部署多套独立的Nginx Ingress Controller来对外提供不同的服务访问。
我们知道,当我们通过阿里云容器服务控制台成功申请一个Kubernetes集群后,默认集群内已经部署了一套带有公网SLB实例的Nginx Ingress Controller服务,通过如下命令可以查看到:
~ # 查询集群默认 Nginx Ingress Controller 服务相关资源
~ kubectl -n kube-system get svc nginx-ingress-lb default-http-backend
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-lb LoadBalancer 172.19.7.30 47.95.97.115 80:31429/TCP,443:32553/TCP 2d
default-http-backend ClusterIP 172.19.11.213 80/TCP 2d
~
~ kubectl -n kube-system get deploy nginx-ingress-controller default-http-backend
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-ingress-controller 2 2 2 2 2d
default-http-backend 1 1 1 1 2d
~
~ kubectl -n kube-system get configmap nginx-configuration tcp-services udp-services
NAME DATA AGE
nginx-configuration 4 2d
tcp-services 0 2d
udp-services 0 2d
从上可以看到集群默认部署的Nginx Ingress Controller服务及相关资源部署在kube-system
命名空间下,并且其默认会监听集群内所有命名空间下创建的且未明确配置注释kubernetes.io/ingress.class
的Ingress配置。
这里我们说明如何在现有的阿里云容器服务Kubernetes集群中再部署一套完全独立的Nginx Ingress Controller服务,其前端绑定一个新的SLB实例(可依据实际需求配置私网SLB实例或公网SLB实例)。
1、通过阿里云负载均衡控制台在对应Region申请一个期望规格和网络类型的SLB实例。
2、准备Nginx Ingress Controller服务的yaml文件:
wget https://acs-k8s-ingress.oss-cn-hangzhou.aliyuncs.com/ingress-controller-template.yml.j2
由于这里需要用到jinja2命令行,安装方式可参考官方文档。通过如下命令来生成我们需要新部署的Nginx Ingress Controller服务的yaml文件:
jinja2 -D Namespace='NAMESPACE' -D LoadbalancerID='SLB_ID' -D IngressClass='INGRESS_CLASS' ingress-controller-template.yml.j2 > ingress-controller.yml
参数说明:
NAMESPACE:期望部署到哪个命令空间下(确保该命名空间已存在且不能再使用kube-system)
SLB_ID:新申请的SLB实例ID
INGRESS_CLASS:Ingress标识(不能使用nginx这个字符串,已预留给集群默认IngressController服务)
3、待yaml生成后通过如下命令部署新的Nginx Ingress Controller服务:
# 部署新 Nginx Ingress Controller 服务
kubectl apply -f ingress-controller.yml
serviceaccount "admin" created
clusterrolebinding.rbac.authorization.k8s.io "admin" created
service "nginx-ingress-lb" created
configmap "nginx-configuration" created
configmap "tcp-services" created
configmap "udp-services" created
deployment.extensions "default-http-backend" created
service "default-http-backend" created
deployment.apps "nginx-ingress-controller" created
# 确认新 Nginx Ingress Controller 服务正常运行起来
kubectl -n get svc nginx-ingress-lb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-lb LoadBalancer 172.19.6.227 39.105.252.62 80:30969/TCP,443:31325/TCP 4m
kubectl -n get pod | grep nginx-ingress-controller
nginx-ingress-controller-78bc478f5b-blpgz 1/1 Running 0 2m
nginx-ingress-controller-78bc478f5b-k5jh7 1/1 Running 0 2m
4、默认情况下系统会自动配置SLB实例的端口监听,请确认您的SLB实例端口监听已正常配置,若无配置说明集群CloudControllerManager服务版本过低,一种方式可参考CloudProvider Release Notes进行版本升级,另一种方式也可以进行手工配置,具体需要的端口映射关系可通过如下命令查看到PORT(S)
:
kubectl -n get svc nginx-ingress-lb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-lb LoadBalancer 172.19.6.227 39.105.252.62 80:30969/TCP,443:31325/TCP 4m
至此在您指定的命名空间下一套新的Nginx Ingress Controller已经成功部署完成。
这里我们部署一个测试应用,并配置通过新部署的Nginx Ingress Controller来对外暴露提供服务访问。
1、 部署一个nginx测试应用:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: nginx
sessionAffinity: None
type: NodePort
2、通过Ingress来对外暴露提供服务访问:注意:这里需要配置注释 kubernetes.io/ingress.class
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx
annotations:
# 注意这里要设置为您前面配置的 INGRESS_CLASS
kubernetes.io/ingress.class: ""
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 80
待部署完成后我们可以看到该Ingress资源对应的端点IP地址与新部署的Nginx Ingress Controller服务的一致:
kubectl -n kube-system get svc nginx-ingress-lb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-lb LoadBalancer 172.19.7.30 47.95.97.115 80:31429/TCP,443:32553/TCP 2d
kubectl -n get svc nginx-ingress-lb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-lb LoadBalancer 172.19.6.227 39.105.252.62 80:30969/TCP,443:31325/TCP 39m
kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
nginx foo.bar.com 39.105.252.62 80 5m
3、此时我们尝试分别通过集群默认的Nginx Ingress Controller服务和新部署的Nginx Ingress Controller服务来访问该应用:
# 通过集群默认的 Nginx Ingress Controller 服务访问该应用(预期返回404)
curl -H "Host: foo.bar.com" http://47.95.97.115
default backend - 404
# 通过新部署的 Nginx Ingress Controller 服务访问该应用(预期返回nginx页面)
curl -H "Host: foo.bar.com" http://39.105.252.62
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
从上面测试访问情况可以看到,通过不同的Nginx Ingress Controller暴露的服务彼此完全是独立的,这特别适用于同一集群内部分服务需要提供公网访问能力,但又有部分服务仅仅只希望为同VPC内非Kubernetes集群的其他服务提供访问的场景。