pulumi / pulumi-kubernetesx

Kubernetes for Everyone
Apache License 2.0
135 stars 16 forks source link

Add an easy way to create a Docker config Secret for private image pulling #49

Open ringods opened 4 years ago

ringods commented 4 years ago
export const imagePullSecret = new k8s.core.v1.Secret(
    "docker-hub",
    {
        type: "kubernetes.io/dockerconfigjson",
        metadata: {
            namespace: "community"
        },
        stringData: {
            ".dockerconfigjson": config
                .requireSecret("docker-hub-token")
                .apply(value => {
                    return JSON.stringify({
                        auths: {
                            "https://index.docker.io/v1/": {
                                auth: value
                            }
                        }
                    })
                })
        },
    },
    {
        provider: kubernetesProvider
    }
);

The above snippet is the current way to create a Secret which can be used to pull private Docker images from Docker Hub. Please provide an easier way to create such a secret.

Context:

Issue created on request of @lblackstone

ringods commented 4 years ago

Note for the documentation: the configured Pulumi secret named docker-hub-token is actually more than just the personal access token. It should be the base64 encoded version of a string of the form:

<username>:<password> or <username>:<personal access token>

It took me a while to get this right so please add this to the documentation so other people do not have to waste time too.

9876691 commented 4 years ago

If you created the registry with pulumi (for example on azure) you can use the outputs from the registry object to generate your secret.

const registry = new azure.containerservice.Registry(....

Then call the below function as follows

const secret = createImagePullSecret(registry.adminUsername, 
    registry.adminPassword, registry.loginServer, k8sProvider)

And to create the secret.

export function createImagePullSecret(username: pulumi.Output<string>,
    password: pulumi.Output<string>, 
    registry : pulumi.Output<string>,
    k8sProvider : k8s.Provider): k8s.core.v1.Secret {

    // Put the username password into dockerconfigjson format.
    let base64JsonEncodedCredentials : pulumi.Output<string> = 
        pulumi.all([username, password, registry])
        .apply(([username, password, registry]) => {
            const base64Credentials = Buffer.from(username + ':' + password).toString('base64')
            const json =  `{"auths":{"${registry}":{"auth":"${base64Credentials}"}}}`
            console.log(json)
            return Buffer.from(json).toString('base64')
        })

    return new k8s.core.v1.Secret('image-pull-secret', {
        metadata: {
            name: 'image-pull-secret',
        },
        type: 'kubernetes.io/dockerconfigjson',
        data: {
            ".dockerconfigjson": base64JsonEncodedCredentials,
        },
    }, { provider: k8sProvider })
}
snipebin commented 4 years ago

For DigitalOcean:

// Private container registry to deploy images into
export const registry = new digitalocean.ContainerRegistry(`container-registry`);

export const registryCreds = pulumi.secret(new digitalocean.ContainerRegistryDockerCredentials("container-registry-creds", { registryName: registry.name }).dockerCredentials);

const registryCredsKubeSecretName = new k8s.core.v1.Secret('registry-creds-secret', {
  type: 'kubernetes.io/dockerconfigjson',
  data: {
    ".dockerconfigjson": registryCreds.apply(v => Buffer.from(v).toString('base64')),
  },
}, { provider })
diofeher commented 3 years ago

Thanks @snipebin <3

slaiyer commented 3 years ago

And how do you patch the default ServiceAccount for a given namespace to use this secret? @snipebin @ianpurton