etcdserver/cluster_util.go
func isCompatibleWithCluster(lg *zap.Logger, cl *membership.RaftCluster, local types.ID, rt http.RoundTripper) bool {
	vers := getVersions(lg, cl, local, rt)
	minV := semver.Must(semver.NewVersion(version.MinClusterVersion))
	maxV := semver.Must(semver.NewVersion(version.Version))
	maxV = &semver.Version{
		Major: maxV.Major,
		Minor: maxV.Minor,
	}
	return isCompatibleWithVers(lg, vers, local, minV, maxV)
}
func isCompatibleWithCluster(lg *zap.Logger, cl *membership.RaftCluster, local types.ID, rt http.RoundTripper) bool {
	vers := getVersions(lg, cl, local, rt)
	minV := semver.Must(semver.NewVersion(version.MinClusterVersion))
	maxV := semver.Must(semver.NewVersion(version.Version))
	maxV = &semver.Version{
		Major: maxV.Major,
		Minor: maxV.Minor,
	}
	return isCompatibleWithVers(lg, vers, local, minV, maxV)
}
// isCompatibleWithCluster return true if the local member has a compatible version with
// the current running cluster.
// The version is considered as compatible when at least one of the other members in the cluster has a
// cluster version in the range of [MinClusterVersion, Version] and no known members has a cluster version
// out of the range.
// We set this rule since when the local member joins, another member might be offline.