Stay Hungry,Stay Foolish!

docker network

引子

https://github.com/fanqingsong/fastapi-react-postgres-keycloak-sso

 

docker compose 配置文件定义了若干service

version: "3"

services:
  nginx:
    image: nginx:1.17
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./logs/nginx:/var/log/nginx
    ports:
      - 80:80
    depends_on:
      - frontend
      - backend

  backend:
    restart: unless-stopped
    build:
      context: backend
      dockerfile: Dockerfile
    env_file:
      - .env
    environment:
      PYTHONPATH: .
      DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_USER}
    volumes:
      - ./logs/backend:/logs
    ports:
      - 8888:8888
    depends_on:
      - postgres
      - keycloak

  frontend:
    build:
      context: frontend
      dockerfile: Dockerfile
    ports:
      - 8000:8000
    environment:
      NODE_ENV: development
      CHOKIDAR_USEPOLLING: "true"

  keycloak:
    image: jboss/keycloak:12.0.4
    environment:
      DB_VENDOR: POSTGRES
      DB_SCHEMA: public
      DB_ADDR: keycloak_postgres
      DB_DATABASE: ${KEYCLOAK_DB_DATABASE}
      DB_USER: ${KEYCLOAK_DB_USER}
      DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD}
      KEYCLOAK_USER: ${KEYCLOAK_ADMIN_USERNAME}
      KEYCLOAK_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
      JDBC_PARAMS: "useSSL=false"
    ports:
      - 8080:8080
    depends_on:
      - keycloak_postgres

  postgres:
    image: postgres
    restart: always
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    ports:
      - 5432:5432
    volumes:
      - postgres_data:/var/lib/postgresql/data

  keycloak_postgres:
    image: postgres
    volumes:
      - keycloak_postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: ${KEYCLOAK_DB_DATABASE}
      POSTGRES_USER: ${KEYCLOAK_DB_USER}
      POSTGRES_PASSWORD: ${KEYCLOAK_DB_PASSWORD}

volumes:
  postgres_data:
  keycloak_postgres_data:

 

nginx反向代理可以直接使用service的名称做代理转发

一般网络访问使用域名或者IP访问网络资源,

什么机制可以支撑使用服务名来访问容器资源?

需要从docker的网络机制说起。

server {
    listen 80;
    listen [::]:80;
    server_name _;


    location / {
        proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_pass http://frontend:8000;

        access_log /var/log/nginx/access_frontend.log;
        error_log /var/log/nginx/error_frontend.log;

        proxy_redirect off;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }


    location /api {
        access_log /var/log/nginx/access_backend.log;
        error_log /var/log/nginx/error_backend.log;
		proxy_pass http://backend:8888/api;
	}
}

 

docker network

https://docs.docker.com/network/

最常使用的三种网络类型

bridge -- 支持单机上的容器互相访问

host -- 支持容器直击使用主机的网络资源, port+IP

overlay -- 支持跨主机的分布式容器互相访问

 

Network drivers

Docker’s networking subsystem is pluggable, using drivers. Several drivers exist by default, and provide core networking functionality:

  • bridge: The default network driver. If you don’t specify a driver, this is the type of network you are creating. Bridge networks are usually used when your applications run in standalone containers that need to communicate. See bridge networks.

  • host: For standalone containers, remove network isolation between the container and the Docker host, and use the host’s networking directly. See use the host network.

  • overlay: Overlay networks connect multiple Docker daemons together and enable swarm services to communicate with each other. You can also use overlay networks to facilitate communication between a swarm service and a standalone container, or between two standalone containers on different Docker daemons. This strategy removes the need to do OS-level routing between these containers. See overlay networks.

 

bridge tutorial

https://docs.docker.com/network/network-tutorial-standalone/

 

host tutorial

https://docs.docker.com/network/network-tutorial-host/

 

overlay tutorial

https://docs.docker.com/network/network-tutorial-overlay/

 

networking practice on docker

https://docs.docker.com/get-started/07_multi_container/

Multi container apps

 

Up to this point, you’ve been working with single container apps. But, now you will add MySQL to the application stack. The following question often arises - “Where will MySQL run? Install it in the same container or run it separately?” In general, each container should do one thing and do it well. The following are a few reasons to run the container separately:

  • There’s a good chance you’d have to scale APIs and front-ends differently than databases.
  • Separate containers let you version and update versions in isolation.
  • While you may use a container for the database locally, you may want to use a managed service for the database in production. You don’t want to ship your database engine with your app then.
  • Running multiple processes will require a process manager (the container only starts one process), which adds complexity to container startup/shutdown.

And there are more reasons. So, like the following diagram, it’s best to run your app in multiple containers.

Todo App connected to MySQL container

 

networking on compose

https://docs.docker.com/compose/networking/

与前节对比, compose就是对docker 网络原语的封装。

如果没有指定网络, 则会创建默认bridge网络,所有的业务的容器工作在此默认网络中

 

For example, suppose your app is in a directory called myapp, and your docker-compose.yml looks like this:

 
services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    ports:
      - "8001:5432"

When you run docker compose up, the following happens:

  1. A network called myapp_default is created.
  2. A container is created using web’s configuration. It joins the network myapp_default under the name web.
  3. A container is created using db’s configuration. It joins the network myapp_default under the name db.

Each container can now look up the hostname web or db and get back the appropriate container’s IP address. For example, web’s application code could connect to the URL postgres://db:5432 and start using the Postgres database.

It is important to note the distinction between HOST_PORT and CONTAINER_PORT. In the above example, for db, the HOST_PORT is 8001 and the container port is 5432 (postgres default). Networked service-to-service communication uses the CONTAINER_PORT. When HOST_PORT is defined, the service is accessible outside the swarm as well.

Within the web container, your connection string to db would look like postgres://db:5432, and from the host machine, the connection string would look like postgres://{DOCKER_IP}:8001 for example postgres://localhost:8001 if your container is running locally.

 

也可以做更细的网络划分

services:
  proxy:
    build: ./proxy
    networks:
      - frontend
  app:
    build: ./app
    networks:
      - frontend
      - backend
  db:
    image: postgres
    networks:
      - backend

networks:
  frontend:
    # Use a custom driver
    driver: custom-driver-1
  backend:
    # Use a custom driver which takes special options
    driver: custom-driver-2
    driver_opts:
      foo: "1"
      bar: "2"

 

posted @ 2023-05-16 21:53  lightsong  阅读(50)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel