零敲碎打,积少成多!
获取网段的地址池大小
package main
import (
"fmt"
"math"
"net"
)
func main() {
size:=RangeSize(&net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(24, 32)})
fmt.Println(size) // => 256
}
// RangeSize returns the size of a range in valid addresses.
// returns the size of the subnet (or math.MaxInt64 if the range size would overflow int64)
func RangeSize(subnet *net.IPNet) int64 {
ones, bits := subnet.Mask.Size()
if bits == 32 && (bits-ones) >= 31 || bits == 128 && (bits-ones) >= 127 {
return 0
}
// this checks that we are not overflowing an int64
if bits-ones >= 63 {
return math.MaxInt64
}
return int64(1) << uint(bits-ones)
}
从地址池获取IP
package main
import (
"fmt"
"math/big"
"net"
)
func main() {
subnet:=&net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(24, 32)}
// 获取地址池第一个IP
firstIpInPool,err:=GetIndexedIP(subnet,1)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(firstIpInPool)
}
// BigForIP creates a big.Int based on the provided net.IP
func BigForIP(ip net.IP) *big.Int {
// NOTE: Convert to 16-byte representation so we can
// handle v4 and v6 values the same way.
return big.NewInt(0).SetBytes(ip.To16())
}
// AddIPOffset adds the provided integer offset to a base big.Int representing a net.IP
// NOTE: If you started with a v4 address and overflow it, you get a v6 result.
func AddIPOffset(base *big.Int, offset int) net.IP {
r := big.NewInt(0).Add(base, big.NewInt(int64(offset))).Bytes()
r = append(make([]byte, 16), r...)
return net.IP(r[len(r)-16:])
}
// GetIndexedIP returns a net.IP that is subnet.IP + index in the contiguous IP space.
func GetIndexedIP(subnet *net.IPNet, index int) (net.IP, error) {
ip := AddIPOffset(BigForIP(subnet.IP), index)
if !subnet.Contains(ip) {
return nil, fmt.Errorf("can't generate IP with index %d from subnet. subnet too small. subnet: %q", index, subnet)
}
return ip, nil
}
kubernetes service ip选定
service ip 范围是kubernetes分配给Service
的服务IP地址。
- pkg/controlplane/services.go
// ServiceIPRange checks if the serviceClusterIPRange flag is nil, raising a warning if so and
// setting service ip range to the default value in kubeoptions.DefaultServiceIPCIDR
// for now until the default is removed per the deprecation timeline guidelines.
// Returns service ip range, api server service IP, and an error
func ServiceIPRange(passedServiceClusterIPRange net.IPNet) (net.IPNet, net.IP, error) {
// 检查是否为空,如果为空,默认设置api server service为10.0.0.1
serviceClusterIPRange := passedServiceClusterIPRange
if passedServiceClusterIPRange.IP == nil {
klog.Warningf("No CIDR for service cluster IPs specified. Default value which was %s is deprecated and will be removed in future releases. Please specify it using --service-cluster-ip-range on kube-apiserver.", kubeoptions.DefaultServiceIPCIDR.String())
serviceClusterIPRange = kubeoptions.DefaultServiceIPCIDR
}
// 检查service ip 地址池大小 大于 8
size := integer.Int64Min(utilnet.RangeSize(&serviceClusterIPRange), 1<<16)
if size < 8 {
return net.IPNet{}, net.IP{}, fmt.Errorf("the service cluster IP range must be at least %d IP addresses", 8)
}
// Select the first valid IP from ServiceClusterIPRange to use as the GenericAPIServer service IP.
apiServerServiceIP, err := utilnet.GetIndexedIP(&serviceClusterIPRange, 1)
if err != nil {
return net.IPNet{}, net.IP{}, err
}
klog.V(4).Infof("Setting service IP to %q (read-write).", apiServerServiceIP)
return serviceClusterIPRange, apiServerServiceIP, nil
}