# Docker 简介

  • Docker 官方文档:https://docs.docker.com/
  • Docker 架构遵循 C/S 架构,分为客户端、Docker 主机、Docker 镜像仓库三部分

Docker_Architecture

  • 安装 (opens new window)

    sudo yum install -y yum-utils
    sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
    sudo yum install -y docker-ce docker-ce-cli containerd.io
    sudo systemctl enable docker
    sudo systemctl start docker
    
    1
    2
    3
    4
    5
    6
    # Install Docker&Docker Compose
    curl -sSL https://get.docker.com/ | sh
    sudo pip install docker-compose
    
    1
    2
    3
  • Docker 镜像地址配置

    • 网易镜像地址:http://hub-mirror.c.163.com
    • https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://wi2behga.mirror.aliyuncs.com"],
      "log-level": "debug"
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

# Docker 常用命令 (opens new window)

  • docker version:显示 Docker 版本信息
  • docker info:显示 Docker 系统信息,包括镜像和容器数
  • docker system df:Show docker disk usage
  • docker system events:Get real time events from the server
  • docker system info:Display system-wide information
  • docker system prune:Remove unused data

Docker常用命令

# 镜像相关

  • docker images:列出本地镜像
  • docker search <镜像>:搜索镜像
  • docker pull <镜像>:获取镜像
  • docker rmi <镜像>:删除本地镜像

# 容器相关

# 容器生命周期管理

  • docker run [OPTIONS] IMAGE [COMMAND] [ARG...],常用选项 (opens new window)
    --rm:在容器退出时移除容器(--rm 和 -d 不能共用)
    -i: 以交互模式运行容器,通常与 -t 同时使用
    -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用
    -d:后台运行容器
    -e:设置环境变量
    --expose / -p 宿主端口:容器端口 --name:指定容器名称
    --link:链接不同容器
    -v 宿主目录:容器目录:挂载磁盘卷
    --network=my-net:将容器连接到网络(Service discovery is unavailable on the default bridge network. Containers can communicate via their IP addresses by default. To communicate by name, they must be linked.)
    --add-host=docker:93.184.216.34:将其它主机动态添加到容器的 /etc/hosts 文件中

  • docker start/stop/restart <容器名>

  • docker rm <容器名>:-v 删除与容器关联的卷,-f 通过 SIGKILL 信号强制删除一个运行中的容器

  • docker exec [OPTIONS] CONTAINER COMMAND [ARG...]:在运行的容器中执行命令,如 docker exec -it mongo bash,退出容器 exit

  • docker container top <容器名>

# 容器内访问宿主机

  • Docker v20.10 加入了一个 feature,在容器中可以通过 host.docker.internal 来访问宿主机。Use your internal IP address or connect to the special DNS name host.docker.internal which will resolve to the internal IP address used by the host.

  • 在启动 docker 时,增加参数:--add-host=host.docker.internal:host-gateway

  • 在容器内通过 host.docker.internal:PORT 来访问宿主机上提供的服务

  • 如果使用的是 Docker Compose,在模板文件对应的 container 中增加声明:

    extra_hosts:
      - "host.docker.internal:host-gateway"
    
    1
    2

# 容器操作

  • docker ps:列出容器,-a 显示所有的容器(包括未运行的)
  • docker top <容器名>:查看容器中运行的进程信息
  • docker inspect <容器名>:获取容器/镜像的元数据
  • docker update --restart=always <容器名>:更新一个或多个容器的配置,重启策略有 no、on-failure[:max-retries]、unless-stopped、always
  • docker logs -tf --tail=500 --since="2016-07-01" <容器名>:查看容器日志,-f 跟踪日志输出,-t 显示时间戳
  • docker network connect NETWORK CONTAINER:将正在运行的容器添加到网络

# 安装常用服务

# Portainer 容器管理
docker pull portainer/portainer && docker run -d --name portainer --restart always -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v ~/docker-data/portainer/data:/data -v ~/docker-data/portainer/cn:/public portainer/portainer

