本文首发于我的个人网站: https://hewanyue.com/
本文作者: Hechao
本文链接: https://hewanyue.com/blog/5c39f4ef.html
安装完Docker的服务,我们就可以开始使用Docker了。
Docker镜像
之前我们提到,docker是一个运行容器的工具,可以单独隔离每个服务的运行环境,达到互不干扰和节约资源的目的。而docker运行的容器,是基于一层一层的镜像联合挂载构建而成。所以我们需要先有镜像。
所谓镜像,其实可以理解为,一个个的最简化的安装包,里面只集成了一些必备的程序和文件,且每一层和每一层镜像是可以相互一样的,大大的节约了空间,提高了资源利用率。举个最简单的例子,我们从官方下载一个centos系统的镜像包centos:apline,大小才5.55兆,而centos差不多至少200兆了,而centos安装的ISO镜像文件也都差不多1G左右。这是因为容器使用的镜像系统,需要依赖宿主机内核来运行,容器本身是没有内核的,只包含一些基础功能命令而已。可用docker images查看本地镜像,从大小来看,就知道容器确实很精简。
root@DockerUbuntu:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest 965ea09ff2eb 6 weeks ago 5.55MB
centos latest 0f3e07c0138f 2 months ago 220MB
centos 7.6.1810 f1cb7c7d58b7 8 months ago 202MB
我们可以在docker官方镜像仓库https://hub.docker.com查看官方镜像,也可以通过命令直接搜索centos的可用容器
docker search centos
注意:官方仓库也有很多是个人的镜像,为避免未知风险,一定要采用官方镜像,千万别使用安全性未知或来源不明的的镜像。一般排在第一个是官方镜像。
使用命令docker pull centos就可以自动从docker官方镜像仓库docker.io,下载centos镜像了,因为我们没有指定版本标签,所以这条命令会默认下载centos:latest版本,也就是最新版。生产中我们出于稳定性和便于管理,都会推荐使用指定的稳定版本,而不会采用latest版本(,随着版本发型,之前的latest版本和几个月之后的latest版很有可能就不是一个版本,不利于规范化统一)。我们本次以CentOS7.6中的最新版centos:7.6.1810最为本次演示的版本。下载镜像命令如下:
docker pull centos:7.6.1810
使用docker image rm [ OPTION ] 容器ID可以删除不要的镜像,如果已有容器基于此镜像启动,则会提示错误,无法删除,需先停止容器,或直接加-f选项强制删除镜像,此时容器也会被停止。注意,当容器被停止时,上面的数据也都会丢失,所以需要谨慎关闭容器和删除镜像。
此外,docker官方镜像站,因为在国外(美国,不过应该是有CDN或者国内镜像加速站点的,不过还是有点点慢),肯定不如阿里的容器镜像仓库速度快。所以我们可以配置阿里的镜像加速器,需要注册阿里账号。
进入阿里网站http://cr.console.aliyun.com,登陆之后,可以看到阿里的镜像仓库(之后再细说)还有镜像加速器,点击镜像加速器,可看到如图所示界面:
执行将下面代码,便可实现镜像加速了。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
之后使用docker info命令就可以看到已经添加镜像仓库成功

