k8s Tidb 实践-运维篇

继上篇-k8s实践部署之后在此基础上对跑在k8s机器上的tidb服务进行基础运维测试

01 Tidb 组件扩缩容

缩容pd为2 副本:

kubectl patch -n dba tc dba --type merge --patch '{"spec":{"pd":{"replicas":2}}}'

image
扩容pd为3副本:

kubectl patch -n dba tc dba --type merge --patch '{"spec":{"pd":{"replicas":3}}}'
kubectl get po -n dba -o wide

image

02 维护k8s node

维护db53 node

kubectl cordon db53

扩容一个pd,发现不会在db53分配新的pod了,db55 分配了2个,当然这是模拟,同一node 不建议存在两个相同集群角色
image

假设存在tikv 节点,首先迁移tikv region leader

为 TiKV Pod 添加一个 key 为 tidb.pingcap.com/evict-leader 的 annotation:

kubectl -n dba annotate pod dba-tikv-2   tidb.pingcap.com/evict-leader="none"

执行以下命令,检查 Region Leader 是否已经全部被迁移走:

kubectl -n dba get tc dba -ojson | jq ".status.tikv.stores | .[] | select ( .podName == \"dba-tikv-2\" ) | .leaderCount"

0
重建TIKV POD

查看TIKV Pod store-id:

kubectl get -n dba tc dba -ojson | jq ".status.tikv.stores | .[] | select ( .podName == \"dba-tikv-2\" ) | .id"

“1”

在任意一个 PD Pod 中,使用 pd-ctl 命令下线该 TiKV Pod:

kubectl exec -n dba dba-pd-0 -- /pd-ctl store delete 1

image

注意

下线 TiKV Pod 前,需要保证集群中剩余的 TiKV Pod 数不少于 PD 配置中的 TiKV 数据副本数(配置项:max-replicas,默认值 3)。假如不符合该条件,需要先操作扩容 TiKV。

遇到上面报错首先扩容一个tikv节点:

kubectl patch -n dba tc dba --type merge --patch '{"spec":{"tikv":{"replicas":4}}}'

image
新扩容的节点一直处于pending 状态

查看报错:

 kubectl describe pod dba-tikv-3  -n dba

image
提示有1个节点在维护状态,剩下的节点cpu 不足,此时我们可以调整下tikv 节点需要的资源来满足k8s模拟场景

解除维护node:

 kubectl uncordon db53.clouddb.bjzdt.qihoo.net

修改配置文件:
image
使配置生效:

 kubectl replace -f david/tidb-cluster.yaml

image
可以看到tikv jpod 已重启

然后按照上面的步骤重新维护节点,扩容tikv 副本为4,发现现在没问题了,扩容成功
image
image
再次执行下线Tikv Pod:

kubectl exec -n dba dba-pd-0 -- /pd-ctl store delete 1

Success!
image
解除 TiKV Pod 与当前使用的存储的绑定。

查询 Pod 使用的 PersistentVolumeClaim:

kubectl get pvc -n dba

image
删除该 PersistentVolumeClaim:

上图的NAME 就是PVC 的名字

kubectl delete -n dba pvc tikv-dba-tikv-2 --wait=false

删除 TiKV Pod,并等待新创建的 TiKV Pod 加入集群。

kubectl delete -n dba pod dba-tikv-2

pod “dba-tikv-2” deleted
等待新创建的 TiKV Po 状态变为 Up。

image
从输出中可以看到,新的 TiKV Pod 有着新的 store-id,并且 Region Leader 会自动调度到该 TiKV Pod 上。

移除不再需要的 evict-leader-schedul

kubectl exec -n dba dba-pd-0 -- /pd-ctl scheduler remove evict-leader-scheduler-1

Success!

查看当前tikv 所在node 已经没db53了,db53节点维护成功
image

03 部署Tidb monitor

编辑配置文件:

apiVersion: pingcap.com/v1alpha1
kind: TidbMonitor
metadata:
  name: dba
  namespace: dba
