文章标签 ‘docker’
20247 月16

为群晖 Container Manager 配置代理

原文地址:https://blog.chai.ac.cn/posts/docker-proxy

最后更新:2024年7月15日

最近又见识到了一些神奇的骚操作,考虑到在将来 Docker 的国内各个镜像站可能变得不可用,需要未雨绸缪一下。 有旁路由自然是好的,但现在打算用 Proxy 来解决这个问题。 由于群晖的 Container Manager 是基于 Docker 的,但部分配置路径不同,所以特意记录一下。

注意事项:

  • 本教程在全新的 Ubuntu 22.04 LTS 系统环境下通过测试
  • 本教程在群晖 DSM 7.2 版本通过测试,假定具备 root 权限
  • 假定你已有可以代理 HTTP 或 SOCKS 协议的端口:例如 192.168.50.100:7893
  • 尽可能引用官方文档,本文主要针对需要代理的部分的设置

安装 Docker,为 apt 设置代理

群晖 Container Manager 用户可以跳过这一小节,你实际上已经有 Docker 了。

Docker Engine 安装过程请参考 官方文档

Docker 官方给出了许多安装方式,我选择用 apt 从官方维护的源中安装。

你也可以选择手动下载二进制包,然后用 dpkg 安装.

这里选择使用 apt 演示,关键在于很多人还不清楚如何为 apt 设置代理:

shell

sudo vi /etc/apt/apt.conf

shell

Acquire::http::Proxy "http://192.168.50.100:7893";
Acquire::https::Proxy "http://192.168.50.100:7893";

注意第二个行依旧是 http 协议,否则会碰到 TLS Could not handshake 问题。 代理服务器只需要负责做请求转发和响应转发,不会像 HTTPS 协议一样进行解密和加密。

为 Docker Daemon 设置代理

安装完成后,官网教程会让你运行 docker run hello-world 来验证安装是否成功。

默认情况下,你的本地肯定不存在任何有关镜像(如下所示),因此会从官方库拉取:

shell

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Retrying in 1 second
docker: error pulling image configuration: 
  download failed after attempts=6: dial tcp 31.13.82.33:443: i/o timeout.

执行拉取操作的是 Docker Daemon,参考 官方文档 进行 Proxy 有关的设置:

对于 Docker 引擎 23.0 及更高版本

提示

使用 docker info 可以查询到版本信息,版本太低的话请参考下一节的方法。

Docker Daemon 大多数配置选项都可根据 daemon.json 文件进行设置。

对于 Docker 引擎 23.0 及更高版本,可以在该文件中设置代理行为:

  • Root 模式:/etc/docker/daemon.json
  • Rootless 模式:~/.config/docker/daemon.json
  • 群晖 Container Manager:/var/packages/ContainerManager/etc/docker.json

shell

{
  "proxies": {
    "http-proxy": "http://192.168.50.100:7893",
    "https-proxy": "http://192.168.50.100:7893",
    "no-proxy": "127.0.0.0/8"
  }
}

这些配置将覆盖 docker.service 默认的 systemd 设定。

如果您位于 HTTP 或 HTTPS 代理服务器后面,例如在公司设置中, 则必须在 systemd 服务文件中指定守护程序代理配置,而不是在 daemon.json 文件中或使用环境变量。

较为通用的 systemd 设置方法

如 Docker 版本太低,不支持通过 daemon.json 配置代理,则需手动创建 systemd 文件:

  • Root 模式:/etc/systemd/system/docker.service.d
  • Rootless 模式:~/.config/systemd/user/docker.service.d
  • 群晖:/etc/systemd/system/pkg-ContainerManager-dockerd.service.d

添加 http-proxy.conf 文件,下面以群晖 Container Manager 为例:

shell

sudo mkdir -p /etc/systemd/system/pkg-ContainerManager-dockerd.service.d
sudo vi /etc/systemd/system/pkg-ContainerManager-dockerd.service.d/http-proxy.conf

shell

[Service]
Environment="HTTP_PROXY=http://192.168.50.100:7893"
Environment="HTTPS_PROXY=http://192.168.50.100:7893"
Environment="NO_PROXY=localhost,127.0.0.1"

如果你有内建的 registry-mirrors, 记得加入 NO_PROXY 中。

重启 Docker Daemon

不论采用上面哪种方式,都需要重启 Docker Daemon 服务:

  • 如果是旧版本群晖(6.0+),要用 synoservice 代替 systemctl.
  • 如果是 rootless 模式,要用 systemctl --user 代替 sudo systemctl.

下面仅仅给出 root 模式和群晖 Container Manager 的重启方法:

sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl restart pkg-ContainerManager-dockerd.service

重启 Docker/Conatiner Manager 服务需要一定的时间,取决于你正在运行的容器数量。

检查设置是否生效:

sudo systemctl show --property=Environment docker
systemctl show --property=Environment pkg-ContainerManager-dockerd.service

再次跑 docker run hello-world,应该就能成功了。

为 Docker 容器设置代理

有的时候,你使用的 Docker 镜像在 build 和 run 时也需要代理。 大部分应该都知道怎么配置,或者会通过环境变量来设置。 但有的时候希望代理配置默认对所有容器生效(那为什么不用机器或路由级别的代理呢),可以参考下面的方法。

参考 官方文档 中的说明,你可以在 ~/.docker/config.json 中设置代理。

shell

{
 "proxies": {
   "default": {
     "httpProxy": "http://192.168.50.100:7893",
     "httpsProxy": "http://192.168.50.100:7893",
     "noProxy": "127.0.0.0/8"
   }
 }
}

保存文件后配置将生效,适用于新容器的生成和运行,无需重启 Docker,

本质上,它通过影响 Docker CLI 来添加环境变量,效果类似于:

shell

