Docker image与container

本文深入探讨Docker的镜像与容器技术,包括镜像构建、资源限制、容器操作及底层技术支撑。从Dockerfile语法详解到镜像仓库管理,再到容器资源调控,全面解析Docker的核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

02 Image and Container

2.1 深入探讨Image
在这里插入图片描述
说白了,image就是由一层一层的layer组成的。

2.1.1 官方image

https://github.com/docker-library

mysql

https://github.com/docker-library/tomcat/blob/master/8.5/jdk8/openjdk/Dockerfile

2.1.2 Dockerfile

不妨我们也来制作一个自己的image镜像,顺便学习一下Dockerfile文件中常见语法

2.1.2.1 FROM

指定基础镜像,比如FROM ubuntu:14.04
FROM ubuntu:14.04

2.1.2.2 RUN

在镜像内部执行一些命令,比如安装软件,配置环境等,换行可以使用""

RUN groupadd -r mysql && useradd -r -g mysql mysql

2.1.2.3 ENV
设置变量的值,ENV MYSQL_MAJOR 5.7,可以通过docker run --e key=value修改,后面可以直接使用${MYSQL_MAJOR}

ENV MYSQL_MAJOR 5.7

2.1.2.4 LABEL

设置镜像标签
LABEL email=“itcrazy2016@163.com”
LABEL name=“itcrazy2016”

2.1.2.5 VOLUME

指定数据的挂在目录
VOLUME /var/lib/mysql

2.1.2.5 COPY

将主机的文件复制到镜像内,如果目录不存在,会自动创建所需要的目录,注意只是复制,不会提取和解压
COPY docker-entrypoint.sh /usr/local/bin/

2.1.2.6 ADD

将主机的文件复制到镜像内,和COPY类似,只是ADD会对压缩文件提取和解压
ADD application.yml /etc/itcrazy2016/

2.1.2.7 WORKDIR

指定镜像的工作目录,之后的命令都是基于此目录工作,若不存在则创建
WORKDIR /usr/local
WORKDIR tomcat
RUN touch test.txt
会在/usr/local/tomcat下创建test.txt文件
WORKDIR /root
ADD app.yml test/
会在/root/test下多出一个app.yml文件

2.1.2.8 CMD

容器启动的时候默认会执行的命令,若有多个CMD命令,则最后一个生效
CMD [“mysqld”]或CMD mysqld

2.1.2.9 ENTRYPOINT

和CMD的使用类似
ENTRYPOINT [“docker-entrypoint.sh”]
和CMD的不同
docker run执行时,会覆盖CMD的命令,而ENTRYPOINT不会

2.1.2.10 EXPOSE

指定镜像要暴露的端口,启动镜像时,可以使用-p将该端口映射给宿主机
EXPOSE 3306

2.1.3 Dockerfile实战Spring Boot项目

(1)创建一个Spring Boot项目
(2)写一个controller
@RestController

public class DockerController {
@GetMapping("/dockerfile")
@ResponseBody
String dockerfile() {
return “hello docker” ;
}
}
(3)mvn clean package打成一个jar包
在target下找到"dockerfile-demo-0.0.1-SNAPSHOT.jar"
(4)在docker环境中新建一个目录"first-dockerfile"
(5)上传"dockerfile-demo-0.0.1-SNAPSHOT.jar"到该目录下,并且在此目录创建Dockerfile
(6)创建Dockerfile文件,编写内容
FROM openjdk:8
MAINTAINER itcrazy2016
LABEL name=“dockerfile-demo” version=“1.0” author=“itcrazy2016” COPY dockerfile-demo-0.0.1-SNAPSHOT.jar dockerfile-image.jar CMD [“java”,"-jar",“dockerfile-image.jar”]
(7)基于Dockerfile构建镜像
docker build -t test-docker-image .
(8)基于image创建container
docker run -d --name user01 -p 6666:8080 test-docker-image
(9)查看启动日志docker logs user01
(10)宿主机上访问curl localhost:6666/dockerfile hello docker
(11)还可以再次启动一个
docker run -d --name user02 -p 8081:8080 test-docker-image

2.1.4 镜像仓库

2.1.4.1 docker hub

hub.docker.com
itcrazy2018登录

(1)在docker机器上登录
docker login
(2)输入用户名和密码
(3)docker push itcrazy2018/test-docker-image [注意镜像名称要和docker id一致,不然push不成功]
(4)给image重命名,并删除掉原来的
docker tag test-docker-image itcrazy2018/test-docker-image docker rmi -f test-docker-image
(5)再次推送,刷新hub.docker.com后台,发现成功
(6)别人下载,并且运行
docker pull itcrazy2018/test-docker-image
docker run -d --name user01 -p 6661:8080 itcrazy2018/test-docker-image

2.1.4.2 阿里云docker hub

