目录

一、docker离线安装

2.docker常用命令

二、docker制作系统服务

1.contes7快捷方式

2.麒麟v10操作系统 docker快捷方式启动

三、离线安装nginx

四、安装mysql

1.单点mysql

2.主从mysql

五、安装docker-compose

1.从github上下载docker-compose二进制文件安装

2.docker-compose常用命令

六、Docker容器监控之 CAdvisor+InfluxDB+Granfana

七、Docker轻量级可视化工具Portainer

八、docker-compose 部署 NGINX + PHP+MySQL

九、docker网络详解

  1. 自定义网络(推荐使用)
  2. 网络连通

一、docker离线安装
1.安装步骤

1. 下载 Docker 二进制文件(离线安装包)

下载地址:https://download.docker.com/linux/static/stable/x86_64/

2. 通过xftp工具将 docker-18.06.3-ce.tgz 上传到服务器上

3. 解压安装包

tar zxf docker-18.06.3-ce.tgz

4. 将docker 相关命令拷贝到 /usr/bin,方便直接运行命令

sudo cp docker/* /usr/bin/

5. 启动Docker守护程序

sudo dockerd &

6. 验证是否安装成功,执行docker info命令,若正常打印版本信息则安装成功。

docker info
2.docker常用命令

官网docker | Docker Documentation

Docker容器的一些命令按功能分类大致如下

打包

docker save easzlab/k8s-cache:1.16.0 > /root/k8s-cache:1.16.0.tar

加载包

docker load -i /root/k8s-cache:1.16.0.tar

Docker环境信息 info、version
镜像仓库命令 login、logout、pull、push、search
镜像管理 build、images、import、load、rmi、save、tag、commit
容器生命周期管理 create、exec、kill、pause、restart、rm、run、start、stop、unpause
容器运维操作 attach、export、inspect、port、ps、rename、stats、top、wait、cp、diff、update
容器资源管理 volume、network
系统信息日志 events、history、logs
1.events打印容器的实时系统事件
2.history 打印出指定镜像的历史版本信息
3.logs打印容器中进程的运行日志

docker --help #查看docker命令
docker info #docker 详细信息,镜像和容器
docker version #查看docker版本
帮助文档地址:https://docs.docker.com/reference/

docker images # 查看docker镜像;

具体列解释含义:

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

docker images -a #列出本地所有的镜像
docker images -q #只显示镜像ID
docker images --digests #显示镜像的摘要信息
docker images --no-trunc #显示完整的镜像信息

docker search tomcat # 从Docker Hub上查找tomcat镜像
STARS: # 关注度
docker search --filter=stars=300 tomcat #从Docker Hub上查找关注度大于300的tomcat镜像

docker pull tomcat #从Docker Hub上下载tomcat镜像,默认是最新版本。等价于:docker pull tomcat:latest
docker pull tomcat:8 # 选择指定版本下载

单个镜像删除,相当于:docker rmi java:latest

docker rmi java

强制删除(删除正在运行的镜像,注:以后台方式运行的不能被强制删除)

docker rmi -f java

多个镜像删除,不同镜像间以空格间隔

docker rmi -f java tomcat nginx

删除本地全部镜像

docker rmi -f $(docker images -q)

查看正在运行的容器

docker ps

查看所有容 包括停止的容器

docker ps -a

-q参数,只显示container id

docker ps -q

查看容器详细信息

docker inspect demo1

容器启动与停止

新建并启动容器,参数:-i 以交互模式运行容器;-t 为容器重新分配一个伪输入终端;--name 为容器指定一个名称

docker run -i -t --name mycentos 镜像名称/镜像ID

后台启动容器,参数:-d 已守护方式启动容器

docker run -d mycentos

启动止容器

docker start 容器id

重启容器

docker restart 容器id

关闭容器

docker kill 容器id
docker stop 容器id

-t 参数让Docker分配一个伪终端并绑定到容器的标准输入上
-i 参数则让容器的标准输入保持打开。
-c 参数用于给运行的容器分配cpu的shares值
-m 参数用于限制为容器的内存信息,以 B、K、M、G 为单位
-v 参数用于挂载一个volume,可以用多个-v参数同时挂载多个volume
-p 参数用于将容器的端口暴露给宿主机端口 格式:host_port:container_port 或者 host_ip:host_port:container_port
--name 容器名称
--net 容器使用的网络
-d 创建一个后台运行容器

容器进入与退出

使用run方式在创建时进入

docker run -it centos /bin/bash

关闭容器并退出

exit

仅退出容器,不关闭

快捷键:Ctrl + P + Q
快捷键:Ctrl + Shift + P + Q

容器进程

top支持 ps 命令参数,格式:docker top [OPTIONS] CONTAINER [ps OPTIONS]

列出redis容器中运行进程

docker top tomcat

查看所有运行容器的进程信息

for i in docker ps |grep Up|awk '{print $1}';do echo \ &&docker top $i; done

容器日志

查看redis容器日志,默认参数

docker logs tomcat

查看redis容器日志,参数:-f 跟踪日志输出;-t 显示时间戳;--tail 仅列出最新N条容器日志;

docker logs -f -t --tail=20 redis

查看容器redis从2021年08月10日后的最新10条日志。

docker logs --since="2021-08-10" --tail=10 redis

容器内拷贝文件到主机

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

二、docker制作系统服务

1.contes7快捷方式

杀掉docker

pkill -9 docker

在 /usr/lib/systemd/system/ 目录下创建docker.service 文件

cat > /usr/lib/systemd/system/docker.service <<EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
EOF

添加docker仓库

mkdir -p /etc/docker/
cat >/etc/docker/daemon.json<<EOF
{

"registry-mirrors": ["https://gv33cz42.mirror.aliyuncs.com", "https://registry.docker-cn.com", "https://docker.mirrors.ustc.edu.cn", "https://dockerhub.azk8s.cn"],
"exec-opts": ["native.cgroupdriver=systemd"],
"max-concurrent-downloads": 20,
"live-restore": true,
"storage-driver": "overlay2",
"max-concurrent-uploads": 10,
"debug": true,
"log-opts": {
"max-size": "100m",
"max-file": "10"
}

}
EOF

启动

systemctl daemon-reload && systemctl restart docker && systemctl enable docker && systemctl status docker|grep Active

2.麒麟v10操作系统 docker快捷方式启动

杀掉docker

pkill -9 docker

cat > /usr/lib/systemd/system/docker.service <<EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
EOF

启动

systemctl daemon-reload && systemctl restart docker && systemctl enable docker && systemctl status docker|grep Active

三、离线安装nginx

下载高版本nginx

docker pull nginx:1.23.2

将镜像保存为本地tar文件

docker save nginx:1.23.2 > /root/nginx-1.23.2.tar

使用load加载tar文件

docker load -i /root/nginx-1.23.2.tar

之后的文件就放这里面,对 docker 里 Nginx 对应的目录进行映射,就不用改文件进到容器里了

mkdir -p /data/nginx/{conf,conf.d,html,logs}

把 nginx.conf 文件和 conf.d 里的 default.conf 复制到对应文件夹放好,后面就是修改了

cat > /data/nginx/conf/nginx.conf <<EOF
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {

worker_connections  1024;

}
http {

include       /etc/nginx/mime.types;
default_type  application/octet-stream;
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
access_log  /var/log/nginx/access.log  main;
sendfile        on;
#tcp_nopush     on;
keepalive_timeout  65;
#gzip  on;
include /etc/nginx/conf.d/*.conf;

}
EOF

cat > /data/nginx/conf.d/default.conf <<EOF
server {

listen       80;
listen  [::]:80;
server_name  localhost;
#access_log  /var/log/nginx/host.access.log  main;
location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
}
#error_page  404              /404.html;
# redirect server error pages to the static page /50x.html
#
error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root   /usr/share/nginx/html;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
#    root           html;
#    fastcgi_pass   127.0.0.1:9000;
#    fastcgi_index  index.php;
#    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
#    include        fastcgi_params;
#}

}
EOF

cat > /data/nginx/html/index.html <<EOF
<!DOCTYPE html>


Welcome to nginx!


nginx-v01



EOF

部署nginx

docker run --name myNginx -d -p 80:80 \
-v /data/nginx/html:/usr/share/nginx/html \
-v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /data/nginx/conf.d:/etc/nginx/conf.d \
-v /data/nginx/logs:/var/log/nginx \
-v /etc/localtime:/etc/localtime:ro \
nginx:1.23.2
四、安装mysql
1.单点mysql
mkdir -p /data/mysql/{log,data,conf}

cat > /data/mysql/conf/my.cnf <<EOF
[client]
default_character_set=utf8
[mysqld]
socket=/var/run/mysqld/mysqld.sock
collation_server = utf8_general_ci
character_set_server = utf8

设置不区分大小写

lower_case_table_names = 1
EOF

运行

docker run -d -p 3306:3306 --privileged=true \
-v /data/mysql/log:/var/log/mysql \
-v /data/mysql/data:/var/lib/mysql \
-v /data/mysql/conf:/etc/mysql/conf.d \
-v /etc/localtime:/etc/localtime:ro \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql \
mysql:5.7

查看

docker ps |grep mysql

验证

进入 mysql-master

docker exec -it mysql /bin/bash

登入

mysql -uroot -proot

查看字符集

SHOW VARIABLES LIKE 'character%';
2.主从mysql
a.安装 主mysql

新建目录

mkdir -p /mydata/mysql-master/{log,data,conf}
mkdir -p /mydata/mysql-slave/{log,data,conf}

创建主mysql

docker run -d -p 3307:3306 --privileged=true \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql \
-v /etc/localtime:/etc/localtime:ro \
-e MYSQL_ROOT_PASSWORD=root \
--name mysql-master \
mysql:5.7.30

查看

docker ps

主配置

cat > /mydata/mysql-master/conf/my.cnf<<EOF
[mysqld]
socket=/var/run/mysqld/mysqld.sock

同一局域网内注意要唯一

server-id=100

开启二进制日志功能,可以随便取(关键)

log-bin=mysql-bin
EOF

重启

docker restart mysql-master

查看

docker ps

进入 mysql-master

docker exec -it mysql-master /bin/bash

登入

mysql -uroot -proot

创建同步用户,授权

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . TO 'slave'@'%';
flush privileges;

在主节点查看id

show master status;
b.安装 从mysql

新建从服务器容器实例3308

docker run -d -p 3308:3306 --privileged=true \
-v /mydata/mysql-slave/log:/var/log/mysql \
-v /mydata/mysql-slave/data:/var/lib/mysql \
-v /mydata/mysql-slave/conf:/etc/mysql \
-v /etc/localtime:/etc/localtime:ro \
-e MYSQL_ROOT_PASSWORD=root \
--name mysql-slave \
mysql:5.7.30

查看

docker ps

从配置

cat > /mydata/mysql-slave/conf/my.cnf<<EOF
[mysqld]
socket=/var/run/mysqld/mysqld.sock

设置server_id,注意要唯一

server-id=101

开启二进制日志功能,以备Slave作为其它Slave的Master时使用

log-bin=mysql-slave-bin

relay_log配置中继日志

relay_log=edu-mysql-relay-bin
EOF

重启

docker restart mysql-slave

docker ps

从mysql

docker exec -it mysql-slave /bin/bash

登入mysql

mysql -uroot -proot

在从数据库中配置主从复制 ip填写宿主机ip

change master to master_host='192.168.1.31', master_user='slave', master_password='123456', master_port=3307, master_log_file='mysql-bin.000004', master_log_pos=769, master_connect_retry=30;

在从库 开启主从同步

start slave;

在从库查看状态

show slave status \G;
五、安装docker-compose
1.从github上下载docker-compose二进制文件安装

下载

sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-uname -s-uname -m -o /usr/local/bin/docker-compose

下面无法下载,可以去百度网盘

链接:https://pan.baidu.com/s/1qE06PjPs9547dIhsMcp9iw?pwd=u6jr
提取码:u6jr

添加可执行权限

sudo chmod +x /usr/local/bin/docker-compose

测试安装结果

docker-compose --version
2.docker-compose常用命令
docker-compose 命令 --help 获得一个命令的帮助
docker-compose up -d nginx 构建启动nignx容器
docker-compose exec nginx bash 登录到nginx容器中
docker-compose down 此命令将会停止 up 命令所启动的容器,并移除网络
docker-compose ps 列出项目中目前的所有容器
docker-compose restart nginx 重新启动nginx容器
docker-compose build nginx 构建镜像
docker-compose build --no-cache nginx 不带缓存的构建
docker-compose top 查看各个服务容器内运行的进程
docker-compose logs -f nginx 查看nginx的实时日志
docker-compose images 列出 Compose 文件包含的镜像
docker-compose config 验证文件配置,当配置正确时,不输出任何内容,当文件配置错误,输出错误信息。
docker-compose events --json nginx 以json的形式输出nginx的docker日志
docker-compose pause nginx 暂停nignx容器
docker-compose unpause nginx 恢复ningx容器
docker-compose rm nginx 删除容器(删除前必须关闭容器,执行stop)
docker-compose stop nginx 停止nignx容器
docker-compose start nginx 启动nignx容器
docker-compose restart nginx 重启项目中的nignx容器
docker-compose run --no-deps --rm php-fpm php -v 在php-fpm中不启动关联容器,并容器执行php -v 执行完成后删除容器
六、Docker容器监控之 CAdvisor+InfluxDB+Granfana
1.新建目录

mkdir /mydocker/cig

2.新建3件套组合的 docker-compose.yml

vim /mydocker/cig/docker-compose.yml

version: '3.1'

volumes:
grafana_data: {}

services:
influxdb:
image: tutum/influxdb:0.9
restart: always
environment:

- PRE_CREATE_DB=cadvisor

ports:

- "8083:8083"
- "8086:8086"

volumes:

- ./data/influxdb:/data

cadvisor:
image: google/cadvisor
links:

- influxdb:influxsrv

command: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086
restart: always
ports:

- "8080:8080"

volumes:

- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro

grafana:
user: "104"
image: grafana/grafana
user: "104"
restart: always
links:

- influxdb:influxsrv

ports:

- "3000:3000"

volumes:

- grafana_data:/var/lib/grafana

environment:

- HTTP_USER=admin
- HTTP_PASS=admin
- INFLUXDB_HOST=influxsrv
- INFLUXDB_PORT=8086
- INFLUXDB_NAME=cadvisor
- INFLUXDB_USER=root
- INFLUXDB_PASS=root

3.启动

docker-compose up -d
详细配置参考

Docker学习22 - Docker容器监控之 CAdvisor+InfluxDB+Granfana - suphowe - 博客园

七、Docker轻量级可视化工具Portainer
1.部署

docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
2.选择local选项卡后本地docker详细信息展示

八、docker-compose 部署 NGINX + PHP+MySQL
1.创建数据文件夹

mkdir /data
cd /data
mkdir -p mysql/conf.d
mkdir -p mysql/data
mkdir -p nginx/conf.d
mkdir -p nginx/log
mkdir -p php/conf.d
mkdir www

2.nginx配置文件

sudo docker run --name nginx -d nginx

复制出来配置文件:

sudo docker cp nginx:/etc/nginx/conf.d/default.conf /data/nginx/conf.d/
3.创建php的Dockerfile:

cat /data/php/Dockerfile

FROM php:7.4-fpm
RUN apt-get update && apt-get install -y \

    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng-dev \
    libvpx-dev libwebp-dev \
&& docker-php-ext-configure gd  --with-webp=/usr/include/webp --with-jpeg=/usr/include --with-freetype=/usr/include/freetype2 \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-install mysqli \
&& docker-php-ext-install pdo_mysql 

打包镜像

docker build -t myphp:1.0 ./
4.复制出php的配置文件

sudo docker run --name php -d myphp:1.0
sudo docker cp php:/usr/local/etc/php/php.ini-production php/conf.d/php.ini
5.修改nginx/conf.d/default.conf

cat /data/nginx/conf.d/default.conf

server {

listen       80;
listen  [::]:80;
server_name  localhost;

#access_log  /var/log/nginx/host.access.log  main;

location / {
    root   /usr/share/nginx/html;
    index  index.php index.html index.htm;
}

#error_page  404              /404.html;

# redirect server error pages to the static page /50x.html
#
error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root   /usr/share/nginx/html;
}



# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000

location ~ \.php$ {
   root           /usr/share/nginx/html;
   fastcgi_pass   compose-php:9000;
   fastcgi_index  index.php;
   fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   fastcgi_param  SCRIPT_NAME      $fastcgi_script_name;
   include        fastcgi_params;
}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
#    deny  all;
#}

}
6.复制数据库的配置文件

docker run --name mysql -d mysql:5.7
docker cp mysql:/etc/mysql/conf.d /data/mysql/
6.1删除之前部署的进程

docker kill $(docker ps -a |grep mysql)
docker kill $(docker ps -a |grep php)
docker kill $(docker ps -a |grep nginx)
docker rm $(docker ps -a |grep mysql)
docker rm $(docker ps -a |grep php)
docker rm $(docker ps -a |grep nginx)

  1. cat /data/docker-compose.yaml

version: "3"
services:
nginx:

image: nginx:latest
container_name: "compose-nginx"
restart: always
ports:
  - "80:80"
  - "443:443"
environment:
  - TZ=Asia/Shanghai
depends_on:
  - "php"
volumes:
  - "/data/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf"
  - "/data/nginx/log:/var/log/nginx"
  - "/data/www:/usr/share/nginx/html"
networks:
  - net-app

php:

image: myphp:1.0
container_name: "compose-php"
restart: always
environment:
  - TZ=Asia/Shanghai
volumes:
  - "/data/www:/usr/share/nginx/html"
  - "/data/php/conf.d/php.ini:/usr/local/etc/php/php.ini"
networks:
  - net-app

mysql:

image: mysql:5.7
container_name: "compose-mysql"
environment:
  MYSQL_ROOT_PASSWORD: root
  MYSQL_USER: admin
  MYSQL_PASSWORD: admin
volumes:
  - ./mysql/data:/var/lib/mysql
  - ./mysql/conf.d:/etc/mysql/conf.d
networks:
  - net-app

networks:

net-app:

8.启动

cd /data/

启动

docker-compose up -d

停止

docker-compose stop

卸载

docker-compose down

9.浏览器访问

echo '<?php phpinfo();?>'> www/info.php

curl http://localhost/info.php
或浏览器打开访问

10.连接数据库:

sudo docker run -it --network data_net-app mysql:5.7 mysql -uroot -proot -hcompose-mysql
博客参考:https://blog.csdn.net/shelutai/article/details/125082697

九、Docker网络详解

  1. Docker网络模式

Docker默认提供了3种网络模式,生成容器时不指定网络模式下默认使用bridge桥接模式。

[root@haha docker_web]# docker network ls
NETWORK ID NAME DRIVER SCOPE
aa8a26ae1484 bridge bridge local
62cd016ed66a host host local
fc650e2a675e none null local
1.1 host模式

如果启动容器时使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

Namespace的简要说明:
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的NetworkNamespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。

1.2 container模式

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信
1.3 none模式

使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过–network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
1.4 bridge模式

bridge模式是docker的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。bridge模式如下图所示:

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器都会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。

从上图中我们可以看到,可以看到容器内部和Linux主机都会创建一个新的网卡,而这两个网卡都是成对的。使用的技术就是evth-pair。evth-pair 就是一对的虚拟设备接口,他们是成对出现的,一段连着协议,一段彼此相连。evth-pair充当一个桥梁,连接各种虚拟网络设备。

Docker容器完成bridge网络配置的过程如下:

  1. 在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
  2. Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以vethb22db1b4这样类似的名字命名,并将这个网络设备加入到docker0网桥中。
  3. 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。

   宿主机和Docker容器之间是可以进行网络连接的,同样的,Docker容器和容器之间也可以直接进行网络连接

[root@haha docker_web]# docker exec -it a52bd646da1f 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.193 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.134 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.132 ms

[root@haha docker_web]# docker exec -it 386ffc29485d ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.146 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.137 ms
容器1和容器2,都使用公用的路由器docker0。所有的容器在不指定网络情况下,都是由docker0路由的,Docker会给我们容器默认分配一个随机的可用IP地址,这些IP地址之间是可以进行网络交互的,交互模型图如下:

  1. 容器互联

在微服务部署的场景下,注册中心是使用服务名来唯一识别微服务的,而我们上线部署的时候微服务对应的IP地址可能会改动,所以我们需要使用容器名来配置容器间的网络连接。使–link可以完成这个功能。

首先不设置–link的情况下,是无法通过容器名来进行连接的。centos02容器是可以直接ping通centos01的容器ip,但是无法ping通centos01的容器name:

[root@haha ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c742968a290a 5d0da3dc9764 "/bin/bash" 9 seconds ago Up 8 seconds centos02
581740709b5e 5d0da3dc9764 "/bin/bash" 30 seconds ago Up 28 seconds centos01
[root@haha ~]#
[root@haha ~]# docker exec -it centos01 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

34: eth0@if35: <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

[root@haha ~]#
[root@haha ~]# docker exec -it centos02 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.102 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.135 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.137 ms
[root@haha ~]#
[root@haha ~]# docker exec -it centos02 ping centos01
ping: centos01: Name or service not known
添加参数 –link,可以通过容器name进行连接。centos03容器link到centos01,所以centos03可以直接通过ping centos01的容器名去ping通,但是反过来centos01去ping centos03的容器名是ping不通的。

[root@haha ~]# docker run -d -P -it --name centos03 --link centos01 5d0da3dc9764
a66f059fe26da45e5c59af03a2c33f429452a2dcf884ad5826fa0e3985ab3862
[root@haha ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a66f059fe26d 5d0da3dc9764 "/bin/bash" 7 seconds ago Up 5 seconds centos03
c742968a290a 5d0da3dc9764 "/bin/bash" 11 minutes ago Up 11 minutes centos02
581740709b5e 5d0da3dc9764 "/bin/bash" 11 minutes ago Up 11 minutes centos01
[root@haha ~]#
[root@haha ~]# docker exec -it centos03 ping centos01
PING centos01 (172.17.0.2) 56(84) bytes of data.
64 bytes from centos01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.111 ms
64 bytes from centos01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.074 ms
64 bytes from centos01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.076 ms
^C
[root@haha ~]#
[root@haha ~]# docker exec -it centos01 ping centos03
ping: centos03: Name or service not known
–link的原理就是在centos03容器的hosts文件中添加了要去link的centos01容器的容器名和ip地址映射。但是因为docker0不支持容器名访问,所以–link设置容器互连的方式也不再推荐使用了,更多地选择自定义网络。

  1. 自定义网络(推荐使用)
    docker network 命令及经常使用到的命令:

docker network --help

如何自定义一个网络?

docker network create --help

具体使用:

[root@haha ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
ed1c176a06d49da31969e229138ef5988a5fd9d2b2f2d2fc5ec1078be99a3d39
[root@haha ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
aa8a26ae1484 bridge bridge local
62cd016ed66a host host local
ed1c176a06d4 mynet bridge local
fc650e2a675e none null local
查看新创键的mynet详细信息:

使用自定义网络创建容器后,相同网络name下的容器,不管是通过容器IP还是容器name,都可以进行网络通信

创建两个使用相同自定义网络的容器

[root@haha ~]# docker run -d -P --name centos-net-01 --net mynet -it 5d0da3dc9764 /bin/bash
[root@haha ~]# docker run -d -P --name centos-net-02 --net mynet -it 5d0da3dc9764 /bin/bash
[root@haha ~]#
[root@haha ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2511566dd5f3 5d0da3dc9764 "/bin/bash" 4 seconds ago Up 3 seconds centos-net-02
924e92107f64 5d0da3dc9764 "/bin/bash" 23 seconds ago Up 21 seconds centos-net-01
a66f059fe26d 5d0da3dc9764 "/bin/bash" 43 minutes ago Up 43 minutes centos03
c742968a290a 5d0da3dc9764 "/bin/bash" 54 minutes ago Up 54 minutes centos02
581740709b5e 5d0da3dc9764 "/bin/bash" 55 minutes ago Up 55 minutes centos01

测试容器互连

[root@haha ~]# docker exec -it centos-net-01 ping centos-net-02
PING centos-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.689 ms
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.078 ms
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.097 ms
^C
[root@haha ~]# docker exec -it centos-net-01 ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.091 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.048 ms
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.094 ms
^C

  1. 网络连通
    在没有使用connect命令的情况下,不同网络间的容器是无法进行网络连接的。

不同Docker网络之间的容器想要连接的话,需要把该容器注册到另一个容器所在的网络上,使用docker connect命令。

docker network connect mynet centos01
connect设置成功后,我们可以看到新注册进来的容器信息:

接下来进行容器双向连接测试:

centos-net-01 ping centos01,连接成功

[root@haha ~]# docker exec -it centos-net-01 ping centos01
PING centos01 (192.168.0.4) 56(84) bytes of data.
64 bytes from centos01.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.183 ms
64 bytes from centos01.mynet (192.168.0.4): icmp_seq=2 ttl=64 time=0.139 ms
64 bytes from centos01.mynet (192.168.0.4): icmp_seq=3 ttl=64 time=0.136 ms
^C

centos01 ping centos-net-01,连接成功

[root@haha ~]# docker exec -it centos01 ping centos-net-01
PING centos-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.066 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.135 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.141 ms
^C
[root@haha ~]# 未连接到mynet的容器还是无法访问
[root@haha ~]# docker exec -it centos-net-01 ping centos02
ping: centos02: Name or service not known
感谢狂神B站提供的教程:https://www.bilibili.com/video/BV1og4y1q7M4

感谢高过蓝天Docker网络详解_高过蓝天的云的博客-CSDN博客
————————————————
版权声明:本文为CSDN博主「大虾别跑」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35583325/article/details/127849408

最后修改:2023 年 12 月 30 日
如果觉得我的文章对你有用,请随意赞赏