Docker 学习笔记
最近公司的一些服务将要迁移至 Docker 平台,为了能够理解 Docker 原理,决定自己从零开始学习 Docker 这个风靡全球的容器解决方案,将学习的过程记录下来。
安装
Docker 在 CentOS 6.10 上的安装
公司的系统使用的是 CentOS 6,所以先将内核升级至 3.10 以上版本
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 源中
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
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 版本过低,升级一下
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 创建虚拟机时使用特定网段来解决:
other_args="-bip=192.168.100.1/24"
- 拉取镜像提示 Get https://index.docker.io/v1/repositories/library/hello-world/images: dial tcp 52.207.42.240:443: network is unreachable
这个肯定是网络问题了,公司的标准服务器是没有办法上外网的,系统环境变量中指定我自己的代理服务器居然也不管用,尝试了多种方法,目前问题还没解决
Docker 在 Ubuntu 16.04 上的安装
由于 Docker 最早就是在 Ubuntu 上发展出来的,这里也记录下 Ubuntu 16.04 的安装方法
首先,安装 Docker 官方仓库的 GPG key 到系统中
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
添加 Docker apt 源
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
然后,进行一下更新
sudo apt-get update
确认 Docker repo 可以安装
apt-cache policy docker-ce
如果看到下面的内容说明是 OK 的
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
sudo apt-get install -y docker-ce
确认 Docker 是否已经安装
sudo systemctl status docker
类似下面的输出说明正确安装了
● 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 一样无论如何加代理都不行
# 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 了
$ docker run hello-world
成功后会看到如下的输出:
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
运行一个 Docker 容器
hello-world 这个镜像的作用是输出一段文本然后退出,每一个 Docker 容器其实都是一个有特定功能的应用,比如 ubuntu 这个镜像,就是一个 Ubuntu 虚拟机。
试着运行一个
$ docker run -it -d ubuntu
# -it 参数可以让我们交互式的 shell 进入容器
这个时候会输出一段字符串,这段字符串可以理解为 Docker 容器 ID
41b162b9dd3f4dc2b7d37bf195a2c4f09d38a05cf750cfbf07e90313da2a3995
这个时候,我们就可以进入这个容器内,去一看究竟了
$ 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 容器情况
$ docker ps
输出如下:
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 参数就可以看到了
$ 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 容器
$ 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 命令可以将活动状态的容器停止运行
$ docker stop 41b162b9dd3f
不仅可以使用 container ID 指定容器,还可以使用容器别名来操作
$ docker stop zealous_murdock
zealous_murdock
停止运行的容器就可以关掉了,这里使用的命令是 docker rm
# docker rm zealous_murdock
zealous_murdock
- overlay2 代替 auFS 作为新的 Union File System 来使用