通过 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应用集群的细节。