업데이트 1

업데이트 1

docker swarm을 설정하려고 합니다.

TLS를 통해 통신하려면 노드가 필요합니다.

ExtendedKeyUsage = serverAuth를 사용하여 관리자 노드에 대한 인증서를 만들었습니다.

다음 daemon.json을 사용하여 관리자 노드를 구성했습니다.

{
    "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
    "tlscacert": "/var/docker/ca.pem",
    "tlscert": "/var/docker/server-cert.pem",
    "tlskey": "/var/docker/server-key.pem",
    "tlsverify": true
}

이를 테스트하기 위해 내 노트북에서 Docker API에 연결하는 데 사용되는 클라이언트 인증서를 만들었고 성공적으로 연결할 수 있습니다.

이제 Swarm에 하나의 작업자 노드를 추가해야 합니다.

매니저 노드와 같은 방식으로 설정했습니다. 비슷한 daemon.json을 사용합니다. ExtendedKeyUsage = serverAuth와 함께 SSL 키를 사용했으며 관리자 노드에서와 동일한 방식으로 클라이언트 연결을 입증했습니다.

그런 다음 관리자에서 docker swarm init를 실행했습니다.

작업자 노드를 떼에 가입시키기 위해 다음 명령을 사용합니다: docker swarm Join --token XXX Dockman.myhost.com:2376

하지만 오류가 발생합니다.

Error response from daemon: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: authentication handshake failed: remote error: tls: bad certificate"

작업자 노드에서 관리자 노드의 Docker API에 연결을 시도하면 추가로 테스트할 수 있다고 생각했습니다.

sudo docker --tlsverify --tlscacert=/var/docker/ca.pem --tlscert=./server-cert.pem --tlskey=./server-key.pem -H=127.0.0.1:2376 version

결과는 다음과 같습니다.

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false
The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: Get https://127.0.0.1:2376/v1.40/version: remote error: tls: bad certificate

이번 두 번째 테스트는 나에게 생각할 거리를 더 많이 주었다. 물론 클라이언트 인증서가 아닌 서버 인증서로 연결을 시도하기 때문에 실패하겠지만, 이것이 바로 docker swarm Join이 하려는 작업이 아닐까요? 클라이언트 인증서를 daemon.json에 넣는 것은 나에게 의미가 없습니다. 서버와 클라이언트 모두에 단일 인증서를 만드는 것이 가능하지만 나쁜 습관인 것 같습니다. 필요한 경우 튜토리얼에서 다루었을 것이라고 생각했을 것입니다.

나는이 시점에서 막혔습니다. 어떤 인증서 설정이 필요한지 알 수 없습니다.

나는 팔로우해왔다 https://github.com/docker/docker.github.io/blob/master/swarm/configure-tls.md 이는 인증서 생성에 대해 설명하지만 클라이언트 또는 서버 인증에 대해서는 전혀 언급하지 않습니다.

업데이트 1

인증서는 클라이언트와 서버여야 한다는 문서를 찾았습니다.

https://hub.docker.com/_/swarm/

그래서 노드 인증서를 클라이언트와 서버 모두로 다시 만들었습니다. 이제 docker version 명령은 노드에서 실행할 때 작동하지만 Swarm Join에서는 작동하지 않습니다.

답변1

docker swarmSwarm 모드( 및 유사한 CLI)를 기존 컨테이너 기반 Swarm(Docker 허브에서 컨테이너로 호스팅됨)과 혼합하고 있습니다 . 이들은 두 가지 다른 도구입니다.

두 가지 문서 세트에 대해서는 다음을 참조하세요.

Swarm 모드에서는 수동 TLS 구성을 수행할 필요가 없으며 모두 내장되어 있으며 Swarm 모드용 포트는 Docker API 소켓용 포트와 다릅니다. 정당한 이유(해킹의 일반적인 소스임) 없이 네트워크에 도커 API를 노출하고 싶지 않으며 스웜 모드는 그럴 이유가 없습니다.

따라서 TLS 옵션과 함께 명령 -H에 대한 옵션을 제거해야 합니다. 그런 다음 TLS 자격 증명을 생성하고 자체 서명된 인증서의 해시가 포함된 토큰을 제공하는 첫 번째 관리자에서 dockerd실행합니다 . docker swarm init그런 다음 다른 관리자와 작업자는 a를 실행 docker swarm join하여 클라이언트 인증서를 생성하고, 관리자에 연결하고, 토큰에서 관리자 인증서 해시의 유효성을 검사하고, 조인 토큰의 비밀 부분을 사용하여 관리자에게 자신을 인증합니다.

위의 내용은 관리자와 작업자 간의 관리 평면을 암호화합니다. 작업자 간 오버레이 네트워크에서 전송되는 데이터를 암호화하려면 생성한 오버레이 네트워크에서 IPSec를 활성화해야 합니다.

docker network create --opt encrypted --driver overlay app-overlay-net

이 기능에 대한 문서는 다음 위치에 있습니다.https://docs.docker.com/v17.09/engine/userguide/networking/overlay-security-model/

답변2

인증서가 모두 작동하려면 클라이언트 및 서버 인증서여야 한다는 것이 옳았습니다.

그런 다음 계속해서 다른 문제에 직면했는데, 가장 큰 문제는 내가 사용하고 있는 호스트의 가상 머신이 VMWare에서 사용되는 포트 4789의 사용을 금지한다는 것입니다. 이는 오버레이 네트워크에 사용되는 기본 데이터 경로 포트입니다.

떼에서 모든 노드와 관리자를 완전히 제거하고(효과적으로 삭제) data-path-port 매개변수를 사용하여 다시 초기화해야 했습니다.

docker swarm init --data-path-port=7777

(또한 각 노드의 IP로 광고 주소를 지정했지만 이것이 필수는 아닌 것 같습니다)

물론 내 모든 docker 비밀, docker 구성 및 내 docker 네트워크 중 일부가 이 프로세스에서 손실되어 다시 생성되어야 했습니다.

이 작업을 완료하고 데이터 경로 포트를 사용하여 노드 간 UDP 통신을 허용하도록 방화벽을 변경하면 다시 작동했습니다.

스웜 네트워크는 암호화되어 있기 때문에 모두 작동해야 한다고 생각합니다.

관련 정보