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 -运行完就安装完成了,需要保证 6443 和 443 端口可用。
卷和存储
本地存储
添加一个 pvc.yaml
apiVersion: v1kind: PersistentVolumeClaimmetadata: name: mysql-pvc # pvc的名字,可自定义 namespace: defaultspec: accessModes: - ReadWriteOnce # 只能被单节点读写 storageClassName: local-path # k3s 内置的存储类,如果用 k8s 要自己添加 sc resources: requests: storage: 2Gi再添加一个使用 pvc 的 deployment:mysql.yaml
apiVersion: apps/v1kind: Deploymentmetadata: name: mysqlspec: selector: matchLabels: app: mysql # 选择 app: mysql 标签的 pod
template: # 创建 pod 的模板 metadata: labels: app: mysql # 创建 pod 时添加 app: mysql 标签,以便 Deployment 可以识别 spec: containers: - image: mysql name: mysql env: - name: MYSQL_ROOT_PASSWORD value: "123456" ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-volume # 和下面的 volumeMounts 一致才能 bind mountPath: /var/lib/mysql # mysql的 data 所在位置 volumes: - name: mysql-volume # 和上面的 volumeMounts 一致才能bind persistentVolumeClaim: claimName: mysql-pvc # 和刚刚的pvc保持一致分别使用 kubectl apply 添加,pvc 没有 bind 的时候是 pending 状态,成功之后变成 bound
注意 mysql.yaml 的模板中 version 是 apps/v1,这是资源路径。
如果一直显示 pending 可以使用 kubectl describe pods <container_name> 查看原因,container_name需要 get pods 查看
例如这里一开始搞错了 pvc 名字,修正后 describe 得到成功。

但此时还不能访问 mysql,因为它目前只在集群内部使用
集群服务
集群内的 pod 需要变成 service 才能使用,有三种类型:
- ClusterIP Service:仅限集群内
- NodePort Service:集群外
- LoadBalancer Service:集群外+负载均衡
NodePort
NodePort 实际上并不推荐使用,推荐 LoadBalancer
apiVersion: v1kind: Servicemetadata: name: mysql-servicespec: selector: app: mysql ports: - protocol: TCP # TCP|UDP port: 3306 # 客户端访问服务的端口 targetPort: 3306 # 容器端口(mysql) nodePort: 30000 # 在每个节点都开放30000,并转发到3306,省略则不分配 type: NodePort # ClusterIP|NodePort|LoadBalancer注意 nodePort 要求30000-32767(可设置)
外部访问服务的路线为:外部—>30000—>3306(service)—>3306(pod)
LoadBalancer
一般推荐使用 loadbalancer:
apiVersion: v1kind: Servicemetadata: name: mysql-lb-servicespec: selector: app: mysql ports: - protocol: TCP port: 30001 targetPort: 3306 type: LoadBalancer这时可以直接使用[集群外部IP:端口(30001)]访问。
ClusterIP
仅限集群内访问的 ClusterIP:
apiVersion: v1kind: Servicemetadata: name: mysql-ci-servicespec: selector: app: mysql ports: - protocol: TCP # TCP|UDP port: 30002 targetPort: 3306 type: ClusterIP运行后得到:

一般来说会得到一个 CLUSTER-IP,这个 IP 不会变(自动路由到对应 pod),除非重启服务。
但推荐使用 Service Name 访问(这里是 mysql-ci-service)。这样 IP 变了也无所谓,此外 ClusterIP 还可以指定 IP。
深入:k8s 服务
本地调试
实践中关键数据库一般不会暴露到集群外,如 mysql,假设上面我们只有一个 mysql-ci-service 可用,怎么连上mysql 进行调试呢?
- port-forward:使用 kubectl 端口转发:可以转发到 pod 和服务,只转发端口
- proxy:通过 k8s api 访问集群服务,但只能访问 http 服务
- 使用 telepresence:推荐
port-forward
我们已知上面的service 名称为 mysql-ci-service,端口为 30002,则可以输入:
kubectl port-forward service/mysql-ci-service 3306:30002就把本地端口转发到 service 的 30002,service 再转发到 pod 3306
如果要转发 pod(比如说可能想绕过 service 的负载均衡到达指定 pod),则需要得到 pod 名称,然后输入:
kubectl port-forward pod/mysql-6d57fdf866-f492r 3306:3306proxy
输入 kubectl proxy 即可使用
telepresence
telepresence 可以直接拦截本地流量发送到 k8s 上,看起来就好像身处集群中。
telepresence connect如果想要拦截云上服务的流量,telepresence 也能做到,详细参考文档。