赞
踩
这是我学习Docker容器技术的全部过程,所有的案例全部实现,尽管学习过程中遇到很多困难和问题,但是我从未放弃,经过努力逐一解决,颇有收获。以下的学习过程主要是在CentOS7系统环境,有部分在Win10和Mac系统操作。
。镜像命令
。容器命令
。操作命令
。…
一款产品:开发–上线 两套环境, 应用环境, 应用配置!开发–运维 问题:我在我电脑可以运行!版本更新,导致服务不可用,对运维考验很大。环境配置是十分麻烦,每一个机器都要部署环境(集群Redis, ES,Hadoop…)费时费力
发布一个项目(jar包+(Redis MySQL jdk ES),项目能不能带上环境。安装打包之前在服务器配置一个应用环境Redis MySQL jdk ES Hadoop,配置超麻烦, 不能跨平台,Windows 发布到Linux。现在开发包部署上线,一套流程做完。java – jar(环境)-- 打包项目带上没环境(镜像)-- (Docker仓库:商店 – 下载我们发布的镜像 – 直接运行即可。Docker给以上的问题,提供了解决方案。
Docker的思想来自于集装箱
JRE – 多个应用(端口冲突)-- 原来都是交叉的
隔离:Docker核心思想,打包装箱,每个箱子是互相隔离的。
Docker通过隔离机制,可以将服务器利用到极致
2010年,几个搞IT的年轻人,在美国成立一家公司dotCloud,做一些pass的云计算服务,LXC有关的容器技术
他们将自己的技术(容器化技术)命名Docker
开源:
开发源代码
2013年,Docker开源(开放源代码)
2014年4月9日,Docker1.0发布,容器技术出现之前,都是虚拟机技术。
虚拟机:在windows中安装一个VMware,通过这个软件我们可以虚拟出一台或者多台电脑,耗资源。
虚拟机也是虚拟化技术,Docker容器技术,也是一种虚拟化技术。
vm:linux centos原生镜像(一个电脑)隔离,需要开启多个虚拟机
docker:隔离,镜像(最核心的环境)
Docker基于Go语言开发,开源项目!
官网:https://www.docker.com/
文档地址:https://docs.docker.com/ Docker的文档是超级详细的
仓库地址:https://hub.docker.com/ git push pull
虚拟机技术缺点:
1、资源占用十分多
2、冗余步骤多
3、启动很慢
容器化技术:
容器化技术不是模拟的一个完整的操作系统
比较Docker和虚拟机技术的不同
DevOps(开发、运维)
应用更快速的交付和部署
传统:一堆帮助文档、安装程序
Docker:打包镜像发布测试,一键运行
更便捷的升级和扩容
使用Docker以后,我们部署应用就像搭积木一样
项目打包为一个镜像,扩展服务器A 服务器B
更简单的系统运维
在容器化之后,我们的开发,测试环境都是高度一致的
更高效的计算资源利用:
Docker是内核级别的虚拟化,可以在一个物理机上运行很多容器实例,服务器性能发挥到极致。
docker镜像好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像===>run==>tomcat01容器(提供服务器)
通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中)
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的。
启动,停止,删除,基本命令
目前就可以把这个容器理解为就是一个简易的Linux系统
仓库就是存放镜像的地方
仓库分为公有仓库和私有仓库
Docker Hub(默认是国外的)
阿里云…都有容器服务
1、需要linux基础知识
2、CentOS7
3、我们使用Xshell连接远程服务器进行操作
# 系统内核是3.10以上
[root@localhost ~]# uname -r
3.10.0-1160.42.2.el7.x86_64
# 系统版本 [root@localhost ~]# cat /etc/os-release 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"
帮助文档:
# 1.卸载旧版 $sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine # 2.需要的安装包 $sudo yum install -y yum-utils # 3.设置镜像的仓库 $sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo # 默认是国外的镜像地址 http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 推荐使用国内的阿里云镜像地址 # 4.更新软件包索引 $sudo yum makecache fast # 5.安装docker, docker-ce 社区版 docker-ee 企业版 $sudo yum install docker-ce docker-ce-cli containerd.io # 官方推荐使用社区版 # 可以列出和分类docker版本 $ yum list docker-ce --showduplicates | sort -r # 安装指定版本的docker $sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io # 6. 启动docker $sudo systemctl start docker # 7. 判断启动成功 # docker version [root@localhost ~]# docker version Client: Docker Engine - Community Version: 20.10.8 API version: 1.41 Go version: go1.16.6 Git commit: 3967b7d Built: Fri Jul 30 19:55:49 2021 OS/Arch: linux/amd64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 20.10.8 API version: 1.41 (minimum version 1.12) Go version: go1.16.6 Git commit: 75249d8 Built: Fri Jul 30 19:54:13 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.4.9 GitCommit: e25210fe30a0a703442421b0f60afac609f950a3 runc: Version: 1.0.1 GitCommit: v1.0.1-0-g4144b63 docker-init: Version: 0.19.0 GitCommit: de40ad0 # 8.hello-word $sudo docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 2db29710123e: Pull complete Digest: sha256:2498fce14358aa50ead0cc6c19990fc6ff866ce72aeb5546e1d59caac3d0d60f Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ # 9.查看一下下载的这个hello-world镜像 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql 5.7 c20987f18b13 2 weeks ago 448MB ubuntu latest ba6acccedd29 2 months ago 72.8MB hello-world latest feb5d9fea6a5 3 months ago 13.3kB mariadb latest 6b01262bc780 4 months ago 409MB vulhub/discuz x3.4 5a979b3474c5 4 years ago 441MB
# 1.卸载依赖
$sudo yum remove docker-ce docker-ce-cli containerd.io
# 2.删除资源
$sudo rm -rf /var/lib/docker # dockers的默认工作路径
$sudo rm -rf /var/lib/containerd
$sudo mkdir -p /etc/docker
$sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors":["https://bruce_liu1973@163.com.mirror.aliyuncs.com"]
}
EOF
$sudo systemctl daemon-reload
$sudo systemctl restart docker
docker info #显示docker的系统信息,包括镜像和容器的数量
docker version #显示docker的版本信息
docker --help #帮助命令
帮助文档的地址:https://docs.docker.com/engine/reference/commandline/
# Windows系统环境 C:\cmder λ docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker/getting-started latest 26d80cd96d69 4 weeks ago 28.5MB docker/desktop-kubernetes kubernetes-v1.22.4-cni-v0.8.5-critools-v1.17.0-debian 493a106d3678 6 weeks ago 294MB scrapinghub/splash latest 9364575df985 16 months ago 1.89GB # 解释 REPOSITORY 镜像的仓库源 TAG 镜像的标签 IMAGE ID 镜像的id CREATED 镜像的创建时间 SIZE 镜像的大小 # 可选项 Options: -a, --all Show all images (default hides intermediate images) # 列出所有镜像 -q, --quiet Only show image IDs # 只显示ID
2、docker search搜索镜像
官网地址:https://hub.docker.com/
# Windows系统环境 docker search mysql C:\cmder λ docker search mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 11909 [OK] mariadb MariaDB Server is a high performing open sou… 4556 [OK] mysql/mysql-server Optimized MySQL Server Docker images. Create… 894 [OK] # 可选项 docker search --help Options: -f, --filter filter Filter output based on conditions provided --format string Pretty-print search using a Go template --limit int Max number of search results (default 25) --no-trunc Don't truncate output #通过收藏来过滤 --filter=STARS=3000 # 搜索出来的镜像就是STARS超过3000的 C:\cmder λ docker search mysql --filter=STARS=4000 NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 11909 [OK] mariadb MariaDB Server is a high performing open sou… 4556 [OK]
docker pull 下载镜像
# Windows系统环境 C:\cmder λ docker pull --help Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST] Pull an image or a repository from a registry Options: -a, --all-tags Download all tagged images in the repository --disable-content-trust Skip image verification (default true) --platform string Set platform if server is multi-platform capable -q, --quiet Suppress verbose output # 下载镜像 C:\cmder λ docker pull mysql Using default tag: latest #如果不写tag,默认就是latest latest: Pulling from library/mysql 72a69066d2fe: Pull complete # 分层下载,docker images的核心,联合文件系统 93619dbc5b36: Pull complete 99da31dd6142: Pull complete 626033c43d70: Pull complete 37d5d7efb64e: Pull complete ac563158d721: Pull complete d2ba16033dad: Pull complete 688ba7d5c01a: Pull complete 00e060b6d11d: Pull complete 1c04857f594f: Pull complete 4d7cfa90e6ea: Pull complete e0431212d27d: Pull complete Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 # 签名 Status: Downloaded newer image for mysql:latest docker.io/library/mysql:latest # 真实地址 # 等价命令 docker pull mysql docker pull docker.io/library/mysql:latest # 下载镜像 指定版本 docker pull mysql:5.7 C:\cmder λ docker pull mysql:5.7 5.7: Pulling from library/mysql 72a69066d2fe: Already exists 93619dbc5b36: Already exists 99da31dd6142: Already exists 626033c43d70: Already exists 37d5d7efb64e: Already exists ac563158d721: Already exists d2ba16033dad: Already exists 0ceb82207cd7: Pull complete 37f2405cae96: Pull complete e2482e017e53: Pull complete 70deed891d42: Pull complete Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94 Status: Downloaded newer image for mysql:5.7 docker.io/library/mysql:5.7 # 查看所有的镜像
docker 删除镜像
docker rmi -f c20987f18b13 # image id 删除指定的镜像
docker rmi -f 容器id 容器id 容器id 容器id #删除多个容器
docker rmi -f $(docker images -aq) #删除所有的镜像 -aq是所有的镜像 $()传参
docker pull centos8
docker run --help #docker run启动
docker run[可选参数] image # 参数说明 --name="Name" 容器名字 tomcat 01 tomcat02 用来区分容器 -d 后台方式运行 -it 使用交互方式运行, 进入容器查看内容 -P 指定容器的端口 -p 8080:8080 -p ip:主机端口:容器端口 -P 主机端口:容器端口(常用) -P 容器端口 -p 随机指定端口 # 测试 docker run -it centos /bin/bash # 从容器退回主机 exit
docker ps
docker ps -a #列出当前正在运行的容器+历史运行过的容器
docker ps -n=? # 显示最近创建的容器
docker ps -n=1
docker ps -q #只显示容器的编号
docker ps -aq # 显示所有容器的编号
exit # 直接容器停止并退出
Ctrl+P+Q # 容器不停止退出
docker rm 容器id # 删除指定容器, 不能删除正在运行的容器,如果要强制删除 rm -f
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -a -q|xargs docker rm # 删除所有容器
docker start 容器id #启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前运行的容器
# 命令docker run -d 镜像名
docker run -d 镜像名
# 问题docker ps 发现centos 停止了
# 常见的坑:docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx, 容器启动后,发现自己没有提供服务,就会立刻停止,就没有程序了。
docker logs
docker logs --help # 选项
docker logs -f -t --tail 容器id # 容器,没有日志
# 自己编写shell脚本
"while true;do echo bruce_liu;sleep 1;done"
docker run -d centos -c /bin/sh "while true;do echo bruce_liu;sleep 1;done"
# 显示日志
-tf # 显示日志
--tail num # 要显示的记录条数
# Windows系统环境
# 命令docker top 容器id
C:\cmder
λ docker top 0c7ee03d76dd
UID PID PPID C STIME TTY
TIME CMD
root 5113 5092 0 13:49 ?
00:00:00 /bin/sh -c while true;do echo bruce_liu;sleep 1;done
root 13416 5113 0 14:01 ?
00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
docker inspect --help # 命令 docker inspect 容器id # 测试 C:\cmder λ docker inspect 0c7ee03d76dd # [ { "Id": "0c7ee03d76ddc6dd4c8caea4a639bcbd191309f1f6794c223bb62958f05e13cc", "Created": "2022-01-05T13:49:27.0383541Z", "Path": "/bin/sh", "Args": [ "-c", "while true;do echo bruce_liu;sleep 1;done" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 5113, "ExitCode": 0, "Error": "", "StartedAt": "2022-01-05T13:49:27.6480989Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6", "ResolvConfPath": "/var/lib/docker/containers/0c7ee03d76ddc6dd4c8caea4a639bcbd191309f1f6794c223bb62958f05e13cc/resolv.conf", "HostnamePath": "/var/lib/docker/containers/0c7ee03d76ddc6dd4c8caea4a639bcbd191309f1f6794c223bb62958f05e13cc/hostname", "HostsPath": "/var/lib/docker/containers/0c7ee03d76ddc6dd4c8caea4a639bcbd191309f1f6794c223bb62958f05e13cc/hosts", "LogPath": "/var/lib/docker/containers/0c7ee03d76ddc6dd4c8caea4a639bcbd191309f1f6794c223bb62958f05e13cc/0c7ee03d76ddc6dd4c8caea4a639bcbd191309f1f6794c223bb62958f05e13cc-json.log", "Name": "/brave_cartwright", "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, "CgroupnsMode": "host", "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": [ 30, 120 ], "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/24d07c55a599d8b51e7035d22fd8d1825e132552271702bc42c1410417e22a01-init/diff:/var/lib/docker/overlay2/88853f06c6da7ba74b65019d6f86fcff4301dba97631a2cdd7ebe466cbc3cc0f/diff", "MergedDir": "/var/lib/docker/overlay2/24d07c55a599d8b51e7035d22fd8d1825e132552271702bc42c1410417e22a01/merged", "UpperDir": "/var/lib/docker/overlay2/24d07c55a599d8b51e7035d22fd8d1825e132552271702bc42c1410417e22a01/diff", "WorkDir": "/var/lib/docker/overlay2/24d07c55a599d8b51e7035d22fd8d1825e132552271702bc42c1410417e22a01/work" }, "Name": "overlay2" }, "Mounts": [], "Config": { "Hostname": "0c7ee03d76dd", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/sh", "-c", "while true;do echo bruce_liu;sleep 1;done" ], "Image": "centos", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20210915", "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": "325904a8305da35e3bccb874c66331dceabb2fb0917e0e5f364ec144dac6d891", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/325904a8305d", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "ca20615b2260f60d00b7a801466257e4cf180d6a9cc51ca5b7fe1a31fb5a0241", "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": "bc7d4b7e5df6399b894535936e96884d6f4fd226f10bd0118f2d8293f8df5fc6", "EndpointID": "ca20615b2260f60d00b7a801466257e4cf180d6a9cc51ca5b7fe1a31fb5a0241", "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 } } } } ]
# 我们通常容器都使用后台方式运行的,需要进入容器,修改一些配置 # 命令 docker exec -it 容器id bashShell C:\cmder λ docker exec -it 0c7ee03d76dd /bin/bash [root@0c7ee03d76dd /]# pwd / [root@0c7ee03d76dd /]# clear bash: clear: command not found [root@0c7ee03d76dd /]# ls bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var # 方式二 docker attach 容器id docker attach --help # 测试 C:\cmder λ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0c7ee03d76dd centos "/bin/sh -c 'while t…" 44 minutes ago Up 44 minutes brave_cartwright C:\cmder λ docker attach 0c7ee03d76dd bruce_liu bruce_liu bruce_liu bruce_liu 正在执行当前的代码...... # docker exec ---------进入容器后开启一个新的终端,可以在里面操作(常用) # docker attach ---------进入容器正在执行的终端,不会启动新的进程!
docker cp 容器id:容器内路径 目的地主机路径
docker cp 容器id:路径/文件 目的主机路径
# 进入docker容器内部
docker attach 容器id
# 在容器内执行命令 touch test.java
# 然后执行exit, 退出容器
# 将这个文件拷贝出来的到主机上
docker cp 容器id:/test.java c:\
# 拷贝是一个手动过程,未来我们使用 -v 卷的技术,可以实现
attach Attach to a running container # 当前shell下attach连接指定运行镜像 build Build an image from a Dockerfile # 通过Dockerfile 定制镜像 commit Create a new image from a container changes # 提交当前容器为新的镜像 cp Copy files/folders from the containers filesystem to the host path # 从容器中拷贝指定文件或者目录到宿主机 create Create a new container # 创建一个新的容器, 同run ,但不启动容器 diff Inspect changes on a container's filesystem # 查看docker容器变化 events Get real time events from the server # 从docker服务获取容器实时事件 exec Run a command in an existing container # 在已存在的容器上运行命令 export Stream the contents of a container as a tar archive # 导出容器的内容流作为一个tar,归档文件[对应import] history Show the history of an image # 展示一个镜像形成历史 images List images # 列出系统当前镜像 import Create a new filesystem image from the contents of a tarball # 从tar包中的内容创建一个新的文件系统映像[对应export] info Display system-wide information # 显示系统相关信息 inspect Return low-level information on a container # 查看容器详细信息 kill Kill a running container # kill 指定的docker 容器 load Load an image from a tar archive # 从一个tar包中加载一个镜像[对应save] login Register or Login to the docker registry server # 注册或者登录一个docker源服务器 logout Log out from a Docker registry server # 从当前docker registry退出 logs Fetch the logs of a container # 输出当前容器日志信息 port Lookup the public-facing port which is NAT-ed to PRIVATE_PORT # 查看映射端口对应的容器内部源端口 pause Pause all processs within a container # 暂停容器 ps List containers # 列出容器列表 pull Pull an image or a repository from the docker registry server # 从docker镜像源服务器拉取指定镜像或者镜像库 push Push an image or a repository to the docker registry server # 推送指定镜像或者库镜像至docker 源服务器 restart Restart a running container # 重启运行的容器 rm Remove one or more containers # 移除一个或者多个容器 rmi Remove one or more images # 移除一个或者多个镜像[无容器使用该镜像才可删除,否则删除相关容器才可继续或-f 强制删除] run Run a command in a new container # 创建一个新的容器并运行一个命令 save Save an image to a tar archive # 保存一个镜像为一个tar包(对应load) search Search for an image on the Docker Hub # 在docker hub中搜索镜像 start Start a stopped containers # 启动容器 stop Stop a running containers # 停止容器 tag Tag an image into a repository # 给源中镜像打标签 unpause Unpause a paused container # 取消暂停容器 version Show the docker version information # 查看docker版本号 wait Block until a container stops, then print its exit code # 截取容器停止时的退出状态值
# 搜索镜像,建议去docker hub网站搜索,这样可以看到很多帮助文档信息 # https://hub.docker.com/search?q=nginx&type=image&operating_system=linux [root@localhost docker]# docker search ngnix NAME DESCRIPTION STARS OFFICIAL AUTOMATED userxy2015/ngnix ngnix 12 merpso/ngnix-plus-k8s-ingress NGNIX+ kubernetes-ingess 2 ludwringliccien/ngnix-php7.1 ngnix-php7.1 1 [OK] jhuiting/ngnix 1 sushanth53/ngnix_server ngnix server 0 # 下载镜像 [root@localhost docker]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx a2abf6c4d29d: Pull complete a9edb18cadd1: Pull complete 589b7251471a: Pull complete 186b1aaa4aa6: Pull complete b4df32aa5a72: Pull complete a0bcbecc962e: Pull complete Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest
# 启动nginx ,-d 后台运行,--name为容器命名,-p 指定一个宿主机端口3344映射容器端口80 [root@localhost docker]# docker run -d --name nginx01 -p 3344:80 nginx 0b32d7af3fac83f167050ae25787721467086185c376e46cc5a9cdbfcb5e823a # 本机访问nginx [root@localhost docker]# curl localhost:3344 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> # 进入容器 [root@localhost docker]# docker exec -it nginx01 /bin/bash root@0b32d7af3fac:/# wherei s nginx bash: wherei: command not found root@0b32d7af3fac:/# whereis nginx nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx root@0b32d7af3fac:/# cd /etc/nginx/ root@0b32d7af3fac:/etc/nginx# ls conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
-p 3344:80 # 3344宿主机端口 80 容器内端口
思考题:我们每次改动nginx配置文件,都需要进入容器内部?麻烦,如何在容器外部提供一个映射路径,达到在容器内修改文件名,容器内自动修改。
-v 数据卷
# 官方的使用 [root@localhost]$sudo docker run -it --rm tomcat:9.0 # 我们之前的启动都是后台,停止了容器之后,容器可以查到,docker run -it --rm 一般用来测试,用完即删 # 下载之后启动 [root@localhost]#docker pull tomcat # 启动运行 [root@localhost]# dockerrun -d -p 3355:8080 --name tomcat01 tomcat # 测试访问 http://172.16.12.154:3355 # 进入容器 [root@localhost]# docker exec -it tomcat01 /bin/bash # 发现问题 1.linux命令少了 2.没有webapps,解决办法:从webapps.dist文件夹下的所有文件拷贝到webapps文件夹下,或者直接修改webapps.dis名字 3.阿里云镜像的原因,默认是最小的镜像,所有不必要的都省略了。保证最小可运行的环境。
# es 暴露的端口很多 # es 消耗内存资源 # es 的数据一般需要放置到安全目录,挂载 # --net somenetwork ? 网络配置 # 启动elasticsearch $ docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag # 启动了 linux卡住了 docker stats查看cpu的状态 # es 十分消耗内存 # 测试一下es是否成功 [root@localhost ~]# curl localhost:9200 { "name" : "5506ccc49024", "cluster_name" : "docker-cluster", "cluster_uuid" : "838u-pJUScaq1g3sKs21ZQ", "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" }
# 增加内存的限制,修改配置文件 -e 环境配置修改 , 64m最小 512m最大
[root@localhost ~]# 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
[root@localhost ~]# docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
[root@localhost ~]# docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
http://ip:8088
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G6EycbiA-1641913771905)(http://localhost:8088/5da83cfb4883a59354abeff852cb7394.png)]
可视化面板平时不会使用,可以测试玩玩。
镜像就是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
所有应用,直接打包docker镜像,可以直接运行、部署。
如何得到镜像:
UnionFS(联合文件系统)
我们下载的时候看到的一层一层就是这个。
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存使用权限已由bootfs转交给内核,此时系统也会卸载boots。
黑屏—加载—开机进入系统
Roots(root file system),在bootfs之上,包含的就是典型的Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Cenos等
虚拟机是分钟级启动,容器是秒级。
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。例如:基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
特点:
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层就是我们通常说的容器层,容器之下的都叫镜像层。
docker commit 提交容器成为一个新的副本
# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试
# 1、启动一个默认的tomcat
# 2、发现这个默认的tomcat没有webapps应用,镜像的原因,官方的镜像默认是webapps下面没有任何文件的
# 3、然后我们从webapps.dist文件夹拷贝过去
# 4、将我们操作过的容器通过commit提交为一个镜像,以后我们就直接使用这个修改过的镜像即可。如下图:
理论联系实际,切记要实际操作一下!
#如果想要保存当前容器的状态,就可以通过commit来提交,获得一个新的镜像。我的理解类似于vm快照功能。
docker的理念回顾
将应用和环境打包成一个镜像。
如果数据都在容器中,那么容器删除,数据就会丢失!需求:数据可以长久化,MySQL,容器删了,删库跑路。=需求:MySQL数据可以存储在本地=
容器之间可以有一个数据共享技术!Docker容器中产生的数据,同步到本地。这就是卷技术,目前的挂载,将我们容器内的目录,挂载到Linux上面。
总结:容器的持久化和同步操作,容器间也可以数据共享。
# 方式一:直接使用命令挂载 -v docker run -it -v 主机目录:容器内目录 # 测试 root@liuxiaoweideAir ~ # docker run -it -v /Users/liuxiaowei/ceshi:/home centos /bin/bash #主机目录:/Users/liuxiaowei/ceshi 容器目录:/home # 启动之后,通过docker inspect 容器id 检验卷如何挂载 root@liuxiaoweideAir liuxiaowei # docker inspect 3af3cfc435c3 "Mounts": [ { "Type": "bind", "Source": "/Users/liuxiaowei/ceshi", # 主机内地址 "Destination": "/home", # docker 容器内的地址 "Mode": "", "RW": true, "Propagation": "rprivate" } ]
1、退出容器
2、然后在宿主机目录下进行操作
3、再启动容器
4、查看容器内目录文件同步变化
优点:以后修改只需在本地修改即可,容器内会自动同步。
# 获取镜像 root@liuxiaoweideAir ~ # docker pull mysql:5.7 # 运行容器,需要做数据挂载, 安装启动mysql,需要配置密码的,这需要注意。去https://hub.docker.com/搜索mysql # Start a mysql server instance # Starting a MySQL instance is simple: $ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag # 启动容器 -d 后台运行 -p 端口映射 -v 卷挂载 (两个-v 挂载两个目录) -e 环境配置 --name 容器名字 root@liuxiaoweideAir ~ # docker run -d -p 3310:3306 -v /Users/liuxiaowei/mysql/conf:/etc/mysql/conf.d -v /Users/liuxiaowei/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 42053d1fb7043624bb199b7f5d876ccd2299d5047230cee847a4dcabb5657ddf # 启动成功之后,利用Navicat或者SQL PRO连接测试,连接到服务器的3310 --- 3310和容器内的3306映射。如下图
# 在本地测试创建一个数据库,查看一下我们映射的路径是否同步。
本例:root@liuxiaoweideAir data # ls
auto.cnf ib_logfile1 server-cert.pem
ca-key.pem ibdata1 server-key.pem
ca.pem ibtmp1 sys
client-cert.pem mysql test # 在mysql容器里建立的数据库
client-key.pem performance_schema test1 # 在mysql容器里建立的数据库
ib_buffer_pool private_key.pem
ib_logfile0 public_key.pem
root@liuxiaoweideAir data # pwd
/Users/liuxiaowei/mysql/data
假设我们将容器删除
root@liuxiaoweideAir data # docker rm -f mysql01
mysql01
root@liuxiaoweideAir data # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
root@liuxiaoweideAir data # ls
auto.cnf ib_logfile0 public_key.pem
ca-key.pem ib_logfile1 server-cert.pem
ca.pem ibdata1 server-key.pem
client-cert.pem mysql sys
client-key.pem performance_schema test
ib_buffer_pool private_key.pem test1
发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!
# 匿名挂载 - v 容器内路径 - P 随机映射端口 docker run -d -P --name nginx01 -v /etc/nginx nginx # 查看所有的卷的信息 root@liuxiaoweideAir liuxiaowei # docker volume ls DRIVER VOLUME NAME local 3e8ab2696b7005a359de2bdaf5fc70a01881652fc0a789b3dcbac3d12b42a841 # 匿名 # 具名挂载nginx "juming-nginx" root@liuxiaoweideAir liuxiaowei # docker run -d -P --name nginx02 -v juming-nginx:/ect/nginx nginx df397dd0401dc1f2904671efaeca9749c7813fca846ba097f890666785094327 root@liuxiaoweideAir liuxiaowei # docker volume ls DRIVER VOLUME NAME local f40d828c9c069666740ff54f90c35e6061071cf684198ca5c2e9caab7871fdf0 local juming-nginx # 具名 local vsCodeServerVolume-liuxiaowei-recursing_leakey # 查看一下这个具名卷 root@liuxiaoweideAir liuxiaowei # docker volume inspect juming-nginx [ { "CreatedAt": "2022-01-08T14:24:41Z", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", # 挂载点 "Name": "juming-nginx", "Options": null, "Scope": "local" } ]
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用具名挂载
# 如何确定是具名挂载或者匿名挂载,还是指定路径挂载
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
拓展:
# 通过 -v 容器内路径:ro rw 改变读写权限
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
# ro 说明这个路径只能通过宿主机来操作,容器内部无法操作
Dockerfile 就是用来构建docker镜像的构建文件,就是一个命令脚本,通过这脚本可以生成镜像,镜像是一层一层的,脚本就是一个个的命令,
# 创建一个dockerfile文件,名字可以随意,建议用dockerfile # 文件中内容,指令都是大写,参数 FROM centos VOLUME ["volume01","volume02"] CMD echo "---end----" CMD /bin/bash # 这里的每个命令就是镜像的一层 **本人的理解类似于windows系统的批处理文件** root@liuxiaoweideAir docker-test-volume # docker build -f /Users/liuxiaowei/docker-test-volume/dockerfile1 -t bruceliu/centos:1.0 . [+] Building 1.6s (5/5) FINISHED => [internal] load build definition from dockerfile1 0.5s => => transferring dockerfile: 120B 0.0s => [internal] load .dockerignore 0.5s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => [1/1] FROM docker.io/library/centos 0.4s => exporting to image 0.1s => => exporting layers 0.0s => => writing image sha256:9ec777f9328b3414e208ee19b30072b218f5c6bfb152a 0.0s => => naming to docker.io/bruceliu/centos:1.0 0.0s Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them root@liuxiaoweideAir docker-test-volume # ls dockerfile1
# 启动该容器 root@liuxiaoweideAir liuxiaowei # docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat01 1.0 3694687aedfe 20 hours ago 684MB nginx latest 605c77e624dd 10 days ago 141MB tomcat 9.0 b8e65a4d736d 2 weeks ago 680MB tomcat latest fb5657adc892 2 weeks ago 680MB mysql 5.7 c20987f18b13 2 weeks ago 448MB docker/getting-started latest 26d80cd96d69 5 weeks ago 28.5MB ubuntu latest ba6acccedd29 2 months ago 72.8MB centos latest 5d0da3dc9764 3 months ago 231MB bruceliu/centos 1.0 9ec777f9328b 3 months ago 231MB # dockerfile生成的镜像 docker/dev-environments-default stable-1 7c85b0303242 5 months ago 607MB docker/desktop-git-helper 5a4fca126aadcd3f6cc3a011aa991de982ae7000 efe2d67c403b 5 months ago 44.2MB portainer/portainer latest 580c0e4e98b0 9 months ago 79.1MB scrapinghub/splash latest 9364575df985 16 months ago 1.89GB ubuntu 15.10 9b9cb95443b5 5 years ago 137MB training/webapp latest 6fae60ef3446 6 years ago 349MB root@liuxiaoweideAir liuxiaowei # docker run -it 9ec777f9328b /bin/bash [root@6c7b9856d5de /]# ls bin etc lib lost+found mnt proc run srv tmp var volume02 dev home lib64 media opt root sbin sys usr volume01
这两个卷和外部一定有一个是 和外部同步的目录
FROM centos VOLUME ["volume01","volume02"] # 匿名挂载 CMD echo "----end----" # 查看一下卷挂载的路径 docker inspect 容器id "Mounts": [ { "Type": "volume", "Name": "7b40488c0291a9cc8858a2b831fc11e24807b66794fbcb5e0130fd28eb97955d", "Source": "/var/lib/docker/volumes/7b40488c0291a9cc8858a2b831fc11e24807b66794fbcb5e0130fd28eb97955d/_data", "Destination": "volume01", # 对应匿名卷 "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "2a9464346288b8be9bc62743b05aa3cb1652c7167afad3847e0c617027a00847", "Source": "/var/lib/docker/volumes/2a9464346288b8be9bc62743b05aa3cb1652c7167afad3847e0c617027a00847/_data", "Destination": "volume02", # 对应匿名卷 "Driver": "local", "Mode": "", "RW": true, "Propagation } ]
在此提个问题,也是我遇到的 ,这个挂载卷路径在mac系统是不存在的,通过查阅资料,有一种解决方法就是更新docker之后,然后执行screen 路径,就可以了。但是我尝试了还是不行。
不过在centos环境,不存在这个问题
假设构建镜像时候没有挂载卷,就要手动镜像挂载 -v 卷名:容器路径
多个mysql同步数据
# 启动3个容器,通过我们自己写的脚本生成的镜像bruceliu/centos:1.0启动,下面是在centos7环境执行
[root@localhost]# docker run -it --name docker01 bruceliu/centos:1.0.
# 启动第二个容器继承docker01
[root@localhost]# docker run -it --name docker02 --volumes-from docker01 bruceliu/centos:1.0
Docker01 创建文件docker01同步到docker02里面的volume01,如图:
# 只要通过--volumes-from就可以实现容器间的数据共享
# 测试:可以删除docker01,查看一下docker02和docker03是否还可以访问这个文件 。结果是可以的。
多个mysql实现数据共享
root@liuxiaoweideAir ~ # docker run -d -p 3310:3306 -v /Users/liuxiaowei/mysql/conf:/etc/mysql/conf.d -v /Users/liuxiaowei/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
root@liuxiaoweideAir ~ # docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
# 可以实现两个容器数据同步
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦持久化到了本地,这个时候,本地的数据是不会被删除的
查看一下官网是怎么做的?
很多官方镜像都是基础包,很多功能没有。
我们自己的镜像文件可以根据需求构建
dockerfile的命令,通过百度搜索图片。“dockerfile命令”
dockerfile是面向开发的,我们要发布项目,做镜像,需要编写dockerfile文件。这个文件十分简单!
Docker镜像逐渐成为企业交付标准,必须要掌握!
步骤:开发,部署,上线运维,缺一不可!
DockerFile:构建文件,定义了一切的步骤,源代码。
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品。
Docker容器:容器就是镜像运行起来提供服务
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的,姓名+邮箱 (国际通用标准)
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤:例如,tomcat镜像,这个tomcat压缩包就是添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载目录
EXPOSE # 暴露端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,而且可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承的dockerfile,这时候就会运行ONBUILD的指令,触发指令
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量
# 自己创建一个centos # 1.编写Dockerfile文件 FROM centos MAINTAINER bruce_liu<1134593154@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 # 2.通过这个dockerfile文件构建镜像 # 命令docker build -f dockerfile文件路径 -t 镜像名:[tag] . # 3.测试运行 [root@31a3aaa44ff1 local]# ifconfig # 对比之前的原生centos,可以执行ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet) RX packets 11 bytes 946 (946.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# docker history 容器id 可以显示镜像的形成过程
root@liuxiaoweideAir dockerfile#docker history c20987f18b13
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器的时候要运行的命令,可以追加命令
root@liuxiaoweideAir dockerfile # vim dockerfile-cmd-test FROM centos CMD ["ls","-a"] root@liuxiaoweideAir dockerfile # docker build -f dockerfile-cmd-test -t cmd-test . # 通过dockerfile-cmd-test构建镜像 [+] Building 1.1s (5/5) FINISHED => [internal] load build definition from dockerfile-cmd-test 0.3s => => transferring dockerfile: 76B 0.0s => [internal] load .dockerignore 0.4s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => CACHED [1/1] FROM docker.io/library/centos 0.0s => exporting to image 0.1s => => exporting layers 0.0s => => writing image sha256:7d202bdf002be182b794b7f2b4c90c4fe3560c3ac4f8cebc27f1c8a94ab10a9a 0.0s => => naming to docker.io/library/cmd-test 0.0s Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them root@liuxiaoweideAir dockerfile # docker run -it cmd-test # 通过dockerfile-cmd-test构建镜像,直接执行最后一个CMD,“ls -a” . .dockerenv dev home lib64 media opt root sbin sys usr .. bin etc lib lost+found mnt proc run srv tmp var root@liuxiaoweideAir dockerfile # # 想追加一个命令 -l ,也就是我们希望执行ls -al root@liuxiaoweideAir dockerfile # docker run cmd-test -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown. ERRO[0002] error waiting for container: context canceled # 出现这个错误提示,因为CMD的情况下,-l替换了CMD ["ls","-a"]命令,-l不是完整命令,所以报错 # 如下用ls -al 完整命令替换,就不会报错 root@liuxiaoweideAir dockerfile # docker run cmd-test ls -al total 56 drwxr-xr-x 1 root root 4096 Jan 9 11:15 . drwxr-xr-x 1 root root 4096 Jan 9 11:15 .. -rwxr-xr-x 1 root root 0 Jan 9 11:15 .dockerenv lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x 5 root root 340 Jan 9 11:15 dev drwxr-xr-x 1 root root 4096 Jan 9 11:15 etc drwxr-xr-x 2 root root 4096 Nov 3 2020 home lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64 drwx------ 2 root root 4096 Sep 15 14:17 lost+found drwxr-xr-x 2 root root 4096 Nov 3 2020 media drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt drwxr-xr-x 2 root root 4096 Nov 3 2020 opt dr-xr-xr-x 170 root root 0 Jan 9 11:15 proc dr-xr-x--- 2 root root 4096 Sep 15 14:17 root drwxr-xr-x 11 root root 4096 Sep 15 14:17 run lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Nov 3 2020 srv dr-xr-xr-x 13 root root 0 Jan 9 11:15 sys drwxrwxrwt 7 root root 4096 Sep 15 14:17 tmp drwxr-xr-x 12 root root 4096 Sep 15 14:17 usr drwxr-xr-x 20 root root 4096 Sep 15 14:17 var
# 构建entrypoint dockerfile 文件 root@liuxiaoweideAir dockerfile # vim dockerfile-cmd-entrypoint FROM centos ENTRYPOINT ["ls","-a"] # 生成镜像文件 root@liuxiaoweideAir dockerfile # docker build -f dockerfile-cmd-entrypoint -t entry-centos . [+] Building 1.0s (5/5) FINISHED => [internal] load build definition from dockerfile-cmd-entrypoint 0.2s => => transferring dockerfile: 90B 0.0s => [internal] load .dockerignore 0.3s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => CACHED [1/1] FROM docker.io/library/centos 0.0s => exporting to image 0.1s => => exporting layers 0.0s => => writing image sha256:b325f5b972337e763ad3b2c0f1a720eb2d5b11a39b3d88008cc5a0e42393b617 0.0s => => naming to docker.io/library/entry-centos 0.0s Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them root@liuxiaoweideAir dockerfile # docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 1.0 60d5f5ace1c7 About an hour ago 312MB nginx latest 605c77e624dd 10 days ago 141MB tomcat 9.0 b8e65a4d736d 2 weeks ago 680MB mysql 5.7 c20987f18b13 2 weeks ago 448MB docker/getting-started latest 26d80cd96d69 5 weeks ago 28.5MB ubuntu latest ba6acccedd29 2 months ago 72.8MB entry-centos latest b325f5b97233 3 months ago 231MB root@liuxiaoweideAir dockerfile # docker run -it b325f5b97233 # 运行 entrypoint生成的容器 . .dockerenv dev home lib64 media opt root sbin sys usr .. bin etc lib lost+found mnt proc run srv tmp var
# 追击参数-l,正常执行,直接拼接ENTRYPOINT命令后面,没有报错
root@liuxiaoweideAir dockerfile # docker run -it b325f5b97233 -l
total 56
drwxr-xr-x 1 root root 4096 Jan 9 11:36 .
drwxr-xr-x 1 root root 4096 Jan 9 11:36 ..
-rwxr-xr-x 1 root root 0 Jan 9 11:36 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Jan 9 11:36 dev
drwxr-xr-x 1 root root 4096 Jan 9 11:36 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Sep 15 14:17 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
Dockerfile中很多命令都很相似,我们需要了解它们的区别,最好的学习方法就是对他们进行对比测试。
# 在mac系统环境,能够执行 FROM centos MAINTAINER bruce_liu<1134593154@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u261-macosx-x64.dmg.zip /usr/local/ ADD apache-tomcat-9.0.56.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_261 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.56 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.56 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.56/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.56/logs/catalina.out
# 在centos7系统测试 FROM centos MAINTAINER bruce_liu<1134593154@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-17_linux-x64_bin.tar.gz /usr/local/ ADD apache-tomcat-8.5.33.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk-17.0.1 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.33 ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.33 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-8.5.33/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.33/logs/catalina.out
# 由于是官方标准命名Dockerfile,所以不用添加参数-f 最后一定要加上. # 在mac系统环境能够执行,正常生成镜像,但是按结尾提示执行docker scan会报错。 # 如果在centos7环境一切正常,目前没有找到解决办法 root@liuxiaoweideAir tomcat # docker build -t diytomcat . [+] Building 83.8s (11/11) FINISHED => [internal] load build definition from Dockerfile 0.3s => => transferring dockerfile: 681B 0.0s => [internal] load .dockerignore 0.4s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => CACHED [1/6] FROM docker.io/library/centos 0.0s => [internal] load build context 24.9s => => transferring context: 213.39MB 24.7s => [2/6] COPY readme.txt /usr/local/readme.txt 0.7s => [3/6] ADD jdk-8u261-macosx-x64.dmg.zip /usr/local/ 1.8s => [4/6] ADD apache-tomcat-9.0.56.tar.gz /usr/local/ 2.4s => [5/6] RUN yum -y install vim 44.7s => [6/6] WORKDIR /usr/local 0.8s => exporting to image 7.2s => => exporting layers 7.1s => => writing image sha256:ab919c75922607c3239f6634b06651870d267a4a94589c82ccd319fda610b882 0.0s => => naming to docker.io/library/diytomcat 0.0s Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them root@liuxiaoweideAir tomcat # docker images REPOSITORY TAG IMAGE ID CREATED SIZE diytomcat latest ab919c759226 About a minute ago 527MB
# 在centos7测试 # 由于是官方标准命名Dockerfile,所以不用添加参数-f 最后一定要加上. [root@localhost tomcat]# docker build -t diytomcat . Sending build context to Docker daemon 190.3MB Step 1/15 : FROM centos ---> 5d0da3dc9764 Step 2/15 : MAINTAINER bruce_liu<1134593154@qq.com> ---> Running in b22cb9028743 Removing intermediate container b22cb9028743 ---> be05f2b3b86b Step 3/15 : COPY readme.txt /usr/local/readme.txt ---> 1026e7aab5a8 Step 4/15 : ADD jdk-17_linux-x64_bin.tar.gz /usr/local/ ---> de54e65e0916 Step 5/15 : ADD apache-tomcat-8.5.33.tar.gz /usr/local/ ---> 5f002ff16d92 Step 6/15 : RUN yum -y install vim ---> Running in 2622ef5a0401 CentOS Linux 8 - AppStream 4.3 MB/s | 8.4 MB 00:01 CentOS Linux 8 - BaseOS 875 kB/s | 4.6 MB 00:05 CentOS Linux 8 - Extras 13 kB/s | 10 kB 00:00 Dependencies resolved. ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: vim-enhanced x86_64 2:8.0.1763-16.el8 appstream 1.4 M Installing dependencies: gpm-libs x86_64 1.20.7-17.el8 appstream 39 k vim-common x86_64 2:8.0.1763-16.el8 appstream 6.3 M vim-filesystem noarch 2:8.0.1763-16.el8 appstream 49 k which x86_64 2.21-16.el8 baseos 49 k Transaction Summary ================================================================================ Install 5 Packages Total download size: 7.8 M Installed size: 30 M Downloading Packages: (1/5): gpm-libs-1.20.7-17.el8.x86_64.rpm 355 kB/s | 39 kB 00:00 (2/5): vim-filesystem-8.0.1763-16.el8.noarch.rp 1.1 MB/s | 49 kB 00:00 (3/5): vim-enhanced-8.0.1763-16.el8.x86_64.rpm 1.7 MB/s | 1.4 MB 00:00 (4/5): vim-common-8.0.1763-16.el8.x86_64.rpm 5.8 MB/s | 6.3 MB 00:01 (5/5): which-2.21-16.el8.x86_64.rpm 44 kB/s | 49 kB 00:01 -------------------------------------------------------------------------------- Total 2.1 MB/s | 7.8 MB 00:03 warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/gpm-libs-1.20.7-17.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY CentOS Linux 8 - AppStream 66 kB/s | 1.6 kB 00:00 Importing GPG key 0x8483C65D: Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>" Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial Key imported successfully Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : which-2.21-16.el8.x86_64 1/5 Installing : vim-filesystem-2:8.0.1763-16.el8.noarch 2/5 Installing : vim-common-2:8.0.1763-16.el8.x86_64 3/5 Installing : gpm-libs-1.20.7-17.el8.x86_64 4/5 Running scriptlet: gpm-libs-1.20.7-17.el8.x86_64 4/5 Installing : vim-enhanced-2:8.0.1763-16.el8.x86_64 5/5 Running scriptlet: vim-enhanced-2:8.0.1763-16.el8.x86_64 5/5 Running scriptlet: vim-common-2:8.0.1763-16.el8.x86_64 5/5 Verifying : gpm-libs-1.20.7-17.el8.x86_64 1/5 Verifying : vim-common-2:8.0.1763-16.el8.x86_64 2/5 Verifying : vim-enhanced-2:8.0.1763-16.el8.x86_64 3/5 Verifying : vim-filesystem-2:8.0.1763-16.el8.noarch 4/5 Verifying : which-2.21-16.el8.x86_64 5/5 Installed: gpm-libs-1.20.7-17.el8.x86_64 vim-common-2:8.0.1763-16.el8.x86_64 vim-enhanced-2:8.0.1763-16.el8.x86_64 vim-filesystem-2:8.0.1763-16.el8.noarch which-2.21-16.el8.x86_64 Complete! Removing intermediate container 2622ef5a0401 ---> 57606bc79c81 Step 7/15 : ENV MYPATH /usr/local ---> Running in a2c900e33b46 Removing intermediate container a2c900e33b46 ---> c536dc330700 Step 8/15 : WORKDIR $MYPATH ---> Running in 70aede458361 Removing intermediate container 70aede458361 ---> a4757b245dd7 Step 9/15 : ENV JAVA_HOME /usr/local/jdk-17.0.1 ---> Running in cbdbbd45a77d Removing intermediate container cbdbbd45a77d ---> 29a5fec095c0 Step 10/15 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ---> Running in 44cc4bc03fff Removing intermediate container 44cc4bc03fff ---> 7ee1d774dec6 Step 11/15 : ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.33 ---> Running in 7aedcdacefca Removing intermediate container 7aedcdacefca ---> d51a4835e53b Step 12/15 : ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.33 ---> Running in c5545d41cfe0 Removing intermediate container c5545d41cfe0 ---> 3ca740e8fb50 Step 13/15 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin ---> Running in 11e9db1569cc Removing intermediate container 11e9db1569cc ---> fa987bac62df Step 14/15 : EXPOSE 8080 ---> Running in c3f3b3bf9010 Removing intermediate container c3f3b3bf9010 ---> a9f6ace395f0 Step 15/15 : CMD /usr/local/apache-tomcat-8.5.33/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.33/logs/catalina.out ---> Running in 5f8629ecaac4 Removing intermediate container 5f8629ecaac4 ---> c5e5274bde3b Successfully built c5e5274bde3b Successfully tagged diytomcat:latest
# 在centos7环境成功
[root@localhost tomcat]# docker run -d -p 9090:8080 --name bruceliutomcat -v /home/bruce_liu/build/tomcat/test:/usr/local/apache-tomcat-8.5.33/webapps/test -v /home/bruce_liu/build/tomcat/tomcatlogs:/usr/local/apache-tomcat-8.5.33/logs diytomcat
97d08b3ba87ae920cf3fdabfa6b03e9e827310b79c3e9f14db471a1ea65b499f
# 例如在test文件夹下建立WEB-INFO文件夹,然后编辑web.xml <html> <body> <script> if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("GET","cd_catalog.xml",false); xmlhttp.send(); xmlDoc=xmlhttp.responseXML; document.write("<table border='1'>"); var x=xmlDoc.getElementsByTagName("CD"); for (i=0;i<x.length;i++) { document.write("<tr><td>"); document.write(x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue); document.write("</td><td>"); document.write(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue); document.write("</td></tr>"); } document.write("</table>"); </script> </body> </html>
# 在宿主机的test路径下建一个文件index.jsp # 在外网访问成功 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Bruce_liu</title> </head> <body> Hello Bruce_liu!<br/> <% out.println("你的 IP 地址 " + request.getRemoteAddr()); %> </body> </html>
结果:项目部署成功,可以直接访问!✌️
题外话:
假设以后搞开发,那么需要掌握Dockerfile的编写,所有项目一律都使用docker镜像发布运行!
1、地址:https://hub.docker.com/注册自己的账号
2、确定这个账号可以登录
3、在这个服务器上提交自己的镜像
# centos7环境 root@localhost test]# 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 # 登录账号 [root@localhost test]# docker login -u bruceliu1973 Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
4、登录完毕,可以提交镜像,执行docker push命令
# 在centos7环境执行,但是出现一个问题 [root@localhost test]# docker push diytomcat Using default tag: latest The push refers to repository [docker.io/library/diytomcat] 41597dc9883c: Preparing ba91795798ac: Preparing 43b27989aa87: Preparing 9445929b0a14: Preparing 74ddd0ec08fa: Preparing denied: requested access to the resource is denied # 解决push镜像的问题 # 给镜像增加一个tag # 语法,[root@localhost test]#docker tag 容器id username/imagename *****username 是dockerhub用户名,imagename是镜像名, imagename一定跟要push的镜像名一样,否则还是被拒绝 [root@localhost test]# docker tag 66f61ab160f4 bruceliu1973/diytomcat:1.0 # 修改为username/imagename:tag格式,push成功,如下图 [root@localhost tomcat]# docker push bruceliu1973/diytomcat:1.0 The push refers to repository [docker.io/bruceliu1973/diytomcat] 41597dc9883c: Pushed ba91795798ac: Pushed 43b27989aa87: Pushed 9445929b0a14: Pushed 74ddd0ec08fa: Pushed 1.0: digest: sha256:f37ddc8c0333224c1e5a98588469919bad63aa5632722977c56720718e6886f5 size: 1372
注意:提交的时候也是按照镜像的层级来进行提交的。
1、登录阿里云
2、找到容器镜像服务(https://cr.console.aliyun.com/cn-hangzhou/instances)
3、创建命名空间
4、创建容器镜像
5、浏览阿里云
点击仓库,看到里面有一些基本信息。
# 登录阿里云
[root@localhost ~]# docker login --username=bruce刘晓伟 registry.cn-hangzhou.aliyuncs.com
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json. # 宿主机这里存储用户名和密码,json文件未加密
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
# 登录成功以后,执行
[root@localhost ~]# docker tag[ImageId] registry.cn-hangzhou.aliyuncs.com/bruce_liu1973/bruce_liuxiaowei:[镜像版本号]
# 本例
[root@localhost ~]# docker tag[ImageId] registry.cn- hangzhou.aliyuncs.com/bruce_liu1973/bruce_liuxiaowei:66f61ab160f4
# docker push,严格按照阿里云镜像推送命令格式执行,否则会被拒绝
[root@localhost ~]# docker push bruceliu1973/diytomcat:1.0 # 这个命令格式传DockerHub可以,传阿里云拒绝
# 按照阿里云格式推送到Registry,[镜像版本号]为上一步骤生成的版本号,此例为1.0,不是imageId
[root@localhost ~]# docker tag[ImageId] registry.cn-hangzhou.aliyuncs.com/bruce_liu1973/bruce_liuxiaowei:[镜像版本号]
# 实际操作命令格式
[root@localhost ~]# docker push registry.cn-hangzhou.aliyuncs.com/bruce_liu1973/bruce_liuxiaowei:1.0
总结:阿里云容器镜像参考并严格按照官方文档格式执行命令。
以后如果想让自己的网站被大家访问,就可以把网站镜像发到阿里云或者DockerHub,然后大家pull—run— OK
镜像打包成一个tar压缩包,可以发送压缩包给别人,涉及到两个命令
[root@localhost ~]# docker save --help
Usage: docker save [OPTIONS] IMAGE [IMAGE...]
Save one or more images to a tar archive (streamed to STDOUT by default)
Options:
-o, --output string Write to a file, instead of STDOUT
# centos7系统环境 # 清空所有容器 [root@localhost ~]#docker rm -f $(docker ps -aq) 5b2b527d0cde 7f3c9bbc1a19 0153e509926d d0184a7eb0ed cb638941890b 1ce46e3625c8 31a3aaa44ff1 9ed360d184c0 1ac5ac579488 # 清除所有镜像 [root@localhost ~]# docker rmi -f $(docker images -aq) Deleted: sha256:164e693bcb758292a0fc8b32b9c40d053d33eb3f5418b5a84a42f911a7121bb8 Untagged: mycentos:1.0 Deleted: sha256:60d5f5ace1c7cb9e3f882b494671a973f5a5dc6eb28479c30149fc3c796116b5 Untagged: nginx:latest Untagged: nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31 Deleted: sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85 Deleted: sha256:b625d8e29573fa369e799ca7c5df8b7a902126d2b7cbeb390af59e4b9e1210c5 Deleted: sha256:7850d382fb05e393e211067c5ca0aada2111fcbe550a90fed04d1c634bd31a14 Deleted: sha256:02b80ac2055edd757a996c3d554e6a8906fd3521e14d1227440afd5163a5f1c4 Deleted: sha256:b92aa5824592ecb46e6d169f8e694a99150ccef01a2aabea7b9c02356cdabe7c Deleted: sha256:780238f18c540007376dd5e904f583896a69fe620876cabc06977a3af4ba4fb5 Deleted: sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f Untagged: tomcat:9.0 Untagged: tomcat@sha256:cd96d4f7d3f5fc4d3bc1622ec678207087b8215d55021a607ecaefba80b403ea Deleted: sha256:b8e65a4d736dca28cd65b1b3b18100aad2984fc9a484d423db7a8fcee1ed5d48 Deleted: sha256:7cea9b28ec076e69d2921f8fec7a6a0d40a815d8fc91a5ecfb7e817a0ae6d5cf
测试
# centos7系统环境 # 查看IP地址 1.lo:本机回环地址 2.ens33:阿里云内网地址 5.docker0:docker地址(可以想象为路由器),也是其他容器的gw [root@localhost ~]# ip add 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:90:b4:23 brd ff:ff:ff:ff:ff:ff inet 172.16.12.154/24 brd 172.16.12.255 scope global noprefixroute dynamic ens33 valid_lft 1499sec preferred_lft 1499sec inet6 fe80::20c:29ff:fe90:b423/64 scope link valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:46:90:be brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:46:90:be brd ff:ff:ff:ff:ff:ff 5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:d4:3f:64:05 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:d4ff:fe3f:6405/64 scope link valid_lft forever preferred_lft forever 6: br-983a1a9b2f0f: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:dd:dd:3e:ce brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-983a1a9b2f0f valid_lft forever preferred_lft forever inet6 fe80::42:ddff:fedd:3ece/64 scope link valid_lft forever preferred_lft forever
三个网络
# 问题:docker 是如何处理容器网络访问的?
tomcat 容器 ----------> mysql 容器
# centos7系统环境 # 执行一个tomcat容器运行命令 [root@localhost ~]# docker run -d -P --name tomcat01 tomcat # 查看容器的内部网络地址 ip addr [root@localhost ~]# docker exec -it tomcat01 ip addr ****如果出现报错提示**** [root@localhost ~]# docker exec -it tomcat01 ip addr OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown # 按照如下方式解决 # 执行如下命令交互模式进入容器内 [root@localhost ~]# docker exec -it 6fde5463673b /bin/bash root@6fde5463673b:/usr/local/tomcat# pwd /usr/local/tomcat # 在容器内安装iproute2 root@6fde5463673b:/usr/local/tomcat# apt update && apt install -y iproute2 Get:1 http://security.debian.org/debian-security bullseye-security InRelease [44.1 kB] Get:2 http://deb.debian.org/debian bullseye InRelease [116 kB] Get:3 http://deb.debian.org/debian bullseye-updates InRelease [39.4 kB] Get:4 http://security.debian.org/debian-security bullseye-security/main amd64 Packages [102 kB] Get:5 http://deb.debian.org/debian bullseye/main amd64 Packages [8183 kB] Get:6 http://deb.debian.org/debian bullseye-updates/main amd64 Packages [2592 B] Fetched 8487 kB in 3min 44s (37.9 kB/s) Reading package lists... Done Building dependency tree... Done Reading state information... Done All packages are up to date. Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: libatm1 libbpf0 libcap2 libcap2-bin libelf1 libmnl0 libpam-cap libxtables12 # 容器内安装ping命令 [root@localhost ~]# apt-get install iputils-ping # 安装vim命令 [root@localhost ~]# apt-get install vim #安装ifconfig命令 [root@localhost ~]#apt-get install net-tools # 在容器内执行 ip addr,发现容器启动的时候会得到一个eth0@if18 ip地址,docker分配 [root@6fde5463673b:/usr/local/tomcat]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 17: eth0@if18: <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 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever # 思考:linux宿主机能不能ping通容器内部 # 在linux宿主机ping docker容器ip地址,结果如下,可以ping通 [root@localhost ~]# 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=5.87 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.054 ms 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.061 ms --- 172.17.0.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev = 0.054/1.995/5.871/2.740 ms
原理
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个默认网卡docker桥接模式,使用的技术是***veth-pair***技术,如图所示:
在centos7宿主机再次测试 ip addr
# 在宿主机linux环境执行,查看ip配置信息 [root@localhost ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:90:b4:23 brd ff:ff:ff:ff:ff:ff inet 172.16.12.154/24 brd 172.16.12.255 scope global noprefixroute dynamic ens33 valid_lft 1654sec preferred_lft 1654sec inet6 fe80::20c:29ff:fe90:b423/64 scope link valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:46:90:be brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:46:90:be brd ff:ff:ff:ff:ff:ff 5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:d4:3f:64:05 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:d4ff:fe3f:6405/64 scope link valid_lft forever preferred_lft forever 6: br-983a1a9b2f0f: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:dd:dd:3e:ce brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-983a1a9b2f0f valid_lft forever preferred_lft forever inet6 fe80::42:ddff:fedd:3ece/64 scope link valid_lft forever preferred_lft forever # 启动一个容器,宿主机就会出现一对网卡 18: veth4f4cbe7@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether ca:17:c3:c0:51:6c brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::c817:c3ff:fec0:516c/64 scope link valid_lft forever preferred_lft forever
2、再启动一个容器tomcat02测试,发现又多了一对网卡
# 我们发现容器带来的网卡,都是成对出现
# veth-pari就是一对的虚拟设备接口,所有容器的指向一个共同网关,宿主机docker0
# OpenStac Docker容器之间的连接,OVS的连接,都是使用veth-pair技术
3、测试一下tomcat01和tomcat02是否ping通,完全可以,都在一个网段
结论:tomcat01和tomcat02是共用一个路由器docker0,所有的容器在不指定网络的情况下,都是有docker0转发。
Docker中的所有网络接口都是虚拟的,虚拟的转发效率高。(内网传递文件)
如果容器删除,对应的vets-pair对删除(veth-pair)
# 直接这样执行是ping不通的 [root@localhost ~]# docker exec -it tomcat02 ping tomcat01 ping:tomcat01: No address associated with hostname # 如何解决呢? # 通过 --link即可以解决网络连通问题 [root@localhost ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat 3e5adcd4d5b5e4b488f6f68747c21886d157e3518180d8109d607b2de8281d21 [root@localhost ~]# 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=24.5 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.074 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.098 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.078 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=5 ttl=64 time=0.075 ms # 反向可以ping通吗? [root@localhost ~]# docker exec -it tomcat02 ping tomcat03 ping:tomcat03: No address associated with hostname
# 在centos系统环境执行如下命令 # 第一行是docker0 [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE f0252b7d323e bridge bridge local 4d03c52372e1 host host local 898465300bee none null local 983a1a9b2f0f x34-arbitrary-file-deletion_default bridge local # 然后执行docker network inspect [NETWORK ID] [root@localhost ~]# docker network inspect f0252b7d323e [ { "Name": "bridge", "Id": "f0252b7d323ed587414479e7c9500efe84a011bee1fc745674a6193fc2147874", "Created": "2022-01-09T15:16:02.834596925-05:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", # 默认docker0 "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" # 网关docker0 } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "2923494636b68c0208e750a5617387899a50ac8ff5f59a139d2e1b3d49f9725e": { "Name": "tomcat01", "EndpointID": "8b947e54e960868ec731fb26371916b20d5f1fe9e583b5b4fd05359d58b504bb", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", # 每启动一个容器,不指定ip,容器就会随机分配一个IP "IPv6Address": "" }, "3e5adcd4d5b5e4b488f6f68747c21886d157e3518180d8109d607b2de8281d21": { "Name": "tomcat03", "EndpointID": "186c9a43a4ca47d8603e5487c6f909fc5490b2bdb9456d719d230cc592e6df4c", "MacAddress": "02:42:ac:11:00:04", "IPv4Address": "172.17.0.4/16", # 每启动一个容器,不指定ip,容器就会随机分配一个IP "IPv6Address": "" }, "fc4aa0be8b52ff3967ad44a5e6678e194767f26e1fd3840d9e2b1340fa24e1df": { "Name": "tomcat02", "EndpointID": "872b06c64cbca78d15d3a0fb5f4b559e5fe02cb649a86020d40a1f20e2838948", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", # 每启动一个容器,不指定ip,容器就会随机分配一个IP "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]
其实这个tomcat03就是在本地配置了tomcat02的配置
# 查看hosts配置,在这里可以发现原理。
[root@localhost ~]# docker exec -it 3e5adcd4d5b5 cat /etc/hosts
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 fc4aa0be8b52 # 在 tomcat03的hosts配置里172.17.0.3 ---->tomcat02映射
172.17.0.4 3e5adcd4d5b5 # tomcat03
本质:–link就是我们在hosts配置里增加了一条172.17.0.3 tomcat02 fc4aa0be8b52映射
真实操作场景,已经***不建议***使用–link了!!
自定义网络,***不适用***docker0!
docker0问题:***不支持***容器名连接访问!
[root@localhost ~] # docker network ls
NETWORK ID NAME DRIVER SCOPE
f0252b7d323e bridge bridge local
4d03c52372e1 host host local
898465300bee none null local
983a1a9b2f0f x34-arbitrary-file-deletion_default bridge local
清空网络容器
[root@localhost ~]#docker rm -f $(docker ps -aq)
# 直接启动的命令 --net bridge, 这个就是docker0 [root@localhost ~] # docker run -d -P --name tomcat01 tomcat # 原来的启动方式 [root@localhost ~] # docker run -d -P --name tomcat01 --net bridge tomcat # 默认 # docker0特点:默认,域名不能访问, --link可以打通连接 # 我们可以自定义网络 # --driver bridge # --subnet 192.168.0.0/24 # --gateway 192.168.0.1 [root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 mynet 3fa16a661c63da775336a98aadba1447d69e01009f5afbf2e38f2bbb0cdf669d [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE f0252b7d323e bridge bridge local 4d03c52372e1 host host local 3fa16a661c63 mynet bridge local 898465300bee none null local 983a1a9b2f0f x34-arbitrary-file-deletion_default bridge local # 查看一下自己创建的网络配置信息 [root@localhost ~]# docker network inspect 3fa16a661c63 [ { "Name": "mynet", "Id": "3fa16a661c63da775336a98aadba1447d69e01009f5afbf2e38f2bbb0cdf669d", "Created": "2022-01-10T08:18:36.27124654-05:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/24", # 子网 "Gateway": "192.168.0.1" # 网关 } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
启动一个容器,网络配置是我们自己创建的网络
# 启动两个容器,网络配置mynet [root@localhost ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat 5a85dd02380c7c62714c3fe64e959ad3f1d98d33e44d61e212c3e864e229f927 [root@localhost ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat a207c17e91dbde264af88b999cd12497d8a649692d5c96d081c8bd09547bb04b # 查看一下自己创建的网络配置信息,发现两个容器的网络配置都已配置好 [root@localhost ~]# docker network inspect mynet [ { "Name": "mynet", "Id": "3fa16a661c63da775336a98aadba1447d69e01009f5afbf2e38f2bbb0cdf669d", "Created": "2022-01-10T08:18:36.27124654-05:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/24", "Gateway": "192.168.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "5a85dd02380c7c62714c3fe64e959ad3f1d98d33e44d61e212c3e864e229f927": { "Name": "tomcat-net-01", "EndpointID": "3efde84d7d3d212a6d4a464467a7baf08a4577036b9c29c116f4a6977451190c", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/24", # 容器 01 网络配置 "IPv6Address": "" }, "a207c17e91dbde264af88b999cd12497d8a649692d5c96d081c8bd09547bb04b": { "Name": "tomcat-net-02", "EndpointID": "1d055768a18f5d2f21b14a90a8182f103cd5d33234918b9acfcca87204545825", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/24", # 容器 02 网络配置 "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] # 再次测试ping连接 [root@localhost ~]# docker exec -it tomcat-net-01 ping 192.168.0.3 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.100 ms 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.072 ms 64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.088 ms # 现在不使用--link,也可以ping容器名字 [root@localhost ~]# docker exec -it tomcat-net-01 ping tomcat-net-02 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.117 ms 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.069 ms 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.136 ms
好处:
Redis – 不同的集群使用不同的网络,保证集群都是安全和健康的 例如:192.168.0.1/24
MySQL-- 不同的集群使用不同的网络,保证集群是安全和健康的 例如:192.168.0.2/24
# 查看docker network 帮助文件 [root@localhost ~]# docker network --help Usage: docker network COMMAND Manage networks Commands: connect Connect a container to a network # 连通一个容器到一个网络,结合下图 容器tomcat-01到mynet网络 create Create a network disconnect Disconnect a container from a network inspect Display detailed information on one or more networks ls List networks prune Remove all unused networks rm Remove one or more networks Run 'docker network COMMAND --help' for more information on a command.
# 测试tomcat-01容器连通mynet网络
# 执行docker network inspect mynet,发现容器tomcat-01加在了mynet网络
[root@localhost ~]# docker network connect mynet tomcat-01
# 再次检测一下mynet配置信息,结果如图:
# 发现tomcat-01容器有两个IP地址{172.17.0.2/16 192.168.0.4/24},类似于阿里云服务:公网ip 私网ip
[root@localhost ~]# docker network inpsect mynet
# 测试tomcat-01 ping tomcat-net-01, 测试成功ok
[root@localhost ~]# docker exec -it tomcat-01 ping tomcat-net-01
# tomcat-02 依然ping不通,但是加入mynet就可以
[root@localhost ~]# docker network connect mynet tomcat-02
结论
如果跨网段连接,需要使用docker network connect命令连通!✌️
m : master s : slave
首先移除所有容器
[root@localhost ~]# docker rm -f $(docker ps -aq)
# 创建网卡 docker network create redis --subnet 172.38.0.0/16 # 创建完之后可以查看一下,[root@localhost ~]# docker network ls # 查看redis配置 [root@localhost ~]# docker network inspect redis # 通过脚本创建六个redis配置 # for 循环6次,因为创建六个redis配置 for port in $(seq 1 6); \ do \ mkdir -p /mydata/redis/node-${port}/conf touch /mydata/redis/node-${port}/conf/redis.conf cat <<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 # 接下来启动容器 # 可以用这个做脚本,Python编程,批量运行容器 [root@localhost ~]# docker run -p 637${port}:6379 -p 1637${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; \ # 以下的容器启动过程可以用python编个脚本执行,很简单 [root@localhost ~]# 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 [root@localhost ~]# 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 [root@localhost ~]# 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 [root@localhost ~]# 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 [root@localhost ~]# docker run -p 6375:6379 -p 16375:16379 --name redis5 \ -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 [root@localhost ~]# 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 # 创建集群 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 # 创建集群代码及运行过程 /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 >>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 172.38.0.15:6379 to 172.38.0.11:6379 Adding replica 172.38.0.16:6379 to 172.38.0.12:6379 Adding replica 172.38.0.14:6379 to 172.38.0.13:6379 M: 43362f7068a0318c81705e6b1d4ed9fe8235e3ec 172.38.0.11:6379 slots:[0-5460] (5461 slots) master M: 3062e9bbc8f3b4af1e9b4be85a5cfe42deb86543 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master M: ab3fd407c91b53077117f2d4e81a3c52c2082d99 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master S: b7ad902f534c30879eaeb27afb7b364c114369b4 172.38.0.14:6379 replicates ab3fd407c91b53077117f2d4e81a3c52c2082d99 S: 46852447ade8944c1b565dad320b974d70fd9b43 172.38.0.15:6379 replicates 43362f7068a0318c81705e6b1d4ed9fe8235e3ec S: 7b2915b456a5d3663df65d878721fcb5659a91ba 172.38.0.16:6379 replicates 3062e9bbc8f3b4af1e9b4be85a5cfe42deb86543 Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join ... >>> Performing Cluster Check (using node 172.38.0.11:6379) M: 43362f7068a0318c81705e6b1d4ed9fe8235e3ec 172.38.0.11:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: ab3fd407c91b53077117f2d4e81a3c52c2082d99 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: 46852447ade8944c1b565dad320b974d70fd9b43 172.38.0.15:6379 slots: (0 slots) slave replicates 43362f7068a0318c81705e6b1d4ed9fe8235e3ec M: 3062e9bbc8f3b4af1e9b4be85a5cfe42deb86543 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: b7ad902f534c30879eaeb27afb7b364c114369b4 172.38.0.14:6379 slots: (0 slots) slave replicates ab3fd407c91b53077117f2d4e81a3c52c2082d99 S: 7b2915b456a5d3663df65d878721fcb5659a91ba 172.38.0.16:6379 slots: (0 slots) slave replicates 3062e9bbc8f3b4af1e9b4be85a5cfe42deb86543 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. /data #
请注意: master 172.38.0.13 fail , 172.38.0.14 slave 自动变为master
总结:因此有了docker容器技术之后,我们可以利用docker让所有的技术变得简单高效!
# 下图是在centos7系统下的IDEA开发环境
1、打开IDEA
[root@localhost ~]# cd /opt/idea-IU_181.5540.23/bin/
[root@localhost bin]# ./idea.sh
# 进入IDEA环境之后,新建project,本实例均采取默认命名
# 建立一个controller package,再写一个HelloController.java小程序
# 编译成功
# 本地测试一下,浏览器地址栏输入localhost:8080/hello, 成功!
# 接下来在Maven Projects窗口执行package进行打包,生成jar包
# 进入File-->Settings-->--Plugins-->docker-->search in repository,安装Docker插件
# 在target文件夹下右键-->File-->新建Dockerfile文件,用于生成docker镜像
# 建一个名为idea文件夹,将Dockerfile,demo-0.0.1-SNAPSHOT.jar包文件拷贝过来
[root@localhost ~]# docker build -t bruce_liu .
# 启动容器
[root@localhost ~]# docker run -d -P --name Bruce_liu-springboot-web bruce_liu
# 在宿主机或者外部电脑浏览器输入http://172.16.12.154:49153/hello,声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/260804?site
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。