基于 openEuler 操作系统使用 Sealos 构建 Kubernetes 高可用集群

基于 openEuler 操作系统使用 Sealos 构建 Kubernetes 高可用集群

闫志聪
2023-10-30 / 0 评论 / 265 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年11月21日,已超过182天没有更新,若内容或图片失效,请留言反馈。


1 前言

(1)本文主要包含以下几个方面的内容:

  • 使用 Sealos 工具构建 Kubernetes 高可用集群(3 master,1 node)
  • 使用 Helm 安装 Ingress-nginx,并使用 Service 的 NodePort 模式向集群外部暴露端口
  • 部署 Prometheus 监控工具和 Grafana 图形化展示工具,使用 Ingress-nginx 作入口访问代理
  • 部署过程常见的错误及解决方案

(2)本文使用机器详情

主机名称身份IP 地址操作系统版本Linux 内核版本
m0master192.168.255.100openEuler 22.03 (LTS-SP2)5.10.0-153.12.0.92.oe2203sp2.x86_64
m1master192.168.255.101openEuler 22.03 (LTS-SP2)5.10.0-153.12.0.92.oe2203sp2.x86_64
m2master192.168.255.102openEuler 22.03 (LTS-SP2)5.10.0-153.12.0.92.oe2203sp2.x86_64
n1node192.168.255.103openEuler 22.03 (LTS-SP2)5.10.0-153.12.0.92.oe2203sp2.x86_64

(3)组件版本及安装方式

Kubernetes、Helm、Calico 均使用当前最新版本

组件名称版本号安装方式软件来源
Kubernetes1.28.3Sealos + 镜像labring/kubernetes - Docker Image
Helm3.12.3Sealos + 镜像labring/helm - Docker Image
Calico3.26.1Sealos + 镜像labring/calico - Docker Image
Ingress-nginx4.8.3Helm + Chart 包ingress-nginx 4.8.3 · kubernetes/ingress-nginx (artifacthub.io)
Prometheus + Grafana0.13kubectlGitHub - 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.xyzhttp://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

问题完美解决,访问一切正常

1

评论

博主关闭了当前页面的评论