2023-04-09
之前所有的实验都是基于 Minikube,因为其安装非常地简单,但是 minikube 的官方文档也说了,minikube 只推荐在测试环境运行。当我想要建多个节点并在 live 运行的时候,就需要非常注意了。
我的计划如下:
- raspberrypi 安装 k3s master
- cloud server 安装 k3s node
- 使用 cloudflare zero trust 实现内网穿透,使得 node 可以访问本地运行的 master 节点
卸载 minikube
除此之外,卸载原来的 kubctl: sudo mv /usr/local/bin/kubectl /usr/local/bin/kubectl-cjh-uninstalled
这里并没有完全卸载,为的是眼下先留一面,日后万一出了问题好相见。
其他部分参考链接即可。
安装 k3s
网上安装的教程多如牛毛,但又杂七杂八,再加上 k3s 的官网文档其实写的并不好,所以这里推荐直接看下面的视频一步一步来即可:
恢复之前的任务
因为卸载了 minikube,所以之前的 QQ 机器人集群、config-map 都被删除了,这里需要重新运行下:
>>> k apply -f configmap.yaml
>>> k apply -f statefulset.yaml
... wait for a while
>>> k logs cqhttp-0 -f
... scan qr-code to login ...
>>> k logs cqhttp-1 -f
... scan qr-code to login ...
>>> k logs cqhttp-2 -f
... scan qr-code to login ...
另外,需要将之前配置的 prometheus / grafana 兄弟俩重新配置下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: prom-graf
labels:
app: prom-graf
spec:
replicas: 1
selector:
matchLabels:
app: prom-graf
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: prom-graf
spec:
containers:
- name: prometheus
image: prom/prometheus:latest
ports:
- containerPort: 9090
args:
- "--config.file=/etc/prometheus/prometheus.yml"
volumeMounts:
- name: prometheus-data
mountPath: /prometheus
- name: prometheus-config
mountPath: /etc/prometheus/
- name: prom-logs
mountPath: /etc/podinfo
- name: grafana
image: grafana/grafana:latest
ports:
- containerPort: 3000
volumeMounts:
- name: grafana-data
mountPath: /var/lib/grafana
restartPolicy: Always
volumes:
- name: prometheus-config
configMap:
name: prometheus-config
- name: prometheus-data
hostPath:
path: /mnt/prometheus-data
type: DirectoryOrCreate
- name: grafana-data
hostPath:
path: /mnt/grafana-data
type: DirectoryOrCreate
然后再用 configmap 定义好 prometheus 的配置文件内容:
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
labels:
app: prom-graf
data:
prometheus.yml: |
global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
# external_labels:
# monitor: 'codelab-monitor'
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090']
# Example job for node_exporter
- job_name: 'node_exporter'
static_configs:
- targets: ['node_exporter:9100']
# Example job for cadvisor
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
- job_name: myweb3
scrape_interval: 10s
static_configs:
- targets: ['hdcjh.xyz:80']
然后在 /mnt/prometheus-data
文件夹下创建 data
文件夹,并且将其权限改为所有人都可写,否则 prometheus 无法成功在此写入文件。
>>> sudo mkdir /mnt/prometheus-data/data
>>> sudo chmod 777 /mnt/prometheus-data/data
>>> sudo chmod 777 /mnt/grafana/data
更进一步的话,可以使用 initContainers
来自动完成上面的步骤,不过这里为了简便就自己创建了。
应用上面的声明:
k apply -f configmap.yaml
k apply -f deployment.yaml
过了一会后,就发现 prometheus 已经成功启动了:
>>> k get pods -l app=prom-graf
NAME READY STATUS RESTARTS AGE
prom-graf-795b5888f5-pq9vk 2/2 Running 0 92s
现在两个监控的组件都已经成功启动了,可以用下面的命令浅浅试一下:
- 通过
k describe prom-graf-795b5888f5-pq9vk
找到 pod 的 IP 地址 - 通过
sudo socat -d -d TCP-LISTEN:3000,fork,reuseaddr TCP:10.42.0.36:3000
在 host 上暴露 grafana 服务 - 直接使用浏览器访问
http://raspberrypi.local:3000

但是还不能从外部访问,下面使用 k8s 自带的 traefik 来实现 ingress 控制。
- 介绍 K8S service
- 介绍 K8S ingress
- 安装 helm
- 使用 helm 安装 traefik,并进行简单测试
- 编写 traefik 配置文件,重新启动,查看是否成功
看似步骤很多,其实每个步骤都很简单的。
(1) Traefik 如何在 K8S 中工作
- official doc
- 重点看 LoadBalander 部分
下面是 helm 默认安装的 traefik service 声明:
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/instance: traefik-default
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: traefik
helm.sh/chart: traefik-23.0.1
name: traefik
namespace: default
spec:
allocateLoadBalancerNodePorts: true
ports:
- name: web
port: 80
protocol: TCP
targetPort: web
- name: websecure
port: 443
protocol: TCP
targetPort: websecure
selector:
app.kubernetes.io/instance: traefik-default
app.kubernetes.io/name: traefik
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 192.168.0.127
比如我现在要用 Apple 访问 Raspberrypi: curl -XGET https://raspberrypi.local
,当我把这条命令发出去的时候,最终的流量会走到 192.168.0.127
,这是树莓派的 IP 地址。
因为我访问的是 443 端口,所以 traefik service 就会将流量转发到 label 含有 app.kubernetes.io/instance: traefik-default
或者 app.kubernetes.io/name: traefik
的 pod 中去,且根据 ports
部分的配置规则,443 端口的流量会转发到相应 pod 的 websecure
端口。
下面是 traefik pod 声明的节选:
name: traefik
ports:
- containerPort: 9100
name: metrics
protocol: TCP
- containerPort: 9000
name: traefik
protocol: TCP
- containerPort: 8000
name: web
protocol: TCP
- containerPort: 8443
name: websecure
protocol: TCP
这里可以看到 pod 给所有自己暴露的端口都起了新的名字,这样就可以像上面 service 里声明的一样,直接指定端口英文名即可。
当请求流量走到 pod 以后,下面就是 traefik 的逻辑了,根据我们具体定义的配置将不同的请求流量转发到不同的 pod 中。