Docker 学习笔记

最近公司的一些服务将要迁移至 Docker 平台,为了能够理解 Docker 原理,决定自己从零开始学习 Docker 这个风靡全球的容器解决方案,将学习的过程记录下来。

安装

Docker 在 CentOS 6.10 上的安装

公司的系统使用的是 CentOS 6,所以先将内核升级至 3.10 以上版本

1
2
3
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
yum install https://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
yum --enablerepo=elrepo-kernel install kernel-lt -y

之后使用下面的命令将 Docker 源加入到 yum 源中

1
2
3
4
5
6
7
8
tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

之后运行下面的命令安装、启动 Docker

1
2
3
yum install -y docker-engine
service docker start

中间遇到很多问题,大概列举一下

  • docker: relocation error: docker: symbol dm_task_get_info_with_deferred_remove, version Base not defined in file libdevmapper.so.1.02 with link time reference

这个是说 device-mapper 版本过低,升级一下

1
yum update device-mapper
  • FATAL: Module bridge not found.

内核版本问题,升级到 3.10 以上解决

  • FATA[0000] Error starting daemon: Error initializing network controller: Error creating default “bridge” network: can’t find an address range for interface “docker0”

此错误是因为公司内网有 172.16.0.0/16 的路由表,将 docker0 的网卡网段占用了导致的,通过在 /etc/sysconfig/docker 中增加以下参数,强制让 Docker 创建虚拟机时使用特定网段来解决:

1
other_args="-bip=192.168.100.1/24"

这个肯定是网络问题了,公司的标准服务器是没有办法上外网的,系统环境变量中指定我自己的代理服务器居然也不管用,尝试了多种方法,目前问题还没解决

Docker 在 Ubuntu 16.04 上的安装

由于 Docker 最早就是在 Ubuntu 上发展出来的,这里也记录下 Ubuntu 16.04 的安装方法

首先,安装 Docker 官方仓库的 GPG key 到系统中

1
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

添加 Docker apt 源

1
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

然后,进行一下更新

1
sudo apt-get update

确认 Docker repo 可以安装

1
apt-cache policy docker-ce

如果看到下面的内容说明是 OK 的

1
2
3
4
5
6
7
Output of apt-cache policy docker-ce
docker-ce:
Installed: (none)
Candidate: 18.06.1~ce~3-0~ubuntu
Version table:
18.06.1~ce~3-0~ubuntu 500
500 https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages

安装 Docker

1
sudo apt-get install -y docker-ce

确认 Docker 是否已经安装

1
sudo systemctl status docker

类似下面的输出说明正确安装了

1
2
3
4
5
6
7
8
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2018-10-18 20:28:23 UTC; 35s ago
Docs: https://docs.docker.com
Main PID: 13412 (dockerd)
CGroup: /system.slice/docker.service
├─13412 /usr/bin/dockerd -H fd://
└─13421 docker-containerd --config /var/run/docker/containerd/containerd.toml

另外,docker run 仍然是提示网络问题无法访问,跟 CentOS 一样无论如何加代理都不行

1
2
3
4
# docker run hello-world
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
See 'docker run --help'.

最后,只能让 Docker Host 直接连接外网来解决这个问题。

使用

执行 Docker 命令

开始了解 Docker 命令,最简单的方法就是执行 Hello World 了

1
$ docker run hello-world

成功后会看到如下的输出:

1
2
3
4
Hello from Docker!
This message shows that your installation appears to be working correctly.

...

运行一个 Docker 容器

hello-world 这个镜像的作用是输出一段文本然后退出,每一个 Docker 容器其实都是一个有特定功能的应用,比如 ubuntu 这个镜像,就是一个 Ubuntu 虚拟机。

试着运行一个

1
2
3
$ docker run -it -d ubuntu

# -it 参数可以让我们交互式的 shell 进入容器

这个时候会输出一段字符串,这段字符串可以理解为 Docker 容器 ID

1
41b162b9dd3f4dc2b7d37bf195a2c4f09d38a05cf750cfbf07e90313da2a3995

