-
-
Notifications
You must be signed in to change notification settings - Fork 2
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
Comments
我为什么要在家庭服务中上 kubernetes?我的家庭服务演变是这样的: 先是只有公网云,此时部署服务采用的是单体 Docker 的方式: docker run。 后来服务逐渐变多,且每个服务配置文件大为不同,docker run 的方式也无法持久化命令,所以改为 docker compose。 但是随着服务器变多,docker compose 的弊端也显现了:无法集中管理,有时你会不知道什么服务位于哪台服务器上 。在物色一番后选择了 portainer 作为 Web 管理端,在这里集中的管理每一台机器的 docker compose 配置文件。但是弊端也非常明显,列举几个我感受最明显的:
我需要 k8s 帮我解决什么问题?
|
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 之后会有几个问题:
先看 treafik,按照 k3s 的文档来看,有几种禁用的方式:
再看禁用 ServiceLB 的方法:
咱就是说,逻辑统一下可还行? 综上来看,我们可以把禁用各组件的逻辑收口在 k3s 配置文件上(官方文档),所以我们找到 k3s 配置文件,路径在: 直接编辑增加参数: 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。 |
helm我用的是 Ubuntu,所以这里采用 snap 安装: sudo snap install helm --classic 其他的安装方式可以看官方文档: Install Helm 有一点需要注意,helm 配置文件读取的是 sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
|
多云环境组建 k3s 集群简化环境,这里仅以 2 台服务器为例做记录:
并且 2 台服务器之间通过 tailscale subnet 的方式建立内网(本文假设你已经启动了 tailscale 并以 subnet 方式做了组网,Refer: #201 )。 1. 启动 k3s master在安装启动 k3s server 之前,首先写好配置文件,路径在 disable:
- "traefik"
- "servicelb"
node-external-ip: 192.168.31.31
node-ip: 192.168.31.31
flannel-iface: tailscale0 关于其中
配置完毕后启动 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 -
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 都启动成功了,测试一下: 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> 都能正常访问,皆大欢喜。 参考资料 |
通过 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 种方法:
正常肯定是 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 链添加一条规则,来源地址不是 这里选择的是 raw 表而不是 filter,因为数据包流转是这个顺序:
因为 k8s, docker 都是在 nat 表中做的端口转发,同时 nat 表没有 DROP 功能,所以必须选择一个优先级比 nat 还要高的 raw 表处理。 |
通过 tailscale 组建 k3s 集群正文首先确保你阅读了上面的安装集群的文章,这里只保留最重要的部分。
{
// 这里省略了其他配置
"autoApprovers": {
"routes": {
"10.42.0.0/16": ["Bpazy@github"], // 这是需要增加的配置
"192.168.31.0/24": ["Bpazy@github"], // 这是我自己本身就存在的
},
},
}
# 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
全部配置修改完毕后依次重启 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
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'
为什么会有这问题,因为我的 k3s server 和 tailscale subnet 转发节点在同一台机器上,k3s 启动时会运行 tailscale 命令 所以这个问题只会发生在 k3s (server or agent) 与 subnet router 处于同一台机器时。
问题记录
一些其他人的参考 |
给 node 添加标签
|
节点标签和节点污染我的 k3s 同时存在本地节点、云节点,且本地存在不应该被 Pod 调度到的节点,so 每个节点的 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。 |
通过 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 由于该配置会导致公网也可以访问 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
|
集群内 Pod 无法访问外部网络第二篇又遇到了该问题,且使用上文方法(#320 (comment)) 无效。 这里记录查排查解决步骤:
/usr/share/grafana $ ping baidu.com
PING baidu.com (198.18.0.66): 56 data bytes
|
集群 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 想起来是 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 文档描述,
再次测试,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 |
观望 k3s 好几年了,现在也有上的场景,干就完了!奥利给!
The text was updated successfully, but these errors were encountered: