Docker - 图1

Docker概述

Docker 教程Docker官网Docker HubDocker 文档

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker的应用场景

  • Web 应用的自动化打包和发布。
  • 自动化测试和持续集成、发布。
  • 在服务型环境中部署和调整数据库或其他的后台应用。
  • 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。

与虚拟机对比

虚拟机技术

Docker - 图2

虚拟机技术缺点

1、资源占用十分多

2、冗余步骤多

3、启动很慢

容器化技术

容器化技术不是模拟的一个完整的操作系统

Docker - 图3

比较 Docker和虚拟机技术的不同

  • 传统虚拟机,虚拟出硬件,运行完整的操作系统,然后在这个系统上安装和运行软件
  • 容器内的应用直接运行在宿主机的内核,容器是没有自己的内核的,也没有虚拟硬件,相对就轻便。
  • 每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响。

DevOps(开发运维)

应用更快速的交付和部署

传统:一堆帮助文档,安装程序。

Docker:打包镜像发步测试,一键运行。

更便捷的升级和扩缩容

使用了 Docker之后,部署应用就和搭积木一样

项目打包为—个镜像,水平扩展服务器A出现问题,负载均衡可以服务器B上直接运行。

更简单的系统运维

在容器化之后,开发、测试环境都是高度一致的。

更高效的计算资源利用

Docker是内核级别的虚拟化,可以再一个物理机上可以运行很多的容器实例,服务器的性能可以被压榨到极致。

Docker 安装

Docker基本组成

Docker - 图4

镜像(image):

docker镜像就好比是—个模板,可以通过这个模板来创建容器服务,tomcat镜像 ==> run ==> tomcat01容器(提供服务),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。

容器(container):

Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建。
启动,停止,删除,基本命令。
目前就可以把这个容器理解为就是一个简易的Linux系统。

仓库(repository):

仓库就是存放镜像的地方。

仓库分为公有仓库和私有仓库。

Docker Hub(默认是国外的)。

阿里云…都有容器服务器(配置镜像加速)。

安装Docker

环境准备

1、需要会一些的 Linux的基础
2、Centos7
3、连接远程服务器进行操作

环境查看

  1. # 系统内核是 3.10以上
  2. [root@6b92d6 /]# uname -r
  3. 3.10.0-1062.18.1.el7.x86_64
  1. # 系统版本
  2. [root@6b92d6 /]# cat /etc/os-release
  3. NAME="CentOS Linux"
  4. VERSION="7 (Core)"
  5. ID="centos"
  6. ID_LIKE="rhel fedora"
  7. VERSION_ID="7"
  8. PRETTY_NAME="CentOS Linux 7 (Core)"
  9. ANSI_COLOR="0;31"
  10. CPE_NAME="cpe:/o:centos:centos:7"
  11. HOME_URL="https://www.centos.org/"
  12. BUG_REPORT_URL="https://bugs.centos.org/"
  13. CENTOS_MANTISBT_PROJECT="CentOS-7"
  14. CENTOS_MANTISBT_PROJECT_VERSION="7"
  15. REDHAT_SUPPORT_PRODUCT="centos"
  16. REDHAT_SUPPORT_PRODUCT_VERSION="7"

安装

Install Docker Engine on CentOS

  1. # 1、卸载旧版本
  2. sudo yum remove docker \
  3. docker-client \
  4. docker-client-latest \
  5. docker-common \
  6. docker-latest \
  7. docker-latest-logrotate \
  8. docker-logrotate \
  9. docker-engine
  10. # 2、需要安装包
  11. sudo yum install -y yum-utils
  12. # 3、设置镜像仓库
  13. sudo yum-config-manager \
  14. --add-repo \
  15. https://download.docker.com/linux/centos/docker-ce.repo # 默认是国外。
  16. sudo yum-config-manager \
  17. --add-repo \
  18. http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 阿里云镜像
  19. # 更新软件包索引
  20. yum makecache fast
  21. # 4、安装Docker相关 docker-ce 社区版 ee企业版
  22. sudo yum install docker-ce docker-ce-cli containerd.io
  23. # 5、启动Docker
  24. sudo systemctl start docker
  25. # 6、查看Docker是否启动成功
  26. docker version

Docker - 图5

  1. # 7、测试docker
  2. sudo docker run hello-world

Docker - 图6

  1. # 8、查看下载的hello-world镜像
  2. docker images

Docker - 图7

卸载Docker

  1. # 1、卸载依赖
  2. sudo yum remove docker-ce docker-ce-cli containerd.io
  3. # 2、删除资源
  4. sudo rm -rf /var/lib/docker
  5. sudo rm -rf /var/lib/containerd
  6. # /var/lib/docker docker的默认工作路径

镜像加速

阿里云镜像加速

1、登录阿里云找到容器镜像服务

Docker - 图8

2、找到镜像加速地址

Docker - 图9

  1. sudo mkdir -p /etc/docker
  2. sudo tee /etc/docker/daemon.json <<-'EOF'
  3. {
  4. "registry-mirrors": ["https://059c062d470010170fa0c00f935d6d60.mirror.swr.myhuaweicloud.com"]
  5. }
  6. EOF
  7. sudo systemctl daemon-reload
  8. sudo systemctl restart docker

输入docker info查看加速的镜像配置信息

  1. [root@6b92d6 ~]# docker info

Docker - 图10

华为云镜像加速

Docker - 图11

Docker - 图12

Docker - 图13

配置流程同阿里云

回顾分析HelloWorld流程

Docker - 图14

流程图

Docker - 图15

底层原理

Docker 是如何工作的?

Docker 是一个 Client - Server 结构的系统,Docker的守护进程运行在主机上。通过 Socket从客户端访问。
DockerServer接收到 Docker- Client的指令,就会执行这个命令

Docker - 图16

Docker:使用socket 代理

逻辑结构

Docker - 图17

所有操作在需要拉取镜像的服务器上执行

Docker 为什么比 VM 快?

1、Docker有着比虚拟机更少的抽象层,由于Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在Cpu、内存利用率上Docker将会在效率上有明显优势。

2、Docker利用的是宿主机的内核,而不需要Guest OS,因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统,避免了引导、加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的,而Docker由于直接利用宿主机的操作系统则省略了这个过程,因此新建一个Docker容器只需要几秒钟。

Docker容器 虚拟机(VM)
操作系统 与宿主机共享OS 宿主机OS上运行宿主机OS
存储大小 镜像小,便于存储与传输 镜像庞大(vmdk等)
运行性能 几乎无额外性能损失 操作系统额外的cpu、内存消耗
移植性 轻便、灵活、适用于Linux 笨重、与虚拟化技术耦合度高
硬件亲和性 面向软件开发者 面向硬件运维者

Docker - 图18

Docker常用命令

帮助命令

  1. docker version # 显示docker的版本信息
  2. docker info # 显示docker的系统信息,包括镜像和容器数量
  3. docker 命令 --help # 帮助命令

docker官方帮助文档

Docker 帮助文档地址

镜像命令

docker images 查看所有本地的本机上的镜像

  1. [root@6b92d6 ~]# docker images
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. hello-world latest d1165f221234 2 months ago 13.3kB
  4. # 解释
  5. REPOSITORY 镜像的仓库源
  6. TAG 镜像的标签
  7. IMAGE ID 镜像的id
  8. CREATED 镜像的创建时间
  9. SIZE 镜像的大小
  10. # 可选项
  11. -a, --all # 列出所有的镜像
  12. -q, --quiet # 只显示镜像的id

docker search 搜索镜像

  1. [root@6b92d6 ~]# docker search mysql
  2. NAME DESCRIPTION STARS OFFICIAL AUTOMATED
  3. mysql MySQL is a widely used, open-source relation 10852 [OK]
  4. mariadb MariaDB Server is a high performing open sou 4092 [OK]
  5. # 可选项,通过收藏来过滤
  6. --filter=STARS=5000 # 搜索出来的镜像就是STARS大于5000的
  7. [root@6b92d6 ~]# docker search mysql --filter=STARS=5000
  8. NAME DESCRIPTION STARS OFFICIAL AUTOMATED
  9. mysql MySQL is a widely used, open-source relation 10852 [OK]
  10. [root@6b92d6 ~]# docker search mysql -f=STARS=5000
  11. NAME DESCRIPTION STARS OFFICIAL AUTOMATED
  12. mysql MySQL is a widely used, open-source relation 10852 [OK]

docker pull 下载镜像

  1. # 下载镜像 docker pull 镜像名[:tag]
  2. [root@6b92d6 ~]# docker pull mysql
  3. Using default tag: latest # 如果不写 tag,默认就是 later
  4. latest: Pulling from library/mysql
  5. f7ec5a41d630: Pull complete # 分层下载,docker image的核心 联合文件系统
  6. 9444bb562699: Pull complete
  7. 6a4207b96940: Pull complete
  8. 181cefd361ce: Pull complete
  9. 8a2090759d8a: Pull complete
  10. 15f235e0d7ee: Pull complete
  11. d870539cd9db: Pull complete
  12. d44467b42d4c: Pull complete
  13. ae6d21974457: Pull complete
  14. be4ff89fec0f: Pull complete
  15. 2c9b0d7f6e0f: Pull complete
  16. c6fb9ccf35d9: Pull complete
  17. Digest: sha256:cd42db5e061f8d1b1854e5fe597ad7ab9b9a5198ca1a2a560e5c4135b2d2b005 # 签名
  18. Status: Downloaded newer image for mysql:latest
  19. docker.io/library/mysql:latest # 真实地址
  20. # 下面两个命令等价,默认下载最新版本
  21. docker pull mysql
  22. docker pull docker.io/library/mysql:latest
  23. # 指定版本下载
  24. [root@6b92d6 ~]# docker pull mysql:5.7
  25. 5.7: Pulling from library/mysql
  26. f7ec5a41d630: Already exists
  27. 9444bb562699: Already exists
  28. 6a4207b96940: Already exists
  29. 181cefd361ce: Already exists
  30. 8a2090759d8a: Already exists
  31. 15f235e0d7ee: Already exists
  32. d870539cd9db: Already exists
  33. cb7af63cbefa: Pull complete
  34. 151f1721bdbf: Pull complete
  35. fcd19c3dd488: Pull complete
  36. 415af2aa5ddc: Pull complete
  37. Digest: sha256:a655529fdfcbaf0ef28984d68a3e21778e061c886ff458b677391924f62fb457
  38. Status: Downloaded newer image for mysql:5.7
  39. docker.io/library/mysql:5.7

Docker - 图19

docker rmi 删除镜像

  1. [root@6b92d6 ~]# docker rmi -f 镜像id # 删除指定镜像
  2. [root@6b92d6 ~]# docker rmi -f 镜像id 镜像id 镜像id # 删除多个镜像
  3. [root@6b92d6 ~]# docker rmi -f $(docker images -aq) # 删除全部镜像

容器命令

说明:有了镜像才可以创建容器,Linux,下载一个 centos 镜像来测试学习

  1. docker pull centos

