一、docker概述
二、docker安装
2.1、docker的基本组成
- 镜像(image):
- docker镜像就好比是一个模版,可以通过这个模板来创建容器服务,tomcat镜像===>run ==> tomcat01 容器(提供服务器)通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。
- 容器(container)
- Docker利用容器技术,独立运行—个或者一个组应用,通过镜像来创建的。启动,停止,删除,基本命令!目前就可以把这个容器理解为就是一个简易的linux系统
- 仓库(repository)
- 仓库就是存放镜像的地方!仓库分为公有仓库和私有仓库!Docker Hub(默认是国外的)阿里云…都有容器服务器(配置镜像加速!)
2.2、docker安装
https://blog.csdn.net/weixin_53466908/article/details/124132218
2.3、docker run的流程图
2.4、底层原理
2.4.1、docker是怎么工作的?
Docker 是一个 Client - Server 结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
DockerServer 接收到 Docker-Client 的指令,就会执行这个命令!
2.4.2、Dokcer为什么比vm快?
1、 Docker有着比虚拟机更少的抽象层。
2、 docker 利用的是宿主机的内核,vm 需要是 Guest OS.
所以说,新建一个容器的时候,docker不需要想虚拟机一样重新加载一个操作系统内核,避免引1导。虚拟机是加载 Guest os,分钟级别的,而docker 是利用 宿主机的操作系统吗,省略了这个复杂的过程,秒级!
三、docker常用命令
帮助命令
docker version # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help #帮助命令
镜像命令
docker images 查看所有本地主机上的镜像
[root@yang ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx new 3b166d184108 2 weeks ago 1.4 GB
nginx v3 a1342d1a9ffa 2 weeks ago 142 MB
yang.ubuntu v2.0.2 03f7cecc519f 2 weeks ago 78.7 MB
yang/ubuntu v2.0.1 53853ef186db 2 weeks ago 78.8 MB
yang/ubuntu v3.0.1 53853ef186db 2 weeks ago 78.8 MB
yang/ubuntu v1.0.1 3b40cc83456e 2 weeks ago 78.4 MB
docker.io/mysql latest 40b83de8fb1a 3 weeks ago 535 MB
docker.io/redis alpine d29f18e8bc92 3 weeks ago 28.4 MB
docker.io/nginx latest 51086ed63d8c 4 weeks ago 142 MB
docker.io/ubuntu latest 216c552ea5ba 4 weeks ago 77.8 MB
docker.io/centos centos7.5.1804 cf49811e3cdb 3 years ago 200 MB
registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g latest 3fa112fd3642 6 years ago 6.85 GB
docker.io/training/webapp latest 6fae60ef3446 7 years ago 349 MB
docker.io/training/postgres latest 6fa973bb3c26 8 years ago 365 MB
解释
- REPOSITORY 镜像仓库源
- TAG 镜像的标签
- IMAGE ID 镜像的id
- CREATED 镜像的创建时间
- SIZE 镜像的大小
可选项
- -a 列出所有的镜像
- -q 只显示镜像的id
docker search 搜索镜像
- docker search 镜像名称
- 可选项,通过搜索过滤
- --filter=STARS=50 只搜索STARS大于50的
docker pull 下载镜像
- docker pull 镜像名称
- 拉取镜像,不指定版本默认是最新版
- docker pull 镜像名称:版本号
- 查看镜像列表
docker rmi 删除镜像
docker rmi -f 容器id # 删除指定的容器 docker rmi -f 容器id 容器id 容器id 容器id # 删除多个容器 docker rmi -f $(docker images -aq) # 删除全部的容器
容器命令
新建容器的并启动
docker run [可选参数] image # 参数说明 --name="Name" 容器的名字,用来区分容器 -d 后台方式运行 -it 使用交互方式运行,进入容器查看内容 -p 指定容器端口 -p 8080:8080 -p 主机端口:容器端口 (常用) -p 容器端口 容器端口 -P 随机指定端口
- 测试
- 退出exit
列出所有运行的容器
docker ps # 列出当前正在运行的容器 -a # 列出当前正在运行的容器 + 带出历史运行的程序 -n=?# 列出当前正在运行的容器+带出历史运行过的容器 (?是数字) -q # 只显示容器的编号
退出容器
exit # 直接容器停止并退出 ctrl + P + Q # 容不停止退出
删除容器
docker rm 容器id # 删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -f docker rm -f $(docker ps -aq) # 删除所有的容器 docker ps -a -q|xargs docker rm # 删除所有的容器
启动和停止容器操作
docker start 容器id # 启动容器 docker restart 容器id # 重启容器 docker stop容器id # 停止当前正在运行的容器 docker kill 容器id # 强制停止当前正在运行的容器
常用其他命令
后台启动容器
查看日志
查看容器中的进程信息
docker top 容器id
查看镜像的元数据
docker imspect 容器id
[root@yang ~]# docker inspect c74ba4e6e133 [ { "Id": "c74ba4e6e1339e2de2bc892c3ea372554ab676cc3419543c743c2d97383a733d", "Created": "2022-10-20T07:46:35.691292093Z", "Path": "/run.sh", "Args": [], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 31807, "ExitCode": 0, "Error": "", "StartedAt": "2022-10-20T07:46:36.163249414Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:3b166d1841085566c70d729b563be970b42cedf1f9eb40917ed8fe420201677b", "ResolvConfPath": "/var/lib/docker/containers/c74ba4e6e1339e2de2bc892c3ea372554ab676cc3419543c743c2d97383a733d/resolv.conf", "HostnamePath": "/var/lib/docker/containers/c74ba4e6e1339e2de2bc892c3ea372554ab676cc3419543c743c2d97383a733d/hostname", "HostsPath": "/var/lib/docker/containers/c74ba4e6e1339e2de2bc892c3ea372554ab676cc3419543c743c2d97383a733d/hosts", "LogPath": "", "Name": "/nginxnew1", "RestartCount": 0, "Driver": "overlay2", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": [ "6e33884d160f8d44ac9093d8db5e4b5e3835e0386cb83108cf8aa25cb6811468", "4bd41145bbd49e3cf256f45287be6e5624c9d1830e00105873d62811924c1e56", "8bd41c265851541a9babec60d427ec44dd563f149c6c270e2ccfecd41cc8cd55" ], "HostConfig": { "Binds": [ "/opt/docker/server/nginx/conf.d/:/etc/nginx/conf.d", "/opt/docker/server/nginx/html/:/usr/share/nginx/html", "/opt/docker/server/nginx/log/:/var/log/nginx" ], "ContainerIDFile": "", "LogConfig": { "Type": "journald", "Config": {} }, "NetworkMode": "default", "PortBindings": { "443/tcp": [ { "HostIp": "", "HostPort": "443" } ], "80/tcp": [ { "HostIp": "", "HostPort": "80" } ] }, "RestartPolicy": { "Name": "always", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": null, "CapAdd": null, "CapDrop": null, "Dns": [], "DnsOptions": [], "DnsSearch": [], "ExtraHosts": null, "GroupAdd": null, "IpcMode": "", "Cgroup": "", "Links": null, "OomScoreAdj": 0, "PidMode": "", "Privileged": false, "PublishAllPorts": false, "ReadonlyRootfs": false, "SecurityOpt": null, "UTSMode": "", "UsernsMode": "", "ShmSize": 67108864, "Runtime": "docker-runc", "ConsoleSize": [ 0, 0 ], "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": null, "BlkioDeviceReadBps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteIOps": null, "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DiskQuota": 0, "KernelMemory": 0, "MemoryReservation": 0, "MemorySwap": 0, "MemorySwappiness": -1, "OomKillDisable": false, "PidsLimit": 0, "Ulimits": null, "CpuCount": 0, "CpuPercent": 0, "IOMaximumIOps": 0, "IOMaximumBandwidth": 0 }, "GraphDriver": { "Name": "overlay2", "Data": { "LowerDir": "/var/lib/docker/overlay2/6cc30bcdb25096bbec3eba5e075dae1e1f70512170dc7a91cbec51693ab3d193-init/diff:/var/lib/docker/overlay2/8828436c47c03bcbdc240468fceb1c437395771557fd49fa9e01d75b9d89e6d1/diff:/var/lib/docker/overlay2/b2f59a8371815435b28c11ce971db41fb56ddc8564338fba8976e0274dbae426/diff:/var/lib/docker/overlay2/2ad48c78553dbacd1ca11abf7b3cbb5260a7f62a51088d0162d93c40a611954e/diff:/var/lib/docker/overlay2/80ed5d78b699d28fd1c7fffac38ef01134e93df5a67f5ffd61bc035df44a9e52/diff:/var/lib/docker/overlay2/87812d19ab72acd45947bcb18421f176aa9a9e2624a6af694f364ce05c71d1d3/diff:/var/lib/docker/overlay2/5dce31b791abd66c53a9fa88c6dc65cfb003893c567ae9e38aff0b28d4f8c354/diff:/var/lib/docker/overlay2/b9bd197e625aa13d53d529289839c33d688933a9c91785356fc0d39bd9981a77/diff:/var/lib/docker/overlay2/6248f792b79cd44ad4245638abf5a0ea5e8ca80c05a3478c0f85e333971d1aea/diff:/var/lib/docker/overlay2/e4457de5166b7771f19209b8b623f6f4e25115e0b5159d9be8586fa17483621d/diff:/var/lib/docker/overlay2/9a0c2dd62d1c72901f734773aca80fb8b9a6e6f7c119bba04f4614358b8b77b9/diff", "MergedDir": "/var/lib/docker/overlay2/6cc30bcdb25096bbec3eba5e075dae1e1f70512170dc7a91cbec51693ab3d193/merged", "UpperDir": "/var/lib/docker/overlay2/6cc30bcdb25096bbec3eba5e075dae1e1f70512170dc7a91cbec51693ab3d193/diff", "WorkDir": "/var/lib/docker/overlay2/6cc30bcdb25096bbec3eba5e075dae1e1f70512170dc7a91cbec51693ab3d193/work" } }, "Mounts": [ { "Type": "bind", "Source": "/opt/docker/server/nginx/conf.d", "Destination": "/etc/nginx/conf.d", "Mode": "", "RW": true, "Propagation": "rprivate" }, { "Type": "bind", "Source": "/opt/docker/server/nginx/html", "Destination": "/usr/share/nginx/html", "Mode": "", "RW": true, "Propagation": "rprivate" }, { "Type": "bind", "Source": "/opt/docker/server/nginx/log", "Destination": "/var/log/nginx", "Mode": "", "RW": true, "Propagation": "rprivate" } ], "Config": { "Hostname": "c74ba4e6e133", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "443/tcp": {}, "80/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/run.sh" ], "ArgsEscaped": true, "Image": "3b166d184108", "Volumes": null, "WorkingDir": "/root/nginx", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.schema-version": "= 1.0 org.label-schema.name=CentOS Base Image org.label-schema.vendor=CentOS org.label-schema.license=GPLv2 org.label-schema.build-date=20180531" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "71db1d2a5e3ab3549dd038bd2b0c23fdebefc12a198c8f0d7b5714d7403cd20e", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { "443/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "443" } ], "80/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "80" } ] }, "SandboxKey": "/var/run/docker/netns/71db1d2a5e3a", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "7e175b0f23de76688ec2bd2a62a1a64354f56d3f63ef59d55e2e5c40062c451f", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.7", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:07", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "871cd74edc68bc3a6c71dc3de973f6a0f9e6f444ed2231e04a5ea6d74de913b6", "EndpointID": "7e175b0f23de76688ec2bd2a62a1a64354f56d3f63ef59d55e2e5c40062c451f", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.7", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:07" } } } } ]
进入正在运行的容器
- 方式一:docker exec -it 容器id /bin/bash
- 方式二:docker attach 容器id
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的的主机的路径
拷贝是一个手动过程,未来我们使用 -v 卷的技术,可以实现
小结
四、docker练习
4.1、docker安装nginx
# 1、搜索镜像 search # 2、下载镜像 # 3、运行测试
# -d 后台运行 --name 给容器命名 -p 宿主机端口:容器内部端口
端口暴露概念
4.2、docker安装tomcat
官方的使用
docker run -it --rm tomcat:9.0
我们之前启动都是后台启动,停止了容器之后,容器还是可以查到的 docker run -it --rm 一般用来测试,用完就会删除
# 安装tomcat docker pull tomcat:9.0 # 启动运行 docker run -it -d -p 3355:8080 --name tomcat01 tomcat
- 测试
- 没问题 ,证明我们的tomcat已经部署上了
- 进入容器
- docker exec -it tomcat01 /bin/bash
- 发现问题 1、linux命令少了 2、没有webapps 阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除掉来保证最小的运行环境
- 进入容器发现多了一个webapps.disk 的文件夹,进入后发现有ROOT文件夹
- 思考:我们把webapps.disk文件夹里的东西 拷贝到webapps文件夹里会不会就可以了
- 拷贝webapps.disk文件夹 中的文件到webapps文件夹中
- 成功部署tomcat
五、docker可视化
- portainer(先用这个
5.1、portainer
docker图形可视化界面管理工具! 提供了一个后台管理面板我们操作
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
测试访问:http://yang.gunveda.top:8088/
- 设置密码后进入,选择本地进去
六、docker镜像讲解
6.1、镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码,运行时、库、环境变量配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来!
如何得到镜像:
- 从远程仓库
- 自己制作镜像
6.2、分层理解
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到的是一层一层的在下载
思考:为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过 docker image inspect 命令!
... "RootFS": { "Type": "layers", "Layers": [ "sha256:4826cdadf1ef360641a2f2745453e2e8bb30e3e82a683f4d1145e94bf1c18d9f", "sha256:13a1e48615a300f4e514cc00bdf070658119d33e5861b70f846f3e503d1f13eb", "sha256:5c33e3f4d69f4ef51d067459bce10661591a9be0db25e5bbe8064419845ee9bf", "sha256:1415c6e0009c12d85f51b0c3fda706448cab7ec4b4bdf8c955b66e2b6d6d6cf8", "sha256:7f1726b83d263a8bab94228b0177f987550d2dbe15455e7fa4bd1afc16eab13f", "sha256:aefe39b1319bafec9d6526145e4e7f96f7a5365ddfa97ce76fef868d0c4951ab", "sha256:ff223764d66b9841ef85b864451fe262f6082e244dd0db83cafd12d800d92b89", "sha256:bc7811ca2b2a4558f3ea49e3ca330ad5677e6bdaeb7b533d767944d6f6839493", "sha256:b1c5d117c09b1ec179cff7a65d0ba21e15dd6d659804075da5e844f582d193c1", "sha256:0fba40db297e4489b66d976042711b4042114eca732738c5f35da8fa19008cef" ] }
理解
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下都叫镜像层!
如何提交一个自己的镜像
6.3、commit镜像
docker commit 提交容器成为一个新的副本
# 命令和git原理类似 docker commit -m=“提交的描述信息” -a=“作者” 容器id 目标镜像名:[TAG]
实战测试
- 启一个默认的tomcat
- 发现这个默认的tomcat是没有webapps应用的,镜像的原因,官方的镜像默认 webapps下面是没有文件的
- 我自己拷贝进去一些基本文件
- 将我们操作过的容器通过commit提交为一个镜像!我们以后就使用我们修改过的镜像文件即可,这就是我们自己修改过的镜像
七、容器数据卷
什么是数据卷
将应用和环境打包成一个镜像!
数据如果都在容器中,那么我们容器删除了,数据就会都是!
需求:数据可以持久化。
容器之间可以有一个数据共享技术!Docker容器产生的数据,同步到本地!这就是卷技术!目录的挂载,将我们容器内的目录挂载到Linux上面!
总结一句话:容器的持久化和同步操作!容器之间也是可以数据共享的
使用数据卷
方式一:直接使用命令挂载 -v
docker run -it -v 主机目录:容器内目录 # 测试 [root@yang ~]# docker run -it -v /home/ceshi:/home cf49811e3cdb /bin/bash # 启动起来的时候我们可以通过 dokcer inspect 容器id 查看容器详细信息
测试文件的同步
实战:部署mysql
思考:Mysql的数据持久化的问题
# 获取镜像 docker pull mysql:5.7 # 运行容器,需要做数据挂载! # 安装启动mysql,需要配置密码的,这是要注意点! # 官方测试:docker run --name some-mysql -e MYSQL -ROOT_PASSWORD=my-secret-pw -d mysql :tag #启动我们的 -d 后台运行 -p 端口映射 -v 卷挂载 -e 环境配置 --name 容器名字 [root@yang ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 DataGrep测试链接成功 # 将容器强制删除后,本地挂载的数据卷仍然在
具名与匿名挂载
如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
- v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
拓展:
初识Dockerfile
Dockerfile就是构建docker镜像的构建文件
通过这个脚本生成一个镜像
# 创建一个dockerfile文件 # 文件中的内容(指令大写)参数 FROM centos VOLUME ["volume01","volume02"] CMD echo "-------end------" CMD /bin/bash #这里的每个命令,就是镜像的一层
我们来启动一下我们生成的
这个卷和外部一定有一个同步的目录
查看一下卷挂载的路径
测试一下刚才的文件是否同步出去了!
这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,要手动镜像挂载-v卷名:容器内路径!
数据卷容器
多个mysql同步数据
- 启动3个容器,通过我们刚才自己写的容器启动
docker run -it -d --name docker02 --volumes-from docker01 6dbcedb81511
--volumes-from 命令是可以理解为继承
继承了docker01 容器 继承了以后启动的容器就有了和docker01有的所有东西,在docker01 中的数据改变也会自动同步到docker02中去
多个mysql实现数据共享
八、Dockerfile
dockerfile介绍
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
- 编写一个dockerfile文件
- dokcer build 构建成一个镜像
- docker run 运行镜像
- docker push 发布镜像(DcckerHub 、 阿里云镜像仓库
查看下官方是怎么做的
Dockerfile构建过程
基础知识
- 没有一个关键字(指令) 都是必须大写的字母
- 执行从上到下顺序执行
- #表示注释
- 每一个指令都会创建提交一个新的镜像层并提交!
- dockerfile是面向开发的,我们以后发布项目的时候,做程镜像,就需要编写dockerfile文件,这个文件非常重要
Doclerfile:构建文件定义了一切步骤
DockerImages:通过DokcerFile构建生成一个镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务的
Dockerfile的指令
FROM # 基础镜像 一切从这里开始 MAINTAINMER # 镜像是是谁写的 姓名+邮箱 RUN # 镜像构建的时候需要运行的命令 ADD # 步骤,tomcat镜像,这个tomcat压缩包就是添加的内容 WORKDIR # 镜像的工作目录 VOLUME # 挂载的目录 EXPOSE # 保留端口配置(暴露端口) CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令 ONBUILD # 当构建一个呗继承的 DockerFile 这个时候就会运行 ONBUILD 的指令 COPY # 类似ADD 将我们的文件拷贝到镜像中 ENV # 构建的时候设置环境变量
实战测试
Docker Hub 中 99%镜像都是这个基础镜像过来的FROM scratch ,然后配置需要的软件和配置来进行构建
创建一个自己的centos
- 编写Dockerfile文件
[root@yang centos]# cat dockerfile-centos FROM centos MAINTAINER Guoyang<826044698@qq.com> ENV MYPATH /usr/local WORKDIR #MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo #MYPATH CMD echo "-----end------" CMD /bin/bash
- 通过这个文件构建镜像
- 命令:
docker build -f dockerfile-centos -t centos:0.1 .
- 测试运行即可
CMD和ENTRYPOINT区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
测试cmd
# 写一个dockerfile 文件 [root@yang centos]# cat dockerfile-cmdtest FROM centos CMD ["ls", "-a"] # 构建镜像 [root@yang centos]# docker build -f dockerfile-cmdtest -t cmdtest . # 运行镜像 发现我们的ls -a 命令生效 [root@yang centos]# docker run cmdtest . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc
想追加一个命令 -l 理想的是“ls -al”
实际上
[root@yang centos]# docker run cmdtest -l container_linux.go:290: starting container process caused "exec: \"-l\": executable file not found in $PATH" /usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:290: starting container process caused "exec: \"-l\": executable file not found in $PATH".
- cmd的清理下 -l 替换了CMD{"ls" , "-a"} 命令。-l 不是一个命令所以报错
测试ENTRYPOINT
[root@yang centos]# docker build -f dockerfile-entorypoint-test -t entorytest . Sending build context to Docker daemon 4.096 kB Step 1/2 : FROM centos ---> 5d0da3dc9764 Step 2/2 : ENTRYPOINT ls -a ---> Running in 25474c14eec6 ---> 3bcef5429a75 Removing intermediate container 25474c14eec6 Successfully built 3bcef5429a75 [root@yang centos]# docker run 3bcef5429a75 . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@yang centos]# docker run 3bcef5429a75 -l total 56 drwxr-xr-x 1 root root 4096 Nov 7 15:30 . drwxr-xr-x 1 root root 4096 Nov 7 15:30 .. -rwxr-xr-x 1 root root 0 Nov 7 15:30 .dockerenv lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x 5 root root 340 Nov 7 15:30 dev drwxr-xr-x 1 root root 4096 Nov 7 15:30 etc drwxr-xr-x 2 root root 4096 Nov 3 2020 home lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64 drwx------ 2 root root 4096 Sep 15 2021 lost+found drwxr-xr-x 2 root root 4096 Nov 3 2020 media drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt drwxr-xr-x 2 root root 4096 Nov 3 2020 opt dr-xr-xr-x 129 root root 0 Nov 7 15:30 proc dr-xr-x--- 2 root root 4096 Sep 15 2021 root drwxr-xr-x 1 root root 4096 Nov 7 15:30 run lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Nov 3 2020 srv dr-xr-xr-x 13 root root 0 Feb 26 2022 sys drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp drwxr-xr-x 12 root root 4096 Sep 15 2021 usr drwxr-xr-x 20 root root 4096 Sep 15 2021 var
ENTRYPOINT 降命令进行追加