-
Notifications
You must be signed in to change notification settings - Fork 407
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
node-servant: add preflight-convert command (#686)
- Loading branch information
Showing
17 changed files
with
922 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
Copyright 2021 The OpenYurt 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 preflight_convert | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
"k8s.io/klog/v2" | ||
|
||
preflightconvert "github.com/openyurtio/openyurt/pkg/node-servant/preflight-convert" | ||
) | ||
|
||
const ( | ||
latestYurtHubImage = "openyurt/yurthub:latest" | ||
latestYurtTunnelAgentImage = "openyurt/yurt-tunnel-agent:latest" | ||
) | ||
|
||
// NewxPreflightConvertCmd generates a new preflight-convert check command | ||
func NewxPreflightConvertCmd() *cobra.Command { | ||
o := preflightconvert.NewPreflightConvertOptions() | ||
cmd := &cobra.Command{ | ||
Use: "preflight-convert", | ||
Short: "", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
if err := o.Complete(cmd.Flags()); err != nil { | ||
klog.Errorf("Fail to complete the preflight-convert option: %s", err) | ||
os.Exit(1) | ||
} | ||
preflighter := preflightconvert.NewPreflighterWithOptions(o) | ||
if err := preflighter.Do(); err != nil { | ||
klog.Errorf("Fail to run pre-flight checks: %s", err) | ||
os.Exit(1) | ||
} | ||
klog.Info("convert pre-flight checks success") | ||
}, | ||
} | ||
setFlags(cmd) | ||
|
||
return cmd | ||
} | ||
|
||
func setFlags(cmd *cobra.Command) { | ||
cmd.Flags().StringP("kubeadm-conf-path", "k", "", | ||
"The path to kubelet service conf that is used by kubelet component to join the cluster on the work node."+ | ||
"Support multiple values, will search in order until get the file.(e.g -k kbcfg1,kbcfg2)", | ||
) | ||
cmd.Flags().String("yurthub-image", latestYurtHubImage, "The yurthub image.") | ||
cmd.Flags().String("yurt-tunnel-agent-image", latestYurtTunnelAgentImage, "The yurt-tunnel-agent image.") | ||
cmd.Flags().BoolP("deploy-yurttunnel", "t", false, "If set, yurt-tunnel-agent will be deployed.") | ||
cmd.Flags().String("ignore-preflight-errors", "", "A list of checks whose errors will be shown as warnings. "+ | ||
"And value needs to be lowercase. Example: 'isprivilegeduser,imagepull'.Value 'all' ignores errors from all checks.", | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
/* | ||
Copyright 2021 The OpenYurt 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 components | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
goruntime "runtime" | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
utilsexec "k8s.io/utils/exec" | ||
) | ||
|
||
const ( | ||
dockerSocket = "/var/run/docker.sock" // The Docker socket is not CRI compatible | ||
containerdSocket = "/run/containerd/containerd.sock" | ||
// DefaultDockerCRISocket defines the default Docker CRI socket | ||
DefaultDockerCRISocket = "/var/run/dockershim.sock" | ||
|
||
// PullImageRetry specifies how many times ContainerRuntime retries when pulling image failed | ||
PullImageRetry = 5 | ||
) | ||
|
||
// ContainerRuntime is an interface for working with container runtimes | ||
type ContainerRuntimeForImage interface { | ||
IsDocker() bool | ||
PullImage(image string) error | ||
ImageExists(image string) (bool, error) | ||
} | ||
|
||
// CRIRuntime is a struct that interfaces with the CRI | ||
type CRIRuntime struct { | ||
exec utilsexec.Interface | ||
criSocket string | ||
} | ||
|
||
// DockerRuntime is a struct that interfaces with the Docker daemon | ||
type DockerRuntime struct { | ||
exec utilsexec.Interface | ||
} | ||
|
||
// NewContainerRuntime sets up and returns a ContainerRuntime struct | ||
func NewContainerRuntimeForImage(execer utilsexec.Interface, criSocket string) (ContainerRuntimeForImage, error) { | ||
var toolName string | ||
var runtime ContainerRuntimeForImage | ||
|
||
if criSocket != DefaultDockerCRISocket { | ||
toolName = "crictl" | ||
// !!! temporary work around crictl warning: | ||
// Using "/var/run/crio/crio.sock" as endpoint is deprecated, | ||
// please consider using full url format "unix:///var/run/crio/crio.sock" | ||
if filepath.IsAbs(criSocket) && goruntime.GOOS != "windows" { | ||
criSocket = "unix://" + criSocket | ||
} | ||
runtime = &CRIRuntime{execer, criSocket} | ||
} else { | ||
toolName = "docker" | ||
runtime = &DockerRuntime{execer} | ||
} | ||
|
||
if _, err := execer.LookPath(toolName); err != nil { | ||
return nil, errors.Wrapf(err, "%s is required for container runtime", toolName) | ||
} | ||
return runtime, nil | ||
} | ||
|
||
// IsDocker returns true if the runtime is docker | ||
func (runtime *CRIRuntime) IsDocker() bool { | ||
return false | ||
} | ||
|
||
// IsDocker returns true if the runtime is docker | ||
func (runtime *DockerRuntime) IsDocker() bool { | ||
return true | ||
} | ||
|
||
// PullImage pulls the image | ||
func (runtime *CRIRuntime) PullImage(image string) error { | ||
var err error | ||
var out []byte | ||
for i := 0; i < PullImageRetry; i++ { | ||
out, err = runtime.exec.Command("crictl", "-r", runtime.criSocket, "pull", image).CombinedOutput() | ||
if err == nil { | ||
return nil | ||
} | ||
} | ||
return errors.Wrapf(err, "output: %s, error", out) | ||
} | ||
|
||
// PullImage pulls the image | ||
func (runtime *DockerRuntime) PullImage(image string) error { | ||
var err error | ||
var out []byte | ||
for i := 0; i < PullImageRetry; i++ { | ||
out, err = runtime.exec.Command("docker", "pull", image).CombinedOutput() | ||
if err == nil { | ||
return nil | ||
} | ||
} | ||
return errors.Wrapf(err, "output: %s, error", out) | ||
} | ||
|
||
// ImageExists checks to see if the image exists on the system | ||
func (runtime *CRIRuntime) ImageExists(image string) (bool, error) { | ||
err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "inspecti", image).Run() | ||
return err == nil, nil | ||
} | ||
|
||
// ImageExists checks to see if the image exists on the system | ||
func (runtime *DockerRuntime) ImageExists(image string) (bool, error) { | ||
err := runtime.exec.Command("docker", "inspect", image).Run() | ||
return err == nil, nil | ||
} | ||
|
||
// detectCRISocketImpl is separated out only for test purposes, DON'T call it directly, use DetectCRISocket instead | ||
func detectCRISocketImpl(isSocket func(string) bool) (string, error) { | ||
foundCRISockets := []string{} | ||
knownCRISockets := []string{ | ||
// Docker and containerd sockets are special cased below, hence not to be included here | ||
"/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, DefaultDockerCRISocket) | ||
} 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) { | ||
foundCRISockets = append(foundCRISockets, socket) | ||
} | ||
} | ||
|
||
switch len(foundCRISockets) { | ||
case 0: | ||
// Fall back to Docker if no CRI is detected, we can error out later on if we need it | ||
return DefaultDockerCRISocket, 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, ", ")) | ||
} | ||
|
||
} | ||
|
||
// isExistingSocket checks if path exists and is domain socket | ||
func isExistingSocket(path string) bool { | ||
fileInfo, err := os.Stat(path) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
return fileInfo.Mode()&os.ModeSocket != 0 | ||
} | ||
|
||
// 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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
Copyright 2021 The OpenYurt 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 components | ||
|
||
import ( | ||
"os" | ||
) | ||
|
||
const ( | ||
KubeletSvcEnv = "KUBELET_SVC" | ||
KubeletSvcPathSystemUsr = "/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf" | ||
KubelerSvcPathSystemEtc = "/etc/systemd/system/kubelet.service.d/10-kubeadm.conf" | ||
) | ||
|
||
func GetDefaultKubeadmConfPath() []string { | ||
kubeadmConfPath := []string{} | ||
path := os.Getenv(KubeletSvcEnv) | ||
if path != "" && path != KubeletSvcPathSystemUsr && path != KubelerSvcPathSystemEtc { | ||
kubeadmConfPath = append(kubeadmConfPath, path) | ||
} | ||
kubeadmConfPath = append(kubeadmConfPath, KubeletSvcPathSystemUsr, KubelerSvcPathSystemEtc) | ||
return kubeadmConfPath | ||
} |
Oops, something went wrong.