Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

三摸 k3s: 正式部署 #320

Open
Bpazy opened this issue Mar 2, 2024 · 12 comments
Open

三摸 k3s: 正式部署 #320

Bpazy opened this issue Mar 2, 2024 · 12 comments
Labels

Comments

@Bpazy
Copy link
Owner

Bpazy commented Mar 2, 2024

观望 k3s 好几年了,现在也有上的场景,干就完了!奥利给!

@Bpazy
Copy link
Owner Author

Bpazy commented Mar 2, 2024

我为什么要在家庭服务中上 kubernetes?

我的家庭服务演变是这样的:

先是只有公网云,此时部署服务采用的是单体 Docker 的方式: docker run。

后来服务逐渐变多,且每个服务配置文件大为不同,docker run 的方式也无法持久化命令,所以改为 docker compose。

但是随着服务器变多,docker compose 的弊端也显现了:无法集中管理,有时你会不知道什么服务位于哪台服务器上 。在物色一番后选择了 portainer 作为 Web 管理端,在这里集中的管理每一台机器的 docker compose 配置文件。但是弊端也非常明显,列举几个我感受最明显的:

  1. yaml 被收在 portainer 内部了,我无法通过 git 去做追踪管理,一旦数据损失,后果无法估量。
  2. portainer 未提供接口去做一些操作,比如重启某容器。当然我知道 portainer 提供了 API,但是非常难用,你几乎无法使用脚本去做直接调用。

我需要 k8s 帮我解决什么问题?

  1. 配置文件集中管理;
  2. 服务通过标签的形式直接部署到边缘节点,不需要我再到对应的机器操作;
  3. 服务不健康后自动重启(当然这一点在前面的方案中也都有解决方案);
  4. 高可用:家中多台服务器,某机器故障后自动转移。比如:家里的智能家居们依赖 home assistant,一旦下线,家里人连灯都关不了。

@Bpazy
Copy link
Owner Author

Bpazy commented Mar 2, 2024

k3s 的安装

主体部分

先前做过 k3s 安装、使用的调研:

本次来做一个系统的记录。

首先需要安装 k3s:

curl -sfL https://get.k3s.io | sh -

不过由于国内无法正常访问到部分网站,所以官网的中文版文档提供了另一个安装脚本:

curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

k3s agent 安装命令有所不同:

sudo curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://192.168.31.31:6443 K3S_TOKEN=YOUR_TOKEN sh -

K3S_TOKEN 使用的值存储在 Server 节点上的 /var/lib/rancher/k3s/server/node-token 中

安装 k3s 之后会有几个问题:

  1. k3s 默认使用的是 treafik,需要替换为 ingress-nginx;
  2. k3s 携带了一个名为 ServiceLB 的组件,它会占用宿主机的 80, 443 端口(参考这里),需要禁用,开放端口咱们可以用 hostPort 或者 nodePort 的方式解决(参考这里)

先看 treafik,按照 k3s 的文档来看,有几种禁用的方式:

  1. 启动时指定 --disable=traefik 参数;
  2. 新建路径为 /var/lib/rancher/k3s/server/manifests/traefik.yaml.skip 的文件;
  3. /etc/rancher/k3s/config.yaml 新增 disable 参数;

再看禁用 ServiceLB 的方法:

  1. 在启动时指定 --disable=servicelb
  2. /etc/rancher/k3s/config.yaml 新增 disable 参数;

咱就是说,逻辑统一下可还行?

综上来看,我们可以把禁用各组件的逻辑收口在 k3s 配置文件上(官方文档),所以我们找到 k3s 配置文件,路径在: /etc/rancher/k3s/config.yaml

直接编辑增加参数:

disable:
  - "traefik"
  - "servicelb"

然后重启 k3s 服务:

sudo systemctl daemon-reload
sudo systemctl restart k3s

后面接着安装 ingress-nginx:

kubectl create clusterrolebinding cluster-admin-binding \
  --clusterrole cluster-admin \
  --user $(gcloud config get-value account)

当然,想顺利是不可能的,这里同样会遇到网络问题,可以通过下载配置文件,修改镜像地址为可访问地址即可,操作如下:

curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/baremetal/deploy.yaml \
  | sed -e "s/registry.k8s.io/k8s.dockerproxy.net/" > nginx-ingress.yaml
sudo kubectl apply -f nginx-ingress.yaml

这里我在网上搜到的一个镜像代理网站 dockerproxy.com,用了还行,就是速度有点慢。

好了,到这里就安装完毕了。