docker build --build-arg HTTP_PROXY="http://192.168.50.100:7893" .
docker run --env HTTP_PROXY="http://192.168.50.100:7893" redis

但一般还是建议单独针对需要代理服务的容器手动设置这些环境变量, 同样地,一些 Docker 内的应用是不按照环境变量来设置代理的,需要手动配置,需要额外注意。 折腾了这么多,是不是还是觉得旁路由+规则代理的方法会更加简单呢?这就看个人需求了。

20166 月13

Docker:部署Node.js项目

 

Dockerfile:

FROM node:6.2
# Author
MAINTAINER wizzer "wizzer@qq.com"
ENV PORT 1337
RUN apt-get update && apt-get install -y \
		imagemagick \
	--no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /node/nodeshop
WORKDIR /node/nodeshop

RUN npm config set registry https://registry.npm.taobao.org
RUN npm i node-gyp -g
RUN npm i pm2 -g
ADD api /node/nodeshop/api
ADD assets /node/nodeshop/assets
ADD config /node/nodeshop/config
ADD tasks /node/nodeshop/tasks
ADD views /node/nodeshop/views
ADD app.js /node/nodeshop
ADD Gruntfile.js /node/nodeshop
ADD package.json /node/nodeshop
RUN npm i
EXPOSE ${PORT}
ENV LANG C.UTF-8
ENV TZ "Asia/Shanghai"
VOLUME ["/node/nodeshop/cert", "/node/nodeshop/upload", "/node/nodeshop/backup"]
CMD [ "pm2", "start", "--no-daemon", "app.js" ]

docker-compose.yml:

redis:
  image: redis
db:
  image: mariadb:5.5
  environment:
    "MYSQL_ROOT_PASSWORD": "xxxxxx"
    "MYSQL_DATABASE": "db123"
  command: "mysqld --character-set-server=utf8"
  ports:
    - "127.0.0.1:3306:3306"
  volumes:
    - "/node/nodeshop/db:/var/lib/mysql"
web:
  image: wizzer/nodeshop
  links:
    - redis
    - db
  environment:
    "MYSQL_HOST": "db"
    "MYSQL_USER": "root"
    "MYSQL_PASSWORD": "xxxxxx"
    "MYSQL_DATABASE": "db123"
    "MYSQL_LIMIT": 150
    "REDIS_HOST": "redis"
    "REDIS_PASS": ""
    "LOG_LEVEL": "verbose"
    "PORT": 1337
    "NODE_ENV": "development"
  command: "pm2 start /node/nodeshop/app.js --no-daemon"
  ports:
    - "1337:1337"
  volumes:
    - "/node/nodeshop/cert:/node/nodeshop/cert"
    - "/node/nodeshop/upload:/node/nodeshop/upload"
    - "/node/nodeshop/backup:/node/nodeshop/backup"

说明:
1、把数据库端口3306映射到127.0.0.1:3306 是为了还原数据库,web映射端口不绑定IP这样外网可以访问,通过nginx代理出去.
2、volumes将数据文件、数据库文件使用容器外文件夹,这样重启后不丢失数据.

1、打包最新image
docker build -t wizzer/nodeshop .

. 为当前文件夹,通过Dockerfile打包
wizzer/nodeshop:v1.0 用户名/项目:版本号

docker images 列出所有镜像
docker rmi ID 删除某个镜像
docker ps -a 列出所有容器
docker rm ID 删除某个容器
2、Centos安装Docker-engine 1.7.1版本(windows安装docker-toolbox即可)

vi /etc/yum.repos.d/docker.repo

[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/6/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg

yum search docker
yum install docker-engine.x86_64
service docker start 启动docker服务
chkconfig docker on 设置为开启启动

3、Centos安装docker-compose 1.1.0版本(windows安装docker-toolbox即可)

curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

ps:第一行命令复制会少符号,到 https://github.com/docker/compose/releases/ 复制命令。

4、迁移镜像
docker ps -a 列出容器快照
docker export ID > nodeshop.tar 将容器快照导出
cat /node/nodeshop.tar | docker import – wizzer/nodeshop 加载容器快照

5、创建运行目录
分别创建4个文件夹【必须】
/node/nodeshop/cert 将证书文件拷贝进去
/node/nodeshop/upload 附件上传文件夹
/node/nodeshop/backup 数据库备份文件夹
/node/nodeshop/db 数据库文件夹
将Dockfile 、 docker-compose.yml 拷贝到 /node/nodeshop 目录

6、启动项目

cd /node/nodeshop
docker-compose up -d

docker-compose ps 列出正在运行的服务
docker-compose stop 停止服务
docker ps -a 列出所有容器状态
docker rm ID 删除容器

若要修改环境变量,可以修改 /node/nodeshop/docker-compose.yml 文件内容

7、安装mariadb客户端(用于连接数据库)

cd /etc/yum.repos.d/
vi MariaDB.repo

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/5.5/centos6-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

yum install MariaDB-client

MariaDB-server 不需要安装

8、还原数据

mysql -h 127.0.0.1 -u root -p
密码
show databases;
use nodeshop;
source /node/nodeshop/db.sql;
show tables;
exit;

9、重启docker容器

docker-compose stop
docker-compose start

10、进入容器执行命令,比如测试网络情况

docker ps -a
docler exec -it ID /bin/bash
ping 192.168.1.11
exit

如果网络不通,可能需要关闭防火墙,然后重启docker服务:

service docker restart

11、容器开机自启动

vi /etc/rc.d/rc.local
/usr/local/bin/docker-compose -f /node/sunshop/docker-compose.yml up -d

注意:如果是centos7 则需要执行 chmod +x /etc/rc.d/rc.local 添加执行权限.

 


本教程适用于Centos6.x版本,7或有不同。