通过 Ingress 访问K8S内部的应用
2020-03-10 by dongnan
开始之前
Ingress 是 Kubernetes
的一种 API
对象,将集群内部的 Service
通过 HTTP/HTTPS
方式暴露到集群外部,并通过规则定义 HTTP/HTTPS
的路由。
- 集群外部可访问的 URL
- 负载均衡
- SSL Termination
- 按域名(路径)进行路由
目标
部署 Ingress
控制器,并通过 monitor.io
访问 K8S
集群内部的应用(Service/Pod
)。
数据流大致是这样的:
Client -> SLB (L7 TCP:443) -> ECS -> IngressController(SVC:TCP 32002:443)
-> IngressRule(Host: monitor.io) -> App(SVC:TCP 80:80)
环境描述
测试的k8s
集群由一个Master
管理节点、两个Worker
计算节点组成。
主机: AliYun ecs.g6.large 2c/8G
OS: Ubuntu Server 18.04
Docker: docker-ce:18.09.9
Kubernetes: v1.17.x
网络: 使用相同的 VPC 与 安全组
角色:
master:
主机名: host0
IP: 10.0.20.20
worker:
主机名: host1
IP: 10.0.20.21
主机名: host2
IP: 10.0.20.22
k8s 部署请参考这篇文章
操作步骤
需要使用到的文件
tree k8s/ingress/
k8s/ingress/
├── controller
│ ├── ingress-svc.yaml
│ └── mandatory.yaml
└── default
├── ds.yaml
├── ing.yaml
└── svc.yaml
2 directories, 5 files
部署 ingress 控制器
使用 kubectl
命令完成部署
kubectl apply -f k8s/ingress/controller/
将自动创建 NameSpace
、Service
、Deployment
、Pod
等资源:
# namespaces
kubectl get ns ingress-nginx
NAME STATUS AGE
ingress-nginx Active 101d
# service
kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 172.19.xxx.223 <none> 80:32001/TCP,443:32002/TCP 101d
# deployment
kubectl -n ingress-nginx get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-ingress-controller 2/2 2 2 101d
# pod
kubectl -n ingress-nginx get pod
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-5b454769bd-8bqqk 1/1 Running 0 101d
nginx-ingress-controller-5b454769bd-ftp7j 1/1 Running 0 101d
需要注意的是,Service
使用的是 NodePort
方式,这将暴露ECS
的端口给SLB
负载均衡器使用。
创建 ingress 规则
当拥有 ingress
控制器后,就可以创建具体的 ingress
规则了,例如希望访问 monitor.io/check.html
时代理到后端的 nginx
服务。
首先看下 ingress
规则,在这个 yaml
文件定义了 host
与path
。
cat ing.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: monitor.io
annotations:
nginx.ingress.kubernetes.io/enable-access-log: "false" # 关闭日志
spec:
rules:
- host: monitor.io
http:
paths:
- path: /check.html
backend:
serviceName: default-svc # 注意
servicePort: 80
创建 Ingress
kubectl apply -f k8s/ingress/default/ing.yaml
查看 Ingress
kubectl get ingresses.
NAME HOSTS ADDRESS PORTS AGE
monitor.io monitor.io 172.19.xxx.223 80 101d
但是只有 ingress
规则只是第一步,还需要 Service
和 Pod
资源才能提供完整的服务,可以看到在规则中指定了 Service
为 default-svc
。
创建 Service
Service 在这个 yaml
文件中则定义了 协议、端口和集群类型等,并指定后端Pod
必须带有 app: default-nginx
这个标签。
cat svc.yaml
apiVersion: v1
kind: Service
metadata:
name: default-svc
labels:
app: default-svc
spec:
selector:
app: default-nginx # 注意
ports:
- name: default-svc-port
protocol: TCP
port: 80
targetPort: 80
type: ClusterIP # ClusterIP/NodePort/LoaderBalancer
# sessionAffinity: ClientIP
创建 Service
kubectl apply -f k8s/ingress/default/svc.yaml
查看 Service
kubectl get svc default-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default-svc ClusterIP 172.19.xxx.151 <none> 80/TCP 101d
创建 Pod
这里的 Pod
是使用 DaemonSet
进行管理维护,与 Deployment
不同的是 DaemonSet
将在K8s
集群每个Worker
节点都会上运行此Pod
。
在这个 yaml
文件定义了标签 app: default-nginx
,也就与 Service selector
所对应的标签。
cat default/ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: default-nginx
labels:
app: default-nginx
spec:
selector:
matchLabels:
app: default-nginx
template:
metadata:
labels:
app: default-nginx # 注意
spec:
containers:
- name: nginx
image: hub.xyc.com/library/nginx-health:0.0.3
创建 Pod
kubectl apply -f k8s/ingress/default/ds.yaml
查看 Pod
kubectl get pod
NAME READY STATUS RESTARTS AGE
default-nginx-k8p2q 1/1 Running 2 101d
default-nginx-kmhkc 1/1 Running 1 101d
验证
在K8s
集群外部通过浏览器访问返回ok
表示 ingress
可以正常使用。
# 这里使用 curl 模拟浏览器访问
curl -H "Host:monitor.io" -k https://Your-Server-IP/check.html
ok
小结
- Ingress 控制器是非常重要的,可以将它理解为一个智能的
Nginx
代理服务器。 - 而
Ingress
规则 与Service
、Pod
共同描述了这个Web
应用集群的细节。