123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- /*
- Copyright 2017 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package ipvs
- import (
- "net"
- "strconv"
- "strings"
- "fmt"
- "k8s.io/apimachinery/pkg/util/version"
- "k8s.io/utils/exec"
- )
- // Interface is an injectable interface for running ipvs commands. Implementations must be goroutine-safe.
- type Interface interface {
- // Flush clears all virtual servers in system. return occurred error immediately.
- Flush() error
- // AddVirtualServer creates the specified virtual server.
- AddVirtualServer(*VirtualServer) error
- // UpdateVirtualServer updates an already existing virtual server. If the virtual server does not exist, return error.
- UpdateVirtualServer(*VirtualServer) error
- // DeleteVirtualServer deletes the specified virtual server. If the virtual server does not exist, return error.
- DeleteVirtualServer(*VirtualServer) error
- // Given a partial virtual server, GetVirtualServer will return the specified virtual server information in the system.
- GetVirtualServer(*VirtualServer) (*VirtualServer, error)
- // GetVirtualServers lists all virtual servers in the system.
- GetVirtualServers() ([]*VirtualServer, error)
- // AddRealServer creates the specified real server for the specified virtual server.
- AddRealServer(*VirtualServer, *RealServer) error
- // GetRealServers returns all real servers for the specified virtual server.
- GetRealServers(*VirtualServer) ([]*RealServer, error)
- // DeleteRealServer deletes the specified real server from the specified virtual server.
- DeleteRealServer(*VirtualServer, *RealServer) error
- // UpdateRealServer updates the specified real server from the specified virtual server.
- UpdateRealServer(*VirtualServer, *RealServer) error
- }
- // VirtualServer is an user-oriented definition of an IPVS virtual server in its entirety.
- type VirtualServer struct {
- Address net.IP
- Protocol string
- Port uint16
- Scheduler string
- Flags ServiceFlags
- Timeout uint32
- }
- // ServiceFlags is used to specify session affinity, ip hash etc.
- type ServiceFlags uint32
- const (
- // FlagPersistent specify IPVS service session affinity
- FlagPersistent = 0x1
- // FlagHashed specify IPVS service hash flag
- FlagHashed = 0x2
- // IPVSProxyMode is match set up cluster with ipvs proxy model
- IPVSProxyMode = "ipvs"
- )
- // IPVS required kernel modules.
- const (
- // ModIPVS is the kernel module "ip_vs"
- ModIPVS string = "ip_vs"
- // ModIPVSRR is the kernel module "ip_vs_rr"
- ModIPVSRR string = "ip_vs_rr"
- // ModIPVSWRR is the kernel module "ip_vs_wrr"
- ModIPVSWRR string = "ip_vs_wrr"
- // ModIPVSSH is the kernel module "ip_vs_sh"
- ModIPVSSH string = "ip_vs_sh"
- // ModNfConntrackIPV4 is the module "nf_conntrack_ipv4"
- ModNfConntrackIPV4 string = "nf_conntrack_ipv4"
- // ModNfConntrack is the kernel module "nf_conntrack"
- ModNfConntrack string = "nf_conntrack"
- )
- // Equal check the equality of virtual server.
- // We don't use struct == since it doesn't work because of slice.
- func (svc *VirtualServer) Equal(other *VirtualServer) bool {
- return svc.Address.Equal(other.Address) &&
- svc.Protocol == other.Protocol &&
- svc.Port == other.Port &&
- svc.Scheduler == other.Scheduler &&
- svc.Flags == other.Flags &&
- svc.Timeout == other.Timeout
- }
- func (svc *VirtualServer) String() string {
- return net.JoinHostPort(svc.Address.String(), strconv.Itoa(int(svc.Port))) + "/" + svc.Protocol
- }
- // RealServer is an user-oriented definition of an IPVS real server in its entirety.
- type RealServer struct {
- Address net.IP
- Port uint16
- Weight int
- ActiveConn int
- InactiveConn int
- }
- func (rs *RealServer) String() string {
- return net.JoinHostPort(rs.Address.String(), strconv.Itoa(int(rs.Port)))
- }
- // Equal check the equality of real server.
- // We don't use struct == since it doesn't work because of slice.
- func (rs *RealServer) Equal(other *RealServer) bool {
- return rs.Address.Equal(other.Address) &&
- rs.Port == other.Port
- }
- // GetKernelVersionAndIPVSMods returns the linux kernel version and the required ipvs modules
- func GetKernelVersionAndIPVSMods(Executor exec.Interface) (kernelVersion string, ipvsModules []string, err error) {
- kernelVersionFile := "/proc/sys/kernel/osrelease"
- out, err := Executor.Command("cut", "-f1", "-d", " ", kernelVersionFile).CombinedOutput()
- if err != nil {
- return "", nil, fmt.Errorf("error getting os release kernel version: %v(%s)", err, out)
- }
- kernelVersion = strings.TrimSpace(string(out))
- // parse kernel version
- ver1, err := version.ParseGeneric(kernelVersion)
- if err != nil {
- return kernelVersion, nil, fmt.Errorf("error parsing kernel version: %v(%s)", err, kernelVersion)
- }
- // "nf_conntrack_ipv4" has been removed since v4.19
- // see https://github.com/torvalds/linux/commit/a0ae2562c6c4b2721d9fddba63b7286c13517d9f
- ver2, _ := version.ParseGeneric("4.19")
- // get required ipvs modules
- if ver1.LessThan(ver2) {
- ipvsModules = append(ipvsModules, ModIPVS, ModIPVSRR, ModIPVSWRR, ModIPVSSH, ModNfConntrackIPV4)
- } else {
- ipvsModules = append(ipvsModules, ModIPVS, ModIPVSRR, ModIPVSWRR, ModIPVSSH, ModNfConntrack)
- }
- return kernelVersion, ipvsModules, nil
- }
|