kubeadm: update the CRI socket detection logic

- Throw an error if there is more than one known socket on the host.
- Remove the special handling for docker+containerd.
- Remove the local instances of constants for endpoints for
Windows / Unix and use the defaultKnownCRISockets variable
which is populated from OS specific constants.
- Update error message in detectCRISocketImpl to have more
details.
- Make detectCRISocketImpl accept a list of "known" sockets
- Update unit tests for detectCRISocketImpl and make them
use generic paths such as "unix:///foo/bar.sock".
This commit is contained in:
Lubomir I. Ivanov 2022-01-04 23:36:45 +02:00
parent ea2c948799
commit f3f1332223
4 changed files with 19 additions and 50 deletions

View File

@ -27,6 +27,13 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
)
// defaultKnownCRISockets holds the set of known CRI endpoints
var defaultKnownCRISockets = []string{
constants.CRISocketContainerd,
constants.CRISocketCRIO,
constants.CRISocketDocker,
}
// ContainerRuntime is an interface for working with container runtimes
type ContainerRuntime interface {
Socket() string
@ -115,21 +122,8 @@ func (runtime *CRIRuntime) ImageExists(image string) (bool, error) {
}
// detectCRISocketImpl is separated out only for test purposes, DON'T call it directly, use DetectCRISocket instead
func detectCRISocketImpl(isSocket func(string) bool) (string, error) {
func detectCRISocketImpl(isSocket func(string) bool, knownCRISockets []string) (string, error) {
foundCRISockets := []string{}
knownCRISockets := []string{
// Docker and containerd sockets are special cased below, hence not to be included here
"unix:///var/run/crio/crio.sock",
}
if isSocket(dockerSocket) {
// the path in dockerSocket is not CRI compatible, hence we should replace it with a CRI compatible socket
foundCRISockets = append(foundCRISockets, constants.DefaultCRISocket)
} else if isSocket(containerdSocket) {
// Docker 18.09 gets bundled together with containerd, thus having both dockerSocket and containerdSocket present.
// For compatibility reasons, we use the containerd socket only if Docker is not detected.
foundCRISockets = append(foundCRISockets, containerdSocket)
}
for _, socket := range knownCRISockets {
if isSocket(socket) {
@ -139,18 +133,20 @@ func detectCRISocketImpl(isSocket func(string) bool) (string, error) {
switch len(foundCRISockets) {
case 0:
// Fall back to Docker if no CRI is detected, we can error out later on if we need it
// Fall back to the default socket if no CRI is detected, we can error out later on if we need it
return constants.DefaultCRISocket, nil
case 1:
// Precisely one CRI found, use that
return foundCRISockets[0], nil
default:
// Multiple CRIs installed?
return "", errors.Errorf("Found multiple CRI sockets, please use --cri-socket to select one: %s", strings.Join(foundCRISockets, ", "))
return "", errors.Errorf("Found multiple CRI endpoints on the host. Please define which one do you wish "+
"to use by setting the 'criSocket' field in the kubeadm configuration file: %s",
strings.Join(foundCRISockets, ", "))
}
}
// DetectCRISocket uses a list of known CRI sockets to detect one. If more than one or none is discovered, an error is returned.
func DetectCRISocket() (string, error) {
return detectCRISocketImpl(isExistingSocket)
return detectCRISocketImpl(isExistingSocket, defaultKnownCRISockets)
}

View File

@ -380,32 +380,15 @@ func TestDetectCRISocketImpl(t *testing.T) {
},
{
name: "One valid CRI socket leads to success",
existingSockets: []string{"unix:///var/run/crio/crio.sock"},
existingSockets: []string{"unix:///foo/bar.sock"},
expectedError: false,
expectedSocket: "unix:///var/run/crio/crio.sock",
},
{
name: "CRI and Docker sockets lead to an error",
existingSockets: []string{
"unix:///var/run/docker.sock",
"unix:///var/run/crio/crio.sock",
},
expectedError: true,
},
{
name: "Docker and containerd lead to Docker being used",
existingSockets: []string{
"unix:///var/run/docker.sock",
"unix:///run/containerd/containerd.sock",
},
expectedError: false,
expectedSocket: constants.DefaultCRISocket,
expectedSocket: "unix:///foo/bar.sock",
},
{
name: "Multiple CRI sockets lead to an error",
existingSockets: []string{
"unix:///var/run/crio/crio.sock",
"unix:///run/containerd/containerd.sock",
"unix:///foo/bar.sock",
"unix:///foo/baz.sock",
},
expectedError: true,
},
@ -419,9 +402,9 @@ func TestDetectCRISocketImpl(t *testing.T) {
return true
}
}
return false
})
}, test.existingSockets)
if (err != nil) != test.expectedError {
t.Fatalf("detectCRISocketImpl returned unexpected result\n\tExpected error: %t\n\tGot error: %t", test.expectedError, err != nil)
}

View File

@ -24,11 +24,6 @@ import (
"net/url"
)
const (
dockerSocket = "unix:///var/run/docker.sock" // The Docker socket is not CRI compatible
containerdSocket = "unix:///run/containerd/containerd.sock"
)
// isExistingSocket checks if path exists and is domain socket
func isExistingSocket(path string) bool {
u, err := url.Parse(path)

View File

@ -25,11 +25,6 @@ import (
winio "github.com/Microsoft/go-winio"
)
const (
dockerSocket = "npipe:////./pipe/docker_engine" // The Docker socket is not CRI compatible
containerdSocket = "npipe:////./pipe/containerd-containerd" // Proposed containerd named pipe for Windows
)
// isExistingSocket checks if path exists and is domain socket
func isExistingSocket(path string) bool {
u, err := url.Parse(path)