Pulumi - 如何从私有注册表中提取 docker 图像?
Pulumi - how to pull a docker image from a private registry?
我已经声明了一个包含两个容器的 Kubernetes 部署。一个是本地构建的,另一个需要从私有注册表中提取。
const appImage = new docker.Image("ledgerImage", {
imageName: 'us.gcr.io/qwil-build/ledger',
build: "../../",
});
const ledgerDeployment = new k8s.extensions.v1beta1.Deployment("ledger", {
spec: {
template: {
metadata: {
labels: {name: "ledger"},
name: "ledger",
},
spec: {
containers: [
{
name: "api",
image: appImage.imageName,
},
{
name: "ssl-proxy",
image: "us.gcr.io/qwil-build/monolith-ssl-proxy:latest",
}
],
}
}
}
});
当我 运行 pulumi up
它挂起 - 这是因为 You don't have the needed permissions to perform this operation, and you may have invalid credentials
的投诉而发生的。当我 运行 kubectl describe <name of pod>
时,我看到了这个抱怨。但是,当我 运行 docker pull us.gcr.io/qwil-build/monolith-ssl-proxy:latest
它执行得很好。我已经重新 gcloud auth configure-docker
但没有帮助。
我找到了 https://github.com/pulumi/pulumi-cloud/issues/112,但似乎 docker.Image
需要一个 build
arg,这表明它适用于本地图像,而不是远程图像。
如何从私有注册表中提取映像?
编辑:
原来我有一个本地 dockerfile 用于构建我需要的 SSL 代理。我已经用
声明了一个新的 Image
const sslImage = new docker.Image("sslImage", {
imageName: 'us.gcr.io/qwil-build/ledger-ssl-proxy',
build: {
context: "../../",
dockerfile: "../../Dockerfile.proxy"
}
});
并正确更新了 Deployment
中的图像引用。但是,我仍然遇到身份验证问题。
哦!看起来 RemoteImage
是答案:https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/docker/#RemoteImage
编辑:
我试过了
const sslImage = new docker.RemoteImage("sslImage", {
name: 'us.gcr.io/qwil-build/monolith-ssl-proxy:latest',
})
而且我仍然收到身份验证错误,所以这不是我想的答案。
原来 运行 pulumi destroy --yes && pulumi up --skip-preview --yes
是我需要的。我想我当时处于某种奇怪的不一致状态,但现在已修复。
您需要为集群提供 Docker 注册表的凭据,以便它可以从中提取图像。
手动过程为:
docker login registry.gitlab.com
cat ~/.docker/config.json | base64
然后用上面的输出创建一个registry_secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: regsec
data:
.dockerconfigjson: ewJImF1dGhzIjogewoJCSJyZWdpc3RyeS5naXfRsYWsi7fQoJfSwKCSJIdHRwSGVhZGVycyI6IHsKCQkdiVXNlci1BZ2VudCI6ICJEb2NrZXItQ2xpZW50LzEaLjxzLxjUgKH9yIjogInN3YXJtIgp9
type: kubernetes.io/dockerconfigjson
然后使用
将其应用到您的集群
kubectl apply -f registry_secret.yaml && kubectl get secrets
您可以将其包装到 Pulumi 中,因为它支持类似
的 yaml 文件
new k8s.yaml.ConfigGroup("docker-secret", {files: "registry_secret.yaml"});
这仅在您将凭据编码为 .docker/config.json 时有效,如果您使用的是凭据存储,则此方法无效
另一种方法是通过提供您的用户凭据并提取令牌来直接创建密钥
kubectl create secret docker-registry regsec \
--docker-server=registry.gitlab.com --docker-username=... \
--docker-email=... --docker-password=... \
--dry-run -o yaml | grep .dockerconfigjson: | sed -e 's/.dockerconfigjson://' | sed -e 's/^[ \t]*//'
此令牌现在可以存储为 pulumi 秘密
pulumi config set docker_token --secret <your_token>
这样使用
import {Secret} from "@pulumi/kubernetes/core/v1";
import {Config} from "@pulumi/pulumi";
/**
* Creates a docker registry secret to pull images from private registries
*/
export class DockerRegistry {
constructor(provider: any) {
const config = new Config();
const dockerToken = config.require("docker_token");
new Secret("docker-registry-secret", {
metadata: {
name: "docker-registry-secret"
},
data: {
".dockerconfigjson": dockerToken
},
type: "kubernetes.io/dockerconfigjson"
}, {provider});
}
}
我有一个只使用代码的解决方案,我用它从 Gitlab 上的私有存储库检索图像:
config.ts
import { Config } from "@pulumi/pulumi";
//
// Gitlab specific config.
//
const gitlabConfig = new Config("gitlab");
export const gitlab = {
registry: "registry.gitlab.com",
user: gitlabConfig.require("user"),
email: gitlabConfig.require("email"),
password: gitlabConfig.requireSecret("password"),
}
import * as config from "./config";
import { Base64 } from 'js-base64';
import * as kubernetes from "@pulumi/kubernetes";
[...]
const provider = new kubernetes.Provider("do-k8s", { kubeconfig })
const imagePullSecret = new kubernetes.core.v1.Secret(
"gitlab-registry",
{
type: "kubernetes.io/dockerconfigjson",
stringData: {
".dockerconfigjson": pulumi
.all([config.gitlab.registry, config.gitlab.user, config.gitlab.password, config.gitlab.email])
.apply(([server, username, password, email]) => {
return JSON.stringify({
auths: {
[server]: {
auth: Base64.encode(username + ":" + password),
username: username,
email: email,
password: password
}
}
})
})
}
},
{
provider: provider
}
);
// Then use the imagePullSecret in your deployment like this
deployment = new k8s.apps.v1.Deployment(name, {
spec: {
selector: { matchLabels: labels },
template: {
metadata: { labels: labels },
spec: {
imagePullSecrets: [{ name: args.imagePullSecret.metadata.apply(m => m.name) }],
containers: [container]
},
},
},
});
我已经声明了一个包含两个容器的 Kubernetes 部署。一个是本地构建的,另一个需要从私有注册表中提取。
const appImage = new docker.Image("ledgerImage", {
imageName: 'us.gcr.io/qwil-build/ledger',
build: "../../",
});
const ledgerDeployment = new k8s.extensions.v1beta1.Deployment("ledger", {
spec: {
template: {
metadata: {
labels: {name: "ledger"},
name: "ledger",
},
spec: {
containers: [
{
name: "api",
image: appImage.imageName,
},
{
name: "ssl-proxy",
image: "us.gcr.io/qwil-build/monolith-ssl-proxy:latest",
}
],
}
}
}
});
当我 运行 pulumi up
它挂起 - 这是因为 You don't have the needed permissions to perform this operation, and you may have invalid credentials
的投诉而发生的。当我 运行 kubectl describe <name of pod>
时,我看到了这个抱怨。但是,当我 运行 docker pull us.gcr.io/qwil-build/monolith-ssl-proxy:latest
它执行得很好。我已经重新 gcloud auth configure-docker
但没有帮助。
我找到了 https://github.com/pulumi/pulumi-cloud/issues/112,但似乎 docker.Image
需要一个 build
arg,这表明它适用于本地图像,而不是远程图像。
如何从私有注册表中提取映像?
编辑:
原来我有一个本地 dockerfile 用于构建我需要的 SSL 代理。我已经用
声明了一个新的Image
const sslImage = new docker.Image("sslImage", {
imageName: 'us.gcr.io/qwil-build/ledger-ssl-proxy',
build: {
context: "../../",
dockerfile: "../../Dockerfile.proxy"
}
});
并正确更新了 Deployment
中的图像引用。但是,我仍然遇到身份验证问题。
哦!看起来 RemoteImage
是答案:https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/docker/#RemoteImage
编辑:
我试过了
const sslImage = new docker.RemoteImage("sslImage", {
name: 'us.gcr.io/qwil-build/monolith-ssl-proxy:latest',
})
而且我仍然收到身份验证错误,所以这不是我想的答案。
原来 运行 pulumi destroy --yes && pulumi up --skip-preview --yes
是我需要的。我想我当时处于某种奇怪的不一致状态,但现在已修复。
您需要为集群提供 Docker 注册表的凭据,以便它可以从中提取图像。
手动过程为:
docker login registry.gitlab.com
cat ~/.docker/config.json | base64
然后用上面的输出创建一个registry_secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: regsec
data:
.dockerconfigjson: ewJImF1dGhzIjogewoJCSJyZWdpc3RyeS5naXfRsYWsi7fQoJfSwKCSJIdHRwSGVhZGVycyI6IHsKCQkdiVXNlci1BZ2VudCI6ICJEb2NrZXItQ2xpZW50LzEaLjxzLxjUgKH9yIjogInN3YXJtIgp9
type: kubernetes.io/dockerconfigjson
然后使用
将其应用到您的集群kubectl apply -f registry_secret.yaml && kubectl get secrets
您可以将其包装到 Pulumi 中,因为它支持类似
的 yaml 文件new k8s.yaml.ConfigGroup("docker-secret", {files: "registry_secret.yaml"});
这仅在您将凭据编码为 .docker/config.json 时有效,如果您使用的是凭据存储,则此方法无效
另一种方法是通过提供您的用户凭据并提取令牌来直接创建密钥
kubectl create secret docker-registry regsec \
--docker-server=registry.gitlab.com --docker-username=... \
--docker-email=... --docker-password=... \
--dry-run -o yaml | grep .dockerconfigjson: | sed -e 's/.dockerconfigjson://' | sed -e 's/^[ \t]*//'
此令牌现在可以存储为 pulumi 秘密
pulumi config set docker_token --secret <your_token>
这样使用
import {Secret} from "@pulumi/kubernetes/core/v1";
import {Config} from "@pulumi/pulumi";
/**
* Creates a docker registry secret to pull images from private registries
*/
export class DockerRegistry {
constructor(provider: any) {
const config = new Config();
const dockerToken = config.require("docker_token");
new Secret("docker-registry-secret", {
metadata: {
name: "docker-registry-secret"
},
data: {
".dockerconfigjson": dockerToken
},
type: "kubernetes.io/dockerconfigjson"
}, {provider});
}
}
我有一个只使用代码的解决方案,我用它从 Gitlab 上的私有存储库检索图像:
config.ts
import { Config } from "@pulumi/pulumi";
//
// Gitlab specific config.
//
const gitlabConfig = new Config("gitlab");
export const gitlab = {
registry: "registry.gitlab.com",
user: gitlabConfig.require("user"),
email: gitlabConfig.require("email"),
password: gitlabConfig.requireSecret("password"),
}
import * as config from "./config";
import { Base64 } from 'js-base64';
import * as kubernetes from "@pulumi/kubernetes";
[...]
const provider = new kubernetes.Provider("do-k8s", { kubeconfig })
const imagePullSecret = new kubernetes.core.v1.Secret(
"gitlab-registry",
{
type: "kubernetes.io/dockerconfigjson",
stringData: {
".dockerconfigjson": pulumi
.all([config.gitlab.registry, config.gitlab.user, config.gitlab.password, config.gitlab.email])
.apply(([server, username, password, email]) => {
return JSON.stringify({
auths: {
[server]: {
auth: Base64.encode(username + ":" + password),
username: username,
email: email,
password: password
}
}
})
})
}
},
{
provider: provider
}
);
// Then use the imagePullSecret in your deployment like this
deployment = new k8s.apps.v1.Deployment(name, {
spec: {
selector: { matchLabels: labels },
template: {
metadata: { labels: labels },
spec: {
imagePullSecrets: [{ name: args.imagePullSecret.metadata.apply(m => m.name) }],
containers: [container]
},
},
},
});