Docker容器
有了镜像之后我们就可以从中运行容器了。基础的命令有docker pull、docker push、docker create、docker run、docker ps、docker rm、docker start、docker stop、docker images、docker exec、docker inspect等等
pull push
root@DockerUbuntu:~# docker pull --help
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Pull an image or a repository from a registry
Options:
-a, --all-tags Download all tagged images in the repository
--disable-content-trust Skip image verification (default true)
-q, --quiet Suppress verbose output
docker pull命令我们之前也使用过,可以用来拉镜像,相当于命令docker image pull。根据官方帮助信息,我们可以知道,docker pull 如果要拉去指定版本,需要加:tag版本标签,加-a选项可以拉取所有镜像,不过生产中一般都是用的时候公司内部的本地镜像仓库Harbor,所以拉取镜像时,格式要跟公司Harbor服务器的IP或者域名,指定拉取镜像的源仓库,如果不加,则默认从docker官网拉取。镜像名称格式为:Harbor IP/项目名/image 名字:版本号
docker pull 172.18.32.101/centos/centos-base:v1
使用pull从公司Harbor拉取镜像时时,需要先在docker启动文件/lib/systemd/system/docker.service的ExecStart选项结尾加入参数--insecure-registry,表示加入不安全的镜像仓库,可加多个,示例如下。
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.32.19 --insecure-registry 192.168.32.20
docker push是用来推送本地镜像至仓库的,相当于命令docker image push,用法格式与pull相似。不过第一次向镜像仓库推送镜像前,都会需要使用命令docker login +harbor域名进行登录。拉取非公开仓库镜像前也需要登录。
tag
root@DockerUbuntu:~# docker tag --help
Usage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
root@DockerUbuntu:~#
docker tag命令可以用来打标记,格式如上。一般为了区分不同版本,我们会在每次制作完镜像后打上不同的标记,而且要分发到不同的镜像仓库时也要重新打一个对应仓库IP/项目名的镜像,才可以push或pull。
run
docker run可以算是最常用的docker基础命令了,意思是创建并运行容器,相当于docker create和docker start的组合。用法格式如下。
docker run [ OPTION ] 镜像ID [ CMD ]
OPTION
常用选项有-i、-t、-d、-p、-v、-e、--name、--net。
-i,–interactive, Keep STDIN open even if not attached
以交互式方式运行。不过只加-i是没法实现交互式的,通常需要-t参数配合,来给容器加一个伪终端实现交互式。-t,–tty, Allocate a pseudo-TTY
给容器分配一个伪终端,与-i配合使用,通常写作-it。-d,–detach, Run container in background and print container ID
使容器启动时后台运行,如果不加这个选项,则会占据宿主机当前终端,服务类容器等交互式容器一般都会加上这个选项。-p,–publish, list Publish a container’s port(s) to the host
映射本地端口到容器的指定端口,同时映射多个端口,则写多个-p 宿主机端口:容器端口选项。-v,–volume, list Bind mount a volume
使用-v 参数, 将宿主机目录映射到容器内部, 默认是可读写的。-v SOUCE:DEST:ro后面加ro则可实现只读。-e,–env, list Set environment variables
可用-e选项为容器添加启动时的环境变量。虽然大多环境变量都是在制作容器时就写进容器里,不过此选项应用在环境变量经常变化的场景,方便修改。--name,Assign a name to the container
给创建的容器命名。同一个宿主机上的容器之间可以通过自定义的容器名称相互访问,由于容器在启动的时候其内部 IP 地址是 DHCP 随机分配的,所以如果通过内部访问的话,自定义名称是相对比较固定的,因此设置容器别名比较适用于此场景。--link,Add link to another container
为容器设置一个别名,相当于一个路径名。自定义的容器名称可能后期会发生变化, 那么一旦名称发生变化,程序之间也要随之发生变化,比如程序通过容器名称进行服务调用, 但是容器名称发生变化之后再使用之前的名称肯定是无法成功调用, 每次都进行更改的话又比较麻烦, 因此可以使用自定义别名的方式解决,即容器名称可以随意更,只要不更改别名即可。--net
为容器指定网络。容器网络类型,常见的为bridge、host、null,也可以自己创建自定义网络。可用docker network list查看当前已有的网络。
root@DockerUbuntu:~# docker network list
NETWORK ID NAME DRIVER SCOPE
1eb441f702d2 bridge bridge local
241d3e94a6b3 host host local
7cc9cf9eb69e none null local
docker服务安装完成后,默认在每个宿主机会生成一个名称为 docker0 的网卡其 IP 地址都是 172.17.0.1/16,并且会生成三种不同类型的网络,也就是bridge、host和null,分别代表网桥(桥接)、宿主机网络和无网络访问。
如果不加--net选项则默认使用bridge,相当于桥接在宿主机的docker0网卡上。
host网络就是指容器使用宿主机网络,所以端口就不能重复使用,多个使用host网络的容器间端口也不能重复。
null网络指容器只有回环网卡,没有外部网卡,无法与外部交流交流,不常使用,适用于某些不需要与外界通信的数据计算或图形、数据处理服务。
还有一种比较特的类型就是container模式,就是指定与一个已有容器共享网络,格式为--net=container:指定名称或 ID 。使用此模式创建的容器需指定和一个已经存在的容器共享一个网络,而不是和宿主机共享网,新创建的容器不会创建自己的网卡也不会配置自己的 IP,而是和一个已经存在的被指定的容器东西 IP 和端口范围,因此这个容器的端口不能和被指定的端口冲突, 除了网络之外的文件系统、进程信息等仍然保持相互隔离,两个容器的进程可以通过 lo 网卡及容器 IP 进行通信。
CMD
docker run后面跟的CMD表示指定启动容器的命令,如果不指定,则为容器默认命令。可用 命令docker inspect 容器ID查看容器详细参数查看容器创建时的的CMD。
因为容器中没有守护进程systemd,所以进程编号PID=1的根进程,就是我们启动容器时指定的CMD命令或创建容器设定的默认CMD。如果这个PID=1的守护进程结束,则整个容器就将被关闭。所以我们一般会指定一个可以占据前台终端的服务来作为守护进程,例如bash或者tail -f /etc/hosts命令,对于后台nginx等服务来说,想让他们作为守护进程启动容器,需要将在后台执行的这个选项关闭,如nginx可以通过docker run -it -d nginx:alpine nginx -g "daemon off;"命令,加上-g "daemon off"选项传递参数或者在配置文件中设置daemon off来关闭后台执行选项,否则容器启动就会因为没有前台进程而终止。为了方便我们修改配置或者重启服务,企业生产中我们都采用tail -f /etc/hosts后为前台进程,这样我们进入容器后重启服务就不受影响了。
ps
root@DockerUbuntu:~# docker ps --help
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
docker ps命令比较简单,较长使用的参数是-a、-q,分别是显示所有容器(包括为未运行容器,ps默认只显示正在运行的容器)和只显示容器ID。也可以使用docker ps -aq来显示所有容器的ID,可配合其他命令如docker rm命令使用。docker rm -f `docker ps -aq`删除本地所有容器(很危险,小心操作!)。
rm
docker rm命令是用来删除容器的,如果容器正在运行,使用docker rm命令删除时会报错提示Error response from daemon: You cannot remove a running container XXX. Stop the container before attempting removal or force remove,告诉我们无法删除运行中的容器,需要先将容器停止或者强制删除,使用docker rm -f命令强制删除,或者使用下面的停止命令
start stop
docker start 容器ID启动容器,可以加选项-i,表示启动容器并输出容器内的标准输出至宿主机终端。需要注意的是,如果当时用docker run或者docker create命令创建容器时,没有加-it或-d等一些其它选项或者参数的话,在start容器这一步也没法作出更改了的。容器怎么创建的,启动时就会按照创建时设定好的模式运行,这些是没办法再次修改了的,包括启动CMD。
docker stop 容器ID终止容器。需要注意:终止容器时,容器内的数据都将丢失,在备份重要数据之前不要终止容器。
images
docker images命令其实相当于docker image ls,显示本地所有镜像。docker image CMD还有很多,之后介绍镜像管理的时候 在详细介绍。
exec
docker exec命令可以向一个已运行容器发送命令。用法如下所示。
[root@DockerCentOS ~]# docker exec --help
Usage: 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 exec -it 容器ID bash/sh,可以进入正在运行的容器。
本文详述Docker镜像原理,包括镜像下载、管理及加速技巧,解析容器运行机制,涵盖常用命令如pull、push、run、ps、rm等,深入探讨网络模式与数据持久化策略。
1702

被折叠的 条评论
为什么被折叠?



