Docker简介
一、Docker介绍
1.1 什么是Docker
Docker是一个开源的应用容器引擎,使用Go语言开发,基于Linux内核的cgroup,namespace,Union FS等技术,对应用进程进行封装隔离,并且独立于宿主机与其他进程,这种运行时封装的状态称为容器。
Docker早期版本实现是基于LXC,并进一步对其封装,包括文件系统、网络互联、镜像管理等方面,极大简化了容器管理。从0.7版本以后开始去除LXC,转为自省研发的libcontainer,从1.11版本开始,进一步为使用runC和containerd。
Docker理念是将应用及依赖包打包到一个可移植的容器中,可发布到任意Linux发行版Docker引擎上。使用沙箱机制运行程序,程序之间相互隔离。
1.2 Docker体系结构
Containerd:是一个简单的守护进程,使用runC管理容器。向Docker Engine提供接口。
Shim:只负责管理一个容器。
runC:是一个轻量级的工具,只用来运行容器。
- Docker Client:客户端
- Docker Daemon:守护进程
- Docker Images:镜像
- Docker Container:容器
- Docker Registry:镜像仓库
1.3 Docker内部组件
- Namespaces
命名空间,Linux内核提供的一种对进程资源隔离的机制,例如进程、网络、挂载点等资源。
- CGroup
控制组,Linux内核提供的一种限制进程资源的机制;例如CPU、内存等资源。
- UnionFS
联合文件系统,支持将不同位置的目录挂载到同一虚拟文件系统,形成一种分层的模型。
1.4 什么是容器?
- 对软件和其依赖的标准化打包
- 应用之间相互隔离
- 共享同一个OS Keel
- 可以运行在很多主流操作系统上
1.5 容器和虚拟机的区别
以KVM为例与Docker对比
- 启动时间
Docker妙级启动,KVM分钟级启动。
- 轻量级
容器镜像带下通常以M为单位,虚拟机以G为单位。容器资源占用小,要比虚拟机部署更快捷。
- 性能
容器共享宿主机内核,系统级虚拟化,占用资源少,没有Hypervisor层开销,容器性能基本接近物理机;虚拟机需要Hypervisior层支持,虚拟化一些设备,具备完整的GuestOS,虚拟化开销大,因而降低性能,没有容器性能好。
- 安全性
由于共享宿主机内核,只是进程级隔离,因此隔离性和稳定性不如虚拟机,容器具有一定权限访问宿主机内核,存在一定安全隐患。
- 使用要求
KVM基于硬件的完全虚拟化、需要赢家CPU虚拟化技术支持;容器共享所主机内核,可运行在主流的Linux发行版,不用考虑CPU是否支持虚拟化技术。
1.6 虚拟化+容器
二、Docker安装
2.1 Docker官方网站
https://wwww.docker.com
2.2 Docker版本
- 社区版(Community Edition,CE)
- 企业版(Enterprise Edition,EE)
2.3支持平台
- Linux(CentOS,Debian,Fedora,Oracle Linux,RHEL,SUSE和Ubuntu)
- Mac
- Windows
2.4 Linux安装Docker
2.4.1 Docker文档
https://docs.docker.comhttps://docs.docker.com/install/linux/docker-ce/centos/#set-up-the-repository
2.4.2 安装Docker
2.4.2.1关闭防火墙
systemctl stop firewalld systemctl disable firewalld
2.4.2.2关闭selinux
vi /etc/selinux/configSELINUX=disabled #设置为disabledreboot #重启服务器# 查看selinux状态[root@localhost ~]# getenforceDisabled
2.4.2.3安装所需的包
yum install -y yum-utilsdevice-mapper-persistent-datalvm2
2.4.2.4配置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
2.4.2.5安装docker-ce
yum install docker-ce -y
2.4.2.6启动
systemctl start docker# 加入开机启动systemctl enable docker
2.4.2.7运行hello-world
docker run hello-world
2.4.2.8查看docker版本
[root@localhost ~]# docker infoContainers: 1 Running: 0 Paused: 0 Stopped: 1Images: 1Server Version: 18.09.0Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Native Overlay Diff: trueLogging Driver: json-fileCgroup Driver: cgroupfsPlugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf jouald json-file local logentries splunk syslogSwarm: inactiveRuntimes: runcDefault Runtime: runcInit Binary: docker-initcontainerd version: c4446665cb9c30056f4998ed953e6d4ff22c7c39runc version: 4fc53a81fb7c994640722ac585fa9ca548971871init version: fec3683Security Options: seccomp Profile: defaultKeel Version: 3.10.0-862.el7.x86_64Operating System: CentOS Linux 7 (Core)OSType: linuxArchitecture: x86_64CPUs: 1Total Memory: 1.779GiBName: localhost.localdomainID: JDCF:RJAD:HIZF:ZAGM:EZNS:46YY:I2AM:OKBH:PRCS:AQBB:4DGT:X3RZDocker Root Dir: /var/lib/dockerDebug Mode (client): falseDebug Mode (server): falseRegistry: https://index.docker.io/v1/Labels:Experimental: falseInsecure Registries: 127.0.0.0/8Live Restore Enabled: falseProduct License: Community Engine[root@localhost ~]# docker versionClient: Version:18.09.0 API version:1.39 Go version:go1.10.4 Git commit:4d60db4 Built: Wed Nov 7 00:48:22 2018 OS/Arch:linux/amd64 Experimental: falseServer: Docker Engine - Community Engine: Version: 18.09.0 API version: 1.39 (minimum version 1.12) Go version:go1.10.4 Git commit:4d60db4 Built:Wed Nov 7 00:19:08 2018 OS/Arch: linux/amd64 Experimental: false
2.4.2.9查看运行了哪些docker
[root@localhost ~]# docker run -it nginx<<== -it前台运行、再打开一个终端用于查看[root@localhost ~]# docker psCONTAINER IDIMAGECOMMAND CREATED STATUS PORTSNAMES336509fd6799nginx"nginx -g 'daemon of…"8 minutes agoUp 8 minutes80/tcp epic_ride
2.4.2.10查看容器信息
[root@localhost ~]# docker inspect 336509fd6799<<==容器的id,用docker ps查看得到 [{"Id": "336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d","Created": "2018-11-08T12:30:38.462038658Z","Path": "nginx","Args": ["-g","daemon off;"],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 1926,"ExitCode": 0,"Error": "","StartedAt": "2018-11-08T12:30:38.800291064Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:62f816a209e6b57dd5fe98c1994fe3ab19ba4e1fee2a5ec6d77f303be4ed90e9","ResolvConfPath": "/var/lib/docker/containers/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d/resolv.conf","HostnamePath": "/var/lib/docker/containers/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d/hostname","HostsPath": "/var/lib/docker/containers/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d/hosts","LogPath": "/var/lib/docker/containers/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d-json.log","Name": "/epic_ride","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "shareable","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsesMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DiskQuota": 0,"KeelMemory": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": 0,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/asound","/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d-init/diff:/var/lib/docker/overlay2/240731a3ae18beffce7a5053fb4b45c4a93c52c14b2b18e25751bd5ef5bce0b5/diff:/var/lib/docker/overlay2/613cf356b8ebdacffabca1e2f03c02102a19d13df25caef091c10858ec058731/diff:/var/lib/docker/overlay2/82d2821d41013463c69c23a8c1e58a96ab84ae9c6399a181d0b37f0459c8007b/diff","MergedDir": "/var/lib/docker/overlay2/31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d/merged","UpperDir": "/var/lib/docker/overlay2/31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d/diff","WorkDir": "/var/lib/docker/overlay2/31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "336509fd6799","Domainname": "","User": "","AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"ExposedPorts": {"80/tcp": {}},"Tty": true,"OpenStdin": true,"StdinOnce": true,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","NGINX_VERSION=1.15.6-1~stretch","NJS_VERSION=1.15.6.0.2.5-1~stretch"],"Cmd": ["nginx","-g","daemon off;"],"ArgsEscaped": true,"Image": "nginx","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"},"StopSignal": "SIGTERM"},"NetworkSettings": {"Bridge": "","SandboxID": "f98bbeec0b3b1822c8dd90123c99c7e8225470140148e1dc6075d0bf2685d74b","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {"80/tcp": null},"SandboxKey": "/var/run/docker/netns/f98bbeec0b3b","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "a6b4036fb031698c228b5b2567da7b07df949a960bffbe119645e88a9730cb27","Gateway": "172.17.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:11:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "8a60ffdd13c42e28bfa9f6431d0264c790781ff8b5238dfc1f3af34c3d36d9ca","EndpointID": "a6b4036fb031698c228b5b2567da7b07df949a960bffbe119645e88a9730cb27","Gateway": "172.17.0.1","IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:02","DriverOpts": null}}}}][root@localhost ~]# curl -I 172.17.0.2HTTP/1.1 200 OKServer: nginx/1.15.6Date: Thu, 08 Nov 2018 12:43:20 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Tue, 06 Nov 2018 13:32:09 GMTConnection: keep-aliveETag: "5be197d9-264"Accept-Ranges: bytes
2.4.2.11进入容器中
[root@localhost ~]# docker exec -it 336509fd6799 bashroot@336509fd6799:/# lsbin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr varroot@336509fd6799:/# exitexit
三、镜像管理
3.1 镜像是什么
- 一个分层存储的文件
- 一个软件的环境
- 一个镜像可以创建N个容器
- 一种标准化的交付
- 一个不包含Linux内核而又精简的Linux操作系统
镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history <ID/NAME>查看镜像中各层内容及大小,每层对应着Dockerfile中的一条指令。Docker镜像默认存储在/var/lib/docker/<storage-driver>中。
[root@localhost ~]# docker history nginx <<== 查看镜像有哪些分层IMAGECREATED CREATED BY SIZECOMMENT62f816a209e637 hours ago/bin/sh -c #(nop) CMD ["nginx" "-g" "daemon…0B<missing>37 hours ago/bin/sh -c #(nop) STOPSIGNAL [SIGTERM] 0B<missing>37 hours ago/bin/sh -c #(nop) EXPOSE 80/tcp0B<missing>37 hours ago/bin/sh -c ln -sf /dev/stdout /var/log/nginx…22B<missing>37 hours ago/bin/sh -c set -x && apt-get update && apt…53.8MB<missing>37 hours ago/bin/sh -c #(nop) ENV NJS_VERSION=1.15.6.0.…0B<missing>37 hours ago/bin/sh -c #(nop) ENV NGINX_VERSION=1.15.6-…0B<missing>3 weeks ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do…0B<missing>3 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B<missing>3 weeks ago /bin/sh -c #(nop) ADD file:f8f26d117bc4a9289…55.3MB[root@localhost ~]# cd /var/lib/docker/[root@localhost docker]# lsbuilder buildkit containerd containers image network overlay2 plugins runtimes swarm tmp trust volumes[root@localhost docker]# cd overlay2/[root@localhost overlay2]# ls240731a3ae18beffce7a5053fb4b45c4a93c52c14b2b18e25751bd5ef5bce0b531cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d-init613cf356b8ebdacffabca1e2f03c02102a19d13df25caef091c10858ec058731802c4abe1551fbbba1e4445b149852e2b0a8eb969adc2a45955d60ea88cdd37082d2821d41013463c69c23a8c1e58a96ab84ae9c6399a181d0b37f0459c8007bb5044ef06828dd2656c0d59f03cd854917033fe8ebd2e26bc3332b359cfcc148b5044ef06828dd2656c0d59f03cd854917033fe8ebd2e26bc3332b359cfcc148-initbackingFsBlockDevl
3.1.1 镜像从那里来?
Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。地址:https://hub.docker.com/explore
3.1.2 配置镜像加速器
https://www.daocloud.io/mirrorcurl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.iosystemctl restart docker
3.2 镜像与容器联系
如图,容器其实是在镜像的最上面加了一层读写层,在运行容器里文件改动时,会先从镜像里面要写的文件复制到容器自己的文件系统中(读写层)。
如果容器删除了,最上面的读写层也就被删除了,改动也就丢失了。所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作的,并不会修改镜像的源文件,这种方式提高磁盘利用率。
若想持久化这些改动,可以通过docker commit将容器保存成一新的镜像。
root@localhost ~]# docker run -itd nginx5ba9e0be87ade5e68481bface386c8ef592bb80bbe7bf28cf1572e832c8ce355[root@localhost ~]# docker psCONTAINER IDIMAGECOMMAND CREATED STATUS PORTSNAMES5ba9e0be87adnginx"nginx -g 'daemon of…"51 seconds ago Up 50 seconds80/tcp sharp_mayer[root@localhost ~]# docker exec -it 5ba9e0be87ad bashroot@5ba9e0be87ad:/# lsbin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr varroot@5ba9e0be87ad:/# touch nginx.txtroot@5ba9e0be87ad:/# exitexit[root@localhost ~]# docker inspect 5ba9e0be87ad....# 存储驱动GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a-init/diff:/var/lib/docker/overlay2/240731a3ae18beffce7a5053fb4b45c4a93c52c14b2b18e25751bd5ef5bce0b5/diff:/var/lib/docker/overlay2/613cf356b8ebdacffabca1e2f03c02102a19d13df25caef091c10858ec058731/diff:/var/lib/docker/overlay2/82d2821d41013463c69c23a8c1e58a96ab84ae9c6399a181d0b37f0459c8007b/diff","MergedDir": "/var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a/merged","UpperDir": "/var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a/diff","WorkDir": "/var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a/work"},"Name": "overlay2"},...[root@localhost ~]# cd /var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a[root@localhost 44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a]# lsdiff link lower merged work[root@localhost 44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a]# ls diff/ # 与惊喜差异nginx.txt root run var[root@localhost 44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a]# ls merged/ <<==Nginx工作的数据驱动存储bin boot dev etc home lib lib64 media mnt nginx.txt opt proc root run sbin srv sys tmp usr var[root@localhost 44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a]# ls work/work
3.3 管理镜像常用命令
docker image --help
指令 | 描述 |
---|---|
ls | 列出镜像 |
build | 构建镜像来自Dockerfile |
history | 查看镜像历史 |
inspect | 显示一个或多个镜像详细信息 |
pull | 推送一个镜像到镜像仓库 |
rm | 移除一个或多个镜像 |
prune | 移除未使用的镜像。没有被标记或被任何容器引用的。 |
tag | 创建一个引用源镜像标记目标镜像 |
export | 导出容器文件系统到tar归档文件 |
import | 导入容器文件系统tar归档创建镜像 |
save | 保存一个或多个镜像到tar归档文件 |
load | 加载镜像来自tar归档或标准输入 |
四、容器管理
4.1 创建容器常用选项
docker container run --help
选项 | 描述 |
---|---|
-i,-interactive | 交互式 |
-t,-tty | 分配一个伪终端 |
-d,-detach | 运行容器到后台 |
-e,-env | 设置环境变量 |
-p,-publish list | 发布容器端口到主机 |
-P,-publish-all | 发布容器所有EXPOSE端口到宿主机随机端口 |
-name string | 指定容器名称 |
-h,-hostname | 设置容器主机名 |
-ip string | 指定容器IP,只能用于自定义网络 |
-network | 连接容器到一个网络 |
-mount mount | 将文件系统附加到容器 |
-v,-volume list | 绑定挂载一个卷 |
-restart string | 容器退出时重启策略,默认no,可选值:[always|on-failure] |
4.2 容器资源限制
选项 | 描述 |
---|---|
-m,-memory | 容器可以使用的最大内存量 |
-memory-swap | 允许交换磁盘的内存量 |
-memory-swappiness=<0-100> | 容器使用SWAP分区交换的百分比(0-100,默认为-1) |
-oom-kill-disable | 禁用OOM Killer |
-cpus | 可以使用的CPU数量 |
-cpuset-cpus | 限制容器使用特定的CPU核心,(0-3,0,1) |
-cpu-shares | CPU共享(相对权重) |
示例:
4.2.1 内存限额
允许容器最多使用500M内存和100M的swap,并禁用OOM Killer:# 允许使用的swap=memory-swap - memory# memory-swap='-1'时,无限制使用swap# memory-swap 不设置时,默认swap的值时memory的2倍# memory-swap的值等于memory值时,禁用swapdocker run -d --name Nginx01 --memory="500m" --memory-swap="600M" --oom-kill-disable nginx
4.2.2 CPU限额
允许容器最多使用一个半的CPU:
docker run -d --name nginx04 --cpus="1.5" nginx
允许容器最多使用50%的CPU:
docker run -d --name nginx05 --cpus='.5' nginx
4.3 管理容器常用命令
docker container --help
选项 | 描述 |
---|---|
ls | 列出容器 |
inspect | 查看一个或多个容器详细信息 |
commit | 创建一个新镜像来自一个容器 |
cp | 拷贝文件/文件夹到一个容器 |
logs | 获取一个容器日志 |
port | 列出或指定容器端口映射 |
top | 显示一个容器运行的进程 |
stats | 显示容器资源使用统计 |
stop/start | 停止/启动一个或多个容器 |
rm | 删除一个或多个容器 |
五、管理应用程序数据
5.1 将宿主机数据挂载到容器中的三种方式
Docker提供三种方式数据从宿主机挂载到容器中:
- Volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
- bind mounts:将宿主机上的任意位置的文件或者目录挂载到容器中。
- tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久化存储到任何位置,可以使用tmpfs,同时避免写入容器可写层提高性能。
5.2 Volume
- 管理卷
docker volume create nginx-voldocker volume lsdocker volume inspect nginx-vol
- 用卷创建一个容器
# 新语法docker run -d --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx# 旧语法docker run -d --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx
- 清理
docker stop nginx-testdocker rm nginx-testdocker volume rm nginx-vol
注意:
1. 如果没有指定卷,自动创建。2. 建议使用—mount,更通用。
https://docs.docker.com/engine/admin/volumes/volumes/#start-a-container-with-a-volume
5.3 Bind Mounts
- 用卷创建一个容器
# 新语法docker run -d --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx# 旧语法docker run -d --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx
- 验证绑定
docker inspect nginx-test
- 清理
docker stop nginx-testdocker rm nginx-test
注意:
1.2 如果源文件/目录没有存在,不会自动创建,会抛出一个错误。
1.3 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。
https://docs.docker.com/engine/admin/volumes/bind-mounts/#start-a-container-with-a-bind-mount
Volume特点
- 多个运行容器之间共享数据。
- 当容器停止或悲移除时,该卷依然存在。
- 多个容器可以同时挂载相同的卷。
- 当明确删除卷时,卷才会被删除。
- 将容器的数据存储在远程主机或其他存储上
- 将数据从一台Docker主机迁移到另一台时,先停止容器,然后备份卷的目录(/var/lib/docker/volumes)
Bind Mounts特点
- 从主机共享配置文件到容器。默认情况下,挂载主机/etc/resolv.conf到每个容器,提供DNS解析。
- 在Docker主机上的开发环境和容器之间共享源代码。例如,可以将Maven target目录挂载到容器中,每次在Docker主机上构建Maven项目时,容器都可以访问构建的项目包。
- 当Docker主机的文件或目录结构保证与容器所需的绑定挂载一致时。
六、容器网络
6.1 Docker四种网络模式
- bridge
-net=bridge默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
- host
-net=host容器不会获得一个独立的network namespace,而是与宿主机共用一个,这就意味着容器不会有自己的网卡信息,而是使用宿主机的。容器除了网络,其他都是隔离的。
- none
-net=none获取独立的network namespave,但不为容器进行任何网络配置,需要我们手动配置。
- container
-net=container:Name/ID与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还黑隔离的。
- 自定义网络
与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名或者主机名容器之间网络通信。
6.2 容器网络访问原理
Linux IP信息包过滤原理:
Docker主要通过netfilter/iptables实现网络通信。iptables由netfilter和iptables组成,netfilter组件是Linux内核集成的信息包过滤系统,它维护一个信息包过滤表,这个表用于控制信息包过滤处理的规则集,而iptables只是一个在用户空间的工具,用于增删改查这个过滤表的规则。
表 | 链 |
---|---|
filter(过滤) | INPUT、OUTPUT、FORWARD |
nat(地址转换) | PREROUTING、POSTROUTING、OUTPUT |
mangle(拆包、修改、封装) | INPUT、OUTPUT、PREROUTING、 POSTROUTING、OUTPUT |
raw(数据包状态跟踪) | PREROUTING、OUTPUT |
容器访问外部
# iptables -t nat -nLChain POSTROUTING (policy ACCEPT) target prot opt source MASQUERADE all -- 172.17.0.0/16 destination0.0.0.0/0
外部访问容器
Chain DOCKER (2 references) target prot opt source DNAT tcp -- 0.0.0.0/0destination0.0.0.0/0tcp dpt:88 to:172.18.0.2:80
6.3 桥接宿主机网络与配置固定IP
- 临时生效
# 网桥名称br_name=br0# 添加网桥brctl addbr $br_name# 给网桥设置IPip addr add 192.168.1.120/24 dev $br_name# 删除已存在的eth0网卡配置ip addr del 192.168.1.120/24 dev eth0# 激活网卡ip link set $br_name up# 添加eth0到网桥brctl addif $br_name eth0# 添加路由ip route add default via 192.168.1.1 dev br0还需要在Docker启动时桥街这个网桥:# vi /usr/lib/systemd/system/docker.serviceExecStart=/usr/bin/dockerd -b=br0# systemctl restart docker
- 永久生效
# vi /etc/sysconfig/network-scripts/ifcfg-eth0DEVICE=eth0TYPE=EtheetONBOOT=yesBRIDGE=br0# vi /etc/sysconfig/network-scripts/ifcfg-br0DEVICE=br0TYPE=BridgeONBOOT=yesBOOTPROTO=staticIPADDR=192.168.3.10NETMASK=255.255.255.0GATEWAY=192.168.3.1DNS1=114.114.114.114
- 配置固定IP
C_ID=$(docker run -itd --net=none ubuntu)C_PID=$(docker inspect -f '{{.State.Pid}}' $C_ID)# 创建network namespace目录并将容器的network namespace软连接到此目录,以便ip netns命令读取 mkdir -p /var/run/netnsln -s /proc/$C_PID/ns/net /var/run/netns/$C_PID# 添加虚拟网卡veth+容器PID,类型是veth pair,名称是vp+容器PIDip link add veth$C_PID type veth peer name vp$C_PID# 添加虚拟网卡到br0网桥brctl addif br0 veth$C_PID# 激活虚拟网卡ip link set veth$C_PID up# 设置容器网络信息IP='192.168.0.123/24'GW='192.168.0.1'# 给进程配置一个network namespaceip link set vp$C_PID netns $C_PID# 在容器进程里面设置网卡信息ip netns exec $C_PID ip link set dev vp$C_PID name eth0ip netns exec $C_PID ip link set eth0 upip netns exec $C_PID ip addr add $IP dev eth0ip netns exec $C_PID ip route add default via 192.168.1.1
- pipework工具配置容器固定IP
git clone https://github.com/jpetazzo/pipework.git cp pipework/pipework /usr/local/bin/docker run -itd --net=none --name test01 ubuntu pipework br0 test01 192.168.0.123/24@192.168.0.1
七、Dockerfile
7.1 Dockerfile格式
FROM centos:latestMAINTAINER huwlRUN yum install gcc -yCOPY run.sh /usr/binEXPOSE 80CMD ['run.sh]
7.2 Dockerfile常用指令
指令 | 描述 |
---|---|
FROM | 构建新镜像是基于那个镜像 |
MAINTAINER | 镜像维护者姓名或邮箱地址 |
RUN | 构建镜像时运行的Shell命令 |
COPY | 拷贝文件或目录到镜像中 |
ENV | 设置环境变量 |
USER | 为RUN、CMD和ENTRPOTIN执行命令指定运行用户 |
EXPOSE | 声明容器运行的服务端口 |
HEALTHCHECK | 容器中服务健康检查 |
WORKDIR | 为RUN、CMD、ENTRYPOTIN、COPY和ADD设置工作目录 |
ENTRYPOIN | 运行容器时执行,如果有多个ENTRYPOIN指令,最后一个生效 |
CMD | 运行容器时执行,如果有多个CMD指令,最后一个生效 |
7.3 Build构建镜像
Usage:docker build [OPTIONS] PATH | URL | - [flags]Options:-t, --tag list # 镜像名称-f,--file string #指定Dockerfile文件位置# docker build .# docker bulid -t shykes/myapp .# docker bulid -t shykes/myapp -f /path/Dockerfile /path# docker bulid -t shykes/myapp http://www.example.com/Dockerfile
7.4 企业应用案例
7.4.1 构建Nginx基础镜像
- Dockerfile
FROM centos:7RUN yum install -y gcc gcc-c++ make openssl-devel pcre-devel dg-devel iproute net-tools telnet wget curl && yum clean all && rm -rf /var/cache/yum/*RUN wget http://nginx.org/download/nginx-1.15.5.tar.gz && tar zxf nginx-1.15.5.tar.gz && cd nginx-1.15.5 && ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module && make && make installENV PATH $PATH:/usr/local/nginx/sbinWORKDIR /usr/local/nginxEXPOSE 80CMD ["./sbin/nginx","-g","daemon off;"]
- 构建镜像
docker build -t nginx:v1 -f Dockerfile .# Successfully built 373a0bdefe50# Successfully tagged nginx:v1[root@localhost /]# docker image lsREPOSITORY TAG IMAGE IDCREATED SIZEnginxv1 373a0bdefe5056 seconds ago 335MB<none> <none> d582c01a839f4 minutes ago200MBnginxlatest 62f816a209e62 days ago 109MBcentos 775835a67d1344 weeks ago 200MBhello-world latest 4ab4c602aa5e2 months ago1.84kB
- 启动测试
[root@localhost /]# docker run -d --name nginx100 -p 80:80 nginx:v1a29daf4614116f7dba18461e871d1a45ec9b55f722a98bead791c12294b9f1d3[root@localhost /]# docker ps -lCONTAINER IDIMAGECOMMAND CREATED STATUS PORTSNAMESa29daf461411nginx:v1"./sbin/nginx -g 'da…"6 seconds agoUp 5 seconds0.0.0.0:80->80/tcpnginx100[root@localhost /]# curl -I http://192.168.56.146/HTTP/1.1 200 OKServer: nginx/1.15.5Date: Fri, 09 Nov 2018 12:34:03 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Fri, 09 Nov 2018 12:29:20 GMTConnection: keep-aliveETag: "5be57da0-264"Accept-Ranges: bytes
7.4.2 构建PHP基础镜像
- dockerfile
FROM centos:7RUN yum install -y gcc gcc-c++ make gd-devel libxml2-devel libcurl-devel libjpeg-devel libpng-devel openssl-develADD 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.confCOPY php.ini /usr/local/php/etcRUN rm -rf /tmp/php-5.6.31* && yum clean allWORKDIR /usr/local/phpEXPOSE 9000CMD ["./sbin/php-fpm", "-c", "/usr/local/php/etc/php-fpm.conf"]
- 构建php镜像
docker build -t php:v1 -f dockerfile .
- 启动测试
[root@localhost php]# docker run -d --name php01 php:v1ed5276251a6bf5124efba4b314d29a2dbfd12ddc0e0c3371ea16184a07c12bbc[root@localhost php]# docker ps -lCONTAINER IDIMAGECOMMAND CREATED STATUS PORTSNAMESed5276251a6bphp:v1 "./sbin/php-fpm -c /…"5 seconds agoUp 4 seconds9000/tcpphp01[root@localhost php]# docker exec -it php01 bash[root@ed5276251a6b php]# lsbin etc include lib php sbin var[root@ed5276251a6b php]# sbin/php-fpm -vPHP 5.6.31 (fpm-fcgi) (built: Nov 10 2018 01:10:28)Copyright (c) 1997-2016 The PHP GroupZend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
7.4.3 构建Tomcat基础镜像并项目测试
- dockerfile
FROM centos:7ADD jdk-8u45-linux-x64.tar.gz /usr/localENV JAVA_HOME /usr/local/jdk1.8.0_45ADD apache-tomcat-8.0.46.tar.gz /usr/localCOPY server.xml /usr/local/apache-tomcat-8.0.46/confRUN rm -f /usr/local/*.tar.gzWORKDIR /usr/local/apache-tomcat-8.0.46EXPOSE 8080ENTRYPOINT ["./bin/catalina.sh", "run"]
- 构建Tomcat镜像
docker build -t tomcat:v1 -f Dockerfile .
- 启动测试
[root@localhost tomcat]# docker run -d --name tomcat01 -p 8080:8080 tomcat:v1b9ba85bc64748c90ebe8df19e41c36490881cbcf174dab00d127ae6bf1141814[root@localhost tomcat]# curl -I http://192.168.56.146:8080HTTP/1.1 200 OKServer: Apache-Coyote/1.1Content-Type: text/html;charset=UTF-8Transfer-Encoding: chunkedDate: Sat, 10 Nov 2018 01:26:59 GMT
7.5.1 快速部署LNMP网站平台
- 创建自定义网络
docker network create lnmp
- 创建MySQL容器
docker run -d --name lnmp_mysql --net lnmp --mount src=mysql-vol,dst=/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=wordpress mysql:5.7 --character-set-server=utf8
- 创建PHP容器
docker run -d --name lnmp_php --net lnmp --mount src=wwwroot,dst=/wwwwroot php:v1
- 创建Nginx容器
docker run -d --name lnmp_nginx --net lnmp -p 80:80 --mount type=bind,src=$(pwd)/nginx.conf,dst=/usr/local/nginx/conf/nginx.conf --mount src=wwwroot,dst=/wwwroot nginx:v1
- 以wordpress博客为例
https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz
八、企业级镜像仓库Harbor
8.1 Harbor介绍
Habor是由VMWare公司开源的容器镜像仓库。事实上,Habor是在Docker Registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访问控制,AD/DALP集成以及审计日志等,足以满足基本企业需求。
官方地址:https://vmware.github.io/harbor/cn/
组件 | 功能 |
---|---|
harbor-adminserver | 配置管理中心 |
harbor-db | MySQL数据库 |
harbor-jobservice | 负责镜像复制 |
harbor-log | 记录操作日志 |
harbor-ui | web管理页面和API |
Nginx | 前端代理,负责前端页面和镜像上传或下载转发 |
reids | 会话 |
registry | 镜像存储 |
8.2 Harbor部署
Harbor安装有3种方式:
- 在线安装:从Docker Hub下载Harbor相关镜像,因此安装软件包非常小
- 离线安装:安装包包含部署的相关镜像,因此安装包比较大
- OVA安装程序:当用户具有vCenter环境时,使用此安装程序,在部署OVA后启动Harbor
离线安装下载地址:https://github.com/goharbor/harbor/releases
- 部署
curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-composetar xf harbor-offline-installer-v1.6.1.tgzcd harborvim harbor.cfgharbor_admin_password = Harbor12345./prepare./install.sh[root@localhost harbor]# docker-compose psName Command StatePorts-------------------------------------------------------------------------------------------------------------------------------------harbor-adminserver/harbor/start.sh Up (healthy)harbor-db/entrypoint.sh postgres Up (healthy)5432/tcpharbor-jobservice/harbor/start.sh Upharbor-log/bin/sh -c /usr/local/bin/ ...Up (healthy)127.0.0.1:1514->10514/tcpharbor-ui/harbor/start.sh Up (healthy)nginxnginx -g daemon off; Up (healthy)0.0.0.0:443->443/tcp, 0.0.0.0:4443->4443/tcp, 0.0.0.0:80->80/tcpredisdocker-entrypoint.sh redis ...Up 6379/tcpregistry /entrypoint.sh /etc/regist ...Up (healthy)5000/tcp
- 访问
http://192.168.56.146/harbor/sign-in
8.3 Harbor基础使用
- 默认上传镜像连接使用https,添加http受信任
[root@localhost harbor]# cat /etc/docker/daemon.json{"registry-mirrors": ["http://f1361db2.m.daocloud.io"],"insecure-registries": ["192.168.56.146"] #<<= 加入harbor的地址}
- 重启docker
systemctl restart docker
在Harbor web管理——“系统管理”——“用户管理”——新建用户,在——“项目”——“library仓库” ——“成员”把之前添加的用户进来并赋予权限
- 登录仓库上传镜像
docker tag nginx:v1 192.168.56.146/library/nginx:v1docker login harbor地址docker push 192.168.56.146/library/nginx:v1
九、图形化界面管理
9.1 Portainer
https://portainer.io/install.html
Portainer是一个开源、轻量级Docker管理用户界面,基于Docker API,可管理Docker主机或Swarm集群,支持最新版Docker和Swarm模块。
- 创建卷
docker volume create portainer_data
- 创建Portainer容器
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
- 访问portainer
十、构建容器监控系统
10.1 cAdvisor+InfluxDB+Grafna
- 创建monitor
docker network create monitor
- Influxdb
docker run -d --name influxdb --net monitor -p 8083:8083 -p 8086:8086 tutum/influxdb
- cAdvisor
docker run -d --name=cadvisor --net monitor -p 8081:8080 --mount type=bind,src=/,dst=/rootfs,ro --mount type=bind,src=/var/run,dst=/var/run --mount type=bind,src=/sys,dst=/sys,ro --mount type=bind,src=/var/lib/docker/,dst=/var/lib/docker,ro google/cadvisor -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxdb:8086
- Grafana
docker run -d --name grafana --net monitor -p 3000:3000 grafana/grafana
作者:0x00000
来源链接:https://www.cnblogs.com/0x00000/p/9158982.html
版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。
2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。