-
Hello! Let's assume I have two physical machines, machineA with IP 233.252.0.100 and a machineB with IP 198.51.100.50. Theese both machines are able to communicate with each other via Internet. Now, I create a cluster with k3d on machineA with, say, 1 server and 3 agents. And then I want to join another 2 servers and another 3 agents to this same cluster, but from machineB, making the cluster distributed across theese two machines. Is there a way to achieve it? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 8 replies
-
After investigating some more, I found out that k3d uses the rancher/k3s image, which is basically a wrapper around k3s itself, so I guess I can try to use k3s documentation and start it off manually. |
Beta Was this translation helpful? Give feedback.
-
Hey @Evengard , thanks for starting this discussion! There are a few open issues in this repo talking about exactly this topic. What may help you right now is the official k3s docker-compose file: https://github.com/k3s-io/k3s/blob/master/docker-compose.yml. Related issues: |
Beta Was this translation helpful? Give feedback.
-
The results are... Kinda weird. No, I actually managed to setup the configuration I described above... The problem is that when I stop the "primary" server with 2 control plane nodes, leaving only the "fallback" one, the cluster seems to be dead, as the control-plane node on the fallback server for some reason just becomes unresponsive... I've set it up as follows (two separate docker-compose files for two separate KVM hosts): Primary: version: "2.4"
services:
server0-0:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "server --cluster-init --tls-san 0.0.0.0 --tls-san 127.0.0.1 --tls-san 10.110.101.0 --node-name server0-0 --advertise-address <redacted external IP> --https-listen-port 42000 --kube-proxy-arg=conntrack-max-per-core=0 --disable traefik --with-node-id"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml
- K3S_KUBECONFIG_MODE=666
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/server0-0/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/server0-0/log:/var/log
# This is just so that we get the kubeconfig file out
- /srv/k3s/config:/output
ports:
- 42000:42000
networks:
k3s:
ipv4_address: 10.110.101.0
server0-1:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "server --kube-proxy-arg=conntrack-max-per-core=0 --node-name=server0-1 --advertise-address <redacted external IP> --https-listen-port 42000 --tls-san 0.0.0.0 --tls-san 127.0.0.1 --tls-san 10.110.101.1 --disable traefik --with-node-id"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.101.0:42000
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/server0-1/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/server0-1/log:/var/log
- type: bind
source: /srv/k3s/data/server0-0/k3s/server/token
target: /token
read_only: true
networks:
k3s:
ipv4_address: 10.110.101.1
depends_on:
- server0-0
agent:
image: "rancher/k3s:latest"
scale: 3
entrypoint: /entrypoint.sh
command: "agent --kube-proxy-arg=conntrack-max-per-core=0 --node-name=agent --with-node-id"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.101.0:42000
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- type: bind
source: /srv/k3s/data/server0-0/k3s/server/token
target: /token
read_only: true
networks:
k3s:
depends_on:
- server0-0
- server0-1
- ingress0
ingress0:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "agent --kube-proxy-arg=conntrack-max-per-core=0 --node-name=ingress0 --node-ip=10.110.100.0 --node-taint=ingress:NoSchedule --node-label=ingress=true --with-node-id"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.101.0:42000
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/ingress0/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/ingress0/log:/var/log
- type: bind
source: /srv/k3s/data/server0-0/k3s/server/token
target: /token
read_only: true
network_mode: "host"
depends_on:
- server0-0
- server0-1
networks:
k3s:
name: k3s
driver_opts:
com.docker.network.bridge.name: "k3sbr"
ipam:
config:
- subnet: 10.110.0.0/16
ip_range: 10.110.102.0/24
gateway: 10.110.100.0 Fallback: version: "2.4"
services:
server1-0:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "server --kube-proxy-arg=conntrack-max-per-core=0 --node-name=server1-0 --advertise-address <redacted external ip> --https-listen-port 45000 --tls-san 0.0.0.0 --tls-san 127.0.0.1 --tls-san 10.110.111.0 --disable traefik --with-node-id"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.101.0:42000
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/server1-0/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/server1-0/log:/var/log
- type: bind
source: /srv/k3s/config/token
target: /token
read_only: true
networks:
k3s:
ipv4_address: 10.110.111.0
ports:
- 45000:45000
agent:
image: "rancher/k3s:latest"
scale: 2
entrypoint: /entrypoint.sh
command: "agent --kube-proxy-arg=conntrack-max-per-core=0 --node-name=agent --with-node-id"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.111.0:45000
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- type: bind
source: /srv/k3s/config/token
target: /token
read_only: true
networks:
k3s:
depends_on:
- server1-0
- ingress1
ingress1:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "agent --kube-proxy-arg=conntrack-max-per-core=0 --node-name=ingress1 --node-ip=10.110.110.0 --node-taint=ingress:NoSchedule --node-label=ingress=true --with-node-id"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.111.0:45000
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/ingress1/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/ingress1/log:/var/log
- type: bind
source: /srv/k3s/config/token
target: /token
read_only: true
network_mode: "host"
depends_on:
- server1-0
networks:
k3s:
name: k3s
driver_opts:
com.docker.network.bridge.name: "k3sbr"
ipam:
config:
- subnet: 10.110.0.0/16
ip_range: 10.110.112.0/24
gateway: 10.110.110.0 The resulting cluster looks like:
The docker bridges are interconnected between themselves with manually setup VXLAN (that's why I defined "com.docker.network.bridge.name" to a static name - to be able to attach to the bridge the VXLAN interface). The "ingress" agents are hosted with "network_mode: host" to be able to setup on them ingress services to actually be able to use the cluster the "kubernetes-way". That's basically the entry-point. I marked them with a custom label and a taint to avoid scheduling regular nodes on them. The setup is MOSTLY fine, but there is still this problem of the fallback server (control plane) node not taking over when the main ones are dead... |
Beta Was this translation helpful? Give feedback.
-
Well, my problem was indeed etcd majority problems, so I ended up with 3 KVM hosts, having following setups: Management: version: "2.4"
services:
server-manage:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "server --cluster-init --tls-san 192.168.100.106 --tls-san 127.0.0.1 --tls-san 10.110.101.0 --node-name server-manage --advertise-address 192.168.100.106 --https-listen-port 6443 --kube-proxy-arg=conntrack-max-per-core=0 --disable traefik --node-ip=10.110.101.0"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml
- K3S_KUBECONFIG_MODE=666
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/server-manage/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/server-manage/log:/var/log
# This is just so that we get the kubeconfig file out
- /srv/k3s/config:/output
ports:
- 6443:6443
networks:
k3s:
ipv4_address: 10.110.101.0
networks:
k3s:
name: k3s
driver_opts:
com.docker.network.bridge.name: "k3sbr"
ipam:
config:
- subnet: 10.110.0.0/16
ip_range: 10.110.102.0/24
gateway: 10.110.100.0 Primary: version: "2.4"
services:
server-main:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "server --kube-proxy-arg=conntrack-max-per-core=0 --node-name=server-main --https-listen-port 6443 --tls-san 127.0.0.1 --tls-san 10.110.111.0 --tls-san 192.168.100.102 --disable traefik --node-ip=10.110.111.0"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml
- K3S_KUBECONFIG_MODE=666
- K3S_URL=https://10.110.101.0:6443
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/server-main/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/server-main/log:/var/log
- type: bind
source: /srv/k3s/config/token
target: /token
read_only: true
- /srv/k3s/config:/output
networks:
k3s:
ipv4_address: 10.110.111.0
ports:
- 6443:6443
agent-main:
image: "rancher/k3s:latest"
scale: 3
entrypoint: /entrypoint.sh
command: "agent --kube-proxy-arg=conntrack-max-per-core=0 --node-name=agent-main --with-node-id"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.111.0:6443
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- type: bind
source: /srv/k3s/config/token
target: /token
read_only: true
networks:
k3s:
depends_on:
- server-main
- ingress-main
ingress-main:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "agent --kube-proxy-arg=conntrack-max-per-core=0 --node-name=ingress-main --node-ip=10.110.110.0 --node-taint=ingress:NoSchedule --node-label=ingress=true"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.111.0:6443
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/ingress-main/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/ingress-main/log:/var/log
- type: bind
source: /srv/k3s/config/token
target: /token
read_only: true
network_mode: "host"
depends_on:
- server-main
networks:
k3s:
name: k3s
driver_opts:
com.docker.network.bridge.name: "k3sbr"
ipam:
config:
- subnet: 10.110.0.0/16
ip_range: 10.110.112.0/24
gateway: 10.110.110.0 Fallback: version: "2.4"
services:
server-fallback:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "server --kube-proxy-arg=conntrack-max-per-core=0 --node-name=server-fallback --https-listen-port 6443 --tls-san 127.0.0.1 --tls-san 10.110.121.0 --tls-san 192.168.100.105 --disable traefik --node-ip=10.110.121.0"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml
- K3S_KUBECONFIG_MODE=666
- K3S_URL=https://10.110.101.0:6443
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/server-fallback/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/server-fallback/log:/var/log
- type: bind
source: /srv/k3s/config/token
target: /token
read_only: true
- /srv/k3s/config:/output
networks:
k3s:
ipv4_address: 10.110.121.0
ports:
- 6443:6443
agent-fallback:
image: "rancher/k3s:latest"
scale: 2
entrypoint: /entrypoint.sh
command: "agent --kube-proxy-arg=conntrack-max-per-core=0 --node-name=agent-fallback --with-node-id"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.121.0:6443
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- type: bind
source: /srv/k3s/config/token
target: /token
read_only: true
networks:
k3s:
depends_on:
- server-fallback
- ingress-fallback
ingress-fallback:
image: "rancher/k3s:latest"
entrypoint: /entrypoint.sh
command: "agent --kube-proxy-arg=conntrack-max-per-core=0 --node-name=ingress-fallback --node-ip=10.110.120.0 --node-taint=ingress:NoSchedule --node-label=ingress=true"
tmpfs:
- /run
- /var/run
privileged: true
restart: always
environment:
- K3S_URL=https://10.110.121.0:6443
- K3S_TOKEN_FILE=/token
volumes:
- type: bind
source: /srv/k3s/scripts/entrypoint.sh
target: /entrypoint.sh
read_only: true
- /srv/k3s/data/ingress-fallback/k3s:/var/lib/rancher/k3s
- /srv/k3s/data/ingress-fallback/log:/var/log
- type: bind
source: /srv/k3s/config/token
target: /token
read_only: true
network_mode: "host"
depends_on:
- server-fallback
networks:
k3s:
name: k3s
driver_opts:
com.docker.network.bridge.name: "k3sbr"
ipam:
config:
- subnet: 10.110.0.0/16
ip_range: 10.110.122.0/24
gateway: 10.110.120.0 Now when I disable any of theese 3 hosts separately - the cluster doesn't die. It still dies if 2 out of 3 hosts are dead, but there's probably nothing that can be done about it (although I really expected that the majority quorum would be dynamically recalculated based on available cluster members, not total known) - and it most cases it makes sense (except when one of main/fallback and management are dead - I would expect it to still work in a degraded mode, but because of this majority quorum - it can't). Again, the docker networks are interconnected between themselves with help of a VXLAN (hence why the "com.docker.network.bridge.name" driver opt), and can be connected with help of some kind of a VPN solution to another host across Internet if needed (to join it to the cluster, for example). Now I have a handy management host, it could be used to actually be the gate for the VPN =) |
Beta Was this translation helpful? Give feedback.
Well, my problem was indeed etcd majority problems, so I ended up with 3 KVM hosts, having following setups:
Management: