一、Docker入门 1.Docker为什么会出现
2.Docker的历史
3.Docker的学习
4.虚拟化技术和容器化技术对比 4.1.虚拟化技术的缺点
4.2容器化技术
比较Docker和虚拟化技术的不同
传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
容器内的应用直接运行在宿主机的内部,容器是没有自己的内核的,也没有虚拟硬件,所以轻便
每个容器间是相互隔离的,每个容器内都有一个属于自己的文件系统,互不影响
应用更快速的交互和部署
传统:一堆帮助文档,安装程序
Docker:打包镜像发布测试,一键运行
更便捷的升级和扩缩容
更简的系统运维
更高效的计算资源利用
4.3DevOps
DevOps(开发、运维)
应用更快速的交付和部署
传统:一堆帮助文档,安装程序
Docekr:打包镜像发布测试,一键运行
更便捷的升级和扩容
使用了Docker之后,我们部署应用就像搭积木一样!
项目打包为一个镜像,扩展 服务A!服务B
更简单的系统运维
在容器化之后,我们的开发,测试环境都是高度一致的。
更高效的计算资源利用
Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例!服务器的性能可以被压榨到极致。
5.名词解释
镜像(image)
Docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像 ===> run ===> tomcat01容器,通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)
容器(container)
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的
启动,停止,删除,基本命令!
就目前可以把这个容器理解为一个linux系统
仓库(repository)
存放镜像的地方
Dokcer Hub(默认是国外的)
阿里云…都有容器服务(配置镜像加速!)
6.环境准备 1、Linux内核要求3.0以上
2、CentOS 7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@iz2zeak7sgj6i7hrb2g862z ~] 3.10.0-514.26.2.el7.x86_64 [root@iz2zeak7sgj6i7hrb2g862z ~] NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7"
3、阿里云镜像加速
4、登录阿里云服务器,找到容器镜像服务
5、设置Registry登陆密码
6、找到镜像加速器
7、配置使用
1 2 3 4 5 6 7 8 9 10 11 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors" : ["https://pi9dpp60.mirror.aliyuncs.com" ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
7.安装Docker 卸载旧版本 较旧的Docker版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。
1 2 3 4 5 6 7 8 9 yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
安装Docker Engine-Community
安装yum-utils
1 2 yum install -y yum-utils
使用Docker仓库进行安装 在新主机上首次安装Docker Engine-Community之前,需要设置Docker仓库。之后,您可以从仓库安装和更新Docker。
设置仓库(上面安装yum-utils无法使用才进行这一步) 安装所需的软件包。yum-utils提供了yum-config-manager,并且device mapper存储驱动程序需要device-mapper-persistent-data和lvm2。
1 2 3 $ sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
使用一下命令来设置稳定的仓库。
使用官方源地址(比较慢)
1 2 3 4 5 yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
可以选择国内的一些源地址:
阿里云
1 2 3 4 yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
清华大学源
1 2 3 $ sudo yum-config-manager \ --add-repo \ https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
安装 Docker Engine-Community 安装最新版本的 Docker Engine-Community 和 containerd,或者转到下一步安装特地版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 yum makecache fast (Centos8不需要fast) yum install docker-ce docker-ce-cli containerd.io systemctl enable docker systemctl start docker docker version docker run hello-world docker images docker image prune -f 14.1、卸载依赖 yum remove docker-ce docker-ce-cli containerd.io 14.2、删除资源(/var/lib/docker 是docker的默认工作路径) rm -rf /var/lib/docker
Docker 安装完默认未启动,并且已经创建好了 docker 用户组,但该用户组下没有用户。
要特定安装版本的 Docker Engine-Community,请在存储库中列出可用版本,然后选择并安装: 1、列出并排序 您存储库中可用的版本。此示例按版本号(从高到低)对结果进行排序。
1 $ yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-stable docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-stable docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable docker-ce.x86_64 18.06.0.ce-3.el7 docker-ce-stable
2、通过其完整的软件包名称安装特定版本,改软件包名称是软件包名称(docker-ce)加上版本字符串(第二列),从第一个冒号(:)一直到第一个连字符(-)分隔。例如: docker-ce-18.09.1。
1 $ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
启动 Docker
1 $ sudo systemctl start docker
通过运行 hello-world 映像来验证是否正确安装了 Docker Engine-Community。
1 $ sudo docker run hello-world
8.底层原理
Docker 是一个 Client Server 的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。 容器,是一个运行时环境就是我们所说的集装箱。
为什么 Docker 比 vm 快
docker 有着比虚拟机更少的抽象层,由于 docker 不需要 Hypervisor 实现硬件资源虚拟化,运行在 docker 容器上的程序直接使用的都是实际物理机的硬件资源。因此在 CPU、内存利用率上 docker 将会在效率上有明显优势
docker 利用的是宿主机的内核,而不需要 Guest OS 。因此,当新建一个容器时,docker 不需要和虚拟机一样重新加载一个操作系统内核。从而避免引寻、加载操作系统内核是个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载 GuestOS,这个新建过程是分钟级别的,而 docker 由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个 docker 容器只需要几秒钟。
二、Docker 基本命令 1.Docker 的常用命令
帮助命令
1 2 3 docker version docker info docker 命令 --help
镜像命令 docker images 查看所有本地主机上的镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest bf756fb1ae65 7 months ago 13.3kB REPOSITORY TAG IMAGE ID CREATED SIZE --all , -a --quiet , -q docker images -a docker images -aq
dcoker serach 查找镜像
1 2 3 4 5 6 7 8 9 10 11 12 NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 9822 [OK] mariadb MariaDB is a community-developed fork of MyS… 3586 [OK] mysql/mysql-server Optimized MySQL Server Docker images. Create… 719 [OK] --filter=STARS=3000 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 9822 [OK] mariadb MariaDB is a community-developed fork of MyS… 3586
docker pull 下拉镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] Using default tag: latest latest: Pulling from library/mysql bf5952930446: Pull complete 8254623a9871: Pull complete 938e3e06dac4: Pull complete ea28ebf28884: Pull complete f3cef38785c2: Pull complete 894f9792565a: Pull complete 1d8a57523420: Pull complete 6c676912929f: Pull complete ff39fdb566b4: Pull complete fff872988aba: Pull complete 4d34e365ae68: Pull complete 7886ee20621e: Pull complete Digest: sha256:c358e72e100ab493a0304bda35e6f239db2ec8c9bb836d8a427ac34307d074ed Status: Downloaded newer image for mysql:latest docker.io/library/mysql:latest docker pull mysql docker pull docker.io/library/mysql:latest [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] 5.7: Pulling from library/mysql bf5952930446: Already exists 8254623a9871: Already exists 938e3e06dac4: Already exists ea28ebf28884: Already exists f3cef38785c2: Already exists 894f9792565a: Already exists 1d8a57523420: Already exists 5f09bf1d31c1: Pull complete 1b6ff254abe7: Pull complete 74310a0bf42d: Pull complete d398726627fd: Pull complete Digest: sha256:da58f943b94721d46e87d5de208dc07302a8b13e638cd1d24285d222376d6d84 Status: Downloaded newer image for mysql:5.7 docker.io/library/mysql:5.7 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] REPOSITORY TAG IMAGE ID CREATED SIZE mysql 5.7 718a6da099d8 6 days ago 448MB mysql latest 0d64f46acfd1 6 days ago 544MB hello-world latest bf756fb1ae65 7 months ago 13.3kB
docker rmi 删除镜像
1 2 3 4 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]
容器命令 说明:我们有了镜像才可以创建容器,Linux,下载一个 centos 镜像来测试学习
新建容器并启动给
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 docker run [可选参数] image --name=“Name” 容器名字 tomcat01 tomcat02 用来区分容器 -d 后台方式运行 -it 使用交互方式运行,进入容器查看内容 -p 指定容器的端口 -p 8080:8080 -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 容器端口 -p 随机指定端口 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] [root@74e82b7980e7 /] bin etc lib lost+found mnt proc run srv tmp var dev home lib64 media opt root sbin sys usr [root@77969f5dcbf9 /] exit [root@iZ2zeg4ytp0whqtmxbsqiiZ /] bin dev fanfan lib lost+found mnt proc run srv tmp var boot etc home lib64 media opt root sbin sys usr
列出所有的运行的容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 -a -n=? -q [root@iZ2zeg4ytp0whqtmxbsqiiZ /] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@iZ2zeg4ytp0whqtmxbsqiiZ /] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 77969f5dcbf9 centos "/bin/bash" 5 minutes ago Exited (0) 5 minutes ago xenodochial_bose 74e82b7980e7 centos "/bin/bash" 16 minutes ago Exited (0) 6 minutes ago silly_cori a57250395804 bf756fb1ae65 "/hello" 7 hours ago Exited (0) 7 hours ago elated_nash 392d674f4f18 bf756fb1ae65 "/hello" 8 hours ago Exited (0) 8 hours ago distracted_mcnulty 571d1bc0e8e8 bf756fb1ae65 "/hello" 23 hours ago Exited (0) 23 hours ago magical_burnell [root@iZ2zeg4ytp0whqtmxbsqiiZ /] 77969f5dcbf9 74e82b7980e7 a57250395804 392d674f4f18 571d1bc0e8e8
退出容器
删除容器
1 2 3 docker rm -f 容器id docker rm -f $(docker ps -aq) docker ps -a -q|xargs docker rm -f
启动和停止容器的操作
1 2 3 4 docker start 容器id docker restart 容器id docker stop 容器id docker kill 容器id
常用的其他命令 后台启动容器
1 2 3 4 5 6 7 [root@iZ2zeg4ytp0whqtmxbsqiiZ /]
查看日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 docker logs --help Options: --details Show extra details provided to logs * -f, --follow Follow log output --since string Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes) * --tail string Number of lines to show from the end of the logs (default "all" ) * -t, --timestamps Show timestamps --until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes) docker logs -tf --tail number 容器id [root@iZ2zeg4ytp0whqtmxbsqiiZ /] 2020-08-11T10:53:15.987702897Z [root@8d1621e09bff /] [root@iZ2zeg4ytp0whqtmxbsqiiZ /] a0d580a21251da97bc050763cf2d5692a455c228fa2a711c3609872008e654c2 [root@iZ2zeg4ytp0whqtmxbsqiiZ /] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a0d580a21251 centos "/bin/sh -c 'while t…" 3 seconds ago Up 1 second lucid_black -tf --tail number docker logs -t --tail n 容器id docker logs -ft 容器id [root@iZ2zeg4ytp0whqtmxbsqiiZ /]
查看容器中进程信息
1 2 3 4 [root@iZ2zeg4ytp0whqtmxbsqiiZ /] UID PID PPID C STIME TTY root 28498 28482 0 19:38 ?
查看镜像的元数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 docker inspect 容器id [root@iZ2zeg4ytp0whqtmxbsqiiZ /] [ { "Id" : "df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3" , "Created" : "2020-08-11T11:38:34.935048603Z" , "Path" : "/bin/bash" , "Args" : [], "State" : { "Status" : "running" , "Running" : true , "Paused" : false , "Restarting" : false , "OOMKilled" : false , "Dead" : false , "Pid" : 28498, "ExitCode" : 0, "Error" : "" , "StartedAt" : "2020-08-11T11:38:35.216616071Z" , "FinishedAt" : "0001-01-01T00:00:00Z" }, "Image" : "sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566" , "ResolvConfPath" : "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/resolv.conf" , "HostnamePath" : "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/hostname" , "HostsPath" : "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/hosts" , "LogPath" : "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3-json.log" , "Name" : "/hungry_heisenberg" , "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, "Capabilities" : null, "Dns" : [], "DnsOptions" : [], "DnsSearch" : [], "ExtraHosts" : null, "GroupAdd" : null, "IpcMode" : "private" , "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, "DeviceRequests" : null, "KernelMemory" : 0, "KernelMemoryTCP" : 0, "MemoryReservation" : 0, "MemorySwap" : 0, "MemorySwappiness" : null, "OomKillDisable" : false , "PidsLimit" : null, "Ulimits" : null, "CpuCount" : 0, "CpuPercent" : 0, "IOMaximumIOps" : 0, "IOMaximumBandwidth" : 0, "MaskedPaths" : [ "/proc/asound" , "/proc/acpi" , "/proc/kcore" , "/proc/keys" , "/proc/latency_stats" , "/proc/timer_list" , "/proc/timer_stats" , "/proc/sched_debug" , "/proc/scsi" , "/sys/firmware" ], "ReadonlyPaths" : [ "/proc/bus" , "/proc/fs" , "/proc/irq" , "/proc/sys" , "/proc/sysrq-trigger" ] }, "GraphDriver" : { "Data" : { "LowerDir" : "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360-init/diff:/var/lib/docker/overlay2/62926d498bd9d1a6684bb2f9920fb77a2f88896098e66ef93c4b74fcb19f29b6/diff" , "MergedDir" : "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/merged" , "UpperDir" : "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/diff" , "WorkDir" : "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/work" }, "Name" : "overlay2" }, "Mounts" : [], "Config" : { "Hostname" : "df358bc06b17" , "Domainname" : "" , "User" : "" , "AttachStdin" : true , "AttachStdout" : true , "AttachStderr" : true , "Tty" : true , "OpenStdin" : true , "StdinOnce" : true , "Env" : [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd" : [ "/bin/bash" ], "Image" : "centos" , "Volumes" : null, "WorkingDir" : "" , "Entrypoint" : null, "OnBuild" : null, "Labels" : { "org.label-schema.build-date" : "20200809" , "org.label-schema.license" : "GPLv2" , "org.label-schema.name" : "CentOS Base Image" , "org.label-schema.schema-version" : "1.0" , "org.label-schema.vendor" : "CentOS" } }, "NetworkSettings" : { "Bridge" : "" , "SandboxID" : "4822f9ac2058e8415ebefbfa73f05424fe20cc8280a5720ad3708fa6e80cdb08" , "HairpinMode" : false , "LinkLocalIPv6Address" : "" , "LinkLocalIPv6PrefixLen" : 0, "Ports" : {}, "SandboxKey" : "/var/run/docker/netns/4822f9ac2058" , "SecondaryIPAddresses" : null, "SecondaryIPv6Addresses" : null, "EndpointID" : "5fd269c0a28227241e40cd30658e3ffe8ad6cc3e6514917c867d89d36a31d605" , "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" : "30d6017888627cb565618b1639fecf8fc97e1ae4df5a9fd5ddb046d8fb02b565" , "EndpointID" : "5fd269c0a28227241e40cd30658e3ffe8ad6cc3e6514917c867d89d36a31d605" , "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 } } } } ]
进入当前正在运行的容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 docker exec -it 容器id /bin/bash [root@iZ2zeg4ytp0whqtmxbsqiiZ /] [root@df358bc06b17 /] bin etc lib lost+found mnt proc run srv tmp var dev home lib64 media opt root sbin sys usr [root@df358bc06b17 /] UID PID PPID C STIME TTY TIME CMD root 1 0 0 Aug11 pts/0 00:00:00 /bin/bash root 29 0 0 01:06 pts/1 00:00:00 /bin/bash root 43 29 0 01:06 pts/1 00:00:00 ps -ef docker attach 容器id
从容器中拷贝文件到主机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 docker cp 容器id :容器内路径 目的地主机路径 [root@iZ2zeg4ytp0whqtmxbsqiiZ /] [root@iz2zeak7sgj6i7hrb2g862z ~] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 56a5583b25b4 centos "/bin/bash" 7seconds ago Up 6 seconds [root@iz2zeak7sgj6i7hrb2g862z ~] [root@55321bcae33d /] bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@55321bcae33d /] [root@55321bcae33d /] hello [root@55321bcae33d /] exit [root@iz2zeak7sgj6i7hrb2g862z /] [root@iz2zeak7sgj6i7hrb2g862z /] [root@iz2zeak7sgj6i7hrb2g862z home] total 8 -rw-r--r-- 1 root root 0 May 19 22:09 haust.java -rw-r--r-- 1 root root 6 May 22 11:12 java.java drwx------ 3 www www 4096 May 8 12:14 www
小结
命令大全
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 attach Attach local standard input, output, and error streams to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes #提交当前容器为新的镜像 cp Copy files/folders between a container and the local filesystem #拷贝文件 create Create a new container #创建一个新的容器 diff Inspect changes to files or directories on a container' s filesystem events Get real time events from the server exec Run a command in a running container export Export a container's filesystem as a tar archive #导出容器文件系统作为一个tar归档文件[对应import] history Show the history of an image # 展示一个镜像形成历史 images List images #列出系统当前的镜像 import Import the contents from a tarball to create a filesystem image #从tar包中导入内容创建一个文件系统镜像 info Display system-wide information # 显示全系统信息 inspect Return low-level information on Docker objects #查看容器详细信息 kill Kill one or more running containers # kill指定docker容器 load Load an image from a tar archive or STDIN #从一个tar包或标准输入中加载一个镜像[对应save] login Log in to a Docker registry # logout Log out from a Docker registry logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container ps List containers pull Pull an image or a repository from a registry push Push an image or a repository to a registry rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save one or more images to a tar archive (streamed to STDOUT by default) search Search the Docker Hub for images start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers version Show the Docker version information wait Block until one or more containers stop, then print their exit codes
三、Docker部署软件实战 1.Docker部署软件实战 Docker安装Nginx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 [root@iz2zeak7sgj6i7hrb2g862z ~] [root@iz2zeak7sgj6i7hrb2g862z ~] [root@iz2zeak7sgj6i7hrb2g862z ~] [root@iz2zeak7sgj6i7hrb2g862z ~] aa664b0c8ed98f532453ce1c599be823bcc1f3c9209e5078615af416ccb454c2 [root@iz2zeak7sgj6i7hrb2g862z ~] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 75943663c116 nginx "nginx -g 'daemon of…" 41 seconds ago Up 40 seconds 0.0.0.0:82->80/tcp nginx00 [root@iz2zeak7sgj6i7hrb2g862z ~] root@aa664b0c8ed9:/ nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx root@aa664b0c8ed9:/ root@aa664b0c8ed9:/etc/nginx conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf root@aa664b0c8ed9:/etc/nginx exit [root@iz2zeak7sgj6i7hrb2g862z ~] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES aa664b0c8ed9 nginx "nginx -g 'daemon of…" 10 minutes ago Up 10 minutes 0.0.0.0:3344->80/tcp nginx01 [root@iz2zeak7sgj6i7hrb2g862z ~] [root@iZ2zeg4ytp0whqtmxbsqiiZ home] REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 0d120b6ccaa8 32 hours ago 215MB nginx latest 08393e824c32 7 days ago 132MB [root@iZ2zeg4ytp0whqtmxbsqiiZ home] fe9dc33a83294b1b240b1ebb0db9cb16bda880737db2c8a5c0a512fc819850e0 [root@iZ2zeg4ytp0whqtmxbsqiiZ home] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fe9dc33a8329 nginx "/docker-entrypoint.…" 4 seconds ago Up 4 seconds 0.0.0.0:3344->80/tcp nginx01 [root@iZ2zeg4ytp0whqtmxbsqiiZ home] [root@iZ2zeg4ytp0whqtmxbsqiiZ home] root@fe9dc33a8329:/ nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx root@fe9dc33a8329:/ root@fe9dc33a8329:/etc/nginx conf.d koi-utf mime.types nginx.conf uwsgi_params fastcgi_params koi-win modules scgi_params win-utf
端口暴露概念
2.Docker安装Tomcat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 [root@iz2zeak7sgj6i7hrb2g862z ~] --rm Automatically remove the container when it exits 用完即删 [root@iz2zeak7sgj6i7hrb2g862z ~] [root@iz2zeak7sgj6i7hrb2g862z ~] [root@iz2zeak7sgj6i7hrb2g862z ~] curl localhost:8080 [root@iz2zeak7sgj6i7hrb2g862z ~] root@645596565d3f:/usr/local/tomcat root@645596565d3f:/usr/local/tomcat total 152 -rw-r--r-- 1 root root 18982 May 5 20:40 BUILDING.txt -rw-r--r-- 1 root root 5409 May 5 20:40 CONTRIBUTING.md -rw-r--r-- 1 root root 57092 May 5 20:40 LICENSE -rw-r--r-- 1 root root 2333 May 5 20:40 NOTICE -rw-r--r-- 1 root root 3255 May 5 20:40 README.md -rw-r--r-- 1 root root 6898 May 5 20:40 RELEASE-NOTES -rw-r--r-- 1 root root 16262 May 5 20:40 RUNNING.txt drwxr-xr-x 2 root root 4096 May 16 12:05 bin drwxr-xr-x 1 root root 4096 May 21 11:04 conf drwxr-xr-x 2 root root 4096 May 16 12:05 lib drwxrwxrwx 1 root root 4096 May 21 11:04 logs drwxr-xr-x 2 root root 4096 May 16 12:05 native-jni-lib drwxrwxrwx 2 root root 4096 May 16 12:05 temp drwxr-xr-x 2 root root 4096 May 16 12:05 webapps drwxr-xr-x 7 root root 4096 May 5 20:37 webapps.dist drwxrwxrwx 2 root root 4096 May 5 20:36 work root@645596565d3f:/usr/local/tomcat root@645596565d3f:/usr/local/tomcat root@645596565d3f:/usr/local/tomcat/webapps root@645596565d3f:/usr/local/tomcat/webapps root@645596565d3f:/usr/local/tomcat BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work root@645596565d3f:/usr/local/tomcat root@645596565d3f:/usr/local/tomcat/webapps.dist ROOT docs examples host-manager manager root@645596565d3f:/usr/local/tomcat/webapps.dist root@645596565d3f:/usr/local/tomcat root@645596565d3f:/usr/local/tomcat root@645596565d3f:/usr/local/tomcat/webapps ROOT docs examples host-manager manager docker run -it --rm tomcat:9.0 docker pull tomcat docker run -d -p 3344:8080 --name tomcat01 tomcat docker exec -it tomcat01 /bin/bash
这样 docker 部署 tomcat 就可以访问了
问题:我们以后要部署项目,如果每次都要进入容器是不是十分麻烦?要是可以在容器外部提供一个映射路径,比如webapps,我们在外部放置项目,就自动同步内部就好了!
3.Docker 部署 elasticsearch + kibana 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 [root@ihome] a920894a940b354d3c867079efada13d96cf9138712c76c8dea58fabd9c7e96f [root@i] [root@iZ2zeg4ytp0whqtmxbsqiiZ home] { "name" : "a920894a940b" , "cluster_name" : "docker-cluster" , "cluster_uuid" : "bxE1TJMEThKgwmk7Aa3fHQ" , "version" : { "number" : "7.6.2" , "build_flavor" : "default" , "build_type" : "docker" , "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f" , "build_date" : "2020-03-26T06:34:37.794943Z" , "build_snapshot" : false , "lucene_version" : "8.4.0" , "minimum_wire_compatibility_version" : "6.8.0" , "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } [root@iz2zeak7sgj6i7hrb2g862z ~] docker rm -f d73ad2f22dd3 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
作业三:使用 kibana 连接 es (elasticSearch)?思考网路如何才能连接
Portainer 可视化面板安装
1 2 docker run -d -p 8080:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Rancher(CI/CD再用)
什么是portainer
Docker 图形化界面管理工具!提供一个后台面板供我们操作
1 2 3 4 5 6 7 8 9 10 [root@iz2zeak7sgj6i7hrb2g862z ~] --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer Unable to find image 'portainer/portainer:latest' locally latest: Pulling from portainer/portainer d1e017099d17: Pull complete a7dca5b5a9e8: Pull complete Digest: sha256:4ae7f14330b56ffc8728e63d355bc4bc7381417fa45ba0597e5dd32682901080 Status: Downloaded newer image for portainer/portainer:latest 81753869c4fd438cec0e31659cbed0d112ad22bbcfcb9605483b126ee8ff306d
测试访问: 外网:8080 :http://123.56.247.59:8080/
进入面板之后
四、Docker 原理 镜像原理之联合文件系统 镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。
所有应用,直接打包 docker 镜像,就可以直接跑起来!
如何得到镜像
从远程仓库下载
别人拷贝给你
自己制作一个镜像 Dockerfile
Docker 镜像加载原理
UnionFs(联合文件系统)
UnionFs (联合文件系统):Union 文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite serveral directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分成来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合记载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
docker 镜像加载原理
docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
boots(boot file system)主要包含 bootloade 和 Kernel,bootloade主要是引导加载 kernel,Linux刚启动时会加载 bootfs 文件系统,在 Docker 镜像的最底层是 boots。这一层与我们典型的 Linux/Unix 系统是一样的,包含 boot 加载器和内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。
rootfs (root file sysytem),在 bootfs 之上。包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如 Ubuntu,CentOS 等等。
平时我们安装进虚拟机的 CentOS 都是好几个G,为什么 Docker 这里才200M?
对于精简的 OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用 Host 的 kernel,自己只需要提供 rootfs 就可以了。由此可见对于不同的 Linux 发行版,bootfs 基本是一致的,rootfs 会有差别,因此不同的发行版可以公用 bootfs。
虚拟机是分钟级别的,容器是秒级!
分层理解
分层镜像
我们可以去下一个镜像,注意观察下载的日志输出,可以看到的是一层层的在下载
思考:为什么 Docker 镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于资源共享了!比如有多个镜像都是从相同的 Base 镜像构建而来,那么宿主机只需在磁盘上保留一份 base 镜像,同时内存中也只需要加载一份 base 镜像,同时内存中也只需要加载一份 base 镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。查看镜像分层的方式可以通过 docker image inspect 命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 docker image inspect redis [ { "Id" : "sha256:f9b9909726890b00d2098081642edf32e5211b7ab53563929a47f250bcdc1d7c" ,"RepoTags" : ["redis:latest" ], "RepoDigests" : ["redis@sha256:399a9b17b8522e24fbe2fd3b42474d4bb668d3994153c4b5d38c3dafd5903e32" ], "Parent" : "" ,"Comment" : "" ,"Created" : "2020-05-02T01:40:19.112130797Z" ,"Container" : "d30c0bcea88561bc5139821227d2199bb027eeba9083f90c701891b4affce3bc" ,"ContainerConfig" : {"Hostname" : "d30c0bcea885" ,"Domainname" : "" ,"User" : "" ,"AttachStdin" : false ,"AttachStdout" : false ,"AttachStderr" : false ,"ExposedPorts" : {"6379/tcp" : {} }, "Tty" : false ,"OpenStdin" : false ,"StdinOnce" : false ,"Env" : ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ,"GOSU_VERSION=1.12" ,"REDIS_VERSION=6.0.1" ,"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.1.tar.gz" ,"REDIS_DOWNLOAD_SHA=b8756e430479edc162ba9c44dc89ac394316cd482f2dc6b91bcd5fe12593f273" ], "Cmd" : ["/bin/sh" ,"-c" ,"#(nop) " ,"CMD [\"redis-server\"]" ], "ArgsEscaped" : true ,"Image" : "sha256:704c602fa36f41a6d2d08e49bd2319ccd6915418f545c838416318b3c29811e0" ,"Volumes" : {"/data" : {} }, "WorkingDir" : "/data" ,"Entrypoint" : ["docker-entrypoint.sh" ], "OnBuild" : null,"Labels" : {} }, "DockerVersion" : "18.09.7" ,"Author" : "" ,"Config" : {"Hostname" : "" ,"Domainname" : "" ,"User" : "" ,"AttachStdin" : false ,"AttachStdout" : false ,"AttachStderr" : false ,"ExposedPorts" : {"6379/tcp" : {} }, "Tty" : false ,"OpenStdin" : false ,"StdinOnce" : false ,"Env" : ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ,"GOSU_VERSION=1.12" ,"REDIS_VERSION=6.0.1" ,"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.1.tar.gz" ,"REDIS_DOWNLOAD_SHA=b8756e430479edc162ba9c44dc89ac394316cd482f2dc6b91bcd5fe12593f273" ], "Cmd" : ["redis-server" ], "ArgsEscaped" : true ,"Image" : "sha256:704c602fa36f41a6d2d08e49bd2319ccd6915418f545c838416318b3c29811e0" ,"Volumes" : {"/data" : {} }, "WorkingDir" : "/data" ,"Entrypoint" : ["docker-entrypoint.sh" ], "OnBuild" : null,"Labels" : null}, "Architecture" : "amd64" ,"Os" : "linux" ,"Size" : 104101893,"VirtualSize" : 104101893,"GraphDriver" : {"Data" : {"LowerDir" : "/var/lib/docker/overlay2/adea96bbe6518657dc2d4c6331a807eea70567144abda686588ef6c3bb0d778a/diff:/var/lib/docker/overlay2/66abd822d34dc6446e6bebe73721dfd1dc497c2c8063c43ffb8cf8140e2caeb6/diff:/var/lib/docker/overlay2/d19d24fb6a24801c5fa639c1d979d19f3f17196b3c6dde96d3b69cd2ad07ba8a/diff:/var/lib/docker/overlay2/a1e95aae5e09ca6df4f71b542c86c677b884f5280c1d3e3a1111b13644b221f9/diff:/var/lib/docker/overlay2/cd90f7a9cd0227c1db29ea992e889e4e6af057d9ab2835dd18a67a019c18bab4/diff" ,"MergedDir" : "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/merged" ,"UpperDir" : "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/diff" ,"WorkDir" : "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/work" }, "Name" : "overlay2" }, "RootFS" : {"Type" : "layers" ,"Layers" : ["sha256:c2adabaecedbda0af72b153c6499a0555f3a769d52370469d8f6bd6328af9b13" ,"sha256:744315296a49be711c312dfa1b3a80516116f78c437367ff0bc678da1123e990" ,"sha256:379ef5d5cb402a5538413d7285b21aa58a560882d15f1f553f7868dc4b66afa8" ,"sha256:d00fd460effb7b066760f97447c071492d471c5176d05b8af1751806a1f905f8" ,"sha256:4d0c196331523cfed7bf5bafd616ecb3855256838d850b6f3d5fba911f6c4123" ,"sha256:98b4a6242af2536383425ba2d6de033a510e049d9ca07ff501b95052da76e894" ] }, "Metadata" : {"LastTagTime" : "0001-01-01T00:00:00Z" } } ]
理解:
所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu Linux16.04 创建一个新的镜像,这就是镜像的第一层;如果在该镜像中添加 python 包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层,该镜像当前已经包含三个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在额外添加镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点。
在额外添加镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含了来自两个镜像层的6个问文件。
上图的镜像层跟之前途中的略有区别,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样使得文件的更新版本作为以恶新镜像添加到镜像当中
Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像曾对外展示为统一的文件系统
Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储引擎都是基于 Linux中对应的文件系统或者块设备技术,并且每种存储引擎都是具有其独有的性能特点。
Docker 在 windows 上仅支持 Windowsfilter 一种存储引擎,该引擎基于 NTFS 文件系统之上实现了分层和CoW。
下图展示了与系统显示相同的三层镜像。所有镜像层堆栈合并,对外提供统一的视图。
特点
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫做镜像层
1 2 3 4 5 6 docker commit 提交容器成为一个新的副本 docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[版本TAG] docker commit -a="xiaofan" -m="add webapps app" d798a5946c1f tomcat007:1.0
实战测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 docker run -d -p 8080:8080 tomcat docker exec -it de57d0ace571 /bin/bash cp -r webapps.dist/* webappscd webappsls docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG] docker commit -a="kuangshen" -m="add webapps app" 容器id tomcat02:1.0 docker commit -a="csp提交的" -m="add webapps app" de57d0ace571 tomcat02.1.0
如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们使用虚拟机的快照。
五、容器数据卷 1.容器数据卷 1.1.docker 的理解回顾 什么是数据容器卷
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们删除容器,数据就会丢失!需求:数据可以持久化
MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享技术!Docker 容器中产生的数据,同步到本地!
这就是卷技术,目录的挂载,将我们容器内的目录挂载到 Linux 目录上面!
总结一句话:容器的持久化和同步操作!容器间也可以数据共享的!
1.2.使用数据卷
方式一:直接使用命令来挂载 -v
1 2 3 4 5 6 7 8 9 docker run -it -v 主机目录:容器内目录 -p 主机端口:容器内端口 [root@iz2zeak7 home] [root@iz2zeak7sgj6i7hrb2g862z home]
测试文件的同步 (在主机上改动,观察容器变化)
再来测试 (测试通过)
停止容器
主机上修改文件
启动容器
容器内的数据依旧是同步的!
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
1.3.实战:安装 MySQL 思考:MySQL 的数据持久化问题!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@iZ2zeg4ytp0whqtmxbsqiiZ home] docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag -d -p -v -e --name [root@i home] 9552bf4eb2b69a2ccd344b5ba5965da4d97b19f2e1a78626ac1f2f8d276fc2ba
测试连接: 注意3310端口要在阿里云服务器的安全组中打开,否则无法连接。
当我们在本地用 Navicat 新建名称为 test 的数据库时,容器也会创建
假设我们将包含 mysql 的容器删除时
发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能
1.4.匿名和具名挂载 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 -v 容器内路径 docker run -d -P --name nginx01 -v /etc/nginx nginx [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] DRIVER VOLUME NAME local 561b81a03506f31d45ada3f9fb7bd8d7c9b5e0f826c877221a17e45d4c80e096local 36083fb6ca083005094cbd49572a0bffeec6daadfbc5ce772909bb00be760882 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] 26da1ec7d4994c76e80134d24d82403a254a4e1d84ec65d5f286000105c3da17 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 26da1ec7d499 nginx "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:32769->80/tcp nginx02 486de1da03cb nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 0.0.0.0:32768->80/tcp nginx01 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] DRIVER VOLUME NAME local 561b81a03506f31d45ada3f9fb7bd8d7c9b5e0f826c877221a17e45d4c80e096local 36083fb6ca083005094cbd49572a0bffeec6daadfbc5ce772909bb00be760882local juming-nginx [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] [ { "CreatedAt" : "2020-08-12T18:15:21+08:00" , "Driver" : "local" , "Labels" : null, "Mountpoint" : "/var/lib/docker/volumes/juming-nginx/_data" , "Name" : "juming-nginx" , "Options" : null, "Scope" : "local" } ]
所有 Docker 容器内的卷,没有指定目录的情况下都是在**/var/lib/docker/volumes/自定义的卷名/_data下,
如果指定了目录,docker volume ls 是查看不到的
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用的是具名挂载
区分三种挂载方式
1 2 3 4 -v 容器内路径 -v 卷名:容器内路径 -v /宿主机路径:容器内路径
拓展
1 2 3 4 5 6 7 8 ro readonly rw readwrite docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
六、Dockerfile 初始 Dockerfile Dockerfile 就是用来构建docker镜像的构建文件!命令脚本!先体验一下!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 $ vim dockerfile1 FROM centos VOLUME ["volume01" ,"volume02" ] CMD echo "-----end-----" CMD /bin/bash -f dockerfile1 -t caoshipeng/centos . $ docker build -f dockerfile1 -t caoshipeng/centos . Sending build context to Docker daemon 2.56kB Step 1/4 : FROM centos latest: Pulling from library/centos 8a29a15cefae: Already exists Digest: sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700 Status: Downloaded newer image for centos:latest ---> 470671670cac Step 2/4 : VOLUME ["volume01" ,"volume02" ] ---> Running in c18eefc2c233 Removing intermediate container c18eefc2c233 ---> 623ae1d40fb8 Step 3/4 : CMD echo "-----end-----" ---> Running in 70e403669f3c Removing intermediate container 70e403669f3c ---> 0eba1989c4e6 Step 4/4 : CMD /bin/bash ---> Running in 4342feb3a05b Removing intermediate container 4342feb3a05b ---> f4a6b0d4d948 Successfully built f4a6b0d4d948 Successfully tagged caoshipeng/centos:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE caoshipeng/centos latest f4a6b0d4d948 About a minute ago 237MB
1 2 3 4 $ docker run -it f4a6b0d4d948 /bin/bash $ ls -l
这个卷和外部一定有一个同步的目录!
查看一个卷挂载
1 2 $ docker inspect ca3b45913df5
测试一下刚才的文件是否同步到主机上了!
这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!
数据卷容器 多个 mysql 同步数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $ docker run -it --name docker01 caoshipeng/centos:latest $ ls bin home lost+found opt run sys var dev lib media proc sbin tmp volume01 etc lib64 mnt root srv usr volume02 CTRL + Q + P $ docker run -it --name docker02 --volumes-from docker01 caoshipeng/centos:latest $ ls bin home lost+found opt run sys var dev lib media proc sbin tmp volume01 etc lib64 mnt root srv usr volume02
1 2 3 4 5 6 7 $ docker run -it --name docker03 --volumes-from docker01 caoshipeng/centos:latest $ cd volume01 $ ls docker01.txt
多个 mysql 实现数据共享
1 2 3 $ docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 $ docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
结论
容器之间配置信息的传递,数据卷容器的声明周期一直持续到没用容器使用为止。但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
Dockerfile dockerfile 是用来构建 Docker 镜像的文件!命令参数脚本!
构建步骤:
编写一个 dockerfile 文件
docker build 构建成为一个镜像
docker run 运行镜像
docker push 发布镜像 (DockerHub、阿里云镜像)
查看官方是怎么做的
点击跳到一个 dockerfile
很多官方镜像都只是基础包,很多功能不具备,我们通常会搭建自己的镜像!
官方既然可以制作镜像,我们一样可以!
DockerFile 的构建过程 基础知识:
每个保留关键字(指令)必须都是大写字母
执行从上到下的顺序执行
#表示注释
每个指令都会创建提交一个新的镜像层,并提交!
dockerFile 是面向开发的,我们以后要发布项目,做镜像,就需要编写 dockerfile 文件,这个文件十分简单!
Docker 镜像逐渐成为企业的交互标准,必须要掌握!
步骤:开发,部署,运维……缺一不可!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages: 通过 DockerFile 构建生成的镜像,最终发布和运行的产品!
Docker 容器:容器就是镜像并运行起来提供服务器
1 2 3 4 5 6 7 8 9 10 11 12 FROM MAINTAINER RUN ADD WORKDIR VOLUME EXPOSE CMD ENTRYPOINT ONBUILD COPY ENV
DockerFile 指令说明
实战测试
scratch 镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 FROM scratch ADD centos-7-x86_64-docker.tar.xz / LABEL \ org.label-schema.schema-version="1.0" \ org.label-schema.name="CentOS Base Image" \ org.label-schema.vendor="CentOS" \ org.label-schema.license="GPLv2" \ org.label-schema.build-date="20200504" \ org.opencontainers.image.title="CentOS Base Image" \ org.opencontainers.image.vendor="CentOS" \ org.opencontainers.image.licenses="GPL-2.0-only" \ org.opencontainers.image.created="2020-05-04 00:00:00+01:00" CMD ["/bin/bash" ]
Docker Hub 中 99%的镜像都是从这个基础镜像过来的 FROM scratch ,然后配置需要的软件和配置来进行构建。
创建一个自己的CentOS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $ mkdir dockerfile $ vim mydockerfile-centos FROM centos MAINTAINER cao<196655494@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "-----end----" CMD /bin/bash $ docker build -f mydockerfile-centos -t mycentos:0.1 .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 0.1 cbf5110a646d 2 minutes ago 311MB $ docker run -it mycentos:0.1 $ pwd /usr/local $ vim $ ifconfig $ docker history 镜像id $ docker history --no-trunc 镜像:tag
我们可以列出本地进行的变更历史
我们平时拿到一个镜像,可以用 “docker history 镜像id” 研究一下是什么做的
CMD 和 ENTRYPOINT 区别
测试CMD
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $ vim dockerfile-test-cmd FROM centos CMD ["ls" ,"-a" ] $ docker build -f dockerfile-test-cmd -t cmd-test:0.1 . $ docker run cmd-test:0.1 . .. .dockerenv bin dev etc home $ docker run cmd-test:0.1 -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH " : unknown.ERRO[0000] error waiting for container: context canceled
测试ENTRYPOINT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 $ vim dockerfile-test-entrypoint FROM centos ENTRYPOINT ["ls" ,"-a" ] $ docker build -f dockerfile-test-entrypoint -t cmd-test:0.1 . $ docker run entrypoint-test:0.1 . .. .dockerenv bin dev etc home lib lib64 lost+found ... $ docker run entrypoint-test:0.1 -l total 56 drwxr-xr-x 1 root root 4096 May 16 06:32 . drwxr-xr-x 1 root root 4096 May 16 06:32 .. -rwxr-xr-x 1 root root 0 May 16 06:32 .dockerenv lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin drwxr-xr-x 5 root root 340 May 16 06:32 dev drwxr-xr-x 1 root root 4096 May 16 06:32 etc drwxr-xr-x 2 root root 4096 May 11 2019 home lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64 ....
Dockerfile中很多命令都十分的相似,我们需要了解它们的区别,我们最好的学习就是对比他们然后测试效果!
七、DockerFile 制作 tomcat 镜像 DockerFile 制作 tomcat 镜像
准备镜像文件 tomcat 文件压缩包,jdk 的压缩包到当前目录,编写好README!
编写 Dockerfile 文件,官方命名 Dockerfile,build 会自动寻找这个文件,就不需要 -f 指定了!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ vim dockerfile FROM centos MAINTAINER cao<1165680007@qq.com> COPY README /usr/local/README ADD jdk-8u231-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.35.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_231 ENV CLASSPATH $JAVA_HOME /lib/dt.jar:$JAVA_HOME /lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.35 ENV PATH $PATH :$JAVA_HOME /bin:$CATALINA_HOME /lib:$CATALINA_HOME /bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/logs/catalina.out
构建镜像
1 2 $ docker build -t mytomcat:0.1 .
启动镜像
1 2 3 4 $ docker run -d -p 8080:8080 --name tomcat01 -v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs mytomcat:0.1
访问测试
1 2 $ docker exec -it 自定义容器的id /bin/bash $ cul localhost:8080
发布项目(由于做了卷挂载,直接在本地编写项目就可以发布了)
在本地编写web.xml和index.jsp进行测试
1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="UTF-8" ?> <web-app version ="2.4" xmlns ="http://java.sun.com/xml/ns/j2ee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" > </web-app >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8" > <title>hello. xiaofan</title> </head> <body> Hello World!<br/> <% System.out.println("-----my test web logs------" ); %> </body> </html>
发现:项目部署成功,可以直接访问 ok!
我们以后开发的步骤:需要掌握 Dockerfile 的编写!我们之后的一切都是使用 docker 来进行发布运行的!
发布自己的镜像到 Docker Hub
Docker Hub
地址https://hub.docker.com/ 注册自己的账号
确定这个账号可以登录
1 2 3 4 5 6 7 8 9 10 11 $ docker login --help Usage: docker login [OPTIONS] [SERVER] Log in to a Docker registry. If no server is specified, the default is defined by the daemon. Options: -p, --password string Password --password-stdin Take the password from stdin -u, --username string Username $ docker login -u 你的用户名 -p 你的密码
提交 push 镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] The push refers to repository [docker.io/library/diytomcat] 2eaca873a720: Preparing 1b38cc4085a8: Preparing 088ebb58d264: Preparing c06785a2723d: Preparing 291f6e44771a: Preparing denied: requested access to the resource is denied The push refers to repository [docker.io/1314520007/diytomcat] An image does not exist locally with the tag: 1314520007/diytomcat $ docker build -t kuangshen/mytomcat:0.1 . $ docker tag 容器id kuangshen/mytomcat:1.0 $ docker push kuangshen/mytomcat:1.0
发布镜像到阿里云镜像服务上
登录阿里云
找到容器镜像服务
创建命名空间
创建容器镜像
点击仓库名称,参考官方文档即可
总结
八、Docker 网络 1.Docker 网络 链接 Docker0 学习之前清空下面的 docker 镜像、容器
1 2 3 4 5 $ docker rm -f $(docker ps -aq) $ docker rmi -f $(docker images -aq)
测试
三个网络
问题: docker 是如何处理容器网络访问的?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $ docker run -d -P --name tomcat01 tomcat $ docker exec -it 容器id ip addr $ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link /loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 261: eth0@if91: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link /ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0 valid_lft forever preferred_lft forever $ ping 172.18.0.2 PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data. 64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.069 ms 64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.074 ms
原理
1、我们每启动一个 docker 容器,docker 就会给 docker 容器分配一个ip,我们只要安装了 docker,就会有一个网卡 docker0 桥接模式,使用的技术是 veth-pai 技术!
https://www.cnblogs.com/bakari/p/10613710.html
再次测试 ip addr
2、再启动一个容器测试,发现又多了一对网卡
3、我们测试一下 tomcat01 和 tomcat02 之间是否可以 ping 通!
1 2 3 4 5 6 7 8 9 10 11 12 $ docker-tomcat docker exec -it tomcat01 ip addr 550: eth0@if551: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link /ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever $ docker-tomcat docker exec -it tomcat02 ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.098 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.071 ms
网络模型图
结论:容器与容器之间是可以相互 ping 通的,绘制一个网络模型图
结论:tomcat01 和 tomcat02 是共用的一个路由器,docker0
所有的容器在不指定网络的情况下,都是 docker0 路由的,docker 会给我们的容器分配一个默认的可用的ip
小结
Docker 使用的是 Linux 的桥接,宿主机中是一个 Docker 容器的网桥 docker0.
Docker 中的所有的网络接口都是虚拟的,虚拟的转发效率高!(内网传递文件!)
只要容器删除,对应的网桥一对就没了!
– link
思考一个场景,我们编写了一个微服务,database url = ip;项目不重启,数据 ip 换掉了,我们希望可以处理这个问题,可以按名字来访问容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ docker exec -it tomcat02 ping tomca01 ping: tomca01: Name or service not known $ docker run -d -P --name tomcat03 --link tomcat02 tomcat 5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef $ docker exec -it tomcat03 ping tomcat02 PING tomcat02 (172.17.0.3) 56(84) bytes of data. 64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.115 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] ping: tomcat03: Name or service not known
探究:inspect(docker network inspect 网络id 网段相同)
docker inspect tomcat03
查看 tomcat03 里面的 /etc/hosts 发现有 tomcat02 的配置
1 2 3 4 5 6 7 8 9 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 tomcat02 f22ed47ed1be 172.17.0.4 3a2bcaba804c
本质探究:– link 就是我们在 hosts 配置中增加了一个 172.12.0.3 tomcat02 f22ed47ed1be
我们现在玩 Docker 已经不建议使用 – link 了!
自定义网络!不使用 docker0
docker0 的问题:它不支持容器名链接访问!
2.自定义网络 1 2 3 4 5 6 7 8 docker network connect -- Connect a container to a network create -- Creates a new network with a name specified by the disconnect -- Disconnects a container from a network inspect -- Displays detailed information on a network ls -- Lists all the networks created by the userprune -- Remove all unused networks rm -- Deletes one or more networks
查看所有的 docker 网络
网络模式
bridge:桥接模式,桥接 docker (默认,自己创建的也是用 bridge 模式)
none:不配置网络,一般不用
host:和宿主机共享网络
container:容器网络连通!(用的少,局限很大)
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $ docker run -d -P --name tomcat01 tomcat 等价于 => docker run -d -P --name tomcat01 --net bridge tomcat $ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 26a5afdf4805d7ee0a660b82244929a4226470d99a179355558dca35a2b983ec [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] NETWORK ID NAME DRIVER SCOPE 30d601788862 bridge bridge local 226019b14d91 host host local 26a5afdf4805 mynet bridge local 7496c014f74b none null local
我们自己创建的网络就ok了!
$ docker network inspect mynet;
在自己创建的网络里面启动两个 tomcat 容器,再次查看网络情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] 0e85ebe6279fd23379d39b27b5f47c1e18f23ba7838637802973bf6449e22f5c [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] c6e462809ccdcebb51a4078b1ac8fdec33f1112e9e416406b606d0c9fb6f21b5 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] [ { "Name" : "mynet" , "Id" : "26a5afdf4805d7ee0a660b82244929a4226470d99a179355558dca35a2b983ec" , "Created" : "2020-08-14T11:12:40.553433163+08:00" , "Scope" : "local" , "Driver" : "bridge" , "EnableIPv6" : false , "IPAM" : { "Driver" : "default" , "Options" : {}, "Config" : [ { "Subnet" : "192.168.0.0/16" , "Gateway" : "192.168.0.1" } ] }, "Internal" : false , "Attachable" : false , "Ingress" : false , "ConfigFrom" : { "Network" : "" }, "ConfigOnly" : false , "Containers" : { "0e85ebe6279fd23379d39b27b5f47c1e18f23ba7838637802973bf6449e22f5c" : { "Name" : "tomcat-net-01" , "EndpointID" : "576ce5c0f5860a5aab5e487a805da9d72f41a409c460f983c0bd341dd75d83ac" , "MacAddress" : "02:42:c0:a8:00:02" , "IPv4Address" : "192.168.0.2/16" , "IPv6Address" : "" }, "c6e462809ccdcebb51a4078b1ac8fdec33f1112e9e416406b606d0c9fb6f21b5" : { "Name" : "tomcat-net-02" , "EndpointID" : "81ecbc4fe26e49855fe374f2d7c00d517b11107cc91a174d383ff6be37d25a30" , "MacAddress" : "02:42:c0:a8:00:03" , "IPv4Address" : "192.168.0.3/16" , "IPv6Address" : "" } }, "Options" : {}, "Labels" : {} } ] [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data. 64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.113 ms 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.093 ms ^C --- 192.168.0.3 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.093/0.103/0.113/0.010 ms [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data. 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.068 ms 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.096 ms 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.094 ms
我们自定义的网络 docker 都已经帮我们维护好了对应关系,推荐我们平时这样使用网络!
好处:
redis - 不同的集群使用不同的网络,保证集群是安全和健康的
mysql - 不同的集群使用不同的网络,保证集群是安全和健康的
3.网络连通
1 2 3 4 $ docker run -d -P --name tomcat01 tomcat $ docker run -d -P --name tomcat02 tomcat
4.测试打通 tomcat01 和 mynet
1 2 3 4 5 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data. 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.100 ms 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.085 ms ^C --- tomcat-net-01 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.085/0.092/0.100/0.012 ms [root@iZ2zeg4ytp0whqtmxbsqiiZ ~] ping: tomcat-net-01: Name or service not known
结论:假设要跨网络操作别人,就要使用 docker network connect 连通……!
5.实战:部署 redis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 docker network create redis --subnet 172.38.0.0/16 for port in $(seq 1 6);\do \mkdir -p /mydata/redis/node-${port} /conftouch /mydata/redis/node-${port} /conf/redis.confcat << EOF >> /mydata/redis/node-${port}/conf/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.38.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes EOF done for port in $(seq 1 6);\docker run -p 637${port} :6379 -p 1667${port} :16379 --name redis-${port} \ -v /mydata/redis/node-${port} /data:/data \ -v /mydata/redis/node-${port} /conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6371:6379 -p 16371:16379 --name redis-1 \ -v /mydata/redis/node-1/data:/data \ -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6372:6379 -p 16372:16379 --name redis-2 \ -v /mydata/redis/node-2/data:/data \ -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6373:6379 -p 16373:16379 --name redis-3 \ -v /mydata/redis/node-3/data:/data \ -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6374:6379 -p 16374:16379 --name redis-4 \ -v /mydata/redis/node-4/data:/data \ -v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6375:6379 -p 16375:16379 --name redis-5 \ -v /mydata/redis/node-5/data:/data \ -v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6376:6379 -p 16376:16379 --name redis-6 \ -v /mydata/redis/node-6/data:/data \ -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker exec -it redis-1 /bin/sh 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
docker 搭建 redis 集群完成!
6.SpringBoot 微服务打包 Docker 镜像
构建springboot项目
打包应用: mvn package
编写 Dockerfile
1 2 3 4 5 FROM java:8 COPY *.jar /app.jar CMD ["--server.port=8080" ] EXPOSE 8080 ENTRYPOINT ["java" ,"-jar" ,"app.jar" ]
构建镜像
1 2 3 $ docker build -t xxxxx:xx .
发布运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 [root@iZ2zeg4ytp0whqtmxbsqiiZ idea] total 16140 -rw-r--r-- 1 root root 16519871 Aug 14 17:38 demo-0.0.1-SNAPSHOT.jar -rw-r--r-- 1 root root 122 Aug 14 17:38 Dockerfile [root@iZ2zeg4ytp0whqtmxbsqiiZ idea] Sending build context to Docker daemon 16.52MB Step 1/5 : FROM java:8 8: Pulling from library/java 5040bd298390: Pull complete fce5728aad85: Pull complete 76610ec20bf5: Pull complete 60170fec2151: Pull complete e98f73de8f0d: Pull complete 11f7af24ed9c: Pull complete 49e2d6393f32: Pull complete bb9cdec9c7f3: Pull complete Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d Status: Downloaded newer image for java:8 ---> d23bdf5b1b1b Step 2/5 : COPY *.jar /app.jar ---> d4de8837ebf9 Step 3/5 : CMD ["--server.port=8080" ] ---> Running in e3abc66303f0 Removing intermediate container e3abc66303f0 ---> 131bb3917fea Step 4/5 : EXPOSE 8080 ---> Running in fa2f25977db7 Removing intermediate container fa2f25977db7 ---> d98147377951 Step 5/5 : ENTRYPOINT ["java" , "-jar" , "/app.jar" ] ---> Running in e1885e23773b Removing intermediate container e1885e23773b ---> afb6b5f28a32 Successfully built afb6b5f28a32 Successfully tagged xiaofan666:latest [root@iZ2zeg4ytp0whqtmxbsqiiZ idea] REPOSITORY TAG IMAGE ID CREATED SIZE xiaofan666 latest afb6b5f28a32 14 seconds ago 660MB tomcat latest 2ae23eb477aa 8 days ago 647MB redis 5.0.9-alpine3.11 3661c84ee9d0 3 months ago 29.8MB java 8 d23bdf5b1b1b 3 years ago 643MB [root@iZ2zeg4ytp0whqtmxbsqiiZ idea] fd9a353a80bfd61f6930c16cd92204532bfd734e003f3f9983b5128a27b0375e [root@iZ2zeg4ytp0whqtmxbsqiiZ idea] CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fd9a353a80bf xiaofan666 "java -jar /app.jar …" 9 seconds ago Up 8 seconds 0.0.0.0:32779->8080/tcp xiaofan-springboot-web [root@iZ2zeg4ytp0whqtmxbsqiiZ idea] {"timestamp" :"2020-08-14T09:42:57.371+00:00" ,"status" :404,"error" :"Not Found" ,"message" :"" ,"path" :"/" } [root@iZ2zeg4ytp0whqtmxbsqiiZ idea] hello, xiaofan
以后我们使用了 Docker 之后,给别人交付的就是一个镜像!
九、Docker Compose 1.Docker Compose 简介 Docker
Dockerfile build run 手动操作,单个容器!
微服务,100个微服务,依赖关系。
Dcoker Compose 来轻松高效的管理容器,定义运行多个容器。
官方介绍
定义运行多个容器
YAML file 配置文件
single command。命令
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features .
所有的环境都可以使用 compose。
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases .
三步骤
Using Compose is basically a three-step process:
Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
Dockerfile保证我们的项目再任何地方可以运行
Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
Run docker-compose up and Compose starts and runs your entire app.
作用:批量容器编排
我自己的理解
Compose 是 Docker 官方的开源项目,需要安装!
Dockerfile 让程序在任何地方运行,web服务、redis、mysql、nginx…多个容器。run
Compose
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 version: '2.0' services: web: build: . ports: - "5000:5000" volumes: - .:/code - logvolume01:/var/log links: - redis redis: image: redis volumes: logvolume01: {}
docker-copose up 100个服务
Comspose:重要概念
服务 services,容器、应用(web、redis、mysql…)
项目 project。一组关联的容器
安装
下载
1 2 3 4 5 curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s) -$(uname -m) " -o /usr/local/bin/docker-compose curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
授权
1 chmod +x /usr/local/bin/docker-compose
体验(没有测试通过)
地址:https://docs.docker.com/compose/gettingstarted/ python 应用。计数器。redis!
应用app.py
Dockerfile 应用打包为镜像
1 2 3 4 5 6 7 8 9 10 11 12 FROM python:3.6-alpine ADD . /code WORKDIR /code RUN pip install -r requirements.txt CMD ["python" , "app.py" ]
Dockerfile-compose.yaml 文件(定义整个服务,需要的环境 web、redis)完整的上线服务!
1 2 3 4 5 6 7 8 9 10 version: '3.8' services: web: build: . ports: - "5000:5000" volumes: - .:/code redis: image: "redis:alpine"
启动 compose 项目 (docker-compose up -d)
流程:
创建网络
执行 Docker-compose.yaml
启动服务
yaml 规则 docker-compose.yaml 核心!
https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples
开源项目:博客 https://docs.docker.com/compose/compose-file/#compose-file-structure-and-examples
下载程序、安装数据库、配置……
compose 应用 => 一键启动
下载项目(docker-compose.yaml)
如果需要文件。Dockerfile
文件准备齐全,一键启动项目即可
实战:自己编写微服务上线
编写项目微服务
Dockerfile 构建镜像
1 2 3 4 5 FROM java:8 COPY *.jar /app.jar CMD ["--server.port=8080" ] EXPOSE 8080 ENTRYPOINT ["java" , "-jar" , "/app.jar" ]
docker-compose.yml 编排项目
1 2 3 4 5 6 7 8 9 10 11 12 version '3.8' services: xiaofanapp: build: . image: xiaofanapp depends_on: - redis ports: - "8080:8080" redis: image: "library/redis:alpine"
丢到服务器运行 docker-compose up -d
1 2 docker-compose down # 关闭容器并删除容器 docker-compose up --build # 重新构建
总结:
工程、服务、容器
项目 compose: 三层
工程 project
服务
容器 运行实例! docker k8s 容器
十、Docker Swarm 1.Docekr Swarm 集群
购买服务器
登录阿里云账号,进入控制台,创建实例
4台服务器2G
到此,我们服务器购买成功!
四台机器安装 docker
和我们单机安装一样
技巧:xshell 直接同步操作,省时间!
Swarm 集群搭建
1 2 3 4 5 6 7 8 9 docker swarm init --help ip addr [root@iZ2ze58v8acnlxsnjoulk5Z ~] Swarm initialized: current node (otdyxbk2ffbogdqq1kigysj1d) is now a manager. To add a worker to this swarm, run the following command : docker swarm join --token SWMTKN-1-3vovnwb5pkkno2i3u2a42yrxc1dk51zxvto5hrm4asgn37syfn-0xkrprkuyyhrx7cidg381pdir 172.16.250.97:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
初始化结点docker swarm init
docker swarm join 加入一个结点!
1 2 3 docker swarm join-token manager docker swarm join-token worker
1 2 [root@iZ2ze58v8acnlxsnjoulk6Z ~] This node joined a swarm as a worker.
把后面的结点都搭建进去
生成主节点 init
加入 (管理者,worker)
Raft 协议 双主双从:假设一个结点挂了!其他结点是否可以用!
Raft 协议:保证大多数结点存活才可以使用,只要 > 1,集群至少大于3台!
实验:
1、将 docker1 机器停止。宕机!双主,另一个结点也不能使用了!
2、可以将其他结点离开 docker swarm leave
3、worker 就是工作的,管理结点操作!3台结点设置为了管理结点。
4、Docker swarm集群增加节点
十分简单:集群,可用!3个主节点。 > 1台管理结点存活!
Raft 协议:保证大多数结点存活,才可以使用,高可用
体会
弹性、扩缩容!集群!
以后告别 docker run!
docker-compose up! 启动一个项目。单机!
集群:swarm docker-service
k8s service
容器 => 服务!
容器 => 服务! => 副本!
redis => 10个副本!(同时开启10个redis容器)
体验:创建服务、动态扩容服务、动态更新服务
1 2 docker run 容器启动! 不具有扩缩容器 docker service 服务! 具有扩缩容器,滚动更新!
查看服务
动态扩缩容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [root@iZ2ze58v8acnlxsnjoulk5Z ~] 1/3: running [==================================================>] 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged [root@iZ2ze58v8acnlxsnjoulk5Z ~] my-nginx scaled to 5 overall progress: 3 out of 5 tasks overall progress: 3 out of 5 tasks overall progress: 3 out of 5 tasks overall progress: 5 out of 5 tasks 1/5: running [==================================================>] 2/5: running [==================================================>] 3/5: running [==================================================>] 4/5: running [==================================================>] 5/5: running [==================================================>] verify: Service converged [root@iZ2ze58v8acnlxsnjoulk5Z ~] my-nginx scaled to 1 overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged
移出! docker service rm
docker swarm 其实并不难
只要会搭建集群、会启动服务、动态管理容器就可以!
概念总结 swarm
集群的管理和编号,docker 可以初始化一个 swarm 集群,其他结点可以加入。(管理,工作者)
Node
就是一个 docker 结点,多个结点就组成了一个网络集群(管理、工作者)
Service
任务、可以在管理结点或者工作结点来运行。核心、用户访问。
Task
容器内的命令、细节任务!
sevice
命令 -> 管理 -> api -> 调度 -> 工作结点(创建Task容器维护创建!)
服务副本和全局服务
调整 service 以什么方式运行
1 2 3 4 5 --mode string Service mode (replicated or global) (default "replicated" ) docker service create --mode replicated --name mytom tomcat:7 默认的 docker service create --mode global --name haha alpine ping www.baidu.com
拓展:网络模式“PublishModel”:“ingress”
Swarm:
Overlay:
ingress:特殊的Overlay网络!负载均衡功能! ipvs vip!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 [root@iZ2ze58v8acnlxsnjoulk5Z ~] NETWORK ID NAME DRIVER SCOPE 74cecd37149f bridge bridge local 168d35c86dd5 docker_gwbridge bridge local 2b8f4eb9c2e5 host host local dmddfc14n7r3 ingress overlay swarm 8e0f5f648e69 none null local [root@iZ2ze58v8acnlxsnjoulk5Z ~] [ { "Name" : "ingress" , "Id" : "dmddfc14n7r3vms5vgw0k5eay" , "Created" : "2020-08-17T10:29:07.002315919+08:00" , "Scope" : "swarm" , "Driver" : "overlay" , "EnableIPv6" : false , "IPAM" : { "Driver" : "default" , "Options" : null, "Config" : [ { "Subnet" : "10.0.0.0/24" , "Gateway" : "10.0.0.1" } ] }, "Internal" : false , "Attachable" : false , "Ingress" : true , "ConfigFrom" : { "Network" : "" }, "ConfigOnly" : false , "Containers" : { "ingress-sbox" : { "Name" : "ingress-endpoint" , "EndpointID" : "9d6ec47ec8309eb209f4ff714fbe728abe9d88f9f1cc7e96e9da5ebd95adb1c4" , "MacAddress" : "02:42:0a:00:00:02" , "IPv4Address" : "10.0.0.2/24" , "IPv6Address" : "" } }, "Options" : { "com.docker.network.driver.overlay.vxlanid_list" : "4096" }, "Labels" : {}, "Peers" : [ { "Name" : "cea454a89163" , "IP" : "172.16.250.96" }, { "Name" : "899a05b64e09" , "IP" : "172.16.250.99" }, { "Name" : "81d65a0e8c03" , "IP" : "172.16.250.97" }, { "Name" : "36b31096f7e2" , "IP" : "172.16.250.98" } ] } ]
其他命令学习方式
1 2 3 4 5 6 docker-compose 单机部署项目 docker stack 集群部署 docker-compose up -d wordpress.yaml docker stack deploy wordpress.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@iZ2ze58v8acnlxsnjoulk5Z ~] Usage: docker secret COMMAND Manage Docker secrets Commands: create Create a secret from a file or STDIN as content inspect Display detailed information on one or more secrets ls List secrets rm Remove one or more secrets
1 2 3 4 5 6 7 8 9 10 11 12 [root@iZ2ze58v8acnlxsnjoulk5Z ~] Usage: docker config COMMAND Manage Docker configs Commands: create Create a config from a file or STDIN inspect Display detailed information on one or more configs ls List configs rm Remove one or more configs
拓展到k8s 云原生时代
Go语言!必须掌握! java Go!
并发语言!
B语言,C语言的创始人。Unix创始人 VB
go指针
1 2 3 4 5 6 7 8 docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer [root@iZ2zeg4ytp0whqtmxbsqiiZ home] <!DOCTYPE html ><html lang="en" ng-app="portainer" >