Docker基础入门

一、CentOS7安装Docker

#查看服务器内核版本
uname -r
#查看系统信息
cat /etc/os-release

#1.yum包更新到最新
sudo yum update
#2.安装需要的软件包,yum-util提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
sudo yum install -y yum-util device-mapper-persistent-data lvm2
#3.设置yum源
#使用官方源地址(比较慢)
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
#建议使用阿里云地址(比较快)
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#结果
Loaded plugins: fastestmirror, langpacks
adding repo from: http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
#更新yum软件包索引
yum makecache fast
#结果
Loaded plugins: fastestmirror, langpacks
Determining fastest mirrors
docker-ce-stable | 3.5 kB 00:00:00
epel | 4.7 kB 00:00:00
extras | 2.9 kB 00:00:00
os | 3.6 kB 00:00:00
updates | 2.9 kB 00:00:00
(1/2): docker-ce-stable/7/x86_64/updateinfo | 55 B 00:00:00
(2/2): docker-ce-stable/7/x86_64/primary_db | 97 kB 00:00:00
Metadata Cache Created
#4.安装docker,出现输入的界面都按Y,出现Complete!便成功了。
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
#结果
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Total download size: 107 M
Installed size: 376 M
#这里选y
Is this ok [y/d/N]: y
Downloading packages:
(1/18): container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm | 40 kB 00:00:00
(2/18): audit-libs-python-2.8.5-4.el7.x86_64.rpm MB 00:00:59
Retrieving key from https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
Importing GPG key 0x621E9F35:
Userid : "Docker Release (CE rpm) <docker@docker.com>"
Fingerprint: 060a 61c5 1b55 8a7f 742b 77aa c52f eb6b 621e 9f35
From : https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
#这里选y
Is this ok [y/N]: y
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Warning: RPMDB altered outside of yum.
** Found 2 pre-existing rpmdb problem(s), 'yum check' output follows:
······
Installed:
containerd.io.x86_64 0:1.6.16-3.1.el7 docker-buildx-plugin.x86_64 0:0.10.2-1.el7 docker-ce.x86_64 3:23.0.1-1.el7 docker-ce-cli.x86_64 1:23.0.1-1.el7
docker-compose-plugin.x86_64 0:2.16.0-1.el7

Dependency Installed:
audit-libs-python.x86_64 0:2.8.5-4.el7 checkpolicy.x86_64 0:2.5-8.el7 container-selinux.noarch 2:2.119.2-1.911c772.el7_8
docker-ce-rootless-extras.x86_64 0:23.0.1-1.el7 docker-scan-plugin.x86_64 0:0.23.0-3.el7 fuse-overlayfs.x86_64 0:0.7.2-6.el7_8
fuse3-libs.x86_64 0:3.6.1-4.el7 libcgroup.x86_64 0:0.41-21.el7 libsemanage-python.x86_64 0:2.5-14.el7
policycoreutils-python.x86_64 0:2.5-34.el7 python-IPy.noarch 0:0.75-6.el7 setools-libs.x86_64 0:3.3.8-4.el7
slirp4netns.x86_64 0:0.4.3-4.el7_8

Complete!

#5.查看docker版本,验证是否安装成功
sudo docker version
#结果
Client: Docker Engine - Community
Version: 23.0.1
API version: 1.42
Go version: go1.19.5
Git commit: a5ee5b1
Built: Thu Feb 9 19:51:00 2023
OS/Arch: linux/amd64
Context: default

Server: Docker Engine - Community
Engine:
Version: 23.0.1
API version: 1.42 (minimum version 1.12)
Go version: go1.19.5
Git commit: bc3805a
Built: Thu Feb 9 19:48:42 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.16
GitCommit: 31aa4358a36870b21a992d3ad2bef29e1d693bec
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0

#6.启动docker
sudo systemctl start docker

#7.通过运行hello-world映像来验证 Docker 引擎安装是否成功。
sudo docker run hello-world
#结果
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:aa0cc8055b82dc2509bed2e19b275c8f463506616377219d9642221ab53cf9fe
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/

#8.停止docker
#虽然停止了docker服务,但是docker服务在关闭状态下有被访问自动唤醒的机制,即这时再执行任意docker命令会直接启动docker服务
sudo systemctl stop docker
#如果真的不希望docker被访问自动唤醒,需要把守护进程服务也关掉
sudo systemctl stop docker.socket
#查看docker是否真被关掉,查看docker状态
sudo systemctl status docker

卸载docker:

#1.卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
#2.删除资源目录(/var/lib/docker docker的默认工作路径)
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

二、Docker的基本命令

帮助命令

docker version #显示docker的版本信息
docker info #显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help #万能命令

帮助文档地址:docker | Docker Documentation

镜像命令

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

[lighthouse@VM-16-5-centos /]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 16 months ago 13.3kB

# 解释
REPOSITORY # 镜像的仓库源
TAG # 镜像的标签
IMAGE ID # 镜像的id
CREATED # 镜像的创建时间
SIZE # 镜像的大小

# 可选项
-a, --all # 列出所有镜像
-q, --quiet # 只显示镜像的id

docker search 搜索镜像

[lighthouse@VM-16-5-centos /]$ sudo docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 13780 [OK]
mariadb MariaDB Server is a high performing open sou… 5262 [OK]
percona Percona Server is a fork of the MySQL relati… 599 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 734 [OK]
circleci/mysql MySQL is a widely used, open-source relation… 28
bitnami/mysql Bitnami MySQL Docker Image 80 [OK]
bitnami/mysqld-exporter 4
ubuntu/mysql MySQL open source fast, stable, multi-thread… 41

