docker

docker使用到了容器化技术,相当于虚拟化技术的一个缩影,相当于把一个系统需要的依赖打包成一个容器

镜像: 对于一个系统的描述,可以利用镜像来构建容器,同时也可以通过容器转换为镜像,镜像可以使用 dockerfile 来构建,或者可以从仓库中拉取镜像

docker的常用命令就不说了...,参考 docker

Dockerfile

Dockerfile 的作用就是通过已经有的镜像构建容器,比如可以构建装 goubuntu系统,就像是可以把所有依赖打包到一个镜像中并且基于这一个镜像构建容器

接下来基于 alpine 系统构建一个 go 的运行环境,alpine系统是一个 linux发行版,体积小但是足以满足各种业务需求

首先拉取alpine系统的镜像:

sudo docker pull alpine

之后构建 Dockerfilealpine 系统中装载go语言环境,dockerfile 如下:

FROM alpine

# 构建容器中需要运行的命令
RUN mkdir /go && cd /go \
    && wget https://go.dev/dl/go1.24.1.linux-amd64.tar.gz \
    && tar -C /usr/local -zxf go1.24.1.linux-amd64.tar.gz \
    && rm -rf /go/go1.24.1.linux-amd64.tar.gz \
    && mkdir /lib64  \
    && ln -s /bin/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2

# 配置系统环境变量
ENV GOPATH /go
ENV PATH /usr/local/go/bin:$GOPATH/bin:$PATH

# 表示启动时需要运行的命令,防止容器退出
CMD ["ping" , "www.baidu.com"]

之后构建容器:

sudo docker build -t go:alpine .

启动容器

sudo docker run --name go -d go:alpine

进入容器查看是否构建成功

sudo docker exec -it go sh

利用 Docker 部署项目

分为两种方式:

  • 构建好 go 语言的容器之后,进行数据卷的映射,并且在容器中运行项目
  • 编译好可执行文件,并且基于可执行文件来构建 Docker 镜像并且基于镜像构建容器
利用数据卷挂载的方式
  • 首先挂载数据卷:
sudo docker run --name go-zero \
-p 8888:8888 \
-v /home/loser/im-learn/chapter2/grpc-demo1/go-zero:/go/src/im-learn \
-d go:alpine
  • 进入容器并且启动项目,注意到可以如果使用 go module 需要配置镜像
sudo docker exec -it go-zero sh
cd /go/src/im-learn/api
go run .
利用 Dockerfile 构建
  • 首先编译得到可执行文件:
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o bin/user-api ./user.go
  • Dockfile 文件如下:
FROM alpine

# 创建目标文件夹,并且复制内容
RUN mkdir /user && mkdir /user/bin && mkdir /user/conf

# 复制宿主机内容到容器中
COPY bin/user-api /user/bin/

# 复制配置文件(其实也可以挂载)
COPY etc/user.yaml /user/conf/

# 提供可执行文件权限
RUN chmod +x /user/bin/user-api

# 指定工作目录
WORKDIR /user

# 设置容器启动命令,使用 ENTRYPOINT 命令,和 CMD 不同的是不可以被替换
ENTRYPOINT ["/user/bin/user-api" , "-f" , "/user/conf/user.yaml"]

注意各种命令的含义,参考: https://www.runoob.com/docker/docker-dockerfile.html

容器网络

docker 安装之后运行的时候会默认创建三个网络,可以使用 docker network ls查看,内容如下:

NETWORK ID     NAME      DRIVER    SCOPE
00bf102cf338   bridge    bridge    local
7ad790d33916   host      host      local
cca9f20e71ae   none      null      local

三种模式的含义如下:

  • none模式: 这一中模式下容器会独立network,并且没有进行任何网络配置,比如分配 ip
  • bridge模式: Docker 创建一个虚拟以太网桥docker0,新的容器自动连接到这一个接口: Pasted image 20250308163019.png
  • host模式: 容器直接使用主机的网络信息 Pasted image 20250308163513.png

容器网络相关命令

参考 docker

docker 容器互通

  1. 通过宿主机做桥接(端口映射)
  2. 容器都位于同一个网络段之下(需要使用 --net 指定网络)
  3. 通过 link 命令(可以通过容器名访问,底层可能使用了 DNS)

docker-compose

docker-compose 类似于一个 shell 脚本,作用就是可以根据配置文件的内容运行容器

Target: 启动三个容器分别运行 user-api , user-rpcetcd , 并且实现容器之间的互通(使用三者的可执行文件 + Dockerfile 构建镜像)

  1. 创建一个网络段user , 创建命令如下:
sudo docker network create --subnet=168.10.0.0/24 user
  1. 编写 docker-compose.yaml 文件,内容如下,注意语法(不会就去查就可以了):
version: "3"

services:
  # 服务名
  etcd:
    # 选择镜像:镜像的选择会先从本地找,如果没有会去仓库中拉取下来
    image: bitnami/etcd
    # 可以选择指定的dockerfile自动帮我构建
    build:
      # 指定dockerfile所在的目录
      context: ./
      # 指定dockerfile的文件名
      dockerfile: Dockerfile
    # 定义创建的容器名
    container_name: etcd
    # 使创建的容器与宿主机绑定端口
    ports:
      - "2379:2379"
      - "2380:2380"
    # 配置系统环境变量
    environment:
      - ETCD_ENABLE_V2=true
      - ALLOW_NONE_AUTHENTICATION=yes
      - ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
      - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
      - ETCD_NAME=etcd
    # 配置容器与宿主机的共享目录
    # 同时需要注意宿主机存在目录,并且要基于权限不然系统会直接报错
    volumes:
      - ./data:/bitnami/etcd/data
      - ./logs:/bitnami/etcd/logs
    # 设置容器的网络段
    networks:
      user:
        ipv4_address: 168.10.0.20

  user-rpc:
    image: user-rpc:alpine
    container_name: user-rpc
    ports:
      - "8080:8080"
    # 与etcd服务互通
    links:
      - etcd
    # 需要等指定容器启动后才可以启动,填写的是容器的服务名
    depends_on:
      - etcd
    networks:
      user:

  user-api:
    image: user-api:alpine
    container_name: user-api
    ports:
      - "8888:8888"
    # 与etcd服务互通
    links:
      - etcd
    # 需要等指定容器启动后才可以启动,填写的是容器的服务名
    depends_on:
      - etcd
      - user-rpc
    networks:
      user:

# 由docker创建
networks:
  user:
    external:
      name: user
  1. 使用如下命令构建即可:
sudo docker-compose up -d
  1. 可以使用如下命令停止并且删除容器:
sudo docker-compose down