一、快速入门
1. 安装
# 1.查看系统内核(3.10以上才可以)
uname -r
[root@VM-24-12-centos ~]# uname -r
3.10.0-1160.45.1.el7.x86_64
# 2.查看系统环境
cat /etc/os-release
[root@VM-24-12-centos ~]# 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"
# 3.卸载本机docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 4.设置仓库
yum install -y yum-utils
## 设置国内阿里云仓库,速度快
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 5.更新yum包索引
yum makecache fast
# 5.安装docker(ce 社区版 ee 企业版)
yum install docker-ce docker-ce-cli containerd.io
# 6.启动docker
systemctl start docker
# 7.检查docker版本
docker version
[root@VM-24-12-centos ~]# docker version
Client: Docker Engine - Community
Version: 20.10.14
API version: 1.41
Go version: go1.16.15
Git commit: a224086
Built: Thu Mar 24 01:49:57 2022
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.14
API version: 1.41 (minimum version 1.12)
Go version: go1.16.15
Git commit: 87a90dc
Built: Thu Mar 24 01:48:24 2022
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.5.11
GitCommit: 3df54a852345ae127d1fa3092b95168e4a88e2f8
runc:
Version: 1.0.3
GitCommit: v1.0.3-0-gf46b6ba
docker-init:
Version: 0.19.0
GitCommit: de40ad0
# 8.测试docker
docker run hello-world
# 9.查看docker镜像
docker images
[root@VM-24-12-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 6 months ago 13.3kB
# 10.卸载docker
## 10.1 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
##10.2 删除资源
rm -rf /var/lib/docker (docker默认工作路径)
rm -rf /var/lib/containerd
2.配置镜像加速
以阿里云镜像为例:
- 阿里云容器镜像服务-镜像加速器
- 配置
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["xxxxx"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
二、常用命令
0. 预备
docker version # 显示docker版本信息
docker info # 显示docker的系统信息,包括镜像和容器数量
docker 命令 --help # 帮助命令
帮助文档地址:https://docs.docker.com/reference/
1.镜像命令
1.1 查看所有本地主机的镜像
# 查看所有本地主机的镜像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 6 months ago 13.3kB
# 解释:
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的标签
CREATED 镜像的创建时间
SIZE 镜像的大小
# 可选项
Options:
-a, --all Show all images (default hides intermediate images) #列出所有镜像
-q, --quiet Only show numeric IDs # 只显示镜像的id
1.2 搜索镜像
# 搜索镜像
docker search
[root@VM-24-12-centos ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 12413 [OK]
mariadb MariaDB Server is a high performing open sou… 4782 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 918 [OK]
percona Percona Server is a fork of the MySQL relati… 575 [OK]
## 可选项:
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的
[root@VM-24-12-centos ~]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 12413 [OK]
mariadb MariaDB Server is a high performing open sou… 4782 [OK]
搜索镜像【也可以在docker hub上找下载,比较麻烦,没有命令用起来舒服】
1.3 下载镜像
# 下载镜像
docker pull 镜像名[:tag]
[root@VM-24-12-centos ~]# docker pull tomcat:8
8: Pulling from library/tomcat #如果不写tag,默认就是latest
90fe46dd8199: Already exists #分层下载: docker image 的核心 联合文件系统(之前下载过的会,不用下载,共用)
35a4f1977689: Already exists
bbc37f14aded: Already exists
74e27dc593d4: Already exists
93a01fbfad7f: Already exists
1478df405869: Pull complete
64f0dd11682b: Pull complete
68ff4e050d11: Pull complete
f576086003cf: Pull complete
3b72593ce10e: Pull complete
Digest: sha256:0c6234e7ec9d10ab32c06423ab829b32e3183ba5bf2620ee66de866df # 签名防伪
Status: Downloaded newer image for tomcat:8
docker.io/library/tomcat:8 #真实地址
#等价于
docker pull tomcat:8
docker pull docker.io/library/tomcat:8
1.4 删除镜像
# 删除镜像
docker rmi -f 镜像id #删除指定id的镜像
docker rmi -f 容器id 容器id ... # 删除多个容器
docker rmi -f $(docker images -aq) # 删除全部的容器
2.容器命令
说明:有了镜像才可以创建容器
以centos镜像为例:
#docker中下载centos
docker pull centos
#查看镜像
docker images
#测试启动,bash启动
docker run -it centos /bin/bash
[root@VM-24-12-centos ~]# docker run -it centos /bin/bash
[root@0687c291327c /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 退回主机
exit # 直接容器停止并推出
Ctrl + P + Q # 容器不停止退出
2.1 启动容器:
docker run [可选参数] image | docker container run [可选参数] image
#参书说明
--name="Name" #容器名字 tomcat01 tomcat02 用来区分容器
-d #后台方式运行
-it #使用交互方式运行,进入容器查看内容
-p #指定容器的端口 -p 8080(宿主机):8080(容器)
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-P(大写) # 随机指定端口
2.2 查看容器:
docker ps # 列出所有的运行的容器
docker ps -a # 列出所有的运行的容器 + 最近运行过的容器
docker ps -a -n=? # 列出所有的运行的容器 + 最近运行过的容器 ?个
docker ps -q # 只显示容器的编号
docker ps -aq # 只显示容器的编号
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@VM-24-12-centos ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0687c291327c centos "/bin/bash" 4 minutes ago Exited (0) 3 minutes ago peaceful_stonebraker
6f0823b20328 hello-world "/hello" 57 minutes ago Exited (0) 57 minutes ago inspiring_engelbart
[root@VM-24-12-centos ~]# docker ps -a -n=1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0687c291327c centos "/bin/bash" 4 minutes ago Exited (0) 3 minutes ago peaceful_stonebraker
2.3 删除容器:
docker rm 容器id # 删除指定的容器,不能删除正在运行的容器,如果要强制删 rm -f
docker rm -f $(docker ps -aq) # 删除所有的容器
docker ps -a -q|xarg docker rm # 删除所有的容器
2.4 启动和停止容器:
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
3.其他命令
3.1 后台启动:
# 命令 docker run -d 镜像名
[root@VM-24-12-centos ~]# docker run -d centos
a8f922c255859622ac45ce3a535b7a0e8253329be4756ed6e32265d2dd2fac6c
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 问题docker ps. 发现centos 停止了
# 常见的坑,docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
3.2 查看日志:
docker logs --help
Options:
--details Show extra details provided to logs
* -f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
* --tail string Number of lines to show from the end of the logs (default "all")
* -t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
docker run -d centos /bin/sh -c "while true;do echo 666;sleep 1;done" #模拟日志
#显示日志
-tf #显示日志信息(一直更新)
--tail number #需要显示日志条数
docker logs -t --tail n 容器id #查看n行日志
docker logs -ft 容器id #跟着日志
3.3 查看容器中的进程信息:
# 命令 docker top 容器id
[root@VM-24-12-centos ~]# docker top 9865999fe479
UID PID PPID C STIME TTY TIME CMD
root 12852 12833 0 22:46 ? 00:00:00 /bin/sh -c while true;do echo 666;sleep 1;done
root 17867 12852 0 22:49 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
3.4 查看镜像的元数据:
docker inspect 容器id
[root@VM-24-12-centos ~]# docker inspect 9865999fe479
[
{
"Id": "9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e",
"Created": "2022-04-15T14:46:44.445308293Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true;do echo 666;sleep 1;done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 12852,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-04-15T14:46:44.722755109Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
"ResolvConfPath": "/var/lib/docker/containers/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e/hostname",
"HostsPath": "/var/lib/docker/containers/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e/hosts",
"LogPath": "/var/lib/docker/containers/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e-json.log",
"Name": "/zen_taussig",
"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": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/a576bc4c3377d3992efc6b80ba3a93d2690562265e311a152885e0ed025b2088-init/diff:/var/lib/docker/overlay2/9123fd3ce2d692e8f29431878cfad8dc26c3b37973ab99176f479f3f9fe3f15a/diff",
"MergedDir": "/var/lib/docker/overlay2/a576bc4c3377d3992efc6b80ba3a93d2690562265e311a152885e0ed025b2088/merged",
"UpperDir": "/var/lib/docker/overlay2/a576bc4c3377d3992efc6b80ba3a93d2690562265e311a152885e0ed025b2088/diff",
"WorkDir": "/var/lib/docker/overlay2/a576bc4c3377d3992efc6b80ba3a93d2690562265e311a152885e0ed025b2088/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "9865999fe479",
"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 666;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": "4c98fe4130129a2c6f7eb38578c8a2032a9756328060dd026c37fce231bf51e8",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/4c98fe413012",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "aa0e4a6dab7e4b283423df17e1bbb65e54458447959a3c0e13acbbb6abb47446",
"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": "e4fba822dc97104a9a319b745f7b00e87a04eaccd49cae3d366aa4cb47a553de",
"EndpointID": "aa0e4a6dab7e4b283423df17e1bbb65e54458447959a3c0e13acbbb6abb47446",
"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
}
}
}
}
]
3.5 进入当前正在运行的容器
# 方式一:
docker exec -it 容器id bashShell
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9865999fe479 centos "/bin/sh -c 'while t…" 14 minutes ago Up 14 minutes zen_taussig
[root@VM-24-12-centos ~]# docker exec -it 9865999fe479 /bin/bash
[root@9865999fe479 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@9865999fe479 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 14:46 ? 00:00:00 /bin/sh -c while true;do echo 666;sleep 1;done
root 901 0 0 15:01 pts/0 00:00:00 /bin/bash
root 925 1 0 15:01 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root 926 901 0 15:01 pts/0 00:00:00 ps -ef
# 方式二:
docker attach 容器id
正在执行的代码.....
# 比较:
# docker exec # 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach # 进入容器正在执行的终端,不会启动新的进程!
3.6 从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的的主机路径
[root@VM-24-12-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 c20987f18b13 3 months ago 448MB
hello-world latest feb5d9fea6a5 6 months ago 13.3kB
centos latest 5d0da3dc9764 7 months ago 231MB
## 进入docker容器内
[root@VM-24-12-centos home]# docker attach a0aa07d62a3e
[root@a0aa07d62a3e /]# cd /home
[root@a0aa07d62a3e home]# ls
## 在容器内新建一个test.java文件
[root@a0aa07d62a3e home]# touch test.java
[root@a0aa07d62a3e home]# exit
exit
## 将这个文件拷贝到主机上
[root@VM-24-12-centos home]# docker cp a0aa07d62a3e:/home/test.java /home
[root@VM-24-12-centos home]# ls
lighthouse test.java www
小结:
命令大全:
attach Attach local standard input, output, and error streams to a running container
#当前shell下 attach连接指定运行的镜像
build Build an image from a Dockerfile # 通过Dockerfile定制镜像
commit Create a new image from a container's changes #提交当前容器为新的镜像
cp Copy files/folders between a container and the local filesystem #拷贝文件
create Create a new container #创建一个新的容器
diff Inspect changes to files or directories on a container's filesystem #查看docker容器的变化
events Get real time events from the server # 从服务获取容器实时时间
exec Run a command in a running container # 在运行中的容器上运行命令
export Export a container's filesystem as a tar archive #导出容器文件系统作为一个tar归档文件[对应import]
history Show the history of an image # 展示一个镜像形成历史
images List images #列出系统当前的镜像
import Import the contents from a tarball to create a filesystem image #从tar包中导入内容创建一个文件系统镜像
info Display system-wide information # 显示全系统信息
inspect Return low-level information on Docker objects #查看容器详细信息
kill Kill one or more running containers # kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包或标准输入中加载一个镜像[对应save]
login Log in to a Docker registry #
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
4.练习
4.1 部署Nginx
# 1.搜索镜像,建议去dockerhub上搜索,可以看到帮助文档
docker search nginx
# 2.下载镜像
docker pull nginx
# 3.启动
docker run -d --name nginx01 -p 6666:80 nginx
# 4.查看运行状态
docker ps
# 5.测试
curl localhost:6666
4.2 部署Tomcat
# 官方的使用(用完即删,一般用来做测试)
docker run -it --rm tomcat:9.0
# 1.下载镜像
docker pull tomcat:9.0
# 2.启动运行
docker run -d -p 6667:8080 --name tomcat01 tomcat:9.0
#测试访问有没有问题
curl localhost:6667
# 发现问题:1、linux命令少了。 2.webapps目录为空
# 原因:阿里云镜像的原因,阿里云默认是最小的镜像,所以不必要的都剔除掉
# 保证最小可运行的环境!
# 解决方案:
# 将webapps.dist下的文件都拷贝到webapps下即可
# 进入容器
docker exec -it tomcat01 /bin/bash
# 拷贝webapps.dist 内容给webapps
cp -r webapps.dist/* webapps
4.3 部署 es + kibana
# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置的安全目录 ! 挂载
# 1.启动
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
# 2.测试
curl localhost:9200
{
"name" : "d73ad2f22dd3",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "atFKgANxS8CzgIyCB8PGxA",
"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"
}
# 2.查看内存消耗
docker stats
# 3.停止
# 1.增加内存限制启动
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
# 2.查看内存消耗
docker stats 容器id
三、可视化工具
Docker图形化界面管理工具!提供一个后台面板供我们操作!
1. portainer
docker run -d -p 8088:9000 \
> --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
内网测试
curl localhost:8088
外网测试
可能遇到的错误:
在portainer容器启动五分钟后,还没有创建管理员账号,portainer容器就会自动关闭。重新启动就好了。
2. Rancher(CI/CD)
四、Docker镜像
1. 镜像是什么?
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。
所有应用,直接打包docker镜像,就可以直接跑起来!
如何得到镜像
- 从远程仓库下载
- 别人拷贝给你
- 自己制作一个镜像 DockerFile
2. Docker镜像加载原理
2.1 UnionFs (联合文件系统)
UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统
,他支持对文件系统的修改作为一次提交来一层层的叠加
,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
2.2 Docker镜像加载原理
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel, Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 boots。这一层与我们典型的Linux/Unix系统是一样的,包含boot加載器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
对于个精简的OS,rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级!
3.分层理解
分层的镜像
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载
思考:为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于==资源共享==了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect 命令
docker image inspect redis
[
{
"Id": "sha256:f9b9909726890b00d2098081642edf32e5211b7ab53563929a47f250bcdc1d7c",
"RepoTags": [
"redis:latest"
],
"RepoDigests": [
"redis@sha256:399a9b17b8522e24fbe2fd3b42474d4bb668d3994153c4b5d38c3dafd5903e32"
],
"Parent": "",
"Comment": "",
"Created": "2020-05-02T01:40:19.112130797Z",
"Container": "d30c0bcea88561bc5139821227d2199bb027eeba9083f90c701891b4affce3bc",
"ContainerConfig": {
"Hostname": "d30c0bcea885",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"6379/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.0.1",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.1.tar.gz",
"REDIS_DOWNLOAD_SHA=b8756e430479edc162ba9c44dc89ac394316cd482f2dc6b91bcd5fe12593f273"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"redis-server\"]"
],
"ArgsEscaped": true,
"Image": "sha256:704c602fa36f41a6d2d08e49bd2319ccd6915418f545c838416318b3c29811e0",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "18.09.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"6379/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.0.1",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.1.tar.gz",
"REDIS_DOWNLOAD_SHA=b8756e430479edc162ba9c44dc89ac394316cd482f2dc6b91bcd5fe12593f273"
],
"Cmd": [
"redis-server"
],
"ArgsEscaped": true,
"Image": "sha256:704c602fa36f41a6d2d08e49bd2319ccd6915418f545c838416318b3c29811e0",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 104101893,
"VirtualSize": 104101893,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/adea96bbe6518657dc2d4c6331a807eea70567144abda686588ef6c3bb0d778a/diff:/var/lib/docker/overlay2/66abd822d34dc6446e6bebe73721dfd1dc497c2c8063c43ffb8cf8140e2caeb6/diff:/var/lib/docker/overlay2/d19d24fb6a24801c5fa639c1d979d19f3f17196b3c6dde96d3b69cd2ad07ba8a/diff:/var/lib/docker/overlay2/a1e95aae5e09ca6df4f71b542c86c677b884f5280c1d3e3a1111b13644b221f9/diff:/var/lib/docker/overlay2/cd90f7a9cd0227c1db29ea992e889e4e6af057d9ab2835dd18a67a019c18bab4/diff",
"MergedDir": "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/merged",
"UpperDir": "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/diff",
"WorkDir": "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:c2adabaecedbda0af72b153c6499a0555f3a769d52370469d8f6bd6328af9b13",
"sha256:744315296a49be711c312dfa1b3a80516116f78c437367ff0bc678da1123e990",
"sha256:379ef5d5cb402a5538413d7285b21aa58a560882d15f1f553f7868dc4b66afa8",
"sha256:d00fd460effb7b066760f97447c071492d471c5176d05b8af1751806a1f905f8",
"sha256:4d0c196331523cfed7bf5bafd616ecb3855256838d850b6f3d5fba911f6c4123",
"sha256:98b4a6242af2536383425ba2d6de033a510e049d9ca07ff501b95052da76e894"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
理解:
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点.
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。
这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统
Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的文件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。
Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。
下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图。
特点
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
4. commit镜像
# 提交容器成为一个新的副本
docker commit
# 命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试:
- 启动一个默认tomcat
- 默认tomcat没有webapps应用
- 自己拷贝了基本的文件
# 1、启动一个默认的tomcat
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d -p 8080:8080 tomcat
de57d0ace5716d27d0e3a7341503d07ed4695ffc266aef78e0a855b270c4064e
# 2、发现这个默认的tomcat 是没有webapps应用,官方的镜像默认webapps下面是没有文件的!
#docker exec -it 容器id /bin/bash
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker exec -it de57d0ace571 /bin/bash
root@de57d0ace571:/usr/local/tomcat#
# 3、从webapps.dist拷贝文件进去webapp
root@de57d0ace571:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@de57d0ace571:/usr/local/tomcat# cd webapps
root@de57d0ace571:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
# 4、将操作过的容器通过commit调教为一个镜像!我们以后就使用我们修改过的镜像即可,而不需要每次都重新拷贝webapps.dist下的文件到webapps了,这就是我们自己的一个修改的镜像。
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="xiaohang" -m="add webapps app" 容器id tomcat02:1.0
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker commit -a="csp提交的" -m="add webapps app" de57d0ace571 tomcat02.1.0
sha256:d5f28a0bb0d0b6522fdcb56f100d11298377b2b7c51b9a9e621379b01cf1487e
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02.1.0 latest d5f28a0bb0d0 14 seconds ago 652MB
tomcat latest 1b6b1fe7261e 5 days ago 647MB
nginx latest 9beeba249f3e 5 days ago 127MB
mysql 5.7 b84d68d0a7db 5 days ago 448MB
elasticsearch 7.6.2 f29a1ee41030 8 weeks ago 791MB
portainer/portainer latest 2869fc110bf7 2 months ago 78.6MB
centos latest 470671670cac 4 months ago 237MB
hello-world latest bf756fb1ae65 4 months ago 13.3kB
五、容器数据卷
1. 什么是容器数据卷?
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!
需求:==数据可以持久化==
MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个==数据共享==的技术!Docker容器中产生的数据,==同步==到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结一句话:==容器的持久化和同步操作!容器间也是可以数据共享的!==
2. 使用容器数据卷
1.方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
测试:
[root@VM-24-12-centos ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@756b8fb5faa6 /]# [root@VM-24-12-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
756b8fb5faa6 centos "/bin/bash" 29 seconds ago Up 28 seconds modest_elbakyan
7cf1763a18b1 portainer/portainer "/portainer" 26 hours ago Up 26 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp adoring_knuth
797b64907651 tomcat:9.0 "catalina.sh run" 2 days ago Up 42 minutes 0.0.0.0:80->8080/tcp, :::80->8080/tcp tomcat03
[root@VM-24-12-centos ~]# docker inspect 756b8fb5faa6
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi", # 主机内地址
"Destination": "/home", # docker容器内地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
测试文件的同步
再来测试!
1、停止容器
2、宿主机修改文件
3、启动容器
4、容器内的数据依旧是同步的
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
3. 实战:安装MySQL
[root@VM-24-12-centos ~]# docker pull mysql:5.7
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@VM-24-12-centos ~]# 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=root --name mysql03 mysql:5.7
测试连接(别忘了开放安全组)
假设我们将包含mysql的容器删除时,发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能。
4. 具名和匿名挂载
4.1 匿名挂载
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有的volume的情况
docker volume ls
[root@VM-24-12-centos data]# docker volume ls
DRIVER VOLUME NAME
local 5e138dd9c45a0042eda0968e4c1392eeff7ff95b9045a2ddcd84a9bf034113f4
local e157c4fe4cf611bc35ea7f71025d0bc1c59b11d09887a2a6c30e5d90d5c43922
# 这里发现,我们在 -v 只写的容器内的路径,没有写容器外的路径!那么究竟挂载到哪个地方呢?
4.2 具名挂载(推荐)
# 具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
[root@VM-24-12-centos data]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx
通过 -v 卷名:容器内路径
查看一下,挂载的地方:
[root@VM-24-12-centos data]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-04-21T09:20:48+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
得出结论
所有的docker容器内的卷,没有指定目录的情况下都是在
/var/lib/docker/volumes/xxx/_data
我们进入对应的目录:
[root@VM-24-12-centos data]# cd /var/lib/docker/volumes/
[root@VM-24-12-centos volumes]# ls
5e138dd9c45a0042eda0968e4c1392eeff7ff95b9045a2ddcd84a9bf034113f4 backingFsBlockDev e157c4fe4cf611bc35ea7f71025d0bc1c59b11d09887a2a6c30e5d90d5c43922 juming-nginx metadata.db
=> 我们通过具名挂载可以方便的找到我们的一个卷,大多数情况推荐使用:具名挂载
# 如何确定是具名挂载、匿名挂载、指定路径挂载!
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
拓展:
通过 -v 容器内路径:ro/rw 改变读写权限
ro read only # 只读(只有宿主机可操作)
rw readwrite # 可读可写
docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx:ro nginx
5. 初识Dockerfile
Dockerfile 就是用来构建docker镜像的构建文件!命令脚本!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层!
# 新建测试目录
[root@VM-24-12-centos ~]# cd /home
[root@VM-24-12-centos home]# mkdir /home/docker-test-volume
[root@VM-24-12-centos home]# cd docker-test-volume/
[root@VM-24-12-centos docker-test-volume]# pwd
/home/docker-test-volume
## 创建一个dockerfile文件,名字可以随机
[root@VM-24-12-centos docker-test-volume]# vim dockerfile1
## 文件中的内容
FROM centos # 当前这个镜像是以centos为基础的
VOLUME ["volume01","volume02"] # 挂载卷的卷目录列表(多个目录)
CMD echo "-----end-----" # 输出一下用于测试
CMD /bin/bash # 默认走bash控制台
##
# 这里的每个命令,就是镜像的一层!
# 构建出这个镜像
-f dockerfile1 # f代表file,指这个当前文件的地址(这里是当前目录下的dockerfile1)
-t xiaohang/centos # t就代表target,指目标目录(注意xiaohang镜像名前不能加斜杠‘/’)
. # 表示生成在当前目录下
docker build -f dockerfile1 -t xiaohang/centos .
# 生成自己的镜像
[root@VM-24-12-centos docker-test-volume]# docker build -f dockerfile1 -t xiaohang/centos .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in 5e1b9b47c35a
Removing intermediate container 5e1b9b47c35a
---> 8f41c19d3c3f
Step 3/4 : CMD echo "----end-----"
---> Running in f6e32a9e0fbe
Removing intermediate container f6e32a9e0fbe
---> 06d3158c96d5
Step 4/4 : CMD /bin/bash
---> Running in 6909b1600a15
Removing intermediate container 6909b1600a15
---> f36fc725be93
Successfully built f36fc725be93
Successfully tagged xiaohang/centos:latest
## 查看自己生成的镜像
[root@VM-24-12-centos docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xiaohang/centos latest f36fc725be93 52 seconds ago 231MB
## 启动自己写的镜像
[root@VM-24-12-centos docker-test-volume]# docker run -it f36fc725be93 /bin/bash
[root@66ad7f7b420b /]# ll (注意ll没有)
bash: ll: command not found
[root@66ad7f7b420b /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Apr 21 07:13 dev
drwxr-xr-x 1 root root 4096 Apr 21 07:13 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 139 root root 0 Apr 21 07:13 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 Apr 21 07:13 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 Apr 21 07:13 volume01
drwxr-xr-x 2 root root 4096 Apr 21 07:13 volume02
## 最后这两个目录就是我们生成镜像的时候自动挂载的,数据卷目录
思考: 这个卷和外部一定有一个同步的目录!!!
匿名挂载:
## 文件中的内容
...
VOLUME ["volume01","volume02"] # 挂载卷的卷目录列表(多个目录)
...
##
## 查看一下卷挂载的路径:
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fb03c0ac928e f36fc725be93 "/bin/bash" 10 seconds ago Up 9 seconds agitated_napier
48094937fd09 mysql:5.7 "docker-entrypoint.s…" 15 hours ago Up 15 hours 33060/tcp, 0.0.0.0:3310->3306/tcp, :::3310->3306/tcp mysql03
7cf1763a18b1 portainer/portainer "/portainer" 3 days ago Up 3 days 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp adoring_knuth
[root@VM-24-12-centos ~]# docker inspect fb03c0ac928e
"Mounts": [
{
"Type": "volume",
"Name": "9fe1401672d9c3e97cdf28147fa6164da59bcf08a762de24a323180ced0de948",
"Source": "/var/lib/docker/volumes/9fe1401672d9c3e97cdf28147fa6164da59bcf08a762de24a323180ced0de948/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "7c33e40060a3b2ae4e02f9748c46d011d5454ce7d6d109b47edc997b89069e94",
"Source": "/var/lib/docker/volumes/7c33e40060a3b2ae4e02f9748c46d011d5454ce7d6d109b47edc997b89069e94/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
## 不难得出:这是匿名挂载
## 最后,我们测试一下刚才的文件是否同步出去:
### 容器内:
[root@fb03c0ac928e /]# cd /
.dockerenv dev/ home/ lib64/ media/ opt/ root/ sbin/ sys/ usr/ volume01/
bin/ etc/ lib/ lost+found/ mnt/ proc/ run/ srv/ tmp/ var/ volume02/
[root@fb03c0ac928e /]# cd /volume01
[root@fb03c0ac928e volume01]# touch container.txt
### 容器外:
[root@VM-24-12-centos ~]# cd /var/lib/docker/volumes/9fe1401672d9c3e97cdf28147fa6164da59bcf08a762de24a323180ced0de948/_data
[root@VM-24-12-centos _data]# ls
container.txt
## 同步成功!
6. 数据卷容器
# 启动三个容器测试
[root@VM-24-12-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xiaohang/centos latest f36fc725be93 20 hours ago 231MB
# 启动第一个容器:
[root@VM-24-12-centos ~]# docker run -it --name docker01 xiaohang/centos
[root@fe47b170c766 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
Ctrl + P + Q(退出不结束)
[root@fe47b170c766 /]# [root@VM-24-12-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fe47b170c766 xiaohang/centos "/bin/sh -c /bin/bash" About a minute ago Up About a minute docker01
# 启动第二个容器
[root@VM-24-12-centos ~]# docker run -it --name docker02 --volumes-from docker01 xiaohang/centos
[root@280b39ca806f /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
# 启动第二个容器
[root@VM-24-12-centos ~]# docker run -it --name docker03 --volumes-from docker01 xiaohang/centos
[root@280b39ca806f /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
# 进入容器一,创建docker01.txt
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
280b39ca806f xiaohang/centos "/bin/sh -c /bin/bash" 11 minutes ago Up 11 minutes docker02
fe47b170c766 xiaohang/centos "/bin/sh -c /bin/bash" 15 minutes ago Up 15 minutes docker01
[root@VM-24-12-centos ~]# docker exec -it fe47b170c766 /bin/bash
[root@fe47b170c766 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
[root@fe47b170c766 /]# cd volume01
[root@fe47b170c766 volume01]# ls
[root@fe47b170c766 volume01]# touch docker01.txt
[root@fe47b170c766 volume01]# ls
docker01.txt
# 进入容器二,查看是否有docker02.txt
[root@280b39ca806f /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
[root@280b39ca806f /]# cd volume01
[root@280b39ca806f volume01]# ls
docker01.txt
## 测试删除docker01,docker02,docker03还可以继续访问。
多个MySQL实现数据共享:
$ docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
$ docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
# 这个时候,可以实现两个容器数据同步!
结论:
- 容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
- 但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
7. Dockerfile
Dockerfile是用来构建docker镜像的文件!(命令参数脚本)
7.1 构建步骤
- 编写一个dockerfile文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub、阿里云仓库)
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!
官方既然可以制作镜像,那我们也可以!
7.2 Dockerfile构建过程
7.2.1 基础知识:
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序
3、#表示注释
4、每一个指令都会创建提交一个新的镜像曾,并提交!
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成企业交付的标准,必须要掌握!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品。
Docker容器:容器就是镜像运行起来提供服务。
7.2.2 Dockerfile的指令
FROM # from:基础镜像,一切从这里开始构建
MAINTAINER # maintainer:镜像是谁写的, 姓名+邮箱
RUN # run:镜像构建的时候需要运行的命令
ADD # add:步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR # workdir:镜像的工作目录
VOLUME # volume:挂载的目录
EXPOSE # expose:保留端口配置
CMD # cmd:指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # entrypoint:指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # onbuild:当构建一个被继承DockerFile这个时候就会运行onbuild的指令,触发指令
COPY # copy:类似ADD,将我们文件拷贝到镜像中
ENV # env:构建的时候设置环境变量!
以前的话我们就是使用别人的,现在我们知道了这些指令后,我们来练习自己写一个镜像!
7.2.3 实战测试
创建自己的一个centos
# 1./home下新建dockerfile目录
$ mkdir dockerfile
# 2. dockerfile目录下新建mydockerfile-centos文件
$ vim mydockerfile-centos
# 3.编写Dockerfile配置文件
FROM centos # 基础镜像是官方原生的centos
MAINTAINER xiaohang<1531137510@qq.com> # 作者
ENV MYPATH /usr/local # 配置环境变量的目录
WORKDIR $MYPATH # 将工作目录设置为 MYPATH
RUN yum -y install vim # 给官方原生的centos 增加 vim指令
RUN yum -y install net-tools # 给官方原生的centos 增加 ifconfig命令
EXPOSE 80 # 暴露端口号为80
CMD echo $MYPATH # 输出下 MYPATH 路径
CMD echo "-----end----"
CMD /bin/bash # 启动后进入 /bin/bash
# 4.通过这个文件构建镜像
# 命令: docker build -f 文件路径 -t 镜像名:[tag] .
$ docker build -f mydockerfile-centos -t mycentos:0.1 .
# 5.出现下图后则构建成功
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 0.1 cbf5110a646d 2 minutes ago 311MB
# 6.测试运行
$ docker run -it mycentos:0.1 # 注意带上版本号,否则每次都回去找最新版latest
$ pwd
/usr/local # 与Dockerfile文件中 WORKDIR 设置的 MYPATH 一致
$ vim # vim 指令可以使用
$ ifconfig # ifconfig 指令可以使用
# docker history 镜像id 查看镜像构建历史步骤
$ docker history 镜像id
[root@VM-24-12-centos dockerfile]# docker history 605c77e624dd
IMAGE CREATED CREATED BY SIZE COMMENT
605c77e624dd 3 months ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 3 months ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
<missing> 3 months ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 3 months ago /bin/sh -c #(nop) ENTRYPOINT ["/docker-entr… 0B
<missing> 3 months ago /bin/sh -c #(nop) COPY file:09a214a3e07c919a… 4.61kB
<missing> 3 months ago /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7… 1.04kB
<missing> 3 months ago /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0… 1.96kB
<missing> 3 months ago /bin/sh -c #(nop) COPY file:65504f71f5855ca0… 1.2kB
<missing> 3 months ago /bin/sh -c set -x && addgroup --system -… 61.1MB
<missing> 3 months ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~bullseye 0B
<missing> 3 months ago /bin/sh -c #(nop) ENV NJS_VERSION=0.7.1 0B
<missing> 3 months ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.21.5 0B
<missing> 4 months ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
<missing> 4 months ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 4 months ago /bin/sh -c #(nop) ADD file:09675d11695f65c55… 80.4MB
我们平时拿到一个镜像,可以用 “docker history 镜像id” 研究一下是什么做的
7.2.4 CMD 和 ENTRYPOINT
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
测试CMD:
[root@VM-24-12-centos dockerfile]# vim dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]
[root@VM-24-12-centos dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest:0.1 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 5d0da3dc9764
Step 2/2 : CMD ["ls","-a"]
---> Running in 064c77f9e8b2
Removing intermediate container 064c77f9e8b2
---> 3594071968fc
Successfully built 3594071968fc
Successfully tagged cmdtest:0.1
# 运行镜像
$ docker run cmd-test:0.1 # 由结果可得,运行后就执行了 ls -a 命令
.
..
.dockerenv
bin
dev
etc
home
## 想追加一个命令 -l 执行ls -al命令
[root@VM-24-12-centos dockerfile]# docker run 279bb7d5f91f -l
docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled
## cmd情况下, -l 替换了CMD["ls","-a"]命令,-l不是命令,所以报错!
[root@VM-24-12-centos dockerfile]# docker run 279bb7d5f91f ls -al
total 56
drwxr-xr-x 1 root root 4096 Apr 23 06:18 .
drwxr-xr-x 1 root root 4096 Apr 23 06:18 ..
-rwxr-xr-x 1 root root 0 Apr 23 06:18 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Apr 23 06:18 dev
drwxr-xr-x 1 root root 4096 Apr 23 06:18 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 136 root root 0 Apr 23 06:18 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 Apr 21 07:13 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
测试Entrypoint:
[root@VM-24-12-centos dockerfile]# vim dockerfile-entrypoint-test
FROM centos
ENTRYPOINT ["ls","-a"]
[root@VM-24-12-centos dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test .
Sending build context to Docker daemon 4.096kB
Step 1/2 : FROM centos
---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in b4677105ef8d
Removing intermediate container b4677105ef8d
---> f8b8ec376712
Successfully built f8b8ec376712
Successfully tagged entrypoint-test:latest
[root@VM-24-12-centos dockerfile]# docker run f8b8ec376712
.
..
.dockerenv
bin
dev
etc
home
lib
...
[root@VM-24-12-centos dockerfile]# docker run f8b8ec376712 -l
total 56
drwxr-xr-x 1 root root 4096 Apr 23 06:28 .
drwxr-xr-x 1 root root 4096 Apr 23 06:28 ..
-rwxr-xr-x 1 root root 0 Apr 23 06:28 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Apr 23 06:28 dev
drwxr-xr-x 1 root root 4096 Apr 23 06:28 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
...
7.2.5 实战-Tomcat镜像
1、准备镜像文件 tomcat压缩包,jdk的压缩包!
2、编写dockerfile文件,官方命名Dockerfile
,build会自动寻找这个文件,就不需要-f指定了!
FROM centos:7 # 基础镜像centos:7
MAINTAINER xiaohang<1531137510@qq.com> # 作者信息
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u271-linux-x64.tar.gz /usr/local/ # 添加JDK,ADD会自动解压
ADD apache-tomcat-9.0.62.tar.gz /usr/local/ # 添加Tomcat
RUN yum -y install vim # 安装VIM命令
ENV MYPATH /usr/local # 环境变量设置 工作目录
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_271 # JAVA_HOME 环境变量
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.62 # Tomcat 环境变量
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.62
# 设置环境变量,分隔符为:
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:CATALINA_HOME/bin
EXPOSE 8080 # 设置暴露的端口
CMD /usr/local/apache-tomcat-9.0.62/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.62/bin/logs/catalina.out
可能会遇到的错:
CentOS Linux 8 - AppStream 1.6 B/s | 38 B 00:24
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
The command '/bin/sh -c yum -y install vim' returned a non-zero code: 1
请指定Centos版本7
3、构建镜像
# 因为dockerfile命名使用默认命名 因此不用使用-f 指定文件
docker build -t diytomcat .
4、启动镜像
# -d:后台运行 -p:暴露端口 --name:别名 -v:绑定路径
docker run -d -p 8080:8080 --name tomcat01
-v /home/tomcat/test:/usr/local/apache-tomcat-9.0.62/webapps/test
-v /home/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.62/logs mytomcat:0.1
5、访问测试
$ docker exec -it 自定义容器的id /bin/bash
$ cul localhost:8080
6、发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)
发现:项目部署成功,可以直接访问!
我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!
7.2.6 发布自己的镜像
DockerHub
2、确定这个账号可以登录
3、登录
$ docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username
$ docker login -u 你的用户名 -p 你的密码
4、提交 push镜像
docker push mytomcat
# 会发现push不上去,因为如果没有前缀的话默认是push到 官方的library
# 解决方法:
# 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了
$ docker build -t xiaohang/mytomcat:0.1 .
# 第二种 使用docker tag #然后再次push
$ docker tag 容器id xiaohang/mytomcat:1.0 #然后再次push
$ docker push xiaohang/mytomcat:1.0
7.2.7 发布到阿里云镜像服务上
- 登录阿里云,找到容器镜像服务(https://cr.console.aliyun.com/cn-hangzhou/instance/repositories)
- 找到命名空间
- 创建镜像仓库
4.看文档
docker logout 退出当前登录的账号
8. Docker小结:
六、Docker网络
1、理解Docker0
清空所有容器
docker rm -f $(docker ps -aq)
清空所有镜像
docker rmi -f $(docker images -aq)
测试:
[root@VM-24-12-centos ~]# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 52:54:00:49:d1:3b brd ff:ff:ff:ff:ff:ff
inet 10.0.24.12/22 brd 10.0.27.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe49:d13b/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:0e:e5:eb:26 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:eff:fee5:eb26/64 scope link
valid_lft forever preferred_lft forever
三个网络:
问题:Docker是如何处理容器网络访问的?
# 测试 运行一个tomcat
$ docker run -d -P --name tomcat01 tomcat
# 查看容器内部网络地址
$ docker exec -it 容器id ip addr
# 发现容器启动的时候会得到一个 eth0@if91 ip地址,docker分配!
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
261: eth0@if91: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 思考? linux能不能ping通容器内部! 可以 容器内部可以ping通外界吗? 可以!
$ ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.074 ms
原理
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要按照了docker,就会有一个docker0桥接模式,使用的技术是veth-pair
技术!
再次测试 ip addr
2 、再启动一个容器测试,发现又多了一对网络
# 我们发现这个容器带来网卡,都是一对对的
# veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
# 正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
3、我们来测试下tomcat01和tomcat02是否可以ping通
# 获取tomcat01的ip 172.17.0.2
$ docker-tomcat docker exec -it tomcat01 ip addr
550: eth0@if551: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 让tomcat02 ping tomcat01
$ docker-tomcat docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.098 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.071 ms
# 结论:容器和容器之间是可以互相ping通
网络模型图
结论:tomcat01和tomcat02公用一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
小结
Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应的网桥一对就没了!
思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
2、- - Link
思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
$ docker exec -it tomcat02 ping tomca01 # ping不通
ping: tomca01: Name or service not known
# 运行一个tomcat03 --link tomcat02
$ docker run -d -P --name tomcat03 --link tomcat02 tomcat
5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef
# 3连接2
# 用tomcat03 ping tomcat02 可以ping通
$ docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.115 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms
# 2连接3
# 用tomcat02 ping tomcat03 ping不通
探究:
docker network inspect 网络id 网段相同
docker inspect tomcat03
查看tomcat03里面的/etc/hosts发现有tomcat02的配置
–link 本质就是在hosts配置中添加映射
现在使用Docker已经不建议使用–link了!
自定义网络,不适用docker0!
docker0问题:不支持容器名连接访问!
3、自定义网络
查看所有的docker网络
[root@VM-24-12-centos ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
000f0b7bb122 bridge bridge local
46dc3c551551 host host local
2dea6558d00c none null local
网络模式:
- bridge:桥接docker(默认,自己创建也使用这个)
- none:不配置网络
- host:和宿主机共享网络
- container:容器网络连通!(用的少!)
## 我们直接启动的命令 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 -net bridge tomcat
## docker0特点:默认,域名不能访问,--link可以打通连接!
## 我们可以自定义一个网络:(想想自己家里的路由器)
## --driver bridge
## --subnet 192.168.0.0/16
## --gateway 192.168.0.1
[root@VM-24-12-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
00496e0f79c1a09cd4f632e010d1d572a3c5eb77400e6e14c6dc671824337287
[root@VM-24-12-centos ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
000f0b7bb122 bridge bridge local
46dc3c551551 host host local
00496e0f79c1 mynet bridge local
## 查看自己定义的网络
[root@VM-24-12-centos ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "00496e0f79c1a09cd4f632e010d1d572a3c5eb77400e6e14c6dc671824337287",
"Created": "2022-04-27T20:58:09.144161755+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
## 用自己的网络启动
[root@VM-24-12-centos ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
39a25939ca7d17005c6a3a840fc20f671ae73138d6899617dd08b7b6fba354b8
[root@VM-24-12-centos ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
b9a6da9e634209752e9dee02b3bd9a83beda040ffc420a23f7e02b401fd633be
## 再次查看自定义网络
[root@VM-24-12-centos ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "00496e0f79c1a09cd4f632e010d1d572a3c5eb77400e6e14c6dc671824337287",
"Created": "2022-04-27T20:58:09.144161755+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"39a25939ca7d17005c6a3a840fc20f671ae73138d6899617dd08b7b6fba354b8": {
"Name": "tomcat-net-01",
"EndpointID": "4b6d064f9b6b0f56bc0224c4c9d71ec53864e1c66ca88e7f31af04535c9aae78",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"b9a6da9e634209752e9dee02b3bd9a83beda040ffc420a23f7e02b401fd633be": {
"Name": "tomcat-net-02",
"EndpointID": "b3b0ecb8e8b143f2160bd044ac9d362f4dfccef517dac727bf02021f74cdc449",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
在自定义的网络下,服务可以互相ping通,不用使用–link
好处:
- redis -不同的集群使用不同的网络,保证集群是安全和健康的
- mysql-不同的集群使用不同的网络,保证集群是安全和健康的
4、部署Redis集群
# 创建网卡
docker network create redis --subnet 172.38.0.0/16
# 通过脚本创建六个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
# 创建结点1
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
#创建结点2
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
#创建结点3
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
#创建结点4
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
#创建结点5
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点6
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
# 查看镜像
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
869a6ce9f6b0 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 2 seconds ago Up 1 second 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-6
2ead11d175ce redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 9 seconds ago Up 9 seconds 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-5
349c9d30b905 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 16 seconds ago Up 16 seconds 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-4
e534ebf30369 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 23 seconds ago Up 23 seconds 0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp redis-3
847746759c29 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 31 seconds ago Up 30 seconds 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-2
b08ea8b5184e redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 48 seconds ago Up 48 seconds 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-1
#创建集群
[root@VM-24-12-centos ~]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof nodes.conf
/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: 7b7f474f5deb841ed789af0d2cd3a7294c1bac98 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: 32b72ace218af7196f8a1761a3676efc5642a03b 172.38.0.14:6379
replicates 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7
S: f8337c9e18eafbc183b60738ea3410de5f0c55fd 172.38.0.15:6379
replicates 7b7f474f5deb841ed789af0d2cd3a7294c1bac98
S: 4f108a64c4db7b5d274a5de1d9b6292dac9a371c 172.38.0.16:6379
replicates 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40
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: 7b7f474f5deb841ed789af0d2cd3a7294c1bac98 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: f8337c9e18eafbc183b60738ea3410de5f0c55fd 172.38.0.15:6379
slots: (0 slots) slave
replicates 7b7f474f5deb841ed789af0d2cd3a7294c1bac98
S: 32b72ace218af7196f8a1761a3676efc5642a03b 172.38.0.14:6379
slots: (0 slots) slave
replicates 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7
S: 4f108a64c4db7b5d274a5de1d9b6292dac9a371c 172.38.0.16:6379
slots: (0 slots) slave
replicates 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
# docker 搭建redis集群完成
/data # redis-cli -c
172.38.0.13:6379> set a b
OK
172.38.0.13:6379> get a
"b"
172.38.0.13:6379> cluster nodes
32b72ace218af7196f8a1761a3676efc5642a03b 172.38.0.14:6379@16379 slave 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 0 1651130873827 4 connected
4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 172.38.0.12:6379@16379 master - 0 1651130875530 2 connected 5461-10922
f8337c9e18eafbc183b60738ea3410de5f0c55fd 172.38.0.15:6379@16379 slave 7b7f474f5deb841ed789af0d2cd3a7294c1bac98 0 1651130875530 5 connected
8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 172.38.0.13:6379@16379 myself,master - 0 1651130874000 3 connected 10923-16383
4f108a64c4db7b5d274a5de1d9b6292dac9a371c 172.38.0.16:6379@16379 slave 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 0 1651130875830 6 connected
7b7f474f5deb841ed789af0d2cd3a7294c1bac98 172.38.0.11:6379@16379 master - 0 1651130874528 1 connected 0-5460
# 现在我们模拟宕机,挂掉当前的master
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
869a6ce9f6b0 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-6
2ead11d175ce redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-5
349c9d30b905 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-4
e534ebf30369 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp redis-3
847746759c29 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-2
b08ea8b5184e redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-1
[root@VM-24-12-centos ~]# docker stop redis-3
redis-3
# 当前容器成功挂掉
172.38.0.13:6379> get a
^C
# 重新获取 get a
/data # redis-cli -c
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
172.38.0.14:6379> cluster nodes
8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 172.38.0.13:6379@16379 master,fail - 1651131226581 1651131225780 3 connected
32b72ace218af7196f8a1761a3676efc5642a03b 172.38.0.14:6379@16379 myself,master - 0 1651131291000 7 connected 10923-16383
4f108a64c4db7b5d274a5de1d9b6292dac9a371c 172.38.0.16:6379@16379 slave 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 0 1651131291892 6 connected
f8337c9e18eafbc183b60738ea3410de5f0c55fd 172.38.0.15:6379@16379 slave 7b7f474f5deb841ed789af0d2cd3a7294c1bac98 0 1651131290590 5 connected
4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 172.38.0.12:6379@16379 master - 0 1651131291592 2 connected 5461-10922
7b7f474f5deb841ed789af0d2cd3a7294c1bac98 172.38.0.11:6379@16379 master - 0 1651131291000 1 connected 0-5460
七、SpringBoot微服务打包Docker镜像
- 构建SpringBoot项目
- 编写Dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
- 构建镜像
# 把打好的jar包和Dockerfile上传到linux
[root@VM-24-12-centos ceshi]# ll
总用量 17136
-rw-r--r-- 1 root root 17542922 4月 28 16:39 demo-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root 124 4月 28 16:38 Dockerfile
# 构建镜像,不要忘了最后有一个点
[root@VM-24-12-centos ceshi]# docker build -t xiaohang .
Sending build context to Docker daemon 17.55MB
Step 1/5 : FROM java:8
8: Pulling from library/java
5040bd298390: Pull complete
fce5728aad85: Pull complete
76610ec20bf5: Pull complete
60170fec2151: Pull complete
e98f73de8f0d: Pull complete
11f7af24ed9c: Pull complete
49e2d6393f32: Pull complete
bb9cdec9c7f3: Pull complete
Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
Status: Downloaded newer image for java:8
---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
---> 18cfc3f88a7f
Step 3/5 : CMD ["--server.port=8080"]
---> Running in 429a00e60898
Removing intermediate container 429a00e60898
---> ccd6f998893a
Step 4/5 : EXPOSE 8080
---> Running in 9f6841a10f25
Removing intermediate container 9f6841a10f25
---> 3050a62735ad
Step 5/5 : ENTRYPOINT ["java", "-jar", "/app.jar"]
---> Running in 5b4c19329c96
Removing intermediate container 5b4c19329c96
---> e3f233220c0c
Successfully built e3f233220c0c
Successfully tagged xiaohang:latest
[root@VM-24-12-centos ceshi]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xiaohang latest e3f233220c0c 43 seconds ago 661MB
redis 5.0.9-alpine3.11 3661c84ee9d0 2 years ago 29.8MB
java 8 d23bdf5b1b1b 5 years ago 643MB
[root@VM-24-12-centos ceshi]# docker run -d -P --name xiaohang-web xiaohang
9d433ae3ba3290438bac32065071b6360e3db9d58af5df0187dd9c07cedd8832
[root@VM-24-12-centos ceshi]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d433ae3ba32 xiaohang "java -jar /app.jar …" 5 seconds ago Up 4 seconds 0.0.0.0:49157->8080/tcp, :::49157->8080/tcp xiaohang-web
869a6ce9f6b0 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-6
2ead11d175ce redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-5
349c9d30b905 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-4
847746759c29 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-2
b08ea8b5184e redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-1
[root@VM-24-12-centos ceshi]# curl localhost:8080
hello xiaohang!
- 发布运行
八、DockerCompose
1、简介
之前我们是:DockerFile -> build -> run 手动操作,单个容器!
现在我们有很多微服务,使用Docker Compose来轻松高效的管理容器,定义多个容器。
官方介绍
- 定义、运行多个容器。
- YAML file 配置文件
- single command 命令有哪些?
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.
- 所有环境都可以使用 Compose。
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
- 三步骤:
Using Compose is basically a three-step process:
- Define your app’s environment with a
Dockerfile
so it can be reproduced anywhere.
- Dockerfile保证我们的项目在任何地方运行
- Define the services that make up your app in
docker-compose.yml
so they can be run together in an isolated environment.
- services 什么服务。
- docker-compose.yml 这个文件怎么写?
- Run
docker compose up
and the Docker compose command starts and runs your entire app. You can alternatively rundocker-compose up
using the docker-compose binary.
- 启动项目
作用:批量容器编排
个人理解
Compose是Docker官方开源的项目,需要安装!
Compose:
version: "3.9" # optional since v1.27.0
services:
web:
build: .
ports:
- "8000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
重要的概念:
- 服务:Services
- 项目:project 一组关联的容器
2、安装
# 1、下载
# 国内地址
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# 2、授权
sudo chmod +x /usr/local/bin/docker-compose
# 3、检查是否安装成功
docker-compose version
3、体验
补充:(官网的例子无法通过测试)
app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
requirements.txt
flask
redis
Dockerfile
FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
# 官网的用来flask框架,我们这里不用它
# 这告诉Docker
# 从python3.7开始构建镜像
# 将当前目录添加到/code印像中的路径中
# 将工作目录设置为/code
# 安装Python依赖项
# 将容器的默认命令设置为python app.py
docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"
启动:
docker-compose up
流程:
- 创建网络
- 执行Docker-compose.yaml
- 启动服务
Docker小结:
- Docker镜像。 run => 容器
- DockerFile 构建镜像(服务打包)
- docker-compose 启动项目(编排、多个微服务/环境)
- Docker网络
4、yaml规则
docker-compose.yaml 核心!
# 3层
version: '' # 版本
services: # 服务
服务1: web
# 服务配置
images
build
network
......
服务2: redis
.....
服务3: mysql
.....
# 其他配置 网络/卷 全局规则
volumes:
networks:
configs
5、实战开源项目
一键搭建WordPress博客
docker-compose up 启动
docker-compose down 停止
6、实战
1.初始化SpringBoot项目
配置文件:
2.编写Dockerfile文件构建镜像
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
3.docker-compose.yml编排项目
version: '3.8'
services:
demoapp:
build: .
image: demoapp
depends_on:
- redis
ports:
- "8080:8080"
redis:
image: "library/redis:alpine"
4.丢到服务器,docker-compose up 编排启动
打包jar包
一定要检查一下jar包是否打包正确,4KB的那种,是因为maven没有配置插件,没把依赖打包进来。
紧接着,我们上传到服务器中:
[root@VM-24-12-centos home]# mkdir demoDcoker
[root@VM-24-12-centos home]# cd demoDcoker/
[root@VM-24-12-centos demoDcoker]# ls
[root@VM-24-12-centos demoDcoker]# ls
demo-0.0.1-SNAPSHOT.jar docker-compose.yml Dockerfile
[root@VM-24-12-centos demoDcoker]# docker-compose up
Creating network "demodcoker_default" with the default driver
Building demoapp
Step 1/5 : FROM java:8
---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
---> 9642ca5cf204
Step 3/5 : CMD ["--server.port=8080"]
---> Running in d5c3d7311cb4
Removing intermediate container d5c3d7311cb4
---> c9e8a80cc852
Step 4/5 : EXPOSE 8080
---> Running in 7cd3844db211
Removing intermediate container 7cd3844db211
---> 8fadaa095ba1
Step 5/5 : ENTRYPOINT ["java", "-jar", "/app.jar"]
---> Running in ca5f1648bc5a
Removing intermediate container ca5f1648bc5a
---> d3d778d2f33f
Successfully built d3d778d2f33f
Successfully tagged demoapp:latest
WARNING: Image for service demoapp was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating demodcoker_redis_1 ... done
Creating demodcoker_demoapp_1 ... done
Attaching to demodcoker_redis_1, demodcoker_demoapp_1
redis_1 | 1:C 21 Jun 2022 03:35:13.790 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 21 Jun 2022 03:35:13.790 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 21 Jun 2022 03:35:13.790 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1 | 1:M 21 Jun 2022 03:35:13.791 * monotonic clock: POSIX clock_gettime
redis_1 | 1:M 21 Jun 2022 03:35:13.791 * Running mode=standalone, port=6379.
redis_1 | 1:M 21 Jun 2022 03:35:13.791 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1 | 1:M 21 Jun 2022 03:35:13.791 # Server initialized
redis_1 | 1:M 21 Jun 2022 03:35:13.791 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1 | 1:M 21 Jun 2022 03:35:13.791 * Ready to accept connections
demoapp_1 |
demoapp_1 | . ____ _ __ _ _
demoapp_1 | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
demoapp_1 | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
demoapp_1 | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
demoapp_1 | ' |____| .__|_| |_|_| |_\__, | / / / /
demoapp_1 | =========|_|==============|___/=/_/_/_/
demoapp_1 | :: Spring Boot :: (v2.4.1)
demoapp_1 |
demoapp_1 | 2022-06-21 03:35:17.486 INFO 1 --- [ main] com.dockerdemo.DemoApplication : Starting DemoApplication using Java 1.8.0_111 on da5653278dec with PID 1 (/app.jar started by root in /)
demoapp_1 | 2022-06-21 03:35:17.489 INFO 1 --- [ main] com.dockerdemo.DemoApplication : No active profile set, falling back to default profiles: default
demoapp_1 | 2022-06-21 03:35:18.556 INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
demoapp_1 | 2022-06-21 03:35:18.558 INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
demoapp_1 | 2022-06-21 03:35:18.577 INFO 1 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
demoapp_1 | 2022-06-21 03:35:19.188 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
demoapp_1 | 2022-06-21 03:35:19.225 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
demoapp_1 | 2022-06-21 03:35:19.225 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41]
demoapp_1 | 2022-06-21 03:35:19.291 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
demoapp_1 | 2022-06-21 03:35:19.291 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1666 ms
demoapp_1 | 2022-06-21 03:35:20.278 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
demoapp_1 | 2022-06-21 03:35:20.638 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
demoapp_1 | 2022-06-21 03:35:20.651 INFO 1 --- [ main] com.dockerdemo.DemoApplication : Started DemoApplication in 4.093 seconds (JVM running for 6.056)
测试:
重新构建项目:
docker-compose up --build # 重新部署!
总结:
- 工程
- 服务
- 容器
九、DockerSwarm
1、集群
购买服务器(四台) => 搭建双主双从
工作机制:
官网直达
docker swarm init --help
ip addr # 获取自己的ip(用内网的不要流量)
[root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker swarm init --advertise-addr 172.16.250.97
Swarm initialized: current node (otdyxbk2ffbogdqq1kigysj1d) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3vovnwb5pkkno2i3u2a42yrxc1dk51zxvto5hrm4asgn37syfn-0xkrprkuyyhrx7cidg381pdir 172.16.250.97:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
初始化结点docker swarm init
docker swarm join 加入一个结点!
# 获取令牌
docker swarm join-token manager
docker swarm join-token worker
2、Raft协议
保证大多数节点存活才可以用。 至少要保证三个主节点
3、体会
弹性、扩缩容
容器 => 服务
灰度发布:金丝雀发布!
docker run 容器启动! 不具有扩缩容器
docker service 服务! 具有扩缩容器,滚动更新!
4、概念总结
1.swarm
集群的管理和编号,docker可以初始化一个swarm集群,其他节点可以加入。(身份:管理员、工作者)
2.Node
就是一个docker节点,多个节点组成了网络集群。
3.Service
任务,可以在管理节点或者工作节点来运行核心。
4.Task
容器内的命令,细节任务!
逻辑是不变的!
命令 -> 管理 -> API -> 调度 -> 工作节点(创建Task容器维护创建)