Skip to content

Instantly share code, notes, and snippets.

@jdbohrman
Forked from DenisIzmaylov/NOTES.md
Created November 30, 2018 12:15
Show Gist options
  • Save jdbohrman/8f90eb91e488d88bc50dfe3da98c27ba to your computer and use it in GitHub Desktop.
Save jdbohrman/8f90eb91e488d88bc50dfe3da98c27ba to your computer and use it in GitHub Desktop.
Step By Step Guide to Configure a CoreOS Cluster From Scratch

Step By Step Guide to Configure a CoreOS Cluster From Scratch

This guide describes how to bootstrap new Production Core OS Cluster as High Availability Service in a 15 minutes with using etcd2, Fleet, Flannel, Confd, Nginx Balancer and Docker.

Content

Introduction

CoreOS is a powerful Linux distribution built to make large, scalable deployments on varied infrastructure simple to manage.

CoreOS is designed for security, consistency, and reliability. Instead of installing packages via yum or apt, CoreOS uses Linux containers to manage your services at a higher level of abstraction. A single service's code and all dependencies are packaged within a container that can be run on one or many CoreOS machines.

Main building blocks of CoreOS — etcd, Docker and systemd.

See: 7 reasons why you should be using CoreOS with Docker.

Basic Configuration

Connect your servers as a cluster

  1. Find your Cloud Config file location. For examples below we will use:
/var/lib/coreos-install/user_data
  1. Open your config to edit:
sudo vi /var/lib/coreos-install/user_data
  1. Generate new token for your cluster: https://discovery.etcd.io/new?size=X, where X is servers count.
  2. Merge follow lines with your Cloud Config:
coreos:
  etcd2:
    # generate a new token for each unique cluster from https://discovery.etcd.io/new
    # discovery: https://discovery.etcd.io/<token>
    discovery: https://discovery.etcd.io/9c19239271bcd6be78d4e8acfb393551
    # multi-region and multi-cloud deployments need to use $public_ipv4
    advertise-client-urls: http://$private_ipv4:2379,http://$private_ipv4:4001
    initial-advertise-peer-urls: http://$private_ipv4:2380
    # listen on both the official ports and the legacy ports
    # legacy ports can be omitted if your application doesn't depend on them
    listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
    listen-peer-urls: http://$private_ipv4:2380
  
  fleet:
    public-ip: $private_ipv4
    metadata: region=europe,public_ip=$public_ipv4
  
  units:
    - name: etcd2.service
      command: start
      # See issue: https://github.com/coreos/etcd/issues/3600#issuecomment-165266437
      drop-ins:
        - name: "timeout.conf"
          content: |
            [Service]
            TimeoutStartSec=0
    - name: fleet.service
      command: start
    - name: flanneld.service
      command: start
      # Attention! Setup "Network" according your environment
      drop-ins:
      - name: 50-network-config.conf
        content: |
          [Service]
          ExecStartPre=/usr/bin/etcdctl set /coreos.com/network/config '{ "Network": "10.1.0.0/16" }'
  1. For RPN-Online you should also add follow lines to get Private Network working:
  units:
    # ...
    - name: 00-eno2.network
      runtime: true
      content: "[Match]\nName=eno2\n\n[Network]\nDHCP=yes\n\n[DHCP]\nUseMTU=9000\n"
  1. Validate your changes:
sudo coreos-cloudinit -validate --from-file /var/lib/coreos-install/user_data
  1. Reboot the system:
sudo reboot
  1. Check status for etcd2:
sudo systemctl status -r etcd2

Output should contain a follow line:

 Active: active (running)

Sometimes it takes a time. Don't panic. Just wait for a few minutes.

If something goes wrong use follow commands to debug:

# etcd2
sudo systemctl start etcd2
sudo systemctl status etcd2
sudo journalctl -xe
sudo journalctl -ru etcd2
  1. Repeat those steps for each server in your cluster.

  2. Check your cluster health and fleet status:

# should be healthy
sudo etcdctl cluster-health
# should display all servers
sudo fleetctl list-machines

Create Fleet Units

Fleet Scheduling

See: Launching Containers with fleet

Application Unit

  1. Enter to your home directory:
cd ~
  1. Create new Application Template Unit. For example - run vi [email protected] and add follow lines:
[Unit]
Description=test-app%i
After=docker.service

