1 前言
(1)本文主要包含以下几个方面的内容:
- 使用 Sealos 工具构建 Kubernetes 高可用集群(3 master,1 node)
- 使用 Helm 安装 Ingress-nginx,并使用 Service 的 NodePort 模式向集群外部暴露端口
- 部署 Prometheus 监控工具和 Grafana 图形化展示工具,使用 Ingress-nginx 作入口访问代理
- 部署过程常见的错误及解决方案
(2)本文使用机器详情
主机名称 | 身份 | IP 地址 | 操作系统版本 | Linux 内核版本 |
---|---|---|---|---|
m0 | master | 192.168.255.100 | openEuler 22.03 (LTS-SP2) | 5.10.0-153.12.0.92.oe2203sp2.x86_64 |
m1 | master | 192.168.255.101 | openEuler 22.03 (LTS-SP2) | 5.10.0-153.12.0.92.oe2203sp2.x86_64 |
m2 | master | 192.168.255.102 | openEuler 22.03 (LTS-SP2) | 5.10.0-153.12.0.92.oe2203sp2.x86_64 |
n1 | node | 192.168.255.103 | openEuler 22.03 (LTS-SP2) | 5.10.0-153.12.0.92.oe2203sp2.x86_64 |
(3)组件版本及安装方式
Kubernetes、Helm、Calico 均使用当前最新版本
组件名称 | 版本号 | 安装方式 | 软件来源 |
---|---|---|---|
Kubernetes | 1.28.3 | Sealos + 镜像 | labring/kubernetes - Docker Image |
Helm | 3.12.3 | Sealos + 镜像 | labring/helm - Docker Image |
Calico | 3.26.1 | Sealos + 镜像 | labring/calico - Docker Image |
Ingress-nginx | 4.8.3 | Helm + Chart 包 | ingress-nginx 4.8.3 · kubernetes/ingress-nginx (artifacthub.io) |
Prometheus + Grafana | 0.13 | kubectl | GitHub - prometheus-operator/kube-prometheus at release-0.13 |
(4)注意事项
- 请确保机器可以访问谷歌镜像仓库、红帽镜像仓库及 Github,需要下载镜像及源代码
- 主机之间最好能够相互免密登录
- 主机之间保持时间同步
- 主机名称唯一,不能相同
- 不要自己装 Docker
2 Kubernetes 集群构建
2.1 下载 sealos 工具
注意:此步骤需要在所有节点运行
# 获取 sealos 工具的所有可用版本号
[root@m0 ~]# curl --silent "https://api.github.com/repos/labring/sealos/releases" | jq -r '.[].tag_name'
v5.0.0-alpha2
v4.3.7-rc1
v4.3.6
v4.4.0-beta2
v4.4.0-beta1
v4.3.5
v4.3.4
v4.4.0-alpha3
v4.4.0-alpha1
v4.3.3
v4.3.2
......
# 设置 VERSION 环境变量,此处我设置为 v4.3.6,即安装 4.3.6 版本
[root@m0 ~]# VERSION=v4.3.6 && echo $VERSION
v4.3.6
# 下载 sealos 工具
[root@m0 ~]# wget https://github.com/labring/sealos/releases/download/${VERSION}/sealos_${VERSION#v}_linux_amd64.tar.gz
正在保存至: “sealos_4.3.6_linux_amd64.tar.gz”
sealos_4.3.6_linux_amd64.tar.gz 100%[===================================>] 60.05M 9.58MB/s 用时 7.8s
2023-10-30 15:24:15 (7.69 MB/s) - 已保存 “sealos_4.3.6_linux_amd64.tar.gz” [62963874/62963874])
# 解压 sealos 工具,加可执行权限,并将其移动到 /usr/local/bin/ 目录下
[root@m0 ~]# tar -zxvf sealos_4.3.6_linux_amd64.tar.gz sealos && chmod +x sealos && mv sealos /usr/local/bin
# 查看 sealos 工具是否安装成功
[root@m0 ~]# sealos version
SealosVersion:
buildDate: "2023-10-20T14:15:00Z"
compiler: gc
gitCommit: a2719848
gitVersion: 4.3.6
goVersion: go1.20.10
platform: linux/amd64
2.2 sealos 相关命令
(1)sealos run 构建集群
# 构建 Kubernetes 高可用集群
$ sealos run IMAGE --masters IP1,IP2,IP3... --nodes IP1,IP2,IP3... -p SSH-PASSWORD
参数说明:
IMAGE:需要安装的 Kubernetes 及组件的镜像
--masters:指定 Kubernetes master 节点的 IP 地址
--nodes:指定 Kubernetes node 节点的 IP 地址
-p SSH-PASSWORD:指定 SSH 远程登录的密码
例程:
$ sealos run labring/kubernetes:v1.25.0 labring/helm:v3.8.2 labring/calico:v3.24.1 \
--masters 192.168.64.2,192.168.64.22,192.168.64.20 \
--nodes 192.168.64.21,192.168.64.19 \
-p 123456
(2)sealos run 安装应用
# 安装各种应用
$ sealos run IMAGE
参数说明:
IMAGE:要安装的应用的镜像
例程:
$ sealos run labring/helm:v3.8.2
(3) sealos add 增加节点
# 增加 master 节点
$ sealos add --masters 192.168.1.1,192.168.1.2
# 增加 node 节点
$ sealos add --nodes 192.168.1.3,192.168.1.4
(4) sealos delete 删除节点
# 删除 master 节点
$ sealos delete --masters 192.168.1.1,192.168.1.2
# 删除 node 节点
$ sealos delete --nodes 192.168.1.3,192.168.1.4
(5)sealos reset 清理集群
# 清理 Kubernetes 集群
$ sealos reset
(6)sealos status 查看集群
# 查看 Kubernetes 集群运行状态
$ sealos status
(7)其他命令
# 同 docker 命令的用法,不再赘述
$ sealos pull
$ sealos images
$ sealos rmi
$ sealos ps
2.3 使用 sealos 构建集群
再次申明安装注意事项(参考官方说明):
- 每个集群节点应该有不同的主机名。 主机名不要带下划线
- 所有节点的时间同步
- 在 Kubernetes 集群的第一个节点上运行
sealos run
命令,目前集群外的节点不支持集群安装 - 建议使用干净的操作系统来创建集群。不要自己装 Docker
- 支持大多数 Linux 发行版,例如:Ubuntu CentOS Rocky linux
- 支持 DockerHub 中支持的 Kubernetes 版本
- 支持使用 containerd 作为容器运行时
- 在公有云上请使用私有 IP
注意:此步骤只在第一个 master 节点上执行
(1)执行以下命令构建集群
[root@m0 ~]# sealos run labring/kubernetes:v1.28.3 labring/helm:v3.12.3 labring/calico:v3.26.1 \
--masters 192.168.255.100,192.168.255.101,192.168.255.102 \
--nodes 192.168.255.103 \
-p 123456
(2)执行上述命令后,不需要额外操作,一直等待出现以下界面,表示构建完成
2023-10-30T15:49:36 info succeeded in creating a new cluster, enjoy it!
2023-10-30T15:49:36 info
___ ___ ___ ___ ___ ___
/\ \ /\ \ /\ \ /\__\ /\ \ /\ \
/::\ \ /::\ \ /::\ \ /:/ / /::\ \ /::\ \
/:/\ \ \ /:/\:\ \ /:/\:\ \ /:/ / /:/\:\ \ /:/\ \ \
_\:\~\ \ \ /::\~\:\ \ /::\~\:\ \ /:/ / /:/ \:\ \ _\:\~\ \ \
/\ \:\ \ \__\ /:/\:\ \:\__\ /:/\:\ \:\__\ /:/__/ /:/__/ \:\__\ /\ \:\ \ \__\
\:\ \:\ \/__/ \:\~\:\ \/__/ \/__\:\/:/ / \:\ \ \:\ \ /:/ / \:\ \:\ \/__/
\:\ \:\__\ \:\ \:\__\ \::/ / \:\ \ \:\ /:/ / \:\ \:\__\
\:\/:/ / \:\ \/__/ /:/ / \:\ \ \:\/:/ / \:\/:/ /
\::/ / \:\__\ /:/ / \:\__\ \::/ / \::/ /
\/__/ \/__/ \/__/ \/__/ \/__/ \/__/
Website: https://www.sealos.io/
Address: github.com/labring/sealos
Version: 4.3.6-a2719848
(3)查看 Kubernetes 集群运行状态
[root@m0 ~]# sealos status
......
Systemd Service Status
Logger: journalctl -xeu SERVICE-NAME
Error: <nil>
Init System List:
Name: kubelet Status: Enable && Active
Name: containerd Status: Enable && Active
Name: cri-docker Status: Disable && NotActive
Name: docker Status: Disable && NotActive
Name: registry Status: Enable && Active
Name: image-cri-shim Status: Enable && Active
Cluster Node Status
ReadyNode: 4/4
Cluster Pod Status
Namespace: calico-apiserver
RunningPod: 2/2
Namespace: calico-system
RunningPod: 11/11
Namespace: default
RunningPod: 0/0
Namespace: kube-node-lease
RunningPod: 0/0
Namespace: kube-public
RunningPod: 0/0
Namespace: kube-system
RunningPod: 19/19
Namespace: tigera-operator
RunningPod: 1/1
Cluster Service Status
Namespace: calico-apiserver
HealthService: 1/1
UnhealthServiceList:
Namespace: calico-system
HealthService: 2/2
UnhealthServiceList:
Namespace: default
HealthService: 1/1
UnhealthServiceList:
Namespace: kube-node-lease
HealthService: 0/0
UnhealthServiceList:
Namespace: kube-public
HealthService: 0/0
UnhealthServiceList:
Namespace: kube-system
HealthService: 1/1
UnhealthServiceList:
Namespace: tigera-operator
HealthService: 0/0
UnhealthServiceList:
Error: failed to run checker: pods "kube-apiserver-n1" not found
(4)查看主要组件 Pod 运行情况
[root@m0 ~]# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
calico-apiserver calico-apiserver-5c7799c9d7-bclsw 1/1 Running 0 6m31s
calico-apiserver calico-apiserver-5c7799c9d7-fkqjx 1/1 Running 0 6m31s
calico-system calico-kube-controllers-65f68c6768-8vhnp 1/1 Running 0 7m5s
calico-system calico-node-6dgtc 1/1 Running 0 7m5s
calico-system calico-node-clbn7 1/1 Running 0 7m5s
calico-system calico-node-gf8kh 1/1 Running 0 7m5s
calico-system calico-node-lqzlb 1/1 Running 0 7m5s
calico-system calico-typha-b98b4d5f8-dx649 1/1 Running 0 6m57s
calico-system calico-typha-b98b4d5f8-hlclk 1/1 Running 0 7m5s
calico-system csi-node-driver-29z2d 2/2 Running 0 7m5s
calico-system csi-node-driver-c7wrb 2/2 Running 0 7m5s
calico-system csi-node-driver-f79sh 2/2 Running 0 7m5s
calico-system csi-node-driver-rlrw4 2/2 Running 0 7m5s
kube-system coredns-5dd5756b68-7r7mw 1/1 Running 0 11m
kube-system coredns-5dd5756b68-x2g2x 1/1 Running 0 11m
kube-system etcd-m0 1/1 Running 0 11m
kube-system etcd-m1 1/1 Running 0 9m13s
kube-system etcd-m2 1/1 Running 0 7m27s
kube-system kube-apiserver-m0 1/1 Running 0 11m
kube-system kube-apiserver-m1 1/1 Running 0 9m9s
kube-system kube-apiserver-m2 1/1 Running 0 7m17s
kube-system kube-controller-manager-m0 1/1 Running 0 11m
kube-system kube-controller-manager-m1 1/1 Running 0 9m6s
kube-system kube-controller-manager-m2 1/1 Running 0 7m27s
kube-system kube-proxy-9nsl5 1/1 Running 0 9m18s
kube-system kube-proxy-hdlbn 1/1 Running 0 7m14s
kube-system kube-proxy-ptq8n 1/1 Running 0 11m
kube-system kube-proxy-xhphx 1/1 Running 0 7m28s
kube-system kube-scheduler-m0 1/1 Running 0 11m
kube-system kube-scheduler-m1 1/1 Running 0 9m12s
kube-system kube-scheduler-m2 1/1 Running 0 7m23s
kube-system kube-sealos-lvscare-n1 1/1 Running 0 6m57s
tigera-operator tigera-operator-94d7f7696-zwzh5 1/1 Running 0 7m10s
所有 Pod 均为 Running 状态,至此 Kubernetes 集群构建完成
3 安装 Ingress-nginx
(1)添加 Helm 仓库
[root@m0 ~]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
"ingress-nginx" has been added to your repositories
(2)下载 Ingress-nginx 的 chart 包,并解压
[root@m0 ~]# helm fetch ingress-nginx/ingress-nginx --version 4.8.3
[root@m0 ~]# ls
ingress-nginx-4.8.3.tgz
[root@m0 ~]# tar -zxvf ingress-nginx-4.8.3.tgz
(3)修改 values.yaml 文件
因为默认的暴露方式为 LoadBalancer,需要对接云平台,因此需要将 values.yaml 中的 LoadBalance 更改为 NodePort,并进行暴露端口的配置
[root@m0 ~]# cd ingress-nginx
[root@m0 ingress-nginx]# vim values.yaml
type: NodePort
## type: NodePort
## nodePorts:
## http: 32080
## https: 32443
## tcp:
## 8080: 32808
nodePorts:
http: "32080"
https: "32443"
(4)部署 Ingress-nginx
# 创建 ingress-nginx 名字空间
[root@m0 ingress-nginx]# kubectl create namespace ingress-nginx
namespace/ingress-nginx created
# 安装 ingress-nginx,注意命令末尾的 . 不能省略,表示当前目录
[root@m0 ingress-nginx]# helm install -n ingress-nginx ingress-nginx -f values.yaml .
(5)等待出现以下提示,表示安装完成,还需进一步确认 pod 运行状态
NAME: ingress-nginx
LAST DEPLOYED: Mon Oct 30 18:08:16 2023
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
Get the application URL by running these commands:
export HTTP_NODE_PORT=32080
export HTTPS_NODE_PORT=32443
export NODE_IP=$(kubectl --namespace ingress-nginx get nodes -o jsonpath="{.items[0].status.addresses[1].address}")
echo "Visit http://$NODE_IP:$HTTP_NODE_PORT to access your application via HTTP."
echo "Visit https://$NODE_IP:$HTTPS_NODE_PORT to access your application via HTTPS."
An example Ingress that makes use of the controller:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: foo
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- pathType: Prefix
backend:
service:
name: exampleService
port:
number: 80
path: /
# This section is only required if TLS is to be enabled for the Ingress
tls:
- hosts:
- www.example.com
secretName: example-tls
If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: foo
data:
tls.crt: <base64 encoded cert>
tls.key: <base64 encoded key>
type: kubernetes.io/tls
(6)确认 pod 的运行状态
[root@m0 ingress-nginx]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-controller-798796947c-tbp2m 1/1 Running 0 6m18s
Pod 的状态为 Running 表示安装全部成功
(7)查看暴露的端口
[root@m0 ingress-nginx]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.96.0.134 <none> 80:32080/TCP,443:32443/TCP 9m46s
ingress-nginx-controller-admission ClusterIP 10.96.2.66 <none> 443/TCP 9m46s
已对集群外暴露 32080 和 32443 端口,分别作为 HTTP 和 HTTPS 的端口号
(8)访问测试
在 Windows 浏览器中输入 http://Node_IP:32080,例如 http://192.168.255.100:32080 进行访问测试
出现此界面表示安装配置成功,即能够开始使用 Ingress-nginx 了
说明:
在访问测试中,之所以出现 404 报错,是因为没有指定后端 Service,而是使用了默认后端,此为正常现象
4 安装 Prometheus
4.1 安装 Prometheus
(1)从 Github 克隆源代码
[root@m0 ~]# git clone https://github.com/prometheus-operator/kube-prometheus.git
正克隆到 'kube-prometheus'...
remote: Enumerating objects: 18736, done.
remote: Counting objects: 100% (5373/5373), done.
remote: Compressing objects: 100% (332/332), done.
remote: Total 18736 (delta 5194), reused 5060 (delta 5036), pack-reused 13363
接收对象中: 100% (18736/18736), 9.72 MiB | 4.60 MiB/s, 完成.
处理 delta 中: 100% (12619/12619), 完成.
[root@m0 ~]# ls
kube-prometheus
(2)创建名字空间和 CDRs
# 进入项目目录
[root@m0 ~]# cd kube-prometheus/
# 创建 monitoring 名字空间
[root@m0 kube-prometheus]# kubectl apply --server-side -f manifests/setup
......
namespace/monitoring serverside-applied
# 创建 CRDs(Custom Resource Definition,自定义资源)
[root@m0 kube-prometheus]# kubectl wait \
--for condition=Established \
--all CustomResourceDefinition \
--namespace=monitoring
# 查看是否生效
[root@m0 kube-prometheus]# kubectl get namespace
NAME STATUS AGE
monitoring Active 109s
(3)安装 prometheus
[root@m0 kube-prometheus]# kubectl apply -f manifests/
注意:
Pod 之间存在互相调用关系,但是 Pod 创建有快慢,导致调用出现问题,因此需要根据命令返回的结果,可能需要多次执行该命令,直至所有返回结果均为 created 状态
(4)查看 Pod 运行状态
[root@m0 ~]# kubectl get pod -n monitoring
NAME READY STATUS RESTARTS AGE
alertmanager-main-0 2/2 Running 0 3m1s
alertmanager-main-1 2/2 Running 0 3m1s
alertmanager-main-2 2/2 Running 0 3m1s
blackbox-exporter-76b5c44577-crv2h 3/3 Running 0 5m5s
grafana-748964b847-8d5c2 1/1 Running 0 5m3s
kube-state-metrics-6c664d5dc8-xsqkm 3/3 Running 0 5m3s
node-exporter-gxqct 2/2 Running 0 5m2s
node-exporter-hf26f 2/2 Running 0 5m2s
node-exporter-jvrk9 2/2 Running 0 5m2s
node-exporter-qb8w7 2/2 Running 0 5m2s
prometheus-adapter-7cc789bfcc-64wp8 1/1 Running 0 5m1s
prometheus-adapter-7cc789bfcc-mr9zm 1/1 Running 0 5m1s
prometheus-k8s-0 2/2 Running 0 3m
prometheus-k8s-1 2/2 Running 0 3m
prometheus-operator-6479b5dff9-6w9ft 2/2 Running 0 5m1s
等待所有 Pod 全部为 Running 状态,则安装完成
(5)查看相关的 Service
[root@m0 ~]# kubectl get svc -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main ClusterIP 10.96.3.53 <none> 9093/TCP,8080/TCP 3m37s
alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 93s
blackbox-exporter ClusterIP 10.96.1.22 <none> 9115/TCP,19115/TCP 3m37s
grafana ClusterIP 10.96.0.151 <none> 3000/TCP 3m35s
kube-state-metrics ClusterIP None <none> 8443/TCP,9443/TCP 3m35s
node-exporter ClusterIP None <none> 9100/TCP 3m34s
prometheus-adapter ClusterIP 10.96.2.118 <none> 443/TCP 3m33s
prometheus-k8s ClusterIP 10.96.2.71 <none> 9090/TCP,8080/TCP 3m34s
prometheus-operated ClusterIP None <none> 9090/TCP 92s
prometheus-operator ClusterIP None <none> 8443/TCP 3m33s
这里我们重点关注 grafana 和 prometheus-k8s 的 Service 名称和端口号,要在 ingress-nginx 中使用
4.2 使用 Ingress 反向代理
经过 4.1 的一顿操作,Prometheus 已经可以被正常访问了。然而,由于使用的 Service 的 ClusterIP 模式,因此只能在集群内部访问
要想实现在集群外部访问,要么将 ClusterIP 模式更改为 NodePort 模式暴露端口,要么使用 Ingress 作反向代理访问,既然已经安装了 Ingress-nginx,那就用 Ingress 吧
(1)创建名称为 prometheus-ingress.yaml 的资源清单
[root@m0 ~]# vim prometheus-nginx.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: monitoring # 指定名字空间,需要和 Prometheus 所在的名字空间一致
name: prometheus # 随便起一个好记的名字吧
spec:
ingressClassName: nginx # 重点,必须指定 ingress-ningx 类,使用此命令查询 kubectl get ingressclass
rules:
- host: grafana.k8s.xyz # 定义一个域名,访问此域名则访问 grafana
http:
paths:
- path: / # 匹配所有路径
pathType: Prefix # 匹配规则为前缀匹配
backend: # 指定要代理的后端
service: # 后端为 Service
name: grafana # 要访问的 Service 名称,必须和 kubectl get svc 查询到的一致
port:
number: 3000 # 后端 Service 的端口号,必须和 kubectl get svc 查询到的一致
- host: prometheus.k8s.xyz
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prometheus-k8s
port:
number: 9090
(2)将资源清单实例化
[root@m0 ~]# kubectl apply -f prometheus-nginx.yaml
ingress.networking.k8s.io/prometheus created
(3)查看创建的 Ingress 对象
[root@m0 ~]# kubectl get ingress -n monitoring
NAME CLASS HOSTS ADDRESS PORTS AGE
prometheus nginx grafana.k8s.xyz,prometheus.k8s.xyz 10.96.0.134 80 38s
(4)查看反向代理规则
[root@m0 ~]# kubectl get ingress -n monitoring prometheus
......
Rules:
Host Path Backends
---- ---- --------
grafana.k8s.xyz
/ grafana:3000 (100.75.187.137:3000)
prometheus.k8s.xyz
/ prometheus-k8s:9090 (100.94.130.69:9090,100.94.139.202:9090)
......
若此处的后端(Backends)出现了 error 字样,则表示代理失败,原因及解决方案可查看第 5.2 节
(5)访问测试
注意:
- 提前在 C:\Windows\System32\drivers\etc\hosts 配置好 DNS 解析规则
- 关闭 Kubernetes 所有节点的防火墙并清空防火墙规则
在 Windows 浏览器中输入 http://grafana.k8s.xyz:32080,即可进入 Grafana 界面
在 Windows 浏览器中输入 http://prometheus.k8s.xyz:32080,即可进入 Grafana 界面
4.3 配置路由器端口映射
虽然在集群外使用 Windows 浏览器访问到 Prometheus 和 Grafana 了,但是每次输入域名还要输入端口号,这件事情一点都不优雅。另外,假如端口号忘记了,emm...,反正非常麻烦。要解决这一问题也很简单:将 NodePort 暴露的 Ingress 端口更改为 80 和 443 就好了。然而因为 Kubernetes 给 NodePort 分配默认端口号范围为 30000~32767 ,并且是不允许手动更改范围之外的端口号的,强行更改则需要先更改 Kubernetes 规则,此处不再详述,感兴趣的可以搜索教程
另外也实在没必要折腾,因为折腾之后你会发现虽然能够在 Kubernetes 集群外访问,但还没有跳出局域网这个禁锢。即生产环境中不可能让我们直接访问后端服务器,都需要通过入口的路由器的公网网口,路由器端口映射(DNAT)完美解决了这个问题,这样就能实现真正的公网访问了(当然也可以使用外部方向代理)
以下是具体操作流程:
我使用的是 openWrt 软路由,wan 的 IP 地址为 192.168.230.230,lan 的 IP 地址为192.168.255.2,端口映射策略为:
这个策略相当于以下防火墙规则:
iptables -t nat -A PREROUTING -i eth0 -d 192.168.230.230 -p tcp --dport 80 -j DNAT --to-destination 192.168.255.101:32080
此规则的具体含义为:任意来源 IP 只要访问公网网口的 80 端口,则将目标地址转换为内网 Kubernetes 集群的任意一台主机地址的 32080 端口
也许你还有一个疑问,真实生产环境中,路由器的公网 IP 地址可能是动态 IP,经常发生变化,那我也不能总盯着 IP 地址来更新防火墙策略吧。解决这一个问题同样也很简单,只需将域名进行 DDNS(动态域名解析)配置,即可将域名精准解析到公网网口 IP,无论 IP 地址怎样变化
此时,我们只需要访问 http://grafana.k8s.xyz 和 http://prometheus.k8s.xyz 即可访问 Grafana 和 Prometheus 了,终于不用输入那烦人的端口号了,是不是很优雅 😄
注意:
本文演示中,使用用 DNAT 策略将目标地址修改为集群某一个节点的 IP 地址和端口,这样做的缺点是若目标节点死亡,则访问会失败。实际上可以使用 Nginx 或 LVS 将流量负载到集群的多个节点上(因为 NodePort 模式会在集群所有节点上都绑定暴露的端口),既能防止单点故障又能降低单节点访问压力
5 常见报错及处理方案
5.1 访问失败或 502、504
故障现象:使用浏览器访问集群内部服务时,访问失败,但并没有返回错误代码,如下图所示
故障关键字:无法访问此网站
排查思路:
① 首先查看域名输入是否正确,是否是 Ingress 资源清单中 host 字段匹配的域名
② 查看 DNS 是否正确配置,并且能否解析到正确的 IP 地址
③ 不妨清理一下 Kubernetes 集群所有节点的防火墙规则吧
疑问:
在实验过程中发现,系统防火墙总是被创建了大量和 Calico 相关的自定义规则链和对应的规则,这些规则会阻挡集群外部的访问。当执行
iptables -F
命令清空防火墙规则后,并没有发现集群运行出现异常。等待一段时间后这些规则又会被创建,非常烦人,因此我直接使用了一个循环,每隔 5 秒清理一次防火墙规则
5.2 Ingress 代理失败
故障现象:在执行 kubectl describe ingress INGRESS_NAME 命令查看代理规则时,发现代理的后端 Service 出现 error,如图所示
故障关键字:<error: endopints " " not fond>
故障原因:虽然指定了后端 Service 和端口,但是指定的 Service 不能关联到提供服务的 Pod,这是因为 Ingress 对象所在的名字空间和提供服务的 Pod 及 Service 所在的名字空间不一致,出现了隔离
解决方案:在 Ingress 资源清单文件中指定和要关联的Service 和 Pod 相同的名字空间即可
# 指定 .spec.metadata.namespace 字段
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: monitoring
name: test
spec:
ingressClassName: nginx
rules:
- host: grafana.k8s.xyz.test
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grafana
port:
number: 3000
- host: prometheus.k8s.xyz.test
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prometheus-k8s
port:
number: 9090
[root@m0 ~]# kubectl apply -f test.yaml
ingress.networking.k8s.io/test created
[root@m0 ~]# kubectl describe ingress -n monitoring test
......
Rules:
Host Path Backends
---- ---- --------
grafana.k8s.xyz.test
/ grafana:3000 (100.75.187.149:3000)
prometheus.k8s.xyz.test
/ prometheus-k8s:9090 (100.94.130.72:9090,100.94.139.204:9090)
......
Ingress 反向代理正常,没有出现 error 字样
5.3 Ingress 代理 404 报错
故障现象:在配置好 Ingress 并确认代理的各项设置没问题后,访问时竟然出现 404 Not Found 报错
排错思路:
① 出现此报错说明已经能够访问 Ingress-nginx 了,先排除网络、防火墙方面的问题
② 404 Not Found 错误代码含义为:请求资源无法被找到
③ 既然确认了代理没问题,各项设置没有问题,那不妨查看 Ingress-nginx-controller 的日志怎么说吧
为什么要查看 Ingress-nginx-controller 这个 Pod 的日志呢?
Ingress-nginx 本身是一个 nginx 服务器。在安装 Ingress-nginx 控制器时,会部署一个名称为 Ingress-nginx-controller-xxxxx 的 Pod,里面运行了一个被魔改的 nginx
当我们创建 Ingress 对象时,会把代理规则写入到这个 Pod 中的 nginx 配置文件中,此即 Ingress 对象和 Ingress-nginx 控制器的关系,查看这个 Pod 的日志即能够查看真实的访问流程及事件
[root@m0 prometheus]# kubectl logs -n ingress-nginx ingress-nginx-controller-798796947c-tbp2m
......
W1031 06:06:44.699584 6 controller.go:331] ignoring ingress prometheus in monitoring based on annotation : ingress does not contain a valid IngressClass
......
从日志中看到这样一段日志信息,其意为我们创建的 Ingress 对象没有包含可用的 IngressClass。那么问题来了,什么是 IngressClass?又该如何配置 IngressClass 呢?
(1)什么是 IngressClass
在安装 Ingress 控制器时,我们可能部署了多个不同类型的 Ingress Controller,或者部署了多个同一类型的 Ingress Controller(如部署多个 Ingress-nginx),为了区分不同的 Ingress Controller,会为每个 Ingress Controller 设定唯一的 Class,防止出错
(2)如何配置 IngressClass
① 首先执行如下命令,查看 IngressClassName
[root@m0 ~]# kubectl get ingressclass
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 20h
② 在资源清单中添加 IngressClassName 字段
# 在 .spec.ingressClassName 字段中指定
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: monitoring
name: prometheus
spec:
ingressClassName: nginx
rules:
- host: grafana.k8s.xyz
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grafana
port:
number: 3000
- host: prometheus.k8s.xyz
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prometheus-k8s
port:
number: 9090
问题完美解决,访问一切正常
评论