背景
随着国内对 IPv6 发展的推进,节点环境的地址段逐渐向 IPv6 转换,尤其是云数据中心的集群部署。人民银行、工信部等八部门近日联合下发《关于推进IPv6技术演进和应用创新发展的实施意见》,对不同行业的环境部署也做了要求。
TiDB 从 v6.5.1 起,由 v1.4.3 或以上版本的 TiDB Operator 部署的 TiDB 全栈支持 IPv6 地址,这意味着 TiDB 可以支持更大的地址空间,并提供更好的安全性和网络性能。
基于 tidb-operator 的 IPv6 K8S 环境的部署
环境要求
- Kubernetes 环境需要支持 IPv6。
- 如果是双栈的 Kubernetes 环境,tidb-operator 需要使用 1.5 版本,CoreDNS 环境需要支持双栈地址解析,能将 service 域名解析到双栈地址(推荐)。
# kubectl exec -it tidbclu65local-tikv-0 -n tidb sh
/ # nslookup tidbclu65local-pd
Server: 2001:db8:42:1::a
Address: 2001:db8:x:x::a#53
Name: tidbclu65local-pd.tidb.svc.cluster.local
Address: 10.x.x.156
Name: tidbclu65local-pd.tidb.svc.cluster.local
Address: 2001:db8:x:x::a462
- 如果是 IPv6 单栈的 Kubernetes 环境,tidb-operator 需要使用 1.4.3 以上版本,CoreDNS 不能对 ipv4 的响应超时,比如关闭 coredns 对 ipv4 解析的 forward。
- TiDB 使用 6.5.1 或者更新的版本,容器使用 containerd 时要使用 6.5.2。
安装过程的关键步骤
TiDB 集群开启支持 IPv6 参数。
spec:
version: v6.5.2
timezone: Asia/Shanghai
preferIPv6: true
双栈环境常见问题
- TiKV 启动过程中,连接不上 PD,实际上 pd-ctl 工具是正常工作的。
[2023/03/22 20:37:05.125 +08:00] [INFO] [util.rs:560] ["PD failed to respond"] [err="Grpc(RpcFailure(RpcStatus { code: 4-DEADLINE_EXCEEDED, message: \"Dead line Exceeded\", details: [] }))"] [endpoints=http://tidbclu65local-pd:2379]
[2023/03/22 20:37:05.426 +08:00] [INFO] [util.rs:598] ["connecting to PD endpoint"] [endpoints=http://tidbclu65local-pd:2379]
[2023/03/22 20:37:07.427 +08:00] [INFO] [util.rs:560] ["PD failed to respond"] [err="Grpc(RpcFailure(RpcStatus { code: 4-DEADLINE_EXCEEDED, message: \"Dead Line Exceeded\", details: [] }))"] [endpoints=http://tidbclu65local-pd:2379]
[2023/03/22 20:37:07.728 +08:00] [INFO] [util.rs:598] ["connecting to PD endpoint"] [endpoints=http://tidbclu65local-pd:2379] [root@paas-dbpt2-local-master1 ~]# ^C
[root@paas-dbpt2-local-master1 ~]# kubectl cp ./pd-ctl tidb/tidbclu65local-tikv-1:/pd-ctl
[root@paas-dbpt2-local-master1 ~]# kubectl exec tidbclu65local-tikv-1 -it /bin/sh -n tidb
> # ./pd-ctl -u http://tidbclu65local-pd:2379 -i
member
{
"header": {
"cluster_id": 7213348098757423028 },
"members": [ {
"name": "tidbclu65local-pd-2", "member id": 5927812073800337986,
"peer urls": [
"http://tidbclu65local-pd-2.tidbclu65local-pd-peer.tidb.svc:2380" ],
"client_urls": [
"http://tidbclu65local-pd-2.tidbclu65local-pd-peer.tidb.svc:2379" ],
"deploy_path":"/",
"binary version": "v6.5.1",
"git hash": "bd807190154f664d1b337df5e2281f56449e7d82"
原因1:
TiKV GRPC 技术依赖双栈 IP,要求双栈 IP 同时返回。
When host enables IPv6 support, gRPC will try to query both IPv4 and IPv6 addresses and return success only when both requests finish. However DNS doesn't work properly always. If it can only provide one type of address and hang on the other, it will wait till timeout. The default timeout is 120s, which is longer than any client timeout in TiKV, so all requests will fail even it can provide service as there is still address returned.
Coredns 只返回双栈 svc 的 ipv6 的地址,ipv4 的地址返回超时。
解决方案1:升级 coredns 到 1.8.1
原因2:
在IPv6 优先的双栈 K8S 环境中,SVC 的 IP Family Policy 仅有 SingleStack。
原因分析:
SVC 的默认单栈 IP 由集群的第一段 cluster ip 范围指定。 The address family of a Service defaults to the address family of the first service cluster IP range (configured via the --service-cluster-ip-range flag to the kube-apiserver).
k8s 环境第一段 cluster ip 范围是 ipv6 的地址段。 --service-cluster-ip-range=2001:db8:42:1::/112,10.96.0.0/16
Operator 1.4 调用的 k8s 库只能使用默认情况。
临时方法:
在Operator 创建 IPv6 地址 的 SVC 后,手工编辑 SVC(包括 tidbclulocal-pd-peer、tidbclulocal-tikv-peer 等),将定义中的 ipFamilyPolicy 改成 PreferDualStack,实现双栈的 SVC。
kubectl patch svc tidbclulocal-pd -p '{"spec":{"ipFamilyPolicy":"PreferDualStack"}}' -n tidb
修改后的效果。
# kubectl describe svc tidbclu65local-pd -n tidb
Name: tidbclu65local-pd
Namespace: tidb
Labels: app.kubernetes.io/component=pd
app.kubernetes.io/instance=tidbclu65local
app.kubernetes.io/managed-by=tidb-operator
app.kubernetes.io/name=tidb-cluster
app.kubernetes.io/used-by=end-user
Annotations: pingcap.com/last-applied-configuration:
{"ports":[{"name":"client","protocol":"TCP","port":2379,"targetPort":2379}],"selector":{"app.kubernetes.io/component":"pd","app.kubernetes...
Selector: app.kubernetes.io/component=pd,app.kubernetes.io/instance=tidbclu65local,app.kubernetes.io/managed-by=tidb-operator,app.kubernetes.io/name=tidb-cluster
Type: ClusterIP
IP Family Policy: PreferDualStack
IP Families: IPv6,IPv4
IP: 2001:db8:42:1::a462
IPs: 2001:db8:42:1::a462,10.96.56.156
Port: client 2379/TCP
TargetPort: 2379/TCP
Endpoints: [2001:db8:42:0:4ea6:2f5e:3ce5:1bd1]:2379,[2001:db8:42:0:4ea6:2f5e:3ce5:1bf6]:2379,[2001:db8:42:0:4ea6:2f5e:3ce5:1bfb]:2379
Session Affinity: None
Events: <none>
TIKV Pod 内能正确解析到双栈 IP 了。
[root@paas-dbpt2-local-master1 deployer]# kubectl exec -it tidbclu65local-tikv-0 -n tidb sh
/ # nslookup tidbclu65local-pd
Server: 2001:db8:42:1::a
Address: 2001:db8:42:1::a#53
Name: tidbclu65local-pd.tidb.svc.cluster.local
Address: 10.96.56.156
Name: tidbclu65local-pd.tidb.svc.cluster.local
Address: 2001:db8:42:1::a462
手工使用 kubectl patch
的方法不能用于生产。
最终方法:
升级 Operator 到 1.5 版本后,可以自动创建 PreferDualStack 的双栈 SVC。
基于 TiUP 的 IPv6 物理机环境的部署
环境要求
- TiDB 使用 6.5.1 或者更新的版本。
- Tiup cluster 需要 v1.12.1 版本,如果部署指定 listen_host 需要更新的版本(当前的时间点是 nightly)。
$ tiup update --self
download https://tiup-mirrors.pingcap.com/tiup-v1.12.1-linux-amd64.tar.gz 7.15 MiB / 7.15 MiB 100.00% 58.09 MiB/s
Updated successfully!
$ tiup update cluster
download https://tiup-mirrors.pingcap.com/cluster-v1.12.1-linux-amd64.tar.gz 8.68 MiB / 8.68 MiB 100.00% 12.98 MiB/s
Updated successfully!
离线环境请从上述网址下载解压后,替换 {HOME}/.tiup 目录下的二进制。
- 部署环境中具备 DNS,能将节点域名解析到 IPv6 地址。
$ nslookup host104.example.com
Server: 198.18.x.30
Address: 198.18.x.30#53
Non-authoritative answer:
Name: host104.example.com
Address: 2401:1d40:x:x::74a
- 集群节点中已经正确配置 IPv6 地址网段。如下图中的
inet6 2401:1d40:x:x::20a/128
。
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether fa:16:3e:23:ce:44 brd ff:ff:ff:ff:ff:ff
inet 10.10.0.110/24 brd 10.10.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 2401:1d40:x:x::20a/128 scope global noprefixroute
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fe23:ce44/64 scope link noprefixroute
valid_lft forever preferred_lft forever
安装过程的关键步骤
配置 YAML 文件并指定域名做为节点。
...
tidb_servers:
- host: "skydrive092a167.tidb"
...
- host: "skydrive121a13c.tidb"
...
pd_servers:
- host: "skydrive119a15e.tidb"
...
- host: "skydrive121a13c.tidb"
...
- host: "skydrive115a161.tidb"
...
tikv_servers:
- host: "skydrive119a15e.tidb"
...
- host: "skydrive121a13c.tidb"
...
- host: "skydrive115a161.tidb"
...
monitoring_servers:
- host: "skydrive092a167.tidb"
grafana_servers:
- host: "skydrive092a167.tidb"
参考常见问题3,如果 cluster 组件已经更新到最新版本后,可以手工配置 yaml 文件中的节点添加 listen_host 指定为 '::'
。
常见问题
- 集群启动时,ssh 报错
Invalid argument
。
手工验证 ssh 节点同样的报错
$ ssh tidb@host102.pingcap.net
ssh: connect to host host102.pingcap.net port 22: Invalid argument
原因:节点没有正确的配置 IPv6 地址,或公有云上没有正确配置 vpc 的 IPv6 网段。主机上的 IPv6 地址信息是 fec0,属于协议规范的本地 IP 段,类似 IPv4 的 169.254.0.0/16。
解决方案:需要配置正确的 IPv6 地址,或公有云正确配置 vpc 的 IPv6 网段。修改后信息如下:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether fa:16:3e:23:ce:44 brd ff:ff:ff:ff:ff:ff
inet 10.10.0.110/24 brd 10.10.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 2401:1d40:x:x::20a/128 scope global noprefixroute
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fe23:ce44/64 scope link noprefixroute
valid_lft forever preferred_lft forever
- TiUP 部署使用 YAML 文件,节点直接使用 IPv6 地址,部分功能异常。
https://github.com/pingcap/tidb/issues/43286
https://github.com/pingcap/tidb-dashboard/pull/1516
原因:代码上有 IPv6 地址不兼容的地方。
解决方案: 需要在部署时改成域名方式。
- TiKV 的监控面板没数据,Prometheus 的 target 内显示连接被拒。
原因:脚本中 status-addr 地址监听只在 ipv4 地址,需要修改为 IPv6 地址。
物理机部署
$ ps -ef |grep tikv-server
tidb 16592 1 4 Apr23 ? 00:30:41 bin/tikv-server --addr 0.0.0.0:20160 --advertise-addr host100.pingcap.net:20160 --status-addr 0.0.0.0:20180 --advertise-status-addr host100.pingcap.net:20180 --pd host100.pingcap.net:2379,host102.pingcap.net:2379,host104.pingcap.net:2379 --data-dir /apps/tidb-data/tikv-20160 --config conf/tikv.toml --log-file /apps/tidb-deploy/tikv-20160/log/tikv.log
tidb-operator 部署
/ # ps -ef |grep tikv-server
1 root 22h56 /tikv-server --pd=tidbclu-pd:2379 --advertise-addr=tidbclu-tikv-2.tidbclu-tikv-peer.tidb.svc:20160 --addr=[::]:20160 --status-addr=[::]:20180 --data-dir=/var/lib/tikv --capacity=190GB --config=/etc/tikv/tikv.toml --advertise-status-addr=tidbclu-tikv-2.tidbclu-tikv-peer.tidb.svc:20180
1478 root 0:00 grep tikv-server
解决方案: tiup 目前没有类似 tidb-operator 的 preferIPv6 的参数,cluster 组件更新到最新版本后,可以手工配置 yaml 文件中的节点添加 listen_host 指定为 '::'
。
...
tidb_servers:
- host: "skydrive092a167.tidb"
listen_host: '::'
ssh_port: 22
port: 4000
如果 tiup cluster 组件未更新,tiup cluster edit
保存时会报 New topology could not be saved: immutable field changed: TiDBServers.0.ListenHost changed from '' to '::'
。临时方案是在部署完成后手动修改 ~/.tiup/storage/cluster/clusters/{cluster_name}/meta.yaml,再使用 tiup cluster reload
。
IPv6 通讯验证
使用 tcpdump 可以看到包通讯的地址类别。
# PD 节点
tcpdump -i eth0 port 2379 -nn
# TiKV 节点
tcpdump -i eth0 port 20160 -nn
总结
TiDB 从 v6.5.1 起,由 v1.4.3 或以上版本的 TiDB Operator 部署的 TiDB 全栈支持 IPv6 地址。
通过扩展验证,可以与 K8S 环境中一样使用域名的方式在物理机环境中支持 IPv6 地址。
附:物理机环境实验用 DNS 的配置
配置 bind 的 named.conf 配置文件,主要修改如下:
- 添加 listen-on 的监听 IP
- 添加 allow-query 的子网
- 添加 .tidb 域名的配置
- 添加 .tidb 域名主机单栈或者双栈的 IP
- 可选配置 PTR 域名(略)
# yum install bind-utils -y
# cat /etc/named.conf
//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//
options {
listen-on port 53 { 10.x.x.x; };
listen-on-v6 port 53 { any; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
secroots-file "/var/named/data/named.secroots";
recursing-file "/var/named/data/named.recursing";
allow-query { 10.x.x.0/24; };
recursion no;
dnssec-enable yes;
dnssec-validation yes;
managed-keys-directory "/var/named/dynamic";
pid-file "/run/named/named.pid";
session-keyfile "/run/named/session.key";
/* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
include "/etc/crypto-policies/back-ends/bind.config";
};
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
};
zone "." IN {
type hint;
file "named.ca";
};
zone "tidb" IN {
type master;
file "tidb.zone";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
# cat /var/named/tidb.zone
$TTL 1D
@ IN SOA ns1.tidb. root.tidb. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
;DNS Servers
IN NS ns1.tidb.
;Name Servers
ns1 IN A 10.x.x.x
skydrive092a167 IN AAAA 2409:8c20:x:x:x:x:afb:a167
skydrive119a15e IN AAAA 2409:8c20:x:x:x:x:afb:a15e
skydrive121a13c IN AAAA 2409:8c20:x:x:x:x:afb:a13c
skydrive115a161 IN AAAA 2409:8c20:x:x:x:x:afb:a161
视业务需要可以配置双栈域名
skydrive092a167 IN AAAA 2409:8c20:x:x:x:x:afb:a167
skydrive119a15e IN AAAA 2409:8c20:x:x:x:x:afb:a15e
skydrive121a13c IN AAAA 2409:8c20:x:x:x:x:afb:a13c
skydrive115a161 IN AAAA 2409:8c20:x:x:x:x:afb:a161
skydrive092a167 IN A 10.x.x.92
skydrive119a15e IN A 10.x.x.119
skydrive121a13c IN A 10.x.x.121
skydrive115a161 IN A 10.x.x.115
服务启动
systemctl start named