Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

yurtadm join: support deploying local mode yurthub in systemd #2190

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/yurthub/app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@
var err error
// If yurthub is in local mode, create kubeconfig for host control plane to prepare informerFactory.
if util.WorkingMode(options.WorkingMode) == util.WorkingModeLocal {
kubeConfig, err = clientcmd.BuildConfigFromFlags(fmt.Sprintf("http://%s", options.HostControlPlaneAddr), "")
// kubeConfig, err = clientcmd.BuildConfigFromFlags(fmt.Sprintf("http://%s", options.HostControlPlaneAddr), "")
kubeConfig, err = clientcmd.BuildConfigFromFlags("", "/root/ackkubeconfig")

Check warning on line 283 in cmd/yurthub/app/config/config.go

View check run for this annotation

Codecov / codecov/patch

cmd/yurthub/app/config/config.go#L283

Added line #L283 was not covered by tests
} else {
kubeConfig, err = clientcmd.BuildConfigFromFlags(fmt.Sprintf("http://%s:%d", options.YurtHubProxyHost, options.YurtHubProxyPort), "")
}
Expand Down
83 changes: 80 additions & 3 deletions pkg/yurtadm/cmd/join/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import (
"fmt"
"io"
"os"
"strings"

"github.com/pkg/errors"
Expand All @@ -38,6 +39,7 @@
yurtconstants "github.com/openyurtio/openyurt/pkg/yurtadm/constants"
"github.com/openyurtio/openyurt/pkg/yurtadm/util/edgenode"
yurtadmutil "github.com/openyurtio/openyurt/pkg/yurtadm/util/kubernetes"
"github.com/openyurtio/openyurt/pkg/yurtadm/util/localnode"
"github.com/openyurtio/openyurt/pkg/yurtadm/util/yurthub"
"github.com/openyurtio/openyurt/pkg/yurtmanager/controller/yurtstaticset/util"
)
Expand All @@ -52,6 +54,8 @@
organizations string
pauseImage string
yurthubImage string
yurthubBinary string
hostControlPlaneAddr string // hostControlPlaneAddr is the address (ip:port) of host kubernetes cluster that used for yurthub local mode.
namespace string
caCertHashes []string
unsafeSkipCAVerification bool
Expand Down Expand Up @@ -124,7 +128,7 @@
)
flagSet.StringVar(
&joinOptions.nodeType, yurtconstants.NodeType, joinOptions.nodeType,
"Sets the node is edge or cloud",
"Sets the node is edge, cloud or local",
)
flagSet.StringVar(
&joinOptions.nodeName, yurtconstants.NodeName, joinOptions.nodeName,
Expand Down Expand Up @@ -154,6 +158,14 @@
&joinOptions.yurthubImage, yurtconstants.YurtHubImage, joinOptions.yurthubImage,
"Sets the image version of yurthub component",
)
flagSet.StringVar(
&joinOptions.yurthubBinary, yurtconstants.YurtHubBinary, joinOptions.yurthubBinary,
"Sets the binary path of yurthub, this is used for deploying local mode yurthub in systemd",
)
flagSet.StringVar(
&joinOptions.hostControlPlaneAddr, yurtconstants.HostControlPlaneAddr, joinOptions.hostControlPlaneAddr,
"Sets the address of hostControlPlaneAddr, which is the address (ip:port) of host kubernetes cluster that used for yurthub local mode",
)
flagSet.StringSliceVar(
&joinOptions.caCertHashes, yurtconstants.TokenDiscoveryCAHash, joinOptions.caCertHashes,
"For token-based discovery, validate that the root CA public key matches this hash (format: \"<type>:<value>\").",
Expand Down Expand Up @@ -227,6 +239,9 @@
organizations string
pauseImage string
yurthubImage string
yurthubBinary string
hostControlPlaneAddr string
tenantApiServerEndpoints string
yurthubTemplate string
yurthubManifest string
kubernetesVersion string
Expand Down Expand Up @@ -257,6 +272,25 @@
apiServerEndpoint = args[0]
}

