Skip to content

Commit

Permalink
Utilize ExternalDNS as well as ExternalIP (#1928)
Browse files Browse the repository at this point in the history
  • Loading branch information
nanasi880 authored Jan 26, 2021
1 parent 17bb461 commit 1a39cb3
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 6 deletions.
2 changes: 1 addition & 1 deletion build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ KIND_CONTAINER_NAME=$(KIND_PROFILE)-control-plane
# Game Server image to use while doing end-to-end tests
GS_TEST_IMAGE ?= gcr.io/agones-images/simple-game-server:0.1

ALPHA_FEATURE_GATES ?= "PlayerTracking=true&RollingUpdateOnReady=true"
ALPHA_FEATURE_GATES ?= "PlayerTracking=true&RollingUpdateOnReady=true&NodeExternalDNS=true"

# Directory that this Makefile is in.
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
Expand Down
2 changes: 1 addition & 1 deletion cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ steps:
#

- name: 'e2e-runner'
args: ['PlayerTracking=true&SDKWatchSendOnExecute=false&RollingUpdateOnReady=true', 'e2e-test-cluster']
args: ['PlayerTracking=true&SDKWatchSendOnExecute=false&RollingUpdateOnReady=true&NodeExternalDNS=true', 'e2e-test-cluster']
id: e2e-feature-gates
waitFor:
- push-images
Expand Down
29 changes: 25 additions & 4 deletions pkg/gameservers/gameservers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"net"

agonesv1 "agones.dev/agones/pkg/apis/agones/v1"
"agones.dev/agones/pkg/util/runtime"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -34,19 +35,39 @@ func isGameServerPod(pod *corev1.Pod) bool {
return false
}

// address returns the IP that the given Pod is run on.
// This will default to the ExternalIP, but if the ExternalIP is
// not set, it will fall back to the InternalIP,
// address returns the network address that the given Pod is run on.
// This will default to the ExternalDNS, but if the ExternalDNS is
// not set, it will fall back to the ExternalIP then InternalDNS then InternalIP,
// If externalDNS is false, skip ExternalDNS and InternalDNS.
// since we can have clusters that are private, and/or tools like minikube
// that only report an InternalIP.
func address(node *corev1.Node) (string, error) {

externalDNS := runtime.FeatureEnabled(runtime.NodeExternalDNS)

if externalDNS {
for _, a := range node.Status.Addresses {
if a.Type == corev1.NodeExternalDNS {
return a.Address, nil
}
}
}

for _, a := range node.Status.Addresses {
if a.Type == corev1.NodeExternalIP && net.ParseIP(a.Address) != nil {
return a.Address, nil
}
}

// There might not be a public IP, so fall back to the private IP
// There might not be a public DNS/IP, so fall back to the private DNS/IP
if externalDNS {
for _, a := range node.Status.Addresses {
if a.Type == corev1.NodeInternalDNS {
return a.Address, nil
}
}
}

for _, a := range node.Status.Addresses {
if a.Type == corev1.NodeInternalIP && net.ParseIP(a.Address) != nil {
return a.Address, nil
Expand Down
28 changes: 28 additions & 0 deletions pkg/gameservers/gameservers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"testing"

agonesv1 "agones.dev/agones/pkg/apis/agones/v1"
"agones.dev/agones/pkg/util/runtime"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -47,6 +48,7 @@ func TestAddress(t *testing.T) {
fixture := map[string]struct {
node *corev1.Node
expectedAddress string
featureFlags string
}{
"node with external ip": {
node: &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: nodeFixtureName}, Status: corev1.NodeStatus{Addresses: []corev1.NodeAddress{{Address: "12.12.12.12", Type: corev1.NodeExternalIP}}}},
Expand All @@ -64,13 +66,39 @@ func TestAddress(t *testing.T) {
}}},
expectedAddress: "9.9.9.8",
},
"node with external and internal dns": {
node: &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: nodeFixtureName},
Status: corev1.NodeStatus{Addresses: []corev1.NodeAddress{
{Address: "external.example.com", Type: corev1.NodeExternalDNS},
{Address: "internal.example.com", Type: corev1.NodeInternalDNS},
}}},
expectedAddress: "external.example.com",
featureFlags: "NodeExternalDNS=true",
},
"node with external and internal dns without feature flag": {
node: &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: nodeFixtureName},
Status: corev1.NodeStatus{Addresses: []corev1.NodeAddress{
{Address: "external.example.com", Type: corev1.NodeExternalDNS},
{Address: "internal.example.com", Type: corev1.NodeInternalDNS},
{Address: "9.9.9.8", Type: corev1.NodeExternalIP},
{Address: "12.12.12.12", Type: corev1.NodeInternalIP},
}}},
expectedAddress: "9.9.9.8",
featureFlags: "NodeExternalDNS=false",
},
}