[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill test-app%i
ExecStartPre=-/usr/bin/docker rm test-app%i
ExecStartPre=/usr/bin/docker pull willrstern/node-sample
ExecStart=/usr/bin/docker run -e APPNAME=test-app%i --name test-app%i -P willrstern/node-sample
ExecStop=/usr/bin/docker stop test-app%i
  1. Submit Application Template Unit to Fleet:
fleetctl submit [email protected]
  1. Start new instances from Application Template Unit:
fleetctl start test-app@1
fleetctl start test-app@2
fleetctl start test-app@3
  1. Check that all instances has been started and active. It could take a few minutes. Example command and its output:
$ fleetctl list-units
UNIT			MACHINE				ACTIVE	SUB
[email protected]	e1512f34.../10.1.9.17	active	running
[email protected]	a78a3229.../10.1.9.18	active	running
[email protected]	081c8a1e.../10.1.9.19	active	running

Troubleshooting

  • fleet list-units is displaying failed state for any units

    sudo fleetctl journal testapp@1
  • Error response from daemon: Conflict. The name "testapp1" is already in use by container c4acbb70c654. You have to delete (or rename) that container to be able to reuse that name.

    fleetctl stop testapp@1
    docker rm testapp1
    fleetctl start testapp@1
  • fleet ssh command doesn't working

    1. Ensure your public key has been added everywhere in user_data. On each server.
    2. Connect to your server with SSH agent:
    eval `ssh-agent -s`
    ssh-add ~/.ssh/id_rsa
    ssh -A <your-host>

Configure Firewall Rules

Run custom-firewall.sh on your local machine:

curl -O https://raw.githubusercontent.com/deis/deis/master/contrib/util/custom-firewall.sh
# run follow line for each server
ssh core@<host1> 'bash -s' < custom-firewall.sh

Load Balancers and Service Discovery

  1. Modify attached files according to your application.
  2. Submit that to your Fleet:
fleetctl submit [email protected]
fleetctl submit [email protected]
fleetctl submit [email protected]
  1. Start Unit instances from templates:
fleetctl start someapp@{1..6}
fleetctl start someapp-discovery@{1..6}
fleetctl start someapp-lb@{1..2}

Install Deis v1

Attention! It seems that doesn't work correctly with Online.net bare metal setups.

  1. Create backup copy of your original config:
sudo vi cp /var/lib/coreos-install/user_data /var/lib/coreos-install/user_data.without-deis1
  1. Merge your Cloud Config with Deis Cloud Config example.

  2. You can configure Deis Platform from your workstation by following this instruction. The next steps adopted for server environment.

  3. Download deisctl:

curl -sSL http://deis.io/deisctl/install.sh | sudo sh -s 1.12.3
  1. Set your configuration:
deisctl config platform set domain=<your-domain>
  1. Run platform installation:
deisctl install platform
  1. Boot up Deis:
deisctl start platform

If you get problems try to check Docker containers:

docker ps -a

Also you could use journal and status commands for deisctl to debug.

  1. Once you see “Deis started.”, your Deis platform is running on a cluster. Verify that all Deis units are loaded by run:
deisctl list

All Deis units should be active. Otherwise you could destroy that all and don't forget to remove unused Docker volumes.

Appendix 1 - Info and Tutorials

Appendix 2 - Tools and Services

[Unit]
Description=Announce Someapp%i
BindsTo=someapp@%i.service
After=someapp@%i.service
[Service]
ExecStart=/bin/sh -c "sleep 10; while true; do etcdctl set /services/someapp/upstream/someapp%i \"$(sleep 5 && docker inspect -f '{{.NetworkSettings.IPAddress}}' someapp%i):3000\" --ttl 60; sleep 45; done"
ExecStop=/usr/bin/etcdctl rm /services/someapp/upstream/someapp%i
[X-Fleet]
MachineOf=someapp@%i.service
[Unit]
Description=someapp-lb%i
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill someapp-lb
ExecStartPre=-/usr/bin/docker rm someapp-lb
ExecStartPre=/usr/bin/docker pull willrstern/nginx-lb
ExecStart=/usr/bin/sh -c "/usr/bin/docker run --name someapp-lb --rm -p 80:80 -e SERVICE_NAME=someapp -e TEST_HOST=%H -e ETCD=\"$(ifconfig docker0 | awk '/\<inet\>/ { print $2}'):2379\" willrstern/nginx-lb"
ExecStop=/usr/bin/docker stop someapp-lb
[X-Fleet]
Conflicts=someapp-lb@*
MachineMetadata=loadbalancer=true
[Unit]
Description=someapp%i
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill someapp%i
ExecStartPre=-/usr/bin/docker rm someapp%i
ExecStartPre=/usr/bin/docker pull willrstern/node-sample
ExecStart=/usr/bin/docker run --name someapp%i -e APPNAME=someapp%i willrstern/node-sample
ExecStop=/usr/bin/docker kill someapp%i
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment