Published on

Docker Swarm

Authors
  • Name
    Jackson Chen

Docker Swarm

https://docs.docker.com/engine/swarm/

Docker Hub

https://hub.docker.com/

Docker Hub Registry

https://www.docker.com/products/docker-hub/

Docker swarm is the docker manager, that manages nodes, service, network, etc

# docker swarm
Swarm discovery service  - key/value pair  (ensure high availability)
- console

Support a pluggable backend  (ensure high availability)
consul
etcd
zookeeper
docker hub

"LIBVKV" - abstract layer

# Swarm Manager
. Required to administer and program the cluster
. Support HA
- 1 x primary (sends all commands to the cluster)
- N x secondary's (proxies commands to Primary)
  Note: automatically take over in the even of the primary goes down


# Filtering and Scheduling
1. Filtering
. Clients asks for container to be deployed
. Swarm Manager then generates a list of nodes that are appropriate for this container

2. Schedule
. Take that list of possible nodes from the filter
. Schedule a deployment

# command
docker run ...

# Filter Types
. Affinity
    - Run new containers on the same node as the existing containers
    - Run new conainters on any node that has this image pulled locally
. Resource
    - Run new containers on nodes with particular resource free
        Example: node that has port 443 available
. Constraint
    - Standard: filter based on data any field that is returned from the docker info command
    - Custom: labels assigned to engine daemons (same as "tag")

# Example docker command
sudo docker info

chmod 400 swarm-demo.pem
ssh -i "swarm-demo.pem" devops@<swarm-master-fqdn>  # connect to swarm master

# ubuntu master node
sudo apt-get update -y  # install update

# install docker
docker  # verify docker installation
curl -ssl https://get.docker.com | bash     # install docker, it will install docker compose and docker swarm components

docker ps   # you may get permission deny error
    # it will show container information
    CONTAINER ID    IMAGE   COMMAND     CREATED     STATUS      PORTS       NAMES
sudo usermod -aG docker ubuntu
docker swarm init
docker swarm join --token <token> <swarm-master/manager-ip>:2377
docker node list
docker info # verify docker information, such as version

docker run -it -d --name nginx -p 80:80 nginx   # It will download and run the container if not exist
    docker ps
    # Then, need to open required firewall port for external access

docker logs <container-id>  # check the logs

docker images ls    # list all docker images
    REPOSITORY  TAG IMAGE ID    CREATED     SIZE

# Down/add docker image
docker pull <image-name>    # without version numbet, it will download the latest version
docker pull <image-name>:<version-number>   # Example,  docker pull alpine:3.18.2

# Verify the image information from "docker hub" website
https://hub.docker.com

# download / run "httpd" or "apache"
docker run -it -d httpd


# To stop the container
docker stop <container-id>
docker ps   # verify the running containers
docker ps -a    # show all containers, including stopped container

# remove the container
docker rm <container-id>

# ******** Docker compose
Docker compose is the tool to run multiple containers

# create a docker compose yaml file
# cat docker-compose.yaml
version: "3.9"
services:
  web:
    image: nginx
    port:
      - "80:80"
  redis:
    image: "redis:alpine"
    volumes:
      - ./demo:/code


# verify docker compose container
docker compose ps
    NAME    IMAGE       COMMAND     SERVICE     CREATED     STATUS      PORTS

# run docker compose container, "-d" detach mode
docker compose up -d    # It will create the docker container with "docker-compose.yaml" file
docker compose ps   # verify


# shutdown the docker compose container
docker compose down -v  # "v" verbose
docker compose ps   # verify
docker stop <container-id>
docker rm <container-id>    # clean up


# ********* How to initialise docker swarm
docker swarm init   # run on docker master node
    Note: note the output, and the token. The token is requried for node to join swarm cluster
