' b4 h% l! a( T6 _! i
Kubernetes 提供了四层代理用来访问部署在 Pod 中的应用,这种具有四层代理的 Service ,Kubernetes 提供了四种访问方式:
# T3 F$ w7 S X5 k" |- O! {1 w. H8 z* Z# b- \- m% t3 [# K
- ClusterIP:供集群内的其它应用访问,外部无法访问。( l* ] E6 n, D8 A+ E. p
- NodePort:所有节点上开放指定端口,外部可以通过IP+端口访问服务,如果没有指定 NodePort 的端口,默认会随机分配一个30000–32767的端口。
. X% r# W4 W$ \' r - LoadBalancer:在 NodePort 基础上,使用云服务商提供的负载均衡器,把流量转发到服务中。
. |2 @0 m" `; U# f9 @ - ExternalName:通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容。
: W8 D; u3 P' W- J, P 上述的四种方式都不能满足通过域名来访问集群中的应用,为了通过域名访问部署在 Kubernetes 中的应用,最简单的方式就是在集群中部署一个七层代理 Nginx ,通过域名来转发到对应的 Service 。如果有新的部署时,就需要更新一下 Nginx 的配置。为了达到更新配置时其它应用无感知, Ingress 出现了。
# y, E |+ F: Z1 }, k# X# W
, ]8 z: J) L* c3 B
) N4 ?$ P/ U I1 VIngress 可以把 http 和 https 的请求转发到 Kubernetes 集群内部的服务上,最终访问 Service 后端的Pod。可以将 Ingress 配置为 Service 提供外部可访问的 URL、负载均衡流量、提供基于域名的虚拟主机。 6 u$ B! P& w) P$ o; K
/ f3 }3 u/ S L* `/ \# `4 u4 ^- U8 v6 k+ s' w/ N% s" V
Ingress 包含两大组件 Ingress Controller和 Ingress ,常用的 Ingress 有traefik Ingress 和 Nginx Ingress ,本文以 Nginx Ingress 为例。 Ingress Controller 通过与 Kubernetes 的 api 进行交互,动态感知 Kubernetes 集群中 Ingress 服务规则的变化,然后读取这些规则,并按照 Ingress 的规则,转发到 Kubernetes 集群中对应的 Service 上。 Ingress 就是配置这些规则,规则写明了哪个域名对应 Kubernetes 集群中的哪个 Service ,然后根据 Ingress Controller中 Nginx 配置的模板,生成一段对应的 Nginx 配置, Ingress Controller再动态加载这些配置,并把这些配置写入 Ingress Controller 的 Pod 里面运行的 Nginx 服务里,然后reload 一下,使配置生效。
8 C4 {6 s1 ^/ a1 o" |对于部署了 Ingress 的 Kubernetes 集群,我们对 Ingress Controller的 CPU 使用、内存占用、配置文件加载、转发成功率等资源的观测变得非常有必要了。 % j! u, |8 u1 h: q
Ingress 工作原理:
# Y; y/ M7 x/ K# R9 E1 ]2 E l0 J+ m9 i0 W" S n
- 客户端发起http://myNginx.com请求。
/ a2 c$ t" ]" z# I% \0 d* ~ Z - 客户端的 DNS 服务器返回 Ingress 控制器的 IP。
2 R+ x9 i1 w1 u, r! h2 i - 客户端向 Ingress 控制器发送http请求,并在 Host 头中指定myNginx.com。
4 e4 t+ z( L( d. Q" e - 控制器接收到请求后,从头部确定客户端尝试访问哪个服务,通过与该服务关联的 endpoint 对象查看到 pod的 IP。
8 _ X7 V- ]7 p9 X% g" ? - 客户端的请求被转发给具体的 pod 执行。" o2 l' `/ D6 l; ]/ v
' c: }& V* M: b& _5 s; V5 _
! s- j- ~8 D% ^% |. |! E
' Q* e0 V0 B9 E! A% E! ^, }
1 L% s* g9 \) W前置条件
0 R, B& v) p9 U1 v { J1. 安装 Kubernetes
2 T. M1 `# f- C7 i( w+ A# M( ewget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/baremetal/deploy.yaml<hr>2. 安装 DataKit
, _# V7 |) ?# F' p$ f. u登录观测云,【集成】->【Datakit】-> 【Kubernetes】。
* m, b: G6 `. \5 B6 K. U8 P【 观测云 】https://console.guance.com/ % Z7 n0 m7 O! W
3. 部署 Ingress% R0 A) z/ @: w/ q6 S' y: h0 g
生产环境推荐使用 DaemonSet 方式部署 Ingress ,并设置 hosetNetwork 为 true,让 Nginx 直接使用宿主机的网络,然后通过云厂商提供的负载均衡访问 Ingress 。
4 d: ]8 V8 ^$ v3 A2 A1 v0 u(1)下载 deploy.yaml
* U+ t2 C% S1 Q2 l9 Qwget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/baremetal/deploy.yaml(2)编辑 deploy.yaml ; q. B1 L# |( x. O3 K3 }
2.1 替换镜像" d1 }# J) q4 {- J
s& x9 D2 S$ V" B) s使用下面的镜像替换 deploy.yaml 文件中使用的镜像
, J; D& [2 A& uregistry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.1registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.12.2 修改 Deployment 资源文件
2 h. A0 X- ?6 p# t; R( X! z3 N. Q' N9 |% b
找到kind: Deployment部分,修改如下内容:
: C1 E4 k1 b* g- Hkind: DaemonSet #修改 ... hostNetwork: true #新增 dnsPolicy: ClusterFirstWithHostNet #修改 T; U: K" {. `7 A+ X2 q! m
. P9 ?. m& n* S" u D1 Y
kubectl apply -f deploy.yaml
$ l. ~ D, k+ z' G0 ^9 z. H
" v4 h( E. Z @9 t0 ^7 i指标采集3 O) I$ }/ k: r( G3 b
1. 开启 Input
3 c6 `6 I, G4 a; Y6 |$ n观测云接入 Ingress 指标数据,需要 datakit 开启 prom 插件,在 prom 插件配置中指定 exporter 的 url,在 Kubernetes 集群中采集 Ingress Controller指标,推荐使用 annotations 增加注解的方式。打开部署 Ingress 的deploy.yaml 文件,找到上步中修改的 DaemonSet 部分 ,增加 annotations。 6 i; T# L! R: D# w( c5 R9 |
annotations: datakit/prom.instances: | [[inputs.prom]] url = "http://$IP:10254/metrics" source = "prom-ingress" metric_types = ["counter", "gauge", "histogram"] # metric_name_filter = ["cpu"] # measurement_prefix = "" measurement_name = "prom_ingress" interval = "10s" # tags_ignore = ["xxxx"] [[inputs.prom.measurements]] prefix = "nginx_ingress_controller_" name = "prom_ingress" [inputs.prom.tags] namespace = "$NAMESPACE" pod_name = "$PODNAME"
8 j9 j* |0 K! s7 ~% l1 L' d% g \' h" o
7 j* v2 Z9 t2 o4 [
1 T3 z4 t r* E4 p. k6 i参数说明 ' r# x2 V- o: @4 ~1 Z8 X! ^
9 [" @% s3 V, b% G H
- url: Exporter URLs,多个url用逗号分割,示例["http://127.0.0.1:9100/metrics", "http://127.0.0.1:9200/metrics"]
2 ]7 a$ R7 W" `. m5 f2 b* x. y - source: 采集器别名( P. D/ k1 n& Y7 \- A7 ?
- metric_types: 指标类型,可选值是 counter, gauge, histogram, summary
( {; u! O0 p5 U7 g% X - measurement_name: 指标集名称
' v# A4 Z3 ^+ Z. o. [ - interval: 采集频率8 ~1 y/ I% `2 t" @ v
- inputs.prom.measurements: 指标集为 prefix 的前缀归为 name 的指标集
- L4 j; m) B/ B9 m% @* d3 {( i annotations中支持如下几个通配符:
8 M E1 C' C- P- k$ e- O5 h7 t3 e* @. M; g2 w4 a( y' ~ y" V
- $IP:通配 Pod 的内网 IP. D! G$ ~9 t3 \
- $NAMESPACE:Pod Namespace
- i# T# ^( l" H% y' s - $PODNAME:Pod Name8 W$ ^, Z; _: T; }; J
2. 重启 Ingress Controller8 Q& i% D$ u+ J- X6 ~4 f; l6 \1 I
kubectl delete -f deploy.yaml
7 |9 R1 e2 B9 y1 G6 ]- O; qkubectl apply -f deploy.yam" ]: P' t. |) o& W. T
3. 演示案例
" P0 Z8 { N, p$ y编写 Nginx 的部署文件 nginx-deployment.yaml。
& d0 c& e5 y; u, WapiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deploymentspec: selector: matchLabels: app: backend replicas: 1 template: metadata: labels: app: backend spec: # nodeName: df-k8s-node2 containers: - name: nginx image: nginx:latest resources: limits: memory: "128Mi" cpu: "128m" ports: - containerPort: 80 ---apiVersion: v1kind: Servicemetadata: name: nginx-servicespec: selector: app: backend ports: - port: 80 targetPort: 80编写对应的 nginx-ingress .yaml,根据这个规则,如果域名是mynginx .com则转发到 Nginx - Service 这个 Service 。
% s0 c7 d8 w4 l# [apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: nodeport-ingress namespace: default spec: rules: - host: mynginx.com http: paths: - pathType: Prefix path: / backend: service: name: nginx-service port: number: 80部署示例
, _1 Y8 D; q# k. m8 L( lkubectl apply -f nginx-deployment.yamlkubectl apply -f nginx-ingress.yaml测试请求,其中8.136.204.98是 Kubernetes 集群中部署了 Ingress 的节点ip,mynginx.com是 nginx-ingress .yaml中对应的host。 5 M" \3 f* u/ z& R
curl -v http://8.136.204.98 -H 'host: mynginx.com'4. 查看指标数据
. G+ h+ j5 {6 w2 y Y w登录观测云,【指标】-> 找到 prom_ Ingress 指标,其中 prom_ Ingress 是 annotations 中measurement_name 参数的值。
" j5 k" d" H. m$ d
) ~+ m* ?& d8 v7 S D" h* w; L6 t+ J% x
6 v I% k/ }! T* [5 |3 |# L4 q2 \+ O. v. r0 b" I& g
观察 Ingress- D% ^4 G R' r' t
Ingress 监控视图& [! G4 Y- k/ F8 L$ I7 c# G
登录观测云,【场景】->【新建仪表板】,在内置模板库中搜索“ Nginx Ingress Controller”,点击搜索到的模板库,仪表板名称输入“ Nginx Ingress Controller”,点击【确定】。 : d. k( m$ A+ h) q1 N P% P
Ingress 性能指标展示:Ingress Controller 的平均 cpu 使用率、平均内存使用、网络请求/响应合计、 Ingress Config 的加载次数、 Ingress Config 上次加载结果、 Ingress 的转发成功率等。
7 r4 A" I$ i4 L" s
g+ z) ?8 m# h, B/ L9 a9 I
, h0 R5 M' C4 w+ x/ z& d% D9 k
7 l7 @- P7 w x& j" U) C - q1 i- t' Z. h& s: c; D$ c- j- N5 e
【 立即体验观测云 】https://auth.guance.com/register?channel=toutiao
) o! D, U6 ?3 t( i p) U欢迎大家至我们的观测云 Guance Cloud for Observability Github专栏
8 C7 A+ M5 {" l【 Guance Cloud for Observability 】https://github.com/GuanceCloud
, B8 T$ K7 ?, m4 t J了解并使用 喜爱的同时别忘了点击右上角小星星点赞关注哦~
3 j0 ~4 L/ [. T# n, @* c4 G
& M. [$ Q+ b6 [6 X$ P+ m" F, }8 i6 a& u7 E2 J4 D
" o0 a/ e' A9 i3 o! v7 e6 @: m* N* P" o: H
2 \/ e# n/ O, Z- d: i8 p |