阿里云docker仓库
https://cr.console.aliyun.com/cn-hangzhou/instances/repositories
参考手册
https://cr.console.aliyun.com/repository/cn-hangzhou/dreamit/image-repo/details

(1)登录到阿里云docker仓库
sudo docker login --username=itcrazy2016@163.com registry.cn-hangzhou.aliyuncs.com
(2)输入密码
(3)创建命名空间,比如itcrazy2016
(4)给image打tag
sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/itcrazy2016/test-docker-image:v1.0
(5)推送镜像到docker阿里云仓库
sudo docker push registry.cn-hangzhou.aliyuncs.com/itcrazy2016/test-docker-image:v1.0
(6)别人下载,并且运行
docker pull registry.cn-hangzhou.aliyuncs.com/itcrazy2016/test-docker-image:v1.0
docker run -d --name user01 -p 6661:8080 registry.cn-hangzhou.aliyuncs.com/itcrazy2016/test-docker-image:v1.0

2.1.4.3 搭建自己的Docker Harbor

(1)访问github上的harbor项目
https://github.com/goharbor/harbor
(2)下载版本,比如1.7.1
https://github.com/goharbor/harbor/releases
(3)找一台安装了docker-compose[这个后面的课程会讲解],上传并解压
tar -zxvf xxx.tar.gz
(4)进入到harbor目录
修改harbor.cfg文件,主要是ip地址的修改成当前机器的ip地址同时也可以看到Harbor的密码,默认是Harbor12345
(5)安装harbor,需要一些时间
sh install.sh
(6)浏览器访问,比如39.100.39.63,输入用户名和密码即可

2.1.5 Image常见操作

(1)查看本地image列表
docker images
docker image ls
(2)获取远端镜像
docker pull
(3)删除镜像[注意此镜像如果正在使用,或者有关联的镜像,则需要先处理完]
docker image rm imageid
docker rmi -f imageid
docker rmi -f $(docker image ls)
删除所有镜像
(4)运行镜像
docker run image
(5)发布镜像
docker push

2.2 深入探讨Container

既然container是由image运行起来的,那么是否可以理解为container和image有某种关系?
在这里插入图片描述
理解 :其实可以理解为container只是基于image之后的layer而已,也就是可以通过docker run image 创建出一个container出来。

2.2.1 container到image

既然container是基于image之上的,想想是否能够由一个container反推出image呢?
肯定是可以的,比如通过docker run运行起一个container出来,这时候对container对一些修改,然后再生成一个新的image,这时候image的由来就不仅仅只能通过Dockerfile咯。

实验
(1)拉取一个centos image
docker pull centos
(2)根据centos镜像创建出一个container
docker run -d -it --name my-centos centos
(3)进入my-centos容器中
docker exec -it my-centos bash
(4)输入vim命令
bash: vim: command not found
(5)我们要做的是
对该container进行修改,也就是安装一下vim命令,然后将其生成一个新的centos
(6)在centos的container中安装vim
yum install -y vim
(7)退出容器,将其生成一个新的centos,名称为"vim-centos-image"
docker commit my-centos vim-centos-image
(8)查看镜像列表,并且基于"vim-centos-image"创建新的容器
docker run -d -it --name my-vim-centos vim-centos-image
(9)进入到my-vim-centos容器中,检查vim命令是否存在 docker exec -it my-vim-centos bash
vim
结论 :可以通过docker commit命令基于一个container重新生成一个image,但是一般得到image的方式不建议这么做,不然image怎么来的就全然不知咯。

2.2.2 container资源限制

如果不对container的资源做限制,它就会无限制地使用物理机的资源,这样显然是不合适的。查看资源情况 :docker stats

2.2.2.1 内存限制
–memory Memory limit
如果不设置 --memory-swap,其大小和memory一样
docker run -d --memory 100M --name tomcat1 tomcat

2.2.2.2 CPU限制
–cpu-shares 权重
docker run -d --cpu-shares 10 --name tomcat2 tomcat

2.2.2.3 图形化资源监控
https://github.com/weaveworks/scope
sudo curl -L git.io/scope -o /usr/local/bin/scope sudo chmod a+x /usr/local/bin/scope scope launch 39.100.39.63
# 停止scope
scope stop
# 同时监控两台机器,在两台机器中分别执行如下命令
scope launch ip1 ip2

2.2.3 container常见操作

(1)根据镜像创建容器
docker run -d --name -p 9090:8080 my-tomcat tomcat
(2)查看运行中的container
docker ps
(3)查看所有的container[包含退出的]
docker ps -a
(4)删除container
docker rm containerid
docker rm -f $(docker ps -a) 删除所有container
(5)进入到一个container中
docker exec -it container bash
(6)根据container生成image
docker
(7)查看某个container的日志
docker logs container
(8)查看容器资源使用情况
docker stats
(9)查看容器详情信息
docker inspect container
(10)停止/启动容器
docker stop/start container

