Docker基本介绍与安装
Docker入门基础知识
1. 初识Docker
Docker是一个开源应用容器引擎,使用Go语言开发,基于Linux内核的cgroup,namespace, Union FS等技术,对应用进程进行封装隔离,并且独立于宿主机与其他进程,这种运行时封装的状态称为容器。
Docker的优点
Docker的理念是将应用及依赖包打包到一个可移植的容器中,可发布到任意Linux发行版Docker引擎上。使用沙箱机制运行程序,程序之间相互隔离
总结:开箱服务,快速部署,可移植性强,环境隔离等。
Docker的体系结构
Containerd: 是一个简单的守护进程,使用runC管理容器,向Docker Engine提供接口。
Shim:只负责管理一个容器。
runC: 是一个轻量级的工具,只用来运行容器。
内部组件
(1)Kernel Namespace
命名空间,Linux内核提供的一种对进程资源隔离的机制,例如进程、网络、挂载点等资源。
(2)CGroups
控制组,Control Group,Linux内核提供的一种限制进程资源的机制,例如CPU、内存等资源
ls -l /sys/fs/cgroup/
(3)UnionFS
联合文件系统—Union File System,支持将不同位置的目录挂载到同一虚拟文件系统
docker exec -it dockerid
虚拟机与容器的区别
容器在Linux上本机运行,并与其他容器共享主机的内核。 它运行一个独立的进程,不占用任何其他可执行文件的内存,使其轻量级。
相比之下,虚拟机(VM)运行一个完整的“客户”操作系统,通过虚拟机管理程序对主机资源进行虚拟访问。 通常,VM提供的环境比大多数应用程序需要的资源更多。
容器和虚拟机都依赖于宿主机才能运行,宿主机可以是笔记本,是数据中心的物理服务器,也可以是公有云的某个实例。
(1)虚拟机
在虚拟机模型中,首先要开启物理机并启动Hypervisor引导程序(实际上还有BIOS和Bootloader代码等)。 一旦Hypervisor启动,就会占用机器上的物理资源,如CPU、RAM、存储和NIC等,Hypervisor接下来就会将这些物理资源划分为虚拟资源,并且看起来与真实物理资源完全一致。
然后Hypervisor会将打包进一个叫做虚拟机(VM)的软件结构中,这样用户就可以使用这些虚拟机,并在其中安装OS和App,如上图,假设在物理机上运行3个应用,那么在Hypervisor之上需要创建3个虚拟机并且安装3个OS,然后安装相应的App.
缺点:
(a)依赖特定的操作系统(OS),OS会占用额外的CPU,RAM和存储,而这些资源本可以运行更多的应用。
(b)每个OS需要特定的补丁和监控,在某些情况下OS需要许可证才能运行,对运营成本和资金性支出都是一种浪费。
从更高层面上来讲,Hypervisor是硬件虚拟化(Hardware Virtualization),——Hypervisor将硬件物理资源划分为虚拟资源;另外,容器是操作系统虚拟化(OS Virtualization)——容器将系统资源划分为虚拟资源。
虚拟机的额外开销
虚拟机模型将底层硬件资源划分到虚拟机当中,每个虚拟机都是包含了虚拟CPU,虚拟RAM,虚拟磁盘等资源的一种软件结构。因此每个VM都需要自身OS来声明、初始化并管理这些虚拟资源。但是OS本身都需要额外开销,还有独立的许可证,并且打补丁升级,每个操作系统也都面临被攻击的风险。这种现象称为 OS Tax 或者 VM Tax,每个OS都占用一定的资源。
(2)容器
而在容器模型中,略有不同,服务器启动后,所选择的OS会启动,在Docker中可以是Linux,或者Windows,与虚拟机相同,OS也占用了全部的硬件资源,在OS之上,需要安装容器引擎(如Docker),容器引擎可以获取系统资源,比如进程树、文件系统以及网络,接着将资源分隔为安全的互相隔离的资源结构,称为** “容器” **。每个容器看起来就像一个真实的OS,在其内部可以运行应用,按照前面的假设,需要在物理机上运行3个App,因此,需要划分3个容器并在每个容器中运行一个应用。
容器模型具有在宿主机OS中运行单个内核。在一台主机上运行数十个甚至数百个容器都是可能的——容器共享一个OS/Kernel,这意味着只有一个OS消耗CPU,RAM和存储资源,只有一个OS需要授权,只有一个OS需要升级和打补丁。
以KVM和Docker对比为例:
(1)启动时间
Docker秒级启动,KVM分钟级启动。这是因为容器并不是完整的OS,在容器内部并不需要内核,也没有定位、解压以及初始化的过程——更不用提在内核启动过程中对硬件的遍历和初始化了
(2)轻量级
容器镜像大小通常以M为单位,虚拟机以G为单位。
(3)性能
(4)安全性
Docker
(5)使用要求
KVM基于硬件的完全虚拟化,需要硬件CPU虚拟化技术支持;
应用场景
(1) 节省项目环境部署时间
1)单项目打包
2)整套项目打包
3)新开源技术试用
直接从公共镜像仓库pull项目官方做好镜像启动容器即可。
(2) 环境一致性
开发工程师在Windows系统上开发项目,测试,生产环境操作系统都是Linux系统,这就有环境一致性
(3) 持续集成
(4) 微服务
Docker的容器设计原则:一个容器一个服务,容器之间相互隔离,尽可能细粒度
(5) 弹性伸缩
AWS AutoScaling,可以自定义资源阈值,SLB自动添加EC2云主机,应对业务的高峰期。
Docker-CE安装
# 安装依赖包
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
# 更新yum包索引
yum makecache fast
# 安装Docker CE
yum install docker-ce
# 如果出现 No Package docker-ce availabel,执行以下命令
yum install epel-release
yum install docker-io
# 启动
systemctl start docker
卸载Docker
yum remove docker-ce
rm -rf /var/lib/docker
更多问题详见:
https://docs.docker.com/engine/installation/linux/docker-ce/centos/#docker-ce-customers
需要修改时区:
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
date -s “2019-05-05 10:05:00”
2. 镜像管理
镜像是什么
简单地说,Docker镜像是一个不包含Linux内核而又精简的Linux操作系统。
镜像从哪里来?
Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。https://hub.docker.com/explore
默认是国外的源,下载较慢,建议配置国内镜像仓库:
镜像与容器的联系
(1)镜像存在的位置:
ls /var/lib/docker/image
overlay2
cd /var/lib/docker
ls
builder buildkit containers engine_uuid image network overlay2 plugins runtimes swarm tmp trust volumes
[root@docker-vm1 docker]# cd overlay2/
[root@docker-vm1 overlay2]# ls
0f144a211f6cac8edb581d5467a161f8361eae92affba5a9aed2603ec6168e88
0f144a211f6cac8edb581d5467a161f8361eae92affba5a9aed2603ec6168e88-init
40c38df3ee558330e25623cb587f3ee739dc06dcab0fb8642e3f8931a7cd250a
42e2d9f287fdc35d3997c0d0e340897308a1dec23eed14e5f12874012268eb52
5e939e8c46f4e06ccc60fdcc782cceeb78a49f9ea3345f83433c0dc2a9221f49
9c3edd7f769da639a6cac65cd7612f4a0745acb4454e6261bc32e1fd2b356e3f
backingFsBlockDev
l
存储驱动
每个docker容器都有一个本地存储空间,用于保存层叠的镜像层(Image Layer)以及挂载的容器文件系统。默认情况下,容器所有的读写操作都发生在其镜像层上或者挂载的文件系统中,所以存储是每个容器的性能和稳定性不可或缺的一个环节。
常见的Linux发行版支持的存储驱动
Linux distribution | Recommended storage drivers |
---|---|
Docer CE on Ubuntu | aufs, devicemapper,overlay2(Ubuntu 14.04 or later, 16.04 or later), overlay,zfs, vfs |
Docer CE on Debian | aufs, devicemapper, overlay2(Debian Stretch), overlay, vfs |
Docker CE on CentOS | devicemapper, vfs |
Docker CE on Fedora | devicemapper, overlay2(Fedora 26 or later, experimental), overlay(experimental),vfs |
Storage driver | Supported backing filesystems |
---|---|
overlay,overlay2 | ext4,xfs |
aufs | ext4,xfs |
devicemapper | direct-lvm |
btrfs | btrfs |
zfs | zfs |
存储驱动:
注意:
aufs: Ubuntu
overlay overlay2:性能最好,只支持ext4和xfs.
devicemapper: CentOS 早期支持的
下载镜像
例如:下载NGINX,即从Docker主机上获取镜像的操作被称为“拉取”。
[root@docker-vm1 docker]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
27833a3ba0a5: Pull complete
ea005e36e544: Pull complete
d172c7f0578d: Pull complete
Digest: sha256:e71b1bf4281f25533cf15e6e5f9be4dac74d2328152edf7ecde23abc54e16c1c
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
镜像管理命令
(1) 镜像查看
docker images
[root@docker-vm1 overlay2]# docker image inspect nginx:latest
[
{
"Id": "sha256:27a188018e1847b312022b02146bb7ac3da54e96fab838b7db9f102c8c3dd778",
"RepoTags": [
"nginx:latest"
],
"RepoDigests": [
"nginx@sha256:e71b1bf4281f25533cf15e6e5f9be4dac74d2328152edf7ecde23abc54e16c1c"
],
....此处省略
(2) 镜像拉取和推送
docker image pull 容器:tags
[root@docker-vm1 docker]# docker image pull nginx:1.14
1.14: Pulling from library/nginx
27833a3ba0a5: Already exists
0f23e58bd0b7: Pull complete
8ca774778e85: Pull complete
Digest: sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
Status: Downloaded newer image for nginx:1.14
docker.io/library/nginx:1.14
(3)删除一个镜像
docker image rm 容器:tags
[root@docker-vm1 docker]# docker image rm nginx:1.14
Untagged: nginx:1.14
Untagged: nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
Deleted: sha256:295c7be079025306c4f1d65997fcf7adb411c88f139ad1d34b537164aa060369
Deleted: sha256:19606512dfe192788a55d7c1efb9ec02041b4e318587632f755c5112f927e0e3
Deleted: sha256:0b83495b3ad3db8663870c3babeba503a35740537a5e25acdf61ce6a8bdad06f
(4) 标记镜像
docker tag 容器:原始tag 容器:打上的tag
[root@docker-vm1 docker]# docker tag nginx:1.11 nginx:v1
[root@docker-vm1 docker]# docker images
(5) 导出导入镜像
docker image save 镜像名 > 压缩文件名
docker load < nginx1.11.tar
[root@docker-vm1 ~]# docker image save nginx:1.11 > nginx1.11.tar
[root@docker-vm1 ~]# du -sh nginx1.11.tar
182M nginx1.11.tar
注意区分容器导出导入:
# 导出容器
[root@docker-vm1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7e5bd420ac2 nginx "nginx -g 'daemon of…" 22 seconds ago Up 20 seconds 80/tcp brave_booth
[root@docker-vm1 ~]# docker export a7e5bd420ac2 > nginx.tar
[root@docker-vm1 ~]# ls
anaconda-ks.cfg nginx1.11.tar nginx.tar
[root@docker-vm1 ~]# du -sh nginx.tar
107M nginx.tar
# 导入容器
[root@docker-vm1 ~]# docker image import nginx.tar
sha256:b8544495b468974c37d5e8220e02ac1aff744d5b349c594dcec1a9edd2c2ef00
[root@docker-vm1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> b8544495b468 5 seconds ago 108MB
nginx latest 27a188018e18 2 weeks ago 109MB
hello-world latest fce289e99eb9 4 months ago 1.84kB
nginx 1.11 5766334bdaa0 2 years ago 183MB
nginx v1 5766334bdaa0 2 years ago 183MB
3. 容器管理
[root@docker-vm1 ~]# docker container --help
Usage: docker container COMMAND
Manage containers
Commands:
attach Attach local standard input, output, and error streams to a running container
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
exec Run a command in a running container
export Export a container's filesystem as a tar archive inspect Display detailed information on one or more containers kill Kill one or more running containers logs Fetch the logs of a container ls List containers pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container prune Remove all stopped containers rename Rename a container restart Restart one or more containers rm Remove one or more containers 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 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 wait Block until one or more containers stop, then print their exit codes Run 'docker container COMMAND --help' for more information on a command.
(1) 创建容器
Usage: docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 比如创建名为“ng"的nginx的docker容器。
[root@docker-vm1 ~]# docker container run -itd --name ng nginx
bc1038da3e2281a956d7ea6ed851c29b6d704589ff62da356d29a2bb5c6ef8b6
[root@docker-vm1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc1038da3e22 nginx "nginx -g 'daemon of…" 5 seconds ago Up 4 seconds 80/tcp ng
a7e5bd420ac2 nginx "nginx -g 'daemon of…" 25 minutes ago Up 25 minutes 80/tcp brave_booth
# 进入容器中,其中bc1038da3e22为容器ID.
[root@docker-vm1 ~]# docker exec -it bc1038da3e22 /bin/bash
root@bc1038da3e22:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
# 带参数变量创建容器
[root@docker-vm1 ~]# docker container run -itd -e a=123 --name ng1 nginx
b359b0825a4c4a542aa0e51c88e77e052867b16a4103fdb0cb5096329ed728ab
[root@docker-vm1 ~]# docker exec -it ng1 sh
# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
# echo $a
123
# 退出容器采用Ctrl-PQ组合键退出,退出后不会杀死容器进程。
[root@docker-vm1 ~]# docker container run -it nginx bash
root@90bb3f73703c:/# [root@docker-vm1 ~]#
(2)暴露端口到宿主机上
# 把容器的8080端口暴露到宿主机上的80端口,从浏览器进行访问。
[root@docker-vm1 ~]# docker run -itd -p 8080:80 --name ng1 nginx
83272b414ed8cb818a7bed86f9ad923d42f68d1c7d85c449d3bdc723d3855cdb
[root@docker-vm1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83272b414ed8 nginx "nginx -g 'daemon of…" 8 minutes ago Up 8 minutes 0.0.0.0:8080->80/tcp ng1
# 可以查看容器内的日志输出
[root@docker-vm1 ~]# docker logs ng1
202.201.3.54 - - [05/May/2019:12:50:52 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36" "-"
[root@docker-vm1 ~]# ls /var/lib/docker/containers/83272b414ed8cb818a7bed86f9ad923d42f68d1c7d85c449d3bdc723d3855cdb/
83272b414ed8cb818a7bed86f9ad923d42f68d1c7d85c449d3bdc723d3855cdb-json.log config.v2.json hostname mounts resolv.conf.hash
checkpoints hostconfig.json hosts resolv.conf
# 也可以查看ContainerID.log文件中的日志。一般在/var/lib/docker/containers/ContainerID/ContainerID.log文件中。
[root@docker-vm1 ~]# tail /var/lib/docker/containers/83272b414ed8cb818a7bed86f9ad923d42f68d1c7d85c449d3bdc723d3855cdb/83272b414ed8cb818a7bed86f9ad923d42f68d1c7d85c449d3bdc723d3855cdb-json.log
{"log":"202.201.3.54 - - [05/May/2019:12:50:52 +0000] \"GET / HTTP/1.1\" 200 612 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\" \"-\"\r\n","stream":"stdout","time":"2019-05-05T12:50:52.886884817Z"}
{"log":"2019/05/05 12:50:53 [error] 6#6: *1 open() \"/usr/share/nginx/html/favicon.ico\" failed (2: No such file or directory), client: 202.201.3.54, server: localhost, request: \"GET /favicon.ico HTTP/1.1\", host: \"172.16.4.12:8080\", referrer: \"http://172.16.4.12:8080/\"\r\n","stream":"stdout","time":"2019-05-05T12:50:53.155300878Z"}
{"log":"202.201.3.54 - - [05/May/2019:12:50:53 +0000] \"GET /favicon.ico HTTP/1.1\" 404 556 \"http://172.16.4.12:8080/\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\" \"-\"\r\n","stream":"stdout","time":"2019-05-05T12:50:53.155345527Z"}
然后访问,可以看出以下页面。
(3)执行重启策略
# restart=always 表示容器退出时重启策略,默认是no
[root@docker-vm1 ~]# docker container run -itd -p 8081:80 --name ng2 --restart=always nginx
3924a1bb00da877284fdc2d2058ec1ed23809d50a185bc1a112c4e3a841a3afa
(4 )容器资源限制!!!
(1)CPU资源限制
[root@docker-vm1 ~]# docker container run --help | grep cpu
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
--cpu-rt-period int Limit CPU real-time period in microseconds
--cpu-rt-runtime int Limit CPU real-time runtime in microseconds
-c, --cpu-shares int CPU shares (relative weight)
--cpus decimal Number of CPUs
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
# 例如,限制名为ng4的容器最多只能使用2个CPU,命令如下。
[root@docker-vm1 ~]# docker container run -itd --cpus 2 --name ng4 nginx
cd84736c6355616ea53e37670ecbe6223622980fc5b1fd0208298341c330ebc1
[root@docker-vm1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cd84736c6355 nginx "nginx -g 'daemon of…" 4 seconds ago Up 3 seconds 80/tcp ng4
# 同理,可以指定内存,如采用-m指定ng5容器不能使用超过1G的内存,则其默认swap将不会超过物理内存的两倍。
[root@docker-vm1 ~]# docker container run -itd -m 1G --name ng5 nginx
2d0f11403566dc8c607e82dcbf46da978fdc755b5057fbbb28fd910dcb2d1bea
[root@docker-vm1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d0f11403566 nginx "nginx -g 'daemon of…" 4 seconds ago Up 3 seconds 80/tcp ng5
# 通过docker container stats 容器名,可以查看资源利用率。
[root@docker-vm1 ~]# docker container stats ng5
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
2d0f11403566 ng5 0.00% 1.355MiB / 1GiB 0.13% 656B / 0B 0B / 0B 2
容器管理常用命令
(1)查看运行的容器
[root@docker-vm1 ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d0f11403566 nginx "nginx -g 'daemon of…" 7 minutes ago Up 7 minutes 80/tcp ng5
cd84736c6355 nginx "nginx -g 'daemon of…" 22 minutes ago Up 22 minutes 80/tcp ng4
3924a1bb00da nginx "nginx -g 'daemon of…" 30 minutes ago Up 30 minutes 0.0.0.0:8081->80/tcp ng2
83272b414ed8 nginx "nginx -g 'daemon of…" 50 minutes ago Up 50 minutes 0.0.0.0:8080->80/tcp ng1
bc1038da3e22 nginx "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp ng
a7e5bd420ac2 nginx "nginx -g 'daemon of…" 2 hours ago Up 2 hours 80/tcp brave_booth
# 查看容器的详细信息
[root@docker-vm1 ~]# docker container inspect 2d0f11403566
[
{
"Id": "2d0f11403566dc8c607e82dcbf46da978fdc755b5057fbbb28fd910dcb2d1bea",
"Created": "2019-05-05T13:33:17.914070311Z",
"Path": "nginx",
"Args": [
"-g",
"daemon off;"
],
# .....此处省略多数内容
(2)进入容器
# 此处注意,使用attach进入卡住,因为容器可能有进程正在运行
[root@docker-vm1 ~]# docker container attach ng4
# 可以发现ng4容器中有nginx -g进程一直在前台运行
[root@docker-vm1 ~]# docker top ng4
UID PID PPID C STIME TTY TIME CMD
root 8428 8410 0 21:18 pts/0 00:00:00 nginx: master process nginx -g daemon off;
101 8462 8428 0 21:18 pts/0 00:00:00 nginx: worker process
# 此时应该采用docker container exec来开启伪终端。
[root@docker-vm1 ~]# docker container exec -it ng4 bash
root@cd84736c6355:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
(3)容器与宿主机之间的互操作
# 拷贝文件,如将宿主机中的anaconda-ks.cfg拷贝到ng4容器的/root下,重启后并不会丢失。
[root@docker-vm1 ~]# docker container exec ng4 ls /root
[root@docker-vm1 ~]# docker container cp anaconda-ks.cfg ng4:/root
[root@docker-vm1 ~]# docker container exec ng4 ls /root
anaconda-ks.cfg
# 同理,可以从容器拷贝文件到宿主机
(4)查看日志和端口映射
[root@docker-vm1 ~]# docker logs ng1
202.201.3.54 - - [05/May/2019:12:50:52 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36" "-"
2019/05/05 12:50:53 [error] 6#6: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 202.201.3.54, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "172.16.4.12:8080", referrer: "http://172.16.4.12:8080/"
202.201.3.54 - - [05/May/2019:12:50:53 +0000] "GET /favicon.ico HTTP/1.1" 404 556 "http://172.16.4.12:8080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36" "-"
[root@docker-vm1 ~]# docker port ng1
80/tcp -> 0.0.0.0:8080
(5)动态更改资源限制
[root@docker-vm1 ~]# docker container update --help
Usage: docker container update [OPTIONS] CONTAINER [CONTAINER...]
Update configuration of one or more containers
Options:
--blkio-weight uint16 Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
--cpu-rt-period int Limit the CPU real-time period in microseconds
--cpu-rt-runtime int Limit the CPU real-time runtime in microseconds
-c, --cpu-shares int CPU shares (relative weight)
--cpus decimal Number of CPUs
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--kernel-memory bytes Kernel memory limit
-m, --memory bytes Memory limit
--memory-reservation bytes Memory soft limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--pids-limit int Tune container pids limit (set -1 for unlimited)
--restart string Restart policy to apply when a container exits
4. 管理应用程序数据
将Docker主机数据挂载挂载到容器
Docker提供三种不同的方式将数据从宿主机挂载到容器中: volumes, bind mounts和 tmpfs。
volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)
[root@docker-vm1 ~]# ls /var/lib/docker/volumes/
metadata.db
volume : 卷存储在由Docker管理的主机文件系统的一部分中(Linux上的/var/lib /docker /volumes /)。 非Docker进程不应修改文件系统的这一部分。 卷是在Docker中保留数据的最佳方式。
bind mounts:可以存储在宿主机系统的任意位置,它们甚至可能是重要的系统文件或目录。 Docker主机或Docker容器上的非Docker进程可以随时修改它们。
tmpfs:挂载存储在宿主机系统的内存中,而不会写入宿主机的文件系统。
(1)volume
[root@docker-vm1 ~]# docker volume --help
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
# 创建volume
[root@docker-vm1 ~]# docker volume create nginx-vol
nginx-vol
# 查看volume详细信息
[root@docker-vm1 ~]# docker volume inspect nginx-vol
[
{
"CreatedAt": "2019-05-06T08:56:14+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx-vol/_data",
"Name": "nginx-vol",
"Options": {},
"Scope": "local"
}
]
# 创建数据卷,发现宿主机上的/var/lib/docker/volumes/nginx-vol/_data和容器中的/usr/share/nginx/html的文件相同。
# 实际上也可以用 以下命令,但是不具有通用性,只支持volume的形式创建数据卷。
# docker run -d -it --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx
[root@docker-vm1 ~]# docker run -d -it --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
f648a79285b958ce11ab3c3c240727b9c4066cd1a50975264fdf7bc38da5a98a
[root@docker-vm1 ~]# docker container exec -it nginx-test bash
root@f648a79285b9:/# cd /usr/share/nginx/html/
root@f648a79285b9:/usr/share/nginx/html# ls
50x.html index.html
[root@docker-vm1 ~]# ls /var/lib/docker/volumes/nginx-vol/_data/
50x.html index.html
# 测试发现新建1.html文件,在宿主机和容器中都会出现相应的文件。实际上相当于做了个软连接。
root@f648a79285b9:/usr/share/nginx/html# touch 1.html
root@f648a79285b9:/usr/share/nginx/html# ls
1.html 50x.html index.html
root@f648a79285b9:/usr/share/nginx/html# exit
exit
[root@docker-vm1 ~]# ls /var/lib/docker/volumes/nginx-vol/_data/
1.html 50x.html index.html
# 删除所有的容器
[root@docker-vm1 ~]# docker rm -f $(docker ps -qa)
f648a79285b9
2d0f11403566
cd84736c6355
3924a1bb00da
83272b414ed8
bc1038da3e22
a7e5bd420ac2
0bf677158ebb
# 重新创建容器,并暴露8080端口给宿主机。
[root@docker-vm1 ~]# docker run -d -it --name=nginx-test -p 8080:80 --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
ae4f6caad9cd2f638d175a3534004ea2c827d716f44a619c79224148482785fa
再次查看宿主机的/var/lib/docker/volumes/nginx-vol/_data/的数据仍旧存在。再该目录下创建1.html,写入
<h1> hello World!!!</h1>
然后输入网页地址,比如:172.16.4.12:8080/1.html即可访问到相应页面。说明可以访问到容器的数据卷。
同时可以创建多个容器,然后共享同一个数据卷,比如在创建一个名为nginx-test2的容器,但是仍旧公用数据卷nginx-vol
# 注意端口必须不一样。此处暴露的是8081端口
[root@docker-vm1 _data]# docker run -d -it --name=nginx-test2 -p 8081:80 --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
22213c80130138707c551addc8e2d5234e5baa9074ed50e8790944bb248f8519
通过浏览器也能访问到相同的网页内容,这里表现出来容器的极强的扩展性能。实现了数据共享。
# 清理数据卷,注意一定是先停止容器,再删除容器,然后才是删除数据卷。
[root@docker-vm1 _data]# docker container stop nginx-test
nginx-test
[root@docker-vm1 _data]# docker container rm nginx-test
nginx-test
[root@docker-vm1 _data]# docker volume rm nginx-vol
nginx-vol
(2)Bind Mounts
# 注意绑定的源目录必须存在,type=bind表明数据卷以绑定形式存在。
[root@docker-vm1 ~]# docker container run -d -it --name=nginx-test --mount type=bind,src=/app/wwwroot/,target=/usr/share/nginx/html nginx
db2445fef081a943a79986597732a5156f076ad9c379e788a8d931403a6f0ea2
# 进入容器的/usr/share/nginx/html发现为空。
[root@docker-vm1 ~]# docker container exec -it nginx-test bash
root@db2445fef081:/# ls /usr/share/nginx/html/
# 在宿主机的/app/wwwwroot下新建index.html发现在容器中也有index.html
[root@docker-vm1 wwwroot]# touch index.html
[root@docker-vm1 wwwroot]# vi index.html
root@db2445fef081:/usr/share/nginx/html# ls
index.html
注意:
- 如果源文件/目录没有存在,不会自动创建,会抛出一个错误
2)如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。
搭建LNMP(Linux,Nginx, Mysql, PHP)网站平台
(1)创建自定义网络
[root@docker-vm1 ~]# docker network create lnmp
ddc249411e6bff388d77c1c9c5cbb45b8e05db25cb3275321df490a46f676a8b
[root@docker-vm1 ~] docker pull mariadb
(2)创建mysql数据库容器
[root@docker-vm1 ~]# docker run -it --name lnmp_mysql --net lnmp -p 3306:3306 -v /var/lib/docker/volumes \
> -e MYSQL_ROOT_PASSWORD=123456 \
> mariadb
Initializing database
98952038a15a16a837b577f66fa87463745479e22389778a27d34a76594c9664
# 验证mysql容器是否生效,查看数据卷有内容
[root@docker-vm1 wwwroot]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d0432b7e6b7 mariadb "docker-entrypoint.s…" 29 minutes ago Up 29 minutes 0.0.0.0:3306->3306/tcp lnmp_mysql
[root@docker-vm1 ~]# docker top lnmp_mysql
UID PID PPID C STIME TTY TIME CMD
polkitd 14393 14375 3 10:32 pts/0 00:00:01 mysqld --character-set-server=utf8
[root@docker-vm1 ~]# docker logs lnmp_mysql
Initializing database
.....此处省略
(3)创建所需的数据库
[root@docker-vm1 ~]# docker exec lnmp_mysql sh \
> -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e"create database wp"'
mysql: [Warning] Using a password on the command line interface can be insecure.
# 安装mysql客户端,以便于浏览器访问,由于CentOS 7一般用MariaDB来支持mysql.
[root@docker-vm1 ~]# yum install mariadb.service
[root@docker-vm1 ~]# systemct restart mariadb.service
[root@docker-vm1 ~]# systemctl enable mariadb.service
(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
# 最后记得在防火墙中放行3306的端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent
#重启防火墙后看看是否生效
firewall-cmd --reload #重启firewall
firewall-cmd --list-ports #查看已经开放的端口
(6)以浏览器访问,此处注意指定自己服务器IP
http://172.16.4.12:88/wordpress/