碎碎念

我还尝试过按照 k3s 文档描述的设置 HTTP PROXY 的方法,来拉取镜像,但总是不成功,不明其原因,也做个记录:

$ sudo cat /etc/systemd/system/k3s.service.env
HTTP_PROXY=http://192.168.31.10:7890
HTTPS_PROXY=http://192.168.31.10:7890
CONTAINERD_HTTP_PROXY=http://192.168.31.10:7890
CONTAINERD_HTTPS_PROXY=http://192.168.31.10:7890

拉镜像的时候还是会失败,各种 EOF。

@Bpazy
Copy link
Owner Author

Bpazy commented Mar 4, 2024

helm

我用的是 Ubuntu,所以这里采用 snap 安装:

sudo snap install helm --classic

其他的安装方式可以看官方文档: Install Helm

有一点需要注意,helm 配置文件读取的是 ~/.kube/config,而 k3s 的配置文件在 /etc/rancher/k3s/k3s,按理来说 k3s 安装应当是会自动做这个映射的,如果没有,记得 copy 一下:

sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config

k3s 官方文档: https://docs.k3s.io/cluster-access

@Bpazy
Copy link
Owner Author

Bpazy commented Mar 4, 2024

多云环境组建 k3s 集群

简化环境,这里仅以 2 台服务器为例做记录:

  • 本地 1 台服务器,启动 k3s mater
  • 云端 1 台服务器,启动 k3s agent

