mirror of
https://github.com/bingohuang/docker-labs.git
synced 2025-07-14 18:27:25 +08:00
Show docker swarm used ports
This commit is contained in:
parent
a7811b4e33
commit
69050373d7
@ -1,6 +1,8 @@
|
|||||||
FROM docker:1.13.0-rc2-dind
|
FROM docker:1.13.0-rc2-dind
|
||||||
|
|
||||||
ENV DOCKER_STORAGE_DRIVER=overlay2
|
ARG docker_storage_driver=overlay2
|
||||||
|
|
||||||
|
ENV DOCKER_STORAGE_DRIVER=${docker-storage-driver}
|
||||||
|
|
||||||
RUN apk add --no-cache git tmux py-pip apache2-utils vim build-base gettext-dev curl bash
|
RUN apk add --no-cache git tmux py-pip apache2-utils vim build-base gettext-dev curl bash
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ services:
|
|||||||
# use the latest golang image
|
# use the latest golang image
|
||||||
image: golang
|
image: golang
|
||||||
# go to the right place and starts the app
|
# go to the right place and starts the app
|
||||||
command: /bin/sh -c 'cd /go/src/github.com/franela/play-with-docker; go run -race api.go'
|
command: /bin/sh -c 'cd /go/src/github.com/franela/play-with-docker; go run api.go'
|
||||||
ports:
|
ports:
|
||||||
# app exposes port 3000
|
# app exposes port 3000
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
type broadcastInfoTask struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *broadcastInfoTask) Run(i *Instance) {
|
|
||||||
wsServer.BroadcastTo(i.session.Id, "instance stats", i.Name, i.Mem, i.Cpu, i.IsManager, i.Ports)
|
|
||||||
}
|
|
@ -1,6 +1,10 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import "github.com/docker/docker/api/types/swarm"
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
)
|
||||||
|
|
||||||
type checkSwarmStatusTask struct {
|
type checkSwarmStatusTask struct {
|
||||||
}
|
}
|
||||||
@ -12,6 +16,8 @@ func (c checkSwarmStatusTask) Run(i *Instance) {
|
|||||||
} else {
|
} else {
|
||||||
i.IsManager = nil
|
i.IsManager = nil
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
15
services/check_swarm_used_ports.go
Normal file
15
services/check_swarm_used_ports.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
type checkSwarmUsedPortsTask struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c checkSwarmUsedPortsTask) Run(i *Instance) {
|
||||||
|
if i.IsManager != nil && *i.IsManager {
|
||||||
|
// This is a swarm manager instance, then check for ports
|
||||||
|
if err := SetInstanceSwarmPorts(i); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,8 @@ type checkUsedPortsTask struct {
|
|||||||
|
|
||||||
func (c checkUsedPortsTask) Run(i *Instance) {
|
func (c checkUsedPortsTask) Run(i *Instance) {
|
||||||
if ports, err := GetUsedPorts(i); err == nil {
|
if ports, err := GetUsedPorts(i); err == nil {
|
||||||
i.Ports = ports
|
for _, p := range ports {
|
||||||
|
i.setUsedPort(p)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
@ -46,6 +47,55 @@ func GetDaemonInfo(i *Instance) (types.Info, error) {
|
|||||||
}
|
}
|
||||||
return i.dockerClient.Info(context.Background())
|
return i.dockerClient.Info(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetInstanceSwarmPorts(i *Instance) error {
|
||||||
|
if i.dockerClient == nil {
|
||||||
|
return fmt.Errorf("Docker client for DinD (%s) is not ready", i.IP)
|
||||||
|
}
|
||||||
|
|
||||||
|
hostnamesIdx := map[string]*Instance{}
|
||||||
|
for _, ins := range i.session.Instances {
|
||||||
|
hostnamesIdx[ins.Hostname] = ins
|
||||||
|
}
|
||||||
|
|
||||||
|
nodesIdx := map[string]*Instance{}
|
||||||
|
nodes, nodesErr := i.dockerClient.NodeList(context.Background(), types.NodeListOptions{})
|
||||||
|
if nodesErr != nil {
|
||||||
|
return nodesErr
|
||||||
|
}
|
||||||
|
for _, n := range nodes {
|
||||||
|
nodesIdx[n.ID] = hostnamesIdx[n.Description.Hostname]
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks, err := i.dockerClient.TaskList(context.Background(), types.TaskListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
services := map[string][]uint16{}
|
||||||
|
for _, t := range tasks {
|
||||||
|
services[t.ServiceID] = []uint16{}
|
||||||
|
}
|
||||||
|
for serviceID, _ := range services {
|
||||||
|
s, _, err := i.dockerClient.ServiceInspectWithRaw(context.Background(), serviceID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, p := range s.Endpoint.Ports {
|
||||||
|
services[serviceID] = append(services[serviceID], uint16(p.PublishedPort))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, t := range tasks {
|
||||||
|
for _, n := range nodes {
|
||||||
|
ins := nodesIdx[n.ID]
|
||||||
|
for _, p := range services[t.ServiceID] {
|
||||||
|
ins.setUsedPort(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetUsedPorts(i *Instance) ([]uint16, error) {
|
func GetUsedPorts(i *Instance) ([]uint16, error) {
|
||||||
if i.dockerClient == nil {
|
if i.dockerClient == nil {
|
||||||
return nil, fmt.Errorf("Docker client for DinD (%s) is not ready", i.IP)
|
return nil, fmt.Errorf("Docker client for DinD (%s) is not ready", i.IP)
|
||||||
@ -84,7 +134,7 @@ func CreateNetwork(name string) error {
|
|||||||
func ConnectNetwork(containerId, networkId string) error {
|
func ConnectNetwork(containerId, networkId string) error {
|
||||||
err := c.NetworkConnect(context.Background(), networkId, containerId, &network.EndpointSettings{})
|
err := c.NetworkConnect(context.Background(), networkId, containerId, &network.EndpointSettings{})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil && !strings.Contains(err.Error(), "already exists") {
|
||||||
log.Printf("Connection container to network err [%s]\n", err)
|
log.Printf("Connection container to network err [%s]\n", err)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -28,6 +28,19 @@ type Instance struct {
|
|||||||
Mem string `json:"mem"`
|
Mem string `json:"mem"`
|
||||||
Cpu string `json:"cpu"`
|
Cpu string `json:"cpu"`
|
||||||
Ports []uint16 `json:"ports"`
|
Ports []uint16 `json:"ports"`
|
||||||
|
tempPorts []uint16 `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Instance) setUsedPort(port uint16) {
|
||||||
|
rw.Lock()
|
||||||
|
defer rw.Unlock()
|
||||||
|
|
||||||
|
for _, p := range i.tempPorts {
|
||||||
|
if p == port {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i.tempPorts = append(i.tempPorts, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Instance) IsConnected() bool {
|
func (i *Instance) IsConnected() bool {
|
||||||
|
@ -94,6 +94,12 @@ func (s *Session) SchedulePeriodicTasks() {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
// broadcast all information
|
||||||
|
for _, ins := range s.Instances {
|
||||||
|
ins.Ports = ins.tempPorts
|
||||||
|
ins.tempPorts = []uint16{}
|
||||||
|
wsServer.BroadcastTo(ins.session.Id, "instance stats", ins.Name, ins.Mem, ins.Cpu, ins.IsManager, ins.Ports)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -123,7 +129,9 @@ func CloseSession(s *Session) error {
|
|||||||
s.rw.Lock()
|
s.rw.Lock()
|
||||||
defer s.rw.Unlock()
|
defer s.rw.Unlock()
|
||||||
|
|
||||||
s.ticker.Stop()
|
if s.ticker != nil {
|
||||||
|
s.ticker.Stop()
|
||||||
|
}
|
||||||
wsServer.BroadcastTo(s.Id, "session end")
|
wsServer.BroadcastTo(s.Id, "session end")
|
||||||
log.Printf("Starting clean up of session [%s]\n", s.Id)
|
log.Printf("Starting clean up of session [%s]\n", s.Id)
|
||||||
for _, i := range s.Instances {
|
for _, i := range s.Instances {
|
||||||
@ -238,6 +246,13 @@ func LoadSessionsFromDisk() error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Connect PWD daemon to the new network
|
||||||
|
if err := ConnectNetwork("pwd", s.Id); err != nil {
|
||||||
|
log.Println("ERROR NETWORKING")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Printf("Connected pwd to network [%s]\n", s.Id)
|
||||||
|
|
||||||
// Schedule peridic tasks execution
|
// Schedule peridic tasks execution
|
||||||
s.SchedulePeriodicTasks()
|
s.SchedulePeriodicTasks()
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ type periodicTask interface {
|
|||||||
var periodicTasks []periodicTask
|
var periodicTasks []periodicTask
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
periodicTasks = append(periodicTasks, &collectStatsTask{}, &checkSwarmStatusTask{}, &checkUsedPortsTask{}, &broadcastInfoTask{})
|
periodicTasks = append(periodicTasks, &collectStatsTask{}, &checkSwarmStatusTask{}, &checkUsedPortsTask{}, &checkSwarmUsedPortsTask{})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user