这个时候,我们就可以进入这个容器内,去一看究竟了

1
2
3
4
5
6
7
8
$ docker exec -it 41b16 /bin/bash

root@41b162b9dd3f:/# ps -ef

UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:09 pts/0 00:00:00 /bin/bash
root 10 0 0 07:11 pts/1 00:00:00 /bin/bash
root 21 10 0 07:13 pts/1 00:00:00 ps -ef

管理

用一段时间的 Docker 之后,我们可能会有很多运行中的和非运行状态的容器,怎么去管理它们呢?

查看 Docker 容器

docker ps 命令可以让我们看到目前运行中的 Docker 容器情况

1
$ docker ps

输出如下:

1
2
3
4
5
6
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
41b162b9dd3f ubuntu "/bin/bash" 5 minutes ago Up 5 minutes zealous_murdock
47651cfa1d8e golang "bash" 14 hours ago Up 14 hours optimistic_lederberg
3b80522e5902 busybox "sh" 37 hours ago Up 37 hours zealous_darwin
8b881720ceb8 redis "docker-entrypoint.s…" 37 hours ago Up 37 hours 0.0.0.0:6379->6379/tcp musing_noyce
f3f14f20b61f nginx "nginx -g 'daemon of…" 37 hours ago Up 37 hours 80/tcp zealous_blackburn

奇怪,我们刚才运行的 Hello World 没有在列表里,什么原因呢?

其实 Hello World 属于非活动状态的镜像,只要给 docker ps 命令加上 -a 参数就可以看到了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
41b162b9dd3f ubuntu "/bin/bash" 6 minutes ago Up 6 minutes zealous_murdock
258796d0e4ed hello-world "/hello" 12 minutes ago Exited (0) 12 minutes ago trusting_swartz
47651cfa1d8e golang "bash" 14 hours ago Up 14 hours optimistic_lederberg
3b80522e5902 busybox "sh" 37 hours ago Up 37 hours zealous_darwin
8b881720ceb8 redis "docker-entrypoint.s…" 37 hours ago Up 37 hours 0.0.0.0:6379->6379/tcp musing_noyce
0a02170a956f hello-world "/hello" 37 hours ago Exited (0) 37 hours ago determined_mestorf
f3f14f20b61f nginx "nginx -g 'daemon of…" 37 hours ago Up 37 hours 80/tcp zealous_blackburn
b43d4f2ba5ed ubuntu "/bin/bash" 37 hours ago Exited (0) 7 minutes ago unruffled_snyder
66aa497d9767 ubuntu "/bin/bash" 37 hours ago Exited (0) 37 hours ago hungry_boyd
126e0f019b19 ubuntu "/bin/bash" 37 hours ago Exited (0) 37 hours ago competent_goldwasser
600adf161623 ubuntu "/bin/bash" 37 hours ago Exited (0) 37 hours ago upbeat_thompson
3b5d4380392f ubuntu "/bin/bash" 37 hours ago Exited (0) 37 hours ago pedantic_euclid
4fd577a1e8bf ubuntu "/bin/bash" 37 hours ago Exited (0) 37 hours ago upbeat_mcnulty

而如果使用 -l 参数,则可以看到最近创建的 Docker 容器

1
2
3
4
$ docker ps -l

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
41b162b9dd3f ubuntu "/bin/bash" 10 minutes ago Up 10 minutes zealous_murdock

关闭一个 Docker 容器

我们在测试过程中运行了很多容器实例了,一些容器不需要再去使用了,

使用 docker stop 命令可以将活动状态的容器停止运行

1
$ docker stop 41b162b9dd3f

不仅可以使用 container ID 指定容器,还可以使用容器别名来操作

1
2
3
$ docker stop zealous_murdock

zealous_murdock

停止运行的容器就可以关掉了,这里使用的命令是 docker rm

1
2
3
# docker rm zealous_murdock

zealous_murdock
  • overlay2 代替 auFS 作为新的 Union File System 来使用
Author

Archean Zhang

Posted on

2016-03-03

Updated on

2022-07-11

Licensed under

Comments