if opt.nodeType == yurtconstants.LocalNode {
// in local mode, it is necessary to prepare yurthub binary file for deploying systemd yurthub.
if len(opt.yurthubBinary) == 0 {
return nil, errors.New("yurthub binary filepath is empty, so unable to run systemd yurthub in local mode.")

Check warning on line 278 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L277-L278

Added lines #L277 - L278 were not covered by tests
}
_, err := os.Stat(opt.yurthubBinary)
if err != nil {
if os.IsNotExist(err) {
return nil, errors.New("yurthub binary file does not exist.")

Check warning on line 283 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L280-L283

Added lines #L280 - L283 were not covered by tests
}
return nil, errors.Wrapf(err, "stat yurthub binary file %s fail", opt.yurthubBinary)

Check warning on line 285 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L285

Added line #L285 was not covered by tests
}

// in local mode, hostControlPlaneAddr is needed for systemd yurthub accessing host kubernetes cluster.
if len(opt.hostControlPlaneAddr) == 0 {
return nil, errors.New("host control plane address is empty, so unable to run systemd yurthub in local mode.")

Check warning on line 290 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L289-L290

Added lines #L289 - L290 were not covered by tests
}
}

if len(opt.token) == 0 {
return nil, errors.New("join token is empty, so unable to bootstrap worker node.")
}
Expand All @@ -265,8 +299,8 @@
return nil, errors.Errorf("the bootstrap token %s was not of the form %s", opt.token, yurtconstants.BootstrapTokenPattern)
}

if opt.nodeType != yurtconstants.EdgeNode && opt.nodeType != yurtconstants.CloudNode {
return nil, errors.Errorf("node type(%s) is invalid, only \"edge and cloud\" are supported", opt.nodeType)
if opt.nodeType != yurtconstants.EdgeNode && opt.nodeType != yurtconstants.CloudNode && opt.nodeType != yurtconstants.LocalNode {
return nil, errors.Errorf("node type(%s) is invalid, only \"edge, cloud and local\" are supported", opt.nodeType)

Check warning on line 303 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L303

Added line #L303 was not covered by tests
}

if opt.unsafeSkipCAVerification && len(opt.caCertHashes) != 0 {
Expand Down Expand Up @@ -298,6 +332,8 @@
ignorePreflightErrors: ignoreErrors,
pauseImage: opt.pauseImage,
yurthubImage: opt.yurthubImage,
yurthubBinary: opt.yurthubBinary,
hostControlPlaneAddr: opt.hostControlPlaneAddr,
yurthubServer: opt.yurthubServer,
caCertHashes: opt.caCertHashes,
organizations: opt.organizations,
Expand Down Expand Up @@ -327,13 +363,37 @@
}
}

// if the node type is local, before get tls bootstrap config, we need to deploy systemd yurthub for maintaining iptables rules
if opt.nodeType == yurtconstants.LocalNode {
// deploy systemd yurthub
if err := localnode.DeployYurthubInSystemd(data.HostControlPlaneAddr(), data.ServerAddr(), data.YurtHubBinary(), data.NodeRegistration().Name); err != nil {
klog.Errorf("could not deploy local yurthub in systemd, %v", err)
return nil, err

Check warning on line 371 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L369-L371

Added lines #L369 - L371 were not covered by tests
}

// check systemd yurthub is ready or not
if err := localnode.CheckYurthubStatus(); err != nil {
return nil, err

Check warning on line 376 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L375-L376

Added lines #L375 - L376 were not covered by tests
}
klog.V(1).Infof("systemd yurthub agent is ready")

Check warning on line 378 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L378

Added line #L378 was not covered by tests

tenantApiServerEndpoints, err := localnode.GetTenantApiServerEndpoints()
if err != nil {
klog.Errorf("could not get tenantApiServerEndpoints, %v", err)
return nil, err

Check warning on line 383 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L380-L383

Added lines #L380 - L383 were not covered by tests
}
data.tenantApiServerEndpoints = tenantApiServerEndpoints
klog.V(1).Infof("get tenantApiServerEndpoints: %s", tenantApiServerEndpoints)

Check warning on line 386 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L385-L386

Added lines #L385 - L386 were not covered by tests
}