spec:
  clusters:
  - name: dba
  prometheus:
    baseImage: prom/prometheus
    version: v2.18.1
    #limits:
    #  cpu: 8000m
    #  memory: 8Gi
    #requests:
    #  cpu: 4000m
    #  memory: 4Gi
    imagePullPolicy: IfNotPresent
    logLevel: info
    reserveDays: 12
    service:
      type: NodePort
      portName: http-prometheus
  grafana:
    baseImage: grafana/grafana
    version: 6.0.1
    imagePullPolicy: IfNotPresent
    logLevel: info
    #limits:
    #  cpu: 8000m
    #  memory: 8Gi
    #requests:
    #  cpu: 4000m
    #  memory: 4Gi
    username: admin
    password: admin
    envs:
      # Configure Grafana using environment variables except GF_PATHS_DATA, GF_SECURITY_ADMIN_USER and GF_SECURITY_ADMIN_PASSWORD
      # Ref https://grafana.com/docs/installation/configuration/#using-environment-variables
      GF_AUTH_ANONYMOUS_ENABLED: "true"
      GF_AUTH_ANONYMOUS_ORG_NAME: "Main Org."
      GF_AUTH_ANONYMOUS_ORG_ROLE: "Viewer"
      # if grafana is running behind a reverse proxy with subpath http://foo.bar/grafana
      # GF_SERVER_DOMAIN: foo.bar
      # GF_SERVER_ROOT_URL: "%(protocol)s://%(domain)s/grafana/"
    service:
      type: NodePort
      portName: http-grafana
  initializer:
    baseImage: pingcap/tidb-monitor-initializer
    version: v6.1.0
    imagePullPolicy: Always
    #limits:
    #  cpu: 50m
    #  memory: 64Mi
    #requests:
    #  cpu: 50m
    #  memory: 64Mi
  reloader:
    baseImage: pingcap/tidb-monitor-reloader
    version: v1.0.1
    imagePullPolicy: IfNotPresent
    service:
      type: NodePort
      portName: tcp-reloader
    #limits:
    #  cpu: 50m
    #  memory: 64Mi
    #requests:
    #  cpu: 50m
    #  memory: 64Mi
  imagePullPolicy: IfNotPresent
  persistent: true
  storageClassName: shared-ssd-storage
  storage: 10Gi
  nodeSelector: {}
  annotations: {}
  tolerations: []
  kubePrometheusURL: http://prometheus-k8s.monitoring.svc:9090
  alertmanagerURL: ""

你可以通过以下命令来确认 PVC 情况:

kubectl get pvc -l app.kubernetes.io/instance=dba,app.kubernetes.io/component=monitor -n dba

应用配置文件:

kubectl apply -f tidb_monitor.yaml

访问 Grafana 监控面板

对于需要直接访问监控数据的情况,可以通过 kubectl port-forward 来访问 Prometheus:

kubectl port-forward --address 10.228.66.152 -n dba svc/dba-grafana 3000:3000 &>/tmp/portforward-grafana.log &

grafana监控

kubectl port-forward --address 10.228.66.152 -n dba svc/dba-prometheus 9090:9090 &>/tmp/portforward-prometheus.log &

访问 Prometheus 监控数

image

04 Alertmanager 告警配置

如果现有的基础设施已经有可用的alertmanager你服务,可以按照下面步骤配置告警

修改tidb _monitor.yaml 配置文件

image

重新应用下

Kubectl replace -f tidb_monitor.yaml

如果想单独部署一套独立的服务,参考官方https://github.com/prometheus/alertmanager 来部署alertmanager 组件

docker run --name alertmanager -d -p 10.228.66.152:9093:9093 quay.io/prometheus/alertmanager

image

一般需要定制化告警,比如发送到邮件或者其他公司内部沟通软件,下面需要登陆到docker容器修改配置文件

docker ps |grep alert 找到alert  docker 进程id
docker exec -it 25ed6524c91a  sh   登陆进容器

image

按照自己需要可定制发送到邮件或者web hook等

image

cat >>  /etc/alertmanager/alertmanager.yml  << EOF
global:
  smtp_smarthost: 'localhost:25'
  smtp_from: 'alertmanager@example.org'
  smtp_auth_username: 'alertmanager'
  smtp_auth_password: 'password'

route:
  receiver: "webhook-sms"
  group_by: ['env','instance','alertname','type','group','job']
  group_wait: 30s
  group_interval: 3m
  repeat_interval: 3h

receivers:
- name: 'webhook-sms'
  webhook_configs:
  - url: 'http://api.xxxxx/public/alertmanagerSendXSM'

EOF

停止pod:

docker stop cdfe1e7beef4

启动pod:

docker start cdfe1e7beef4

查看服务:

image

image

查看某个pod的容器服务:

kubectl get pods dba-tidb-1 -o jsonpath={.spec.containers[*].name}

kubectl exec -it dba-tidb-0 -c tidb -n dba – /bin/sh

-c 指定某种服务

image

05 单独修改节点配置

Tikv 举例:

进入诊断模式后修改配置

让 TiKV Pod 进入诊断模式后,可以手动修改 TiKV 的配置文件,并指定使用修改后的配置文件启动 TiKV 进程。

