Skip to content

Commit 1310d7d

Browse files
author
priyawadhwa
authored
Merge pull request #1466 from garethjevans/docker-creds
feat(docker creds) can mount docker config into kaniko pod
2 parents 753d516 + cfb38b9 commit 1310d7d

File tree

9 files changed

+147
-15
lines changed

9 files changed

+147
-15
lines changed

examples/annotated-skaffold.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ build:
140140
# namespace: default
141141
# timeout: 20m
142142
# image: defaults to the latest released version of `gcr.io/kaniko-project/executor`
143+
# dockerConfig:
144+
# path: path to the docker config.json
145+
# secretName: docker-cfg
143146

144147
# The deploy section has all the information needed to deploy. Along with build:
145148
# it is a required section.

integration/examples/annotated-skaffold.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ build:
140140
# namespace: default
141141
# timeout: 20m
142142
# image: defaults to the latest released version of `gcr.io/kaniko-project/executor`
143+
# dockerConfig:
144+
# path: path to the docker config.json
145+
# secretName: docker-cfg
143146

144147
# The deploy section has all the information needed to deploy. Along with build:
145148
# it is a required section.

pkg/skaffold/build/kaniko/kaniko.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,19 @@ import (
2929

3030
// Build builds a list of artifacts with Kaniko.
3131
func (b *Builder) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*latest.Artifact) ([]build.Artifact, error) {
32-
teardown, err := b.setupSecret(out)
32+
teardownPullSecret, err := b.setupPullSecret(out)
3333
if err != nil {
34-
return nil, errors.Wrap(err, "setting up secret")
34+
return nil, errors.Wrap(err, "setting up pull secret")
35+
}
36+
defer teardownPullSecret()
37+
38+
if b.DockerConfig != nil {
39+
teardownDockerConfigSecret, err := b.setupDockerConfigSecret(out)
40+
if err != nil {
41+
return nil, errors.Wrap(err, "setting up docker config secret")
42+
}
43+
defer teardownDockerConfigSecret()
3544
}
36-
defer teardown()
3745

3846
return build.InParallel(ctx, out, tagger, artifacts, b.buildArtifactWithKaniko)
3947
}

pkg/skaffold/build/kaniko/secret.go

+54-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3030
)
3131

