docker网络详解:external_links (附带docker常用命令)

​ docker容器本质是多个容器卷的叠加,启动后的容器卷处于容器卷最顶层,不做特殊配置和处理的话,不同的容器之间是相互隔离的,包括文件存储和网络的隔离,其中文件存储可以通过挂载volumes来实现文件同步。

​ 每个容器创建时,会默认创建一对虚拟网卡,用于来链接容器和宿主机,也就是veth-pair。

​ 我们现在创建一个容器,然后分别查看宿主机和容器的ip地址。

#容器内部
[root@74caeaf4fddc /]# 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
259: eth0@if260:  mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:12:00:06 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.6/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

​ 如上, 容器内部查看ip,有一个259的网卡,后面的eth0@if260是指的链接宿主机260虚拟网卡,通过创建一对虚拟网卡,来链接宿主机

#宿主机
[root@VM-0-3-centos ~]# ip addr
....
3: docker0:  mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ca:eb:ae:cd brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:caff:feeb:aecd/64 scope link
       valid_lft forever preferred_lft forever
260: vethd02d55c@if259:  mtu 1500 qdisc noqueue master docker0 state UP g                                 roup default
    link/ether ca:ff:68:26:34:e4 brd ff:ff:ff:ff:ff:ff link-netnsid 4
    inet6 fe80::c8ff:68ff:fe26:34e4/64 scope link
       valid_lft forever preferred_lft forever
....

​ 我们直接创建容器相当于在容器后面默认加上网络配置参数,默认加入docker0网关,可以看到docker0网关是172.18.0.1,新创建的容器ip是172.18.0.6,两者是同一个ip段,网络互通。

docker run -d --net bridge centos

​ 所以容器间的互通,可以直接通过ip访问,但是在我们实际使用过程中,容器启动顺序不一样,会导致ip有变化,所以我们可以自己建一个bridge网络桥,命名mynet,然后手动让新建的容器都加入这个网络桥 --net mynet,容器之间就可以通过容器名相互ping通。

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

​ 让所有容器加入自定义的网络bridge,然后我们的服务配置就可以直接使用容器名来映射ip,例如mysql host直接使用db, redis host使用redis来代替。

spring:
  datasource:
    url: jdbc:mysql://db:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: test
    password: 123456
  redis:
    host: redis # Redis服务器地址
    database: 0 # Redis数据库索引(默认为0)
    port: 6379 # Redis服务器连接端口
    password: #不设置密码

​ 但是到了docker-compose里面,这个创建网络的动作会被再次简化,如果没有特殊声明每个服务所在的网络,那么在yaml服务启动时,会默认创建一个bridge,并且将同一个yml中所有服务都被链接至该bridge。同一个yaml文件中服务可以相互通过服务名ping通。

#docker-compose启动项目,默认创建一个app_default的network
[root@VM-0-3-centos app]# docker-compose -f docker-compose-env.yml up --build
Creating network "app_default" with the default driver
Creating redis_isr ... done
Creating db123     ... done
Attaching to redis_isr, db123
....

​ 但是我们实际生产中,很多时候是多个docker-compose.yml文件分开启动,所以需要通过external-links来链接外部服务,前提是外部服务已经加入一个bridge网络,而external–links本质还是表示将当前yml文件的网络链接到外部服务的bridge网络中,值得一提的是,如果是docker默认的网络,是无法进行external–links。

#先在上方进行redis和mysql的启动,并创建app_default网络,然后再启动2个服务,其中使用external--links到redis和db123;
#会发现后面启动的2个服务并未创建网络桥
[root@VM-0-3-centos app]# docker-compose -f docker-compose-app.yml up --build
Successfully built 06fba95fdb2c
Successfully tagged isr/isr-user-test:1.0
Building isr-discoveryserver
....

​ 我们再查看容器网络app_default,其中有4个容器,正是我们刚刚启动的4个服务。完美链接。

 "Name": "app_default",
        "Id": "7e02c370f248ad744859c94bc6f0b9c550ec492e74937a792636f60e8bd71e8b",
        "Created": "2021-09-12T21:51:24.373375115+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.29.0.0/16",
                    "Gateway": "172.29.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2851dede459e270088ad95d858499b2477bc53f0ecf31e0c36f72a27f6b6e6b9": {
                "Name": "db123",
                "EndpointID": "9762e796ceaf702613273fcf935524e4bb6e9ebed79d0d549036552316913626",
                "MacAddress": "02:42:ac:1d:00:02",
                "IPv4Address": "172.29.0.2/16",
                "IPv6Address": ""
            },
            "54f8d63cc8eeb5d97c6b0e3ac2f257116c99157bb3613850f9bb37c5dbea5117": {
                "Name": "isr-user-test",
                "EndpointID": "16e7794b770a7fab2293332177f6fd754062851a1478bac2cb96ab2e6f4d5069",
                "MacAddress": "02:42:ac:1d:00:05",
                "IPv4Address": "172.29.0.5/16",
                "IPv6Address": ""
            },
            "7121b20ace1bb31833e753e2a4154e198eb062b038e245bbb647a8b2594ef93d": {
                "Name": "redis_isr",
                "EndpointID": "a29027628abe1a694e922bab38d95cc1f03709828302445a0e8dee24e771e780",
                "MacAddress": "02:42:ac:1d:00:03",
                "IPv4Address": "172.29.0.3/16",
                "IPv6Address": ""
            },
            "bb1b901b9cd2e5e074e0c548134a04311eadd67373da7cb2f4761a8040d74c7f": {
                "Name": "isr-discoveryserver-test",
                "EndpointID": "3115410d322ed1bc8745d5b2725ab21ab2172bb2be2ac922c12ea71098c5b309",
                "MacAddress": "02:42:ac:1d:00:04",
                "IPv4Address": "172.29.0.4/16",
                "IPv6Address": ""
            }
        },