2.3 底层技术支持

Container是一种轻量级的虚拟化技术,不用模拟硬件创建虚拟机。
Docker是基于Linux Kernel的Namespace、CGroups、UnionFileSystem等技术封装成的一种自
定义容器格式,从而提供一套虚拟运行环境。
Namespace:用来做隔离的,比如pid[进程]、net[网络]、mnt[挂载点]等
CGroups: Controller Groups用来做资源限制,比如内存和CPU等
Union file systems:用来做image和container分层

<think>嗯,用户询问如何在Docker中删除imagecontainer,这是一个常见的Docker操作问题。用户可能刚接触Docker,或者遇到了无法删除资源的情况。首先需要区分containerimage的删除逻辑。container是运行实例,image是静态模板,两者有依赖关系:存在基于某image运行的container时,该image不能被删除。从引用内容看,用户提供的资料里包含多种删除场景:1.常规删除单个container使用$dockerrm[容器ID]$2.删除image时若提示"dependentchildimages",说明存在子镜像(引用1)3.批量删除container可通过$dockerrm$(dockercontainerls-qa)$实现(引用2)4.删除untaggedimage可用$dockerrmi$(dockerimages|grep"<none>"|awk'{print$3}')$(引用3)用户可能遇到的两个典型难点:-删除image时提示"imageisinuse",需要先停止并删除关联container-权限问题如"Gotpermissiondenied"(引用1),这需要sudo或配置用户组准备在回复中强调操作顺序:先删container再删image,对于批量操作和异常处理给出具体方案。特别要说明依赖关系的解决方法,因为这是最常见的卡点。考虑在相关问题里加入Docker存储原理,因为理解分层机制才能从根本上解释删除冲突的原因。</think>### 如何删除 Docker 中的 ImageContainer #### 一、删除 Container(容器) 1. **删除单个容器** 先停止运行中的容器(若存在): ```bash docker stop <容器ID或名称> ``` 删除容器: ```bash docker rm <容器ID或名称> ``` *例:`docker rm mysql` 删除名为 mysql 的容器[^4]* 2. **批量删除所有容器** ```bash docker rm -f $(docker container ls -aq) # -f 强制删除运行中的容器 ``` *说明:`docker container ls -aq` 列出所有容器ID(含停止状态)[^2][^5]* #### 二、删除 Image(镜像) 1. **删除单个镜像** ```bash docker rmi <镜像ID或名称> ``` *例:`docker rmi ubuntu:20.04`* 2. **解决依赖冲突** 若提示 `image has dependent child images`[^1]: - 先删除依赖该镜像的子镜像 - 或查找关联容器并删除: ```bash docker ps -a --filter ancestor=<镜像ID> # 检查关联容器 docker rm -f $(docker ps -aq --filter ancestor=<镜像ID>) # 删除关联容器 docker rmi <镜像ID> # 再次尝试删除 ``` 3. **批量删除虚悬镜像**(未命名的 `<none>` 镜像) ```bash docker rmi $(docker images -f "dangling=true" -q) ``` *等同于 `docker images | grep "<none>" | awk '{print $3}' | xargs docker rmi`[^3]* #### 三、关键注意事项 1. **删除顺序** 必须**先删除依赖镜像的容器**,才能删除镜像[^1][^4]。 *错误顺序:直接 `docker rmi` → 触发 `conflict` 错误* 2. **权限问题** 若报错 `Got permission denied`[^1],在命令前加 `sudo` 或[配置用户组](https://docs.docker.com/engine/install/linux-postinstall/): ```bash sudo usermod -aG docker $USER # 将当前用户加入 docker 组 newgrp docker # 刷新组权限 ``` 3. **强制删除** 添加 `-f` 参数(慎用): ```bash docker rmi -f <镜像ID> # 可能仍失败于子镜像依赖 ``` > **操作验证**: > - 查看剩余容器:`docker ps -a` > - 查看剩余镜像:`docker images` > 删除后列表应不再显示目标资源[^2][^5]。 --- ### 相关问题 1. 如何清理 Docker 占用的磁盘空间(包括 volumes 和缓存)? 2. Docker 镜像的分层机制如何影响删除操作? 3. 如何安全删除被多个容器共享的镜像? 4. Docker 的 `prune` 命令直接删除有何区别? [^1]: 删除镜像时若存在子镜像依赖会触发 `conflict` 错误,需先清理关联容器 [^2]: 批量删除容器需结合 `docker container ls -aq` 获取 ID 列表 [^3]: 过滤 `<none>` 镜像的关键字是虚悬镜像的标识 [^4]: 删除容器可通过名称、完整 ID 或 ID 前缀操作 [^5]: 删除后使用 `docker ps -a` 验证结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值