32-
func (b *Builder) setupSecret(out io.Writer) (func(), error) {
32+
func (b *Builder) setupPullSecret(out io.Writer) (func(), error) {
3333
color.Default.Fprintf(out, "Creating kaniko secret [%s]...\n", b.PullSecretName)
3434

3535
client, err := kubernetes.GetClientset()
@@ -51,7 +51,7 @@ func (b *Builder) setupSecret(out io.Writer) (func(), error) {
5151

5252
secretData, err := ioutil.ReadFile(b.PullSecret)
5353
if err != nil {
54-
return nil, errors.Wrap(err, "reading secret")
54+
return nil, errors.Wrap(err, "reading pull secret")
5555
}
5656

5757
secret := &v1.Secret{
@@ -65,12 +65,62 @@ func (b *Builder) setupSecret(out io.Writer) (func(), error) {
6565
}
6666

6767
if _, err := secrets.Create(secret); err != nil {
68-
return nil, errors.Wrapf(err, "creating secret: %s", err)
68+
return nil, errors.Wrapf(err, "creating pull secret: %s", err)
6969
}
7070

7171
return func() {
7272
if err := secrets.Delete(b.PullSecretName, &metav1.DeleteOptions{}); err != nil {
73-
logrus.Warnf("deleting secret")
73+
logrus.Warnf("deleting pull secret")
74+
}
75+
}, nil
76+
}
77+
78+
func (b *Builder) setupDockerConfigSecret(out io.Writer) (func(), error) {
79+
if b.DockerConfig == nil {
80+
return func() {}, nil
81+
}
82+
83+
color.Default.Fprintf(out, "Creating docker config secret [%s]...\n", b.DockerConfig.SecretName)
84+
85+
client, err := kubernetes.GetClientset()
86+
if err != nil {
87+
return nil, errors.Wrap(err, "getting kubernetes client")
88+
}
89+
90+
secrets := client.CoreV1().Secrets(b.Namespace)
91+
92+
if b.DockerConfig.Path == "" {
93+
logrus.Debug("No docker config specified. Checking for one in the cluster.")
94+
95+
if _, err := secrets.Get(b.DockerConfig.SecretName, metav1.GetOptions{}); err != nil {
96+
return nil, errors.Wrap(err, "checking for existing kaniko secret")
97+
}
98+
99+
return func() {}, nil
100+
}
101+
102+
secretData, err := ioutil.ReadFile(b.DockerConfig.Path)
103+
if err != nil {
104+
return nil, errors.Wrap(err, "reading docker config")
105+
}
106+
107+
secret := &v1.Secret{
108+
ObjectMeta: metav1.ObjectMeta{
109+
Name: b.DockerConfig.SecretName,
110+
Labels: map[string]string{"skaffold-kaniko": "skaffold-kaniko"},
111+
},
112+
Data: map[string][]byte{
113+
"config.json": secretData,
114+
},
115+
}
116+
117+
if _, err := secrets.Create(secret); err != nil {
118+
return nil, errors.Wrapf(err, "creating docker config secret: %s", err)
119+
}
120+
121+
return func() {
122+
if err := secrets.Delete(b.DockerConfig.SecretName, &metav1.DeleteOptions{}); err != nil {
123+
logrus.Warnf("deleting docker config secret")
74124
}
75125
}, nil
76126
}

pkg/skaffold/build/kaniko/sources/sources.go

+27-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func Retrieve(cfg *latest.KanikoBuild) BuildContextSource {
4848
}
4949

5050
func podTemplate(cfg *latest.KanikoBuild, args []string) *v1.Pod {
51-
return &v1.Pod{
51+
pod := &v1.Pod{
5252
ObjectMeta: metav1.ObjectMeta{
5353
GenerateName: "kaniko-",
5454
Labels: map[string]string{"skaffold-kaniko": "skaffold-kaniko"},
@@ -81,7 +81,32 @@ func podTemplate(cfg *latest.KanikoBuild, args []string) *v1.Pod {
8181
SecretName: cfg.PullSecretName,
8282
},
8383
},
84-
}},
84+
},
85+
},
8586
},
8687
}
88+
89+
if cfg.DockerConfig == nil {
90+
return pod
91+
}
92+
93+
volumeMount := v1.VolumeMount{
94+
Name: constants.DefaultKanikoDockerConfigSecretName,
95+
MountPath: constants.DefaultKanikoDockerConfigPath,
96+
}
97+
98+
pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, volumeMount)
99+
100+
volume := v1.Volume{
101+
Name: constants.DefaultKanikoDockerConfigSecretName,
102+
VolumeSource: v1.VolumeSource{
103+
Secret: &v1.SecretVolumeSource{
104+
SecretName: cfg.DockerConfig.SecretName,
105+
},
106+
},
107+
}
108+
109+
pod.Spec.Volumes = append(pod.Spec.Volumes, volume)
110+
111+
return pod
87112
}

pkg/skaffold/constants/constants.go

