Docker/Infrastruktūras dokumentācija un receptes

From Mana zināšanu grāmata
Revision as of 08:17, 8 October 2018 by Kaspars (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Docker management servera instalācija

Sagatavošana

Izveidojam uz visiem serveriem nepieciešamos vides mainīgos, kas jāpielāgo attiecīgajai videi:

export CLUSTER_SERVER1=vafldckr25
export CLUSTER_DOMAIN=zzdats.lv

Izveidojam uz visiem serveriem nepieciešamos automātiski aprēķināmos vides mainīgos:

export HOSTNAME_IP=$(ip route get 8.8.8.8 | tr -s ' ' | cut -d' ' -f7 | tr -s '\n')
export CLUSTER_SERVER1_IP=$(getent hosts $CLUSTER_SERVER1.$CLUSTER_DOMAIN | awk '{ print $1 }')

Instalācija

Instalējam atjauninājumus

apt-get -y update
apt-get -y dist-upgrade
apt-get -y autoremove
apt-get install curl gnupg software-properties-common -y

Instalējam Docker CE

add-apt-repository    "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get -y install docker-ce unzip
curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

Konfigurācija

Pamata konfigurācijai izpildam:

cat >/etc/docker/daemon.json <<EOL
{
    "graph": "/srv/docker",
    "storage-driver": "overlay2",
    "icc": false,
    "disable-legacy-registry": true,
    "userland-proxy": false,
    "no-new-privileges": false
}
EOL

 

rm -rf /var/lib/docker/*
echo "vm.max_map_count=262144" > /etc/sysctl.d/00-elastic.conf
sysctl -w vm.max_map_count=262144
systemctl restart docker
docker swarm init --advertise-addr $HOSTNAME_IP

Vadības un starpniekservera servisu uzstādīšana

Instalējam iekšējo HaProxy servisu

Augšupielādējam failu ssl_cert.key, kas satur PEM formatā privāto un publisko sertifikāta atslēgu, ko izmantot HTTPS.

Izpildam uz servera komandu:

docker secret create ssl_cert_key ssl_cert.key

 

version: '3.5'
services:
  proxy:
    image: dockerflow/docker-flow-proxy:latest
    ports:
      - 80:80
      - 443:443
    networks:
      - proxy
    environment:
      - LISTENER_ADDRESS=swarm-listener
      - MODE=swarm
      - STATS_USER=admin
      - STATS_PASS=oSFDHjI4s3Wa
      - HTTPS_ONLY=true
    deploy:
      mode: global
      resources:
        limits:
          cpus: '0.2'
          memory: '128M'
      restart_policy:
        condition: on-failure
        delay: 1s
    depends_on:
      - swarm-listener
    secrets:
      - source: "ssl_cert_key"
        target: "cert-mgmt.pem"      
  swarm-listener:
    image: dockerflow/docker-flow-swarm-listener:latest
    networks:
      - proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DF_NOTIFY_CREATE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/reconfigure
      - DF_NOTIFY_REMOVE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/remove
    deploy:
      placement:
        constraints: [node.role == manager]
      resources:
        limits:
          cpus: '0.2'
          memory: '128M'
      restart_policy:
        condition: on-failure
        delay: 5s
secrets:
  ssl_cert_key:
    external: true
networks:
  proxy:
    name: proxy
 
 

Uz pirmā servera augšupielādējam mgmt-docker-flow-proxy.yml un izpildam komandu:

docker stack deploy -c mgmt-docker-flow-proxy.yml proxy

Instalējam portainer serveri

version: '3.5'
services:
  agent:
    image: portainer/agent
    environment:
      AGENT_CLUSTER_ADDR: tasks.agent
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /srv/docker/volumes:/var/lib/docker/volumes
    networks:
      - portainer_agent
    deploy:
      mode: global
      resources:
        limits:
          cpus: '0.2'
          memory: '128M'
      restart_policy:
        condition: on-failure
        delay: 5s
  portainer:
    image: portainer/portainer
    command: -H tcp://agent:9001 --tlsskipverify
    volumes:
      - portainer:/data
    networks:
      - portainer_agent
      - proxy
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]
      resources:
        limits:
          cpus: '0.2'
          memory: '128M'
      restart_policy:
        condition: on-failure
        delay: 5s
      labels:
        - "traefik.docker.network=proxy"
        - "traefik.frontend.rule=Host:vafl-mgmt-atv.zzdats.lv; PathPrefixStrip: /portainer; PathPrefix: /portainer"
        - "traefik.port=9000"
        - "com.df.notify=true"
        - "com.df.serviceDomain=vafl-mgmt-atv.zzdats.lv"
        - "com.df.servicePath=/portainer"
        - "com.df.reqPathSearchReplace=/portainer,"
        - "com.df.port=9000"
networks:
  portainer_agent:
    driver: overlay
    attachable: true
  proxy:
    external: true
volumes:
  portainer:
 

 

Uz pirmā servera augšupielādējam portainer-server.yml un izpildam komandu:

docker stack deploy -c portainer-server.yml portainer

Management servisu uzstādīšana un konfigurācija

Uzstādām Docker reģistru servisu

Pirms tam jāizveido token parakstīšanas sertifikāts.

Portainer managment serverim pievienojam jaunu konfigurāciju sadaļā pievienojam konfigurācijas (Configs):

RTENOTITLE

server:
  addr: ":5001"
token:
  issuer: "VAFL IS Docker Auth (Pre-production)"
  expiration: 900
  certificate: "/config/sign.crt"
  key: "/run/secrets/docker-registry-sign-certificate-private"
ldap_auth:
  addr: "dcast.ast.zzdats.lv:389"
  tls: none
  bind_dn: CN=vafl_cc-service,OU=VAFL,DC=ast,DC=zzdats,DC=lv
  bind_password_file: /run/secrets/docker-registry-ad-user-password
  base: OU=VAFL,DC=ast,DC=zzdats,DC=lv
  filter: (&(objectCategory=Person)(memberOf=CN=Docker Registry,OU=VAFL,DC=ast,DC=zzdats,DC=lv)(sAMAccountName=${account})(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))
acl:
  - match:
      account: /.+/
    actions: ['*']
 

Pievienojam konfigurāciju ar nosaukumu docker-registry-auth-config un saturu no faila config-auth.yml, kuru pielāgojam attiecīgās vides konfigurācijai (AD serveris, lietotāji).

listen_addr: 0.0.0.0:8000
base_path: /hub/
registry_url: https://vafl-mgmt-atv.zzdats.lv/
verify_tls: true
registry_username: vafl_cc-service
registry_password_file: /run/secrets/docker-registry-ad-user-password
event_listener_token: token
event_retention_days: 7
event_database_driver: sqlite3
event_database_location: data/registry_events.db
cache_refresh_interval: 10
anyone_can_delete: false
# Lietotāji, kam ir atļauts dzēst docker image atzīmes
admins: [vafl_admin]
debug: false
purge_tags_keep_days: 90
purge_tags_keep_count: 2
purge_tags_schedule: '00 00 03 * * *'
 

Pievienojam konfigurāciju ar nosaukumu docker-registry-ui-config un saturu no faila config-ui.yml, kuru pielāgojam attiecīgās vides konfigurācijai (Docker reģistra URL, lietotāji).

  •  

Pievienojam konfigurāciju ar nosaukumu docker-registry-sign-certificate-public un saturā parakstīšanas sertifikāta publisko daļu PEM formātā.

Sadaļā noslēpumi (Secret) pievienojam jaunu noslēpumu:

RTENOTITLE

  •  

Pievienojam noslēpumu ar nosaukumu docker-registry-sign-certificate-private un saturā parakstīšanas sertifikāa privāto daļu PEM formātā.

 

listen_addr: 0.0.0.0:8000
base_path: /hub/
registry_url: https://vafl-mgmt-atv.zzdats.lv/
verify_tls: true
registry_username: vafl_cc-service
registry_password_file: /run/secrets/docker-registry-ad-user-password
event_listener_token: token
event_retention_days: 7
event_database_driver: sqlite3
event_database_location: data/registry_events.db
cache_refresh_interval: 10
anyone_can_delete: false
# Lietotāji, kam ir atļauts dzēst docker image atzīmes
admins: [vafl_admin]
debug: false
purge_tags_keep_days: 90
purge_tags_keep_count: 2
purge_tags_schedule: '00 00 03 * * *'
 

 

Pievienojam konfigurāciju ar nosaukumu docker-registry-ui-config un saturu no faila config-ui.yml, kuru pielāgojam attiecīgās vides konfigurācijai (Docker reģistra URL, lietotāji).

  •  

Pievienojam noslēpumu ar nosaukumu docker-registry-ad-user-password un saturā norādām AD lietotaja, kas norādīts docker-registry-auth-config konfigurācijā, paroli.

Sadaļā steki (Stacks) pievienojam jaunu steku:

RTENOTITLE

version: '3.5'
services:
  auth:
    image: cesanta/docker_auth:1
    volumes:
      - authlog:/logs
      - authconf:/config
    secrets:
      - source: docker-registry-ad-user-password
        target: docker-registry-ad-user-password
      - source: docker-registry-sign-certificate-private
        target: docker-registry-sign-certificate-private
    configs:
      - source: docker-registry-auth-config
        target: /config/auth_config.yml
      - source: docker-registry-sign-certificate-public
        target: /config/sign.crt
    deploy:
      resources:
        limits:
          cpus: '0.2'
          memory: '128M'
      restart_policy:
        condition: on-failure
        delay: 5s
      labels:
        - "com.df.notify=true"
        - "com.df.serviceDomain=vafl-mgmt-atv.zzdats.lv"
        - "com.df.servicePath=/auth"
        - "com.df.port=5001"
    networks:
      - proxy
  registry:
    image: registry:2
    environment:
      - "REGISTRY_AUTH=token"
      - "REGISTRY_AUTH_TOKEN_REALM=https://vafl-mgmt-atv.zzdats.lv/auth"
      - "REGISTRY_AUTH_TOKEN_SERVICE=VAFL IS Docker Registry (Pre-production)"
      - "REGISTRY_AUTH_TOKEN_ISSUER=VAFL IS Docker Auth (Pre-production)"
      - "REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry"
      - "REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/certs/sign.crt"
      - "REGISTRY_STORAGE_DELETE_ENABLED=true"
    volumes:
      - registrydata:/var/lib/registry
      - registrycerts:/certs
    configs:
      - source: docker-registry-sign-certificate-public
        target: /certs/sign.crt
    deploy:
      resources:
        limits:
          cpus: '0.2'
          memory: '128M'
      restart_policy:
        condition: on-failure
        delay: 5s
      labels:
        - "com.df.notify=true"
        - "com.df.serviceDomain=vafl-mgmt-atv.zzdats.lv"
        - "com.df.servicePath=/v2"
        - "com.df.port=5000"
    depends_on:
      - auth
    networks:
      - proxy
  ui:
    image: quiq/docker-registry-ui:latest
    volumes:
      - uidata:/opt/data
    secrets:
      - source: docker-registry-ad-user-password
        target: docker-registry-ad-user-password
    configs:
      - source: docker-registry-ui-config
        target: /opt/config.yml
    deploy:
      resources:
        limits:
          cpus: '0.2'
          memory: '128M'
      restart_policy:
        condition: on-failure
        delay: 5s
      labels:
        - "com.df.notify=true"
        - "com.df.serviceDomain=vafl-mgmt-atv.zzdats.lv"
        - "com.df.servicePath=/hub"
        - "com.df.port=8000"
    depends_on:
      - registry
    networks:
      - proxy
volumes:
  authlog:
  authconf:
  registrydata:
  registrycerts:
  uidata:
networks:
  proxy:
    external: true
configs:
  docker-registry-auth-config:
    external: true
  docker-registry-sign-certificate-public:
    external: true
  docker-registry-ui-config:
    external: true
secrets:
  docker-registry-ad-user-password:
     external: true
  docker-registry-sign-certificate-private:
     external: true
 
  • Pievienojam steku ar nosaukumu docker-registry un definicijā norādām saturu no faila docker-registry.yml.

Pēc tam kad ir piestartējies Docker reģistrs, sadaļa reģistri (Registries) pievienojam jaunu reģistru:

RTENOTITLE

  • Pievienojam jaunu reģistru ar nosaukumu vafl-mgmt-atv.zzdats.lv, adresi vafl-mgmt-atv.zzdats.lv un autorizāciju ar sistēmas lietotāju un paroli.

Docker swarm instalācija

 

Sagatavošana

Izveidojam uz visiem serveriem nepieciešamos vides mainīgos, kas jāpielāgo attiecīgajai videi:

export CLUSTER_SERVER1=vafldckr11
export CLUSTER_SERVER2=vafldckr12
export CLUSTER_SERVER3=vafldckr13
export CLUSTER_SERVER4=vafldckr14
export CLUSTER_DOMAIN=zzdats.lv

Izveidojam uz visiem serveriem nepieciešamos automātiski aprēķināmos vides mainīgos:

export HOSTNAME_IP=$(ip route get 8.8.8.8 | tr -s ' ' | cut -d' ' -f7 | tr -s '\n')
export CLUSTER_SERVER1_IP=$(getent hosts $CLUSTER_SERVER1.$CLUSTER_DOMAIN | awk '{ print $1 }')
export CLUSTER_SERVER2_IP=$(getent hosts $CLUSTER_SERVER2.$CLUSTER_DOMAIN | awk '{ print $1 }')
export CLUSTER_SERVER3_IP=$(getent hosts $CLUSTER_SERVER3.$CLUSTER_DOMAIN | awk '{ print $1 }')
export CLUSTER_SERVER4_IP=$(getent hosts $CLUSTER_SERVER4.$CLUSTER_DOMAIN | awk '{ print $1 }')

Instalācija

Instalējam atjauninājumus

apt-get -y update
apt-get -y dist-upgrade
apt-get -y autoremove

Instalējam Docker CE

add-apt-repository    "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get -y install docker-ce unzip
curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

Konfigurācija

Pamata konfigurācijai izpildam:

cat >/etc/docker/daemon.json <<EOL
{
    "graph": "/srv/docker",
    "storage-driver": "overlay2",
    "icc": false,
    "disable-legacy-registry": true,
    "userland-proxy": false,
    "no-new-privileges": true
}
EOL

 

rm -rf /var/lib/docker/*
echo "vm.max_map_count=262144" > /etc/sysctl.d/00-elastic.conf
sysctl -w vm.max_map_count=262144
systemctl restart docker

Izveidojam Docker Swarm klāsteri

Uz pirmā servera izpildām:

docker swarm init --advertise-addr $HOSTNAME_IP
docker swarm join-token manager

Šo komandu izpildes rezultātā konsolē tiks izdrukāts Docker swarm klāstera pievienošanāš talons (piemmēram, SWMTKN-...), kas nepieciešams nākošajā solī.

Pārējos serveros izpildām komandu:

docker swarm join --token <token> $CLUSTER_SERVER1_IP:2377

Docker Swarm klāstera izveide

Uz pirmā servera izpildām komandas:

docker node demote $(docker node ls -f "name=$CLUSTER_SERVER4" --format "Template:.ID")
docker node update --label-add lv.zzdats.vaflis.backoffice=true $(docker node ls -f "name=$CLUSTER_SERVER4" --format "Template:.ID")
docker node update --label-add lv.zzdats.vaflis.queueserver=true $(docker node ls -f "name=$CLUSTER_SERVER2" --format "Template:.ID")
docker node update --label-add lv.zzdats.vaflis.maindb=true $(docker node ls -f "name=$CLUSTER_SERVER3" --format "Template:.ID")
docker node update --label-add lv.zzdats.vaflis.elastic=node1 $(docker node ls -f "name=$CLUSTER_SERVER2" --format "Template:.ID")
docker node update --label-add lv.zzdats.vaflis.elastic=node2 $(docker node ls -f "name=$CLUSTER_SERVER4" --format "Template:.ID")

Vadības un starpniekservera servisu uzstādīšana

 

Instalējam portainer aģentu

version: '3.5'
services:
  agent:
    image: portainer/agent
    environment:
      AGENT_CLUSTER_ADDR: tasks.agent
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /srv/docker/volumes:/var/lib/docker/volumes
    networks:
      - portainer_agent
    ports:
      - target: 9001
        published: 9001
        protocol: tcp
        mode: host
    deploy:
      mode: global
      resources:
        limits:
          cpus: '0.2'
          memory: '128M'
      restart_policy:
        condition: on-failure
        delay: 5s
networks:
  portainer_agent:
    driver: overlay
    attachable: true
 

Uz pirmā servera augšupielādējam portainer-agent.yml un izpildam komandu:

docker stack deploy -c portainer-agent.yml portainer
 
 

Pievienojam klāsteri Portainer administrācijas rīkam

Kā galapunktu (endpoint) izmantojam pirmā servera adresi un portu 9001, piemēram node1.domain:9001

Instalējam klāstera iekšējo HaProxy servisu

Izmantojot portainer administrēšanas rīku, pievienojam jaunu nospēpumu ar nosaukumu ssl_cert_key, kas satur PEM formatā privāto un publisko sertifikāta atslēgu, ko izmantot HTTPS.

Uz pirmā servera augšupielādējam docker-flow-proxy.yml un izpildam komandu:

docker stack deploy -c docker-flow-proxy.yml proxy

 

Pamatservisu uzstādīšana un konfigurācija

 

Pārvaldes vietnes PostgreSQL datu bāze

 

Izmantojot portainer administrēšanas rīku

Pievienojam jaunus nospēpumus:

  • backoffice_db_password ar paroli, kas tiks izmantota, lai uzstādītu datu bāzes struktūru.
  • backoffice_db_password2 ar paroli, kas tiks izmantota, lai no aplikācijas pieslēgtos datu bāzei.

Izveidojam jaunu servisu steku (stack):

  • Nosaukums: backoffice-db
  • Būvēšanas metode: git repozitorijs
  • Repozitorija URL: https://git.zzdats.lv/vaflis/infrastructure.git
  • Compose ceļš: recepies/postgresql/backoffice-db.yml
  • Izmantojot autentifikāciju norādām lietotāju un API talonu

 

API servisu PostgreSQL datu bāze

 

Izmantojot portainer administrēšanas rīku

Pievienojam jaunus nospēpumus:

  • vaflis_db_password ar paroli, kas tiks izmantota, lai uzstādītu datu bāzes struktūru.

Izveidojam jaunu servisu steku (stack):

 

Rindu serviss RabbitMQ

 

Izmantojot portainer administrēšanas rīku

Pievienojam jaunus nospēpumus:

  • rabbitmq_password ar paroli, kas tiks izmantota, lai konfigurētu RabbitMQ serveri.

Izveidojam jaunu servisu steku (stack):

  • Nosaukums: queue-service
  • Būvēšanas metode: tīmekļa redaktors
version: '3.5'
services:
  rabbit1:
    image: rabbitmq:3.7-management-alpine
    hostname: rabbit1
    environment:
      - RABBITMQ_ERLANG_COOKIE=CLXRSSZKSRMFBBZLDGHQ
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS_FILE=/run/secrets/rabbitmq_password
    secrets:
      - source: "rabbitmq_password"
        target: "rabbitmq_password"
    networks:
      - rabbitnet
      - proxy
    deploy:
      placement:
        constraints:
          - node.labels.lv.zzdats.vaflis.queueserver == true
      resources:
        limits:
          cpus: '0.5'
          memory: '1G'
      restart_policy:
        condition: on-failure
        delay: 2s
      labels:
        - "traefik.docker.network=proxy"
        - "traefik.frontend.rule=PathPrefix: /rabbitmq; StripPathPrefix: /rabbitmq"
        - "traefik.port=15672"
        - "com.df.notify=true"
        - "com.df.servicePath.1=/rabbitmq"
        - "com.df.reqPathSearchReplace.1=/rabbitmq,"
        - "com.df.port.1=15672"
        - "com.df.reqMode.2=tcp"
        - "com.df.srcPort.2=5672"
        - "com.df.port.2=5672"
    volumes:
      - rabbitdata:/var/lib/rabbitmq
volumes:
  rabbitdata:
networks:
  rabbitnet:
    driver: overlay
  proxy:
    external: true
secrets:
  rabbitmq_password:
    external: true