Switch swarm to using hyphens as a separator in hostnames
As far as I can tell, this has not been reported on this repository. It is a direct copy of https://github.com/docker/compose/issues/229 which was marked as closed on compose, but the exact same issue exists on docker stack deploy
Description
When using stack deploy, container names are prefixed with the stack name, then an underscore. The DNS entry for the container (regardless of vip or dnsrr) will be stackname_containername. This violates RFCs on valid hostnames (see linked ticket for RFC numbers). Apparently in the past multiple languages / webservers still allowed this, but in modern times multiple languages will reject any incoming HTTP request that has a Host header with an underscore. From the linked ticket, this problem exists in:
- Apache
- Spring Boot (via Tomcat)
- Ruby's URI parse method
- Django (via django.security.DisallowedHost)
Steps to reproduce the issue:
- Launch any modern spring boot application as part of a stack
- Exec into another container inside the same stack and curl/wget into that spring boot app via the DNS name
Describe the results you received:
For Tomcat, here is the resulting error
2021-11-17 01:38:07.226 INFO 1 --- [nio-8081-exec-2] o.apache.coyote.http11.Http11Processor : The host [test_upstream-mock:8081] is not valid
Note: further occurrences of request parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: The character [_] is never valid in a domain name.
at org.apache.tomcat.util.http.parser.HttpParser$DomainParseState.next(HttpParser.java:974) ~[tomcat-embed-core-9.0.53.jar:9.0.53]
Describe the results you expected:
In https://github.com/docker/compose/issues/229 the decision was made to switch to using hyphens, instead of underscores, to prefix container names inside of a stack. These have no routing issues with various language components as they are valid and commonly used in URLs.
Of interest, this was apparently also part of the motivation for using periods in the suffix portion of swarm container naming (e.g. stackname_containername.1.pmybkzo8ovlirri0rf1syyo4p has periods for the number and id), but somehow the underscore for the prefix never went away even though the underscores that were (originally) used for the suffix values were removed
Output of docker version:
Client:
Cloud integration: v1.0.20
Version: 20.10.10
API version: 1.41
Go version: go1.16.9
Git commit: b485636
Built: Mon Oct 25 07:43:15 2021
OS/Arch: darwin/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.10
API version: 1.41 (minimum version 1.12)
Go version: go1.16.9
Git commit: e2f740d
Built: Mon Oct 25 07:41:30 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.11
GitCommit: 5b46e404f6b9f661a205e28d59c982d3634148f8
runc:
Version: 1.0.2
GitCommit: v1.0.2-0-g52b36a2
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Output of docker info:
Client:
Context: default
Debug Mode: false
Plugins:
buildx: Build with BuildKit (Docker Inc., v0.6.3)
compose: Docker Compose (Docker Inc., v2.1.1)
scan: Docker Scan (Docker Inc., 0.9.0)
Server:
Containers: 7
Running: 5
Paused: 0
Stopped: 2
Images: 30
Server Version: 20.10.10
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: active
NodeID: fb4iiubm41rqdw4xk6geclqop
Is Manager: true
ClusterID: ytub70qrgxhq1esdpeuypgdo3
Managers: 1
Nodes: 1
Default Address Pool: 10.0.0.0/8
SubnetSize: 24
Data Path Port: 4789
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 10
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Force Rotate: 0
Autolock Managers: false
Root Rotation In Progress: false
Node Address: 192.168.65.3
Manager Addresses:
192.168.65.3:2377
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 5b46e404f6b9f661a205e28d59c982d3634148f8
runc version: v1.0.2-0-g52b36a2
init version: de40ad0
Security Options:
seccomp
Profile: default
Kernel Version: 5.10.47-linuxkit
Operating System: Docker Desktop
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 5.804GiB
Name: docker-desktop
ID: EJRL:B3PO:RQI6:WXA7:UEHR:TTIN:3YK5:T4O6:3SYM:7JMB:7LEN:LD55
Docker Root Dir: /var/lib/docker
Debug Mode: false
HTTP Proxy: http.docker.internal:3128
HTTPS Proxy: http.docker.internal:3128
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Breaks SSL certificate signing from some CA portals - https://stackname_servicename is the internal addressable service that neds a signed cert for some applications - can't get a cert issued without a valid hostname.
This issue here is related: https://github.com/boto/boto3/issues/703
This boto3 is used by MinIO, which is a self-hosted S3-compatible storage. boto3 won't allow underscores in hostnames anymore. So everything that is hosted in docker swarm won't be compatible with newer versions of MinIO/boto3.
This is still an issue, and quite a major one I think. Compose fixed that, I think Swarm should too.
A workaround is using network aliases: https://docs.docker.com/compose/compose-file/compose-file-v3/#aliases
Using this trick seems to work but it makes stack.yml files heaftier for no reason. Using this trick is also bad for "muscle memory": the service names must be referred to using an underscore in docker commands, but with hyphens when referrencing / resolving DNS from other services. This is prone to errors. Easily detectable errors, but just useless friction.
I looked into submitting a pull request, but I think this is deeper in the core than the cli, which I guess involves recompiling everything to test the idea. A bit to involved for my little experience with this code base.
Nevertheless docker swarm is great. Thanks!
The aliases work to refer to services, but is there any way I can refer to a task without the underscore?