# 可选项,通过收藏数来过滤
--filter=STARS=3000 #搜索出来的镜像就是收藏数大于3000的。

docker pull 下载镜像

#下载镜像 docker pull 镜像名:tag
[lighthouse@VM-16-5-centos /]$ sudo docker pull mysql:5.7
5.7: Pulling from library/mysql #如果哦不写tag,默认就是最新版本
e048d0a38742: Pull complete #分层下载docker image的核心,联合文件系统
c7847c8a41cb: Pull complete
351a550f260d: Pull complete
8ce196d9d34f: Pull complete
17febb6f2030: Pull complete
d4e426841fb4: Pull complete
fda41038b9f8: Pull complete
f47aac56b41b: Pull complete
a4a90c369737: Pull complete
97091252395b: Pull complete
84fac29d61e9: Pull complete
Digest: sha256:8cf035b14977b26f4a47d98e85949a7dd35e641f88fc24aa4b466b36beecf9d6 #签名
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7 #真实地址

docker rmi -f [镜像ID] 删除镜像

#删除镜像
[lighthouse@VM-16-5-centos /]$ sudo docker rmi -f 57da161f45ac #删除指定的镜像
Untagged: mysql:latest
Untagged: mysql@sha256:8653a170e0b0df19ea95055267def2615fc53c62df529e3750817c1a886485f0
Deleted: sha256:57da161f45ac3835bc872dcb50f0cde87f65661ba8f50a5a0835dee7e262703f
Deleted: sha256:9e4b6222a6cefc0be6e8ade3cd1692188b6eecf71fcc2568a693c0e630614a0a
Deleted: sha256:b1cc52ec5ce1f3261dbe86f7b09bb70061e71ece8b9a2864ed847187ddc7605a
Deleted: sha256:06bb8fe22fec310fc5dabc4298e23b46b579d3a7d91413e18229195fe5f54436
Deleted: sha256:1d45093bae7b3d23220a568d07cbee31bdc66e78b4a08d509684faa2500a4adc
Deleted: sha256:a1631c5cec986cf56dfddd8f902a7c79052a0157d4ba325bb28f62c909d0e8ae
Deleted: sha256:5020329708536d258b967ba499c93ce57ca8612b4b78c49d25c2a4a6ad5c8407
Deleted: sha256:02ced332f0c6778bf91754fde67302bbc07bc5933b48a92c77b4576e984e55e8
Deleted: sha256:b289f85ed3850442cb04b1f1f9b7a7409d88a43d277000cdb4f0e6e775a42a65
Deleted: sha256:097c8299fba37fe21a9561d58e1e423d89873064b716aa74c233590db9c6db86
Deleted: sha256:ea6feaa089dca094ae502b77cc9ffc86d2e42cd3fbe1a91d38ecf2064de7ac05
Deleted: sha256:9cd9df9ffc972e9abc946d855162ef0c40dff9a89f10c962b7920154a3d943d8

#删除多个镜像
sudo docker rmi -f 镜像id 镜像id 镜像id
#删除所有镜像
sudo docker rmi -f $(docker images -aq)

容器命令

新建容器并启动(前提是已经下好了镜像)

#新建容器并启动
docker run [可选参数] image:[tag]

#参数说明
--name="Name" #容器名字,tomcat01、tomcat02用来区分容器
-d #后台方式运行
-it #使用交互方式运行,比如进入容器查看内容
-p #指定容器端口,比如 -p 8080 指定8080端口运行容器;也可以和主机端口映射,比如 -p 80:8080。
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
-P #大P 随机指定运行的端口。
-e #环境配置修改,列如:-e ES_JAVA_OPTS="-Xms64m -Xmx512m" 修改内存最小占用64M和最大占用512M。

#启动并进入容器
sudo docker run -it mysql:5.7

列出所有运行中的容器

#列出所有正在运行的容器
sudo docker ps

#列出所有运行中容器+带出历史运行过得容器
sudo docker ps -a
sudo docker ps -aq #只显示所有容器的id
#显示最近创建的容器, ? 为显示的个数
sudo docker ps -n=?

退出容器

#停止并退出容器
exit
#容器不停止并退出
快捷键 Ctrl + P + Q

删除容器

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

启动和停止容器的操作

sudo docker start 容器id      #启动一个已经停止了的容器
sudo docker restart 容器id #重启容器
sudo docker stop 容器id #停止当前正在运行的容器
sudo docker kill 容器id #强制停止容器,杀掉容器

查看容器使用主机资源

sudo docker stats 容器id     #可以看到运行容器使用的CPU占用率和内存占用率

三、常用其他命令

后台启动容器

#命令: docker run -d 镜像名
[lighthouse@VM-16-5-centos /]$ docker run -d centos

#问题docker ps,发现 centos 停止了

#常见的坑:docker容器使用后台运行,就必须要一个前台进程,docker发现没有应用,就会自动停止。
#nginx容器启动后,发现自己没有提供服务就会立刻停止,就是没有程序了。

查看日志

sudo docker logs -tf --tail 日志数量 容器id
#选项
-tf #显示日志
--tail number #number:想要显示的日志数量

查看容器中的进程信息

#查看容器的进程信息
sudo docker top 容器id

查看镜像的元数据

#查看镜像的信息
sudo docker image inspect 镜像名:tag
#查看运行容器的信息
sudo docker inspect 容器id

进入当前正在运行的容器