docker常用命令

  1. 镜像操作

    docker pull mysql:5.0	#拉取指定版本镜像,版本不写默认最新版	
    docker images	#查询镜像,-a 包含中间层镜像,-q只查看id
    docker rmi -f mysql	#移除镜像 -f 表示强制
    docker rmi -f $(docker images -aq)	#移除所有镜像
    
  2. 容器基本操作

    docker run -it(-d) -p(-P) 3307:3306 --name db -v /usr/app/data:/var/lib/data mysql
    #run从镜像创建容器,如果不存在则自动拉取
    #-it 以交互形式打开容器,并分配一个终端,-d 以守护方式后台运行容器
    #-p 将容器内部的3306端口映射到外部服务器的3307端口,-P 将3306映射到外部随机端口
    #--name 给容器命名
    #-v 容器卷挂载,将容器中的/var/lib/data路径挂载到服务器的/usr/app/data路径,无论哪个文件夹对其中文件进行操作,都会同步到另一个文件夹中
    docker exec -it mysql /bin/bash(sh)	#以交互新终端进入容器
    docker rm -f mysql	#删除容器
    docker rm -f $(docker ps -aq)	#删除全部容器
    docker start/stop mysql
    
  3. 容器信息查看

    docker inspect redis
    #查看容器相信信息,包括mount挂载状态,networks网络状态,
    docker top redis	#查看容器状态
    for i in  `docker ps |grep Up|awk '{print $1}'`;do echo \ &&docker top $i; done	#查看所有运行容器的进程
    
    dockers logs mysql #查看启动日志
    

dockerfile

使用dockerfile生成镜像,关键字全部大写。

FROM 基于哪个镜像继续叠加镜像层

ADD 将当前路径中文件复制到容器中,要注意文件路径

RUN 运行容器中命令

EXPOSE 将端口暴露给其他容器,但是外部无法访问

FROM java:8
ADD isr-user-1.0-SNAPSHOT.jar /isr-user-docker.jar
RUN bash -c 'touch /isr-user-docker.jar'
EXPOSE 10119
ENTRYPOINT ["java", "-jar","-Xms512m", "-Xmx512m", "-Xmn256m", "/isr-user-docker.jar", "--spring.profiles.active=test"]
MAINTAINER wuhong

-t tag, 尾端的.表示dockerfile文件,文件名默认Dockerfile

docker build -t 自定义镜像名:[tag] .

docker-compose

external_links链接外部服务,在当前服务中,可以直接使用该外部服务名表示host

ports,expose:ports是将容器内的端口映射到宿主机端口,由宿主机端口对外提供容器端口服务,expose只是将暴露容器的端口给到其他容器,但是并没有暴露给外部访问

docker-compose -p test -f dockers-compose.yml up --build
#-p表示项目名,默认当前文件夹名,如果当前文件夹有多个yml文件,建议指定项目名
#-f表示yml文件
version: '3.3'	#版本号和docker engine版本对应
services:	
  isr-user:	#服务名
    build: ./isr-user	#指定dockerfile路径
    image: isr/isr-user-test:1.0	#
    container_name: isr-user-test
    ports:
      - 10119:10119
    volumes:
      - /mydata/app/isr-user/logs:/mnt/isr/log
      - /etc/localtime:/etc/localtime
    environment:
      - 'TZ="Asia/Shanghai"'
    external_links:
      - db
      - redis
  isr-discoveryserver:
    build: ./isr-discoveryserver
    image: isr/isr-discoveryserver-test:1.0
    container_name: isr-discoveryserver-test
    ports:
      - 9000:9000
    volumes:
      - /mydata/app/isr-user/logs:/mnt/isr/log
      - /etc/localtime:/etc/localtime
    environment:
      - 'TZ="Asia/Shanghai"'
version: '3.3'
services:
  mysql:
    image: mysql:8.0
    container_name: mysql_test
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root #设置root帐号密码
    ports:
      - 3306:3306
    volumes:
      - /mydata/mysql/data/db:/var/lib/mysql #数据文件挂载
      - /mydata/mysql/data/conf:/etc/mysql/conf.d #配置文件挂载
      - /mydata/mysql/log:/var/log/mysql #日志文件挂载
  redis:
    image: redis:5.0
    container_name: redis_test
    restart: unless-stopped
    ports:
      - 6379:6379
    volumes:
      - /mydata/redis/data:/data #数据文件挂载
      - /mydata/redis/conf:/etc/redis/redis.conf #配置文件挂载

你可能感兴趣的:(docker,docker,运维,docker-compose)