Docker学习笔记(一)

Docker基础

Docker概述

Docker是一种容器技术,可以简单快速的部署环境。

容器化技术

传统的虚拟化技术是对硬件进行抽象后单独提供给虚拟机一个独立的环境运行操作系统,而容器技术区别于虚拟机技术,是对操作系统资源进行抽象,提供给进程独立的运行环境。

容器化原理

容器就是一个个互相隔离的进程,而虚拟化技术是一个个互相隔离的系统,因此容器对于虚拟机而言具有启动快、资源少、体积小等优点。

容器技术实现的基础主要是两个技术:NameSpace、Cgroup。

  • NameSpace:命名空间,为容器技术提供隔离性
  • Cgroup:资源管理控制,进程的状态、优先级、资源的占有情况等

Docker为什么会出现

开发部署中的痛点:

  1. 本地环境与线上不一致

    在我本地跑的没问题啊,到线上怎么就出事了(开发)

  2. 环境配置复杂

    环境版本、依赖、大量的服务需要进行配置(运维)

  3. 发布项目麻烦

    运维人员进行代码发布,服务重启等操作(大量机器是件复杂的事情)

Docker问题解决

  1. 镜像机制:将代码运行环境打包成镜像上传到商店,运维只需要下载部署即可

    运行环境 => Docker镜像 => Docker仓库 => 下载到线上机器 => 部署(直接运行镜像)

  2. 隔离机制:运行后的容器之间相互隔离,充分使用服务器资源

    可以跑多个相同的应用,互不影响;充分利用服务器资源

Docker带来的好处

  1. 快速的交付和部署:打包镜像、一键运行
  2. 简单的系统运维:开发测试环境一致
  3. 便捷的升级和扩缩容:使用Docker可以方便的对容器进行管理
  4. 高效的计算资源利用:减少资源的浪费,尽可能的用在Docker容器上

Docker的基本组成

Docker架构图如下:

Docker架构图

上面可以理解为三部分:

  • 客户端:用户访问端,通过客户端发送指令操作服务器
  • 服务器:本地运行的Docker环境,主要分为三部分
    • 守护进程:控制台
    • Docker镜像:静态文件,可以想象成类模板
    • Docker容器:由镜像生成的实例,类比于类生成的对象
  • 仓库:存储Docker镜像

Docker安装

参考官方文档:

https://docs.docker.com/engine/install/

我的安装如下:

环境:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@ramon ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

[root@ramon ~]# uname -a
Linux ramon 3.10.0-957.27.2.el7.x86_64 #1 SMP Mon Jul 29 17:46:05 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

操作步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1. 卸载旧版本(没有就跳过)
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2. 安装需要的安装包
$ sudo yum install -y yum-utils
# 3. 设置镜像仓库(建议使用国内源)
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 4. 更新软件包索引
$ sudo yum makecache fast
# 5. 安装Docker(ce社区版本)
$ sudo yum install docker-ce docker-ce-cli containerd.io
# 6. 启动Docker
$ sudo systemctl start docker
# 7. 检查是否启动成功
$ docker version

最后,运行第一个实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@ramon ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
Status: Downloaded newer image for hello-world:latest

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环境已经搭建完成。

对了,如果你想卸载Docker,官方也给出了方法:

1
2
3
4
# 1. 卸载依赖
$ sudo yum remove docker-ce docker-ce-cli containerd.io
# 2. 删除所有资源
$ sudo rm -rf /var/lib/docker

Docker run流程

简单的分析下刚刚的docker run hello-world流程:

Docker-hello-world

流程分为如下四个步骤:

  1. 去本地找镜像,没找到
  2. 去远程仓库找镜像
  3. 远程仓库找到后下载
  4. 下载成功开始运行

可以分析出大概流程如下:

docker-run

Docker基础命令

帮助命令

1
2
3
docker version # docker版本信息
docker info # docker系统信息(包括镜像和容器信息)
docker command --help # 万能帮助命令

官方命令介绍文档:Reference documentation

官方命令图:

docker command

镜像命令

  1. docker images 查看所有本地的主机上的镜像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 [root@ramon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 470671670cac 4 months ago 237MB
hello-world latest bf756fb1ae65 5 months ago 13.3kB
# 解释
# REPOSITORY 镜像的仓库源(名字)
# TAG 镜像的标签(版本信息)
# IMAGE ID 镜像Id
# CREATED 创建时间
# SIZE 镜像大小
# docker images选项
[root@ramon ~]# 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 numeric IDs # 只输出id(脚本用到)
  1. docker search 搜索镜像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@ramon ~]# docker search nginx
# 解释(放不下所以截图了,看下面截图)
# NAME 镜像名称
# DESCRIPTION 描述信息
# STARS 收藏数
# OFFICIAL 是否为官方发布
# AUTOMATED 是否为Dockerfile自动生成
# docker search 选项
[root@ramon ~]# docker search --help
Usage: docker search [OPTIONS] TERM
Search the Docker Hub for images
Options:
-f, --filter filter Filter output based on conditions provided # 过滤器
--format string Pretty-print search using a Go template # 规定格式
--limit int Max number of search results (default 25) # 限制输出数量
--no-trunc Don't truncate output # 避免被截断,eg下面描述信息
docker search

注:除了使用命令,建议从官网搜索,可以得到更多镜像信息

  1. docker pull 下载镜像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[root@ramon ~]# docker pull mysql
