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 kernel
- 可以运行在很多主流操作系统上
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.com https://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/config selinux=disabled #设置为disabled reboot #重启服务器 # 查看selinux状态 [root@localhost ~]# getenforce disabled
2.4.2.3安装所需的包
yum install -y yum-utils device-mapper-persistent-data lvm2
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 info containers: 1 running: 0 paused: 0 stopped: 1 images: 1 server version: 18.09.0 storage driver: overlay2 backing filesystem: xfs supports d_type: true native overlay diff: true logging driver: json-file cgroup driver: cgroupfs plugins: volume: local network: bridge host macvlan null overlay log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog swarm: inactive runtimes: runc default runtime: runc init binary: docker-init containerd version: c4446665cb9c30056f4998ed953e6d4ff22c7c39 runc version: 4fc53a81fb7c994640722ac585fa9ca548971871 init version: fec3683 security options: seccomp profile: default kernel version: 3.10.0-862.el7.x86_64 operating system: centos linux 7 (core) ostype: linux architecture: x86_64 cpus: 1 total memory: 1.779gib name: localhost.localdomain id: jdcf:rjad:hizf:zagm:ezns:46yy:i2am:okbh:prcs:aqbb:4dgt:x3rz docker root dir: /var/lib/docker debug mode (client): false debug mode (server): false registry: https://index.docker.io/v1/ labels: experimental: false insecure registries: 127.0.0.0/8 live restore enabled: false product license: community engine [root@localhost ~]# docker version client: 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: false server: 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 ps container id image command created status ports names 336509fd6799 nginx "nginx -g 'daemon of…" 8 minutes ago up 8 minutes 80/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": "", "usernsmode": "", "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, "kernelmemory": 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.2 http/1.1 200 ok server: nginx/1.15.6 date: thu, 08 nov 2018 12:43:20 gmt content-type: text/html content-length: 612 last-modified: tue, 06 nov 2018 13:32:09 gmt connection: keep-alive etag: "5be197d9-264" accept-ranges: bytes
2.4.2.11进入容器中
[root@localhost ~]# docker exec -it 336509fd6799 bash root@336509fd6799:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@336509fd6799:/# exit exit
三、镜像管理
3.1 镜像是什么
- 一个分层存储的文件
- 一个软件的环境
- 一个镜像可以创建n个容器
- 一种标准化的交付
- 一个不包含linux内核而又精简的linux操作系统
镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history
docker hub是由docker公司负责维护的公共注册中心,包含大量的容器镜像,docker工具默认从这个公共镜像库下载镜像。地址:https://hub.docker.com/explore 如图,容器其实是在镜像的最上面加了一层读写层,在运行容器里文件改动时,会先从镜像里面要写的文件复制到容器自己的文件系统中(读写层)。 如果容器删除了,最上面的读写层也就被删除了,改动也就丢失了。所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作的,并不会修改镜像的源文件,这种方式提高磁盘利用率。 若想持久化这些改动,可以通过docker commit将容器保存成一新的镜像。 docker image --help docker container run --help 允许容器最多使用一个半的cpu: 允许容器最多使用50%的cpu: docker container --help docker提供三种方式数据从宿主机挂载到容器中: 注意: https://docs.docker.com/engine/admin/volumes/volumes/#start-a-container-with-a-volume 注意: 1.2 如果源文件/目录没有存在,不会自动创建,会抛出一个错误。 1.3 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。 https://docs.docker.com/engine/admin/volumes/bind-mounts/#start-a-container-with-a-bind-mount linux ip信息包过滤原理: 容器访问外部 外部访问容器 habor是由vmware公司开源的容器镜像仓库。事实上,habor是在docker registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访问控制,ad/dalp集成以及审计日志等,足以满足基本企业需求。 官方地址:https://vmware.github.io/harbor/cn/ harbor安装有3种方式: 离线安装下载地址:https://github.com/goharbor/harbor/releases http://192.168.56.146/harbor/sign-in 在harbor web管理——“系统管理”——“用户管理”——新建用户,在——“项目”——“library仓库” ——“成员”把之前添加的用户进来并赋予权限 官网:https://portainer.io https://portainer.io/install.html portainer是一个开源、轻量级docker管理用户界面,基于docker api,可管理docker主机或swarm集群,支持最新版docker和swarm模块。 http://192.168.56.146:9000[root@localhost ~]# docker history nginx <<== 查看镜像有哪些分层
image created created by size comment
62f816a209e6 37 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/tcp 0b
<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]# ls
builder buildkit containerd containers image network overlay2 plugins runtimes swarm tmp trust volumes
[root@localhost docker]# cd overlay2/
[root@localhost overlay2]# ls
240731a3ae18beffce7a5053fb4b45c4a93c52c14b2b18e25751bd5ef5bce0b5
31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d
31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d-init
613cf356b8ebdacffabca1e2f03c02102a19d13df25caef091c10858ec058731
802c4abe1551fbbba1e4445b149852e2b0a8eb969adc2a45955d60ea88cdd370
82d2821d41013463c69c23a8c1e58a96ab84ae9c6399a181d0b37f0459c8007b
b5044ef06828dd2656c0d59f03cd854917033fe8ebd2e26bc3332b359cfcc148
b5044ef06828dd2656c0d59f03cd854917033fe8ebd2e26bc3332b359cfcc148-init
backingfsblockdev
l
3.1.1 镜像从那里来?
3.1.2 配置镜像加速器
https://www.daocloud.io/mirror
curl -ssl https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
systemctl restart docker
3.2 镜像与容器联系
root@localhost ~]# docker run -itd nginx
5ba9e0be87ade5e68481bface386c8ef592bb80bbe7bf28cf1572e832c8ce355
[root@localhost ~]# docker ps
container id image command created status ports names
5ba9e0be87ad nginx "nginx -g 'daemon of…" 51 seconds ago up 50 seconds 80/tcp sharp_mayer
[root@localhost ~]# docker exec -it 5ba9e0be87ad bash
root@5ba9e0be87ad:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@5ba9e0be87ad:/# touch nginx.txt
root@5ba9e0be87ad:/# exit
exit
[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]# ls
diff 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 管理镜像常用命令
指令
描述
ls
列出镜像
build
构建镜像来自dockerfile
history
查看镜像历史
inspect
显示一个或多个镜像详细信息
pull
推送一个镜像到镜像仓库
rm
移除一个或多个镜像
prune
移除未使用的镜像。没有被标记或被任何容器引用的。
tag
创建一个引用源镜像标记目标镜像
export
导出容器文件系统到tar归档文件
import
导入容器文件系统tar归档创建镜像
save
保存一个或多个镜像到tar归档文件
load
加载镜像来自tar归档或标准输入
四、容器管理
4.1 创建容器常用选项
选项
描述
-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值时,禁用swap
docker run -d --name nginx01 --memory="500m" --memory-swap="600m" --oom-kill-disable nginx
4.2.2 cpu限额
docker run -d --name nginx04 --cpus="1.5" nginx
docker run -d --name nginx05 --cpus='.5' nginx
4.3 管理容器常用命令
选项
描述
ls
列出容器
inspect
查看一个或多个容器详细信息
commit
创建一个新镜像来自一个容器
cp
拷贝文件/文件夹到一个容器
logs
获取一个容器日志
port
列出或指定容器端口映射
top
显示一个容器运行的进程
stats
显示容器资源使用统计
stop/start
停止/启动一个或多个容器
rm
删除一个或多个容器
五、管理应用程序数据
5.1 将宿主机数据挂载到容器中的三种方式
5.2 volume
docker volume create nginx-vol
docker volume ls
docker 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-test
docker rm nginx-test
docker volume rm nginx-vol
1. 如果没有指定卷,自动创建。
2. 建议使用—mount,更通用。
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-test
docker rm nginx-test
volume特点
bind mounts特点
六、容器网络
6.1 docker四种网络模式
-net=bridge
默认网络,docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
-net=host
容器不会获得一个独立的network namespace,而是与宿主机共用一个,这就意味着容器不会有自己的网卡信息,而是使用宿主机的。容器除了网络,其他都是隔离的。
-net=none
获取独立的network namespave,但不为容器进行任何网络配置,需要我们手动配置。
-net=container:name/id
与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还黑隔离的。
与默认的bridge原理一样,但自定义网络具备内部dns发现,可以通过容器名或者主机名容器之间网络通信。
6.2 容器网络访问原理
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 -nl
chain postrouting (policy accept) target prot opt source masquerade all -- 172.17.0.0/16
destination
0.0.0.0/0
chain docker (2 references) target prot opt source dnat tcp -- 0.0.0.0/0
destination
0.0.0.0/0
tcp dpt:88 to:172.18.0.2:80
6.3 桥接宿主机网络与配置固定ip
# 网桥名称
br_name=br0
# 添加网桥
brctl addbr $br_name
# 给网桥设置ip
ip 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.service
execstart=/usr/bin/dockerd -b=br0
# systemctl restart docker
# vi /etc/sysconfig/network-scripts/ifcfg-eth0
device=eth0
type=ethernet
onboot=yes
bridge=br0
# vi /etc/sysconfig/network-scripts/ifcfg-br0
device=br0
type=bridge
onboot=yes
bootproto=static
ipaddr=192.168.3.10
netmask=255.255.255.0
gateway=192.168.3.1
dns1=114.114.114.114
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/netns
ln -s /proc/$c_pid/ns/net /var/run/netns/$c_pid
# 添加虚拟网卡veth+容器pid,类型是veth pair,名称是vp+容器pid
ip 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 namespace
ip link set vp$c_pid netns $c_pid
# 在容器进程里面设置网卡信息
ip netns exec $c_pid ip link set dev vp$c_pid name eth0
ip netns exec $c_pid ip link set eth0 up
ip netns exec $c_pid ip addr add $ip dev eth0
ip netns exec $c_pid ip route add default via 192.168.1.1
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:latest
maintainer huwl
run yum install gcc -y
copy run.sh /usr/bin
expose 80
cmd ['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基础镜像
from centos:7
run 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 install
env path $path:/usr/local/nginx/sbin
workdir /usr/local/nginx
expose 80
cmd ["./sbin/nginx","-g","daemon off;"]
docker build -t nginx:v1 -f dockerfile .
# successfully built 373a0bdefe50
# successfully tagged nginx:v1
[root@localhost /]# docker image ls
repository tag image id created size
nginx v1 373a0bdefe50 56 seconds ago 335mb
<none> <none> d582c01a839f 4 minutes ago 200mb
nginx latest 62f816a209e6 2 days ago 109mb
centos 7 75835a67d134 4 weeks ago 200mb
hello-world latest 4ab4c602aa5e 2 months ago 1.84kb
[root@localhost /]# docker run -d --name nginx100 -p 80:80 nginx:v1
a29daf4614116f7dba18461e871d1a45ec9b55f722a98bead791c12294b9f1d3
[root@localhost /]# docker ps -l
container id image command created status ports names
a29daf461411 nginx:v1 "./sbin/nginx -g 'da…" 6 seconds ago up 5 seconds 0.0.0.0:80->80/tcp nginx100
[root@localhost /]# curl -i http://192.168.56.146/
http/1.1 200 ok
server: nginx/1.15.5
date: fri, 09 nov 2018 12:34:03 gmt
content-type: text/html
content-length: 612
last-modified: fri, 09 nov 2018 12:29:20 gmt
connection: keep-alive
etag: "5be57da0-264"
accept-ranges: bytes
7.4.2 构建php基础镜像
from centos:7
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"]
docker build -t php:v1 -f dockerfile .
[root@localhost php]# docker run -d --name php01 php:v1
ed5276251a6bf5124efba4b314d29a2dbfd12ddc0e0c3371ea16184a07c12bbc
[root@localhost php]# docker ps -l
container id image command created status ports names
ed5276251a6b php:v1 "./sbin/php-fpm -c /…" 5 seconds ago up 4 seconds 9000/tcp php01
[root@localhost php]# docker exec -it php01 bash
[root@ed5276251a6b php]# ls
bin etc include lib php sbin var
[root@ed5276251a6b php]# sbin/php-fpm -v
php 5.6.31 (fpm-fcgi) (built: nov 10 2018 01:10:28)
copyright (c) 1997-2016 the php group
zend engine v2.6.0, copyright (c) 1998-2016 zend technologies
7.4.3 构建tomcat基础镜像并项目测试
from centos:7
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"]
docker build -t tomcat:v1 -f dockerfile .
[root@localhost tomcat]# docker run -d --name tomcat01 -p 8080:8080 tomcat:v1
b9ba85bc64748c90ebe8df19e41c36490881cbcf174dab00d127ae6bf1141814
[root@localhost tomcat]# curl -i http://192.168.56.146:8080
http/1.1 200 ok
server: apache-coyote/1.1
content-type: text/html;charset=utf-8
transfer-encoding: chunked
date: sat, 10 nov 2018 01:26:59 gmt
7.5.1 快速部署lnmp网站平台
docker network create lnmp
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
docker run -d --name lnmp_php --net lnmp --mount src=wwwroot,dst=/wwwwroot php:v1
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
https://cn.wordpress.org/wordpress-4.9.4-zh_cn.tar.gz
八、企业级镜像仓库harbor
8.1 harbor介绍
组件
功能
harbor-adminserver
配置管理中心
harbor-db
mysql数据库
harbor-jobservice
负责镜像复制
harbor-log
记录操作日志
harbor-ui
web管理页面和api
nginx
前端代理,负责前端页面和镜像上传或下载转发
reids
会话
registry
镜像存储
8.2 harbor部署
curl -l "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
tar xf harbor-offline-installer-v1.6.1.tgz
cd harbor
vim harbor.cfg
harbor_admin_password = harbor12345
./prepare
./install.sh
[root@localhost harbor]# docker-compose ps
name command state ports
-------------------------------------------------------------------------------------------------------------------------------------
harbor-adminserver /harbor/start.sh up (healthy)
harbor-db /entrypoint.sh postgres up (healthy) 5432/tcp
harbor-jobservice /harbor/start.sh up
harbor-log /bin/sh -c /usr/local/bin/ ... up (healthy) 127.0.0.1:1514->10514/tcp
harbor-ui /harbor/start.sh up (healthy)
nginx nginx -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/tcp
redis docker-entrypoint.sh redis ... up 6379/tcp
registry /entrypoint.sh /etc/regist ... up (healthy) 5000/tcp
8.3 harbor基础使用
[root@localhost harbor]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"insecure-registries": ["192.168.56.146"] #<<= 加入harbor的地址
}
systemctl restart docker
docker tag nginx:v1 192.168.56.146/library/nginx:v1
docker login harbor地址
docker push 192.168.56.146/library/nginx:v1
九、图形化界面管理
9.1 portainer
docker volume create portainer_data
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
十、构建容器监控系统
10.1 cadvisor+influxdb+grafna
docker network create monitor
docker run -d --name influxdb --net monitor -p 8083:8083 -p 8086:8086 tutum/influxdb
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
docker run -d --name grafana --net monitor -p 3000:3000 grafana/grafana