#我们通常容器都是使用后台方式运行的,需要进入容器,修改配置。
#命令一
sudo docker exec -it 容器id /bin/bash #进入容器后开启一个新的终端,可以在里面操作(常用)
#命令二
sudo docker attach 容器id #进入容器正在执行的终端,不会启动新的进程。

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

sudo docker cp 容器id:容器内路径 目的的主机路径

四、作业练习

1.docker安装nginx

#搜索镜像
[lighthouse@VM-16-5-centos /]$ sudo docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 18074 [OK]
bitnami/nginx Bitnami nginx Docker Image 150 [OK]
bitnami/nginx-ingress-controller Bitnami Docker Image for NGINX Ingress Contr… 23 [OK]
ubuntu/nginx Nginx, a high-performance reverse proxy & we… 77
kasmweb/nginx An Nginx image based off nginx:alpine and in… 4
rancher/nginx-ingress-controller 11
rancher/nginx-ingress-controller-defaultbackend 2
bitnami/nginx-exporter 3
rancher/nginx 2
ibmcom/nginx-ingress-controller Docker Image for IBM Cloud Private-CE (Commu… 4
rapidfort/nginx-ib RapidFort optimized, hardened image for NGIN… 0
vmware/nginx-photon 1
rapidfort/nginx RapidFort optimized, hardened image for NGINX 2
ibmcom/nginx-ingress-controller-ppc64le Docker Image for IBM Cloud Private-CE (Commu… 0
bitnami/nginx-ldap-auth-daemon 3
ibmcom/nginx-ppc64le Docker image for nginx-ppc64le 0
vmware/nginx 2
rancher/nginx-conf 0
rapidfort/nginx-official RapidFort optimized, hardened image for NGIN… 1
linuxserver/nginx An Nginx container, brought to you by LinuxS… 184
privatebin/nginx-fpm-alpine PrivateBin running on an Nginx, php-fpm & Al… 72 [OK]
bitnami/nginx-intel 1
rancher/nginx-ssl 0
circleci/nginx This image is for internal use 2
continuumio/nginx-ingress-ws 0
#下载镜像
[lighthouse@VM-16-5-centos /]$ sudo docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
bb263680fed1: Already exists
258f176fd226: Pull complete
a0bc35e70773: Pull complete
077b9569ff86: Pull complete
3082a16f3b61: Pull complete
7e9b29976cce: Pull complete
Digest: sha256:6650513efd1d27c1f8a5351cbd33edf85cc7e0d9d0fcb4ffb23d8fa89b601ba8
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
#运行镜像
[lighthouse@VM-16-5-centos /]$ sudo docker run -d --name nginx01 -p 3344:80 nginx
62922997834fabe72a1051794ac449392d8649cb4de930a8f3afe54c9a086c38
#查看镜像是否运行
[lighthouse@VM-16-5-centos /]$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
62922997834f nginx "/docker-entrypoint.…" 20 seconds ago Up 19 seconds 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
#访问本机3344端口,测试镜像是否运行成功
[lighthouse@VM-16-5-centos /]$ curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#进入容器
[lighthouse@VM-16-5-centos /]$ sudo docker exec -it 62922997834f /bin/bash
root@62922997834f:/#
#查看容器路径及内容
root@62922997834f:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@62922997834f:/# cd /etc/nginx
root@62922997834f:/etc/nginx# ls
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
#退出容器
root@62922997834f:/# exit
exit
[lighthouse@VM-16-5-centos /]$

2、docker安装tomcat

#官方的使用
docker run -it --rm tomcat:9.0
#我们之前启动都是后台,停止了容器之后,容器还可以查到。docker run -it --rm tomcat:9.0 一般用来测试,用完即删。

#我们使用后台启动
#下载tomcat镜像
[lighthouse@VM-16-5-centos /]$ sudo docker pull tomcat:9.0
9.0: Pulling from library/tomcat
10ac4908093d: Pull complete
6df15e605e38: Pull complete
2db012dd504c: Pull complete
8fa912900627: Pull complete
f8fe20946c04: Pull complete
1f8839e6ed79: Pull complete
0839ea5a8b1a: Pull complete
Digest: sha256:88d10376048d05596c7dc0d4b18b29015b4116871698facdcb1fd20c41e33cb7
Status: Downloaded newer image for tomcat:9.0
docker.io/library/tomcat:9.0

#启动容器
[lighthouse@VM-16-5-centos /]$ sudo docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0
dcf25e61c13894a0d61870fcc1ad6a4cefcb531b00e9cd5fec5f7d54971d6871

#查看容器是否启动
[lighthouse@VM-16-5-centos /]$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dcf25e61c138 tomcat:9.0 "catalina.sh run" 44 seconds ago Up 43 seconds 0.0.0.0:3355->8080/tcp, :::3355->8080/tcp tomcat01

#进入容器
[lighthouse@VM-16-5-centos /]$ sudo docker exec -it tomcat01 /bin/bash
root@dcf25e61c138:/usr/local/tomcat# ls
bin BUILDING.txt conf CONTRIBUTING.md lib LICENSE logs native-jni-lib NOTICE README.md RELEASE-NOTES RUNNING.txt temp webapps webapps.dist work
root@dcf25e61c138:/usr/local/tomcat# ls -al
total 172
drwxr-xr-x 1 root root 4096 Feb 1 02:41 .
drwxr-xr-x 1 root root 4096 Feb 1 02:37 ..
drwxr-xr-x 2 root root 4096 Feb 1 02:41 bin
-rw-r--r-- 1 root root 19992 Jan 9 22:33 BUILDING.txt
drwxr-xr-x 1 root root 4096 Feb 13 06:32 conf
-rw-r--r-- 1 root root 6210 Jan 9 22:33 CONTRIBUTING.md
drwxr-xr-x 2 root root 4096 Feb 1 02:41 lib
-rw-r--r-- 1 root root 57092 Jan 9 22:33 LICENSE
drwxrwxrwx 1 root root 4096 Feb 13 06:32 logs
drwxr-xr-x 2 root root 4096 Feb 1 02:41 native-jni-lib
-rw-r--r-- 1 root root 2333 Jan 9 22:33 NOTICE
-rw-r--r-- 1 root root 3398 Jan 9 22:33 README.md
-rw-r--r-- 1 root root 6901 Jan 9 22:33 RELEASE-NOTES
-rw-r--r-- 1 root root 16505 Jan 9 22:33 RUNNING.txt
drwxrwxrwx 2 root root 4096 Feb 1 02:41 temp
drwxr-xr-x 2 root root 4096 Feb 1 02:41 webapps
drwxr-xr-x 7 root root 4096 Jan 9 22:33 webapps.dist
drwxrwxrwx 2 root root 4096 Jan 9 22:33 work
root@dcf25e61c138:/usr/local/tomcat# cd webapps
#进入webapps文件夹发现没有文件
root@dcf25e61c138:/usr/local/tomcat/webapps# ls
root@dcf25e61c138:/usr/local/tomcat/webapps# cd ..
#进入webapps.dist文件夹发现tomcat页面文件在这
root@dcf25e61c138:/usr/local/tomcat# cd webapps.dist/
root@dcf25e61c138:/usr/local/tomcat/webapps.dist# ls
docs examples host-manager manager ROOT
root@dcf25e61c138:/usr/local/tomcat/webapps.dist# cd ..
#将webapps.dist目录下的所有文件拷贝到webapps目录
root@dcf25e61c138:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@dcf25e61c138:/usr/local/tomcat# cd webapps
root@dcf25e61c138:/usr/local/tomcat/webapps# ls -al
total 32
drwxr-xr-x 1 root root 4096 Feb 13 06:46 .
drwxr-xr-x 1 root root 4096 Feb 1 02:41 ..
drwxr-xr-x 15 root root 4096 Feb 13 06:46 docs
drwxr-xr-x 7 root root 4096 Feb 13 06:46 examples
drwxr-xr-x 6 root root 4096 Feb 13 06:46 host-manager
drwxr-xr-x 6 root root 4096 Feb 13 06:46 manager
drwxr-xr-x 3 root root 4096 Feb 13 06:46 ROOT
root@dcf25e61c138:/usr/local/tomcat/webapps#
#此时访问3355端口就会出现tomcat初始欢迎页面

#退出容器
root@dcf25e61c138:/usr/local/tomcat# exit
exit

3、docker安装portainer

什么是portainer?

Docker图形化界面管理工具!提供一个后台面板供我们操作!

#安装并运行portainer容器
sudo docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

访问https://ip:8088,出现登录界面,设置密码并登录,选择连接本地docker,就可以管理docker了!

五、Docker镜像讲解

1、commit镜像

docker commit 提交容器成为一个新的副本

#命令和git原理类似
docker commit -a="作者" -m="提交的描述信息" 容器id 目标镜像名:[tag]



#实践
#下载一个tomcat官方镜像,并运行镜像,发现webapps里没有文件。

#将镜像里的webapps.dist目录里的文件拷贝到webapps目录。

#将修改后的容器提交到本地docker镜像库,使用 docker images 发现已经提交到本地docker镜像库。

#作用
#可以将当前容器的状态,内容保存,相当于版本控制器。

六、容器数据卷

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

-v 表示将主机目录挂载到容器目录

sudo docker run -it -v 主机目录:容器内目录

#测试
sudo docker run -it -v /home/ceshi:/home centos /bin/bash

实战:Docker安装MySQL

思考:MySQL的数据持久化问题 mysql数据都存储在data目录,需要将data目录映射到主机。

#获取镜像
sudo docker pull mysql:5.7
#运行镜像(安装启动mysql时,需要配置密码,这是需要注意的一点)
#官方示列(-e 表示要配置容器环境,-e MYSQL_ROOT_PASSWORD=root 表示配置mysql的密码为root)
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

#测试
-d 后台启动
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名称

sudo 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:5.7

#启动之后在本地用Navicat连接测试。

具名和匿名挂载

#匿名挂载
-v 容器内路径
#示列
sudo docker run -d -P --name nginx01 -v /etc/nginx nginx
#查看所有的卷(volume)的情况
sudo docker volume ls
#结果
[lighthouse@VM-16-5-centos /]$ sudo docker volume ls
DRIVER VOLUME NAME
local e2811eb1e2b4fad36ecf478e91e8ffc6f1c87f389266e29d2c73111631eacf52
#这里发现-v 后面只写了容器内路径,没有写主机路径,得到的卷名是一串哈希值。

#具名挂载
-v 主机目录:容器内目录
#示列
sudo docker run -d -P --name nginx02 -v juming_nginx:/etc/nginx nginx
#查看所有的卷(volume)的情况
sudo docker volume ls
#这里发现 -v 卷名:容器内路径,得到的卷名是指定的juming_nginx。

#查看卷的信息
sudo docker volume inspect 卷名
#结果
[lighthouse@VM-16-5-centos /]$ sudo docker volume inspect e2811eb1e2b4fad36ecf478e91e8ffc6f1c87f389266e29d2c73111631eacf52
[
{
"CreatedAt": "2023-02-12T17:47:52+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/e2811eb1e2b4fad36ecf478e91e8ffc6f1c87f389266e29d2c73111631eacf52/_data",
"Name": "e2811eb1e2b4fad36ecf478e91e8ffc6f1c87f389266e29d2c73111631eacf52",
"Options": null,
"Scope": "local"
}
]

所有的docker容器内的卷,没有指定目录的情况下,所有的卷数据都是存储在 /var/lib/docker/volumes/xxx卷名/_data 目录下。

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

# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载。
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /主机路径:容器内路径 #指定路径挂载

拓展:

#通过 -v 容器内路径:ro|rw 改变读写权限
ro readonly #只读
rw readwrite #可读可写

#一旦设置了这个容器只读权限,容器对我们挂载出来的内容就有限定了!
sudo docker run -d -P --name nginx02 -v juming_nginx:/etc/nginx:ro nginx

sudo docker run -d -P --name nginx02 -v juming_nginx:/etc/nginx:rw nginx

#ro 只要看到ro就说明这个路径内容只能通过宿主机操作,容器内部无法操作。

初识Dockerfile

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

通过脚本生成镜像

  1. 编写Dockerfile脚本文件

    #创建一个dockerfile文件,名字可以随机,建议Dockerfile。
    #文件中的内容: 指令(大写) 参数

    #基于CentOS镜像
    FROM centos
    #挂载数据卷(只写了容器内路径,是匿名挂载,挂载在宿主机的 `/var/lib/docker/volumes/xxx卷名/_data` 目录下)
    VOLUME ["volume01","volume02"]
    #结束了可以打印提示信息
    CMD echo "---------end------------"
    #构建好后进入bash控制台
    CMD /bin/bash

    #这里的每个命令,就是镜像的一层!
  1. 在dockerfile文件所在的路径运行脚本构建镜像

    #注意命令结尾有一个( . )。
    sudo docker build -f dockerfile文件的路径 -t 自定义镜像名:tag .
  1. 通过sudo docker images查看镜像是否生成成功!

这种通过镜像挂载卷的方式使用的十分多,因为我们会经常构建自己的镜像。如果构建镜像时没有挂载卷,要手动挂载就通过 -v 命令进行挂载。

数据卷容器

实现容器的数据卷共享,列如多个mysql同步配置文件。

#命令
子容器 --volumes-from 父容器

#测试
sudo docker run -d -P --name centos01 -v ceshi:/volume01 centos
sudo docker run -d -P --name centos02 --volumes-from centos01 centos

结论:使用数据卷容器可以实现容器之间配置信息的传递与共享!数据卷容器的生命周期可以一直持续到没有容器使用为止!但是一旦你持久化本地,这个时候,本地的数据是不会被删除的!

七、Dockerfile

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

构建步骤:

  1. 编写一个 dockerfile 文件
  2. docker build 构建成一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub、阿里云仓库)

Dockerfile的指令

FROM         #基础镜像,一切从这里构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #添加内容,比如制作tomcat镜像,需要添加tomcat压缩包
WORKDIR #镜像的工作目录。
VOLUME #设置卷,挂载主机目录
EXPOSE #指定暴露对外端口
CMD #指定这个容器启动的时候要运行的命令,与ENTRYPOINT区别(只有最后一个会生效,可被替代)
ENTRYPOINT #指定这个容器启动的时候要运行的命令
ONBUILD #当构建一个被继承 Dockerfile,这个指令被触发。ONBUILD是一个特殊的指令它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
COPY #类似ADD命令,将我们的文件拷贝到镜像中,但不会自动解压。
LABEL #设置镜像的信息
ENV #构建的时候设置环境变量

CMD 和 ENTRYPOINT 的区别:

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

实战测试

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

创建一个自己的centos镜像:

  1. 编写dockerfile文件:

    FROM centos:7       #基于centos7镜像
    MAINTAINER qiancheng<zehong.zhang@qq.com> #作者+邮箱

    #设置环境和工作路径
    ENV MYPATH /usr/local
    WORKDIR $MYPATH

    #为centos7基础镜像添加vim和net-tools
    RUN yum -y install vim
    RUN yum -y install net-tools

    #暴露80端口
    EXPOSE 80

    CMD ["/bin/bash"] #进入bash
  2. 通过dockerfile文件构建镜像:

    #通过dockerfile文件构建镜像
    sudo docker build -f dockerfile文件路径 -t 镜像名:[tag] .
    #查看生成的镜像
    sudo docker images
  3. 查看镜像的构建步骤:

    sudo docker history 镜像id

我们以后开发步骤:需要掌握Dockerfile的编写,我们之后的一切都是使用docker镜像发布运行!

发布自己的镜像

DockerHub

1、地址:https://hub.docker.com/,注册自己的账号!

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

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

#登录DockerHub账号
[lighthouse@VM-16-5-centos local]$ sudo docker login --help

Usage: docker login [OPTIONS] [SERVER]

Log in to a 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

#登录账号
sudo docker login -u #之后提示输入密码

4、登录成功后就可以提交镜像了

sudo docker tag 镜像id DockerHub的用户名/镜像名:tag
sudo docker push DockerHub的用户名/镜像名:tag

5、退出登录

sudo docker logout

八、Docker网络

理解Docker0

#Linux里查看本机ip地址
ip addr
ifconfig

[root@VM-16-5-centos /]# ip addr (或者ifconfig)
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:3f:4f:1c brd ff:ff:ff:ff:ff:ff
inet 10.0.16.5/22 brd 10.0.19.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe3f:4f1c/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:d2:14:5c:09 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:d2ff:fe14:5c09/64 scope link
valid_lft forever preferred_lft forever

#测试是否能ping通docker0
[root@VM-16-5-centos /]# ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.039 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.041 ms
64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=0.042 ms
64 bytes from 172.17.0.1: icmp_seq=4 ttl=64 time=0.036 ms
^C
--- 172.17.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.036/0.039/0.042/0.006 ms

#查看tomcat容器相关信息
[root@VM-16-5-centos /]# docker inspect dcf25e61c138
[
{
"Id": "dcf25e61c13894a0d61870fcc1ad6a4cefcb531b00e9cd5fec5f7d54971d6871",
"Created": "2023-02-13T06:32:31.773322109Z",
"Path": "catalina.sh",
"Args": [
"run"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 19517,
"ExitCode": 0,
"Error": "",
"StartedAt": "2023-02-18T09:58:54.860637695Z",
"FinishedAt": "2023-02-13T08:05:53.824258946Z"
},
"Image": "sha256:b07e16b110887760e9f0a7e2d55c9a64c1d605309bddcd56c95749c91513d451",
"ResolvConfPath": "/var/lib/docker/containers/dcf25e61c13894a0d61870fcc1ad6a4cefcb531b00e9cd5fec5f7d54971d6871/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/dcf25e61c13894a0d61870fcc1ad6a4cefcb531b00e9cd5fec5f7d54971d6871/hostname",
"HostsPath": "/var/lib/docker/containers/dcf25e61c13894a0d61870fcc1ad6a4cefcb531b00e9cd5fec5f7d54971d6871/hosts",
"LogPath": "/var/lib/docker/containers/dcf25e61c13894a0d61870fcc1ad6a4cefcb531b00e9cd5fec5f7d54971d6871/dcf25e61c13894a0d61870fcc1ad6a4cefcb531b00e9cd5fec5f7d54971d6871-json.log",
"Name": "/tomcat01",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {
"8080/tcp": [
{
"HostIp": "",
"HostPort": "3355"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
25,
179
],
"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"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/db58e0d55834b31ce6ef1e6e863fba188007e89f75a5b09597ac6fbcdbea8200-init/diff:/var/lib/docker/overlay2/ccdc5b6b5149fe15f86dbd7b223526471bd34b54adf2712dc516b8dfb47adb25/diff:/var/lib/docker/overlay2/d66bc61537a6126992e4e1de75b93bc9445864fd88e9b076834e72d04a928e70/diff:/var/lib/docker/overlay2/b75495e5bde09db6fd8735152a8c38fea408aa8aff1d1ebd07368e01e10c76fc/diff:/var/lib/docker/overlay2/e5105d9a6b73d9cce4b26ce79a7b7516189896aa6f78c3a0f2b37b571d753da8/diff:/var/lib/docker/overlay2/ce6466763d59debae0c1d1cbce8163318efb5dd385c5e79ef356610ffc9b9b93/diff:/var/lib/docker/overlay2/c22ea8305a7dc3d9536ea9cc8e922192e5b665c09424e2072feb589bce9c5a66/diff:/var/lib/docker/overlay2/63d30096d984ac8e42aafbc726d4907d7e1f8c3e4aeb63fc5e2df77783258548/diff",
"MergedDir": "/var/lib/docker/overlay2/db58e0d55834b31ce6ef1e6e863fba188007e89f75a5b09597ac6fbcdbea8200/merged",
"UpperDir": "/var/lib/docker/overlay2/db58e0d55834b31ce6ef1e6e863fba188007e89f75a5b09597ac6fbcdbea8200/diff",
"WorkDir": "/var/lib/docker/overlay2/db58e0d55834b31ce6ef1e6e863fba188007e89f75a5b09597ac6fbcdbea8200/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "dcf25e61c138",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"8080/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/tomcat/bin:/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"JAVA_HOME=/opt/java/openjdk",
"LANG=en_US.UTF-8",
"LANGUAGE=en_US:en",
"LC_ALL=en_US.UTF-8",
"JAVA_VERSION=jdk-17.0.6+10",
"CATALINA_HOME=/usr/local/tomcat",
"TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib",
"LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib",
"GPG_KEYS=48F8E69F6390C9F25CFEDCD268248959359E722B A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243",
"TOMCAT_MAJOR=9",
"TOMCAT_VERSION=9.0.71",
"TOMCAT_SHA512=6a747e68eff4b68a8defba111103ef6b1606030c180143de0419d015052a5567fca1a86e3d3e058a10246c02b98e89431e9344f80475189573fa0d5c70bfb4cb"
],
"Cmd": [
"catalina.sh",
"run"
],
"Image": "tomcat:9.0",
"Volumes": null,
"WorkingDir": "/usr/local/tomcat",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "22.04"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "f61dadfb0c6776bad36a53022bd2eeaa50ce4146618d34d921268c594658eb88",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"8080/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "3355"
},
{
"HostIp": "::",
"HostPort": "3355"
}
]
},
"SandboxKey": "/var/run/docker/netns/f61dadfb0c67",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "516a547df47472023b78d73c1a9fe9fdf2bfbcac22bd7b75c391cea567ac750f",
"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": "6fd7bb30e2a8bb6aa470d07f4e98f89c9d0bcbb1f48c60b40f53b2774b4da720",
"EndpointID": "516a547df47472023b78d73c1a9fe9fdf2bfbcac22bd7b75c391cea567ac750f",
"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
}
}
}
}
]

