Signed-off-by: Dong Chen <dongluo.chen@docker.com>
| ... | ... |
@@ -27,6 +27,8 @@ type Backend interface {
|
| 27 | 27 |
ContainerStart(name string, hostConfig *container.HostConfig, validateHostname bool, checkpoint string, checkpointDir string) error |
| 28 | 28 |
ContainerStop(name string, seconds *int) error |
| 29 | 29 |
ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error |
| 30 |
+ ActivateContainerServiceBinding(containerName string) error |
|
| 31 |
+ DeactivateContainerServiceBinding(containerName string) error |
|
| 30 | 32 |
UpdateContainerServiceConfig(containerName string, serviceConfig *clustertypes.ServiceConfig) error |
| 31 | 33 |
ContainerInspectCurrent(name string, size bool) (*types.ContainerJSON, error) |
| 32 | 34 |
ContainerWaitWithContext(ctx context.Context, name string) error |
| ... | ... |
@@ -331,6 +331,14 @@ func (c *containerAdapter) createVolumes(ctx context.Context) error {
|
| 331 | 331 |
return nil |
| 332 | 332 |
} |
| 333 | 333 |
|
| 334 |
+func (c *containerAdapter) activateServiceBinding() error {
|
|
| 335 |
+ return c.backend.ActivateContainerServiceBinding(c.container.name()) |
|
| 336 |
+} |
|
| 337 |
+ |
|
| 338 |
+func (c *containerAdapter) deactivateServiceBinding() error {
|
|
| 339 |
+ return c.backend.DeactivateContainerServiceBinding(c.container.name()) |
|
| 340 |
+} |
|
| 341 |
+ |
|
| 334 | 342 |
// todo: typed/wrapped errors |
| 335 | 343 |
func isContainerCreateNameConflict(err error) bool {
|
| 336 | 344 |
return strings.Contains(err.Error(), "Conflict. The name") |
| ... | ... |
@@ -183,6 +183,10 @@ func (r *controller) Start(ctx context.Context) error {
|
| 183 | 183 |
|
| 184 | 184 |
// no health check |
| 185 | 185 |
if ctnr.Config == nil || ctnr.Config.Healthcheck == nil {
|
| 186 |
+ if err := r.adapter.activateServiceBinding(); err != nil {
|
|
| 187 |
+ log.G(ctx).WithError(err).Errorf("failed to activate service binding for container %s which has no healthcheck config", r.adapter.container.name())
|
|
| 188 |
+ return err |
|
| 189 |
+ } |
|
| 186 | 190 |
return nil |
| 187 | 191 |
} |
| 188 | 192 |
|
| ... | ... |
@@ -225,6 +229,10 @@ func (r *controller) Start(ctx context.Context) error {
|
| 225 | 225 |
// set health check error, and wait for container to fully exit ("die" event)
|
| 226 | 226 |
healthErr = ErrContainerUnhealthy |
| 227 | 227 |
case "health_status: healthy": |
| 228 |
+ if err := r.adapter.activateServiceBinding(); err != nil {
|
|
| 229 |
+ log.G(ctx).WithError(err).Errorf("failed to activate service binding for container %s after healthy event", r.adapter.container.name())
|
|
| 230 |
+ return err |
|
| 231 |
+ } |
|
| 228 | 232 |
return nil |
| 229 | 233 |
} |
| 230 | 234 |
case <-ctx.Done(): |
| ... | ... |
@@ -290,6 +298,12 @@ func (r *controller) Shutdown(ctx context.Context) error {
|
| 290 | 290 |
r.cancelPull() |
| 291 | 291 |
} |
| 292 | 292 |
|
| 293 |
+ // remove container from service binding |
|
| 294 |
+ if err := r.adapter.deactivateServiceBinding(); err != nil {
|
|
| 295 |
+ log.G(ctx).WithError(err).Errorf("failed to deactivate service binding for container %s", r.adapter.container.name())
|
|
| 296 |
+ return err |
|
| 297 |
+ } |
|
| 298 |
+ |
|
| 293 | 299 |
if err := r.adapter.shutdown(ctx); err != nil {
|
| 294 | 300 |
if isUnknownContainer(err) || isStoppedContainer(err) {
|
| 295 | 301 |
return nil |
| ... | ... |
@@ -719,6 +719,13 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName |
| 719 | 719 |
return err |
| 720 | 720 |
} |
| 721 | 721 |
|
| 722 |
+ if !container.Managed {
|
|
| 723 |
+ // add container name/alias to DNS |
|
| 724 |
+ if err := daemon.ActivateContainerServiceBinding(container.Name); err != nil {
|
|
| 725 |
+ return fmt.Errorf("Activate container service binding for %s failed: %v", container.Name, err)
|
|
| 726 |
+ } |
|
| 727 |
+ } |
|
| 728 |
+ |
|
| 722 | 729 |
if err := container.UpdateJoinInfo(n, ep); err != nil {
|
| 723 | 730 |
return fmt.Errorf("Updating join info failed: %v", err)
|
| 724 | 731 |
} |
| ... | ... |
@@ -987,3 +994,29 @@ func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, netw |
| 987 | 987 |
} |
| 988 | 988 |
return nil |
| 989 | 989 |
} |
| 990 |
+ |
|
| 991 |
+// ActivateContainerServiceBinding puts this container into load balancer active rotation and DNS response |
|
| 992 |
+func (daemon *Daemon) ActivateContainerServiceBinding(containerName string) error {
|
|
| 993 |
+ container, err := daemon.GetContainer(containerName) |
|
| 994 |
+ if err != nil {
|
|
| 995 |
+ return err |
|
| 996 |
+ } |
|
| 997 |
+ sb := daemon.getNetworkSandbox(container) |
|
| 998 |
+ if sb == nil {
|
|
| 999 |
+ return fmt.Errorf("network sandbox not exists for container %s", containerName)
|
|
| 1000 |
+ } |
|
| 1001 |
+ return sb.EnableService() |
|
| 1002 |
+} |
|
| 1003 |
+ |
|
| 1004 |
+// DeactivateContainerServiceBinding remove this container fromload balancer active rotation, and DNS response |
|
| 1005 |
+func (daemon *Daemon) DeactivateContainerServiceBinding(containerName string) error {
|
|
| 1006 |
+ container, err := daemon.GetContainer(containerName) |
|
| 1007 |
+ if err != nil {
|
|
| 1008 |
+ return err |
|
| 1009 |
+ } |
|
| 1010 |
+ sb := daemon.getNetworkSandbox(container) |
|
| 1011 |
+ if sb == nil {
|
|
| 1012 |
+ return fmt.Errorf("network sandbox not exists for container %s", containerName)
|
|
| 1013 |
+ } |
|
| 1014 |
+ return sb.DisableService() |
|
| 1015 |
+} |
| ... | ... |
@@ -178,6 +178,10 @@ func (daemon *Daemon) SetupIngress(create clustertypes.NetworkCreateRequest, nod |
| 178 | 178 |
if err := ep.Join(sb, nil); err != nil {
|
| 179 | 179 |
logrus.Errorf("Failed joining ingress sandbox to ingress endpoint: %v", err)
|
| 180 | 180 |
} |
| 181 |
+ |
|
| 182 |
+ if err := sb.EnableService(); err != nil {
|
|
| 183 |
+ logrus.WithError(err).Error("Failed enabling service for ingress sandbox")
|
|
| 184 |
+ } |
|
| 181 | 185 |
}() |
| 182 | 186 |
|
| 183 | 187 |
return nil |