docker
容器化
容器化意味着封装或打包软件代码及其所有依赖项,以便它可以在任何基础架构上统一且一致地运行。
什么是docker
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。 它是目前最流行的 Linux 容器解决方案。
和虚拟化技术类似,它极大的方便了应用服务的部署;又与虚拟化技术不同,它以一种更轻量的方式实现了应用服务的打包。使用 Docker 可以让每个应用彼此相互隔离,在同一台机器上同时运行多个应用,不过他们彼此之间共享同一个操作系统。Docker 的优势在于,它可以在更细的粒度上进行资源的管理,也比虚拟化技术更加节约资源。
历史
2010 年,几个搞 IT 的年轻人,在美国旧金山成立了一家名叫 dotCloud 的公司。dotCloud 的平台即服务(Platform-as-a-Service, PaaS)提供商。底层技术上,dotCloud 平台利用了 Linux 的 LXC 容器技术。
Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。
为了方便创建和管理这些容器,dotCloud 基于 Google 公司推出的 Go 语言开发了一套内部工具,之后被命名为 Docker。Docker 就是这样诞生的。
2013 年 3 月,开源。
越来越多的人发现docker的优点!火了。Docker每个月都会更新一个版本!
docker 优势
(1)更高效的利用系统资源 相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
(2)更快速的启动时间。 传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。
(3)一致的运行环境。 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。。
(4)持续交付和部署。 使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。
下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
docker 安装
mac
注意区分是 intel 还是 M1 的cpu
linux centos7
- 卸载当前已经存在的旧版
Docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
- 添加
Docker安装源
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
- 安装最新版本
sudo yum install docker-ce docker-ce-cli containerd.io
如果需要安装指定版本,可以通过下面命令查看版本并选择需要的版本
yum list docker-ce --showduplicates | sort -r
sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
- 安装完成,启动Docker
sudo systemctl start docker
- 先跑一个 helloworld
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
卸载 Docker
#1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#2. 删除资源
rm -rf /var/lib/docker
# /var/lib/docker 是docker的默认工作目录
Docker核心概念
-
镜像(
Image) Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。 -
容器(
Container) 镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间 (opens new window).
- 仓库(
Repository) 镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。
一个 Docker Registry 中可以包含多个 仓库(Repository);每个仓库可以包含多个 标签(Tag);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
仓库名经常以 两段式路径 形式出现,比如 fourtharsenal/liyunfei,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。
Docker 是怎样工作的
Docker Engine是一个C/S架构的应用程序,主要包含下面几个组件;
Docker 守护程序: 守护程序(dockerd)是一个始终在后台运行并等待来自客户端的命令的进程。守护程序能够管理各种 Docker 对象。
Docker 客户端: 客户端(docker)是一个命令行界面程序,主要负责传输用户发出的命令。
REST API: REST API 充当守护程序和客户端之间的桥梁。使用客户端发出的任何命令都将通过 API 传递,最终到达守护程序。
Docker使用了C/S体系架构,Docker客户端与Docker守护进程通信,Docker守护进程负责构建,运行和分发Docker容器。 Docker客户端和守护进程使用REST API通过UNIX套接字或网络接口进行通信。
Docker基础命令操作
docker version #显示docker的版本信息。
docker info #显示docker的系统信息,包括镜像和容器的数量
查看帮助命令
docker [命令] --help
# 查看 docker pull 帮助文档
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)
--platform string Set platform if server is multi-platform capable
-q, --quiet Suppress verbose output
Docker镜像相关操作
Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像。
docker search # 搜索镜像
docker pull #下载镜像 docker image pull
docker images # 查看所有本地主机上的镜像 docker image ls
docker rmi # 删除镜像 docker image rm
搜索官方仓库镜像
docker search centos
NAME DESCRIPTION STARS `OFFICIAL` AUTOMATED
centos The official build of CentOS. 6753 `[OK]`
ansible/centos7-ansible Ansible on Centos7 134 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC session… 130 [OK]
拉取镜像
命令:$ docker pull [Docker Registry 地址[:端口号]/]仓库名[:标签]
说明:
- Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub(docker.io)。
- 仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。
# 拉取 centos 镜像
docker pull centos
Using default tag: latest
latest: Pulling from library/centos
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Image is up to date for centos:latest
docker.io/library/centos:latest
查看当前主机的镜像列表
docker image ls
docker images
-a, --all Show all images (default hides intermediate images) #列出
所有镜像
-q, --quiet Only show numeric IDs # 只显示镜像的id
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
fourtharsenal/docker101tutorial latest f82bbbe08672 About an hour ago 28.3MB
docker101tutorial latest f82bbbe08672 About an hour ago 28.3MB
mysql 5.7 1d7aba917169 12 days ago 448MB
列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。
列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。
- 镜像体积查看
docker system df - 显示镜像摘要:
docker image ls --digests
删除本地镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]
dockder image rm
-f, --force Force removal of the image
<镜像> 可以是 镜像ID、镜像名 或者 镜像摘要
$ docker rmi mysql:5.7
Untagged: mysql:5.7
Untagged: mysql@sha256:d9b934cdf6826629f8d02ea01f28b2c4ddb1ae27c32664b14867324b3e5e1291
Deleted: sha256:1d7aba9171693947d53f474014821972bf25d72b7d143ce4af4c8d8484623417
Deleted: sha256:94ebbead5c58282fef91cc7d0fb56e4006a72434b4a6ae2cd5be98f369cb8c21
Deleted: sha256:989da5efad29ec59bd536cd393d277bc777f8b9b34b8e3ad9593a4b0a83b40f4
Deleted: sha256:7457ee6817c678da3cb383d27a3d79d5f3f25fbcb92958d5e8d5709e7631e23c
Deleted: sha256:fe7dac53adebe33519b4e4fc577bfcddd7372cc313c35fae681fc82fb325fdc0
删除所有镜像
docker rmi $(docker image ls -q)
docker commit
使用 docker commit 从容器生成镜像,但是实际环境中并不会这样使用。定制镜像应该使用 Dockerfile 来完成。 Dockerfile 会在第二篇文章中介绍
docker build
通过dockerfile创建容器镜像, dockerfile会在第二篇文章中介绍
配置镜像加速
对于使用 macOS 的用户,
在任务栏点击 Docker Desktop 应用图标 -> Perferences,在左侧导航菜单选择 Docker Engine,在右侧像下边一样编辑 json 文件。修改完成之后,点击 Apply & Restart 按钮,Docker 就会重启并应用配置的镜像地址了。
mac
{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
Docker 容器相关操作
容器是基于镜像创建的可运行实例,并且单独存在,一个镜像可以创建出多个容器。运行容器化环境时,实际上是在容器内部创建该文件系统的读写副本。 这将添加一个容器层,该层允许修改镜像的整个副本。
容器的生命周期
容器的生命周期是容器可能处于的状态
- created:初建状态
- running:运行状态
- stopped:停止状态
- paused: 暂停状态
- deleted:删除状态
列出所有运行的容器
docker ps或docker container ls命令 列出当前正在运行的容器
# 查看帮助文档
docker container ls --help
-a, --all Show all containers (default shows just running)
-n, --last int Show n last created containers (includes all states) (default -1)
-q, --quiet Only display numeric IDs
# -a 显示所有容器
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
32ac47a2d0a6 nginx "/docker-entrypoint.…" 22 seconds ago Up 21 seconds 0.0.0.0:8088->80/tcp, :::8088->80/tcp webserver
d46790b9f194 hello-world "/hello" About a minute ago Exited (0) About a minute ago crazy_fermat
启动容器
docker create创建容器, 创建的容器处于停止状态
docker create -it --name=busybox busybox
# 查看容器
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e055978e44bf busybox "sh" 26 seconds ago Created busybox
docker start 命令基于已经创建好的容器直接启动
docker start busybox
busybox
# 查看容器
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e055978e44bf busybox "sh" About a minute ago Up 7 seconds busybox
使用docker run命令直接基于镜像新建一个容器并启动,相当于先执行docker create命令从镜像创建容器,然后再执行docker start命令启动容器。
查看帮助文档
docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
docker run用来启动一个新的容器并运行一个命令
启动一个busybox容器并在容器中执行sh命令
docker run -it --name box1 busybox sh
/ # ls
bin dev etc home proc root sys tmp usr var
/ #
参数说明
-
-i 或 --interactive 连接到容器的输入流,以便可以将输入发送到 bash
-
-t 或 --tty 选项可通过分配伪 tty 来格式化展示并提供类似本机终端的体验
-
--name 'Name' 容器名字
-
-d 后台运行
在上面的示例中,为了使容器继续运行,必须将终端窗口保持打开状态。关闭终端窗口会停止正在运行的容器。
-
-p 主机端口:容器端口 -P 会随机分配一个端口 运行一个
nginx容器
docker run -d -P --name nginx nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
a330b6cecb98: Pull complete
e0ad2c0621bc: Pull complete
9e56c3e0e6b7: Pull complete
09f31c94adc6: Pull complete
32b26e9cdb83: Pull complete
20ab512bbb07: Pull complete
Digest: sha256:853b221d3341add7aaadf5f81dd088ea943ab9c918766e295321294b035f3f3e
Status: Downloaded newer image for nginx:latest
e9b80ca47658f4a04864943ca686db81e35a1baac1e1c63b78e16d039ec6e5a8
查看容器
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e9b80ca47658 nginx "/docker-entrypoint.…" 37 seconds ago Up 36 seconds 0.0.0.0:55000->80/tcp, :::55000->80/tcp nginx
可以看到本机的55000端口映射到了容器的80端口,此时访问localhost:55000
终止容器
docker pause 暂停容器
docker stop 或 docker kill 停止容器
# `暂停`容器
docker pause CONTAINER [CONTAINER...]
# `停止`容器
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker kill
stop 命令通过发送信号SIGTERM 来正常关闭容器。如果容器在一定时间内没有停止运行,则会发出 SIGKILL 信号,该信号会立即关闭容器。 docker kill 直接发送 SIGKILL 信号
暂停nginx容器, 此时访问localhost:55000就无法访问到页面
docker pause nginx
重新启动容器,此时可以访问localhost:55000
docker unpause nginx
终止容器,然后再启动容器,因为-P会随机指定端口号,此时端口号有变化,查看,此时映射的端口为55001
docker stop nginx
nginx
docker start nginx
nginx
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e9b80ca47658 nginx "/docker-entrypoint.…" 13 minutes ago Up 8 seconds 0.0.0.0:55001->80/tcp, :::55001->80/tcp nginx
进入容器
docker exec 进入运行中的容器
退出容器
exit #容器直接退出
ctrl +P +Q #容器不停止退出
命令文档
docker exec --help
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Run a command in a running container
进入nginx 容器
docker exec -it nginx sh
# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
删除容器
docker container rm 或 docker rm 删除暂停状态或终止状态的容器
docker rm [OPTIONS] CONTAINER [CONTAINER...]
-f, --force Force the removal of a running container (uses SIGKILL)
强制删除运行中的容器添加-f
导入容器
使用docker export CONTAINER命令导出一个容器到文件,不管此时该容器是否处于运行中的状态。
# 导出容器前我们先进入容器,创建一个文件,
docker exec -it busybox2 sh
cd /tmp && touch test
docker export busybox2 > busybox.tar
ls
busybox.tar docs node_modules package-lock.json package.json yarn.lock
# 使用docker import命令导入容器
# busybox.tar 被导入成为新的镜像,镜像名称为 busybox:test
docker import busybox.tar busybox:test
sha256:55ebe2ae97c68d9cd22f4f102e3235bcba634dc6ab3bbffa5e33aa893e7b38f1
# 使用docker run命令启动
docker run -it busybox:test sh
重命名容器
docker rename
查看容器详细信息
docker inspect
实时监控容器资源数据
docker stats
容器与宿主机之间的数据拷贝
docker cp
# 拷贝宿主机文件
docker cp /Users/liyf/learn/docker/docker-docs busybox2:/test123
ls
busybox.tar docs node_modules package-lock.json package.json yarn.lock
# 进入容器
docker exec -it busybox2 sh
/ # ls
bin dev etc home proc root sys test.txt test123 tmp usr var
/ # cd test123/
/test123 # ls
busybox.tar docs node_modules package-lock.json package.json yarn.lock
/test123 #
容器操作总结:
REPOSITORY
Docker hub 是当前全球最大的镜像市场,差不多超过 10w 个容器镜像,大部分操作系统镜像都来自于此。 仓库(Repository)是集中存放镜像的地方。
一个容易混淆的概念是注册服务器(Registry)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 docker.io/ubuntu 来说,docker.io 是注册服务器地址,ubuntu 是仓库名。
dockerHub注册账号
登录
docker login
-u, --username string username
# 退出
docker logout
推送镜像
docker push
Usage: docker push [OPTIONS] NAME[:TAG]