# dozzle 容器日志查看
# ro 表示将挂载的权限设为 read-only
docker run --name dozzle -d --volume=/var/run/docker.sock:/var/run/docker.sock:ro -p 38888:8080 amir20/dozzle:latest --username=xxx --password=xxx --no-analytics=true

# ReverseProxy
docker run -d --name jrebel --restart always -p 38888:8888 qierkang/golang-reverseproxy

# MySQL
docker run -d --name mysql5.7 --restart always -p 3306:3306 -v ~/docker-data/mysql/lib:/var/lib/mysql -v ~/docker-data/mysql/etc:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=admin mysql:5.7

# MongoDB
docker run -d --name mongo -p 27017:27017 -v ~/docker-data/mongo:/data/db -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=admin mongo

# Redis
mkdir -p ~/docker-data/redis/data && wget -O ~/docker-data/redis/redis.conf https://raw.githubusercontent.com/redis/redis/6.2/redis.conf
# 修改配置(redis.conf):bind 0.0.0.0、requirepass admin
docker run -d --name redis-server -p 6379:6379 -v ~/docker-data/redis/redis.conf:/usr/local/etc/redis/redis.conf -v ~/docker-data/redis/data:/data redis:6.2
# connecting via redis-cli
docker run -it --network container:redis-server --rm redis:6.2 redis-cli

# ZooKeeper
docker run -d --name zookeeper -p 2181:2181 zookeeper:latest

# Consul
docker run -d --name consul -p 8500:8500 -p 8600:8600/udp consul

# Nacos
mkdir -p ~/docker-data/nacos/init.d
docker run -d --name nacos --cap-add=SYS_PTRACE --memory=512M -p 8848:8848 -e MODE=standalone -e JVM_XMS=128m -e JVM_XMX=512m -e JVM_XMN=256m -v ~/docker-data/nacos/init.d:/home/nacos/init.d nacos/nacos-server

# RabbitMQ
mkdir -p ~/docker-data/rabbitmq/plugins & wget -O ~/docker-data/rabbitmq/plugins/rabbitmq_delayed_message_exchange.ez https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/3.9.0/rabbitmq_delayed_message_exchange-3.9.0.ez
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=admin -v ~/docker-data/rabbitmq/plugins:/plugins rabbitmq:management
# 添加新用户并设置权限
# 安装插件

# Zipkin
docker run -d --name zipkin -p 9411:9411 openzipkin/zipkin
docker run -d --name rabbit-zipkin -p 9411:9411--link rabbitmq -e RABBIT_ADDRESSES=rabbitmq:5672 -e RABBIT_USER=root -e RABBIT_PASSWORD=admin openzipkin/zipkin

# Kafdrop
docker run -d --name kafdrop -p 9000:9000 -e KAFKA_BROKERCONNECT=192.168.192.1:9092 -e JVM_OPTS="-Xms32M -Xmx64M" -e SERVER_SERVLET_CONTEXTPATH="/" obsidiandynamics/kafdrop:latest

# Elasticsearch
docker network create elastic
mkdir -p ~/docker-data/elasticsearch/data & chmod 777 ~/docker-data/elasticsearch/data
mkdir -p ~/docker-data/elasticsearch/plugins
touch ~/docker-data/elasticsearch/config/elasticsearch.yml
# 内容示例:
# xpack.security.enabled: false
# discovery.type: single-node
# network.host: 0.0.0.0
# http.cors.allow-origin: "*"
# http.cors.enabled: true
# http.cors.allow-headers : X-Requested-With,X-Auth-Token,Content-Type,Content-Length,Authorization
# http.cors.allow-credentials: true
docker run -d --name elasticsearch --restart=always --network elastic -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -v ~/docker-data/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v ~/docker-data/elasticsearch/plugins:/usr/share/elasticsearch/plugins -v ~/docker-data/elasticsearch/data:/usr/share/elasticsearch/data elasticsearch:7.14.2

