mirror of
https://github.com/siderolabs/talos.git
synced 2025-11-02 01:11:11 +01:00
fix: derive machine-id from node identity
Fixes #4759 This uses existing features: Talos always generates 32 bytes random node identity, we use first 16 bytes of that to generate `machine-id` in compliant format and mount that into the `kubelet` container. Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
This commit is contained in:
parent
d8a2721e12
commit
2e735714d9
@ -377,9 +377,7 @@ COPY ./hack/cleanup.sh /toolchain/bin/cleanup.sh
|
||||
RUN cleanup.sh /rootfs
|
||||
COPY --chmod=0644 hack/containerd.toml /rootfs/etc/containerd/config.toml
|
||||
COPY --chmod=0644 hack/cri-containerd.toml /rootfs/etc/cri/containerd.toml
|
||||
RUN touch /rootfs/etc/resolv.conf
|
||||
RUN touch /rootfs/etc/hosts
|
||||
RUN touch /rootfs/etc/os-release
|
||||
RUN touch /rootfs/etc/{resolv.conf,hosts,os-release,machine-id}
|
||||
RUN mkdir -pv /rootfs/{boot,usr/local/share,mnt,system,opt}
|
||||
RUN mkdir -pv /rootfs/{etc/kubernetes/manifests,etc/cni/net.d,usr/libexec/kubernetes}
|
||||
RUN mkdir -pv /rootfs/opt/{containerd/bin,containerd/lib}
|
||||
@ -421,9 +419,7 @@ COPY ./hack/cleanup.sh /toolchain/bin/cleanup.sh
|
||||
RUN cleanup.sh /rootfs
|
||||
COPY --chmod=0644 hack/containerd.toml /rootfs/etc/containerd/containerd.toml
|
||||
COPY --chmod=0644 hack/cri-containerd.toml /rootfs/etc/cri/containerd.toml
|
||||
RUN touch /rootfs/etc/resolv.conf
|
||||
RUN touch /rootfs/etc/hosts
|
||||
RUN touch /rootfs/etc/os-release
|
||||
RUN touch /rootfs/etc/{resolv.conf,hosts,os-release,machine-id}
|
||||
RUN mkdir -pv /rootfs/{boot,usr/local/share,mnt,system,opt}
|
||||
RUN mkdir -pv /rootfs/{etc/kubernetes/manifests,etc/cni/net.d,usr/libexec/kubernetes}
|
||||
RUN mkdir -pv /rootfs/opt/{containerd/bin,containerd/lib}
|
||||
|
||||
@ -6,6 +6,7 @@ package cluster
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
|
||||
"github.com/jxskiss/base62"
|
||||
@ -39,3 +40,16 @@ func (a identity) Generate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ConvertMachineID returns /etc/machine-id compatible representation.
|
||||
func (a identity) ConvertMachineID() ([]byte, error) {
|
||||
raw, err := base62.DecodeString(a.IdentitySpec.NodeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := make([]byte, 32)
|
||||
hex.Encode(buf, raw[:16])
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
@ -27,3 +27,14 @@ func TestIdentityGenerate(t *testing.T) {
|
||||
assert.GreaterOrEqual(t, length, 43)
|
||||
assert.LessOrEqual(t, length, 44)
|
||||
}
|
||||
|
||||
func TestIdentityConvertMachineID(t *testing.T) {
|
||||
spec := cluster.IdentitySpec{
|
||||
NodeID: "sou7yy34ykX3n373Zw1DXKb8zD7UnyKT6HT3QDsGH6L",
|
||||
}
|
||||
|
||||
machineID, err := clusteradapter.IdentitySpec(&spec).ConvertMachineID()
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "be871ac0d0dd31fa4caca753b0f3f1b2", string(machineID))
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import (
|
||||
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
|
||||
"github.com/talos-systems/talos/pkg/machinery/constants"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/cluster"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/files"
|
||||
runtimeres "github.com/talos-systems/talos/pkg/machinery/resources/runtime"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/v1alpha1"
|
||||
)
|
||||
@ -56,6 +57,10 @@ func (ctrl *NodeIdentityController) Outputs() []controller.Output {
|
||||
Type: cluster.IdentityType,
|
||||
Kind: controller.OutputShared,
|
||||
},
|
||||
{
|
||||
Type: files.EtcFileSpecType,
|
||||
Kind: controller.OutputShared,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,6 +107,19 @@ func (ctrl *NodeIdentityController) Run(ctx context.Context, r controller.Runtim
|
||||
return fmt.Errorf("error modifying resource: %w", err)
|
||||
}
|
||||
|
||||
// generate `/etc/machine-id` from node identity
|
||||
if err := r.Modify(ctx, files.NewEtcFileSpec(files.NamespaceName, "machine-id"),
|
||||
func(r resource.Resource) error {
|
||||
var err error
|
||||
|
||||
r.(*files.EtcFileSpec).TypedSpec().Contents, err = clusteradapter.IdentitySpec(&localIdentity).ConvertMachineID()
|
||||
r.(*files.EtcFileSpec).TypedSpec().Mode = 0o444
|
||||
|
||||
return err
|
||||
}); err != nil {
|
||||
return fmt.Errorf("error modifying resolv.conf: %w", err)
|
||||
}
|
||||
|
||||
if !ctrl.identityEstablished {
|
||||
logger.Info("node identity established", zap.String("node_id", localIdentity.NodeID))
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ import (
|
||||
v1alpha1runtime "github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
|
||||
"github.com/talos-systems/talos/pkg/machinery/constants"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/cluster"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/files"
|
||||
runtimeres "github.com/talos-systems/talos/pkg/machinery/resources/runtime"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/v1alpha1"
|
||||
)
|
||||
@ -68,6 +69,12 @@ func (suite *NodeIdentitySuite) TestDefault() {
|
||||
return nil
|
||||
}),
|
||||
))
|
||||
|
||||
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
|
||||
suite.assertResource(*files.NewEtcFileSpec(files.NamespaceName, "machine-id").Metadata(), func(_ resource.Resource) error {
|
||||
return nil
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
func (suite *NodeIdentitySuite) TestLoad() {
|
||||
@ -93,6 +100,14 @@ func (suite *NodeIdentitySuite) TestLoad() {
|
||||
return nil
|
||||
}),
|
||||
))
|
||||
|
||||
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
|
||||
suite.assertResource(*files.NewEtcFileSpec(files.NamespaceName, "machine-id").Metadata(), func(r resource.Resource) error {
|
||||
suite.Assert().Equal("8d2c0de2408fa2a178bad7f45d9aa8fb", string(r.(*files.EtcFileSpec).TypedSpec().Contents))
|
||||
|
||||
return nil
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
func TestNodeIdentitySuite(t *testing.T) {
|
||||
|
||||
@ -26,6 +26,7 @@ import (
|
||||
"github.com/talos-systems/talos/internal/app/machined/pkg/system"
|
||||
"github.com/talos-systems/talos/internal/app/machined/pkg/system/services"
|
||||
"github.com/talos-systems/talos/pkg/machinery/constants"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/files"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/k8s"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/secrets"
|
||||
"github.com/talos-systems/talos/pkg/machinery/resources/v1alpha1"
|
||||
@ -63,7 +64,7 @@ func (ctrl *KubeletServiceController) Outputs() []controller.Output {
|
||||
//
|
||||
//nolint:gocyclo,cyclop
|
||||
func (ctrl *KubeletServiceController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
|
||||
// initially, wait for the cri to be up
|
||||
// initially, wait for the cri to be up and for machine-id to be generated
|
||||
if err := r.UpdateInputs([]controller.Input{
|
||||
{
|
||||
Namespace: v1alpha1.NamespaceName,
|
||||
@ -71,6 +72,12 @@ func (ctrl *KubeletServiceController) Run(ctx context.Context, r controller.Runt
|
||||
ID: pointer.ToString("cri"),
|
||||
Kind: controller.InputWeak,
|
||||
},
|
||||
{
|
||||
Namespace: files.NamespaceName,
|
||||
Type: files.EtcFileStatusType,
|
||||
ID: pointer.ToString("machine-id"),
|
||||
Kind: controller.InputWeak,
|
||||
},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -82,6 +89,15 @@ func (ctrl *KubeletServiceController) Run(ctx context.Context, r controller.Runt
|
||||
case <-r.EventCh():
|
||||
}
|
||||
|
||||
_, err := r.Get(ctx, resource.NewMetadata(files.NamespaceName, files.EtcFileStatusType, "machine-id", resource.VersionUndefined))
|
||||
if err != nil {
|
||||
if state.IsNotFoundError(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
return fmt.Errorf("error getting etc file status: %w", err)
|
||||
}
|
||||
|
||||
svc, err := r.Get(ctx, resource.NewMetadata(v1alpha1.NamespaceName, v1alpha1.ServiceType, "cri", resource.VersionUndefined))
|
||||
if err != nil {
|
||||
if state.IsNotFoundError(err) {
|
||||
|
||||
@ -108,6 +108,7 @@ func (k *Kubelet) Runner(r runtime.Runtime) (runner.Runner, error) {
|
||||
{Type: "bind", Destination: constants.CgroupMountPath, Source: constants.CgroupMountPath, Options: []string{"rbind", "rshared", "rw"}},
|
||||
{Type: "bind", Destination: "/lib/modules", Source: "/lib/modules", Options: []string{"bind", "ro"}},
|
||||
{Type: "bind", Destination: "/etc/kubernetes", Source: "/etc/kubernetes", Options: []string{"bind", "rshared", "rw"}},
|
||||
{Type: "bind", Destination: "/etc/machine-id", Source: "/etc/machine-id", Options: []string{"bind", "ro"}},
|
||||
{Type: "bind", Destination: "/etc/os-release", Source: "/etc/os-release", Options: []string{"bind", "ro"}},
|
||||
{Type: "bind", Destination: "/etc/cni", Source: "/etc/cni", Options: []string{"rbind", "rshared", "rw"}},
|
||||
{Type: "bind", Destination: "/usr/libexec/kubernetes", Source: "/usr/libexec/kubernetes", Options: []string{"rbind", "rshared", "rw"}},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user