笔记来源:
再小的帆也能远航 !!!
Docker学习
环境准备
1 CentOS 7 或者远程服务器
2 使用shell远程连接服务器进行操作
环境查看
[root@xxz /]# cd / # 根目录下操作
[root@xxz /]# uname -r # 版本查看
3.10.0-1160.92.1.el7.x86_64
[root@xxz /]# 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"
一 Docker安装
安装docker
较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。
# 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 设置镜像的仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 使用阿里云源
# 4 先更新 yum 软件包的索引
yum makecache fast
# 5安装 Docker Engine-Community 安装dokcer docker-ce 社区版 ee 企业版
sudo yum install docker-ce docker-ce-cli containerd.io
# 6 启动docker
sudo systemctl start docker
# 7 查看版本
docker version
# 8 测试启动
docker run hello-world
# 9 查看镜像
[root@xxz /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d2c94e258dcb 7 months ago 13.3kB
卸载docker
# 1 卸载 Docker 依赖
yum remove docker-ce docker-ce-cli containerd.io
# 2 删除资源
rm -rf /var/lib/docker # dockerd的默认资源路径
阿里云镜像加速
- 先登录你的阿里云服务器 并找到容器镜像服务
- 配置使用
# 1 新建一个 目录存放
sudo mkdir -p /etc/docker
# 2 编写配置
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://2q7tffcp.mirror.aliyuncs.com"]
}
EOF
# 3 服务重启
sudo systemctl daemon-reload
# 4 启动dcker 现在docker就会提速
sudo systemctl restart docker
到此就配置完毕了!!!!!!!!!
Run的流程和Docker原理
底层原理:
Docker 是一个Client-Server 结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
DockerServer 接收到 Docker-Client 的指令,就会执行这个命令!
Docker 为什么比 VM 快?
1 docker有着比虚拟机更少的抽象层。
2 docker利用的是宿主机的内核,、而VM需要Guest OS
当新建一个 容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,
虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒
钟。
二 Docker的常用命令
帮助命令
docker version # docker版本信息
docker info # 系统级别的信息,包括镜像和容器的数量
docker --help # 万能命令
docker帮助文档
镜像命令
1 docker images 查看
查看所有本地主机上的镜像
[root@xxz ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d2c94e258dcb 7 months ago 13.3kB
# 解释
REPOSITORY # 镜像的仓库
TAG # 镜像的标签
IMAGE ID # 镜像的ID
CREATED # 镜像的创建时间
SIZE # 镜像的大小
# 可选项
--all , -a # 列出所有镜像
--quiet , -q # 只显示镜像的id
2 docker search 查找
查找镜像
[root@xxz ~]# docker search mysql # 搜索所有的mysql 镜像
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 14718 [OK]
mariadb MariaDB Server is a high performing open sou… 5617 [OK]
percona Percona Server is a fork of the MySQL relati… 623 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 915 [OK]
bitnami/mysql Bitnami MySQL Docker Image 105 [OK]
bitnami/mysqld-exporter 6
cimg/mysql 2
ubuntu/mysql MySQL open source fast, stable, multi-thread… 55
rapidfort/mysql RapidFort optimized, hardened image for MySQL 25
rapidfort/mysql8-ib RapidFort optimized, hardened image for MySQ… 9
google/mysql MySQL server for Google Compute Engine 25 [OK]
rapidfort/mysql-official RapidFort optimized, hardened image for MySQ… 9
hashicorp/mysql-portworx-demo 0
elestio/mysql Mysql, verified and packaged by Elestio 0
bitnamicharts/mysql 0
newrelic/mysql-plugin New Relic Plugin for monitoring MySQL databa… 1 [OK]
# 可选项
--filter=stars=3000 # 搜素出来的镜像就是stars大于3000的
[root@xxz ~]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 14718 [OK]
mariadb MariaDB Server is a high performing open sou… 5617 [OK]
3 docker pull 下载
下载镜像
# 下载镜像,docker pull 镜像名[:tag]
[root@xxz ~]# docker pull mysql
Using default tag: latest # 如果不写tag,默认就是latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete # 分层下载,dockerimages的核心,联合文件系统
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
# 指定版本下载
[root@xxz ~]# 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
# 查看本地镜像
[root@xxz ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f5a6b296b8a2 3 months ago 187MB
redis latest e0ce02f88e58 4 months ago 130MB
mysql <none> d7b085374dbc 4 months ago 581MB
hello-world latest d2c94e258dcb 7 months ago 13.3kB
mysql 5.7 c20987f18b13 24 months ago 448MB
mysql latest 3218b38490ce 24 months ago 516MB
4 docker rmi 删除
删除镜像
[root@xxz ~]# docker rmi -f 容器id # 删除指定容器
[root@xxz ~]# docker rmi -f 容器id 容器id 容器id # 删除多个容器
[root@xxz ~]# docker rmi -f $(docker images -aq) # 删除所有容器
[root@xxz ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f5a6b296b8a2 3 months ago 187MB
redis latest e0ce02f88e58 4 months ago 130MB
mysql <none> d7b085374dbc 4 months ago 581MB # 删除这个
hello-world latest d2c94e258dcb 7 months ago 13.3kB
mysql 5.7 c20987f18b13 24 months ago 448MB
mysql latest 3218b38490ce 24 months ago 516MB
[root@xxz ~]# docker rmi -f d7b085374dbc # 删除指定镜像
Untagged: mysql@sha256:2eabad08824e3120dbec9096c276e3956e1922636c06fbb383ae9ea9c499bf43
Deleted: sha256:d7b085374dbc1ca6ee83a18b488b9da0425749c87051e8bd8287dc2a2c775ecb
[root@xxz ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f5a6b296b8a2 3 months ago 187MB
redis latest e0ce02f88e58 4 months ago 130MB
hello-world latest d2c94e258dcb 7 months ago 13.3kB
mysql 5.7 c20987f18b13 24 months ago 448MB
mysql latest 3218b38490ce 24 months ago 516MB
容器命令
说明: 我们有了镜像才可创建容器,linux,下载一个centos镜像来测试学习
docker pull centos # 下载一个centos系统 下载完去启动
[root@xxz ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
run 帮助命令
docker run --help 这里获取可选参数
1 新建容器并启动
# docker run [可选参数] image
# 参数说明
--name=“Name” 容器名字 tomcat01 tomcat02 用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用) # 常用
-p 容器端口
容器端口
-p 随机指定端口
# 测试,启动并进入容器
[root@xxz ~]# docker images # 查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 5d0da3dc9764 2 years ago 231MB
[root@xxz ~]# docker run -it centos /bin/bash # linux下有很多命令 比如 sh bash命令 而且linux的控制台都在bin目录下 这里默认bash命令
[root@2ac2cefbc60d /]# ls # 查看容器内的centos,基础版本,很多命令是不完善的
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@2ac2cefbc60d /]# exit
exit
[root@xxz /]# ls
bin boot dev etc home lib lib64 lost+found media mnt New File New Folder nohup.out opt proc root run sbin share srv sys tmp usr var
2 列出所有的运行的容器
# docker ps 命令 # 列出当前正在运行的容器
-a # 列出正在运行的容器包括历史容器
-n=? # 显示最近创建的容器
-q # 只显示当前容器的编号
[root@xxz /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@xxz /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ac2cefbc60d centos "/bin/bash" 3 minutes ago Exited (0) 3 minutes ago silly_taussig
19c3da3b4869 d2c94e258dcb "/hello" 11 hours ago Exited (0) 11 hours ago elated_lederberg
6fdfc38f9e3c nginx "/docker-entrypoint.…" 3 months ago Created hopeful_ishizaka
610d94fc129b nginx "/docker-entrypoint.…" 3 months ago Exited (0) 3 months ago cranky_hodgkin
71e54947bf39 redis "docker-entrypoint.s…" 3 months ago Exited (0) 3 months ago xxz-redis
[root@xxz /]# docker ps -qa
2ac2cefbc60d
19c3da3b4869
6fdfc38f9e3c
ecec96ba11fa
10b24b7def92
610d94fc129b
3 退出容器
exit # 直接退出容器并关闭
Ctrl + P + Q # 容器不关闭退出
4 删除容器
docker rm -f 容器id # 删除指定容器
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -a -q|xargs docker rm -f # 删除所有的容器
5 启动和停止容器的操作
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前的容器
常用的其他命令
1 后台启动容器
# 命令 docker run -d 镜像名
[root@xxz /]# docker run -d centos
413a4508621e065bdcd72cd9928e6be26b1e64eaa1a29f3b80a4fdd6b4a5d1f2
[root@xxz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 问题 docker ps, 发现centos停止了
# 常见的坑, docker 容器使用后台运行, 就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx, 容器启动后,发现自己没有提供服务,就会立即停止,就是没有程序了
2 查看日志
docker logs -tf --tail number 容器id # number 就是你想看几条
[root@xxz ~]# docker logs -tf --tail 10 8832910e1e81
^C
[root@xxz ~]#
# 因为运行的centos 容器没有数据所以 日志先看的时候是空白的 所以==》
# 自己编写一段shell脚本
[root@xxz ~]# docker run -d centos /bin/sh -c "while true;do echo 张优秀;sleep 1;done"
8348e12267693896e315d848a4c2db640f7d904f4f77e5d9ea5a6bcce0caee95
[root@xxz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8348e1226769 centos "/bin/sh -c 'while t…" 3 seconds ago Up 2 seconds laughing_sanderson
8832910e1e81 centos "/bin/bash" 7 minutes ago Up 7 minutes funny_wilbur
[root@xxz ~]# docker logs -tf --tail 10 8348e1226769
2023-12-20T11:04:53.018141942Z 张优秀
2023-12-20T11:04:54.020022438Z 张优秀
2023-12-20T11:04:55.022074115Z 张优秀
2023-12-20T11:04:56.023946434Z 张优秀
2023-12-20T11:04:57.025911394Z 张优秀
2023-12-20T11:04:58.027833437Z 张优秀
2023-12-20T11:04:59.029705033Z 张优秀
2023-12-20T11:05:00.031569462Z 张优秀
2023-12-20T11:05:01.033461115Z 张优秀
2023-12-20T11:05:02.035369809Z 张优秀
2023-12-20T11:05:03.037539563Z 张优秀
2023-12-20T11:05:04.039434744Z 张优秀
2023-12-20T11:05:05.041362123Z 张优秀
2023-12-20T11:05:06.043370082Z 张优秀
2023-12-20T11:05:07.045226240Z 张优秀
2023-12-20T11:05:08.047107785Z 张优秀
2023-12-20T11:05:09.049010028Z 张优秀
2023-12-20T11:05:10.051060757Z 张优秀
2023-12-20T11:05:11.053015410Z 张优秀
2023-12-20T11:05:12.054880404Z 张优秀
2023-12-20T11:05:13.056895840Z 张优秀
2023-12-20T11:05:14.058867724Z 张优秀
# 显示日志
-tf # 显示日志
--tail number # 显示日志条数
[root@xxz /]# docker logs -tf --tail 10 容器id
3 查看容器中进程信息
# 命令 docker top 容器id
[root@xxz /]# docker run -d centos # 先后台启动centos容器
f25359202bb726ba1fa17c27de1cfeed0c3c21e8e40d8047befdc0aaed7e7285
[root@xxz /]# docker ps # 查看正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9152d789dc91 centos "/bin/bash" About a minute ago Up About a minute cranky_swartz
[root@xxz /]# docker top 9152d789dc91 # **查看容器中进程信息ps**
UID PID PPID C STIME TTY TIME
root 32075 32056 0 19:17 pts/0 00:00:00
4 查看容器的元数据
# 命令
# docker inspect 容器id
docker inspect 9152d789dc91 # 查看centos容器的元信息
[root@xxz /]# docker inspect 9152d789dc91
[
{
"Id": "9152d789dc9127b30808e031bbb2c3f4a38384322d5039e00e0d9a9977bf907c",
"Created": "2023-12-20T11:17:24.270821834Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 32075,
"ExitCode": 0,
"Error": "",
"StartedAt": "2023-12-20T11:17:24.499153295Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
"ResolvConfPath": "/var/lib/docker/containers/9152d789dc9127b30808e031bbb2c3f4a38384322d5039e00e0d9a9977bf907c/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/9152d789dc9127b30808e031bbb2c3f4a38384322d5039e00e0d9a9977bf907c/hostname",
"HostsPath": "/var/lib/docker/containers/9152d789dc9127b30808e031bbb2c3f4a38384322d5039e00e0d9a9977bf907c/hosts",
"LogPath": "/var/lib/docker/containers/9152d789dc9127b30808e031bbb2c3f4a38384322d5039e00e0d9a9977bf907c/9152d789dc9127b30808e031bbb2c3f4a38384322d5039e00e0d9a9977bf907c-json.log",
"Name": "/cranky_swartz",
"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,
"ConsoleSize": [
44,
180
],
"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",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"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",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/618c1cc07d57d1f667e693a2e58bde8fe8267a81fd360503c0f7fb5593ceed63-init/diff:/var/lib/docker/overlay2/8352204b32f62512e755b73f63c78936b8284e3c9cbeb943245a72a8ae02bae9/diff",
"MergedDir": "/var/lib/docker/overlay2/618c1cc07d57d1f667e693a2e58bde8fe8267a81fd360503c0f7fb5593ceed63/merged",
"UpperDir": "/var/lib/docker/overlay2/618c1cc07d57d1f667e693a2e58bde8fe8267a81fd360503c0f7fb5593ceed63/diff",
"WorkDir": "/var/lib/docker/overlay2/618c1cc07d57d1f667e693a2e58bde8fe8267a81fd360503c0f7fb5593ceed63/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "9152d789dc91",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": true,
"OpenStdin": true,
"StdinOnce": false,
"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": "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": "276680b6ab7a9ccb1e9e053a902484615d3cfbac7dcf1abfca9f204b480d3207",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/276680b6ab7a",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "d91a2f361d6b5623e6c2549e4843ef9b9ffa847e86f2eb2ae651160f77ea02cc",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "173bcec570e7def5e93268d91a4ef942261f08bd1fd267a57beae9c94fbc7b07",
"EndpointID": "d91a2f361d6b5623e6c2549e4843ef9b9ffa847e86f2eb2ae651160f77ea02cc",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
5 进入当前正在运行的容器
# 我们通常容器使用后台方式运行的, 需要进入容器,修改一些配置
# 命令 方式一
docker exec -it 容器id /bin/bash
# 测试
[root@xxz /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9152d789dc91 centos "/bin/bash" 6 minutes ago Up 6 minutes cranky_swartz
[root@xxz /]# docker exec -it 9152d789dc91 /bin/bash
[root@9152d789dc91 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@9152d789dc91 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 11:17 pts/0 00:00:00 /bin/bash
root 15 0 0 11:23 pts/1 00:00:00 /bin/bash
root 31 15 0 11:24 pts/1 00:00:00 ps -ef
# 方式二
docker attach 容器id
# docker exec # 进入容器后开启一个新的终端,可以在里面操作
# docker attach # 进入容器正在执行的终端,不会启动新的进程
6 从容器中拷贝文件到主机
docker cp 容器id:容器内路径 目的地主机路径
[root@9152d789dc91 /]# # docker cp 9152d789dc91:/home/xxz.java /home
# 拷贝是一个手动过程,未来我们使用的是 - v卷的技术 可以说实现 自动同步 将容器中 的目录自动同步到主机中
三,Docker部署软件实战
1 Docker 安装 Nginx
服务器上操作防火墙
- 查看防火墙是否已启动:
sudo systemctl status firewalld
sudo firewall-cmd --state #查看防火墙状态:
- 启动防火墙
sudo systemctl start firewalld
- 查看防火墙开放的端口:
sudo firewall-cmd --list-ports # 查看开放的所有端口
firewall-cmd --query-port=**/tcp # 查看指定端口是否开放
- 开放端口并重启防火墙
sudo firewall-cmd --zone=public --add-port=xxxx/tcp --permanent # 开放xxxx端口
sudo firewall-cmd --reload # 重启防火墙
然后 使用远程服务器的还要去开安全组规则
步骤:
# 1. 搜索镜像 search 建议去docker hub搜索,可以看到帮助文档
# 2. 下载镜像 pull
# 3. 运行测试
[root@xxz /]# 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
[root@xxz /]# docker images # 查看容器
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 24 months ago 141MB
mysql latest 3218b38490ce 24 months ago 516MB
centos latest 5d0da3dc9764 2 years ago 231MB
# -d 后台运行
# -name 给容器命名
# -p 宿主机端口:容器内部端口
记住 要是用的是远程 服务器 记得 去开启安全组 端口号 也就是端口暴露概念
sudo firewall-cmd --zone=public --add-port=9999/tcp --permanent # 开放9999端口
sudo systemctl restart firewalld # 重新启动防火墙
# -p 是为了使用外网可以访问内网的80也就是nginx01
[root@xxz /]# docker run -d --name nginx01 -p 9999:80 nginx
1ecd8db700c6551d90bacdd585b1a1b7d35090b1a66c616eb91d6b0f7c54a6e7
[root@xxz /]# docker run -d --name nginx01 -p 9999:80 nginx
1ecd8db700c6551d90bacdd585b1a1b7d35090b1a66c616eb91d6b0f7c54a6e7
# 类似于ping 测试联通
# curl ip(本地或者远程服务器):9999
[root@xxz /]# curl 8.130.76.253:9999
<!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@xxz /]# docker exec -i -t nginx01 /bin/bash
root@1ecd8db700c6:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
端口暴露:
目的就是为了 可以通过外网访问 到容器内的服务 通过 -p xxxx:80
记得打开 阿里云服务器的 安全组
docker run -d --name nginx01 -p 9999:80 nginx
外网访问测试:
停止后测试就登录不进去了
思考问题:
我们每次改动nginx配置文件,都需要进入容器内部?十分的麻烦,我要是可
以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以
自动修改?v 数据卷 !
2 Docker 安装Tomcat
# 官方的使用方式 用完及删 测试的时候推荐
docker run -it --rm tomcat:9.0
# 我们之前的启动都是后台的,停止了容器之后, 容器还是可以查到,docker run -it --rm 一般用来测试,用完就删掉了
# 方式二
# 下载再启动
docker pull tomcat
# 启动运行 -d 是后台运行 -p 是为了端口映射
docker run -d -p 9999:8080 --name tomcat01 tomcat
# 测试访问没有问题
# 进入容器
docker exec -it tomcat01 /bin/bash
# 发现问题:1.linux命令少了, 2. webapps下内容为空,阿里云净吸纳过默认是最小的镜像,所有不必要的都剔除了,保证最小可运行环境即可
思考问题:我们以后要部署项目,如果每次都要进入容器是不是十分麻烦 ? 我要是可以在容器外部提供一个映射路径,webapps.
我们在外部放置项目,就自动同步到内部就好了 !
3 Docker部署es + kibana
# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录! 挂载
# --net somenetwork 网络配置
# 启动elasticsearch 下载的是7.6.2 版本
docker run -d --name elasticsearch --net somenetwork -p 9300:39300 -p 9200:9200 -e "discovery.type=single-node" elasticsearch:7.6.2
[root@xxz /]# docker run -d --name elasticsearch --net somenetwork -p 9300:39300 -p 9200:9200 -e "discovery.type=single-node" elasticsearch:7.6.2
Unable to find image 'elasticsearch:7.6.2' locally
7.6.2: Pulling from library/elasticsearch
ab5ef0e58194: Pull complete
c4d1ca5c8a25: Pull complete
941a3cc8e7b8: Pull complete
43ec483d9618: Pull complete
c486fd200684: Pull complete
1b960df074b2: Pull complete
1719d48d6823: Pull complete
Digest: sha256:1b09dbd93085a1e7bca34830e77d2981521a7210e11f11eda997add1c12711fa
Status: Downloaded newer image for elasticsearch:7.6.2
81ed078a047c8580449de09f8d998b20507451da87db4c0e2176c85bc28d357b
# 启动了linux就卡主了,docker stats 查看cpu状态
因为是每秒在刷新所以也消耗内存
# 测试一下es成功了
[root@xxz /]# curl ip:9200
{
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
},
"tagline" : "You Know, for Search"
}
# 增加内存限制,修改配置文件 -e 环境配置修改
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
可视化
- portainer(先用这个)
什么是 portainer
Docker的图形化界面管理工具 ,提供一个后台面板供我们操作 !
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# 该使用指定的选项启动Portainer容器。
# 内网的是 9000 外网访问的端口是 8088端口
# -V 后跟的是挂载 --privileged 后面是授权
# 测试
# curl 8.130.76,253:8088
# 外网访问 http://ip:9201
[root@xxz ~]# docker run -d -p 8088:9000 --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
94cfa856b2b1: Pull complete
49d59ee0881a: Pull complete
a2300fd28637: Pull complete
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
1572aca27a0910d22beca4519c2ae77a20a4d4fc5907da0d3b348d8414f17bb9
[root@xxz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1572aca27a09 portainer/portainer "/portainer" 3 minutes ago Up 3 minutes 9000/tcp, 0.0.0.0:9201->9299/tcp, :::9201->9299/tcp flamboyant_hopper
curl 测试
进入:
选择一个仓库 一般选择 本地的
进入之后的面板:
可视化面板我们平时是不会使用的 测试即可!!!!
- Rancher (CI/CD 的时候再用 做持续集成的时候使用)
四 Docker镜像讲解
镜像是什么
Docker镜像加载原理![image-20231221022425621](https://img-blog.csdnimg.cn/img_convert/378292d178194c65efd1dea290a17349.png)
虚拟机是分钟级别 而容器等是秒级别
分层理解
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!
[root@xxz ~]# docker image inspect mysql:8.0
我们真正下载的就是这个镜像
[root@xxz ~]# docker image inspect mysql:8.0
# docker image inspect 他容器id # 查看容器的元数据
特点
Docker 镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶
部!!!!
这一层就是我们通常说的容器层,容器之下的都叫镜像层 !!1
如何提交一个自己的镜像?
方式一 Commit 镜像
docker commit 提交容器成为一个新的版本
# 命令和 Git 原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试
测试启动tomcat 容器
[root@xxz ~]# docker images # 查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 24 months ago 141MB
tomcat 9.0 b8e65a4d736d 24 months ago 680MB
mysql 8.0 3218b38490ce 24 months ago 516MB
centos latest 5d0da3dc9764 2 years ago 231MB
portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB
elasticsearch 7.6.2 f29a1ee41030 3 years ago 791MB
[root@xxz ~]# docker run -it -p 8080:8080 tomcat # 启动tomcat【这个是默认的 官方的 是阉割版】
成功启动
查看正在运行的镜像
官方方式pull 的tomcat下的webapps下是没有东西的 是阉割过的
[root@xxz ~]# docker exec -it ea2066b8b0f9 /bin/bash # 进入tomcat 容器中
root@ea2066b8b0f9:/usr/local/tomcat# cd webapps
root@ea2066b8b0f9:/usr/local/tomcat/webapps# ls
root@ea2066b8b0f9:/usr/local/tomcat/webapps# # 这个时候这是空的
root@ea2066b8b0f9:/usr/local/tomcat/webapps# cd .. # 返回到根目录
root@ea2066b8b0f9:/usr/local/tomcat# ls
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs native-jni-lib temp webapps webapps.dist work
root@ea2066b8b0f9:/usr/local/tomcat# cp -r webapps.dist/* webapps # 拷贝webapps.dist下的所有文件去webapps
root@ea2066b8b0f9:/usr/local/tomcat# cd webapps
root@ea2066b8b0f9:/usr/local/tomcat/webapps# ls # 拷贝进来了 项目就进来了
ROOT docs examples host-manager manager
现在这个镜像不是空白的 是我拷贝操作后 【我就认为是我自己的 测试条件下】我现在进行提交镜像
# docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="zhangyouxiu" -m="add webapps app" ea2066b8b0f9 tomcat99:1.0
署名 信息 镜像id 给起的名:定义的版本
[root@xxz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea2066b8b0f9 tomcat "catalina.sh run" 16 minutes ago Up 16 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp dreamy_allen
[root@xxz ~]# docker commit -a="zhangyouxiu" -m="add webapps app" ea2066b8b0f9 tomcat99:1.0
sha256:4056651ba92726b6688e569ead42bccdde6a266227cefdfd3d26e0375b9a9578
如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,
五,容器数据卷
什么是容器数据卷
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删了,删库跑路! 需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享技术!Docker容器中产生的数据,同步到本地!
这就是 目录的挂载,将我们容器内的目录挂载到linux目录上面!
**总结: **容器的持久化和同步操作!容器间数据也是可以共享的!
使用 卷的目的 就是为了容器的持久化 和数据的同步操作!
使用数据卷
方式一: 指定路径挂载
- V /主机路径:/容器内路径
方式一: 直接使用命令来挂载 - V
[root@xxz ~]# docker run -it -p 主机端口:容器内端口 这里是端口映射 这是上面的内容
[root@xxz ~]# docker run -it -v 主机目录:容器目录 这样是 目录映射
测试
首先保证 主机 也就是服务器上目录中没有这个文件
主机端 也就是服务器端
[root@xxz home]# ls # 空的文件目录
1
[root@xxz home]# pwd
/home
[root@xxz home]# docker run -it -v /home/ceshi:/home centos /bin/bash # 进入容器并进行挂载
[root@f8a9ffe9cb92 /]# # 进入容器
[root@f8a9ffe9cb92 /]# cd home
[root@f8a9ffe9cb92 home]# ls # 查看容器中的 /home目录 发现是空的
[root@f8a9ffe9cb92 home]#
发现主机中命令已经执行完成 已经挂载进主机目录了
而主机端:也已经存在了ceshi 这个目录
说明挂载已经成功 双端是相互影响的 即 当 容器端的 ceshi文件 中有了数据或进行改变后 主机端这个目录也就会发生改变
同样 主机端改变 容器端 也会发生改变 即 双向绑定
# 使用查看容器的元数据进行查看挂载
[root@xxz home]# docker inspect f8a9ffe9cb92
测试文件的同步(在主机上改动,观察容器变化)
追加测试(依旧成功)
- 停止容器
- 主机上修改文件
- 启动容器
- 容器内的数据依旧是同步的!
实际优势: 一旦文件进行挂载后,我们以后修改只需要在本地修改即可,容器内会自动同步!
实战:安装MySQL
思考:MySQL的数据持久化的问题!
# 获取镜像
[root@xxz ~]# docekr pull mysql:8.0
# 运行容器, 需要做数据挂载! # 安装启动mysql,需要配置密码(注意)
# 官方测试给的, docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动我们的
-d # 后台运行
-p # 端口隐射
-v # 卷挂载
-e # 环境配置
--name # 容器的名字
[root@xxz home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:8.0
e13f2e81b677430453554cc86c380b1ddf0126dfacdfa405a4cb49ce1b004833
# 启动成功之后,我们在本地使用navicat链接测试一下
# navicat链接到服务器的3310 --- 3310 和 容器的3306映射,这个时候我们就可以连接上mysql喽!
# 在本地测试创建一个数据库,查看下我们的路径是否ok!
#解释 -d 后台运行 -p 暴露端口 映射端口 主机端口:容器内端口 -v 目录文件映射 主机内目录:容器内目录 可以连续挂载 -e 配置
现在我在连接中创建一个数据库 你会实时看到容器中也出现这个 因为挂载原因 所以主机同时也出现这个文件
测试:实现容器数据持久化的功能
假设我们将容器删除
发现,我们排载到本地的数据卷依旧没有丢失。
匿名和具名挂载
-v /容器内路径 # 匿名挂载
-v 卷名:/容器内路径 # 具名挂载
-v /主机路径:/容器内路径 # 指定路径挂载
# 查看所有volume的情况 就是查看具名和匿名情况
docker volume ls
-p 指定映射端口 -P 随机映射端口
匿名挂载
- v /容器内路径
我们在 -v 后面只写了容器内的路径,没有写主机中的路径
# 匿名挂载 因为只说了容器内的文件目录
[root@xxz ~]# docker run -d -P --name nginx02 -v /etc/nginx nginx
8974201a878b606aaf59c91402a81525fac305c6b1df0457fe12c056645a83b0
[root@xxz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8974201a878b nginx "/docker-entrypoint.…" 7 seconds ago Up 7 seconds 0.0.0.0:32768->80/tcp, :::32768->80/tcp nginx02
# 查看所有volume的情况
[root@xxz ~]# docker volume ls
DRIVER VOLUME NAME
local 0025e7120379eaf4bfbadb2cbbd6c929afea0443be332876c9f0e11d3ac492a3
local 53feec115a9c58c0f5640183cf5cf8e01dad3a933f8beb470c768f9e41a756a6
local 928c86e218ef9ab6fc4dc3222e66cafc271fab96bce81a111e305043be6fcccd
local 26061237c91fe0d2f7c32197cb58a3d911878ea559e136a0f0efd7a5d40c9808
local d34c0bb9b1fa6eab094d46e38e088738f9474d3ac672808d380138554b39fbea
local d1306e7a61cac5b8d0d7b891a1012e448e40cbf906a8f5dd50004968591f241a
local d919731b5991fd3d9a3fb760f6cdee89a3958f66f822adab191e1d889fc242be
local e42a1aff46023b6586c688f401aab430916d0fe697f9863b2652f26d9572b497
# 这里发现,这种情况就是匿名挂载,我们在-v 后面只写了容器内的路径,没有写容器外的路径!
具名挂载【常用】
格式:
-v 卷名:/容器内路径
也就是给挂载的行为起名字
-v 后面的 xxz-nginx 因为没加/ 绝对路径符号 所以这是为其起名
[root@xxz ~]# docker run -d -P --name nginx03 -v xxz-nginx:/etc/nginx nginx # -v 后面的 xxz-nginx 因为没加/ 绝对路径符号 所以这是为其起名
4250ba79883a42486c571094e92521c43ec702f4e1be2aba61c377a83ca82163
[root@xxz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4250ba79883a nginx "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:32769->80/tcp, :::32769->80/tcp nginx03
8974201a878b nginx "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 0.0.0.0:32768->80/tcp, :::32768->80/tcp nginx02
[root@xxz ~]# docker volume ls
DRIVER VOLUME NAME
local 0025e7120379eaf4bfbadb2cbbd6c929afea0443be332876c9f0e11d3ac492a3
local 53feec115a9c58c0f5640183cf5cf8e01dad3a933f8beb470c768f9e41a756a6
local 928c86e218ef9ab6fc4dc3222e66cafc271fab96bce81a111e305043be6fcccd
local 26061237c91fe0d2f7c32197cb58a3d911878ea559e136a0f0efd7a5d40c9808
local d34c0bb9b1fa6eab094d46e38e088738f9474d3ac672808d380138554b39fbea
local d1306e7a61cac5b8d0d7b891a1012e448e40cbf906a8f5dd50004968591f241a
local d919731b5991fd3d9a3fb760f6cdee89a3958f66f822adab191e1d889fc242be
local e42a1aff46023b6586c688f401aab430916d0fe697f9863b2652f26d9572b497
local xxz-nginx
如何查看这个卷的 信息?
# docker volume inspect ·卷名字·
[root@xxz ~]# docker volume inspect xxz-nginx
[
{
"CreatedAt": "2023-12-21T18:05:59+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/xxz-nginx/_data",
"Name": "xxz-nginx",
"Options": null,
"Scope": "local"
}
]
所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxxx/_data
拓展
慎用!!!!!
ro 和 rw 针对的是容器的权限
# 通过 -v 容器内容路径 ro rw 改变读写权限
ro readonly # 只读 缩写 ro
rw readwrite # 可读可写 缩写 rw
# 一旦这个了设置了容器权限,容器对我们挂载出来的内容就有限定了!!!!!! 慎用!!!!!!
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 只要看到ro就说明这个路径只能通过宿主机来操作,容器内容无法操作
初始DockerFile
DockerFile 就是用来构建docker镜像的构建文件!命令脚本!
前面我们通过 commint 生成过镜像 这是第二种方式
如何提交一个自己的镜像?
方式二 DockerFile
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!
就是手工打造了一个镜像
配置文件
# 创建一个dockerfile文件, 名字可以随机 但是建议是 dockerfile
# 文件的内容 指定(大写) 参数
# 这里的挂载只有 容器内的目录 所以这个属于 匿名挂载
FROM centos # 使用那个作为基础的 这里时用 centos 作为基础的 基础镜像 必有的
VOLUME ["volume01", "volume02"] # 通过volume == -V 进行挂载 后跟挂载文件 正常是对应容器内的
CMD echo "----end----" # 这是构建完 产生的提示信息
CMD /bin/bash # 默认走的是 bash 控制台
# 这里的每一个命令都是镜像的一层!
FROM centos
VOLUME ["volume01", "volume02"]
CMD echo "----end----"
CMD /bin/bash
创建那个就启动那个 启动和创建一个就好
# docker build -f /home/docker-test-volume/dockerfile01 -t xxz/centos:1.0 . # 不加版本号就会默认找最新的
# docker build -f /home/docker-test-volume/dockerfile01 -t xxz/centos .
启动自己的容器
docker images
docker run -it `镜像名` /bin/bash
# 启动方式 可以是 通过 REPOSITORY 也可以是通过 id
docker run -it xxz/centos /bin/bash
docker run -it bcb7b9d02259 /bin/bash # 启动最新版本的
这个卷和外部一定有一个同步的目录!
测试
找到通过dockerfile 匿名挂载的主机端文件存放地址
而怎么找同容器内挂载文件的外部的存放文件地址???
去主机端一边
# docker inspect 容器id
docker inspect bcb7b9d02259
去找看是否同步成功?测试一下刚才的文件是否同步到主机上了!
这种方式我们未来使用的十分多, 因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,
就要要手动镜像挂载 -v 卷名:/容器内路径! 使用 具名 挂载
数据卷容器
容器之间的挂载
也就是容器间 数据进行挂载
重点 –voulme-from 继承挂载 通过它来实现容器间的数据共享
启动3个容器,通过我们刚才自己写的镜像启动
1 启动父容器 docker01
-it == -i -t 等于交互式 访问
docker run -it --name docker01 `名或者id`
docker run -it --name docker01 xxz/centos
用 id 登录方式
用 IMAGE 登录方式 要不是最新的版本 名字后得加上版本 不然它自己会找的是最新版本的
这里我们 可以
Ctrl + P + Q # 容器不关闭退出
2 启动子1 docker02 容器
docker attach 容器id === 等于 docker exec -it 容器id /bin/bash 都是进入容器的方式
docker run -it --name docker02 --voulme-from docker01 `父容器名 `
起名docker02 --voulme-from 继承挂载
docker run -it --name docker02 --volumes-from docker01 xxz/centos
[root@xxz home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa641578bff0 xxz/centos "/bin/sh -c /bin/bash" 2 minutes ago Up 2 minutes docker02
c784d3aeed27 xxz/centos "/bin/sh -c /bin/bash" 9 minutes ago Up 9 minutes docker01
4cd784c526e0 xxz/centos "/bin/bash" 17 minutes ago Up 17 minutes admiring_shannon
4250ba79883a nginx "/docker-entrypoint.…" 5 hours ago Up 5 hours 0.0.0.0:32769->80/tcp, :::32769->80/tcp nginx03
8974201a878b nginx "/docker-entrypoint.…" 5 hours ago Up 5 hours 0.0.0.0:32768->80/tcp, :::32768->80/tcp nginx02
[root@xxz home]# docker attach fa641578bff0 # 进入docker02 容器
[root@fa641578bff0 /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Dec 21 15:01 dev
drwxr-xr-x 1 root root 4096 Dec 21 15:01 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 2021 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 142 root root 0 Dec 21 15:01 proc
dr-xr-x--- 2 root root 4096 Sep 15 2021 root
drwxr-xr-x 11 root root 4096 Sep 15 2021 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 Aug 23 13:20 sys
drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp
drwxr-xr-x 12 root root 4096 Sep 15 2021 usr
drwxr-xr-x 20 root root 4096 Sep 15 2021 var
drwxr-xr-x 2 root root 4096 Dec 21 14:54 volume01
drwxr-xr-x 2 root root 4096 Dec 21 14:54 volume02
[root@fa641578bff0 /]# cd volume01 # 因为这两是挂载目录 回看初始DockerFile 创建的两个挂载目录 匿名挂载
[root@fa641578bff0 volume01]# ls
[root@fa641578bff0 volume01]# touch 2023-12-21.txt
[root@fa641578bff0 volume01]# ls
2023-12-21.txt
现在 我们在 docker02 子容器中创建了 这个 2023-12-21.txt
文件 , 那么首先 父容器 docker01 中肯定是存在的
[root@xxz home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa641578bff0 xxz/centos "/bin/sh -c /bin/bash" 8 minutes ago Up 8 minutes docker02
c784d3aeed27 xxz/centos "/bin/sh -c /bin/bash" 15 minutes ago Up 15 minutes docker01
4cd784c526e0 xxz/centos "/bin/bash" 23 minutes ago Up 23 minutes admiring_shannon
4250ba79883a nginx "/docker-entrypoint.…" 5 hours ago Up 5 hours 0.0.0.0:32769->80/tcp, :::32769->80/tcp nginx03
8974201a878b nginx "/docker-entrypoint.…" 5 hours ago Up 5 hours 0.0.0.0:32768->80/tcp, :::32768->80/tcp nginx02
[root@xxz home]# docker attach c784d3aeed27 # 现在我们进入 父容器看
[root@c784d3aeed27 /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Dec 21 14:54 dev
drwxr-xr-x 1 root root 4096 Dec 21 14:54 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 2021 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 140 root root 0 Dec 21 14:54 proc
dr-xr-x--- 2 root root 4096 Sep 15 2021 root
drwxr-xr-x 11 root root 4096 Sep 15 2021 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 Aug 23 13:20 sys
drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp
drwxr-xr-x 12 root root 4096 Sep 15 2021 usr
drwxr-xr-x 20 root root 4096 Sep 15 2021 var
drwxr-xr-x 2 root root 4096 Dec 21 15:07 volume01
drwxr-xr-x 2 root root 4096 Dec 21 14:54 volume02
[root@c784d3aeed27 /]# cd volume01
[root@c784d3aeed27 volume01]# ls # 这个文件我们只是在子容器中创建 因为创建容器继承了父容器 即存在挂载关系 所以 这个文件也就自然存在
2023-12-21.txt
可以自己再加做子2 容器docker03 的测试 !!!!
说明: 容器之间 也可以通过挂载 实现多个mysql同步数据!
核心:
就是
–voulme-from 继承挂载 通过它来实现容器间的数据共享
要是我们将 父容器 docker01 停止并且删掉 我们会发现 数据在 两个子容器中依旧存在 因为已经继承挂载了父的数据了
这也说明了 容器间的 数据共享
多个mysql实现数据共享 或者多个 Redis 容器之间实现数据共享是可以实现的
结论
容器之间配置信息的传递, 数据卷容器的声明周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
Docker 中数据共享 是通过:
-
使用数据卷 方式一: 直接使用命令来挂载 - V
-
匿名挂载 - v /容器内路径
-
具名挂载 -v 卷名:/容器内路径
-
方式二: 使用 docekrfile 做镜像配置的时候配置挂载
-
容器间 数据进行挂载 数据卷容器
一定是一种连接 思想 不能连接就不可以
DockerFile
dockerFile是用来构建docker镜像的文件!命令参数脚本!
构建步骤
1. 编写一个dockerFile文件
2.docker build 构建成为一个镜像
3. docker run 运行镜像
4. docker push 发布镜像(DockerHub、阿里云镜像)
到此 我们先看一眼 官方怎么构建基础的 镜像
举例 centos镜像
这也就是一个基本的镜像
很多官方镜像都像是基础包,很多功能都不具备,我们通常会自己搭建自己的镜像!
官方既然可以制作镜像,能我们一样可以!
这是最基本的镜像 基础镜像 也就知道从那来的
因为添加了centos7 所以我们有了centos7 的功能
这是 添加了一些 centos7 的一些基本的标签
这是通过 /bin /bash
控制台运行
这也是最基础的镜像 所以当我们去使用 clear等命令的时候 会出错 因为这些命令都是需要安装的 !!!!!
DockerFile的构建过程
Dockerfile 文件的构建并不难 只要会写这个脚本就ok
基础知识:
- 每个保留关键字(指令)都是必须大写字母
- 执行从上到下顺序执行
#
表示注释- 每个指令都会创建提交一个新的镜像层,并提交!
dockerFile是面向开发的, 我们以后要发布项目, 做镜像, 就需要编写dockefile文件, 这个文件十分简单!
Docker镜像逐渐成为企业的交互标准,必须要掌握!
步骤:开发,部署, 运维… 缺一不可!
DockerFile: 构建文件, 定义了一切的步骤,源代码
DockerImages: 通过DockerFile构建生成的镜像, 最终发布和运行的产品!
Docker容器:容器就是镜像运行起来提供服务器
重要的是
1 ADD
2 EXPOSE
- ADD 你基础镜像中 比如 centos 中没有tomcat 这些 就是依靠add添加的
- EXPOSE 暴露端口 这里不暴露的话就需要通过 - p 【指定映射端口】或者 -P 【随机映射端口】来暴露端口
FROM # 基础镜像, 一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱
MAINTAINER已经被弃用了,最新使用LABEL,可以多行
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤, tomcat镜像, 这个tomcat压缩包 就属于添加内容 添加所需要的软件和配置
WORKDIR # 镜像的工作目录 项目在那工作
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令, 可以追加命令
ONBUILD # 当构建一个被继承【--voulme -from】DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令
COPY # 类似ADD, 将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!
CMD 和 ENTRYPOINT 的区别:
二者都是指定这个容器启动的时候要运行的命令 CMD 是可替换 ENTRYPOINT 是执行追加命令
比如 执行 ls -a run docker -l 使用 CMD 就是执行这样的命令 ls -l run docker
而 ls -a run docker -l 使用 ENTRYPOINT 是执行追加的命令 ls -a -l run docker
实际开发中 之前的方式就是给一个 jar 或者war包 现在就是交一个镜像并将环境和服务等都包括好 所以解决方式来了
创建一个自己的 Centos
我们主要是做镜像和加配置
先测试 这个镜像的配置有无 即vim命令存在不
开始制作镜像通过Dockerfile 文件配置
[root@xxz ~]# cd /
[root@xxz /]# cd home
[root@xxz home]# ls
1 ceshi docker-test-volume log mysql
[root@xxz home]# mkdir dockerfile # 创建dockerfile 文件
[root@xxz home]# ls
1 ceshi dockerfile docker-test-volume log mysql
[root@xxz home]# cd dockerfile/
[root@xxz dockerfile]# ls
[root@xxz dockerfile]#
[root@xxz dockerfile]# vim mydockerfile # 1 编辑 dockerfile文件
[root@xxz dockerfile]# cat mydockerfile
FROM centos
LABEL xxz<2243431996@qq.com>
ENV MYPATH /home
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 通过这个文件进行构建镜像 通过 buile 构建
-f 是指那个docekrfile文件 -t 后面就是 自己起的镜像名字加版本 后空格加 . 表示生成在当前目录
[root@xxz dockerfile]# docker build -f dockerfile -t mycentos:9.9 .
一个CMD运行一个命令,所以这里用了多个CMD。
这里还是先不用 LABEL 还是改用 MAINTAINER
修改后再试:
测试 安装的命令 是否可以使用?
效果对比:
前:
后:
查看历史改动记录:列出本地进行的变更历史
实战:Tomcat镜像
记得先创建好存放镜像文件的空间
1 编写 Dockerfile
1 首先需要准备镜像文件 也就是dockerfile 其次需要有tomcat的压缩包 而因为tomcat是依赖于java的 所以我们还需要有jdk的压缩包
2 编写 Dockerfile 文件
先完成第一步 准备tomcat和jdk 压缩包 最好写一个 帮助文档
开始第二步:
编写 Dockerfile 文件 就写这个大写的 是官方命名 严谨 而且 build 会自动找这个文件,就不需要使用 - f
去指定文件名了
这里的 日志挂载 的是本地 所以就是 usr
排错:
# docker logs `镜像名`
[root@xxz tomcat]# docker logs zzytomcat
/bin/sh: /usr/local/apache-tomcat-9.0.76/bin/starup.sh: No such file or directory # 找到startup.sh单词拼写的问题
2 构建镜像
然后开始构建镜像 使用 docker build
命令
因为我们这里使用的是官方推荐的dockerfile 文件名 也就是 Dockerfile
所以我们构建镜像的时候不许要再使用 - f
来告诉我们是通过那个文件来构建的
[root@xxz build]# docker build -t zzy913 . # . 表示当前目录 别忘记
构建成功
3 启动自己的镜像:
使用 docker run
命令
docker run -d 镜像名 是后台启动容器
并且注意
sudo firewall-cmd --list-ports # 查看开放的端口
# 需注意 做挂载 路径和文件名 一定要对
[root@xxz tomcat]# docker run -d -p 913:8080 --name zzy913 -v /home/zhangyouxiu/build/test:/usr/local/apache-tomcat-9.0.76/webapps/test -v /home/zhangyouxiu/build/tomcatlogs:/usr/local/apache-tomcat-9.0.76/logs zzy913
060c4617c7e387374119f745cf8b88f006640d4367788df27acc53fc9deffe3f
[root@xxz tomcat]# docker exec -it 060c4617c7 /bin/bash # 进入容器 因为配置文件中暴露了端口和给定了挂载
[root@0c7112300d48 local]# ls -l
total 52
drwxr-xr-x 1 root root 4096 Dec 23 19:09 apache-tomcat-9.0.76
drwxr-xr-x 2 root root 4096 Apr 11 2018 bin
drwxr-xr-x 2 root root 4096 Apr 11 2018 etc
drwxr-xr-x 2 root root 4096 Apr 11 2018 games
drwxr-xr-x 2 root root 4096 Apr 11 2018 include
drwxr-xr-x 7 10 143 4096 Dec 15 2018 jdk1.8.0_202
drwxr-xr-x 2 root root 4096 Apr 11 2018 lib
drwxr-xr-x 2 root root 4096 Apr 11 2018 lib64
drwxr-xr-x 2 root root 4096 Apr 11 2018 libexec
-rw-r--r-- 1 root root 0 Dec 23 18:00 readme.txt
drwxr-xr-x 2 root root 4096 Apr 11 2018 sbin
drwxr-xr-x 5 root root 4096 Nov 13 2020 share
drwxr-xr-x 2 root root 4096 Apr 11 2018 src
[root@0c7112300d48 local]# cd apache-tomcat-9.0.76/
[root@0c7112300d48 apache-tomcat-9.0.76]# ls
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs temp webapps work
[root@0c7112300d48 apache-tomcat-9.0.76]# cd webapps/
[root@0c7112300d48 webapps]# ls
ROOT docs examples host-manager manager
[root@0c7112300d48 webapps]# cd ../bin/
[root@0c7112300d48 bin]# ls
bootstrap.jar catalina.sh commons-daemon-native.tar.gz configtest.sh digest.sh setclasspath.bat shutdown.sh tomcat-juli.jar tool-wrapper.sh
catalina-tasks.xml ciphers.bat commons-daemon.jar daemon.sh makebase.bat setclasspath.sh startup.bat tomcat-native.tar.gz version.bat
catalina.bat ciphers.sh configtest.bat digest.bat makebase.sh shutdown.bat startup.sh tool-wrapper.bat version.sh
[root@0c7112300d48 bin]# pwd
/usr/local/apache-tomcat-9.0.76/bin
启动之后 Ctrl + P + Q 不关闭退出
测试访问:
主机中查看:
[root@xxz /]# curl 8.130.76.253:913
外部访问:
成功 !!!
发布项目
(由于做了卷挂载, 我们直接在本地编写项目就可以发布了)
[root@xxz /]# cd home
[root@xxz home]# ls
1 ceshi dockerfile docker-test-volume log mysql zhangyouxiu
[root@xxz home]# cd zhangyouxiu/
[root@xxz zhangyouxiu]# ls
build
[root@xxz zhangyouxiu]# cd build/
[root@xxz build]# ls
test tomcat tomcatlogs
[root@xxz build]# cd test/
[root@xxz test]# ls
[root@xxz test]# mkdir WEB-IF
[root@xxz test]# ls
WEB-IF
[root@xxz test]# cd WEB-IF/
[root@xxz test]# vim web.xml
<?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>
[root@xxz WEB-IF]# ls
web.xml
[root@xxz WEB-IF]# cd ..
[root@xxz test]# ls
WEB-IF
[root@xxz test]# vim index.jsp
[root@xxz test]# ls
index.jsp WEB-IF
[root@xxz test]# cat index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>nihao xxz</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("-----my test web logs------");
%>
</body>
</html>
这样你去访问 就会发现
主机IP + 映射的主机端口号 / test
成功!!!!
暂时 知识点就先到这里因为做的项目未使用到 后面网络配置 后期补充 !!!!!!