dummyGS := &agonesv1.GameServer{}
dummyGS.Name = "some-gs"

runtime.FeatureTestMutex.Lock()
defer runtime.FeatureTestMutex.Unlock()

for name, fixture := range fixture {
t.Run(name, func(t *testing.T) {
err := runtime.ParseFeatures(fixture.featureFlags)
assert.NoError(t, err)

addr, err := address(fixture.node)
require.NoError(t, err)
assert.Equal(t, fixture.expectedAddress, addr)
Expand Down
4 changes: 4 additions & 0 deletions pkg/util/runtime/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ const (
// FeatureRollingUpdateOnReady is a feature flag to enable/disable rolling update fix of scale down, when ReadyReplicas
// count is taken into account
FeatureRollingUpdateOnReady Feature = "RollingUpdateOnReady"

// NodeExternalDNS is a feature flag to enable/disable node ExternalDNS and InternalDNS use as GameServer address
NodeExternalDNS Feature = "NodeExternalDNS"
)

var (
Expand All @@ -51,6 +54,7 @@ var (
FeaturePlayerTracking: false,
FeatureSDKWatchSendOnExecute: true,
FeatureRollingUpdateOnReady: false,
NodeExternalDNS: false,
}

// featureGates is the storage of what features are enabled
Expand Down
10 changes: 10 additions & 0 deletions site/content/en/docs/FAQ/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ Each `GameServer` inherits the IP Address of the Node on which it resides. If it
the Node (which it should if it's a publicly addressable Node), that it utilised, otherwise it falls back to using the
`InternalIP` address.

{{% feature publishVersion="1.12.0" %}}
### How do I use the DNS name of the Node?
[You can make this available by using the feature flag.]({{< ref "/docs/Guides/feature-stages.md" >}})
Agones uses an IP address as the game server address by default.
This works fine in most cases, but can be a problem if your game server and game client are running on different IP protocols.
e.g) The game server is connected only to the IPv4 network, and the game client is connected only to the IPv6 network.
When this feature is enabled, Agones will preferentially use the External DNS of the Node on which the GameServer Pod is running.
Since the game client can get the domain name instead of the IP address, it will be able to communicate with the game server via DNS64 and NAT64.
{{% /feature %}}

### How is traffic routed from the allocated Port to the GameServer container?

Traffic is routed to the GameServer Container utilising the `hostPort` field on a
Expand Down
1 change: 1 addition & 0 deletions site/content/en/docs/Guides/feature-stages.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The current set of `alpha` and `beta` feature gates are:
| [Player Tracking]({{< ref "/docs/Guides/player-tracking.md" >}}) | `PlayerTracking` | Disabled | `Alpha` | 1.6.0 |
| [SDK Send GameServer on Watch execution]({{< ref "/docs/Guides/Client SDKs/_index.md#watchgameserverfunctiongameserver" >}}) | `SDKWatchSendOnExecute` | Enabled | `Beta` | 1.12.0 |
| Fix for RollingUpdate [Scale down](https://github.com/googleforgames/agones/issues/1625) and additional [details]({{< ref "/docs/Guides/fleet-updates.md#alpha-feature-rollingupdateonready" >}}) | `RollingUpdateOnReady` | Disabled | `Alpha` | 1.9.0 |
| [Utilize Node ExternalDNS](https://github.com/googleforgames/agones/issues/1921) and additional [details]({{< ref "/docs/FAQ/_index.md" >}}) | `NodeExternalDNS` | Disabled | `Alpha` | 1.12.0 |
{{% /feature %}}
## Description of Stages

Expand Down

0 comments on commit 1a39cb3

Please sign in to comment.