具体操作步骤如下:

从 TiKV 的日志中获取 TiKV 的启动命令,后续步骤中将会使用。

kubectl logs pod dba-tikv-0 -n dba -c tikv | head -2 | tail -1

输出类似如下,该行就是 TiKV 的启动命令。

/tikv-server --pd=http://dba-pd:2379 --advertise-addr=dba-tikv-0.dba-tikv-peer.dba.svc:20160 --addr=0.0.0.0:20160 --status-addr=0.0.0.0:20180 --advertise-status-addr=dba-tikv-0.dba-tikv-peer.dba.svc:20180 --data-dir=/var/lib/tikv --capacity=0 --config=/etc/tikv/tikv.toml 

注意:

如果 TiKV Pod 持续处于 CrashLoopBackoff 状态,无法从日志中获取启动命令,可以按照上述的命令格式来拼接出启动命令。

对 Pod 开启诊断模式,并重启 Pod。

执行以下命令为 Pod 添加 Annotation,等待下一次 Pod 重启。

kubectl annotate pod dba-tikv-0 -n dba runmode=debug

如果 Pod 一直处于运行中,你可以执行以下命令强制让 TiKV 容器重启。

kubectl exec dba-tikv-0  -n dba -c tikv -- kill -SIGTERM 1

可以通过检查 TiKV 的日志,确认是否进入了诊断模式。

kubectl logs dba-tikv-0   -n dba -c tikv

期望的日志内容如下:

entering debug mode.

执行下面命令进入 TiKV 容器。

kubectl exec -it dba-tikv-0  -n dba -c tikv -- sh

在 TiKV 容器中,复制 TiKV 的配置文件,然后在新的文件上修改 TiKV 的配置。

cp /etc/tikv/tikv.toml /tmp/tikv.toml && vi /tmp/tikv.tmol

在 TiKV 容器中,根据第 1 步中获取的 TiKV 的启动命令,修改启动参数 --config 为刚刚新创建的配置文件路径后,启动 TiKV 进程。

/tikv-server --pd=http://dba-pd:2379 --advertise-addr=dba-tikv-0.dba-tikv-peer.dba.svc:20160 --addr=0.0.0.0:20160 --status-addr=0.0.0.0:20180 --advertise-status-addr=dba-tikv-0.dba-tikv-peer.dba.svc:20180 --data-dir=/var/lib/tikv --capacity=0 --config=/tmp/tikv.toml

测试完成后,如果要恢复 TiKV Pod,可以直接删除当前的 TiKV Pod,并等待 TiKV Pod 自动被拉起。

kubectl delete dba-tikv-0 -n dba

06 压力测试

工具:sysbench

底层存储:nvme 盘,open-local 存储卷模式,网络直通

主要测试只读/只写/读写对应的性能指标

sysbench oltp_read_write --mysql-host=xxx --mysql-port=30002  --table-size=1000000 --db-driver=mysql  --mysql-db=test  --mysql-user=root --mysql-password=''  --time=300   --threads=%s --tables=5 run

Tidb cpu 限制最大使用8c,tikv 限制cpu 最大10c,并发线程128进行压测,top 查看确实限制住了

image

只读测试

image
image

结论:

  随着压测线程增加,只读qps 基本维持在35000-40000/s,延时在32线程之后明显提升,最大耗时在170ms

只写测试

image
image

结论:

  随着压测线程增加,只读qps 基本维持在35000-40000/s,延迟在64线程之后有明显提升最大到112ms

读写测试

image
image

结论:

  随着压测线程增加,只读qps 基本维持在35000-40000/s,延时在64线程之后明显提升,最大耗时在193ms,8-64线程压测延时也在30多ms

07 总结

   在k8s 上跑有db 这种有状态服务目前还待成熟,学习成本比较高,对应运维难度增加,目前个人感觉网上可搜索的实战文章较少,如果对k8s 不熟悉,纠错成本比较高,毕竟官网也不可能全部概括,希望未来小伙伴使用越来越多,大家一起交流学习
1 个赞

想用,就是怕上面有问题搞不定,k8s跑的性能和普通的比怎么样

我也是在测试,性能损失那是一定的,在10-20%,主要是感觉hold 不住,需要k8s 团队配合,还有看下是否强需求吧,是考虑节约成本还是所谓的自动化,我感觉tidb 自身region 基于raft 3副本是可以完成故障转移的,因此并不是强需求,但是可以玩玩,目前准备测试环境整,玩顺了,再上线

还有就是可参考运维实战文章太少了,没点k8s 基础就错成本太高了