+8-6
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ const (
4747

4848
DefaultKustomizationPath = "."
4949

50-
DefaultKanikoImage = "gcr.io/kaniko-project/executor:v0.7.0@sha256:0b4e0812aa17c54a9b8d8c8d7cb35559a892a341650acf7cb428c3e8cb4a3919"
51-
DefaultKanikoSecretName = "kaniko-secret"
52-
DefaultKanikoTimeout = "20m"
53-
DefaultKanikoContainerName = "kaniko"
54-
DefaultKanikoEmptyDirName = "kaniko-emptydir"
55-
DefaultKanikoEmptyDirMountPath = "/kaniko/buildcontext"
50+
DefaultKanikoImage = "gcr.io/kaniko-project/executor:v0.7.0@sha256:0b4e0812aa17c54a9b8d8c8d7cb35559a892a341650acf7cb428c3e8cb4a3919"
51+
DefaultKanikoSecretName = "kaniko-secret"
52+
DefaultKanikoTimeout = "20m"
53+
DefaultKanikoContainerName = "kaniko"
54+
DefaultKanikoEmptyDirName = "kaniko-emptydir"
55+
DefaultKanikoEmptyDirMountPath = "/kaniko/buildcontext"
56+
DefaultKanikoDockerConfigSecretName = "docker-cfg"
57+
DefaultKanikoDockerConfigPath = "/kaniko/.docker"
5658

5759
DefaultBusyboxImage = "busybox"
5860

pkg/skaffold/schema/defaults/defaults.go

+21
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func Set(c *latest.SkaffoldPipeline) error {
4343
setDefaultKanikoNamespace,
4444
setDefaultKanikoSecret,
4545
setDefaultKanikoBuildContext,
46+
setDefaultDockerConfigSecret,
4647
); err != nil {
4748
return err
4849
}
@@ -175,6 +176,26 @@ func setDefaultKanikoSecret(kaniko *latest.KanikoBuild) error {
175176
return nil
176177
}
177178

179+
func setDefaultDockerConfigSecret(kaniko *latest.KanikoBuild) error {
180+
if kaniko.DockerConfig == nil {
181+
return nil
182+
}
183+
184+
kaniko.DockerConfig.SecretName = valueOrDefault(kaniko.DockerConfig.SecretName, constants.DefaultKanikoDockerConfigSecretName)
185+
186+
if kaniko.DockerConfig.Path != "" {
187+
absPath, err := homedir.Expand(kaniko.DockerConfig.Path)
188+
if err != nil {
189+
return fmt.Errorf("unable to expand dockerConfig.path %s", kaniko.DockerConfig.Path)
190+
}
191+
192+
kaniko.DockerConfig.Path = absPath
193+
return nil
194+
}
195+
196+
return nil
197+
}
198+
178199
func setDefaultKanikoBuildContext(kaniko *latest.KanikoBuild) error {
179200
if kaniko.BuildContext == nil {
180201
kaniko.BuildContext = &latest.KanikoBuildContext{

pkg/skaffold/schema/latest/config.go

+7
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ type KanikoBuild struct {
126126
Namespace string `yaml:"namespace,omitempty"`
127127
Timeout string `yaml:"timeout,omitempty"`
128128
Image string `yaml:"image,omitempty"`
129+
DockerConfig *DockerConfig `yaml:"dockerConfig,omitempty"`
130+
}
131+
132+
// DockerConfig contains information about the docker config.json to mount
133+
type DockerConfig struct {
134+
Path string `yaml:"path,omitempty"`
135+
SecretName string `yaml:"secretName,omitempty"`
129136
}
130137

131138
type TestConfig []*TestCase

pkg/skaffold/schema/versions_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ build:
8888
pullSecretName: secret-name
8989
namespace: nskaniko
9090
timeout: 120m
91+
dockerConfig:
92+
secretName: config-name
93+
path: /kaniko/.docker
9194
`
9295
badConfig = "bad config"
9396
)
@@ -169,6 +172,7 @@ func TestParseConfig(t *testing.T) {
169172
expected: config(
170173
withKanikoBuild("demo", "secret-name", "nskaniko", "/secret.json", "120m",
171174
withGitTagger(),
175+
withDockerConfig("config-name", "/kaniko/.docker"),
172176
),
173177
withKubectlDeploy("k8s/*.yaml"),
174178
),
@@ -264,6 +268,15 @@ func withKanikoBuild(bucket, secretName, namespace, secret string, timeout strin
264268
}
265269
}
266270

271+
func withDockerConfig(secretName string, path string) func(*latest.BuildConfig) {
272+
return func(cfg *latest.BuildConfig) {
273+
cfg.KanikoBuild.DockerConfig = &latest.DockerConfig{
274+
SecretName: secretName,
275+
Path: path,
276+
}
277+
}
278+
}
279+
267280
func withKubectlDeploy(manifests ...string) func(*latest.SkaffoldPipeline) {
268281
return func(cfg *latest.SkaffoldPipeline) {
269282
cfg.Deploy = latest.DeployConfig{

0 commit comments

Comments
 (0)