不会飞的章鱼

熟能生巧,勤能补拙;念念不忘,必有回响。

一天掌握Docker

Docker介绍与安装

Docker是什么

  • 使用最广泛的开源容器引擎
  • 一种操作系统级的虚拟化技术
  • 依赖于Linux内核特性:Namespace(资源隔离)和Cgroups(资源限制)
  • 一个简单的应用程序打包工具

Docker设计目标

  • 提供简单的应用程序打包工具
  • 开发人员和运维人员职责逻辑分离
  • 多环境保持一致性

Docker基本组成

  • Docker Client:客户端
  • Docker Daemon:守护进程
  • Docker Images:镜像
  • Docker Container:容器
  • Docker Registry:镜像仓库

容器 VS 虚拟机

Container VM
启动速度 秒级 分钟级
运行性能 接近原生 5%左右损失
磁盘占用 MB GB
数量 成百上千 一般几十台
隔离性 进程级别 系统级(更彻底)
操作系统 主要支持Linux 几乎所有
封装程度 只打包项目代码和依赖关系,共享宿主机内核 完整的操作系统

Docker应用场景

  • 应用程序打包和发布
  • 应用程序隔离
  • 持续集成
  • 部署微服务
  • 快速搭建测试环境
  • 提供PaaS产品(平台即服务)

Linux安装Docker

Docker版本

  • 社区版(Community Edition,CE)
  • 企业版(Enterprise Edition,EE)

支持平台

  • Linux(CentOS,Debian,Fedora,Oracle Linux,RHEL,SUSE和Ubuntu)
  • Mac
  • Windows

CentOS7.x安装Docker

1
2
3
4
5
6
7
8
9
10
11
# 安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加Docker软件包源
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 安装Docker CE
yum install -y docker-ce
# 启动Docker服务并设置开机启动
systemctl start docker
systemctl enable docker

镜像管理

什么是镜像?

简单说,Docker镜像是一个不包含Linux内核而又精简的Linux操作系统。

镜像从哪里来?

Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。

https://hub.docker.com/explore默认是国外的源,下载会慢,建议配置国内镜像仓库:

1
2
3
4
# vi /etc/docker/daemon.json 
{
"registry-mirrors": [ "https://registry.docker-cn.com"]
}

镜像与容器联系

镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history <ID/NAME>查看镜像中各层内容及大小,每层对应着Dockerfile中的一条指令。Docker镜像默认存储在/var/lib/docker/<storage-driver>中。
容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。
Docker使用存储驱动管理镜像每层内容及可读写层的容器层。

存储驱动

镜像管理指令

指令 Container
ls 列出镜像
build 构建镜像来自Dockerfile
history 查看镜像历史
inspect 显示一个或多个镜像详细信息
pull 从镜像仓库拉取镜像
push 推送一个镜像到镜像仓库
rm 移除一个或多个镜像
prune 移除未使用的镜像。没有被标记或被任何容器引用的
tag 创建一个引用源镜像标记目标镜像
export 导出容器文件系统到tar归档文件
import 导入容器文件系统tar归档文件创建镜像
save 保存一个或多个镜像到一个tar归档文件
load 加载镜像来自tar归档或标准输入
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
$ docker

