1、历史
Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。
Docker自2013年以来非常火热,无论是从 github 上的代码活跃度,还是Redhat在RHEL6.5中集成对Docker的支持, 就连 Google 的 Compute Engine 也支持 docker 在其之上运行。
2、概要说明
- 容器之间互相隔离
- 占用资源小
对比 VM
3、常用指令
3.1、整体
docker 采用的是 C/S 架构,和常规 C/S 架构软件大致相同,主要由三部分构成:
- Clients 客户端
- Hosts 服务端
镜像和容器常用命令转换关系
指令 | 说明 | ** |
---|---|---|
attach | 当前shell下 attach连接指定运行镜像 | |
build | 通过DockerFile 定制镜像 | |
commit | 提交当前容器为新的镜像 | |
cp | 从容器中拷贝指定文件或者目录到宿主机中 | |
create | 创建一个新的容器,同run,但不启动容器 | |
diff | 查看docker容器变化 | |
events | 从docker服务获取容器实时事件 | |
exec | 在已存在的容器上运行命令 | |
export | 导出容器的内容流作为一个tar归档文件[对应import] | |
history | 展示一个镜像形成历史 | |
images | 列出系统当前镜像 | |
import | 从tar包中的内容创建一个新的文件系统映像[对应export] | |
info | 显示系统相关信息 | |
inspect | 查看容器详细信息 | |
kill | kill指定docker容器 | |
load | 从一个tar包中加载一个镜像[对应save] | |
login | 注册或者登录一个docker源服务器 | |
logout | 从当前docker registry退出 | |
logs | 输出当前容器日志信息 | |
port | 查看映射端口对应的容器内部源端口 | |
pause | 暂停容器 | |
ps | 列出容器列表 | |
pull | 从docker镜像源服务器拉取指定镜像或者库镜像 | |
push | 从docker镜像源服务器拉取指定镜像或者库镜像 | |
restart | 重启运行的容器 | |
rm | 移除一个或者多个容器 | |
rmi | 移除一个或多个镜像[无容器使用该镜像才可删除,否则需要删除相关容器才可继续或 -f 强制删除] | |
run | 创建一个新的容器并运行一个命令 | |
save | 保存一个镜像为一个tar包[对应load] | |
search | 在docker hub中搜索镜像 | |
start | 启动容器 | |
stop | 启动容器 | |
tag | 给源中镜像打标签 | |
top | 查看容器中的进程信息 | |
unpause | 取消暂停容器 | |
version | 查看docker版本号 | |
wait | 截取容器停止时的退出状态值 |
对于以上命令,如果不清楚其中命令 参数信息,可通过 docker command —help 查看详细说明
以 images 为例
docker images --help
[root@VM-0-7-centos ~]# docker images —help
Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]
List images
Options:
-a, —all Show all images (default hides intermediate images)
—digests Show digests
-f, —filter filter Filter output based on conditions provided
—format string Pretty-print images using a Go template
—no-trunc Don’t truncate output
-q, —quiet Only show image IDs
1.环境搭建
1.1 安装 docker 服务端
# 1. 卸载原本可能存在的旧版
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
>>>>>
Loaded plugins: fastestmirror, langpacks
No Match for argument: docker
No Match for argument: docker-client
No Match for argument: docker-client-latest
No Match for argument: docker-common
No Match for argument: docker-latest
No Match for argument: docker-latest-logrotate
No Match for argument: docker-logrotate
No Match for argument: docker-engine
No Packages marked for removal
# 2.安装 Docker Engine-Community
# 使用 Docker 仓库进行安装
# 在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库。之后,您可以从仓库安装和更新 Docker。
# 2.1 设置仓库
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
# 2.2 使用以下命令来设置稳定的仓库。
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 2.3 真正开始安装Docker Engine-Community
sudo yum install docker-ce docker-ce-cli containerd.io
因为 docker 服务器在国外,国内访问较慢,因此需要通过 镜像加速器 进行加速,国内主要的 docker 镜像加速器地址如下:
- 科大镜像:https://docker.mirrors.ustc.edu.cn/
- 网易:https://hub-mirror.c.163.com/
- 阿里云:https://<你的ID>.mirror.aliyuncs.com
- 七牛云加速器:https://reg-mirror.qiniu.com
具体操作参考链接:菜鸟教程-Docker 镜像加速
以 阿里云 为例
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://x4lyyl7d.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
1.2 查看是否安装成功/查看版本
docker -v
# Docker version 20.10.11, build dea9396
1.3 卸载 docker
# 卸载安装包
yum remove docker-ce
# 删除容器,镜像,配置文件
rm -rf /var/lib/docker
2.启动 docker
systemctl start docker
>>>
docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2021-11-23 23:08:26 CST; 15s ago
Docs: https://docs.docker.com
Main PID: 30045 (dockerd)
Tasks: 7
Memory: 26.5M
CGroup: /system.slice/docker.service
└─30045 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
3.2、镜像
3.2.1、镜像搜索
先从本地,再从远端
docker search xxxx
3.2.2、镜像远程拉取
docker pull xxx
3.2.3、删除
docker rmi xxx
删除时,需要先确认以该镜像运行的 容器 是否正在运行,否则会提示
Error response from daemon: conflict: unable to delete feb5d9fea6a5 (must be forced) - image is being used by stopped container 9faaf809b35c
查看正在运行的容器信息
# 查看容器运行历史
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eed53c659ffa hello-world “/hello” 30 minutes ago Exited (0) 30 minutes ago silly_maxwell
9faaf809b35c hello-world “/hello” 7 days ago Exited (0) 7 days ago funny_ride根据 CONTAINER ID 删除指定 容器
docker rm eed53c659ffa
再次删除镜像
上一步将 该镜像对应的容器都删除完毕后,再重新删除该镜像docker rmi xxx
批量(全部删除)
docker rmi -f $(docker images -qa)
3.2.4、构建(Build)
主要用在 根据 Dockerfile 构建一个自定义镜像。具体 Dockerfile 的介绍 :xxxx
示例:
cat Dockerfile
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
然后在当前文件夹下构建
docker build -t 镜像名称 .
参数说明:
- -t :指定要创建的目标镜像名
- . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
3.2.5、提交
当想把进行一定自定义修改的 容器 反向生成一个全新的镜像时使用。
docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
各个参数说明:
- -m: 提交的描述信息
- -a: 指定镜像作者
- e218edb10161:容器 ID
- runoob/ubuntu:v2: 指定要创建的目标镜像名
3.3、容器
3.3.1、启动容器
docker run -it ubuntu /bin/bash
参数说明:
- -i: 交互式操作。
- -t: 终端。
- -d:后台运行
- ubuntu: ubuntu 镜像。
- /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
如果要退出,直接输入 exit(也可以直接 ctrl + z) 强制中断退出,并结束容器
如果是以有交互的后台运行(-itd) 方式启动,则输入 exit 不会直接结束容器
3.3.2、启动已停止的容器
查看容器运行历史
docker ps -a
重新启动容器
docker start 容器ID
3.3.3、停止容器
查看正在运行的容器
docker ps
停止(正在运行)的容器
docker stop 容器
3.3.4、进入容器
此处进入的是以后台运行方式(有 -d) 运行的容器。容器启动后会进入后台,如果要进入容器,则有两种方式。
- docker attach
- docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
attach
用这种方式进入,如果输入 exit 退出,就会使容器停止docker attach 容器ID
exec
docker exec -it 容器ID /bin/bash
如果从这个容器退出,容器不会停止
3.3.5、删除容器
删除的是已经停止了的容器,如果要删除正在运行容器,可以通过强制删除的方式
docker rm -rf 容器ID
也可以先停止运行的容器,再删除
方法二:
docker rm $(docker ps -a -q)
<a name="qeF3k"></a>
### 3.3.6、查看容器日志
查看容器应用的日志
```shell
docker logs -f 容器ID
3.3.7、查看容器内进程信息
docker top 容器ID
UID PID PPID C STIME TTY TIME CMD
root 10315 10296 0 11:43 pts/0 00:00:17 /usr/local/openjdk-11/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start
3.3.8、查看容器内信息
以 json 的形式显示容器内的配置信息,状态 等等
docker inspect 容器ID
[
{
“Id”: “690274b4837e9720777cb89730b548bffdbf3acc6e8659605d944437820f7f76”,
“Created”: “2021-12-01T03:43:09.700425388Z”,
“Path”: “catalina.sh”,
“Args”: [
“run”
],
“State”: {
“Status”: “running”,
“Running”: true,
“Paused”: false,
“Restarting”: false,
“OOMKilled”: false,
“Dead”: false,
“Pid”: 10315,
“ExitCode”: 0,
“Error”: “”,
“StartedAt”: “2021-12-01T03:43:10.088403631Z”,
“FinishedAt”: “0001-01-01T00:00:00Z”
},
“Image”: “sha256:904a98253fbf7ce6ff0d5410387256c5fe4eedc5ff2fe130c821b6522558b5bf”,
“ResolvConfPath”: “/var/lib/docker/containers/690274b4837e9720777cb89730b548bffdbf3acc6e8659605d944437820f7f76/resolv.conf”,
“HostnamePath”: “/var/lib/docker/containers/690274b4837e9720777cb89730b548bffdbf3acc6e8659605d944437820f7f76/hostname”,
“HostsPath”: “/var/lib/docker/containers/690274b4837e9720777cb89730b548bffdbf3acc6e8659605d944437820f7f76/hosts”,
“LogPath”: “/var/lib/docker/containers/690274b4837e9720777cb89730b548bffdbf3acc6e8659605d944437820f7f76/690274b4837e9720777cb89730b548bffdbf3acc6e8659605d944437820f7f76-json.log”,
“Name”: “/cool_noyce”,
“RestartCount”: 0,
“Driver”: “overlay2”,
“Platform”: “linux”,
“MountLabel”: “”,
“ProcessLabel”: “”,
“AppArmorProfile”: “”,
“ExecIDs”: null,
“HostConfig”: {
“Binds”: null,
“ContainerIDFile”: “”,
“LogConfig”: {
“Type”: “json-file”,
“Config”: {}
},
“NetworkMode”: “default”,
“PortBindings”: {},
“RestartPolicy”: {
“Name”: “no”,
“MaximumRetryCount”: 0
},
“AutoRemove”: false,
“VolumeDriver”: “”,
“VolumesFrom”: null,
“CapAdd”: null,
“CapDrop”: null,
“CgroupnsMode”: “host”,
“Dns”: [],
“DnsOptions”: [],
“DnsSearch”: [],
“ExtraHosts”: null,
“GroupAdd”: null,
“IpcMode”: “private”,
“Cgroup”: “”,
“Links”: null,
“OomScoreAdj”: 0,
“PidMode”: “”,
“Privileged”: false,
“PublishAllPorts”: false,
“ReadonlyRootfs”: false,
“SecurityOpt”: null,
“UTSMode”: “”,
“UsernsMode”: “”,
“ShmSize”: 67108864,
“Runtime”: “runc”,
“ConsoleSize”: [
0,
0
],
“Isolation”: “”,
“CpuShares”: 0,
“Memory”: 0,
“NanoCpus”: 0,
“CgroupParent”: “”,
“BlkioWeight”: 0,
“BlkioWeightDevice”: [],
“BlkioDeviceReadBps”: null,
“BlkioDeviceWriteBps”: null,
“BlkioDeviceReadIOps”: null,
“BlkioDeviceWriteIOps”: null,
“CpuPeriod”: 0,
“CpuQuota”: 0,
“CpuRealtimePeriod”: 0,
“CpuRealtimeRuntime”: 0,
“CpusetCpus”: “”,
“CpusetMems”: “”,
“Devices”: [],
“DeviceCgroupRules”: null,
“DeviceRequests”: null,
“KernelMemory”: 0,
“KernelMemoryTCP”: 0,
“MemoryReservation”: 0,
“MemorySwap”: 0,
“MemorySwappiness”: null,
“OomKillDisable”: false,
“PidsLimit”: null,
“Ulimits”: null,
“CpuCount”: 0,
“CpuPercent”: 0,
“IOMaximumIOps”: 0,
“IOMaximumBandwidth”: 0,
“MaskedPaths”: [
“/proc/asound”,
“/proc/acpi”,
“/proc/kcore”,
“/proc/keys”,
“/proc/latency_stats”,
“/proc/timer_list”,
“/proc/timer_stats”,
“/proc/sched_debug”,
“/proc/scsi”,
“/sys/firmware”
],
“ReadonlyPaths”: [
“/proc/bus”,
“/proc/fs”,
“/proc/irq”,
“/proc/sys”,
“/proc/sysrq-trigger”
]
},
“GraphDriver”: {
“Data”: {
“LowerDir”: “/var/lib/docker/overlay2/b9892b76ec15efe2aa0ca4dfdf3ec82020e8d1ebacc48f936d5726743551fa88-init/diff:/var/lib/docker/overlay2/b26f5453c2bc0054925152abe19596875e8e2c22ff5f9a78e57a8936c392a5b3/diff:/var/lib/docker/overlay2/43e7f05c6d44e97d21d1b2917ff533246870cf4f77856a12f60791dde2e89ad0/diff:/var/lib/docker/overlay2/64de179aad06f1c2ec05ebe3c5b7d3749d2b85ea7a5ca63b3a0fc378281941d9/diff:/var/lib/docker/overlay2/f84b56821635e4f422a75b1f45937cd1197514c29f19180b02022f720e2945bc/diff:/var/lib/docker/overlay2/a80b72e2c662fcaa63bc2d4468e7d2d9e318e759efea4a2860f9634667578270/diff:/var/lib/docker/overlay2/b3d7ec37dfd68aab92881aa51d0039aa08995ca1611a6f8c35fc62da97bc6e5c/diff:/var/lib/docker/overlay2/7101466adb34e32f6ace57583593c10a8732a96d4cac961bc88f22534fb5604b/diff:/var/lib/docker/overlay2/9fb156af467499ef6b375bb993eebd4b04389806b7e0a2a3766de81de836a43f/diff:/var/lib/docker/overlay2/fcd1b6e4508c61e2a8ad72b408968f644d1208464789b749825e6841ab92998a/diff:/var/lib/docker/overlay2/d4a986360761cb5158c5376b2dade54dd2754592ea9e567fd52b482397be3266/diff”,
“MergedDir”: “/var/lib/docker/overlay2/b9892b76ec15efe2aa0ca4dfdf3ec82020e8d1ebacc48f936d5726743551fa88/merged”,
“UpperDir”: “/var/lib/docker/overlay2/b9892b76ec15efe2aa0ca4dfdf3ec82020e8d1ebacc48f936d5726743551fa88/diff”,
“WorkDir”: “/var/lib/docker/overlay2/b9892b76ec15efe2aa0ca4dfdf3ec82020e8d1ebacc48f936d5726743551fa88/work”
},
“Name”: “overlay2”
},
“Mounts”: [],
“Config”: {
“Hostname”: “690274b4837e”,
“Domainname”: “”,
“User”: “”,
“AttachStdin”: false,
“AttachStdout”: false,
“AttachStderr”: false,
“ExposedPorts”: {
“8080/tcp”: {}
},
“Tty”: true,
“OpenStdin”: true,
“StdinOnce”: false,
“Env”: [
“PATH=/usr/local/tomcat/bin:/usr/local/openjdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”,
“JAVA_HOME=/usr/local/openjdk-11”,
“LANG=C.UTF-8”,
“JAVA_VERSION=11.0.13”,
“CATALINA_HOME=/usr/local/tomcat”,
“TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib”,
“LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib”,
“GPG_KEYS=A9C5DF4D22E99998D9875A5110C01C5A2F6059E7”,
“TOMCAT_MAJOR=10”,
“TOMCAT_VERSION=10.0.13”,
“TOMCAT_SHA512=fecfe06f38ff31e31fa43c15f2566f6fcd26bb874a9b7c0533087be81d1decd97f81eefeaca7ecb5ab2b79a3ea69ed0459adff5f9d55c05f5af45f69b0725608”
],
“Cmd”: [
“catalina.sh”,
“run”
],
“Image”: “tomcat”,
“Volumes”: null,
“WorkingDir”: “/usr/local/tomcat”,
“Entrypoint”: null,
“OnBuild”: null,
“Labels”: {}
},
“NetworkSettings”: {
“Bridge”: “”,
“SandboxID”: “a44fa548388253cf7828cd56c89059e14d9e4c8aec8141ab28768f1d2ece72de”,
“HairpinMode”: false,
“LinkLocalIPv6Address”: “”,
“LinkLocalIPv6PrefixLen”: 0,
“Ports”: {
“8080/tcp”: null
},
“SandboxKey”: “/var/run/docker/netns/a44fa5483882”,
“SecondaryIPAddresses”: null,
“SecondaryIPv6Addresses”: null,
“EndpointID”: “6cca0a21013096aa6af08a75decc9fb1503bcccbd4ab864184cf57cb3a885553”,
“Gateway”: “172.17.0.1”,
“GlobalIPv6Address”: “”,
“GlobalIPv6PrefixLen”: 0,
“IPAddress”: “172.17.0.2”,
“IPPrefixLen”: 16,
“IPv6Gateway”: “”,
“MacAddress”: “02:42:ac:11:00:02”,
“Networks”: {
“bridge”: {
“IPAMConfig”: null,
“Links”: null,
“Aliases”: null,
“NetworkID”: “694cac0be2cb57dfecdc3dda30cb41ae8906869998a9026376628e2f74b6ddff”,
“EndpointID”: “6cca0a21013096aa6af08a75decc9fb1503bcccbd4ab864184cf57cb3a885553”,
“Gateway”: “172.17.0.1”,
“IPAddress”: “172.17.0.2”,
“IPPrefixLen”: 16,
“IPv6Gateway”: “”,
“GlobalIPv6Address”: “”,
“GlobalIPv6PrefixLen”: 0,
“MacAddress”: “02:42:ac:11:00:02”,
“DriverOpts”: null
}
}
}
}
]
4、仓库管理(docker hub)
就像 github 一样,docker 也有集中管理镜像的地方,用户可以上传自定义镜像,也可以从上面拉去其他用户编写完成的 docker 镜像,其中也有部分 docker 官方维护的镜像。 docker pull xxx 其实也是从 docker hub 中拉取的。
官方链接:Docker Hub
操作参考: 菜鸟教程-Docker 仓库管理
4.1、基本操作
4.1.1、登录
docker login
4.1.2、提交本地镜像到远程仓库
先给本地镜像打一个标签
经过上述命令,本地会生成一个新的镜像docker tag 本地镜像名:本地镜像版本 远程仓库用户名/远程仓库镜像名:远程镜像版本号
推送到远程
镜像名命名规范: docker hub用户名/仓库名docker push 镜像名:镜像版本
4.1.3、删除打包后的镜像
如果想删除打包后的镜像,对于非
latest
版本的镜像,不能直接docker rmi registry.cn-hangzhou.aliyuncs.com/hzx_dev/nginx
,需要说明详细要删除的版本docker rmi registry.cn-hangzhou.aliyuncs.com/hzx_dev/nginx:1.0.0
4.1.4、登出
docker logout
>>>>>>>>>>
Removing login credentials for https://index.docker.io/v1/
4.1.5、推送到远程镜像仓库
登录阿里云Docker Registry
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。
您可以在访问凭证页面修改凭证密码。$ docker login --username=何昭翔 registry.cn-hangzhou.aliyuncs.com
从Registry中拉取镜像
$ docker pull registry.cn-hangzhou.aliyuncs.com/hezx_test/springboot:[镜像版本号]
将镜像推送到Registry
请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。$ docker login --username=何昭翔 registry.cn-hangzhou.aliyuncs.com
$ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/hezx_test/springboot:[镜像版本号]
$ docker push registry.cn-hangzhou.aliyuncs.com/hezx_test/springboot:[镜像版本号]
4.2、阿里云远程镜像仓库
登录地址:阿里云远程镜像仓库
4.2.1、登录
4.2.2、创建个人版实例
4.2.3、远程链接登录
按照以上步骤就能成功登录连接远程阿里云镜像仓库了
4.2.4、创建远程仓库
此时如果想从本地拉取或者从本地推送镜像到远程镜像仓库,还需要进行仓库信息的配置。
仓库名组成:命名空间+仓库名
上传成功后截图
4.3、自建 Harbor
自建 Harbor 需要用到 docker-compose 相关技术,具体展开查看3_Docker进阶
5.Dockerfile
1.常用指令
RUN
RUN [“可执行文件”, “参数1”, “参数2”]
例如:
RUN [“./test.php”, “dev”, “offline”] 等价于 RUN ./test.php dev offline
- 说明<br />用于执行后面跟着的命令行命令<br />**注意:**<br />Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如: 以上执行会创建 3 层镜像。可简化为以下格式: <br />如上,以 **&&** 符号连接命令,这样执行后,只会创建 1 层镜像
```dockerfile
FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
FROM centos
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
FROM
格式
FROM <image>
# 或者 FROM <image>:<tag>
说明
FROM指令的功能是为后面的指令提供基础镜像,因此Dockerfile必须以FROM指令作为 第一条非注释指令 。从公共镜像库中拉取镜像很容易,基础镜像可以选择任何有效的镜像。
在一个Dockerfile中FROM指令可以出现多次,这样会构建多个镜像。tag的默认值是latest,如果参数image或者tag指定的镜像不存在,则返回错误。
COPY
格式
COPY [--chown=<user>:<group>] <源路径1>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
说明
复制命令,从上下文目录(物理机)复制文件或者目录到容器中指定路径
例如:[—chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。
<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。
<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
COPY hom* /mydir/
COPY hom?.txt /mydir/
ADD
格式
ADD [--chown=<user>:<group>] <源路径1>... <目标路径>
ADD [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
说明
ADD 指令和 COPY 使用格式类似(同样需求下,官方推荐 COPY)功能也类似。最大的差异: ADD 在执行 <源文件> 为 tar 压缩文件的话, 会自动解压到容器内指定文件夹下
CMD
格式
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...] # 推荐使用
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
说明
功能和 RUN 类似,但是两者执行的时间不一致- CMD 在 docker run 时运行
- RUN 在 docker build 时运行
CMD 会被 docker run 时,被命令行中的参数所覆盖,当 Dockerfile 中存在多个 CMD 指令的时候,只有 最后一个会生效 。
ENTRYPOINT
格式
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
说明
和CMD 功能类似,当 Dockerfile 中存在多个 ENTRYPOINT 指令时,只有最后一个会生效。但是不会被 docker run 命令行参数指定的指定所覆盖。
如果 docker run 时使用了 —entrypoint 选项,将覆盖 CMD 指令指定的程序。一般是变参 使用 CMD ,这里的 CMD 等于是给 ENTRYPOINT 传参
CMD 与 ENTRYPOINT 的使用示例:
假设已通过 Dockerfile 构建了 nginx:test 镜像:
```dockerfile FROM nginx
ENTRYPOINT [“nginx”, “-c”] # 定参 CMD [“/etc/nginx/nginx.conf”] # 变参
- 不传参数 <br />容器内会默认运行以下命令,启动主进程。
```dockerfile
$ docker run nginx:test
nginx -c /etc/nginx/nginx.conf
- 传参运行 <br />容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
$ docker run nginx:test -c /etc/nginx/new.conf
nginx -c /etc/nginx/new.conf
ENV
格式
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
说明
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
示例:
(假定宿主机已有 test.txt)FROM centos
ENV MY_DIR /myDir/
COPY test.txt $MY_DIR
RUN cat $MY_DIR/test.txt
VOLUME
格式
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
说明
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。- 避免重要的数据,因容器重启而丢失,这是非常致命的。
- 避免容器不断变大。
- 在启动容器 docker run 的时候,我们可以 通过 -v 参数修改挂载点。
docker run 会自动在宿主机中随机找一个文件路径进行映射关联
查看具体映射关系,可通过
docker inspect 容器ID
在结果 json 中 搜索 Mounts ,示例如下:
VOLUME [ "/data" ]
//...
"Mounts": [
{
"Type": "volume",
"Name": "675bba435a6580f7c601a5c59c967616171fd3b3377dd0359f7d053ca0599ead",
// Source 后面的地址就是宿主机的映射路径
"Source": "/var/lib/docker/volumes/675bba435a6580f7c601a5c59c967616171fd3b3377dd0359f7d053ca0599ead/_data",
// Destination:后面的地址就是容器内的映射地址
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
//...
至此,宿主机和容器内就有数据卷进行联通,如果在宿主机中该目录下操作文件,对应容器内也会实时更新。
如果容器停止,宿主机关联的路径并不会就此取消,还会继续存在,并保存之前关联的文件
EXPOSE
格式
EXPOSE <端口1> [<端口2>...]
说明
仅仅只是声明端口。- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
- 会被 docker run 时被 参数 -p /-P 替换。在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
```dockerfile FROM centos EXPOSE 1234
> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4698a9d2ad9c env_test “/bin/bash” 4 seconds ago Up 3 seconds 1234/tcp elastic_lamarr ```
WORKDIR
格式
WORKDIR <工作目录路径>
说明
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
近似 cd 切换当前路径
示例: 则最后 pwd 输出的路径是 /a/b/cWORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
USER
格式
USER <用户名>[:<用户组>]
说明
用于指定执行 后续命令 的用户和用户组,这边只是 切换 后续命令执行的用户( 用户和用户组必须提前已经存在 )。
LABEL
格式
LABEL <key>=<value> <key>=<value> <key>=<value> ...
说明
功能和旧版的 MAINTAINER 相同,都是给 容器信息中添加指定信息( docker inspect 容器ID)
示例:
效果FROM centos
LABEL MY_NAME="ZS"
LABEL MY_AGE="18"
//...
"Config": {
"Hostname": "e0d774560afc",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": true,
"OpenStdin": true,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "env_test",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
//自定义 LABEL 信息
"MY_AGE": "18",
"MY_NAME": "ZS",
"org.label-schema.build-date": "20210915",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
}
//...
2.构建Dockerfile
主要用到的命令 :
docker build [OPTIONS] PATH | URL | -
OPTIONS说明:
- —build-arg=[] :设置镜像创建时的变量;
- —cpu-shares :设置 cpu 使用权重;
- —cpu-period :限制 CPU CFS周期;
- —cpu-quota :限制 CPU CFS配额;
- —cpuset-cpus :指定使用的CPU id;
- —cpuset-mems :指定使用的内存 id;
- —disable-content-trust :忽略校验,默认开启;
- -f :指定要使用的Dockerfile路径;
- —force-rm :设置镜像过程中删除中间容器;
- —isolation :使用容器隔离技术;
- —label=[] :设置镜像使用的元数据;
- -m :设置内存最大值;
- —memory-swap :设置Swap的最大值为内存+swap,”-1”表示不限swap;
- —no-cache :创建镜像的过程不使用缓存;
- —pull :尝试去更新镜像的新版本;
- —quiet, -q :安静模式,成功后只输出镜像 ID;
- —rm :设置镜像成功后删除中间容器;
- —shm-size :设置/dev/shm的大小,默认值是64M;
- —ulimit :Ulimit配置。
- —squash :将 Dockerfile 中所有的操作压缩为一层。
- —tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
- —network: 默认 default。在构建期间设置RUN指令的网络模式
命令最后的 . 表示当前目录下 ,会自动识别当前目录下的 Dockerfile 文件,并构建成镜像。
简单示例:
docker build -t my_centos .
6.网络-Dokcer0
参考链接:【csdn】Docker学习(五)docker网络(Docker0、evth-pair 技术、—link、docker network)
6.1、概述
docker 安装在 linux 后,就会创建一个 虚拟网卡
等到容器启动后,docker 会给容器随机安排一个 ip ,并且不同容器之间默认是可以互相访问的。因为在 docker run
其实有一个参数 --network
这个是可以设置网络的。默认是直接用 docker0,所以可以理解 默认情况下, 容器是在同一个网络下,所以就互相可以访问。
6.2、测试默认网络
先启动两个 centos 镜像
# 第一个 centos 容器,名字为 centos01
docker run -itd -P --name centos01 centos
# 第二个 centos 容器,名字为 centos02
docker run -itd -P --name centos02 centos
再分别查看两个容器的IP信息
docker exec -it centos01 ip addr
docker exec -it centos02 ip addr
6.2.1、先使用ip测试连通性
docker exec -it centos01 ping 172.17.0.3
6.2.2、再使用容器名(域名)进行测试
docker exec -it centos02 ping 172.17.0.2
结果不通,说明默认情况下,网络只支持通过IP进行访问。
但这样就会造成新的问题:docker 每次重建后就会重新生成IP,IP也会随着进行变化。
针对以上问题,docker 两种解决方案,可以用来解决访问域名访问问题,并且也形成 网络隔离,防止不同作用的容器可能造成的网络冲突,影响。
- 容器互联—link
- Docker网络 network
6.3、—link 容器互联
设置容器互联需要在 容器启动时设置--link
链接另一个已启动好的容器# --link
docker run -itd --name centos03 --link centos01 centos
# 测试,成功
docker exec -it centos03 ping centos01
# 反向测试,失败
docker exec -it centos01 ping centos03
从上图可知,反向 ping 是不通的,说明--link
是只有单向性,只有配置的映射单向互相访问,不支持双向6.4、network 自定义网络
为了解决--link
单向访问问题,并且为了形成网络组
(也即如果是在同一个组内,可以互相访问。如果不同组,则彼此访问不通),引入了新的指令:**network**
通过这个指令,可以创建,加入自定义网络
docker network COMMAND
>>>
Usage: docker network COMMAND
Manage networks
Commands:
# 将一个容器加入到一个网络中
connect Connect a container to a network
# 创建一个网络
create Create a network
# 从一个网络中断开
disconnect Disconnect a container from a network
# 显示网络详情
inspect Display detailed information on one or more networks
# 查看网络列表
ls List networks
# 移除所有未被使用的网络
prune Remove all unused networks
# 移除一个或者多个网络
rm Remove one or more networks
Run 'docker network COMMAND --help' for more information on a command.
最终目标是 自定义多个网络,网络内容器之间可以通过域名访问,网络和网络之间形成网络隔离。并且通过设置,网络和指定容器之间也是可以访问
6.3.1、inspect - 详情
6.3.2、create - 创建
创建一个自定义网络
docker network create --driver=bridge --subnet=192.168.0.0/16 br0
在运行容器时,通过 --network 网络名
指定该容器所在的网络
示例:
docker run -itd --network my-net centos
# 指定网络为 自定义的 my-net
查看对比 默认网络和自定义网络的差异:
- 默认ip:172.17.0.3
- 自定义 my-net : 192.168.0.2
6.3.3、容器使用自定义网络
# 创建时 通过 --network 声明连接的网络,默认 docker0
docker run -itd --network br0 --name centos04 centos
6.3.4、connect - 连接
将一个容器加入到某一个网络中。
根据网络知识可知,在不同网段中的网络是不能访问的,以上述提到的 192.168.0.2
和 172.17.0.3
为例
docker exec -it 385f3fac3e47 ping 172.17.0.3
# 385f3fac3e47 是使用自定义网络,ip 192.168.0.2
# 测试结果是访问不通
但是可以将 172.17.0.3 所属的容器加入到网络中。
docker network connect my-net d401cc22782d
# docker network connect 自定义网络名 将要加入的容器ID
# d401cc22782d 是 172.17.0.3所属的容器
通过 dokcer network inspect my-net
查看可得
刚才 d401cc22782d 对应的容器已经加入 my-net 中,并且被赋予新的 ip,至此, d401cc22782d 该容器就变成 一个容器, 两个IP
最后再两个容器相互请求,进行对比,从下图可知,两个容器之间是可以访问的
6.3.5、ls - 列表
docker network ls
6.3.6、rm - 移除
docker network rm 自定义网络名
在移除时,需要先停止,删除已经使用该自定义网络的容器