Docker基本使用总结
Docker的基本使用
Docker命令示意图:
1.1 准备工作
1.1.1 安装、启动以及卸载
(1)centos安装docker
-
删除旧版本
sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
-
The contents of
/var/lib/docker/
, including:- images
- containers
- volumes
- networks
-
The Docker Engine package is now called
docker-ce
.
(2)安装
-
安装时使用稳定版仓库
sudo yum install -y yum-utils sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
-
使用其他仓库
nightly:
sudo yum-config-manager --enable docker-ce-nightly
test channel:
sudo yum-config-manager --enable docker-ce-test
-
取消使用特定仓库:
sudo yum-config-manager --disable docker-ce-nightly sudo yum-config-manager --disable docker-ce-test
-
-
安装Docker引擎(最新版本)
sudo yum install docker-ce docker-ce-cli containerd.io
-
安装其他版本
检查可用版本:
yum list docker-ce --showduplicates | sort -r docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-stable docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-stable docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable docker-ce.x86_64 18.06.0.ce-3.el7
安装特定版本:
sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
-
脚本安装:
Warning:Always examine scripts downloaded from the internet before running them locally.
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh
-
(3)启动docker
-
启动
sudo systemctl start docker
-
开机启动docker守护进程服务
sudo systemctl enable docker
-
重启服务
sudo systemctl daemon-reload sudo systemctl restart docker
(4)卸载
-
卸载docker
sudo yum remove docker-ce docker-ce-cli containerd.io
-
删除容器,卷,自定义配置文件
sudo rm -rf /var/lib/docker
1.1.2 Docker在windows环境下的安装
(1)使用WSL2安装Docker
- 因为docker是采用直接利用宿主机内核的方式去执行虚拟机功能,所以在Windows环境下的docker只能运行Windows相关的系统或应用软件容器,但是我们可以利用Windows提供的WSl2来在Windows中运行一个Linux内核的Linux系统,进而运行docker;而且在Docker Desktop中,也提供了使用WSL2运行docker的方式,所以可以在Windows系统下运行基于Linux的docker!
(2)WSL2以及Windows docker desktop的安装
WSL2的介绍与使用可以去官网看,也可以找博客看。(WSL2相当于在Windows上并行运行了一个Linux内核的Linxu子系统,个人感觉使用Windows的WSl2后,最起码在新手阶段(非底层开发),可以代替常规的Linux来使用,加上Windows上的丰富的软件又可以弥补在Linux的软件匮乏,简直不要爽歪歪!!!)
(3)在WSL2中安装docker并测试:
最终效果:(使用Fluent Terminal做了一些美化)
1.2 常用命令
1.2.1 docker镜像基本使用
(1)镜像加速
-
创建或修改
/etc/docker/daemon.json
文件,修改为如下形式{ "registry-mirrors": [ "https://e9cvqj3d.mirror.aliyuncs.com", "http://hub-mirror.c.163.com", "https://registry.docker-cn.com", "https://docker.mirrors.ustc.edu.cn" ] }
-
重启生效
sudo systemctl daemon-reload sudo systemctl restart docker
(2)使用镜像
-
搜索镜像
docker search image_name
-
使用latest版本镜像
docker pull image_name
-
指定版本
docker pull image_name:tag
-
(3)查看镜像列表
-
查看下载的镜像
docker images -h 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 numeric IDs
(4)删除镜像
-
删除镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]
选项:
Options: -f, --force Force removal of the image --no-prune Do not delete untagged parents
1.2.2 容器的使用
(1)创建容器并启动
-
docker run
命令以镜像为模板作为容器执行 -
注意:如果运行的容器没有前台进程运行则该容器会直接自杀
- 可以使用top,tail命令查看日志文件来制造前台进程防止自杀
常用选项:
-
-d
:后台方式运行 -
-e Command
:指定容器应用参数 -
-it
:以终端交互方式运行 -
--name=
:指定创建的容器的名称(容器都只能使用唯一的名) -
-rm
:使用完后边删除容器 -
-p [主机IP:][docker内应用IP]
所有命令选项:
sudo docker run --help Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] Run a command in a new container Options: --add-host list Add a custom host-to-IP mapping (host:ip) -a, --attach list Attach to STDIN, STDOUT or STDERR --blkio-weight uint16 Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0) --blkio-weight-device list Block IO weight (relative device weight) (default []) --cap-add list Add Linux capabilities --cap-drop list Drop Linux capabilities --cgroup-parent string Optional parent cgroup for the container --cidfile string Write the container ID to the file --cpu-period int Limit CPU CFS (Completely Fair Scheduler) period --cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota --cpu-rt-period int Limit CPU real-time period in microseconds --cpu-rt-runtime int Limit CPU real-time runtime in microseconds -c, --cpu-shares int CPU shares (relative weight) --cpus decimal Number of CPUs --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-mems string MEMs in which to allow execution (0-3, 0,1) -d, --detach Run container in background and print container ID --detach-keys string Override the key sequence for detaching a container --device list Add a host device to the container --device-cgroup-rule list Add a rule to the cgroup allowed devices list --device-read-bps list Limit read rate (bytes per second) from a device (default []) --device-read-iops list Limit read rate (IO per second) from a device (default []) --device-write-bps list Limit write rate (bytes per second) to a device (default []) --device-write-iops list Limit write rate (IO per second) to a device (default []) --disable-content-trust Skip image verification (default true) --dns list Set custom DNS servers --dns-option list Set DNS options --dns-search list Set custom DNS search domains --domainname string Container NIS domain name --entrypoint string Overwrite the default ENTRYPOINT of the image -e, --env list Set environment variables --env-file list Read in a file of environment variables --expose list Expose a port or a range of ports --gpus gpu-request GPU devices to add to the container ('all' to pass all GPUs) --group-add list Add additional groups to join --health-cmd string Command to run to check health --health-interval duration Time between running the check (ms|s|m|h) (default 0s) --health-retries int Consecutive failures needed to report unhealthy --health-start-period duration Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s) --health-timeout duration Maximum time to allow one check to run (ms|s|m|h) (default 0s) --help Print usage -h, --hostname string Container host name --init Run an init inside the container that forwards signals and reaps processes -i, --interactive Keep STDIN open even if not attached --ip string IPv4 address (e.g., 172.30.100.104) --ip6 string IPv6 address (e.g., 2001:db8::33) --ipc string IPC mode to use --isolation string Container isolation technology --kernel-memory bytes Kernel memory limit -l, --label list Set meta data on a container --label-file list Read in a line delimited file of labels --link list Add link to another container --link-local-ip list Container IPv4/IPv6 link-local addresses --log-driver string Logging driver for the container --log-opt list Log driver options --mac-address string Container MAC address (e.g., 92:d0:c6:0a:29:33) -m, --memory bytes Memory limit --memory-reservation bytes Memory soft limit --memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap --memory-swappiness int Tune container memory swappiness (0 to 100) (default -1) --mount mount Attach a filesystem mount to the container --name string Assign a name to the container --network network Connect a container to a network --network-alias list Add network-scoped alias for the container --no-healthcheck Disable any container-specified HEALTHCHECK --oom-kill-disable Disable OOM Killer --oom-score-adj int Tune host's OOM preferences (-1000 to 1000) --pid string PID namespace to use --pids-limit int Tune container pids limit (set -1 for unlimited) --platform string Set platform if server is multi-platform capable --privileged Give extended privileges to this container -p, --publish list Publish a container's port(s) to the host -P, --publish-all Publish all exposed ports to random ports --read-only Mount the container's root filesystem as read only --restart string Restart policy to apply when a container exits (default "no") --rm Automatically remove the container when it exits --runtime string Runtime to use for this container --security-opt list Security Options --shm-size bytes Size of /dev/shm --sig-proxy Proxy received signals to the process (default true) --stop-signal string Signal to stop a container (default "SIGTERM") --stop-timeout int Timeout (in seconds) to stop a container --storage-opt list Storage driver options for the container --sysctl map Sysctl options (default map[]) --tmpfs list Mount a tmpfs directory -t, --tty Allocate a pseudo-TTY --ulimit ulimit Ulimit options (default []) -u, --user string Username or UID (format: <name|uid>[:<group|gid>]) --userns string User namespace to use --uts string UTS namespace to use -v, --volume list Bind mount a volume --volume-driver string Optional volume driver for the container --volumes-from list Mount volumes from the specified container(s) -w, --workdir string Working directory inside the container
(2)docker容器进程查看
-
查看运行进程
sudo docker ps
-
选项
Usage: docker ps [OPTIONS] List containers Options: -a, --all Show all containers (default shows just running) -f, --filter filter Filter output based on conditions provided --format string Pretty-print containers using a Go template -n, --last int Show n last created containers (includes all states) (default -1) -l, --latest Show the latest created container (includes all states) --no-trunc Don't truncate output -q, --quiet Only display numeric IDs -s, --size Display total file sizes
-
(3)docker容器的启动、终止、进入、退出、暂停、继续
-
启动已经停止容器
docker start [OPTIONS] CONTAINER [CONTAINER...]
-
选项:
Start one or more stopped containers Options: -a, --attach Attach STDOUT/STDERR and forward signals --checkpoint string Restore from this checkpoint --checkpoint-dir string Use a custom checkpoint storage directory --detach-keys string Override the key sequence for detaching a container -i, --interactive Attach container's STDIN
-
-
通过默认终端来连接正在运行中的容器
docker attach [OPTIONS] CONTAINER
-
选项:
Attach local standard input, output, and error streams to a running container Options: --detach-keys string Override the key sequence for detaching a container --no-stdin Do not attach STDIN --sig-proxy Proxy all received signals to the process (default true)
-
-
通过一个新的终端进入正在运行中的容器
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
-
选项:
Run a command in a running container Options: -d, --detach Detached mode: run command in the background --detach-keys string Override the key sequence for detaching a container -e, --env list Set environment variables -i, --interactive Keep STDIN open even if not attached --privileged Give extended privileges to the command -t, --tty Allocate a pseudo-TTY -u, --user string Username or UID (format: <name|uid>[:<group|gid>]) -w, --workdir string Working directory inside the container
-
-
暂停容器
docker pause CONTAINER [CONTAINER...]
-
恢复暂停
docker unpause CONTAINER [CONTAINER...]
-
停止容器
docker stop [OPTIONS] CONTAINER [CONTAINER...]
选项:
-t, --time int Seconds to wait for stop before killing it (default 10)
-
强制退出容器
docker kill [OPTIONS] CONTAINER [CONTAINER...]
-s, --signal string Signal to send to the container (default "KILL")
该方式可能发生数据丢失
(4)文件复制
-
主机文件复制到容器
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
-
容器文件复制到主机中
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
-
选项:
Copy files/folders between a container and the local filesystem Use '-' as the source to read a tar archive from stdin and extract it to a directory destination in a container. Use '-' as the destination to stream a tar archive of a container source to stdout. Options: -a, --archive Archive mode (copy all uid/gid information) -L, --follow-link Always follow symbol link in SRC_PATH
-
(5)容器的删除
-
docker创建临时使用的容器如果不删除会一直占用空间
docker rm containerID/name
-
选项:
Options: -f, --force Force the removal of a running container (uses SIGKILL) -l, --link Remove the specified link -v, --volumes Remove anonymous volumes associated with the container
-
-
删除所有创建的docker容器
docker rm `docker ps -a -q`
1.3 Docker可视化管理
1.3.1 portainer
(1)安装并启动portainer
-
运行
docker run -d -p 7072:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
- 搜索时可以搜到中文版但是考虑稳定性与安全性不建议使用。
(2)查看效果
-
登录网站设置好个人账号密码后,连接localhost:
-
点击local进行操作
1.4 Docker镜像
1.4.1 镜像介绍
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
(1)UnionFS(联合文件系统)
-
UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Dokcer镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的镜像。
-
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统加载起来,这样最终的文件系统会包含所有的底层文件和目录
(2)查看镜像信息
-
查看镜像信息
docker image inspect [OPTIONS] IMAGE:[tag] [IMAGE:[tag]...]
-
选项:
Display detailed information on one or more images Options: -f, --format string Format the output using the given Go template
-
1.4.2 镜像分层
(1)Docker镜像加载原理
-
docker的镜像实际上是由一层一层的文件系统构成,这种层级的文件系统UnionFS。
-
bootfs(boot file system)
主要包含bootloader
和kernel
- bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的linux/unix系统是一样的,包含boot加载器内核。
- 当boot加载完之后整个内核就都在内存中了,此时内存的使用权已经由bootfs交给内核了,此时系统也会卸载bootfs
-
rootfs(root file system)
在bootfs之上包含的是经典Linux系统中的/dev,/proc/bin,/ect等目录与文件,可以将rootfs看作linux发行版; -
对以一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就行,因为底层直接用host和kernel,自己只需要提供rootfs就行。由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs
(2)镜像分层介绍
-
当下载部分文件已有的情况下是可以跳过下载,实际上表示本机内已经存在该层文件。
-
启动镜像时,一个新的可写层会加载到镜像的顶层。这一层通常称为"容器层",之下是"镜像层"。
容器层可以读写,容器所有发生文件变更写都发生在这一层。镜像层只允许读取,read-only。
1.4.3 自制镜像
(1)提交自己的镜像
-
从容器中创建一个新的镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
-
选项:
Create a new image from a container's changes Options: -a, --author string Author (e.g., "John Hannibal Smith <hannibal@a-team.com>") -c, --change list Apply Dockerfile instruction to the created image -m, --message string Commit message -p, --pause Pause container during commit (default true)
- 默认情况下,在提交映像时,将暂停提交的容器及其进程。这降低了在创建提交过程中遇到数据损坏的可能性。如果此行为是不需要的,则将选项设置为 false。
--pause
- 默认情况下,在提交映像时,将暂停提交的容器及其进程。这降低了在创建提交过程中遇到数据损坏的可能性。如果此行为是不需要的,则将选项设置为 false。
示例:
-
以运行的容器制造镜像( 96d596566a10 为容器ID)
docker commit -m="portainer备份" -a="niss" 96d596566a10 portainer-back:1.0
-
查看镜像
[root@niss ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE portainer-back 1.0 27e6310e3582 26 seconds ago 79.1MB wordpress latest b301a17258fe 2 days ago 540MB nginx latest 4392e5dad77d 3 days ago 132MB portainer/portainer latest cd645f5a4769 3 days ago 79.1MB redis latest 36304d3b4540 7 days ago 104MB mysql 5.7 a4fdfd462add 2 weeks ago 448MB mysql latest 30f937e841c8 2 weeks ago 541MB tomcat latest 1b6b1fe7261e 2 weeks ago 647MB centos latest 470671670cac 4 months ago 237MB hello-world latest bf756fb1ae65 5 months ago 13.3kB vulhub/php xxe ce531f8a34fa 23 months ago 230MB
-
-
保存镜像
docker save [OPTIONS] IMAGE [IMAGE...]
选项:
Save one or more images to a tar archive (streamed to STDOUT by default) Options: -o, --output string Write to a file, instead of STDOUT
-
从备份中加载镜像
docker load [OPTIONS
选项:
Load an image from a tar archive or STDIN Options: -i, --input string Read from tar archive file, instead of STDIN -q, --quiet Suppress the load output
1.4.3 dockerhub 的使用
(1)dockerhub
(2)常用命令
-
登录:dockerhub:
docker login username:yourusername password:yourpassword
或者:
docker login --username=yourusername
-
推送镜像
首先需要标记镜像:
docker tag 镜像名 yourusername/仓库名[:标签]
本地镜像推送到仓库:
docker push yourusername/仓库名[:标签]
-
退出
docker logout
(3)阿里云镜像仓库
-
登录阿里云镜像仓库服务阿里云镜像服务
-
创建命名空间
-
创建仓库
-
按提示使用
例:我的阿里云:
- 登录阿里云Docker Registry
sudo docker login --username=niss187 registry.cn-hangzhou.aliyuncs.com
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。
您可以在访问凭证页面修改凭证密码。
- 从Registry中拉取镜像
sudo docker pull registry.cn-hangzhou.aliyuncs.com/niss-images/aliyun-dockerhub:[镜像版本号]
- 将镜像推送到Registry
sudo docker login --username=niss187 registry.cn-hangzhou.aliyuncs.com sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/niss-images/aliyun-dockerhub:[镜像版本号] sudo docker push registry.cn-hangzhou.aliyuncs.com/niss-images/aliyun-dockerhub:[镜像版本号]
1.5 容器数据卷
1.5.1 容器数据卷介绍
(1)容器数据卷概念以及意义
- docker容器运行的数据本身全部保存在容器内,倘若容器被删除则数据就全部会丢失,比如MySQL,Tomcat配置文件等等。
- 在Docker中,要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束),需要将数据从宿主机挂载到容器中。
1.5.2 数据卷的使用
(1)run
命令参数挂载数据卷
-
-v 命令参数挂载数据卷
docker run -v 主机目录:容器目录:[权限] [-v 主机目录:容器目录:[权限] [-v 主机目录:容器目录:[权限]]...]
- 开始时如果宿主机没有该文件或者目录,则会自动创建
- 可以挂载多个目录
- 如果表示文件或目录要指定以绝对路径“/”开头,不然会认为是具名挂载;
- 可以在挂载目录最后设置文件权限(一旦设置,之后就很难去修改了):
ro
:read-only,即只能由宿主机创建以及修改挂载卷的文件内容;rw
:read-write
- 数据卷不会因容器的删除而被删除;
示例:
-
创建MySQL容器:
docker run -d -p 3306:3306 \ -v /home/mysql/conf:/ect/mysql/conf.d \ -v /home/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=password --name=mysql mysql:5.7
-
查看文件:
[root@niss mysql]# ls /home/mysql/data auto.cnf client-key.pem ib_logfile1 private_key.pem sys ca-key.pem ib_buffer_pool ibtmp1 public_key.pem ca.pem ibdata1 mysql server-cert.pem client-cert.pem ib_logfile0 performance_schema server-key.pem
(2)匿名挂载与具名挂载
-
匿名挂载:不指定宿主机的文件、目录路径或卷名
docker run -v /容器内路径:[权限] [-v /容器内路径:[权限]]
- 该方法挂载的卷会给一个随机的唯一卷名(不建议使用)
-
具名挂载:指定不指定宿主机的文件路径但是指定卷名
docker run -v 卷名:/容器内路径:[权限] [-v 卷名:/容器内路径:[权限]]
- 该方法挂载的卷的文件内容保存在:
/var/lib/docker/volumes/卷名/_data
例:
-
匿名挂载nginx:
docker run -d --name=nginx01 -v /usr/share/nginx nginx 328a5f13b8ef03752b5e5fa84ad99dd12c1858c05e2db6d02cae01742f7d2733 docker run -d --name=nginx02 -v nginxVol:/etc/nginx nginx 9d1f00d3ee598cbc2e5d2c69d25c0cc7fb5164254e6dd5fff40f3be3351eabb4
-
查看具名挂载的卷的信息:
docker volume inspect nginxVol [ { "CreatedAt": "2020-06-07T01:28:17+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/nginxVol/_data", "Name": "nginxVol", "Options": null, "Scope": "local" } ]
- 该方法挂载的卷的文件内容保存在:
1.5.3 docker build
制作镜像
(1)Dockerfile介绍
-
Dockerfile
是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明 -
docker build
自制镜像过程:-
docker build
命令会自动寻找名为./Dockerfile
的文件进行构建;- 也可以使用参数
-f
指定Dockerfile路径
- 也可以使用参数
-
每个关键字都要大写;
-
从上往下执行
-
表示注释;
-
每个指令都会创建一个新的镜像文件层,并提交;
-
(2)Dockerfile指令
-
FROM
:指定基础镜像。 -
MAINTAINER
:注明维护者信息。 -
RUN
:镜像构建时要运行的命令。例:
-
构建镜像时安装vim以及net-tools:
# 基础镜像 FROM centos # 维护者信息 MAINTAINER niss<xxxxxx@qq.com> # 安装工具 RUN yum -y install vim RUN yum -y install net-tools # 启动时就执行该程序 CMD /bin/bash
-
-
WORKDIR
:指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。WORKDIR <工作目录路径>
- docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
例:
-
构建一个带有vim与net-tools的centos镜像
# centos with vim and net-tools # 基础镜像 FROM centos # 维护者信息 MAINTAINER niss<xxxxxx@qq.com> # 环境 ENV MYPATH /usr/local WORKDIR $MYPATH # 安装工具 RUN yum -y install vim RUN yum -y install net-tools # 默认暴露端口 EXPOSE 80 # 启动时就执行该程序 CMD /bin/bash
-
COPY
:复制指令,从上下文目录中复制文件或者目录到容器里指定路径。COPY [--chown=<user>:<group>] <源路径1>... <目标路径> # 或者 COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
-
[--chown=
: :可选参数,用户改变复制到容器内文件的拥有者和属组。] -
<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。
例如:
COPY hom* /mydir/ COPY hom?.txt /mydir/
-
-
ADD
:ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:- ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
- ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
-
VOLUME
:定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。VOLUME ["<路径1>", "<路径2>"...] # 或者 VOLUME <路径>
- 避免重要的数据,因容器重启而丢失,这是非常致命的。
- 避免容器不断变大。
- 在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
-
EXPOSE
:声明端口EXPOSE <端口1> [<端口2>...]
-
帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
-
在运行时使用随机端口映射时,也就是 docker run -P 时,会将宿主机随机端口映射到 EXPOSE 的端口。
-
默认使用
tcp
,可以以\udp
方式使用udp:例(同时暴露tcp与udp的80端口供宿主机使用):
EXPOSE 80/tcp EXPOSE 80/udp
-
-
CMD
:类似于 RUN 指令,用于运行程序,但二者运行的时间点不同CMD <shell 命令> CMD ["<可执行文件或命令>","<param1>","<param2>",...] CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
- CMD 在docker run 时运行。
- RUN 是在 docker build为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。
- CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
- 如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个CMD指令生效
CMD示例:
-
构建Dockerfile:
FROM centos # 第一个CMD命令显示当前文件路径 CMD pwd # ping百度 CMD ping www.baidu.com
```bash $ sudo docker build -t centos-ping:1.0 . Sending build context to Docker daemon 2.048kB Step 1/3 : FROM centos ---> 831691599b88 Step 2/3 : CMD pwd ---> Running in 8e0e80b51c80 Removing intermediate container 8e0e80b51c80 ---> c1fcc514f15b Step 3/3 : CMD ping www.baidu.com ---> Running in e3e77b474742 Removing intermediate container e3e77b474742 ---> 1c0c35f1bc4b Successfully built 1c0c35f1bc4b Successfully tagged centos-ping:1.0
-
只会执行最后一条CMD命令-ping
$ sudo docker run centos-ping:1.0 PING www.a.shifen.com (180.101.49.11) 56(84) bytes of data. 64 bytes from 180.101.49.11 (180.101.49.11): icmp_seq=1 ttl=51 time=25.2 ms 64 bytes from 180.101.49.11 (180.101.49.11): icmp_seq=2 ttl=51 time=25.8 ms ...
-
当添加附加命令时,
-l
会替换掉ls -a
,已经不是一条命令了,所以会报错
-
ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
-
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:
-
如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
-
但是, 如果运行 docker run 时使用了
--entrypoint
选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。
-
ENTRYPOINT示例:
FROM centos ENTRYPOINT ["ls","-a"]
$ docker run -it centos-entry -l total 56 drwxr-xr-x 1 root root 4096 Jun 7 09:25 . drwxr-xr-x 1 root root 4096 Jun 7 09:25 .. -rwxr-xr-x 1 root root 0 Jun 7 09:25 .dockerenv lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin drwxr-xr-x 5 root root 360 Jun 7 09:25 dev ...省略 drwxr-xr-x 12 root root 4096 Jan 13 21:49 usr drwxr-xr-x 20 root root 4096 Jan 13 21:49 var
- ENRTRYPOINT会以追加方式添加命令
-
-
ENV
:设置环境变量,定义了环境变量,那么在后续的指令以及容器中,就可以使用这个环境变量ENV <key> <value> ENV <key1>=<value1> <key2>=<value2>...
-
例:
FROM centos ENV name='niss' qq='162'
构建好后运行:
$ sudo docker run -it centos-ping:1.0 /bin/bash [root@bbe47066cc11 /]# echo $name && echo $qq niss 162
-
-
ARG
:构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。ARG <参数名>[=<默认值>]
- 构建命令 docker build 中可以用
--build-arg
<参数名>=<值> 来覆盖。
- 构建命令 docker build 中可以用
-
USER
:用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)USER <用户名>[:<用户组>]
-
ONBUILD
:用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
(3).dockerignore file
-
可以通过在构建时的根目录中创建
.dockerignore
文件声明要忽略的文件,避免构建镜像时添加进一些无用文件。 -
文件路径匹配规则:
Rule Behavior # comment
Ignored.(忽略) */temp*
Exclude files and directories whose names start with temp
in any immediate subdirectory of the root. For example, the plain file/somedir/temporary.txt
is excluded, as is the directory/somedir/temp
.(匹配任意的文件夹下的以temp为开头的文件)*/*/temp*
Exclude files and directories starting with temp
from any subdirectory that is two levels below the root. For example,/somedir/subdir/temporary.txt
is excluded.(匹配两层文件夹下的以temp为开头的文件)temp?
Exclude files and directories in the root directory whose names are a one-charac*ter extension of temp
. For example,/tempa
and/tempb
are excluded.(匹配以temp为开头的tempX文件或文件夹)**/*.go
**/*.go
will exclude all files that end with.go
that are found in all directories, including the root of the build context.(匹配在根目录下的所有的后缀为.go的文件) -
使用
!
来排除所要忽略的文件:-
例如想要忽略除了README.md之外的所有的md文件:
*.md !README.md
- !只在最后一行才会起作用;
-
这种情况下所有的README文件都将被包含(不会加入被忽略名单):
*.md README-secret.md !README*.md
-
-
甚至可以使用·dockerignore文件来排除Dockerfile和.dockerignore文件。
-
更多规则请查看匹配规则官方文档
(4) docker build
构建镜像
-
用法:
docker build [OPTIONS] PATH | URL | -
-
-f dockerfile构建文件
-
-t 目标镜像:[tag]
-
不指定标签则会使用
latest
-
可以同时指定多个仓库镜像与标签,例如:
$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
-
-
-
docker history 镜像名[:tag]
查看镜像的构建过程:例:构建tomcat+jdk镜像
-
准备:
apache-tomcat-9.0.35.tar.gz jdk-8u251-linux-x64.tar.gz
-
编写Dockerfiles(需要提前准备JDK以及Tomcat压缩包)
FROM centos MAINTAINER niss<ni18724787072@outlook.com> COPY readme.md /usr/local/readme.md # ADD会自动识别tar.gz并解压至目标文件 ADD jdk-8u251-linux-x64.tar.gz /usr/local ADD apache-tomcat-9.0.35.tar.gz /usr/local # 安装vim RUN yum -y install vim # 设置环境变量 ENV MYPATH /usr/local # 设置工作目录 WORKDIR $MYPATH # 设置JDK以及Tomcat的环境变量 ENV JAVA_HOME /usr/local/jdk1.8.0_251 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.35 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh $$ tail -F /usr/local/apache-tomcat-9.0.35/logs/catalina.out
-
构建镜像
docker build -t tomcat_jdk:1.0 .
-
启动镜像
docker run -it -p 7070:8080 --name=tomcat \ -v /home/web/tomcat/webapps/:/usr/local/apache-tomcat-9.0.35/webapps/ \ -v /home/web/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs \ tomcat-jdk
-
1.6 docker网络
1.6.1 docker网络介绍
(1)安装并启动了docker服务服务器网络
-
查看docker网络
# root @ niss in ~ [10:01:00] $ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:16:3e:0e:84:10 brd ff:ff:ff:ff:ff:ff inet 172.16.121.72/20 brd 172.16.127.255 scope global dynamic eth0 valid_lft 313982894sec preferred_lft 313982894sec 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:4f:3a:be:9d brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 scope global docker0 valid_lft forever preferred_lft forever 812: veth2c09b5d@if811: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 8e:9a:e4:08:1e:21 brd ff:ff:ff:ff:ff:ff link-netnsid 0 162: br-58fd6f6d2257: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:59:73:3d:f0 brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-58fd6f6d2257 valid_lft forever preferred_lft forever
- 环回地址:127.0.0.1/8
- 内网地址:172.16.121.72/20
- docker0:172.17.0.1/16
- docker地址:172.18.0.1/16
-
启动tomcat镜像,查看网络信息
# root @ niss in ~ [10:04:31] $ docker run --name=tomcat01 -d tomcat c2fe7ba1530d5d685ad6fe63b2cc4ec6858102f27934022804ca24ff6afc7235 # root @ niss in ~ [10:04:49] $ docker exec -it tomcat01 /bin/bash root@c2fe7ba1530d:/usr/local/tomcat# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 813: eth0@if814: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
- 环回地址:127.0.0.1/8
- eth0@if810:容器启动时,docker为之分配的IP地址:inet 172.17.0.2/16
-
再次启动一个tomcat:
# root @ niss in ~ [10:08:35] $ docker exec -it tomcat02 /bin/bash root@adc336154f86:/usr/local/tomcat# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 815: eth0@if816: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
- 172.17.0.3/16
-
容器与宿主机连通性测试
- 可以ping通
1.6.2 容器互联
(1)容器互联问题
-
当以容器名为连接性测试对象时,无法识别主机
root@adc336154f86:/usr/local/tomcat# ping tomcat01 ping: tomcat01: Name or service not known
-
然而很多情况下需要以主机名作为连接对象(就像浏览网站,只需要记住url,即使IP更改,只要有人维护IP与域名的映射关系,就不会对访问者造成影响)
(2)link
-
在创建容器时使用
--link
选项来连接其他容器:# root @ niss in ~ [9:08:51] C:130 $ docker run -d -P --name=tomcat03 --link "tomcat01" --link"tomcat02" tomcat unknown flag: --linktomcat02 See 'docker run --help'. # root @ niss in ~ [9:08:57] C:125 $ docker run -d -P --name=tomcat03 --link "tomcat01" --link "tomcat02" tomcat ff37a3e051442bc939dab557a8994ccb67b69e84c67e7d6605e30b608582ac7f
连通性测试:
# root @ niss in ~ [9:10:46] C:125 $ docker exec -it tomcat03 ping tomcat01 PING tomcat01 (172.17.0.2) 56(84) bytes of data. 64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.169 ms 64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.104 ms ^C --- tomcat01 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.104/0.136/0.169/0.034 ms
-
但是此时tomcat02仍然不能以tomcat03为主机名进行连接性测试
# root @ niss in ~ [9:10:58] $ docker exec -it tomcat01 ping tomcat03 ping: tomcat03: Name or service not known
(3)docker network
命令
-
使用
docker network
命令参数: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
-
查看docker网络详细信息
# root @ niss in ~ [9:16:20] $ docker network ls NETWORK ID NAME DRIVER SCOPE a0dc6e118c93 bridge bridge local 13fc812121dc host host local acb2c6a1d19f none null local 58fd6f6d2257 phpxxe_default bridge local # root @ niss in ~ [9:17:31] $ docker network inspect a0dc6e118c93
容器的网络设置:
网络连接选项:
-
查看tomcat03容器的配置信息:
在最后:
- 可以看到网关为172.17.0.1
-
查看tomcat03的hosts文件配置信息:
# root @ niss in ~ [9:26:41] C:1 $ docker exec -it tomcat03 cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.2 tomcat01 c2fe7ba1530d 172.17.0.3 tomcat02 adc336154f86 172.17.0.5 ff37a3e05144
- 实际上--link就是在/etc/hosts添加容器名与容器IP的映射
再比如tomcat01的hosts文件:
# root @ niss in ~ [9:27:16] $ docker exec -it tomcat01 cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.2 c2fe7ba1530d
- 此时就没有相应的主机映射;
1.6.3 容器互联-自定义网络
(1)网络模式
- bridge:桥接docker默认(docker0)
- none:不配置网络
- host:与宿主机共享网络
- container:容器网络联通
(2)查看自定义网络
-
查看docker网络:
docker network ls NETWORK ID NAME DRIVER SCOPE a0dc6e118c93 bridge bridge local 13fc812121dc host host local acb2c6a1d19f none null local 58fd6f6d2257 phpxxe_default bridge local
- brige实际上对应的就是docker0网络,默认;如果未指定,容器不能靠容器名网络连接;
(3)创建自定义网络
-
docker network create
:Create a network Options: --attachable Enable manual container attachment --aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[]) --config-from string The network from which copying the configuration --config-only Create a configuration only network -d, --driver string Driver to manage the Network (default "bridge") --gateway strings IPv4 or IPv6 Gateway for the master subnet --ingress Create swarm routing-mesh network --internal Restrict external access to the network --ip-range strings Allocate container ip from a sub-range --ipam-driver string IP Address Management Driver (default "default") --ipam-opt map Set IPAM driver specific options (default map[]) --ipv6 Enable IPv6 networking --label list Set metadata on a network -o, --opt map Set driver specific options (default map[]) --scope string Control the network's scope --subnet strings Subnet in CIDR format that represents a network segment
例:
# root @ niss in ~ [9:46:22] C:130 $ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynetwork c1c801784c1c58d913eccb2c1b0132763ca5d2aeff641ebf367423f7fa6cc141 $ docker network inspect mynetwork [ { "Name": "mynetwork", "Id": "c1c801784c1c58d913eccb2c1b0132763ca5d2aeff641ebf367423f7fa6cc141", "Created": "2020-06-15T09:46:26.470339626+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/16", "Gateway": "192.168.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
- 桥接模式
- 子网:192.168.0.0/16
- 网关:192.168.0.1
- 网络名:mynetwork
(4)创建容器时使用自定义网络
-
删除之前的所有容器,创建新的属于自定义网络的容器
使用
--net 网络ID
:# root @ niss in ~ [9:49:52] $ docker run --name tomcat01 -P -d --net mynetwork tomcat 9beabc19bafaa7e842511be8537563023d85df5a4f58b6bffbdef83958055296 # root @ niss in ~ [9:50:27] $ docker run --name tomcat02 -P -d --net mynetwork tomcat d42357da832bcd136e057cc79c1e68955cca4b3991c48f20c541bc519b239e89
此时:
# root @ niss in ~ [9:50:34] $ docker network inspect mynetwork [ { "Name": "mynetwork", "Id": "c1c801784c1c58d913eccb2c1b0132763ca5d2aeff641ebf367423f7fa6cc141", "Created": "2020-06-15T09:46:26.470339626+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/16", "Gateway": "192.168.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "9beabc19bafaa7e842511be8537563023d85df5a4f58b6bffbdef83958055296": { "Name": "tomcat01", "EndpointID": "5560fbafc4d6154c247fc52465afe6eb61b33e5c19684177f17bea33942b3e59", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" }, "d42357da832bcd136e057cc79c1e68955cca4b3991c48f20c541bc519b239e89": { "Name": "tomcat02", "EndpointID": "225ae1e8f4e58bb931f9d89436871342868d692b561c6f8df7c849bb012ba877", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
此时再次进行连通性测试:
# root @ niss in ~ [9:51:53] C:1 $ docker exec tomcat01 ping tomcat02 PING tomcat02 (192.168.0.3) 56(84) bytes of data. 64 bytes from tomcat02.mynetwork (192.168.0.3): icmp_seq=1 ttl=64 time=0.136 ms 64 bytes from tomcat02.mynetwork (192.168.0.3): icmp_seq=2 ttl=64 time=0.099 ms
- 此时就可以根据容器名正常联通
1.6.4 容器与网络的联通
(1)docker network connect
-
将容器添加到网络中,使该网络间的容器可以相互连通;
-
使用方式:
Usage: docker network connect [OPTIONS] NETWORK CONTAINER Connect a container to a network Options: --alias strings Add network-scoped alias for the container --driver-opt strings driver options for the network --ip string IPv4 address (e.g., 172.30.100.104) --ip6 string IPv6 address (e.g., 2001:db8::33) --link list Add link to another container --link-local-ip strings Add a link-local address for the container
示例:将容器mysql添加到mynwtwork网络中,相互连通;
# root @ niss in ~ [9:24:24] $ docker network connect mynetwork mysql
检查网络:
# root @ niss in ~ [9:29:56] C:1 $ docker network inspect mynetwork [ { "Name": "mynetwork", "Id": "c1c801784c1c58d913eccb2c1b0132763ca5d2aeff641ebf367423f7fa6cc141", "Created": "2020-06-15T09:46:26.470339626+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/16", "Gateway": "192.168.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "c3e76d01dbff94ef2499bc10bed8f92b615ecaa803f13083c7821103bc386331": { "Name": "mysql", "EndpointID": "505f679d560d2986b4bc914babd50a6d092db5280d6ef7147e145f2c54725871", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]