fix: use image digest when starting a container
First of all, it seems to be "right way", as it makes sure the image is looked up by the digest. Second, it fixes the case when image is specified with both tag and digest (which is not supposed to be the correct ref, but it is used frequently). Talos since 1.5.0 stores images with the following aliases: ``` gcr.io/etcd-development/etcd:v3.5.9 gcr.io/etcd-development/etcd@sha256:8c956d9b0d39745fa574bb4dbacd362ffdc1109479432f54094859d4cf984b17 ghcr.io/siderolabs/kubelet:v1.28.0 ghcr.io/siderolabs/kubelet@sha256:50710f2cd3328c23f57dfc7fb00940d8cfd402315e33fc7cb8184fc660650a5c sha256:50710f2cd3328c23f57dfc7fb00940d8cfd402315e33fc7cb8184fc660650a5c sha256:8c956d9b0d39745fa574bb4dbacd362ffdc1109479432f54094859d4cf984b17 ``` This change pulls the digest format (the last in this list) and uses it to start a container. Fixes #7640 Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
This commit is contained in:
parent
175747cea5
commit
574d48e540
@ -67,6 +67,8 @@ type Etcd struct {
|
||||
args []string
|
||||
client *etcd.Client
|
||||
|
||||
imgRef string
|
||||
|
||||
// if the new member was added as a learner during the service start, its ID is kept here
|
||||
learnerMemberID uint64
|
||||
|
||||
@ -81,18 +83,18 @@ func (e *Etcd) ID(r runtime.Runtime) string {
|
||||
// PreFunc implements the Service interface.
|
||||
//
|
||||
//nolint:gocyclo
|
||||
func (e *Etcd) PreFunc(ctx context.Context, r runtime.Runtime) (err error) {
|
||||
if err = os.MkdirAll(constants.EtcdDataPath, 0o700); err != nil {
|
||||
func (e *Etcd) PreFunc(ctx context.Context, r runtime.Runtime) error {
|
||||
if err := os.MkdirAll(constants.EtcdDataPath, 0o700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Data path might exist after upgrade from previous version of Talos.
|
||||
if err = os.Chmod(constants.EtcdDataPath, 0o700); err != nil {
|
||||
if err := os.Chmod(constants.EtcdDataPath, 0o700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Make sure etcd user can access files in the data directory.
|
||||
if err = filetree.ChownRecursive(constants.EtcdDataPath, constants.EtcdUserID, constants.EtcdUserID); err != nil {
|
||||
if err := filetree.ChownRecursive(constants.EtcdDataPath, constants.EtcdUserID, constants.EtcdUserID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -106,11 +108,13 @@ func (e *Etcd) PreFunc(ctx context.Context, r runtime.Runtime) (err error) {
|
||||
// Pull the image and unpack it.
|
||||
containerdctx := namespaces.WithNamespace(ctx, constants.SystemContainerdNamespace)
|
||||
|
||||
_, err = image.Pull(containerdctx, r.Config().Machine().Registries(), client, r.Config().Cluster().Etcd().Image(), image.WithSkipIfAlreadyPulled())
|
||||
img, err := image.Pull(containerdctx, r.Config().Machine().Registries(), client, r.Config().Cluster().Etcd().Image(), image.WithSkipIfAlreadyPulled())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to pull image %q: %w", r.Config().Cluster().Etcd().Image(), err)
|
||||
}
|
||||
|
||||
e.imgRef = img.Target().Digest.String()
|
||||
|
||||
// Clear any previously set learner member ID
|
||||
e.learnerMemberID = 0
|
||||
|
||||
@ -213,7 +217,7 @@ func (e *Etcd) Runner(r runtime.Runtime) (runner.Runner, error) {
|
||||
&args,
|
||||
runner.WithLoggingManager(r.Logging()),
|
||||
runner.WithNamespace(constants.SystemContainerdNamespace),
|
||||
runner.WithContainerImage(r.Config().Cluster().Etcd().Image()),
|
||||
runner.WithContainerImage(e.imgRef),
|
||||
runner.WithEnv(env),
|
||||
runner.WithOCISpecOpts(
|
||||
oci.WithDroppedCapabilities(cap.Known()),
|
||||
|
@ -40,7 +40,9 @@ var _ system.HealthcheckedService = (*Kubelet)(nil)
|
||||
|
||||
// Kubelet implements the Service interface. It serves as the concrete type with
|
||||
// the required methods.
|
||||
type Kubelet struct{}
|
||||
type Kubelet struct {
|
||||
imgRef string
|
||||
}
|
||||
|
||||
// ID implements the Service interface.
|
||||
func (k *Kubelet) ID(r runtime.Runtime) string {
|
||||
@ -66,11 +68,13 @@ func (k *Kubelet) PreFunc(ctx context.Context, r runtime.Runtime) error {
|
||||
// Pull the image and unpack it.
|
||||
containerdctx := namespaces.WithNamespace(ctx, constants.SystemContainerdNamespace)
|
||||
|
||||
_, err = image.Pull(containerdctx, r.Config().Machine().Registries(), client, spec.Image, image.WithSkipIfAlreadyPulled())
|
||||
img, err := image.Pull(containerdctx, r.Config().Machine().Registries(), client, spec.Image, image.WithSkipIfAlreadyPulled())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
k.imgRef = img.Target().Digest.String()
|
||||
|
||||
// Create lifecycle resource to signal that the kubelet is about to start.
|
||||
err = r.State().V1Alpha2().Resources().Create(ctx, k8s.NewKubeletLifecycle(k8s.NamespaceName, k8s.KubeletLifecycleID))
|
||||
if err != nil && !state.IsConflictError(err) { // ignore if the lifecycle resource already exists
|
||||
@ -148,7 +152,7 @@ func (k *Kubelet) Runner(r runtime.Runtime) (runner.Runner, error) {
|
||||
&args,
|
||||
runner.WithLoggingManager(r.Logging()),
|
||||
runner.WithNamespace(constants.SystemContainerdNamespace),
|
||||
runner.WithContainerImage(spec.Image),
|
||||
runner.WithContainerImage(k.imgRef),
|
||||
runner.WithEnv(environment.Get(r.Config())),
|
||||
runner.WithOCISpecOpts(
|
||||
containerd.WithRootfsPropagation("shared"),
|
||||
|
Loading…
Reference in New Issue
Block a user