4
这个楼主还没有留下简介。
第 18 篇使用 Compose 示例中的 ziti-private-blue Router 承载了 Web 服务。本篇换一种更灵活的方式:启动独立的 ziti-host 容器,让它把一个 Docker 应用接入 OpenZiti。
text客户端 Tunneler → OpenZiti 网络 → ziti-host 容器 → demo-app:8000
openziti/ziti-host 使用 run-host 模式,负责承载获得 Bind 授权的服务。这个示例不需要给它添加 privileged 或 NET_ADMIN。身份文件需要保存在可写的持久卷中,供后续启动和证书更新使用。官方 Docker Tunneler 指南提供了对应的镜像和卷配置。
本文继续使用第 17、18 篇的完整 Compose 网络,以及已经注册在 Docker 宿主机上的 docker-web-client 身份。
进入第 17 篇的目录,并打开 Controller 容器:
bashcd ~/openziti-docker-lab
docker compose exec ziti-controller bash
在容器内登录:
bashzitiLogin
为 ziti-host 创建独立身份:
bashziti edge create identity docker-app-host \ -o /tmp/docker-app-host.jwt
创建客户端拦截配置:
bashziti edge create config docker-app-intercept intercept.v1 \
'{"protocols":["tcp"],"addresses":["docker-app.ziti"],"portRanges":[{"low":80,"high":80}]}'
创建服务端配置,指向稍后创建的 Docker 应用:
bashziti edge create config docker-app-host-config host.v1 \
'{"protocol":"tcp","address":"demo-app","port":8000}'
创建服务和策略:
bashziti edge create service docker-app \
--configs docker-app-intercept,docker-app-host-config
ziti edge create service-policy docker-app-dial Dial \
--identity-roles '@docker-web-client' \
--service-roles '@docker-app'
ziti edge create service-policy docker-app-bind Bind \
--identity-roles '@docker-app-host' \
--service-roles '@docker-app'
docker-app.ziti:80 是客户端入口;demo-app:8000 是 ziti-host 容器访问后端时使用的 Docker 地址。服务配置的作用可参考官方 创建第一个服务。
输入 exit 返回宿主机,将 JWT 复制出来:
bashdocker compose cp \
ziti-controller:/tmp/docker-app-host.jwt \
./docker-app-host.jwt
chmod 600 docker-app-host.jwt
在 ~/openziti-docker-lab 中新建 compose.app.yaml:
bashnano compose.app.yaml
写入:
yamlservices:
demo-app:
image: openziti/hello-world
networks:
- zitiblue
demo-ziti-host:
image: openziti/ziti-host
depends_on:
- demo-app
environment:
- ZITI_ENROLL_TOKEN
volumes:
- demo-ziti-host-identity:/ziti-edge-tunnel
networks:
- zitiblue
volumes:
demo-ziti-host-identity:
这里复用了第 17 篇 compose.yaml 中定义的 zitiblue 网络。demo-app 没有配置宿主机 ports 映射;demo-ziti-host 通过 Docker 服务名访问它。
之后执行本篇的 Compose 命令时,需要同时指定两个文件:
text-f compose.yaml -f compose.app.yaml
把 JWT 内容传给首次启动的容器:
bashexport ZITI_ENROLL_TOKEN="$(< ./docker-app-host.jwt)"
docker compose -f compose.yaml -f compose.app.yaml \
up -d demo-app demo-ziti-host
查看状态和日志:
bashdocker compose -f compose.yaml -f compose.app.yaml \
ps demo-app demo-ziti-host
docker compose -f compose.yaml -f compose.app.yaml \
logs --tail=50 demo-ziti-host
注册成功后,身份文件会保存在 demo-ziti-host-identity 数据卷中。确认成功后清除当前终端中的令牌:
bashunset ZITI_ENROLL_TOKEN
容器首次启动时的环境中仍有该值。确认项目 .env 中没有设置 ZITI_ENROLL_TOKEN 后,可以重建 demo-ziti-host,让它从数据卷加载已注册身份:
bashdocker compose -f compose.yaml -f compose.app.yaml \ up -d --no-deps --force-recreate demo-ziti-host
随后可删除宿主机和 Controller 容器中用于传输的 JWT 副本。保留身份数据卷:删除卷后,容器将失去已注册身份,而原 JWT 已经使用,不能直接重复注册。
先从 Docker 蓝色网络内检查应用是否可达:
bashdocker compose -f compose.yaml -f compose.app.yaml \
exec ziti-private-blue curl -fsS http://demo-app:8000
这一步检查 Docker 网络。接着在已经注册 docker-web-client 的宿主机上,通过 OpenZiti 测试:
bashcurl --noproxy '*' --connect-timeout 10 http://docker-app.ziti/
返回 Hello World 页面后,说明客户端已通过新服务访问 demo-app。
ZITI_ENROLL_TOKEN 的值必须是 JWT 内容,不是文件路径;同时检查容器能否解析并连接 Controller。demo-ziti-host 和 demo-app 都在 zitiblue 网络,且应用在容器内监听 8000 端口。127.0.0.1:两个容器使用各自的网络命名空间,127.0.0.1 在这里指向 ziti-host 容器自身。应使用可从它访问的 demo-app:8000。depends_on 控制启动顺序,不保证应用已经准备好;可以先检查 demo-app 日志。ports 就完全隔离了吗? 同一 Docker 网络中的其他容器仍可能直接访问 demo-app:8000,还需要管理 Docker 网络成员和宿主机权限。