# Kibana
docker run -d --name kibana --network elastic -p 5601:5601 -e "I18N_LOCALE=zh-CN" kibana:7.14.2

# Cerebro
docker run -d --name cerebro --network elastic -p 9000:9000 lmenezes/cerebro

# MinIO 高性能对象存储
# https://github.com/minio/minio
mkdir -p ~/docker-data/minio/config && mkdir -p ~/docker-data/minio/data
docker run -d -p 9000:9000 -p 9001:9001 --name minio -e "MINIO_ACCESS_KEY=minioadmin" -e "MINIO_SECRET_KEY=minioadmin" -v ~/docker-data/minio/config:/root/.minio -v ~/docker-data/minio/data:/data quay.io/minio/minio server /data --console-address ":9001"

# Prometheus
# https://prometheus.io/docs/prometheus/latest/installation/
mkdir -p ~/docker-data/prometheus
# 在 ~/docker-data/prometheus/ 目录下增加配置文件 prometheus.yml,可参考 https://github.com/prometheus/prometheus/blob/main/config/testdata/conf.good.yml
docker run -d --name prometheus -p 9090:9090 -v ~/docker-data/prometheus:/etc/prometheus --add-host=host.docker.internal:host-gateway prom/prometheus

# 使用 node_exporter 监控 Linux 主机指标
# https://prometheus.io/docs/guides/node-exporter/
# 参考 https://gist.github.com/jarek-przygodzki/735e15337a3502fea40beba27e193b04

# Grafana
# https://grafana.com/docs/grafana/latest/setup-grafana/configure-docker/
mkdir -p ~/docker-data/grafana
# 配置权限,因为 grafana 用户会在这个目录写入文件,可以直接设置权限为 777
# chmod 777 -R ~/docker-data/grafana
# starts grafana with your user id and using the data folder
docker run -d --name=grafana --user $(id -u) -p 3000:3000 -v ~/docker-data/grafana:/var/lib/grafana grafana/grafana-enterprise
# 默认的用户名和密码都是 admin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  • prometheus.yml

    # my global config
    global:
      scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
      evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
      # scrape_timeout is set to the global default (10s).
    
    # Alertmanager configuration
    alerting:
      alertmanagers:
        - static_configs:
            - targets:
              # - alertmanager:9093
    
    # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
    rule_files:
      # - "first_rules.yml"
      # - "second_rules.yml"
    
    # A scrape configuration containing exactly one endpoint to scrape:
    # Here it's Prometheus itself.
    scrape_configs:
      # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
      - job_name: "prometheus"
    
        # metrics_path defaults to '/metrics'
        # scheme defaults to 'http'.
    
        static_configs:
          - targets: ["localhost:9090"]
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

# Docker 镜像

  • 镜像是静态的只读模板
  • 镜像中包含构建 Docker 容器的指令
  • 镜像是分层的(联合文件系统)
  • 通过 Dockerfile 来创建镜像

# Dockerfile

  • Dockerfile 是一个文本文件,里面包含了构建 Docker 镜像所需要用到的命令(Instruction)

# 常用指令 (opens new window)

指令 作用 格式举例
FROM 基于哪个镜像 FROM <image>[:<tag>] [AS <name>]
LABEL 设置标签 LABEL maintainer="Sdky"
RUN 运行安装命令 RUN ["executable", "param1", "param2"]
CMD 容器启动时的命令 CMD ["executable","param1","param2"]
ENTRYPOINT 容器启动后的命令 ENTRYPOINT ["executable", "param1", "param2"]
VOLUME 挂载目录 VOLUME ["/data"]
EXPOSE 容器要监听的端口 EXPOSE <port> [<port>/<protocol>...]
ENV 设置环境变量 ENV <key> <value>
ADD 添加文件 ADD [--chown=<user>:<group>] <src>... <dest>
WORKDIR 设置运行的工作目录 WORKDIR /path/to/workdir
USER 设置运行的用户 USER <user>[:<group>]