Using default tag: latest # 不写tag模式就是latest,最新
latest: Pulling from library/mysql
8559a31e96f4: Pull complete # 分层下载,docker image核心(联合文件系统)
d51ce1c2e575: Pull complete
c2344adc4858: Pull complete
fcf3ceff18fc: Pull complete
16da0c38dc5b: Pull complete
b905d1797e97: Pull complete
4b50d1c6b05c: Pull complete
c75914a65ca2: Pull complete
1ae8042bdd09: Pull complete
453ac13c00a3: Pull complete
9e680cd72f08: Pull complete
a6b5dc864b6c: Pull complete
Digest: sha256:8b7b328a7ff6de46ef96bcf83af048cb00a1c86282bfca0cb119c84568b4caf6 # 签名信息
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
# 注意:
docker pull mysql <=> docker pull docker.io/library/mysql:latest # 相同的

# 下载5.7版本的mysql镜像
[root@ramon ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql # 加上标签后下载对应标签的镜像
8559a31e96f4: Already exists # 重点,分层下载的好处,已经有的就可以共用,节省空间
d51ce1c2e575: Already exists
c2344adc4858: Already exists
fcf3ceff18fc: Already exists
16da0c38dc5b: Already exists
b905d1797e97: Already exists
4b50d1c6b05c: Already exists
d85174a87144: Pull complete
a4ad33703fa8: Pull complete
f7a5433ce20d: Pull complete
3dcd2a278b4a: Pull complete
Digest: sha256:32f9d9a069f7a735e28fd44ea944d53c61f990ba71460c5c183e610854ca4854
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
  1. docker rmi 删除镜像
1
2
[root@ramon ~]# docker rmi image_id												# 删除指定镜像
[root@ramon ~]# docker rmi -f $(docker images -aq) # 删除全部镜像

容器命令

  1. docker run 新建并启动容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
https://cdn.jsdelivr.net/gh/gewuang/cloudimg
docker run [可选参数] image
# 常用参数
# --name="Name" 容器名称
# -d 后台方式运行
# -it 交互方式运行(前台)
# -p 指定容器与宿主机端口映射
# -p ip:宿主机端口:容器端口 映射到指定宿主机端口
# -p 宿主机端口:容器端口 映射到当前宿主机端口
# -p 容器端口 不开放外部
# 容器端口 同上
# -P 随机指定端口

# 使用/bin/bash启动并进入容器
[root@ramon ~]# docker run -it centos /bin/bash
[root@c436a9e8f153 /]#

# 从容器中退回主机
# $ exit 直接退出
# ^p^q 退出前台应用,后台继续执行
  1. docker ps 列出运行中的容器
docker ps

(文本框放不下一行内容,所以使用截图)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 选项
[root@ramon ~]# docker help 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
  1. docker rm 删除容器
1
2
3
4
5
6
7
8
9
10
docker rm 容器id 								# 删除指定容器(运行中的要使用-f选项)

# 选项
[root@ramon ~]# docker help rm
Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]
Remove one or more containers
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
dockerRm
  1. 启动和停止容器的操作
1
2
3
4
docker start 容器ID       # 启动容器
docker restart 容器ID # 重启容器
docker stop 容器ID # 停止当前运行的容器
docker kill 容器ID # 强制停止当前容器
  1. docker logs 查看日志
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 选项
[root@ramon ~]# docker help logs
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
Options:
--details Show extra details provided to logs
-f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
--tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)

# 实例
# 1. 创建一个运行中的容器
[root@ramon ~]# docker run -d centos /bin/sh -c "while true; do echo hello docker;sleep 1; done"
3c8b38832879ef4389b8d7129d7a003d01b83d0e5981316448c68a41ecb45a9b
# 2. 查看log
[root@ramon ~]# docker logs -ft 3c8b38832879e
2020-06-17T00:44:22.982085606Z hello docker
2020-06-17T00:44:24.060574474Z hello docker

# 3. 历史log太多可以只查看历史n行(这里n=10)
[root@ramon ~]# docker logs -tf --tail 10 3c8b38832879e
  1. 容器信息查看
1
2
3
# 查看容器进程信息
docker top 容器ID
# 实例见下图,太大了放不下
docker top
1
2
3
# 容器所有信息查看
docker inspect 容器ID
# 很重要,可以找到你想要的容器信息
  1. 进入运行中的容器

docker exec 启动新的终端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
docker exec -it 容器id /bin/bash
# 示例
[root@ramon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
60b1a3c64db8 centos "/bin/sh -c 'while t…" 32 seconds ago Up 31 seconds nervous_black
[root@ramon ~]# docker exec -it 60b1a3c64db8 /bin/bash
[root@60b1a3c64db8 /]# ps aux | grep echo
root 1 0.0 0.1 11880 1512 ? Ss 14:52 0:00 /bin/sh -c while true; do echo hello; sleep 1; done
root 80 0.0 0.0 9168 704 pts/0 S+ 14:53 0:00 grep --color=auto echo
[root@60b1a3c64db8 /]#

# 选项
[root@ramon ~]# 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
[root@ramon ~]#

docker attach 进入运行中的容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
docker attach 容器id

# 示例
[root@ramon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
60b1a3c64db8 centos "/bin/sh -c 'while t…" 59 minutes ago Up 59 minutes nervous_black
[root@ramon ~]# docker attach 60b1a3c64db8
hello
hello
hello

# 选项
[root@ramon ~]# docker attach --help
Usage: 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)
  1. docker cp 文件拷贝
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 选项
[root@ramon ~]# docker cp --help
Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER: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

# 示例(将文件从容器拷贝到本地)
[root@f17d770dee4e /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@f17d770dee4e /]# echo hello world > test
[root@f17d770dee4e /]# cat test
hello world
[root@ramon ~]# ls
[root@ramon ~]# docker cp f17d770dee4e:/test ./
[root@ramon ~]# ll test
-rw-r--r-- 1 root root 12 6月 18 00:11 test
[root@ramon ~]# cat test
hello world

参考文献

狂神B站Docker视频

-------------本文结束,感谢您的阅读-------------