#测试是否能ping通正在运行的tomcat容器
[root@VM-16-5-centos /]# 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.055 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.032 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.032 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.043 ms
^C
--- 172.17.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.032/0.040/0.055/0.011 ms

#linux可以ping通docker容器内部,因为我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0,桥接模式,使用veth-pair技术;
#测试docker内容器之间能否ping通,(结论:能通过容器ip来互相ping通)
docker exec -it dcf25e61c138 ping 172.17.0.3

结论:1、Linux系统可以ping通容器内部;2、容器和容器之间可以ping通;3、容器之间是公用一个路由器,也就是docker0;4、容器停止或删除这个ip配置便失效了;

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

#我们发现通过容器名字ping不通
docker exec -it tomcat02 ping tomcat01

#如何解决呢?通过--link
docker exec -it tomcat02 --link tomcat01
docker run -d -P --name tomcat03 --link tomcat01 tomcat:9.0

#测试,发现tomcat02可以ping通tomcat01,tomcat03可以ping通tomcat01,但是这是单向的,反过来就不能ping通了。
docker exec -it tomcat02 ping tomcat01 #成功
docker exec -it tomcat03 ping tomcat01 #成功
docker exec -it tomcat01 ping tomcat02 #失败
docker exec -it tomcat01 ping tomcat03 #失败

