diff --git a/pkg/rkecerts/certs.go b/pkg/rkecerts/certs.go
index f19a02d59fc1a2ec8af6ed5b3ccfbc9045195bad..0df4655465f2e55db6d3c487950993f7b0552bdb 100644
--- a/pkg/rkecerts/certs.go
+++ b/pkg/rkecerts/certs.go
@@ -2,8 +2,10 @@ package rkecerts
 
 import (
 	"bytes"
+	"crypto/md5"
 	"crypto/rsa"
 	"crypto/x509"
+	"fmt"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -15,6 +17,7 @@ import (
 	"github.com/rancher/rancher/pkg/librke"
 	"github.com/rancher/rke/pki"
 	"github.com/rancher/types/apis/management.cattle.io/v3"
+	"github.com/sirupsen/logrus"
 	"k8s.io/client-go/util/cert"
 )
 
@@ -153,3 +156,24 @@ func (f *fileWriter) write(path string, content []byte, x509cert *x509.Certifica
 func (f *fileWriter) err() error {
 	return types.NewErrors(f.errs...)
 }
+
+func (b *Bundle) Changed() bool {
+	var newCertPEM string
+	for _, item := range b.certs {
+		oldCertPEM, err := ioutil.ReadFile(item.Path)
+		if err != nil {
+			logrus.Warnf("Unable to read certificate %s: %v", item.Name, err)
+			return false
+		}
+		if item.Certificate != nil {
+			newCertPEM = string(cert.EncodeCertPEM(item.Certificate))
+		}
+		oldCertChecksum := fmt.Sprintf("%x", md5.Sum([]byte(oldCertPEM)))
+		newCertChecksum := fmt.Sprintf("%x", md5.Sum([]byte(newCertPEM)))
+
+		if oldCertChecksum != newCertChecksum {
+			return true
+		}
+	}
+	return false
+}
diff --git a/pkg/rkeworker/docker.go b/pkg/rkeworker/docker.go
index 304b7fc8d735d8c25a01675c0e2c21710d38575f..6c04e20b5393aafc854757ef6a3f396ee1de05ea 100644
--- a/pkg/rkeworker/docker.go
+++ b/pkg/rkeworker/docker.go
@@ -6,6 +6,7 @@ import (
 	"os"
 	"reflect"
 	"strings"
+	"time"
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
@@ -27,7 +28,7 @@ type NodeConfig struct {
 	Files       []v3.File             `json:"files"`
 }
 
-func runProcess(ctx context.Context, name string, p v3.Process, start bool) error {
+func runProcess(ctx context.Context, name string, p v3.Process, start bool, forceRestart bool) error {
 	c, err := client.NewEnvClient()
 	if err != nil {
 		return err
@@ -69,6 +70,11 @@ func runProcess(ctx context.Context, name string, p v3.Process, start bool) erro
 			}
 		} else {
 			matchedContainers = append(matchedContainers, container)
+			if forceRestart {
+				if err := restart(ctx, c, container.ID); err != nil {
+					return err
+				}
+			}
 		}
 	}
 
@@ -222,3 +228,8 @@ func sliceToMap(args []string) map[string]bool {
 	}
 	return result
 }
+
+func restart(ctx context.Context, c *client.Client, id string) error {
+	timeoutDuration := 10 * time.Second
+	return c.ContainerRestart(ctx, id, &timeoutDuration)
+}
diff --git a/pkg/rkeworker/execute.go b/pkg/rkeworker/execute.go
index 967a16b91c8f0f65c68235cc91731f05836d8b1d..20dda9070a6b032d3e5224fce2a11a533a3205c9 100644
--- a/pkg/rkeworker/execute.go
+++ b/pkg/rkeworker/execute.go
@@ -14,12 +14,14 @@ import (
 )
 
 func ExecutePlan(ctx context.Context, nodeConfig *NodeConfig, writeCertOnly bool) error {
+	var bundleChanged bool
 	if nodeConfig.Certs != "" {
 		bundle, err := rkecerts.Unmarshal(nodeConfig.Certs)
 		if err != nil {
 			return err
 		}
 
+		bundleChanged = bundle.Changed()
 		if err := bundle.Explode(); err != nil {
 			return err
 		}
@@ -35,7 +37,7 @@ func ExecutePlan(ctx context.Context, nodeConfig *NodeConfig, writeCertOnly bool
 
 	for name, process := range nodeConfig.Processes {
 		if strings.Contains(name, "sidekick") || strings.Contains(name, "share-mnt") {
-			if err := runProcess(ctx, name, process, false); err != nil {
+			if err := runProcess(ctx, name, process, false, false); err != nil {
 				return err
 			}
 		}
@@ -43,7 +45,7 @@ func ExecutePlan(ctx context.Context, nodeConfig *NodeConfig, writeCertOnly bool
 
 	for name, process := range nodeConfig.Processes {
 		if !strings.Contains(name, "sidekick") {
-			if err := runProcess(ctx, name, process, true); err != nil {
+			if err := runProcess(ctx, name, process, true, bundleChanged); err != nil {
 				return err
 			}
 		}