// get tls bootstrap config
cfg, err := yurtadmutil.RetrieveBootstrapConfig(data)
if err != nil {
klog.Errorf("could not retrieve bootstrap config, %v", err)
return nil, err
}
data.tlsBootstrapCfg = cfg
klog.Infof("RetrieveBootstrapConfig: %#+v", *cfg)

Check warning on line 396 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L396

Added line #L396 was not covered by tests

// get kubernetes version
client, err := kubeconfigutil.ToClientSet(cfg)
Expand All @@ -342,6 +402,7 @@
return nil, err
}
data.clientSet = client
klog.Infof("ToClientSet: %#+v", *client)

Check warning on line 405 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L405

Added line #L405 was not covered by tests

k8sVersion, err := yurtadmutil.GetKubernetesVersionFromCluster(client)
if err != nil {
Expand All @@ -350,6 +411,9 @@
}
data.kubernetesVersion = k8sVersion

// test for get k8s version
klog.Infof("GetKubernetesVersionFromCluster: %s", k8sVersion)

Check warning on line 415 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L415

Added line #L415 was not covered by tests

// check whether specified nodePool exists
if len(opt.nodePoolName) != 0 {
np, err := apiclient.GetNodePoolInfoWithRetry(cfg, opt.nodePoolName)
Expand Down Expand Up @@ -439,6 +503,19 @@
return j.yurthubImage
}

// YurtHubBinary returns the YurtHub binary.
func (j *joinData) YurtHubBinary() string {
return j.yurthubBinary

Check warning on line 508 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L507-L508

Added lines #L507 - L508 were not covered by tests
}

func (j *joinData) HostControlPlaneAddr() string {
return j.hostControlPlaneAddr

Check warning on line 512 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L511-L512

Added lines #L511 - L512 were not covered by tests
}

func (j *joinData) TenantApiServerEndpoints() string {
return j.tenantApiServerEndpoints

Check warning on line 516 in pkg/yurtadm/cmd/join/join.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/join.go#L515-L516

Added lines #L515 - L516 were not covered by tests
}