新建容器并启动

  1. docker run [可选参数] image
  2. # 参数说明
  3. --name="Name" 容器姓名 tomcat01 tomcat02,用来区分容器
  4. -d 后台方式运行
  5. -it 使用交互方式运行,进入容器查看内容
  6. -p 指定容器的端口 (小写p -p 8080:8080
  7. -p ip:主机端口:容器端口
  8. -p 主机端口:容器端口 【常用】
  9. -p 容器端口
  10. 容器端口
  11. -P 随机指定端口 (大写P
  12. # 测试,启动并进入容器
  13. [root@6b92d6 ~]# docker run -it centos /bin/bash
  14. [root@ecec2292617b /]# ls # 查看容器内的centos,基本版本,命令不完善
  15. bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
  16. # 从容器中退回主机
  17. [root@ecec2292617b /]# exit
  18. exit
  19. [root@6b92d6 /]# ls
  20. bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var

列出所有运行的容器

  1. # docker ps 命令
  2. # 列出当前正在运行的容器
  3. -a # 列出当前正在运行的容器 + 历史运行过的容器
  4. -n=? # 显示最近创建的?个容器
  5. -q # 只显示容器的编号
  6. [root@6b92d6 /]# docker ps
  7. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  8. [root@6b92d6 /]# docker ps -a
  9. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  10. ecec2292617b centos "/bin/bash" 12 minutes ago Exited (0) 8 minutes ago elated_jang
  11. 6e628da270ee d1165f221234 "/hello" 36 hours ago Exited (0) 36 hours ago vigilant_lamarr

退出容器

  1. exit # 容器直接停止并退出
  2. Ctrl + P + Q # 容器不停止退出

删除容器

  1. docker rm 容器id # 删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm-f
  2. docker rm -f $(docker ps -aq) # 删除所有的容器
  3. docker ps -a -q|xargs docker rm # 删除所有的容器

启动和停止容器的操作

  1. docker start 容器id # 启动容器
  2. docker restart 容器id # 重启容器
  3. docker stop 容器id # 停止当前正在运行的容器
  4. docker kill 容器id # 强制停止当前容器

其他常用命令

后台启动容器

  1. # 命令 docker run -d 镜像名
  2. [root@6b92d6 ~]# docker run -d centos
  3. # 问题 docker ps,发现 centos 停止了
  4. # 常见的坑,docker 容器使用后台运行,就必须要有一个前台进程,docker 发现没有应用,就会自动停止

查看日志

  1. docker logs -f -t --tail 容器,没有日志
  2. # 编写一段shell脚本
  3. [root@6b92d6 ~]# docker run -d centos /bin/sh -c "whlie true;do echo 6b92d6;sleep 1;done"
  4. [root@6b92d6 ~]# docker ps
  5. CONTAINER ID IMAGE
  6. 35ef3480191b centos
  7. # 显示日志
  8. -tf # 显示日志
  9. --tail number # 要显示日志条数
  10. [root@6b92d6 ~]# docker logs -tf --tail 10 35ef3480191b

查看容器中的进程信息

  1. # 命令 docker top 容器id
  2. [root@6b92d6 ~]# docker top 35ef3480191b
  3. UID PID PPID C STIME TTY TIME CMD
  4. root 14406 14385 0 00:13 ? 00:00:00 /bin/bash

镜像元数据

  1. # 命令 docker inspect 容器id
  2. [root@6b92d6 ~]# docker inspect e6b34a62f2e1
  3. [
  4. {
  5. "Id": "e6b34a62f2e107fc36c62cb2134d65af7edd984cafea33aac65fae730c108641",
  6. "Created": "2021-05-12T04:51:02.611560796Z",
  7. "Path": "/bin/sh",
  8. "Args": [
  9. "-c",
  10. "whlie true;do echo 6b92d6;sleep 1;done"
  11. ],
  12. "State": {
  13. "Status": "exited",
  14. "Running": false,
  15. "Paused": false,
  16. "Restarting": false,
  17. "OOMKilled": false,
  18. "Dead": false,
  19. "Pid": 0,
  20. "ExitCode": 1,
  21. "Error": "",
  22. "StartedAt": "2021-05-12T04:51:02.934871716Z",
  23. "FinishedAt": "2021-05-12T04:51:02.940944414Z"
  24. },
  25. "Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
  26. "ResolvConfPath": "/var/lib/docker/containers/e6b34a62f2e107fc36c62cb2134d65af7edd984cafea33aac65fae730c108641/resolv.conf",
  27. "HostnamePath": "/var/lib/docker/containers/e6b34a62f2e107fc36c62cb2134d65af7edd984cafea33aac65fae730c108641/hostname",
  28. "HostsPath": "/var/lib/docker/containers/e6b34a62f2e107fc36c62cb2134d65af7edd984cafea33aac65fae730c108641/hosts",
  29. "LogPath": "/var/lib/docker/containers/e6b34a62f2e107fc36c62cb2134d65af7edd984cafea33aac65fae730c108641/e6b34a62f2e107fc36c62cb2134d65af7edd984cafea33aac65fae730c108641-json.log",
  30. "Name": "/brave_shamir",
  31. "RestartCount": 0,
  32. "Driver": "overlay2",
  33. "Platform": "linux",
  34. "MountLabel": "",
  35. "ProcessLabel": "",
  36. "AppArmorProfile": "",
  37. "ExecIDs": null,
  38. "HostConfig": {
  39. "Binds": null,
  40. "ContainerIDFile": "",
  41. "LogConfig": {
  42. "Type": "json-file",
  43. "Config": {}
  44. },
  45. "NetworkMode": "default",
  46. "PortBindings": {},
  47. "RestartPolicy": {
  48. "Name": "no",
  49. "MaximumRetryCount": 0
  50. },
  51. "AutoRemove": false,
  52. "VolumeDriver": "",
  53. "VolumesFrom": null,
  54. "CapAdd": null,
  55. "CapDrop": null,
  56. "CgroupnsMode": "host",
  57. "Dns": [],
  58. "DnsOptions": [],
  59. "DnsSearch": [],
  60. "ExtraHosts": null,
  61. "GroupAdd": null,
  62. "IpcMode": "private",
  63. "Cgroup": "",
  64. "Links": null,
  65. "OomScoreAdj": 0,
  66. "PidMode": "",
  67. "Privileged": false,
  68. "PublishAllPorts": false,
  69. "ReadonlyRootfs": false,
  70. "SecurityOpt": null,
  71. "UTSMode": "",
  72. "UsernsMode": "",
  73. "ShmSize": 67108864,
  74. "Runtime": "runc",
  75. "ConsoleSize": [
  76. 0,
  77. 0
  78. ],
  79. "Isolation": "",
  80. "CpuShares": 0,
  81. "Memory": 0,
  82. "NanoCpus": 0,
  83. "CgroupParent": "",
  84. "BlkioWeight": 0,
  85. "BlkioWeightDevice": [],
  86. "BlkioDeviceReadBps": null,
  87. "BlkioDeviceWriteBps": null,
  88. "BlkioDeviceReadIOps": null,
  89. "BlkioDeviceWriteIOps": null,
  90. "CpuPeriod": 0,
  91. "CpuQuota": 0,
  92. "CpuRealtimePeriod": 0,
  93. "CpuRealtimeRuntime": 0,
  94. "CpusetCpus": "",
  95. "CpusetMems": "",
  96. "Devices": [],
  97. "DeviceCgroupRules": null,
  98. "DeviceRequests": null,
  99. "KernelMemory": 0,
  100. "KernelMemoryTCP": 0,
  101. "MemoryReservation": 0,
  102. "MemorySwap": 0,
  103. "MemorySwappiness": null,
  104. "OomKillDisable": false,
  105. "PidsLimit": null,
  106. "Ulimits": null,
  107. "CpuCount": 0,
  108. "CpuPercent": 0,
  109. "IOMaximumIOps": 0,
  110. "IOMaximumBandwidth": 0,
  111. "MaskedPaths": [
  112. "/proc/asound",
  113. "/proc/acpi",
  114. "/proc/kcore",
  115. "/proc/keys",
  116. "/proc/latency_stats",
  117. "/proc/timer_list",
  118. "/proc/timer_stats",
  119. "/proc/sched_debug",
  120. "/proc/scsi",
  121. "/sys/firmware"
  122. ],
  123. "ReadonlyPaths": [
  124. "/proc/bus",
  125. "/proc/fs",
  126. "/proc/irq",
  127. "/proc/sys",
  128. "/proc/sysrq-trigger"
  129. ]
  130. },
  131. "GraphDriver": {
  132. "Data": {
  133. "LowerDir": "/var/lib/docker/overlay2/063bbd5cd87321d1108b101ecd97a5b3d8f7393056d8f33a225e778ad8d798d7-init/diff:/var/lib/docker/overlay2/e391cea676db50733036bece9ad2e8c412fc65b1a66db763fa20039b7b08af57/diff",
  134. "MergedDir": "/var/lib/docker/overlay2/063bbd5cd87321d1108b101ecd97a5b3d8f7393056d8f33a225e778ad8d798d7/merged",
  135. "UpperDir": "/var/lib/docker/overlay2/063bbd5cd87321d1108b101ecd97a5b3d8f7393056d8f33a225e778ad8d798d7/diff",
  136. "WorkDir": "/var/lib/docker/overlay2/063bbd5cd87321d1108b101ecd97a5b3d8f7393056d8f33a225e778ad8d798d7/work"
  137. },
  138. "Name": "overlay2"
  139. },
  140. "Mounts": [],
  141. "Config": {
  142. "Hostname": "e6b34a62f2e1",
  143. "Domainname": "",
  144. "User": "",
  145. "AttachStdin": false,
  146. "AttachStdout": false,
  147. "AttachStderr": false,
  148. "Tty": false,
  149. "OpenStdin": false,
  150. "StdinOnce": false,
  151. "Env": [
  152. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  153. ],
  154. "Cmd": [
  155. "/bin/sh",
  156. "-c",
  157. "whlie true;do echo 6b92d6;sleep 1;done"
  158. ],
  159. "Image": "centos",
  160. "Volumes": null,
  161. "WorkingDir": "",
  162. "Entrypoint": null,
  163. "OnBuild": null,
  164. "Labels": {
  165. "org.label-schema.build-date": "20201204",
  166. "org.label-schema.license": "GPLv2",
  167. "org.label-schema.name": "CentOS Base Image",
  168. "org.label-schema.schema-version": "1.0",
  169. "org.label-schema.vendor": "CentOS"
  170. }
  171. },
  172. "NetworkSettings": {
  173. "Bridge": "",
  174. "SandboxID": "e0df155fd86fd3ff0afa9627088b256b986683c8ebf02645edb12005293d2e92",
  175. "HairpinMode": false,
  176. "LinkLocalIPv6Address": "",
  177. "LinkLocalIPv6PrefixLen": 0,
  178. "Ports": {},
  179. "SandboxKey": "/var/run/docker/netns/e0df155fd86f",
  180. "SecondaryIPAddresses": null,
  181. "SecondaryIPv6Addresses": null,
  182. "EndpointID": "",
  183. "Gateway": "",
  184. "GlobalIPv6Address": "",
  185. "GlobalIPv6PrefixLen": 0,
  186. "IPAddress": "",
  187. "IPPrefixLen": 0,
  188. "IPv6Gateway": "",
  189. "MacAddress": "",
  190. "Networks": {
  191. "bridge": {
  192. "IPAMConfig": null,
  193. "Links": null,
  194. "Aliases": null,
  195. "NetworkID": "0fe8e113f3ad34cb12f9c40ed735c882abb7b4e13631031e2a1ceb0558c606c9",
  196. "EndpointID": "",
  197. "Gateway": "",
  198. "IPAddress": "",
  199. "IPPrefixLen": 0,
  200. "IPv6Gateway": "",
  201. "GlobalIPv6Address": "",
  202. "GlobalIPv6PrefixLen": 0,
  203. "MacAddress": "",
  204. "DriverOpts": null
  205. }
  206. }
  207. }
  208. }
  209. ]

进入当前正在运行的容器

  1. # 通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
  2. # 命令
  3. docker exec -it 容器id bashShell
  4. [root@6b92d6 ~]# docker ps
  5. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  6. 443245f63b32 centos "/bin/bash" 3 hours ago Up 3 hours pedantic_chatelet
  7. 35ef3480191b centos "/bin/bash" 16 hours ago Up 16 hours charming_hamilton
  8. [root@6b92d6 ~]# docker exec -it 443245f63b32 /bin/bash
  9. [root@443245f63b32 /]# ls
  10. bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
  11. [root@443245f63b32 /]# ps -ef
  12. UID PID PPID C STIME TTY TIME CMD
  13. root 1 0 0 04:50 pts/0 00:00:00 /bin/bash
  14. root 15 0 0 08:03 pts/1 00:00:00 /bin/bash
  15. root 29 15 0 08:03 pts/1 00:00:00 ps -ef
  16. # 方式二
  17. docker attach 容器id
  18. # 测试
  19. [root@6b92d6 ~]# docker attach 35ef3480191b
  20. 正在执行当前的代码……
  21. # docker exec # 进入容器后开启一个新的终端,可以在里面操作(常用)
  22. # docker attach # 进入容器正在执行的终端,不会开启新的终端

从容器内拷贝文件到主机上

  1. docker cp 容器id:容器内路径 目的的主机路径
  2. # 查看当前主机目录
  3. [root@6b92d6 home]# ls
  4. dafran.java fastdfs git ljc
  5. [root@6b92d6 home]# docker ps
  6. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  7. 55bfc18e4e5b centos "/bin/bash" About a minute ago Up About a minute flamboyant_bhabha
  8. # 进入docker容器内部
  9. [root@6b92d6 home]# docker attach 55bfc18e4e5b
  10. [root@55bfc18e4e5b /]# cd home/
  11. [root@55bfc18e4e5b home]# ls
  12. # 在容器内新建一个文件
  13. [root@55bfc18e4e5b home]# touch test.java
  14. [root@55bfc18e4e5b home]# ls
  15. test.java
  16. [root@55bfc18e4e5b home]# exit
  17. exit
  18. [root@6b92d6 home]# docker ps -a
  19. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  20. 55bfc18e4e5b centos "/bin/bash" 3 minutes ago Exited (0) 15 seconds ago flamboyant_bhabha
  21. # 将这文件拷贝到主机上
  22. [root@6b92d6 home] docker cp 55bfc18e4e5b:/home/test.java /home
  23. [root@6b92d6 home] ls
  24. dafran.java fastdfs git test.java
  25. [root@6b92d6 home]
  26. # 拷贝是一个手动过程,未来使用卷的技术,可以实现,自动同步

命令小结

Docker - 图20

  1. attach Attach to a running container # 当前 shell 下 attach 连接指定运行镜像
  2. build Build an image from a Dockerfile # 通过 Dockerfile 定制镜像
  3. commit Create a new image from a container changes # 提交当前容器为新的镜像
  4. cp Copy files/folders from the containers filesystem to the host path #从容器中拷贝指定文件或者目录到宿主机中
  5. create Create a new container # 创建一个新的容器,同 run,但不启动容器
  6. diff Inspect changes on a container's filesystem # 查看 docker 容器变化
  7. events Get real time events from the server # 从 docker 服务获取容器实时事件
  8. exec Run a command in an existing container # 在已存在的容器上运行命令
  9. export Stream the contents of a container as a tar archive # 导出容器的内容流作为一个 tar 归档文件[对应 import ]
  10. history Show the history of an image # 展示一个镜像形成历史
  11. images List images # 列出系统当前镜像
  12. import Create a new filesystem image from the contents of a tarball # 从tar包中的内容创建一个新的文件系统映像[对应export]
  13. info Display system-wide information # 显示系统相关信息
  14. inspect Return low-level information on a container # 查看容器详细信息
  15. kill Kill a running container # kill 指定 docker 容器
  16. load Load an image from a tar archive # 从一个 tar 包中加载一个镜像[对应 save]
  17. login Register or Login to the docker registry server # 注册或者登陆一个 docker 源服务器
  18. logout Log out from a Docker registry server # 从当前 Docker registry 退出
  19. logs Fetch the logs of a container # 输出当前容器日志信息
  20. port Lookup the public-facing port which is NAT-ed to PRIVATE_PORT # 查看映射端口对应的容器内部源端口
  21. pause Pause all processes within a container # 暂停容器
  22. ps List containers # 列出容器列表
  23. pull Pull an image or a repository from the docker registry server # 从docker镜像源服务器拉取指定镜像或者库镜像
  24. push Push an image or a repository to the docker registry server # 推送指定镜像或者库镜像至docker源服务器
  25. restart Restart a running container # 重启运行的容器
  26. rm Remove one or more containers # 移除一个或者多个容器
  27. rmi Remove one or more images # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
  28. run Run a command in a new container # 创建一个新的容器并运行一个命令
  29. save Save an image to a tar archive # 保存一个镜像为一个 tar 包[对应 load]
  30. search Search for an image on the Docker Hub # 在 docker hub 中搜索镜像
  31. start Start a stopped containers # 启动容器
  32. stop Stop a running containers # 停止容器
  33. tag Tag an image into a repository # 给源中镜像打标签
  34. top Lookup the running processes of a container # 查看容器中运行的进程信息
  35. unpause Unpause a paused container # 取消暂停容器
  36. version Show the docker version information # 查看 docker 版本号
  37. wait Block until a container stops, then print its exit code # 截取容器停止时的退出状态值

作业练习

docker 安装 nginx

  1. # 1、搜索镜像 search 建议去官网搜索,可以看到帮助文档
  2. # 2、下载镜像 pull
  3. # 3、运行测试
  4. [root@6b92d6 /]# docker images
  5. REPOSITORY TAG IMAGE ID CREATED SIZE
  6. nginx latest f0b8a9a54136 17 hours ago 133MB
  7. centos latest 300e315adb2f 5 months ago 209MB
  8. # -d 后台运行
  9. # --name 给容器命令
  10. # -p 宿主机端口:容器端口
  11. [root@6b92d6 /]# docker run -d --name nginx01 -p 3344:80 nginx
  12. 956c4172792a6b52496878c899c7dc7dac60fad02508d3270971d72bf2098dda
  13. [root@6b92d6 /]# docker ps
  14. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  15. 956c4172792a nginx "/docker-entrypoint.…" 9 seconds ago Up 8 seconds 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
  16. [root@6b92d6 /]# curl localhost:3344
  17. # 进入容器
  18. [root@6b92d6 /]# docker exec -it nginx01 /bin/bash
  19. root@956c4172792a:/# whereis nginx
  20. nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
  21. root@956c4172792a:/# cd /etc/nginx
  22. root@956c4172792a:/etc/nginx# ls
  23. conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf

Docker - 图21

  1. 每次改动 nginx配置文件,都需要进入容器内部,十分的麻烦。要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改。 —-数据卷

docker 安装tomcat

  1. # 官方使用
  2. docker run -it --rm tomcat:9.0
  3. # 之前的启动都是后台,停止后,容器还是可以查到 docker run-it--rm,一般用来测试,用完即删除
  4. # 下载
  5. docker pull tomcat
  6. # 启动运行
  7. docker run -d -p 8080:8080 --name tomcat01 tomcat
  8. # 测试访问没有问题
  9. # 进入容器
  10. [root@6b92d6 /]# docker exec -it tomcat01 /bin/bash
  11. # 发现问题:1、linux命令少了; 2、没有 webapps。 阿里云镜像原因,默认最小镜像,剔除掉所有不必要。
  12. # 保证最小可运行的环境

以后要部署项目,如果每次都要进入容器十分麻烦?要是可以在容器外部提供一个映射路径,webapps,在外部放置项目,就自动同步到内部就好。

docker 部署 es + kibana

  1. # es 暴露的端口很多
  2. # es 十分的耗内存
  3. # es 的数据一般需要放置到安全目录 --挂载
  4. # --net somenetwork 网络配置
  5. docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag
  6. # 启动 elasticsearch
  7. docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
  8. # 启动了linux就卡住 docker stats查看cpu的状态
  9. # 测试es是否成功
  10. [root@6b92d6 /]# curl loacalhost:9200
  11. # 查看 docker stats
  12. # 关闭,增加内存的限制 修改配置文件 -e 环境配置修改
  13. docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
  14. # 查看 docker stats

Docker - 图22

  1. [root@6b92d6 /]# curl localhost:9200
  2. {
  3. "name" : "f250139646d8",
  4. "cluster_name" : "docker-cluster",
  5. "cluster_uuid" : "-zCCF0zIQS6y3VWrjJIYUA",
  6. "version" : {
  7. "number" : "7.6.2",
  8. "build_flavor" : "default",
  9. "build_type" : "docker",
  10. "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
  11. "build_date" : "2020-03-26T06:34:37.794943Z",
  12. "build_snapshot" : false,
  13. "lucene_version" : "8.4.0",
  14. "minimum_wire_compatibility_version" : "6.8.0",
  15. "minimum_index_compatibility_version" : "6.0.0-beta1"
  16. },
  17. "tagline" : "You Know, for Search"
  18. }

使用 kibana连接es?网络如果才能连接过去?

Docker - 图23

可视化

  • portainer
  1. docker run -d -p 8088:9000 \
  2. --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher(CI/CD再用)

portainer

Docker图形化界面管理工具,提供一个后台面板可以操作。

  1. docker run -d -p 8088:9000 \
  2. --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

测试访问:http://ip:8088/

设置admin用户密码,需要输入两次相同的密码

Docker - 图24

选择本地的

Docker - 图25

注意:该页面上有提示需要挂载本地/ar/run/ docker: socker与容器内的/var/run/ docker socker连接。因此,在启动时必须指定该挂载文件。

管理面板

Docker - 图26

Docker镜像讲解

镜像是什么?

  1. 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码,运行时库、环境变量和配置文件

所有的应用,直接打包docker镜像,就可以直接跑起来。

如何到镜像:

  • 从远程仓库下载
  • 从他人处拷贝
  • 自己制作镜像 DockerFile

Dcoker镜像加载原理

UnionFS(联合文件系统)

  1. UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。

bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs(root file system),在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

Docker - 图27

Docker - 图28

  1. 对于一个精简的OSrootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Hostkernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs

分层理解

当下载一个镜像时,可以观察到,是一层层的下载,而且有些已经重复的文件,不会再额外下载。

Docker - 图29

为什么Docker要分层下载呢?

  1. 最大的好处,就是资源共享,比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份Base镜像,同时内存中也只需要加载一份Base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享

查看镜像分层的方式可以通过 docker image inspect [redis:latest] 命令

  1. "RootFS": {
  2. "Type": "layers",
  3. "Layers": [
  4. "sha256:02c055ef67f5904019f43a41ea5f099996d8e7633749b6e606c400526b2c4b33",
  5. "sha256:ec5652c3523d96657d66169c0eb71b572ff065711c705a15ec02f60a21c212c3",
  6. "sha256:76d3e24d63f60e6a73af70be15959eb4021dd7a5a09da6925037d3b4a1673fca",
  7. "sha256:f281464c05be6822b95403339e2b7744fd1664e88ee9d118c7e89436ab094d58",
  8. "sha256:7fde79e38c038ef46904196710861e2c556363d723b8f8bf9b00369944d36aec",
  9. "sha256:6d4185a1708b677241d83683283c76703e788e41a2341b7c1bf4dbf12aebab45"
  10. ]
  11. },
  12. "Metadata": {
  13. "LastTagTime": "0001-01-01T00:00:00Z"
  14. }

所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。

举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。

该镜像当前已经包含3个镜像层,如下图所示。

Docker - 图30

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而整体的大镜像包含了来自两个镜像层的6个文件。

Docker - 图31

上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件。

下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。

Docker - 图32

这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的文件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。

Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。

下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图

Docker - 图33

特点

Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部。

这一层就是通常说的容器层,容器之下的都叫镜像层。

Docker - 图34

commit 提交镜像

  1. docker commit 提交容器成为一个新的副本
  2. # 命令和git原理类似
  3. docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[版本TAG]

测试

  1. # 1、启动一个默认的tomcat
  2. docker run -it -p 8080:8080 tomcat
  3. # 2、发现这个默认的tomcat是没有webapps应用的,镜像的原因。官方的镜像默认webapps下面是没有文件的!
  4. docker exec -it 1fd85f61aeb8 /bin/bash
  5. # 3、将webapp.dist下文件拷贝至webapps下
  6. root@1fd85f61aeb8:/usr/local/tomcat# cp -r webapps.dist/* webapps
  7. # 4、将操作过的容器通过commit提交为一个镜像!以后就可以使用修改过的镜像了,这就是一个自己修改的镜像
  8. [root@6b92d6 ~]# docker commit -a="6b92d6" -m"add webapps" 1fd85f61aeb8 tomcat000:1.0

Docker - 图35

容器数据卷

什么是容器数据卷

docker的理念回顾

将应用和环境打包成一个镜像!

数据;如果数据都在容器中,那么容器被删除,数据就会丢失!需求:数据可以持久化
MySQL;容器删了,删库跑路!需求:MySQL数据可以存储在本地

容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地。

这就是卷技术;目录的挂载,将容器内的目录,挂载到Linux宿主机上面

Docker - 图36

总结一句话:容器的持久化和同步操作;容器间也是可以数据共享的;

使用数据卷

方式一:直接使用命令来挂载 -v

  1. docker run -it -v 主机目录:容器内目录
  2. # 测试
  3. docker run -it -v /home/6b92d6:/home centos /bin/bash
  4. # 启动后,可以通过 docker inspect 容器id

Docker - 图37

测试文件同步

再次进行测试

1、停止容器
2、宿主机上修改文件
3、启动容器
4、容器内的数据依旧是同步的

Docker - 图38

好处:以后修改只需要在本地修改即可,容器内会自动同步

实战:MySQL

MySQL的数据持久化的问题

  1. # 获取镜像
  2. docker pull mysql:5.7
  3. # 运行容器,需要做数据挂载; 安装启动mysql,需要配置密码的,这是注意点
  4. # 官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
  5. # 启动
  6. -d 后台运行
  7. -p 端口映射
  8. -v 卷挂载
  9. -e 环境配置
  10. --name 容器命名
  11. docker run -d -p 3310:3306 -v /home/6b92d6/mysql/conf:/etc/mysql/conf.d -v /home/6b92d6/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
  12. # 启动成功之后,在本地使用Navcat来接测试一下
  13. # Navcat-连接到服务器的3310---3310和容器内的3306映射,这个时候连接上了
  14. # 在本地测试创建一个数据库,查看一下映射的路径是否ok

假设将容器删除

Docker - 图39

发现,挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能

具名和匿名挂载

  1. # 匿名挂载
  2. -v 容器内路径
  3. docker run -d -P --name nginx01 -v /ect/nginx nginx
  4. # 查看所有 volume 的情况
  5. [root@6b92d6 ~]# docker volume ls
  6. DRIVER VOLUME NAME
  7. local 4d550aaecab90abe3e0506ea2b0e195c2d489f3a017f217d8454d16c0b921f9a
  8. # 这里发现,这种就是匿名挂载,在-v只写了容器内的路径,没有写容器外的路径
  9. # 具名挂载
  10. [root@6b92d6 6b92d6]# docker run -d -P --name nginx02 -v juming-nginx:/ect/nginx nginx
  11. [root@6b92d6 6b92d6]# docker volume ls
  12. DRIVER VOLUME NAME
  13. local juming-nginx
  14. # -v 卷名:容器内路径
  15. # 查看一下这个卷

Docker - 图40

所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data

通过具名挂载可以方便的找到卷,大多数情况在使用的具名挂载

  1. # 如何确定是具名挂载还是匿名挂载,还是指定路径挂载
  2. -v 容器内路径 # 匿名挂载
  3. -v 卷名:容器内路径 # 具名挂载
  4. -v /宿主机路径:容器内路径 # 指定路径挂载

扩展:

  1. # 通过 -v 容器内路径: ro rw 改变读写权限
  2. ro readonly # 只读
  3. rw readwrite # 可读可写
  4. # 一旦设置了容器权限,容器对挂载出来的内容就有限定
  5. docker run -d -p --name nginx02 -v juming nginx:/etc/nginx:ro nginx
  6. docker run -d -p --name nginx02 -v juming nginx:/etc/nginx:rw nginx
  7. # ro 只要看到ro就说明这个路径只能通过宿主机来操作,而容器内部是无法操作!

初识 DockerFile

DockerFile 就是用来构建 docker 镜像的构建文件,命令脚本

通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层

  1. [root@6b92d6 home]# mkdir docker-test-volume
  2. [root@6b92d6 home]# ls
  3. 6b92d6 docker-test-volume
  4. [root@6b92d6 home]# cd docker-test-volume/
  5. [root@6b92d6 docker-test-volume]# vim dockerfile1
  6. # 建一个 dockerfile 文件,名字可以随机建议 Dockerfile
  7. # 文件中的内容 指令(大写)参数
  8. FROM centos
  9. VOLUME ["volume01","volume02"]
  10. CMD echo "---end---"
  11. CMD /bin/bash
  12. # 每条命令,就是镜像的一层
  13. mkdir docker-test-volume
  14. [root@6b92d6 docker-test-volume]# docker build -f /home/6b92d6/docker-test-volume/dockerfile1 -t dafran/centos:1.0 .

Docker - 图41

  1. # 启动自定义的容器
  2. [root@6b92d6 docker-test-volume]# docker run -it 765fd5473df1 /bin/bash

Docker - 图42

这个卷和外部一定有一个同步的目录

Docker - 图43

查看卷挂载路径

  1. docker inspect 89b77cee2bfa

Docker - 图44

测试一下刚才的文件是否同步出去了

这种方式未来使用的十分多,因为通常会构建自己的镜像

假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径

数据卷容器

Docker - 图45

  1. # 启动3个容器,使用之前自定义的镜像启动
  2. [root@6b92d6 ~]# docker run -it --name docker01 6b92d6/centos:1.0
  3. [root@6b92d6 ~]# docker ps
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. 002eaa6fd799 6b92d6/centos:1.0 "/bin/sh -c /bin/bash" 3 minutes ago Up 2 minutes docker01
  6. 4214ced18e05 centos "/bin/bash" 48 minutes ago Up 48 minutes dazzling_pasteur
  7. [root@6b92d6 ~]# docker run -it --name docker02 --volumes-from docker01 6b92d6/centos:1.0
  8. [root@93355ed0e158 /]# ls -l
  9. [root@6b92d6 ~]# docker attach 002eaa6fd799 # 进入docker01 创建文件测试是否同步
  10. [root@002eaa6fd799 /]# cd volume01
  11. [root@002eaa6fd799 volume01]# touch docker01

docker01

Docker - 图46

docker02

Docker - 图47

docker03

Docker - 图48

  1. # 测试:可以删除 docker01,查看一下 docker02 和 docker03
  2. # 测试依旧可以访间

Docker - 图49

Docker - 图50

Docker - 图51

多个mysq实现数据共享

  1. [root@6b92d6 ~]# docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
  2. [root@6b92d6 ~]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
  3. # 这个时候,可以实现两个容器数据同步

结论:

容器之间配置信息的传递,数据卷容器的生命周期,一直持续到没有容器使用为止。

但是一旦持久化到了本地,这个时候,本地的数据是不会删除的!

DockerFile

DockerFile介绍

dockerfile是用来构建 dokcer 镜像的文件,命令参数脚本

构建步骤

1、编写一个 dockerfile 文件

2、docker build 构建成为一个镜像

3、docker run 运行镜像

4、docker push 发布镜像(Dockerhub、阿里云镜像仓库)

查看官方版本如何制作的

Docker - 图52

Docker - 图53

很多官方镜像都是基础包,很多功能没有,通常会自己搭建自己的镜像

DockerFile构建过程

基础知识

1、每个保留关键字(指令)都是必须是大写字母

2、指令从上到下顺序执行

3、# 表示注释

4、每一个指令都会创建提交一个新的镜像层,并提交

Docker - 图54

dockerfile是面向开发的,以后要发布项目、做镜像,就需要编写 dockerfile 文件。

步骤:开发、部署、运维、缺一不可

Docker file:构建文件、定义了一切的步骤。类似源代码

DockerImages:通过 Dockerfile 构建生成的镜像,最终发布和运行的产品。

Docker容器:容器就是镜像运行起来提供服务的

DockerFile的指令

  1. FROM # 基础镜像,从这里开始构建
  2. MAINTAINER # 镜像的维护者姓名+邮箱
  3. RUN # 镜像构建的时候需要运行的命令
  4. ADD # 将本地文件添加到容器的指定目录中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源
  5. WORKDIR # 镜像的工作目录
  6. VULUME # 挂载的目录
  7. EXPOSE # 保留端口配置
  8. CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
  9. ENRTYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
  10. ONBUILD # 当构建一个被继承的 DockerFile 这个时候就会运行 ONBULID 指令。 触发指令
  11. COPY # 似ADD,将文件拷贝到镜像中
  12. ENV # 构建环境的时候设置环境变量

Docker - 图55

DockerFile指令详解

实战:自定义centos

Docker Hub中99%镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行的构建

Docker - 图56

  1. # 1、编写 Dockerfile文件
  2. [root@6b92d6 dockerfile]# vim mydockerfile-centos
  3. [root@6b92d6 dockerfile]# cat mydockerfile-centos
  4. FROM centos
  5. MAINTAINER 6b92d6<6b92d6@gmail.com>
  6. ENV MYPATH /usr/local
  7. WORKDIR $MYPATH
  8. RUN yum -y install vim
  9. RUN yum -y install net-tools
  10. EXPOSE 80
  11. CMD echo $MYPATH
  12. CMD echo "----end----"
  13. CMD /bin/bash
  14. # 2、通过这个文件构建镜像
  15. # 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag]
  16. [root@6b92d6 dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
  17. Successfully built 75c9fbb22f84
  18. Successfully tagged mycentos:0.1
  19. # 3、测试运行
  20. [root@6b92d6 dockerfile]# docker run -it mycentos:0.1

Docker - 图57

自己构建的镜像

Docker - 图58

可以列出本地进行的变更历史

Docker - 图59

CMD 和 ENTRYPOINT区别

  1. CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
  2. ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令

CMD

  1. # 编写 dockerfile 文件
  2. [root@6b92d6 dockerfile]# vim docker-cmd-test
  3. FROM centos
  4. CMD ["ls","-a"]
  5. # 构建镜像
  6. [root@6b92d6 dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
  7. # run运行,发现 ls -a 命令生效
  8. [root@6b92d6 dockerfile]# docker run 23c5406f3291
  9. .
  10. ..
  11. .dockerenv
  12. bin
  13. dev
  14. etc
  15. home
  16. lib
  17. lib64
  18. # 想追加一个命令 -l 即 ls -a
  19. [root@6b92d6 dockerfile]# docker run 23c5406f3291 -l
  20. docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
  21. ERRO[0000] error waiting for container: context canceled
  22. # cmd的情况下, -l 替换了 CMD ["ls","-a"] 命令,-l 不是命令 所以报错

ENTRYPOINT

  1. [root@6b92d6 dockerfile]# vim dockerfile-entrypoint-test
  2. FROM centos
  3. ENTRYPOINT ["ls","-a"]
  4. [root@6b92d6 dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test .
  5. Sending build context to Docker daemon 16.9kB
  6. Step 1/2 : FROM centos
  7. ---> a0477e85b8ae
  8. Step 2/2 : ENTRYPOINT ["ls","-a"]
  9. ---> Running in c9ac5bf8c2fe
  10. Removing intermediate container c9ac5bf8c2fe
  11. ---> f6c790788325
  12. Successfully built f6c790788325
  13. Successfully tagged entrypoint-test:latest
  14. [root@6b92d6 dockerfile]# docker run f6c790788325
  15. .
  16. ..
  17. .dockerenv
  18. bin
  19. dev
  20. etc
  21. home
  22. lib
  23. lib64
  24. lost+found
  25. media
  26. mnt
  27. opt
  28. proc
  29. root
  30. run
  31. sbin
  32. srv
  33. sys
  34. tmp
  35. usr
  36. var
  37. # 追加命令,是直接拼接在 ENTRYPOINT 命令的后面
  38. [root@6b92d6 dockerfile]# docker run f6c790788325 -l
  39. total 56
  40. drwxr-xr-x 1 root root 4096 May 19 14:13 .
  41. drwxr-xr-x 1 root root 4096 May 19 14:13 ..
  42. -rwxr-xr-x 1 root root 0 May 19 14:13 .dockerenv
  43. lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
  44. drwxr-xr-x 5 root root 340 May 19 14:13 dev
  45. drwxr-xr-x 1 root root 4096 May 19 14:13 etc
  46. drwxr-xr-x 2 root root 4096 Nov 3 2020 home
  47. lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
  48. lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
  49. drwx------ 2 root root 4096 Dec 4 17:44 lost+found
  50. drwxr-xr-x 2 root root 4096 Nov 3 2020 media
  51. drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
  52. drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
  53. dr-xr-xr-x 132 root root 0 May 19 14:13 proc
  54. dr-xr-x--- 2 root root 4096 Dec 4 17:45 root
  55. drwxr-xr-x 11 root root 4096 Dec 4 17:45 run
  56. lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
  57. drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
  58. dr-xr-xr-x 12 root root 0 May 18 13:52 sys
  59. drwxrwxrwt 7 root root 4096 Dec 4 17:45 tmp
  60. drwxr-xr-x 12 root root 4096 Dec 4 17:44 usr
  61. drwxr-xr-x 20 root root 4096 Dec 4 17:45 var

实战:Tomcat镜像

1、准备镜像文件 tomcat 压缩包,jdk的压缩包

Docker - 图60

2、准备 DockerFile 文件。官方命名Dockerfile,build 会自动寻找这个文件,就不再需要 -f 指定了

  1. FROM centos
  2. MAINTAINER 6b92d6<6b92d6@gmail.com>
  3. COPY readme.txt /usr/local/readme.txt
  4. ADD jdk-8u291-linux-aarch64.tar.gz /usr/local/
  5. ADD apache-tomcat-9.0.46.tar.gz /usr/local/
  6. RUN yum -y install vim
  7. ENV MYPATH /usr/local
  8. WORKDIR $MYPATH
  9. ENV JAVA_HOME /usr/local/jdk1.8.0_291
  10. ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
  11. ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.46
  12. ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.46
  13. ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
  14. EXPOSE 8080
  15. CMD /usr/local/apache-tomcat-9.0.46/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.46/bin/logs/catalina.out

3、构建镜像

  1. # docker build -t diytomcat .

4、启动镜像

  1. docker run -d -p 9090:8080 --name 6b92d6tomcat -v /home/6b92d6/build/tomcat/test:/usr/local/apache-tomcat-9.0.46/webapps/test -v /home/6b92d6/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.46/logs diytomcat
  2. docker exec -it 98444cc5c9d8b7a93 /bin/bash

5、访问测试

6、发布项目(由于做了卷挂载,可以直接在本地编写项目)

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://java.sun.com/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  5. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  6. version="2.5">
  7. </web-app>

jsp

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <meta charset="utf-8">
  7. <title>6b92d6</title>
  8. </head>
  9. <body>
  10. Hello World!<br/>
  11. <%
  12. System.out.println("----------6b92d6-----------");
  13. %>
  14. </body>
  15. </html>

发现:项目部署成功,可以直接访问计科

以后开发的步骤:需要掌握 Dokcerfile 的编写。之后的一切都是使用 docker 镜像来发布运行

发布镜像

DockerHub

1、Docker Hub注册账号

2、确定这个这账号可以登录

3、在服务器上提交自己的镜像

  1. [root@6b92d6 tomcat]# docker login --help
  2. Usage: docker login [OPTIONS] [SERVER]
  3. Log in to a Docker registry.
  4. If no server is specified, the default is defined by the daemon.
  5. Options:
  6. -p, --password string Password
  7. --password-stdin Take the password from stdin
  8. -u, --username string Username
  9. [root@6b92d6 tomcat]# docker login -u 6b92d6
  10. Password:
  11. WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
  12. Configure a credential helper to remove this warning. See
  13. https://docs.docker.com/engine/reference/commandline/login/#credentials-store
  14. Login Succeeded

4、登录完毕后就可以提交镜像了,就是一步 docker push

  1. # push镜像到服务器上
  2. [root@6b92d6 tomcat]# docker push 6b92d6/diytomcat:1.0
  3. The push refers to repository [docker.io/6b92d6/diytomcat]
  4. An image does not exist locally with the tag: 6b92d6/diytomcat
  5. # 解决:增加 tag
  6. [root@6b92d6 tomcat]# docker tag 187701fa3049 6b92d6/diytomcat:1.0
  7. [root@6b92d6 tomcat]# docker images
  8. REPOSITORY TAG IMAGE ID CREATED SIZE
  9. 6b92d6/diytomcat 1.0 187701fa3049 9 hours ago 497MB
  10. diytomcat latest 187701fa3049 9 hours ago 497MB
  11. entrypoint-test latest f6c790788325 12 hours ago 249MB
  12. cmdtest latest 23c5406f3291 12 hours ago 249MB
  13. mycentos 0.1 75c9fbb22f84 20 hours ago 326MB
  14. 6b92d6/centos 1.0 70a797b97735 36 hours ago 249MB
  15. centos latest a0477e85b8ae 5 months ago 249MB
  16. # docker push,尽量带上版本号
  17. [root@6b92d6 tomcat]# docker push 6b92d6/diytomcat:1.0
  18. The push refers to repository [docker.io/6b92d6/diytomcat]
  19. 29969211c97f: Pushing [======> ] 7.029MB/55.02MB
  20. 7e9305d86567: Pushing [=========> ] 3.023MB/15.92MB
  21. 35c5f46a6855: Pushing [===> ] 10.79MB/177.7MB
  22. 4856b8427c6e: Pushed
  23. 16764cdd1bc4: Mounted from library/centos

Docker - 图61

提交的时候也是按照镜像的层级来进行提交的

阿里云镜像服务

1、登录阿里云

2、找到容器镜像服务

3、创建命名空间

Docker - 图62

4、创建容器镜像

Docker - 图63

5、浏览创建的阿里云镜像仓库

Docker - 图64

问题:登录问题

Docker - 图65

  1. docker login --username=t_1484923626050_056 registry.cn-hangzhou.aliyuncs.com

同理华为云也是类似

小结

Docker - 图66

  1. 镜像打包成为一个tar压缩包,可以发送压缩包给别人

Docker网络

理解Docker0

清空所有环境

  1. docker rm -f $(docker ps -aq)
  2. docker rmi -f $(docker images -aq)

ip adder

Docker - 图67

三个网络

  1. # 问题:docker 如何处理容器网络访问的
  1. [root@6b92d6 ]# docker run -d -P --name tomcat01 tomcat
  2. # 查看容器的内部网络地址 ip addr 发现容器启动的时候会得到 eth0@if41 ip docker分配的
  3. [root@6b92d6 ]# docker exec -it tomcat01 ip addr
  4. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  5. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  6. inet 127.0.0.1/8 scope host lo
  7. valid_lft forever preferred_lft forever
  8. 40: eth0@if41: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
  9. link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
  10. inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
  11. valid_lft forever preferred_lft forever
  12. # 思考:liunx能不能ping通容器内部
  13. [root@6b92d6 ]# ping 172.17.0.2
  14. PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
  15. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.072 ms
  16. 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.053 ms
  17. # linux可以ping通 docker 容器内部

原理

1、每启动一个 docker 容器,docker 就会给 docker 容器分配一个ip,只要安装了 docker,就会有一个网卡 docker0(桥接模式),使用的技术是 evth-pair 技术

再次测试 ip addr

Docker - 图68

  1. 与上面的41 eth0[@if40 ](/if40 ) 相连

2、在启动一个容器测试,发现又多了一对网卡

Docker - 图69

  1. # 发现这个容器带来网卡,都是一对对的
  2. # evth-pair就是虚拟设备接口,它们都是成对出现的,一端连着协议,一端彼此相连
  3. # 正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
  4. # openstack, Docker 容器之间的连接,OVS的连接,均使用 evth-pair技术

3、测试 tomcat01 和 tomcat02 是否可以 ping 通

  1. [root@6b92d6 ~]# docker exec -it tomcat02 ping 172.17.0.2
  2. PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
  3. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.091 ms
  4. 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.064 ms
  5. # 结论:容器直接是可以ping通的

Docker - 图70

结论:Tomcat01 和 Tomcat02 是公用的一个路由器 —— docker0

所有的容器不指定网络的情况下,都是 docker0 路由的, docker 会给容器分配一个默认的可用IP

小结

Docker 使用的是 Linux的桥接,宿主机中是一个 Dokcer 容器的网桥 docker0

Docker - 图71

Docker中的所有的网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)

只要容器删除,对应网桥一对就没了

  1. [root@6b92d6 ~]# docker network --help
  2. Commands:
  3. connect Connect a container to a network
  4. create Create a network
  5. disconnect Disconnect a container from a network
  6. inspect Display detailed information on one or more networks
  7. ls List networks
  8. prune Remove all unused networks
  9. rm Remove one or more networks
  10. [root@6b92d6 ~]# docker network ls
  11. NETWORK ID NAME DRIVER SCOPE
  12. d7d1e28321bb bridge bridge local
  13. 7f7b51e0b636 host host local
  14. 869e5384af15 none null local
  15. [root@6b92d6 ~]# docker network inspect d7d1e28321bb

Docker - 图72

- - link

思考:编写了一个微服务, database url=ip;项目不重启,数据库ip换掉了。希望可以处理这个问题,可以名字来进行访问容器

  1. # 如何解决
  2. [root@6b92d6 ~]# docker exec -it tomcat02 ping tomcat01
  3. ping: tomcat01: Name or service not known
  4. # --link 可以解决网络连通问题
  5. [root@6b92d6 ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
  6. 15176f551e6314db2086a3eeb3348df17740c825a49eb6e60e9aaff3d21069d0
  7. [root@6b92d6 ~]# docker exec -it tomcat03 ping tomcat02
  8. PING tomcat02 (172.17.0.3) 56(84) bytes of data.
  9. 64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.088 ms
  10. 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.061 ms
  11. # 反向可以ping通吗
  12. [root@6b92d6 ~]# docker exec -it tomcat02 ping tomcat03
  13. ping: tomcat03: Name or service not known

inspect

Docker - 图73

其实 tomcat03 就是在本地配置了 tomcat02的配置

  1. # 查看host配置
  2. [root@6b92d6 ~]# docker exec -it tomcat03 cat /etc/hosts
  3. 127.0.0.1 localhost
  4. ::1 localhost ip6-localhost ip6-loopback
  5. fe00::0 ip6-localnet
  6. ff00::0 ip6-mcastprefix
  7. ff02::1 ip6-allnodes
  8. ff02::2 ip6-allrouters
  9. 172.17.0.3 tomcat02 67361bdd5015
  10. 172.17.0.4 15176f551e63

本质:––link就是在 hosts配置中增加了一个172.17.0.3 tomcat02 67361bdd5015

docker 已经不在再使用 —link

自定义网络

查看所有的docker网络

Docker - 图74

网络模式

  • bridge:桥接 docker(默认)
  • none:不配置网络
  • host:主机模式,和宿主机(Linux)共享网络
  • container:容器内网络连通(用的少,局限很大)

测试

  1. # 默认直接启动的命令 --net bridge 而这个就是 docker0
  2. [root@6b92d6 ~]# docker run -d -P --name tomcat01 --net bridge tomcat
  3. # docker0特点:默认、域名不能访问、--1ink可以打通连接
  4. # 自定义网络
  5. # --driver bridge 桥接模式
  6. # --subnet 192.168.0.0/16 子网地址
  7. # --gateway 192.168.0.1 网关
  8. [root@6b92d6 ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
  9. cefc81d06f93b81b7f4c401f0997f040bf8eca85ceb82da533272b868d1580ee
  10. [root@6b92d6 ~]# docker network ls
  11. NETWORK ID NAME DRIVER SCOPE
  12. d7d1e28321bb bridge bridge local
  13. 7f7b51e0b636 host host local
  14. cefc81d06f93 mynet bridge local
  15. 869e5384af15 none null local

Docker - 图75

  1. [root@6b92d6 ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
  2. 52822a1797281a13737f802974b286a4617ff680f2fb97348149463d50489de2
  3. [root@6b92d6 ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
  4. bfa86cdb237610f08e666036ccea339b64e9e47578b3159d4602844daa60e625
  5. [root@6b92d6 ~]# docker network inspect mynet
  6. [
  7. {
  8. "Name": "mynet",
  9. "Id": "cefc81d06f93b81b7f4c401f0997f040bf8eca85ceb82da533272b868d1580ee",
  10. "Created": "2021-05-23T00:50:10.694303537+08:00",
  11. "Scope": "local",
  12. "Driver": "bridge",
  13. "EnableIPv6": false,
  14. "IPAM": {
  15. "Driver": "default",
  16. "Options": {},
  17. "Config": [
  18. {
  19. "Subnet": "192.168.0.0/16",
  20. "Gateway": "192.168.0.1"
  21. }
  22. ]
  23. },
  24. "Internal": false,
  25. "Attachable": false,
  26. "Ingress": false,
  27. "ConfigFrom": {
  28. "Network": ""
  29. },
  30. "ConfigOnly": false,
  31. "Containers": {
  32. "52822a1797281a13737f802974b286a4617ff680f2fb97348149463d50489de2": {
  33. "Name": "tomcat-net-01",
  34. "EndpointID": "5263de1c771b53846f1aa4def7823d9b63bb98727a67e5f1c708e686b5b56d64",
  35. "MacAddress": "02:42:c0:a8:00:02",
  36. "IPv4Address": "192.168.0.2/16",
  37. "IPv6Address": ""
  38. },
  39. "bfa86cdb237610f08e666036ccea339b64e9e47578b3159d4602844daa60e625": {
  40. "Name": "tomcat-net-02",
  41. "EndpointID": "438ff3087fd0d904cb5d0c5a4787c206c01f866db528bef1c2631f89a8b795f2",
  42. "MacAddress": "02:42:c0:a8:00:03",
  43. "IPv4Address": "192.168.0.3/16",
  44. "IPv6Address": ""
  45. }
  46. },
  47. "Options": {},
  48. "Labels": {}
  49. }
  50. ]
  51. # 再次测试ping连接
  52. [root@6b92d6 ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
  53. PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
  54. 64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.100 ms
  55. 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.072 ms
  56. ^C
  57. --- 192.168.0.3 ping statistics ---
  58. 2 packets transmitted, 2 received, 0% packet loss, time 44ms
  59. rtt min/avg/max/mdev = 0.072/0.086/0.100/0.014 ms
  60. # 不使用 --link 也可以ping
  61. [root@6b92d6 ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
  62. PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
  63. 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.057 ms
  64. 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.067 ms
  65. ^C
  66. --- tomcat-net-02 ping statistics ---
  67. 2 packets transmitted, 2 received, 0% packet loss, time 2ms
  68. rtt min/avg/max/mdev = 0.057/0.062/0.067/0.005 ms

自定义的网络 docker都已经维护好了对应的关系,推荐平时这样使用网络

好处:不同的集群使用不同的网络,保证集群是安全和健康的

网络连通

Docker - 图76

  1. # 测试连通 tomcat01 到 mynet
  2. [root@6b92d6 ~]# docker network connect mynet tomcat01
  3. # 连通以后发现就是将 tomcat01 放到 mynet 网络下
  4. [root@6b92d6 ~]# docker network inspect mynet
  5. # 一个容器两个ip 阿里云服务器,一个公网ip,一个私网ip

Docker - 图77

  1. # tomcat01打通
  2. [root@6b92d6 ~]# docker exec -it tomcat01 ping tomcat-net-01
  3. PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
  4. 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.079 ms
  5. 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.083 ms
  6. # tomcat02依旧打不通
  7. [root@6b92d6 ~]# docker exec -it tomcat02 ping tomcat-net-01
  8. ping: tomcat-net-01: Name or service not known

结论:假设要跨网络操作别人,就需要使用 docker network connect连通

实战:部署Redis集群

docker 网络 实战测试 redis 集群 分片 + 高可用 + 负载均衡 网络 实战测试 redis 集群 分片 + 高可用 + 负载均衡.png)

  1. # 创建网卡
  2. docker network create redis --subnet 172.38.0.0/16
  3. # 通过脚本创建六个redis配置
  4. for port in $(seq 1 6); \
  5. do \
  6. mkdir -p /mydata/redis/node-${port}/conf
  7. touch /mydata/redis/node-${port}/conf/redis.conf
  8. cat <<EOF>/mydata/redis/node-${port}/conf/redis.conf
  9. port 6379
  10. bind 0.0.0.0
  11. cluster-enabled yes
  12. cluster-config-file nodes.conf
  13. cluster-node-timeout 5000
  14. cluster-announce-ip 172.38.0.1${port}
  15. cluster-announce-port 6379
  16. cluster-announce-bus-port 16379
  17. appendonly yes
  18. EOF
  19. done
  20. # 1-6
  21. for port in $(seq 1 6); \
  22. do \
  23. docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
  24. -v /mydata/redis/node-${port}/data:/data \
  25. -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
  26. -d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server
  27. /etc/redis/redis.conf; \
  28. done
  29. docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
  30. -v /mydata/redis/node-1/data:/data \
  31. -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
  32. -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
  33. #创建集群的配置
  34. [root@6b92d6 conf]# docker exec -it redis-1 /bin/sh
  35. /data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
  36. >>> Performing hash slots allocation on 6 nodes...
  37. Master[0] -> Slots 0 - 5460
  38. Master[1] -> Slots 5461 - 10922
  39. Master[2] -> Slots 10923 - 16383
  40. Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
  41. Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
  42. Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
  43. M: a41efe0aab97aff316a6813121a85ef818a39376 172.38.0.11:6379
  44. slots:[0-5460] (5461 slots) master
  45. M: 1a31aa8f9f1ce41acfe41e30876e9efb480a7c94 172.38.0.12:6379
  46. slots:[5461-10922] (5462 slots) master
  47. M: 0e7260e23e38aed13abbdb00f9d536b9d8842a07 172.38.0.13:6379
  48. slots:[10923-16383] (5461 slots) master
  49. S: b7dab86ff429249b38fadc5502c733a99fd74c55 172.38.0.14:6379
  50. replicates 0e7260e23e38aed13abbdb00f9d536b9d8842a07
  51. S: 483b8f7ad6578cd1e9f622954a73f1635ad83e0e 172.38.0.15:6379
  52. replicates a41efe0aab97aff316a6813121a85ef818a39376
  53. S: 1a5fb18ed3514c390bab6052514a874393c0c8e2 172.38.0.16:6379
  54. replicates 1a31aa8f9f1ce41acfe41e30876e9efb480a7c94
  55. Can I set the above configuration? (type 'yes' to accept): yes
  56. >>> Nodes configuration updated
  57. >>> Assign a different config epoch to each node
  58. >>> Sending CLUSTER MEET messages to join the cluster
  59. Waiting for the cluster to join
  60. >>> Performing Cluster Check (using node 172.38.0.11:6379)
  61. M: a41efe0aab97aff316a6813121a85ef818a39376 172.38.0.11:6379
  62. slots:[0-5460] (5461 slots) master
  63. 1 additional replica(s)
  64. S: 1a5fb18ed3514c390bab6052514a874393c0c8e2 172.38.0.16:6379
  65. slots: (0 slots) slave
  66. replicates 1a31aa8f9f1ce41acfe41e30876e9efb480a7c94
  67. S: b7dab86ff429249b38fadc5502c733a99fd74c55 172.38.0.14:6379
  68. slots: (0 slots) slave
  69. replicates 0e7260e23e38aed13abbdb00f9d536b9d8842a07
  70. S: 483b8f7ad6578cd1e9f622954a73f1635ad83e0e 172.38.0.15:6379
  71. slots: (0 slots) slave
  72. replicates a41efe0aab97aff316a6813121a85ef818a39376
  73. M: 0e7260e23e38aed13abbdb00f9d536b9d8842a07 172.38.0.13:6379
  74. slots:[10923-16383] (5461 slots) master
  75. 1 additional replica(s)
  76. M: 1a31aa8f9f1ce41acfe41e30876e9efb480a7c94 172.38.0.12:6379
  77. slots:[5461-10922] (5462 slots) master
  78. 1 additional replica(s)
  79. [OK] All nodes agree about slots configuration.
  80. >>> Check for open slots...
  81. >>> Check slots coverage...
  82. [OK] All 16384 slots covered.
  83. # 测试集群
  84. /data # redis-cli -c
  85. 127.0.0.1:6379> cluster info # 集群信息
  86. 127.0.0.1:6379> cluster info # 集群节点

Spring Boot微服务打包 Docker镜像

1、构建 SpringBoot项目

2、打包应用

3、编写 dockerfile

  1. FROM java:8
  2. COPY *.jar /app.jar
  3. CMD ["--server.port=8080"]
  4. EXPOSE 8080
  5. ENTRYPOINT ["java","-jar","/app.jar"]

4、构建镜像

  1. [root@6b92d6 idea]# docker build -t 6b92d6 .

5、发布运行

  1. docker run -d -P --name 6b92d6-springboot-web 6b92d6
  2. curl localhost:端口号

Docker Compose

Docker swarm

CI/CD之 Jenkins