Swarm initialized: current node (node-id> is now a manager.
To add a worker to this swarm, run the following command
    docker swarm join -token <token> <master-ip>:<port>

Note:
1. Need to open the master manager TCP port for other nodes to join
2.a It will need to run update
    sudo apt-get update -y
2.b Then, install docker
    curl -ssl https://get.docker.com | bash
2.c Update permission
    sudo usermod -aG docker ubuntu
3. Join docker swarm manager/cluster
    docker swarm join --token <token-id> <master/manager IP>:2377
    Result:
        This node joined a swarm as a workder.
4. Verify docker swarm nodes
    docker node ls  
5. Verify docker node info
    docker n


# list docker nodes
docker node ls
    ID  HOSTNAME    STATUS      AVAILABILITY    MANAGER     STATUS      ENGINE      VERSION
                                Leader  <----- lead/active manager
# inspect docker nodes
docker node inspect <node-id>   # it will show the information about <node-id>



To add a manager to this swarm, run
    docker swarm join-token manager


#----------------------

docker node ls
docker node --help
docker swarm --help
docker service --help
docker node promote node_name
# ---------------------

docker swarm leave
docker swarm leave --force
    # when run in the worker node, the node will leave docker swarm
    # if check from master/manager node, it will show the node is "down"
    # To completely remove it from docker swarm, run "docker node rm <node-id>, after leave docker swarm

# Docker commands
docker events --since 4h
docker events --since 10m

# only show swarm related events
docker events --since 1h --filter scope=swarm --filter type=network

#-------- docker config -----------
docker config create nginx ./nginx.conf
docker config ls
docker config inspect nginx
docker config rm nginx
docker service create --config source=nginx, target=/etc/nginx/nginx.conf

#--------- smwarm volumes --------------------------
docker service update --mount-add type=volume, source=my-volume, target=/apps test
docker service inspect --pretty test
docker service create --mount add type=volume, source=my-volume, target=/apps test1 nginx

#----------- bind mount -----------------------
docker service create --mount-add type=bind, source=./, target=/apps test1 nginx

#------------- global mode ------------
docker service create --name myservice --mode global nginx


# ------- docker service
docker service create --replicas 3 --publish 80:80 nginx
docker service ls
docker service rm <service-name> or id  <--------- delete service-id, it will delete the containers
docker service inspect --pretty service-id
docker service ps   <--------- it will show the container is running on which node
docker service ps service-id
docker service scale service-id=4   # add docker container
docker service update --image nginx:1.9.5 service-name


#------ docker stack ------------
docker stack deploy -c filename.yaml stack-name
docker stack ls

# -------- docker event
docker event --since 5m     # h   <----------- debug, troubleshooting application


#-------------- How to add new master node
1. create a new master node instance
2. Run update
    sudo apt-get update -y
3. Install docker
    curl -ssl https://get.docker.com | bash
4. Grant permission
    sudo usermod -aG docker ubuntu
5. Joint docker swarm as manager    <----- run on the existing manager node
    docker swarm join-token manager     # It will output token id
        # example
            docker swarm join --token <token-id> <manager-ip>:<port>

Note:
If need to join another worker node, to obtain the worker join-token
    docker swarm join-token worker

6. Run the docker swarm join in the new manager node (ssh to the new manager node)
a. Run/verify
    docker node ls  # Error, this node is not a swarm manager
b. Update firewall rule, add the <port>
c. Join as manager
    docker swarm join --token <manager-join-token-id> <manager-ip>:<port>
        Note: output - This node joined a swarm as a manager


#----------------- Docker overlay network -----------------
docker network create --driver overlay demo-network
docker service create --replicas 3 --network demo-network --name test nginx

--- to add existing network ---
docker service update --network-add demo-network test

-- to remove network --
docker service update --network-rm demo-network test

# check docker network
    docker network ls
        NETWORK ID  NAME    DRIVER      SCOPE
                    overlay     swarm

Where:
    Driver: bridge, host, overlay, null network type

# command
docker network create --driver overlay <name>
    Example: docker network create --driver overlay demo-network

docker network inspect <network-id>|<name>


# Create container replica on the required overlay network
docker service create --replica <number> --network <overlay-network-name> --name <service-name> <image-to-use>

Example:
    docker service create --replica 3 --network demo-network --name mynewnetwork nginx

docker network ls   # verify the result

docker service inspect --pretty <service-name>
    docker service inspect --pretty mynewnetwork


# How to add new network to existing service
1. verify the networks
docker network ls

2. Update the network
docker service update --network-add <new-network-name> <service-name>
    docker service update --network-add demo-network demo

3. Verfiy update
docker service inspect --pretty <service-name>
    docker service inspect --pretty demo
    docker service ls

List all docker services and docker nodes where docker service is running

# ssh to docker swarm controller or manager node
docker node ps $(docker node ls -q)
docker servie ls        # lis all running docker services