我想要的
我有一个不再构建的Dockerfile,因为它的某些初始构建步骤依赖于不再可用的服务,因此进行反向工程很痛苦。整个过程很快就会被重写,但是现在我只想使用包含问题步骤的图层中的修复程序来重建图像。
我的Dockerfile看起来像这样:
FROM ubuntu:14.04
RUN this_thing_that_breaks
RUN apt-get install etc
COPY blah
我本质上想将第3层用作基础层,并在此基础上构建。
我做了什么
docker pull ecr/my-image:cache
docker build --cache-from ecr/my-image:cache -t ecr/my-image:fix .
目前,我希望自己的构建使用:cache
的现有层来构建:fix
,但是我的构建从头开始,但失败了。
This layer explanation post似乎说1.10
之后,docker镜像将其所有层作为一个整体运送出去,这些层实际上不再可访问。
但是,当我查看docker inspect ecr/my-image:cache
时,会看到一大堆图层的sha256 ID。再次让我觉得应该有一种方法可以指向一个特定的层,并将其用作缓存的基础。
是否可以通过给出层的sha256 id列表来构建docker映像?
修复后,我打算对此进行核对,因此在这里不需要优雅。
其他信息
$ docker version
Version: 18.09.1
API version: 1.39
OS/Arch: darwin/amd64
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.1
答案 0 :(得分:1)
要将某个图像的特定图层用作其他图像的基础,可以在public class CacheService
{
private readonly IDatabase cache;
private static readonly string connectionString = ConfigurationManager.AppSettings["RedisConnection"];
private static LoadedLuaScript ruleLuaScript;
public CacheService()
{
this.cache = Connection.GetDatabase();
ruleLuaScript = LoadLuaScriptForGetRule(@"Lua/getMultiHashWithParameter.lua");
}
private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
return ConnectionMultiplexer.Connect(connectionString);
});
public static ConnectionMultiplexer Connection
{
get
{
return lazyConnection.Value;
}
}
private LoadedLuaScript LoadLuaScriptForGetRule(string scriptUrl)
{
string script = File.ReadAllText(scriptUrl);
LuaScript luaScript = LuaScript.Prepare(script);
var endpoints = Connection.GetEndPoints();
var endpoint = endpoints[0];
IServer server = Connection.GetServer(endpoint);
return luaScript.Load(server);
}
public void PrepareLuaScript(dynamic parameters)
{
RedisResult result = this.cache.ScriptEvaluate(ruleLuaScript, parameters);
if (!result.IsNull)
{
//how to read result?
}
}
}
指令中直接使用该图层的SHA256哈希。
例如,假设您有这个Dockerfile
FROM
,并且已经从该Dockerfile成功构建了映像(当时FROM ubuntu:14.04
RUN this_thing_that_breaks
RUN apt-get install etc
COPY blah
工作正常)。 this_thing_that_breaks
最近停止工作,我们现在无法建立图片。
说,已构建的图像被标记为RUN this_thing_that_breaks
。要找到要断开的确切图层的SHA256 ID,请运行my-image:cache
并记下SHA256 ID(此处与docker history my-image:cache
对应的ID)。
说记录下来的SHA256 ID是RUN this_thing_that_breaks
。现在,删除066a73a3a0c4
之前的所有说明,并将其替换为RUN this_thing_that_breaks
。
FROM 066a73a3a0c4
现在,使用FROM 066a73a3a0c4
RUN apt-get install etc
COPY blah
构建新映像my-image:fix
。现在,这应该使用已缓存为创建新图像的基础图像的特定中断层。
希望这会有所帮助!
上一个答案:
不使用缓存的原因可能是docker build --cache-from my-image:cache -t my-image:fix .
中的ubuntu:14.04
图像和本地缓存的ecr/my-image:cache
图像与此处描述的不一样:
https://github.com/moby/moby/issues/26065#issuecomment-249046559
如果
ubuntu:14.04
映像发生更改,则不会重用缓存。这是有用的,实际上很重要,因为否则用户将无法检测到基本映像中存在重要的安全修复程序,因为他们始终使用缓存。但这也可能使某些用户感到惊讶。我认为我们不应该尝试通过破解来解决此问题,而是如果某些用户想要不同的行为,他们应该只使用不可变的标签或摘要作为FROM
图像。
因此,我看到的一个选择是使用FROM
删除本地缓存的ubuntu:14.04
,然后运行docker rmi ubuntu:14.04
。
我希望这能奏效,但我尚未确认。如果这样做不起作用,建议您检查this issue并检查其中提到的选项。
答案 1 :(得分:0)
这种情况下的问题是void listBox1_MouseMove(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left && listBox1.SelectedItems.Count > 0) {
int mouseIndex = listBox1.IndexFromPoint(e.Location);
if (mouseIndex > -1) {
ListBox.SelectedObjectCollection x = new ListBox.SelectedObjectCollection(listBox1);
if (Control.ModifierKeys == Keys.Shift) {
int i1 = Math.Min(listBox1.SelectedIndex, mouseIndex);
int i2 = Math.Max(listBox1.SelectedIndex, mouseIndex);
for (int i = i1; i <= i2; ++i) {
x.Add(listBox1.Items[i]);
}
} else {
x = listBox1.SelectedItems;
}
var dropResult = DoDragDrop(x, DragDropEffects.Move);
}
}
}
和docker build
Certificate Usage Scenarios for the WCF Send Ports
该图像最初是使用docker-compose build
构建的,而我使用的是直接使用的docker。
使用docker-compose时,按预期使用缓存层。
虽然这不能回答如何从某些特定图层构建图像的问题,但确实清除了我的障碍。