# 构建 Docker 镜像

  1. 手动构建:进入 Dockerfile 所在目录,docker build -t spring-boot-demo-docker .
  2. 通过 Maven 插件构建:dockerfile-maven-plugin (opens new window)

# Docker Compose (opens new window)

  • Docker Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排
  • 安装:yum install -y docker-compose

# Docker Compose 模板文件

# 安装 Kafka

version: '2'
services:
  zookeeper:
    image: zookeeper:latest

  kafka:
    # https://github.com/confluentinc/cp-docker-images/blob/5.3.3-post/examples/kafka-single-node/docker-compose.yml
    image: confluentinc/cp-kafka:latest
    depends_on:
      - zookeeper
    ports:
      - 9092:9092
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 安装 RocketMQ

cd docker-data
mkdir -p namesrv/logs namesrv/store broker/logs broker/store
# 容器中的 RocketMQ 启动用户为 rocketmq:uid=3000(rocketmq) gid=3000(rocketmq) groups=3000(rocketmq)
# 设置映射本地目录的所有者
chown 3000:3000 ./namesrv/logs ./namesrv/store ./broker/logs ./broker/store
wget https://raw.githubusercontent.com/foxiswho/docker-rocketmq/master/rmq/rmq/brokerconf/broker.conf
# 修改 broker.conf 文件中的 brokerIP1 为宿主机 IP
1
2
3
4
5
6
7
version: '3.5'

services:
  # Service for nameserver
  rmqnamesrv:
    image: foxiswho/rocketmq:4.8.0
    container_name: rmqnamesrv
    ports:
      - 9876:9876
    volumes:
      - ./namesrv/logs:/home/rocketmq/logs
      - ./namesrv/store:/home/rocketmq/store
    environment:
      JAVA_OPT_EXT: "-Duser.home=/home/rocketmq -Xms128M -Xmx512M -Xmn128m"
    command: ["sh","mqnamesrv"]

  # Service for broker
  rmqbroker:
    image: foxiswho/rocketmq:4.8.0
    container_name: rmqbroker
    ports:
      - 10909:10909
      - 10911:10911
    volumes:
      - ./broker/logs:/home/rocketmq/logs
      - ./broker/store:/home/rocketmq/store
      - ./broker.conf:/etc/rocketmq/broker.conf
    environment:
      JAVA_OPT_EXT: "-Duser.home=/home/rocketmq -Xms128M -Xmx512M -Xmn128m"
    command: ["sh","mqbroker","-c","/etc/rocketmq/broker.conf","-n","rmqnamesrv:9876","autoCreateTopicEnable=true"]
    depends_on:
      - rmqnamesrv

  # Service for console
  rmqconsole:
    image: styletang/rocketmq-console-ng
    container_name: rmqconsole
    ports:
      - 8180:8080
    environment:
      JAVA_OPTS: "-Drocketmq.namesrv.addr=rmqnamesrv:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false"
    depends_on:
      - rmqnamesrv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 常用命令

  • docker-compose -f docker-compose.yml up -d [SERVICE...]:使用的 Compose 模板文件(默认为 docker-compose.yml),在后台启动服务
  • docker-compose ps:列出项目中目前的所有容器
  • docker-compose logs [SERVICE...]:查看服务容器的输出,-f 实时输出
  • docker-compose start [SERVICE...]:启动已经存在的服务容器
  • docker-compose stop [SERVICE...]:停止正在运行的容器
  • docker-compose rm [SERVICE...]:删除(停止状态的)服务容器
  • docker-compose down:停止和删除容器、网络、卷、镜像
  • docker-compose exec [options] SERVICE COMMAND
  • docker-compose pause/unpause [SERVICE...]:暂停/恢复
Updated at: 2023-12-22 00:34:21