docker基本概念
目录
- 环境
- docker基本操作
- 安装
- docker info\version
- docker ps
- docker pull/images
- docker run
- docker exec
- docker stop
- docker rm
- docker架构
- docker rmi
- Container容器
- 容器技术优点
- 容器与虚拟机
- images 镜像
- Layer
- DockerFile
- Docker build
- Registry(镜像仓库)
- 如何上传自己的镜像
- 离线环境怎么办?
- 容器如何与内外互通?
- 拷贝文件
- 共享文件
- 网络互通
- host模式
- bridge模式
- 分配端口号
环境
云服务器:Ubuntu22.04
docker基本操作
安装
sudo apt install docker.iosudo service docker start #启动docker服务
sudo usermod -aG docker ${USER} #当前用户加入docker组
第二个命令是启动Docker的后台服务,第三个命令是讲当前用户加入到docker组,因为docker组有root权限。
docker info\version
docker version会显示docker的版本信息和架构信息。
root@lavm-70nixok1l4:~ docker version
Client: Docker Engine - CommunityVersion: 28.5.1API version: 1.51Go version: go1.24.8Git commit: e180ab8Built: Wed Oct 8 12:17:03 2025OS/Arch: linux/amd64Context: defaultServer: Docker Engine - CommunityEngine:Version: 28.5.1API version: 1.51 (minimum version 1.24)Go version: go1.24.8Git commit: f8215ccBuilt: Wed Oct 8 12:17:03 2025OS/Arch: linux/amd64Experimental: falsecontainerd:Version: v1.7.28GitCommit: b98a3aace656320842a23f4a392a33f46af97866runc:Version: 1.3.0GitCommit: v1.3.0-0-g4ca628d1docker-init:Version: 0.19.0GitCommit: de40ad0
docker info 会显示当前docker系统相关信息,例如CPU、内存、容器数量、容器运行时、存储文件系统等等如下:
root@lavm-70nixok1l4:~# docker info
Client: Docker Engine - Community
Server:Containers: 3Running: 0Paused: 0Stopped: 3Images: 3Server Version: 28.5.1Storage Driver: overlay2Backing Filesystem: extfsCgroup Driver: systemdCgroup Version: 2Swarm: inactiveRuntimes: io.containerd.runc.v2 runcDefault Runtime: runcKernel Version: 5.15.0-60-genericOperating System: Ubuntu 22.04.3 LTSOSType: linuxArchitecture: x86_64CPUs: 2Total Memory: 1.929GiBDocker Root Dir: /var/lib/docker
这个显示的信息,对于我们了解Docker的内部运行状态非常有用,比如,你能看到有三个容器处于stoped状态,有3个镜像,存储用的文件系统是overlay2,Linux内核是5.15,操作系统是Ubuntu 22.04.3 LTS,硬件是x86_64,两个CPU,内存2G
docker ps
查看当前正在运行的容器,-a选项列出所有运行过的容器。
root@lavm-70nixok1l4:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
root@lavm-70nixok1l4:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7c485b41f6fd hello-world "/hello" 3 hours ago Exited (0) 3 hours ago jolly_kalam
7d0dcc604c86 busybox "echo hello world" 3 hours ago Exited (0) 3 hours ago strange_pike
2cb2ed2c14af hello-world "/hello" 2 days ago Exited (0) 2 days ago dreamy_kare
root@lavm-70nixok1l4:~#
docker pull/images
拉取镜像
docker pull busybox #拉取busybox镜像
docker images查看自己的镜像
可以看到已经成功下载了busybox镜像,ID号是一串16进制数字,大小是4.43MB
docker run
使用该命令即可运行镜像了。
root@lavm-70nixok1l4:~# docker run busybox echo hello world!
hello world!
基本的格式是“docker run 设置参数”,再跟上“镜像名或 ID”,后面可能还会有附加的“运行命令”
- -it 表示开启一个交互式操作的shell,这样可以直接进入容器内部,好像是登陆虚拟机一样
- -d 表示让容器在后台运行,启动Redis服务的时候经常用
- –name 可以为容器起名字,方便我们查看,如果不用,docker默认会分配一个随机的名字
第一个是以后台运行nginx,第二个是后台运行同时起别名red_svr,第三个是使用IMAGE ID登陆ubuntu:18.04
然后运行docker ps查看正在运行的容器:
这里你会发现每个运行的容器也有Container id,跟images id是一个意思。
docker exec
docker exec命令是在已经存在的容器里面执行命令。
下面就是进入redis容器里面。
docker stop
使用该命令停止运行中容器,可以使用container id(前三位数字) 或者 names来停止容器。
docker rm
容器被停止后使用docker ps命令看不到了,不过容器没有被彻底销毁,ps -a选项可以查看系统里所有的容器。
运行 docker rm 命令,使用“CONTAINER ID”的前两位数字来删除这些容器:
这样删除似乎太麻烦了,如果我们确定不需要的话,可以在docker run后面加上–rm选项,容器运行完毕自动清除,不保存。
docker架构
我们通过client与Docker Engine里的后台服务Docker daemon通信,而镜像则在远端的仓库Registry里面,客户端并不能直接访问镜像仓库。
可以通过Docker client 执行build\pull\run等命令向Docker daemon发送请求,而Docker daemon 负责从远端拉取镜像、在本地存储镜像、还有从镜像生成容器、管理容器等所有功能。
docker run hello-world 可以查看Docker详细的工作流程
docker rmi
删除镜像 可以指定名字(+TAG)或者IMAGE ID来删除。
下面两种方法都可以,注意如果不加TAG默认latest
docker rmi ubuntu:18.04
docker rmi f9
Container容器
简单看一个例子,拉取一个Alpine一个小型的操作系统然后运行他。
docker pull alpine
这里多了一个-it选项,意思是离开当前的OS,进入启动容器的那个界面。
第二个cat命令发现,此时的OS系统变成了我们下载的Alpine系统。
ps -ef命令发现也没有其他别的进程。
因此我们推测,在容器里运行的是一个全新的操作系统,在这里运行的应用程序完全看不到外面的Ubuntu系统,两个系统被互相“隔离了”。
容器技术优点
- 系统安全
通过容器技术,容器之间彼此隔离,容器中的应用程序运行在一个有严密防护的盒子里面。 - 资源隔离
支持在系统里切分一部分资源,让它只能使用指定的配额。
实现技术:
基于Linux内核技术:namespace,cgroup,chroot
Docker的隔离这三个技术,namespace用于创建独立的文件系统、主机名、进程号、网络;cgroup实现对进程CPU、内存等资源进行配额限制;chroot用于限制进程访问原有的文件系统。
容器与虚拟机
images 镜像
简单理解功能上来看,镜像相当于可执行文件,容器相当于进程。(其实这样是不对的)
镜像里面其实不光包括可执行文件,还包含应用时的整个系统环境,这样他就可以一次打包,到处运行!
Layer
容器镜像的内部并不是一个平坦的结构,而是由许多镜像层组成的,每层都是只读不可修改的文件,相同的层可以在镜像之间共享,多个层像积木一样堆叠起来,使用“Union FS 联合文件系统”将各个层合并起来,形成了容器最终的文件系统。
使用下面命令可以查看FS,就是这个镜像需要什么文件系统,如果缺的话就需要下载, 如果不缺的话可以共享。
docker inspect [IMAGE ID]
DockerFile
如何构建一个镜像呢?
DockerFile是一个规则文件,相当于一个操作步骤,记录了一系列的构建指令,比如选择基础镜像、拷贝文件、运行脚本等等,每个指令都会生成一个Layer,Docker会根据这个顺序,最终会创建一个新的镜像出来。
下面看一个DockerFile文件。
# Dockerfile.busybox
FROM busybox # 选择基础镜像
CMD echo "hello world" # 启动容器时默认运行的命令
docker用 -f 参数指定 Dockerfile 文件名,后面必须跟一个文件路径,叫做“构建上下文”(build’s context),这里只是一个简单的点号,表示当前路径的意思。
接下来,你就会看到 Docker 会逐行地读取并执行 Dockerfile 里的指令,依次创建镜像层,再生成完整的镜像。
新的镜像暂时还没有名字(用 docker images 会看到是 none),使用docker run IMAGEID 运行。
DockerFile常用指令:
- FROM:构建的第一条指令,基础镜像的选择非常关键。如果关注的是镜像的安全和大小,那么一般会选择 Alpine;如果关注的是应用的运行稳定性,那么可能会选择 Ubuntu、Debian、CentOS。
FROM alpine:3.15 # 选择Alpine镜像
FROM ubuntu:bionic # 选择Ubuntu镜像
- 使用 COPY 命令,可以把源码,配置文件传进去,它的用法和 Linux 的 cp 差不多,不过拷贝的源文件必须是“构建上下文”路径里的,不能随意指定文件。也就是说,如果要从本机向镜像拷贝文件,就必须把这些文件放到一个专门的目录,然后在 docker build 里指定“构建上下文”到这个目录才行。
COPY ./a.txt /tmp/a.txt # 把构建上下文里的a.txt拷贝到镜像的/tmp目录
COPY /etc/hosts /tmp # 错误!不能使用构建上下文之外的文件
- 指令 RUN ,它可以执行任意的 Shell 命令,比如更新系统、安装应用、下载文件、创建目录、编译程序等等,实现任意的镜像构建步骤,非常灵活。
RUN apt-get update \&& apt-get install -y \build-essential \curl \make \unzip \&& cd /tmp \&& curl -fSL xxx.tar.gz -o xxx.tar.gz\&& tar xzf xxx.tar.gz \&& cd xxx \&& ./config \&& make \&& make clean
RUN命令太长的话可以把它写进一个脚本里。用 COPY 命令拷贝进去再用 RUN 来执行:
COPY setup.sh /tmp/ # 拷贝脚本到/tmp目录RUN cd /tmp && chmod +x setup.sh \ # 添加执行权限&& ./setup.sh && rm setup.sh # 运行脚本然后再删除
- 由于RUN指令支持shell编程,有变量的概念。ARG和ENV,ARG只在容器创建时可见,ENV直到容器运行时仍然可见。
ARG IMAGE_BASE="node"
ARG IMAGE_TAG="alpine"ENV PATH=$PATH:/tmp
ENV DEBUG=OFF
- EXPOSE 用于声明容器对外公开端口号
EXPOSE 443 # 默认是tcp协议
EXPOSE 53/udp # 可以指定udp协议
注意:因为每个指令都会生成一个镜像层,所以 Dockerfile 里最好不要滥用指令,尽量精简合并,否则太多的层会导致镜像臃肿不堪。
Docker build
Docker build命令就是把构建上下文的所有文件全部打包的daemon中。然后daemon帮助咱们构建文件。为了防止它将无用的文件上传到daemon中,还支持*.dockerignore*文件。
下面表示忽略.swp和.sh文件
# docker ignore
*.swp
*.sh
- -f指定Dockerfile文件
- -t指定镜像标签,这样构建的镜像就有名字了。
Registry(镜像仓库)
这是docker的官方仓库,汇集了官方镜像、认证镜像、“民间”镜像。首先官方镜像(Office Image)和认证镜像(Verfied Publisher)是比较权威的,因为只有大公司才会有资格获得认证镜像。所谓“民间”镜像也分两类,一类是注册账号的公司不想交钱的镜像,另一类就是个人发表的镜像。
docker pull nginx:[tag] # 不加tag默认是最新的官方镜像# 下载非官方镜像时,必须把用户名也带上才可以,否则默认使用官方镜像。
docker pull bitnami/nginx
docker pull ubuntu/nginx
如何上传自己的镜像
假如我们已经打包好了自己的镜像ngx-app.
- 需要登陆镜像仓库
docker login -u [username]
- 使用docker tag命令给他改成带用户名的完整名字(使用默认的名字也可以)
docker tag ngx-app chronolaw/ngx-app:1.0
- 将镜像推送上去 docker push
docker push chronolaw/ngx-app:1.0
离线环境怎么办?
- 在能下载镜像的地方 执行docker pull
- 下载下来之后执行docker save打包成压缩包
docker save ngx-app:latest -o ngx.tar
- scp命令上传到指定服务器
- 使用docker load 加载
docker load -i ngx.tar
容器如何与内外互通?
拷贝文件
使用docker cp命令,类似于cp/scp命令,指定源路径和目标路径就可以。把文件从源路径传递到目标路径。
假设其用了一个Redis:
把文件从当前目录传到容器里面
docker cp a.txt 062:/tem
进入容器里面检查
把容器里面的数据拷贝出来
docker cp 062:/tmp/a.txt ./b.txt
共享文件
docker -v命令 可以在启动容器的时候把宿主机的目录挂在到容器里面,这样就可以共享文件了。格式是"宿主机路径:容器内路径"
docker run -d --rm -v /tmp:/tmp redis
网络互通
docker提供了三种网络模式,null、host和bridge。
null是最简单的模式,也就是没有网络,但允许其他的网络插件来自定义网络连接。这里不介绍了。
host模式
host模式需要在docker run的时候使用–net=host参数,下面就用这个参数启动Nginx:
docker run -d --rm --net=host nginx:alpine
分别查看 ip addr发现结果一样,nginx共享了主机网络。
bridge模式
桥接模式,类似现实世界里的交换机、路由器,只不过是由软件虚拟出来的。容器和宿主机再通过这个虚拟网卡介入网桥(图中docker0)。和host模式相比,bridge模式多了虚拟网桥和网卡,效率低一些。
默认启动就是桥接模式,显示指定是–net=bridge。
分配端口号
端口号映射需要使用 bridge 模式,并且在 docker run 启动容器时使用 -p 参数,形式和共享目录的 -v 参数很类似,**用 : 分隔本机端口和容器端口。比如,**如果要启动两个 Nginx 容器,分别跑在 80 和 8080 端口上:
docker run -d --rm -p 80:80 nginx:alpine
docker run -d --rm -p 8080:80 nginx:alpine