Wednesday, June 17, 2015

6-17-2015, SALT as in saltstack (status : home done, AWS todo)

SALT is written in Python. Puppet is written in something I don't program in anymore. The choice is clear when its my choice. I have seen people use Puppet even though someone was SALT certified because puppet has been around longer and the more experienced people got their way. But puppet isn't bad at all. I just prefer SALT. I could care less really. I plan on writing modules, and its easier if its in a language I know.

I will be adding to this doc as time goes on, now that AWS, my home laptops, DNS, MySQL (rep and cluster), and mongo are setup. I have to redo some of this in SALT however.

WARNING: you are opening up several ports for salt on servers. Make sure they are firewalled and those ports are not open to the outside. Make sure in AWS you don't let anybody use those ports and block off access to those ports for people not in your local are network.

Links:


  • http://docs.saltstack.com/en/latest/
  • youtube: https://www.youtube.com/user/SaltStack
  • User group in bay area: http://www.meetup.com/Salt-Stack-DevOps/


  • Steps
    • Add salt.mylocaldomain to the DNS
      • Add "salt IN CNAME ns2" to /etc/bind/db.mylocaldomain
      • Restart DNS: service bind9 restart
    • The Master (which will also be a minion). We do everything to the master, and then one section for each other service. 
      1. sudo add-apt-repository ppa:saltstack/salt
        sudo apt-get update
        sudo apt-get install salt-master salt-minion salt-syndic
        
      2. sed -i 's/\#master: salt/master: salt.mylocaldomain/' /etc/salt/minion
          # It asks a question I can't seem to get rid of here. Good in a way. 
        
        service salt-master restart
        service salt-minion restart
        service salt-syndic restart
      3. Now setup the minion part of this server -- use the master as its own minion.
        1. When minion is restarted above it will attempt to make its own key and connect to the master.
        2. salt-call key.finger --local @ Should look like
        3. local:
        4.    28:01:06:52:9e:e6:97:7d:cc:00:2d:7f:fa:16:93:a3
        5. Now accept the key on the master:
          • List the key status: salt-key -L
          • Accept the key either as
            • salt-key -A
            • or, salt-key -a NAME
    Now add the other minions, make sure "salt" is added to the DNS before you do this:
    • Install it:
      • sudo add-apt-repository ppa:saltstack/salt
          # It asks a question I can't seem to get rid of here. Good in a way. 
        
        sudo apt-get -y update
        sudo apt-get -y install salt-minion
        sed -i 's/\#master: salt/master: salt.mylocaldomain/' /etc/salt/minion
        service salt-minion restart
      • Do an "nslookup salt.mylocaldomain" and if it comes up correct. 
        • If so, when you restarted salt minion it should have submitted a key to the salt master. 
      • On the master: salt-key -A. 


    The first commands (some of them are in the docs). Do this on the master.

    • salt '*' test.ping
      • On the hosts should return "True". If not, the DNS might be wrong, you may not have installed sal-minion on the target, or its config file doesn't point to the master, or the master had not accepted its key
    • salt '*' disk.usage
      • salt '*' disk.usage --out raw
      • salt '*' disk.usage --out yaml

    Now let's put the command in a script. Parsing console output is stupid when its already parsed in the language.

    Make this script and save it as "salt.py" :
    import salt.client
    
    local = salt.client.LocalClient()
    
    result = local.cmd('*', 'test.ping', timeout=2)
    print result
    
    result = local.cmd('*', 'disk.usage', timeout=2)
    print result 
    

    And then execute the script as "python salt1.py". It shows the output (I think in json format) and you can modify the script to deal with the parsed data instead of reparsing it from a cli. I will have examples in scripts for my DAD.


    Now let's parse the output of the "result" output. For this module, it seems be a multi hash. Let's just get the capacity of each partitions.




    import salt.client
    
    local = salt.client.LocalClient()
    # I chose this one since I think it might be multi process, not sure.                                                                                                 
    # I need to actually test it out.                                                                                                                                     
    inter1 = local.cmd_iter('*', 'disk.usage', timeout=2)
    
    for i in inter1:
      for host in i:
    #      print i[host]                                                                                                                                                  
          retcode = i[host]['retcode']
          if retcode != 0:
              print "ERROR:", host, retcode
          else:
              ret = i[host]['ret']
          for partition in ret:
     capacity = ret[partition]['capacity']
     print host, partition, capacity
    
    # which hosts failed. There msust be a better way where above it will return the ones failed.                                                                         
    result = local.cmd('*', 'test.ping', timeout=2)
    print result
    

    Now I want to see if this is multi-process (or threaded or whatever)
    import salt.client
    
    local = salt.client.LocalClient()
    inter1 = local.cmd_iter('*', 'cmd.run', ['echo "test" > /tmp/START; sleep 120; echo "test" > /tmp/STOP'], timeout=2)
    
    for i in inter1:
      for host in i:
    #      print i[host]                                                                                                                 
          retcode = i[host]['retcode']
          if retcode != 0:
              print "ERROR:", host, retcode
          else:
              ret = i[host]['ret']
          for partition in ret:
            capacity = ret[partition]['capacity']
            print host, partition, capacity
    

    And looking at the output of the processes on the master server.....
    mark2 ~ # ps auwx | grep minion
    root      4544  0.0  0.5 522460 20036 ?        S    01:14   0:00 /usr/bin/python /usr/bin/salt-minion
    root      4725  0.0  0.0  11744   912 pts/2    S+   01:15   0:00 grep --colour=auto minion
    root      7815  0.0  0.2  73712 10196 ?        Ss   Jun17   0:00 /usr/bin/python /usr/bin/salt-minion
    root      7819  0.0  0.5 522460 20296 ?        Sl   Jun17   7:24 /usr/bin/python /usr/bin/salt-minion
    

    Now looking at the timestamps of the 3 servers.....

    mark ~ # ls -al /tmp/S* 
    -rw-r--r-- 1 root root 5 Jun 25 01:14 /tmp/START
    -rw-r--r-- 1 root root 5 Jun 25 01:16 /tmp/STOP
    
    mark2 ~ # ls -al /tmp/S*
    -rw-r--r-- 1 root root 5 Jun 25 01:14 /tmp/START
    -rw-r--r-- 1 root root 5 Jun 25 01:16 /tmp/STOP
    
    mark3 ~ # ls -al /tmp/S*
    -rw-r--r-- 1 root root 5 Jun 25 01:14 /tmp/START
    -rw-r--r-- 1 root root 5 Jun 25 01:16 /tmp/STOP
    

    We see that they all have the same timestamps, and there were 3 processes running, so that command is verified to be what we want. Imagine if we have 1000 computers. Doing this serially would suck.

    Now let's organize stuff ---- doing.


    Thursday, June 11, 2015

    6-11-2015, DNS continued (status: done)


    • Setup DNS servers on all 3 servers at home, each primary masters, since they won't change, its okay to just copy them all and make them independent and not make them secondary DNS servers.
    • Setup AWS DNS server for local domain. 
      • apt-get install bind9
      • Setup resolv.conf : Not sure which did, but restarting the server made resolv.conf right. 
        • Added "nameserver 127.0.0.1" to the file /etc/resolvconf/resolv.conf.d/head.
        • /etc/resolvconf/resolv.conf.d/head:search mylocaldomain us-east-2.compute.internal
        • /etc/resolvconf/resolv.conf.d/base:search    mylocaldomain us-east-2.compute.internal
      • Added the forwarder to the amazon DNS. 
        • To the file /etc/bind/named.conf.options
          • forwarders {     172.32.0.2;           };
        • Add add this but you should add more restrictions. Since l let AWS restrict by network  put this in. Otherwise, none of your servers will be able to query it. 
          • allow-query { any; };
      • Follow the steps in the previous doc from "Now setup the DNS for your own network."
        • Being an idiot, I didn't figure out the command to restart the netowork, so just reboot it. 
        • Get the ip addresses from the EC2 console, or the scripts. 
        • Finally, to let the other servers use your DNS server:
          • Open up the DNS port only to those servers you trust. 
          • Add your DNS server /etc/resolvconf/resolv.conf.d/head  on those servers. 
            • TODO --- this needs to be done, last step. 
              • At home, each is a master. DONE
            • AWS
    For AWS servers......
    echo "nameserver 1.1.1.1" >> /etc/resolvconf/resolv.conf.d/head
    echo "search mylocaldomain us-west-2.compute.internal" >> /etc/resolvconf/resolv.conf.d/head
    echo "search mylocaldomain us-west-2.compute.internal" >> /etc/resolvconf/resolv.conf.d/base
    reboot # I must find a better way.
    After reboot, test DNS entries.
    


    DONE at home and work.
    I will need to maintain this, but I am going to leave it out of SALT. Now to SALT, then voltdb, vertica,  DAD. 

    Tuesday, June 9, 2015

    6-9-2015 BIND, DNS (status : done)

    I need to install bind at home and AWS. Home first because my computers was way more powerful than then micro computers on AWS. Need two things: one as a cache server and one as a master. Then the other servers in the network will cache only from the master. Eventually, set this up in salt. Just want it work first, and then do stuff in salt after that. Salt shouldn't maintain the the main DNS, except maybe parts of it.

    Links:


    • https://help.ubuntu.com/12.04/serverguide/dns-configuration.html
    • https://www.centos.org/docs/5/html/Deployment_Guide-en-US/s1-bind-zone.html
    Steps:
    • apt-get install bind9
    • route -n # This gives you the ip address of your router at home with is also the DNS. For AWS I will have to use the AWS servers. 
    • In the forwards section of       /etc/bind/named.conf.options , I added my router at home and google's DNS for fun.
      forwarders {
           8.8.8.8;    
           192.168.1.1;
                 };
      
      
    • Test that it works locally: nslookup google.com 192.168.1.209 
      • restart bind: service network-manager restart
      • Change the ip address to your local computer.
    • Change the resolv.conf to point to your own computer at the file: /etc/resolvconf/resolv.conf.d/head
      • search mylocaldomain
        nameserver 127.0.0.1
        nameserver 8.8.8.8
        # blank space
        
    • Restart network: sudo service network-manager restart
      • /etc/resolv.conf should have your changes. Check it. 
    • Now setup the DNS for your own network. 
      • Edit the file /etc/bind/named.conf.local and add:
        • zone "mylocaldomain" {
           type master;
                  file "/etc/bind/db.mylocaldomain";
          };
          
      • Edit the file and put in your own hosts at /etc/bind/db.mylocaldomain. This worked when I tested it. I am sure technically I could make the below better. 
        • ;
          
          ;
          ; BIND data file for example.com
          ;
          $TTL    604800
          @       IN      SOA     ns1.mylocaldomain. root.mylocaldomain. (
                                        2         ; Serial
                                   604800         ; Refresh
                                    86400         ; Retry
                                  2419200         ; Expire
                                   604800 )       ; Negative Cache TTL
          @       IN      NS      ns1.mylocaldomain.
          @       IN      NS      ns2.mylocaldomain.
          @       IN      NS      ns3.mylocaldomain.
          
          @       IN      A       192.168.1.158
          @       IN      AAAA    ::1
          
          ns1     IN      A       192.168.1.158
          ns2      IN      A       192.168.1.209
          ns3      IN      A       192.168.1.50
          
          
          mark  IN CNAME ns1
          mark2 IN CNAME ns2
          mark3 IN CNAME ns3
          
          salt IN CNAME ns2
          
          
          ns3   IN A 192.168.1.30
          mark4 IN CNAME ns3
          ns4   IN A 192.168.1.179
          mark5 IN CNAME ns4
          
          
          
          
        • Restart bind: service network-manager restart
        • Do an "nslookup mark", and mark2, and mark3 to see if they come up. nslookup other domains like google.com to see if them come up. 

    Wednesday, June 3, 2015

    6-3-2015 Immediate list

    1. Finish taking the two mongodb classes is possible. This is in preparation for mongodb certifcation. -- ABANDONED. to much to do. taking exam later anyways.
    2. DONE install DNS at home. This is for setting up easy hostnames.
    • Fix the ip address on the wireless. --- DONE. 
    • Setup primary and document. --- DONE. 
    • Setup DNS with secondaries on all the servers. 
    • Use the google dns, comcast dns, and set these up as cache with forwarding. 
      • The big advantage is once it is cached, further lookups happen locally.  
    3. Setup salt at AWS. Possibly let the local servers also connect to it, or setup salt server at me too.

    • DNS was setup in AWS to make it easy. 
    • TODO: setup salt in AWS. 

     4. Make SALT do the entire configuration and setup and initialize.
    • A topologu must exist for all of these. 
    • Detect if exist:
      • No
        • Initialize
        • If part of a group try to connect to group. 
        • If it has to be primary (MySQL rep) see if other servers are running. If they are, spit out error messages.
      •  Yes
        • See we can start and reconnect. 
          • If you can't error out. 
    5. Install these by SALT:
    • Mongodb 3.0
    • Percona - rep
    • Percona -- Galera
    • MaxScale from MariaDB. Yes, I should be installing MariaDB instead of Percona but a lot of companies are hooked on Percona. It sucks. 
    • voltDB
    • Vertica
    6. Add voltdb and vertica to DAD as well as MySQL and MongoDB. I need MySQL Rep and MySQL Cluster as separate sections.