目录
1.从github上下载docker-compose二进制文件安装
六、Docker容器监控之 CAdvisor+InfluxDB+Granfana
八、docker-compose 部署 NGINX + PHP+MySQL
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
官网docker | Docker Documentation
Docker容器的一些命令按功能分类大致如下
命令
- #打包
- docker save registry.cn-beijing.aliyuncs.com/kubesphereio/ks-apiserver:v3.3.2 > /root/ks-apiserver-v3.3.2.tar
-
- #加载包
- docker load -i /root/ks-apiserver-v3.3.2.tar
-
- #修改镜像名称
- docker tag registry.cn-beijing.aliyuncs.com/kubesphereio/ks-apiserver:v3.3.2 kubesphere/ks-apiserver:v3.3.2
-
- #删除镜像
- docker rmi registry.cn-beijing.aliyuncs.com/kubesphereio/ks-apiserver:v3.3.2
-
- #查看镜像
- docker images |grep ks-apiserver
-
- #强制删除部署的程序
- docker rm -f es-01
-
- #部署程序
- docker run -d -p 3306:3306 --privileged=true \
- -v /mydata/mysql/log:/var/log/mysql \
- -v /mydata/mysql/data:/var/lib/mysql \
- -v /mydata/mysql/conf:/etc/mysql/conf.d \
- -e MYSQL_ROOT_PASSWORD="123456" \
- --name mysql mysql:5.7
-
- #列出本地所有的镜像
- docker images -a
-
- #只显示镜像ID
- docker images -q
-
- #显示镜像的摘要信息
- docker images --digests
-
- #显示完整的镜像信息
- docker images --no-trunc
-
- # 从Docker Hub上查找tomcat镜像
- docker search tomcat
-
- # 关注度
- STARS:
-
- #从Docker Hub上查找关注度大于300的tomcat镜像
- docker search --filter=stars=300 tomcat
-
- #从Docker Hub上下载tomcat镜像,默认是最新版本。等价于:docker pull tomcat:latest
- docker pull tomcat
-
- # 选择指定版本下载
- 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
- 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
-
- #杀掉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
- 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
Welcome to nginx! - html { color-scheme: light dark; }
- body { width: 35em; margin: 0 auto;
- font-family: Tahoma, Verdana, Arial, sans-serif; }
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
- 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%';
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;
- #下载
- 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
- 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 执行完成后删除容器
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 - 博客园
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详细信息展示
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)
7. 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 ''> 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
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地址之间是可以进行网络交互的,交互模型图如下:
2. 容器互联
在微服务部署的场景下,注册中心是使用服务名来唯一识别微服务的,而我们上线部署的时候微服务对应的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:
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:
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设置容器互连的方式也不再推荐使用了,更多地选择自定义网络。
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
在没有使用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