Usage: docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
--config string Location of client config files (default
"/home/neo/.docker")
-c, --context string Name of the context to use to connect to the
daemon (overrides DOCKER_HOST env var and
default context set with "docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level
("debug"|"info"|"warn"|"error"|"fatal")
(default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default
"/home/neo/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default
"/home/neo/.docker/cert.pem")
--tlskey string Path to TLS key file (default
"/home/neo/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit

Management Commands:
builder Manage builds
config Manage Docker configs
container Manage containers
context Manage contexts
engine Manage the docker engine
image Manage images
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes

Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes

容器管理

创建容器常用选项

指令 描述 资源限制指令 描述
-i, –interactive 交互式 -m,–memory 容器可以使用的最大内存量
-t, –tty 分配一个伪终端 –memory-swap 允许交换到磁盘的内存量
-d, –detach 运行容器到后台 –memory-swappiness=<0-100> 容器使用SWAP分区交换的百分比(0-100,默认为-1)
-a, –attach list 附加到运行的容器 –memory-reservation 内存软限制,Docker检测主机容器争用或内存不足时所激活的软限制,使用此选项,值必须设置低于—memory,以使其优先
–dns list 设置DNS服务器 –oom-kill-disable 当宿主机内存不足时,内核会杀死容器中的进程。建议设置了-memory选项再禁用OOM。如果没有设置,主机可能会耗尽内存
-e, –env list 设置环境变量 –cpus 限制容器可以使用多少可用的CPU资源
–env-file list 从文件读取环境变量 –cpuset-cpus 限制容器可以使用特定的CPU
-p, –publish list 发布容器端口到主机 –cpu-shares 此值设置为大于或小于默认1024值,以增加或减少容器的权重,并使其可以访问主机CPU周期的更大或更小比例
-P, –publish-all 发布容器所有EXPOSE的端口到宿主机随机端口
-h, –hostname string 设置容器主机名
–ip string 指定容器IP,只能用于自定义网络
–link list 添加连接到另一个容器
–network 连接容器到一个网络
-v, –volume list 挂载宿主机目录到容器
–restart string 容器退出时重启策略,默认no[always on-failure]
–add-host list 添加其他主机到容器中/etc/hosts

管理容器常用命令

指令 描述
ls 列出容器
attach 附加本地标准输入,输出和错误到一个运行的容器
exec 在运行容器中执行命令
inspect 显示一个或多个容器详细信息
commit 创建一个新镜像来自一个容器
cp 拷贝文件/文件夹到一个容器
logs 获取一个容器日志
port 列出或指定容器端口映射
stats 显示容器资源使用统计
top 显示一个容器运行的进程
update 更新一个或多个容器配置
stop/start 停止/启动一个或多个容器
rm 删除一个或多个容器

管理应用程序数据

将Docker主机数据挂载到容器

Docker提供三种不同的方式将数据从宿主机挂载到容器中:volumes,bind mounts和tmpfs。
volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。
bind mounts:可以存储在宿主机系统的任意位置。
tmpfs:挂载存储在宿主机系统的内存中,而不会写入宿主机的文件系统。

Volume

1
2
3
4
5
6
7
8
9
10
11
管理卷:
# docker volume create nginx-vol
# docker volume ls
# docker volume inspect nginx-vol
用卷创建一个容器:
# docker run -d -it --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
# docker run -d -it --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx
清理:
# docker container stop nginx-test
# docker container rm nginx-test
# docker volume rm nginx-vol

注意:

  • 如果没有指定卷,自动创建。
  • 建议使用mount,更通用。

官方文档

Bind Mounts

1
2
3
4
5
6
7
8
用卷创建一个容器:
# docker run -d -it --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
# docker run -d -it --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx
验证绑定:
# docker inspect nginx-test
清理:
# docker container stop nginx-test
# docker container rm nginx-test

注意:

  • 如果源文件/目录没有存在,不会自动创建,会抛出一个错误。
  • 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。

官方文档

搭建LNMP(Linux+Nginx+MySQL+PHP)网站平台

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
1、自定义网络
docker network create lnmp
2、创建Mysql数据库容器
docker run -itd \
--name lnmp_mysql \
--net lnmp \
-p 3306:3306 \
--mount src=mysql-vol,dst=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7 --character-set-server=utf8

3、创建所需数据库
docker exec lnmp_mysql sh \
-c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e"create database wp"'

4、创建PHP环境容器
docker run -itd \
--name lnmp_web \
--net lnmp \
-p 88:80 \
--mount type=bind,src=/app/wwwroot,dst=/var/www/html richarvey/nginx-php-fpm

5、以wordpress博客为例测试
wget https://cn.wordpress.org/wordpress-4.7.4-zh_CN.tar.gz
tar zxf wordpress-4.7.4-zh_CN.tar.gz -C /app/wwwroot
# 浏览器测试访问
http://IP:88/wordpress

网络管理

网络模式

Docker支持5种网络模式

  • bridge:默认网络,Docker启动后默认创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
  • host:容器不会获得一个独立的network namespace,而是与宿主机共用一个。
  • none:获取独立的network namespace,但不为容器进行任何网络配置。
  • container:与指定的容器使用同一个network namespace,网卡配置也都是相同的。
  • 自定义:自定义网桥,默认与bridge网络一样。

Dockerfile

Dockerfile指令

指令 描述
FROM 构建的新镜像是基于哪个镜像。例如:FROM centos:6
MAINTAINER 镜像维护者姓名或邮箱地址。例如:MAINTAINER lizhenliang
RUN 构建镜像时运行的Shell命令。例如:RUN [“yum”, “install”, “httpd”],RUN yum install httpd
CMD 运行容器时执行的Shell命令。例如:CMD [“-c”, “/start.sh”],CMD [“/usr/sbin/sshd”, “-D”],CMD /usr/sbin/sshd –D
EXPOSE 声明容器运行的服务端口。例如:EXPOSE 80 443
ENV 设置容器内环境变量。例如:ENV MYSQL_ROOT_PASSWORD 123456
ADD 拷贝文件或目录到镜像,如果是URL或压缩包会自动下载或自动解压。ADD ,ADD https://xxx.com/html.tar.gz /var/www/html
COPY 拷贝文件或目录到镜像。例如:COPY ./start.sh /start.sh
ENTRYPOINT 运行容器时执行的Shell命令。例如:例如:ENTRYPOINT [“/bin/bash”, “-c”, “/start.sh”],ENTRYPOINT /bin/bash -c ‘/start.sh’
VOLUME 指定容器挂载点到宿主机自动生成的目录或其他容器。例如:例如:VOLUME [“/var/lib/mysql”]
USER 为RUN、CMD和ENTRYPOINT执行命令指定运行用户为RUN、CMD和ENTRYPOINT执行命令指定运行用户USER [:] or USER [:]。例如:USER neozhang
WORKDIR 为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录。例如:WORKDIR /data
HEALTHCHECK 健康检查。HEALTHCHECK –interval=5m –timeout=3s –retries=3 \ CMD curl -f http://localhost/
ARG 在构建镜像时指定一些参数。例如:FROM centos:6,ARG user # ARG user=root,USER $user ,# docker build –build-arg user=lizhenliang Dockerfile .

Build镜像命令

1
2
3
4
Usage:  docker image build [OPTIONS] PATH | URL | -
Options:
-t, --tag list # 镜像名称
-f, --file string # 指定Dockerfile文件位置

示例:

1
2
3
docker build .
docker build -t shykes/myapp .
docker build -t shykes/myapp -f /path/Dockerfile /path

构建PHP网站环境镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FROM centos:7
MAINTAINER www.aliangedu.com
RUN yum install -y gcc gcc-c++ make openssl-devel pcre-devel
ADD nginx-1.12.1.tar.gz /tmp

RUN cd /tmp/nginx-1.12.1 && \
./configure --prefix=/usr/local/nginx && \
make -j 2 && \
make install

RUN rm -rf /tmp/nginx-1.12.1* && yum clean all

COPY nginx.conf /usr/local/nginx/conf

WORKDIR /usr/local/nginx
EXPOSE 80
CMD ["./sbin/nginx", "-g", "daemon off;"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
FROM centos:7
MAINTAINER www.aliangedu.com
RUN yum install -y gcc gcc-c++ make gd-devel libxml2-devel libcurl-devel libjpeg-devel libpng-devel openssl-devel
ADD php-5.6.31.tar.gz /tmp/

RUN cd /tmp/php-5.6.31 && \
./configure --prefix=/usr/local/php \
--with-config-file-path=/usr/local/php/etc \
--with-mysql --with-mysqli \
--with-openssl --with-zlib --with-curl --with-gd \
--with-jpeg-dir --with-png-dir --with-iconv \
--enable-fpm --enable-zip --enable-mbstring && \
make -j 4 && \
make install && \
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
sed -i "s/127.0.0.1/0.0.0.0/" /usr/local/php/etc/php-fpm.conf && \
sed -i "21a \daemonize = no" /usr/local/php/etc/php-fpm.conf
COPY php.ini /usr/local/php/etc

RUN rm -rf /tmp/php-5.6.31* && yum clean all

WORKDIR /usr/local/php
EXPOSE 9000
CMD ["./sbin/php-fpm", "-c", "/usr/local/php/etc/php-fpm.conf"]

自定义网络

1
docker network create lnmp

创建PHP容器

1
2
3
4
5
docker run -itd \
--name lnmp_php \
--net lnmp \
--mount type=bind,src=/app/wwwroot/,dst=/usr/local/nginx/html \
php:v1

创建Nginx容器

1
2
3
4
5
docker run -itd \
--name lnmp_nginx \
--net lnmp \
--mount type=bind,src=/app/wwwroot/,dst=/usr/local/nginx/html \
nginx:v1

创建MySQL容器

1
2
3
4
5
6
7
docker run -itd \
--name lnmp_mysql \
--net lnmp \
-p 3306:3306 \
--mount src=mysql-vol,dst=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql --character-set-server=utf8

构建JAVA网站环境镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM centos:7
MAINTAINER www.aliangedu.com

ADD jdk-8u45-linux-x64.tar.gz /usr/local
ENV JAVA_HOME /usr/local/jdk1.8.0_45

ADD apache-tomcat-8.0.46.tar.gz /usr/local
COPY server.xml /usr/local/apache-tomcat-8.0.46/conf

RUN rm -f /usr/local/*.tar.gz

WORKDIR /usr/local/apache-tomcat-8.0.46
EXPOSE 8080
ENTRYPOINT ["./bin/catalina.sh", "run"]

创建容器

1
2
3
4
5
docker run -itd \
--name=tomcat \
-p 8080:8080 \
--mount type=bind,src=/app/webapps/,dst=/usr/local/apache-tomcat-8.0.46/webapps \
tomcat:v1

镜像仓库

Harbor是VMware公司开源的企业级Docker Registry项目

参考资料

Docker官方文档
阿里云源:http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

------ 本文结束------
如果本篇文章对你有帮助,可以给作者加个鸡腿~(*^__^*),感谢鼓励与支持!