#查看docker里的网络
[root@VM-16-5-centos /]# docker network COMMAND

Usage: docker network COMMAND

Manage networks

Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.

#查看所有网卡列表
docker network ls
[root@VM-16-5-centos /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
6fd7bb30e2a8 bridge bridge local
03bbfbb9b664 host host local
1b3e4d05081a none null local

#查看docker0网卡的ip配置信息
docker network inspect networkID
[root@VM-16-5-centos /]# docker network inspect 6fd7bb30e2a8
[
{
"Name": "bridge",
"Id": "6fd7bb30e2a8bb6aa470d07f4e98f89c9d0bcbb1f48c60b40f53b2774b4da720",
"Created": "2023-02-11T16:02:52.832137135+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"dcf25e61c13894a0d61870fcc1ad6a4cefcb531b00e9cd5fec5f7d54971d6871": {
"Name": "tomcat01",
"EndpointID": "516a547df47472023b78d73c1a9fe9fdf2bfbcac22bd7b75c391cea567ac750f",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]

—link只能单向映射,容器之间要互相连通,需要互相—link才行,非常麻烦,所以已经不建议—link了。

这时我们需要自定义网络,不使用docker0的网桥方式。

docker0的问题:它不支持容器名连接访问!

自定义网络

查看所有的docker网络

[root@VM-16-5-centos /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
6fd7bb30e2a8 bridge bridge local
03bbfbb9b664 host host local
1b3e4d05081a none null local

网络模式

  1. bridge(桥接模式):桥接docker(默认)
  2. none:不配置网络
  3. host(主机模式):和宿主机共享网络
  4. container:容器网络连通(用的少!)

我们自定义网络也使用桥接模式!

测试

[root@VM-16-5-centos /]# docker network --help

Usage: docker network COMMAND

Manage networks

Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.

#我们直接启动的命令 --net bridge ,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat:9.0
docker run -d -P --name tomcat01 --net bridge tomcat:9.0 #与上一条命令一样的效果,因为默认就是使用docker0的桥接模式
#docker0特点:默认,容器名不能访问,--link可以打通连接!

#我们可以自定义网络!
#查看创建网络的命令怎样使用
[root@VM-16-5-centos /]# docker network create --help

Usage: docker network create [OPTIONS] NETWORK

Create a network

Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
--config-from string The network from which to copy the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a network segment


#--driver bridge bridge桥接模式
#--subnet 192.168.0.0/16 子网地址
#--gateway 192.168.0.1 网关地址
#创建一个叫mynet的网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
#查看一下创建的网络
docker network ls
docker network inspect mynet

#容器使用自定义的网络
docker run -d -P --name tomcat01 --net mynet tomcat:9.0
docker run -d -P --name tomcat02 --net mynet tomcat:9.0

#现在互相ping,发现不管是ping的 ip 还是 容器名 都是可直接互相访问的。实现了容器互相访问,但修复了docker0的缺点。
docker exec -it tomcat01 ping 192.168.0.3
docker exec -it tomcat02 ping 192.168.0.2
docker exec -it tomcat01 ping tomcat02
docker exec -it tomcat02 ping tomcat01
#我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!

好处:

Redis—不同的集群使用不同的网络,保证集群是安全和健康的

MySQL—不同的集群使用不同的网络,保证集群是安全和健康的

网络连通

问题:docker0与自定义网络之间不能ping通。也就是不同网络之间的容器是不能直接连通的。这时候就需要进行网络连通,容器跟网络之间的打通。

#查看docker网络指令
[root@VM-16-5-centos /]# docker network COMMAND

Usage: docker network COMMAND

Manage networks

Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.

#使用connect指令进行网络连通
#查看connect指令用法
[root@VM-16-5-centos /]# docker network connect --help

Usage: docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network

Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., "172.30.100.104")
--ip6 string IPv6 address (e.g., "2001:db8::33")
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
#connect指令进行网络连通
docker network connect mynet tomcat01
#连通之后通过docker network inspect mynet命令可以看到mynet网络直接将tomcat01添加到了此网络中。
#一个容器两个ip地址
#此时使用ping 命令可以发现tomcat01可以连通mynet网络的容器。

实战:部署Redis集群

#创建一个加redis的网卡
docker network create redis --subnet 172.38.0.0/16

#查看创建的网卡
[root@VM-16-5-centos /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
6fd7bb30e2a8 bridge bridge local
03bbfbb9b664 host host local
1b3e4d05081a none null local
e6ef4403e005 redis bridge local
#查看网卡信息
[root@VM-16-5-centos /]# docker network inspect redis
[
{
"Name": "redis",
"Id": "e6ef4403e005712f4accddf84049956edb37ecf157eeb9993fced0c08b3354a5",
"Created": "2023-02-19T13:16:27.470782749+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.38.0.0/16"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]

#通过脚本创建六个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

#查看是否创建成功,可以看到已经创建了6个Redis配置文件
[root@VM-16-5-centos /]# cd /mydata
[root@VM-16-5-centos mydata]# ls
redis
[root@VM-16-5-centos mydata]# cd redis
[root@VM-16-5-centos redis]# ll
total 24
drwxr-xr-x 3 root root 4096 Feb 19 13:32 node-1
drwxr-xr-x 3 root root 4096 Feb 19 13:32 node-2
drwxr-xr-x 3 root root 4096 Feb 19 13:32 node-3
drwxr-xr-x 3 root root 4096 Feb 19 13:32 node-4
drwxr-xr-x 3 root root 4096 Feb 19 13:32 node-5
drwxr-xr-x 3 root root 4096 Feb 19 13:32 node-6
[root@VM-16-5-centos redis]# cd node-1/conf
[root@VM-16-5-centos conf]# ll
total 4
-rw-r--r-- 1 root root 206 Feb 19 13:32 redis.conf
[root@VM-16-5-centos conf]# cat 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.11
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes

# 启动六个Redis容器
#模板
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:6.0 redis-server /etc/redis/redis.conf

#
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:6.0 redis-server /etc/redis/redis.conf

#
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:6.0 redis-server /etc/redis/redis.conf


#进入redis-1容器
docker exec -it redis-1 /bin/sh
ls #可以看到appendonly.aof持久化配置文件和nodes.conf节点配置文件
#创建一个集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

#演示结果
[root@VM-16-5-centos /]# docker exec -it redis-1 /bin/sh
# ls
appendonly.aof nodes.conf
# redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
>>> 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: a2f87397ea9742d9e6c37406b68229e54e5e2930 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 43ae87e93995d5e2a6daf9c085cb287e386da50e 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: b4f29f904038f8657f160cfaedc6882f147c9b90 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: 34ed53f1ee51b99acbf5df8f948f7c1b5d89d9bf 172.38.0.14:6379
replicates b4f29f904038f8657f160cfaedc6882f147c9b90
S: 95038905f2e00ed28cb6e53760e5b5100bafad2e 172.38.0.15:6379
replicates a2f87397ea9742d9e6c37406b68229e54e5e2930
S: 6abd725c56b4d745e9873b3f584658314c97f568 172.38.0.16:6379
replicates 43ae87e93995d5e2a6daf9c085cb287e386da50e
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: a2f87397ea9742d9e6c37406b68229e54e5e2930 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 43ae87e93995d5e2a6daf9c085cb287e386da50e 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 6abd725c56b4d745e9873b3f584658314c97f568 172.38.0.16:6379
slots: (0 slots) slave
replicates 43ae87e93995d5e2a6daf9c085cb287e386da50e
S: 34ed53f1ee51b99acbf5df8f948f7c1b5d89d9bf 172.38.0.14:6379
slots: (0 slots) slave
replicates b4f29f904038f8657f160cfaedc6882f147c9b90
M: b4f29f904038f8657f160cfaedc6882f147c9b90 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 95038905f2e00ed28cb6e53760e5b5100bafad2e 172.38.0.15:6379
slots: (0 slots) slave
replicates a2f87397ea9742d9e6c37406b68229e54e5e2930
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

#查看集群信息
# redis-cli -c #进入集群
127.0.0.1:6379> cluster info #查看集群信息
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:504
cluster_stats_messages_pong_sent:510
cluster_stats_messages_sent:1014
cluster_stats_messages_ping_received:505
cluster_stats_messages_pong_received:504
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:1014
127.0.0.1:6379> cluster nodes #查看集群节点
43ae87e93995d5e2a6daf9c085cb287e386da50e 172.38.0.12:6379@16379 master - 0 1676788078000 2 connected 5461-10922
6abd725c56b4d745e9873b3f584658314c97f568 172.38.0.16:6379@16379 slave 43ae87e93995d5e2a6daf9c085cb287e386da50e 0 1676788077000 2 connected
34ed53f1ee51b99acbf5df8f948f7c1b5d89d9bf 172.38.0.14:6379@16379 slave b4f29f904038f8657f160cfaedc6882f147c9b90 0 1676788076597 3 connected
b4f29f904038f8657f160cfaedc6882f147c9b90 172.38.0.13:6379@16379 master - 0 1676788078100 3 connected 10923-16383
95038905f2e00ed28cb6e53760e5b5100bafad2e 172.38.0.15:6379@16379 slave a2f87397ea9742d9e6c37406b68229e54e5e2930 0 1676788077699 1 connected
a2f87397ea9742d9e6c37406b68229e54e5e2930 172.38.0.11:6379@16379 myself,master - 0 1676788077000 1 connected 0-5460

#测试
# set a b
#然后将存储的节点容器停止,然后测试
# get a
#可以发现是从副节点取得的值,集群搭建成功

SpringBoot微服务打包Docker镜像

1、构建springboot项目

2、打包应用

3、编写dockerfile

4、构建镜像

5、发布运行

小结

做完上述实验测试需要删除的数据挂载目录有:

/home/mysql————mysql目录及目录下的所有文件

/mydata———————-mydata目录及目录下的所有文件

做完上述实验测试需要删除的docker网络有:redis