// YurtHubServer returns the YurtHub server addr.
func (j *joinData) YurtHubServer() string {
return j.yurthubServer
Expand Down
3 changes: 3 additions & 0 deletions pkg/yurtadm/cmd/join/joindata/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ type YurtJoinData interface {
JoinToken() string
PauseImage() string
YurtHubImage() string
YurtHubBinary() string
HostControlPlaneAddr() string
TenantApiServerEndpoints() string
YurtHubServer() string
YurtHubTemplate() string
YurtHubManifest() string
Expand Down
19 changes: 12 additions & 7 deletions pkg/yurtadm/cmd/join/phases/postcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"k8s.io/klog/v2"

"github.com/openyurtio/openyurt/pkg/yurtadm/cmd/join/joindata"
"github.com/openyurtio/openyurt/pkg/yurtadm/constants"
"github.com/openyurtio/openyurt/pkg/yurtadm/util/kubernetes"
"github.com/openyurtio/openyurt/pkg/yurtadm/util/yurthub"
)
Expand All @@ -33,15 +34,19 @@
klog.V(1).Infof("kubelet service is active")

klog.V(1).Infof("waiting hub agent ready.")
if err := yurthub.CheckYurthubHealthz(data.YurtHubServer()); err != nil {
return err
}
klog.V(1).Infof("hub agent is ready")

if err := yurthub.CleanHubBootstrapConfig(); err != nil {
return err
// check staticpod yurthub for edge node and cloud node
if data.NodeRegistration().WorkingMode != constants.LocalNode {
if err := yurthub.CheckYurthubHealthz(data.YurtHubServer()); err != nil {
return err

Check warning on line 41 in pkg/yurtadm/cmd/join/phases/postcheck.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/postcheck.go#L39-L41

Added lines #L39 - L41 were not covered by tests
}
klog.V(1).Infof("staticpod yurthub agent is ready")

Check warning on line 43 in pkg/yurtadm/cmd/join/phases/postcheck.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/postcheck.go#L43

Added line #L43 was not covered by tests

if err := yurthub.CleanHubBootstrapConfig(); err != nil {
return err

Check warning on line 46 in pkg/yurtadm/cmd/join/phases/postcheck.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/postcheck.go#L45-L46

Added lines #L45 - L46 were not covered by tests
}
klog.V(1).Infof("clean yurthub bootstrap config file success")

Check warning on line 48 in pkg/yurtadm/cmd/join/phases/postcheck.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/postcheck.go#L48

Added line #L48 was not covered by tests
}
klog.V(1).Infof("clean yurthub bootstrap config file success")

return nil
}
32 changes: 17 additions & 15 deletions pkg/yurtadm/cmd/join/phases/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,25 @@
if err := yurtadmutil.SetKubeletUnitConfig(); err != nil {
return err
}
if err := yurtadmutil.SetKubeletConfigForNode(); err != nil {
return err
}
if err := yurthub.SetHubBootstrapConfig(data.ServerAddr(), data.JoinToken(), data.CaCertHashes()); err != nil {
return err
}
if err := yurthub.AddYurthubStaticYaml(data, constants.StaticPodPath); err != nil {
return err
}
if len(data.StaticPodTemplateList()) != 0 {
// deploy user specified static pods
if err := edgenode.DeployStaticYaml(data.StaticPodManifestList(), data.StaticPodTemplateList(), constants.StaticPodPath); err != nil {
if data.NodeRegistration().WorkingMode != constants.LocalNode {
if err := yurtadmutil.SetKubeletConfigForNode(); err != nil {
return err

Check warning on line 70 in pkg/yurtadm/cmd/join/phases/prepare.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/prepare.go#L68-L70

Added lines #L68 - L70 were not covered by tests
}
if err := yurthub.SetHubBootstrapConfig(data.ServerAddr(), data.JoinToken(), data.CaCertHashes()); err != nil {
return err

Check warning on line 73 in pkg/yurtadm/cmd/join/phases/prepare.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/prepare.go#L72-L73

Added lines #L72 - L73 were not covered by tests
}
if err := yurthub.AddYurthubStaticYaml(data, constants.StaticPodPath); err != nil {
return err

Check warning on line 76 in pkg/yurtadm/cmd/join/phases/prepare.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/prepare.go#L75-L76

Added lines #L75 - L76 were not covered by tests
}
if len(data.StaticPodTemplateList()) != 0 {

Check warning on line 78 in pkg/yurtadm/cmd/join/phases/prepare.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/prepare.go#L78

Added line #L78 was not covered by tests
// deploy user specified static pods
if err := edgenode.DeployStaticYaml(data.StaticPodManifestList(), data.StaticPodTemplateList(), constants.StaticPodPath); err != nil {
return err

Check warning on line 81 in pkg/yurtadm/cmd/join/phases/prepare.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/prepare.go#L80-L81

Added lines #L80 - L81 were not covered by tests
}
}
if err := yurtadmutil.SetDiscoveryConfig(data); err != nil {

Check warning on line 84 in pkg/yurtadm/cmd/join/phases/prepare.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/cmd/join/phases/prepare.go#L84

Added line #L84 was not covered by tests
return err
}
}
if err := yurtadmutil.SetDiscoveryConfig(data); err != nil {
return err
}
if data.CfgPath() == "" {
if err := yurtadmutil.SetKubeadmJoinConfig(data); err != nil {
Expand Down
23 changes: 23 additions & 0 deletions pkg/yurtadm/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const (
PauseImagePath = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2"
DefaultCertificatesDir = "/etc/kubernetes/pki"
DefaultDockerCRISocket = "/var/run/dockershim.sock"
YurthubServiceFilepath = "/etc/systemd/system/yurthub.service"
YurthubEnvironmentFilePath = "/etc/systemd/system/yurthub.default"
YurthubYamlName = "yurthub.yaml"
YurthubStaticPodManifest = "yurthub"
YurthubNamespace = "kube-system"
Expand Down Expand Up @@ -72,6 +74,7 @@ const (

EdgeNode = "edge"
CloudNode = "cloud"
LocalNode = "local"

// CertificatesDir
CertificatesDir = "cert-dir"
Expand Down Expand Up @@ -107,6 +110,10 @@ const (
Namespace = "namespace"
// YurtHubImage flag sets the yurthub image for worker node.
YurtHubImage = "yurthub-image"
// YurtHubBinary flag sets the yurthub Binary for worker node.
YurtHubBinary = "yurthub-binary"
// HostControlPlaneAddr flag sets the address of host kubernetes cluster
HostControlPlaneAddr = "host-control-plane-addr"
// YurtHubServerAddr flag set the address of yurthub server (not proxy server!)
YurtHubServerAddr = "yurthub-server-addr"
// ServerAddr flag set the address of kubernetes kube-apiserver
Expand Down Expand Up @@ -272,5 +279,21 @@ spec:
hostNetwork: true
priorityClassName: system-node-critical
priority: 2000001000
`

YurthubSyetmdServiceContent = `
[Unit]
Description=local mode yurthub is deployed in systemd
Documentation=https://github.com/openyurtio/openyurt/pull/2124

[Service]
EnvironmentFile=/etc/systemd/system/yurthub.default
ExecStart=/usr/bin/yurthub --working-mode ${WORKINGMODE} --node-name ${NODENAME} --server-addr ${SERVERADDR} --host-control-plane-address ${HOSTCONTROLPLANEADDRESS}
Restart=always
StartLimitInterval=0
RestartSec=10

[Install]
WantedBy=multi-user.target
`
)
3 changes: 3 additions & 0 deletions pkg/yurtadm/util/initsystem/initsystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ type InitSystem interface {

// ServiceIsActive ensures the service is running, or attempting to run. (crash looping in the case of kubelet)
ServiceIsActive(service string) bool

// ServiceToStart tries to start a specific service
ServiceStart(service string) error
}
16 changes: 16 additions & 0 deletions pkg/yurtadm/util/initsystem/initsystem_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@
return !strings.Contains(outStr, "stopped") && !strings.Contains(outStr, "does not exist")
}

// ServiceStart tries to start a specific service
func (openrc OpenRCInitSystem) ServiceStart(service string) error {
args := []string{service, "start"}
return exec.Command("rc-service", args...).Run()

Check warning on line 58 in pkg/yurtadm/util/initsystem/initsystem_unix.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/util/initsystem/initsystem_unix.go#L56-L58

Added lines #L56 - L58 were not covered by tests
}

// SystemdInitSystem defines systemd
type SystemdInitSystem struct{}

Expand Down Expand Up @@ -94,6 +100,16 @@
return false
}

// ServiceStart tries to start a specific service
func (sysd SystemdInitSystem) ServiceStart(service string) error {

Check warning on line 104 in pkg/yurtadm/util/initsystem/initsystem_unix.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/util/initsystem/initsystem_unix.go#L104

Added line #L104 was not covered by tests
// Before we try to start any service, make sure that systemd is ready
if err := sysd.reloadSystemd(); err != nil {
return err

Check warning on line 107 in pkg/yurtadm/util/initsystem/initsystem_unix.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/util/initsystem/initsystem_unix.go#L106-L107

Added lines #L106 - L107 were not covered by tests
}
args := []string{"start", service}
return exec.Command("systemctl", args...).Run()

Check warning on line 110 in pkg/yurtadm/util/initsystem/initsystem_unix.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtadm/util/initsystem/initsystem_unix.go#L109-L110

Added lines #L109 - L110 were not covered by tests
}

// GetInitSystem returns an InitSystem for the current system, or nil
// if we cannot detect a supported init system.
// This indicates we will skip init system checks, not an error.
Expand Down
Loading
Loading