并且 2 台服务器之间通过 tailscale subnet 的方式建立内网(本文假设你已经启动了 tailscale 并以 subnet 方式做了组网,Refer: #201 )。

1. 启动 k3s master

在安装启动 k3s server 之前,首先写好配置文件,路径在 /etc/rancher/k3s/config.yaml:

disable:
  - "traefik"
  - "servicelb"
node-external-ip: 192.168.31.31
node-ip: 192.168.31.31
flannel-iface: tailscale0

关于其中 disable 部分上文已经说过了,这里省略,我们看下其他几个参数:

配置项 说明
node-external-ip 节点设置外部 IP。这里应当不重要,考虑不设置
node-ip 内网IP,后续 k3s 集群会使用该 IP 通信
flannel-iface 集群通信网卡,这里写 tailscale0 是指通过 tailscale 通信

配置完毕后启动 server:

curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

2. 启动 agent 节点

同样的,先写配置文件:

node-external-ip: 150.111.111.134
node-ip: 150.111.111.134
flannel-iface: tailscale0

然后启动:

sudo curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://192.168.31.31:6443 K3S_TOKEN=YOUR_TOKEN sh -

K3S_TOKEN 使用的值存储在 Server 节点上的 /var/lib/rancher/k3s/server/node-token 中。

3. 验证集群成功启动

回到 server 节点:

ziyuan@pve-ubuntu:/etc/rancher/k3s$ sudo kubectl get node -o wide -A
NAME           STATUS   ROLES                  AGE   VERSION        INTERNAL-IP       EXTERNAL-IP       OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
pve-ubuntu     Ready    control-plane,master   51m   v1.28.7+k3s1   192.168.31.31     192.168.31.31     Ubuntu 20.04.2 LTS   5.4.0-155-generic   containerd://1.7.11-k3s2
shan-tencent   Ready    <none>                 51m   v1.28.7+k3s1   150.111.111.134   150.111.111.134   Ubuntu 20.04 LTS     5.4.0-77-generic    containerd://1.7.11-k3s2

我们还需要继续验证 nodePort 可以正确的在集群中转发,所以我们按照上文的方式新建一个 nginx-ingress。

查看 pods:

ziyuan@pve-ubuntu:/etc/rancher/k3s$ sudo kubectl get pods -o wide -A
NAMESPACE       NAME                                        READY   STATUS      RESTARTS   AGE   IP          NODE           NOMINATED NODE   READINESS GATES
kube-system     coredns-6799fbcd5-llfd6                     1/1     Running     0          54m   10.42.0.4   pve-ubuntu     <none>           <none>
kube-system     local-path-provisioner-6c86858495-vxdg4     1/1     Running     0          54m   10.42.0.3   pve-ubuntu     <none>           <none>
kube-system     metrics-server-67c658944b-9ccq7             1/1     Running     0          54m   10.42.0.2   pve-ubuntu     <none>           <none>
portainer       portainer-agent-548d57f7b5-s52pb            1/1     Running     0          53m   10.42.1.2   shan-tencent   <none>           <none>
ingress-nginx   ingress-nginx-admission-create-nwdcb        0/1     Completed   0          48m   10.42.1.3   shan-tencent   <none>           <none>
ingress-nginx   ingress-nginx-controller-69f9ffd959-bkls5   1/1     Running     0          48m   10.42.0.6   pve-ubuntu     <none>           <none>

查看 service:

ziyuan@pve-ubuntu:/etc/rancher/k3s$ sudo kubectl get svc -o wide -A
NAMESPACE       NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
default         kubernetes                           ClusterIP      10.43.0.1       <none>        443/TCP                      55m   <none>
kube-system     kube-dns                             ClusterIP      10.43.0.10      <none>        53/UDP,53/TCP,9153/TCP       54m   k8s-app=kube-dns
kube-system     metrics-server                       ClusterIP      10.43.74.179    <none>        443/TCP                      54m   k8s-app=metrics-server
portainer       portainer-agent                      NodePort       10.43.13.160    <none>        9001:30778/TCP               54m   app=portainer-agent
portainer       portainer-agent-headless             ClusterIP      None            <none>        <none>                       54m   app=portainer-agent
ingress-nginx   ingress-nginx-controller             LoadBalancer   10.43.5.251     <pending>     80:30424/TCP,443:30925/TCP   48m   app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
ingress-nginx   ingress-nginx-controller-admission   ClusterIP      10.43.181.246   <none>        443/TCP                      48m   app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx

可以看到 nginx 与对应的 svc 都启动成功了,测试一下:
server 节点:

ziyuan@pve-ubuntu:/etc/rancher/k3s$ curl localhost:30424
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

agent 节点:

ubuntu@shan-tencent:/etc/nginx/sites-enabled$  curl localhost:30424
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

都能正常访问,皆大欢喜。

参考资料

@Bpazy
Copy link
Owner Author

Bpazy commented Mar 7, 2024

通过 DaemonSet 在每个节点部署 Shadowsocks 用于代理

DaemonSet 的作用是给每个节点启动 1 份 Pod,完美适配我的场景,so:

# deploy.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: shadowsocks-client
data:
  config.json: |
    {
      "server": "0.0.0.0",
      "server_port": 32019,
      "password": "sadsada-e642-4616-dsadas-884778233531",
      "method": "aes-128-gcm",
      "local_address": "0.0.0.0",
      "local_port": 30000
    }

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: shadowsocks-client
  namespace: default
spec:
  selector:
    matchLabels:
      name: shadowsocks-client
  template:
    metadata:
      labels:
        name: shadowsocks-client
    spec:
      tolerations:
        - effect: NoSchedule
          operator: Exists
      containers:
        - name: shadowsocks-client
          image: ghcr.io/shadowsocks/sslocal-rust:v1.18.1
          ports:
            - containerPort: 30000
              hostPort: 30000
          volumeMounts:
            - name: config
              mountPath: /etc/shadowsocks-rust
              readOnly: true
      volumes:
      - name: config
        configMap:
          name: shadowsocks-client

---
apiVersion: v1
kind: Service
metadata:
  name: shadowsocks-client
spec:
  type: NodePort
  selector:
    name: shadowsocks-client
  ports:
    - port: 30000
      targetPort: 30000
      nodePort: 30000

接着启动:

sudo kubectl apply -f deploy.yaml

但是这里有一个问题,k8s 无论是 nodePort 亦或者 hostPort,都是监听在 0.0.0.0 这个地址上的,同时没有配置可以修改该值。所以我们必须添加 iptables 规则,来禁止外部访问我们本地的 shadowsocks。

这里有 2 种方法:

  1. 利用 k8s 的 initContainer 来初始化 iptables 规则,添加 NET_ADMIN 权限即可;
  2. 手动在需要禁止外部访问的机器上添加规则;

正常肯定是 initContainer 来做比较好,但是我的情况是每个 node 用的都是 iptables,而 shadowsocks 容器里却是 iptables_nft,两者是无法兼容的,所以先手动处理了:

sudo iptables -t raw -A PREROUTING ! -s 127.0.0.1 -p tcp --dport 30000 -j DROP

翻译一下:在 raw 表中的 PREROUTING 链添加一条规则,来源地址不是 127.0.0.1 并且端口是 30000 的数据包,直接 DROP。

这里选择的是 raw 表而不是 filter,因为数据包流转是这个顺序:

raw -> nat -> filter

因为 k8s, docker 都是在 nat 表中做的端口转发,同时 nat 表没有 DROP 功能,所以必须选择一个优先级比 nat 还要高的 raw 表处理。

@Bpazy
Copy link
Owner Author

Bpazy commented Mar 17, 2024

通过 tailscale 组建 k3s 集群

正文

首先确保你阅读了上面的安装集群的文章,这里只保留最重要的部分。

  1. 在 tailscale admin 上申请好 auth key: Settings -> Keys -> Auth Keys -> Generate auth key…

  2. 在 tailscale admin 上设置好 authApprove ACL:

{
       // 这里省略了其他配置
	"autoApprovers": {
		"routes": {
			"10.42.0.0/16":    ["Bpazy@github"], // 这是需要增加的配置
			"192.168.31.0/24": ["Bpazy@github"], // 这是我自己本身就存在的
		},
	},
}
  1. server, agent 节点分别指定 vpn-auth:
# disable 只在 server 节点指定
disable:
  - "traefik"
  - "servicelb"
# 这 3 行就可以省略了,将 tailscale 打通的任务交给 k3s 去完成
#node-external-ip: 192.168.31.31
#node-ip: 192.168.31.31
#flannel-iface: tailscale0
vpn-auth: name=tailscale,joinKey=XXXX

joinKey 在 tailscale setting 里申请一个。

全部配置修改完毕后依次重启 k3s 服务:

sudo systemctl restart k3s

agent 节点:

sudo systemctl restart k3s-agent

查看效果:

ziyuan@pve-ubuntu:/etc/rancher/k3s$ sudo kubectl get nodes -o wide
NAME           STATUS   ROLES                  AGE   VERSION        INTERNAL-IP      EXTERNAL-IP       OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
shan-tencent   Ready    <none>                 13d   v1.28.7+k3s1   100.114.165.63   150.111.159.111   Ubuntu 20.04 LTS     5.4.0-77-generic     containerd://1.7.11-k3s2
nhan-ubuntu    Ready    <none>                 10h   v1.28.7+k3s1   100.64.40.111    192.168.31.21     Ubuntu 18.04.5 LTS   4.15.0-149-generic   containerd://1.7.11-k3s2
pve-ubuntu     Ready    control-plane,master   13d   v1.28.7+k3s1   100.83.63.108    192.168.31.31     Ubuntu 20.04.2 LTS   5.4.0-155-generic    containerd://1.7.11-k3s2
  1. 由于 k3s 利用了 tailscale 的 subnet 特性,并且这里 k3s 在设置 subnet 的时候会覆盖我以前设置好的 subnet,so,覆盖回去:
sudo tailscale up --advertise-routes 192.168.31.0/24,10.42.0.0/24 --accept-routes --reset

并且这一点每次 k3s 重启都会发生,考虑在 k3s systemctl 配置文件中做自动逻辑:

# /etc/systemd/system/k3s.service
# 增加这一行
ExecStartPost=/bin/sh -c 'sleep 10; tailscale up --advertise-routes 192.168.31.0/24,10.42.0.0/24 --accept-routes --reset'

10.42.0.0/16 为 k3s 默认的 pod CIDR。但是 k3s 启动时会默认给不同的机器 pod 分配不同的子网区间,比如我的 k3s server 被分配为 10.42.0.0/24,k3s agent 被分配为 10.42.1.0/24。所以写这段命令的时候,记得去 tailscale 上查看默认子网分配范围,避免网络配置打架。

为什么会有这问题,因为我的 k3s server 和 tailscale subnet 转发节点在同一台机器上,k3s 启动时会运行 tailscale 命令 sudo tailscale up --advertise-routes 10.42.0.0/24 --accept-routes --reset 把我之前配置好的 subnet 配置覆盖了。

所以这个问题只会发生在 k3s (server or agent) 与 subnet router 处于同一台机器时。

还有一个细节:为什么 k3s 没有在 tailscale 中映射 10.43.0.0/16 这个子网段呢?因为该网段属于 svc,同时 k3s svc 是通过 iptables 将流量从 svc 转发至 pod 的。既然 iptables 已经将转发的事情做了,就不要在 tailscale 重复做了,否则会导致网络问题。

问题记录

  1. subnet 覆盖的问题,参考正文即可;
  2. 如果服务器 ipv6 有问题,则 k3s 启动的时候可能会卡住,从 systemctl ststua k3s 命令的返回值应该能看出,解决办法是给 k3s 增加启动参数: --kubelet-arg "node-ip=0.0.0.0",配置文件同理。

可以参考:

  1. https://ysicing.me/k3s-tailscale hove
  2. failed to validate secondaryNodeIP with tailscale k3s-io/k3s#9410
  1. 局域网内有多个 subnet 时局域网无法互联: tailscale 组网 #201 (comment)

一些其他人的参考

@Bpazy
Copy link
Owner Author

Bpazy commented Apr 3, 2024

给 node 添加标签

ziyuan@pve-ubuntu:~/k8s$ kubectl label nodes pve-ubuntu type=local
node/pve-ubuntu labeled
ziyuan@pve-ubuntu:~/k8s$ kubectl label nodes nhan-ubuntu type=local
node/nhan-ubuntu labeled
ziyuan@pve-ubuntu:~/k8s$ kubectl label nodes shan-tencent type=cloud
node/shan-tencent labeled

@Bpazy
Copy link
Owner Author

Bpazy commented Apr 8, 2024

节点标签和节点污染

我的 k3s 同时存在本地节点、云节点,且本地存在不应该被 Pod 调度到的节点,so 每个节点的 /etc/rancher/k3s/config.yaml 需要指定节点标签与节点污染(官方文档):

node-taint:
  - mtype=bareMetal:NoSchedule
node-label:
  - type=local

如果想在节点注册后更改节点标签和污点,或者添加保留标签,请使用 kubectl:

kubectl taint nodes pve mtype=bareMetal:NoSchedule

查询节点标签:

$ kubectl get nodes --show-labels
pve            Ready    <none>                 13m   v1.28.8+k3s1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=k3s,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=pve,kubernetes.io/os=linux,node.kubernetes.io/instance-type=k3s,type=local

查询节点污染:

$ kubectl describe node pve
.......
Taints:         mtype=bareMetal:NoSchedule

目前只使用污点能力,就足矣覆盖我的场景:部分 node 不允许调度业务 pod。

@Bpazy
Copy link
Owner Author

Bpazy commented Apr 10, 2024

通过 DaemonSet 在每个节点部署 node expoter 用于监控

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
  labels:
    k8s-app: node-exporter
spec:
  selector:
    matchLabels:
      k8s-app: node-exporter
  template:
    metadata:
      labels:
        k8s-app: node-exporter
    spec:
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.3.1
        imagePullPolicy: IfNotPresent
        ports:
        - name: metrics
          containerPort: 9100
        args:
        - "--path.procfs=/host/proc"
        - "--path.sysfs=/host/sys"
        - "--path.rootfs=/host"
        volumeMounts:
        - name: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: sys
          mountPath: /host/sys
        - name: rootfs
          mountPath: /host
      volumes:
      - name: dev
        hostPath:
          path: /dev
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys
      - name: rootfs
        hostPath:
          path: /
      hostPID: true
      hostNetwork: true
      tolerations:
      - effect: NoSchedule
        operator: Exists

由于该配置会导致公网也可以访问 9100,所以通过上文 iptables 的方法,我们需要在公网可访问的机器上禁止非 127.0.0.1 对 9100 的访问:

sudo iptables -t raw -I PREROUTING -p tcp --dport 9100 -j DROP
sudo iptables -t raw -I PREROUTING -s 127.0.0.1 -p tcp --dport 9100 -j ACCEPT
sudo iptables -t raw -I PREROUTING -s 192.168.31.0/24 -p tcp --dport 9100 -j ACCEPT
sudo iptables -t raw -I PREROUTING -s 10.42.0.0/16 -p tcp --dport 9100 -j ACCEPT
sudo iptables -t raw -I PREROUTING -s 10.43.0.0/16 -p tcp --dport 9100 -j ACCEPT
sudo iptables -t raw -I PREROUTING -s 150.150.150.150 -p tcp --dport 9100 -j ACCEPT
  • 10.42.0.0/16, 10.43.0.0/16 为 k3s 默认的 pod, svc CIDR,如果你用的是其他发行版,注意修改。
  • 150.150.150.150 为公网地址,用于 k8s 内部启动的 prometheus 可以正常通过域名访问到 bind 在宿主机上 9100 端口的 exporter。

@Bpazy
Copy link
Owner Author

Bpazy commented Aug 13, 2024

集群内 Pod 无法访问外部网络

今日发生故障,集群内 Pod 无法访问外部网络:

  • ping 114.114.114.114 err
  • ping baidu.com err
  • ping 192.168.31.31 ok
  • ping 其他 pod ip, svc ip err

尝试解决:

  • 重置 tailscale subnet 未生效
  • 重启 k3s server 未生效
  • 重启 k3s agent 生效

监控恢复后,检查状态:
image

发现集群网络中断发生在 21:50 左右,此时我开始了 QNAP NAS 自动向百度网盘备份的功能,跑满了带宽
image

而我的 k3s 网络依赖本地网络进行路由转发,可能是带宽满导致 tailscale subnet 故障,进而导致依赖 subnet 的 k3s 故障。

@Bpazy
Copy link
Owner Author

Bpazy commented Sep 3, 2024

集群内 Pod 无法访问外部网络第二篇

又遇到了该问题,且使用上文方法(#320 (comment)) 无效。

这里记录查排查解决步骤:

  1. 进入 pod 发现 ping 外部域名、IP 均不通,但是 ping 其他 node 是通的;
  2. 观察 ping 解析的域名发现有点像 fake-ip
/usr/share/grafana $ ping baidu.com
PING baidu.com (198.18.0.66): 56 data bytes
  1. 想起 k3s 集群中 master node 更改了网关地址指向了 OpenWrt 并且运行了 OpenClash,且打开了 Fake-IP 模式
  2. 将 Fake-IP 变更为 Redit-Host 模式,并重启 k3s server(这里应该重启 coredns 就可以解决: kubectl -n kube-system rollout restart deployment coredns
  3. 问题修复

@Bpazy
Copy link
Owner Author

Bpazy commented Oct 29, 2024

集群 Pod 无法访问其他 Pod, svc 问题

现象:victoria-metrics 无法访问其他 pod:

ziyuan@pve-ubuntu:~/k8s$ kubectl exec -n monitoring -it victoria-metrics-76958fb59-4kdcm -- /bin/sh
/ # nslookup vmalert
nslookup: write to '10.43.0.10': Connection refused
;; connection timed out; no servers could be reached

排查发现是 coredns pod down 了:

ziyuan@pve-ubuntu:~/grafana$ kubectl get pod -o wide -A | grep dns
kube-system      coredns-bbfb79444-mpgct                      0/1     ContainerCreating     0                 67m     10.42.4.2        shan-ucloud    <none>           <none>

describe 看下发现卡在了 image pull:

$ kubectl describe pod coredns-bbfb79444-mpgct -n kube-system
...
  Warning  FailedCreatePodSandBox  34m                    kubelet            Failed to create pod sandbox: rpc error: code = DeadlineExceeded desc = failed to get sandbox image "rancher/mirrored-pause:3.6": failed to pull image "rancher/mirrored-pause:3.6": failed to pull and unpack image "docker.io/rancher/mirrored-pause:3.6": failed to resolve reference "docker.io/rancher/mirrored-pause:3.6": failed to do request: Head "https://registry-1.docker.io/v2/rancher/mirrored-pause/manifests/3.6": dial tcp 108.160.167.156:443: i/o timeout

想起来是 shan-ucloud 这个 node 是新加入集群的机器,那就配置下 k3s 的仓库镜像吧:

sudo cat /etc/rancher/k3s/registries.yaml

mirrors:
  docker.io:
    endpoint:
      - "https://mirror.aliyuncs.com"
      - "https://dockerproxy.com"
      - "https://mirror.baidubce.com"
      - "https://docker.m.daocloud.io"
      - "https://docker.nju.edu.cn"
      - "https://docker.mirrors.sjtug.sjtu.edu.cn"
      - "https://docker.mirrors.ustc.edu.cn"
      - "https://mirror.iscas.ac.cn"
      - "https://docker.rainbond.cc"
      - "https://registry-1.docker.io"

按照 k3s 文档描述,/etc/rancher/k3s/registries.yaml 文件是 k3s 为了简化 containerd 配置镜像而存在的,该文件配置完毕后,重启 k3s 即可生效:

sudo systemctl restart k3s-agent

再次测试,coredns 已正常,pod 互相访问也正常了:

ziyuan@pve-ubuntu:~/grafana$ kubectl get pod -o wide -A | grep dns
kube-system      coredns-bbfb79444-mpgct                      1/1     Running     0                 115m    10.42.4.2        shan-ucloud    <none>           <none>

ziyuan@pve-ubuntu:~/k8s$ kubectl exec -n monitoring -it victoria-metrics-76958fb59-4kdcm -- /bin/sh
/ # nslookup vmalert
nslookup: write to '10.43.0.10': Connection refused
;; connection timed out; no servers could be reached

/ # 
/ # 
/ # nslookup vmalert
Server:         10.43.0.10
Address:        10.43.0.10:53

@Bpazy Bpazy added the K3S label Dec 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant