87
Package Managers and Puppet Joe Damato packagecloud.io

Puppet Camp LA 2/19/2015

  • Upload
    ice799

  • View
    281

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Puppet Camp LA 2/19/2015

Package Managers and Puppet

Joe Damato packagecloud.io

Page 2: Puppet Camp LA 2/19/2015

slides available at:

blog.packagecloud.io

Page 3: Puppet Camp LA 2/19/2015

hi, I’m joe!• i think these things are cool:

• computer programs

• reproducible builds / infrastructure

• automation

• configuration management

• tahdig** an rice food

Page 4: Puppet Camp LA 2/19/2015

packagecloud.io

• I work on packagecloud.io

• packagecloud makes it easy to upload, download, store, and delete software packages

• you should use it, it’s cool.

Page 5: Puppet Camp LA 2/19/2015

marc falardeau, https://flic.kr/p/8gKeGS

Page 6: Puppet Camp LA 2/19/2015

Wade M, https://flic.kr/p/5aghr9

Page 7: Puppet Camp LA 2/19/2015

Why?• Central to maintaining, building, and testing

infrastructure.

• Packages are a primitive in Puppet.

• Understanding where packages come from, and how to store them properly is a requirement for infrastructure of any size.

• Packages and packaging are much trickier than they seem!

Page 8: Puppet Camp LA 2/19/2015

Overview

• what is a package?

• what is a package manager?

• ./configure && make && make install pattern

• open source tools for package repositories

• HOWTO manage repos in your infra with puppet

Page 9: Puppet Camp LA 2/19/2015

What is a package?

Beck Gusler, https://flic.kr/p/4A15jm

Page 10: Puppet Camp LA 2/19/2015

What is a package?

• A package generally consists of:

• metadata (version, architecture, deps, etc)

• files to be written to the filesystem (/usr/sbin/nginx, etc)

Page 11: Puppet Camp LA 2/19/2015

Common package types

Page 12: Puppet Camp LA 2/19/2015

Common package types• RPM packages

• Used on CentOS, RHEL, Scientific Linux, Fedora, …

• files typically have the “.rpm” file extension

• can be inspected, installed, and removed with rpm

• are actually a:

• header structure (binary data)

• CPIO archive

Page 13: Puppet Camp LA 2/19/2015

man 8 rpm

Page 14: Puppet Camp LA 2/19/2015

Common package types

Page 15: Puppet Camp LA 2/19/2015

Common package types• Deb packages:

• Used on Ubuntu, Debian, Knoppix, …

• files typically have the “.deb” file extension

• can be inspected, installed, and removed with dpkg

Page 16: Puppet Camp LA 2/19/2015

Common package types• Deb packages:

• are actually an AR archive with:

• version file: the debian format version

• data.tar.gz: the actual files to write to the filesystem

• control.tar.gz: the package metadata

• Can be GPG signed, but signatures are never checked!

Page 17: Puppet Camp LA 2/19/2015

man 1 dpkg

Page 18: Puppet Camp LA 2/19/2015

Common package types

• There are lots more! (ruby gems, npm, java, python, …)

• Some packaging systems also have source packages.

Page 19: Puppet Camp LA 2/19/2015

What is a source package?• A source package consists of:

• metadata (version, architecture(s), build deps, etc).

• source files (C source, C++ source, py scripts, etc).

• Allows you to rebuild a binary package easily.

Page 20: Puppet Camp LA 2/19/2015

Install packages with puppet

Use the resource type ‘package’ to install packages:

package { 'pygpgme': ensure => latest, }

Page 21: Puppet Camp LA 2/19/2015

Install packages with puppet

package { 'pygpgme': ensure => ‘0.3-11’, }

Specify the version you want by setting ensure:

Page 22: Puppet Camp LA 2/19/2015

Summary• Packages are a collection of files with metadata.

• The metadata usually has info like:

• architecture

• version

• dependency info

• and more.

• Installation is easy if you don’t have dependencies.

Page 23: Puppet Camp LA 2/19/2015

Dependencies

Nick Sieger, https://flic.kr/p/qQu1e

Page 24: Puppet Camp LA 2/19/2015

Dependencies• Installing 1 package is as easy as:

• dpkg -i filename.deb

• rpm -ivh filename.rpm

• Of course, you should use puppet instead :D

• But what if your program needs other programs?

• For example: nginx depends on libssl, zlib, …

Page 25: Puppet Camp LA 2/19/2015

r-hol, https://flic.kr/p/6UZb98

Page 26: Puppet Camp LA 2/19/2015

So, what’s a package manager?

Page 27: Puppet Camp LA 2/19/2015

Package manager

• A package manager is a collection of software that allows you to:

• install, upgrade, remove packages

• query package info from local system or repos

• Some tools include more advanced features like mirroring or more advanced caching features.

Page 28: Puppet Camp LA 2/19/2015

Common package managers

http://en.wikipedia.org/wiki/Yellowdog_Updater,_Modified#mediaviewer/File:Yum.png

Page 29: Puppet Camp LA 2/19/2015

• yum (Yellowdog Updater, Modified)

• Common on RHEL, CentOS, Fedora, …

• Used for installing, removing, configuring, and querying RPM packages and dependencies.

Common package managers

Page 30: Puppet Camp LA 2/19/2015

Common package managers

APT

Page 31: Puppet Camp LA 2/19/2015

Common package managers

• APT (Advanced Package Tool)

• Common on Debian, Ubuntu, KNOPPIX, …

• Used for installing, removing, configuring, and querying Debian packages and dependencies.

Page 32: Puppet Camp LA 2/19/2015

Install packages with puppet

• When you install packages with puppet, puppet will automatically detect which package manager to use.

• You won’t need to worry about which command to run, or what options to pass; puppet will take care of that for you!

Page 33: Puppet Camp LA 2/19/2015

Summary• package managers help you install software and

associated dependencies

• easily remove, upgrade, and query packages

• Puppet will automatically detect the system’s package manager when you install a package.

Page 34: Puppet Camp LA 2/19/2015

Kellie Parker, https://flic.kr/p/mtNMb

Page 35: Puppet Camp LA 2/19/2015

A problem

• You run Ubuntu 10.04 LTS

• You want to install redis

• Ubuntu 10.04 comes with redis-server 1.2.0-1

• That’s too old! You need 2.8.19!

• So, now what?

Page 36: Puppet Camp LA 2/19/2015

Common (not great) solution

• A common solution to this sort of problem is building redis (or ruby, or …) from source in your puppet manifest

• Like this….

Page 37: Puppet Camp LA 2/19/2015

exec { 'install-redis': command => "make && make install PREFIX=${redis_bin_dir}", cwd => $redis_src_dir, path => '/bin:/usr/bin', unless => "test $(${redis_bin_dir}/bin/redis-server --version | cut -d ' ' -f 1) = ‘Redis'", require => [ Exec['unpack-redis'], Class['gcc'] ], }

Common (not great) solution

Page 38: Puppet Camp LA 2/19/2015

Why?• It’s easy!

• ./configure && make && make install

• It works!

• I’m using puppet so it’s reproducible!

Page 39: Puppet Camp LA 2/19/2015

But…• What happens if you need to:

• completely remove Redis?

• install a security update?

• install a new version?

• install the same exact Redis on 200 machines?

Page 40: Puppet Camp LA 2/19/2015

The not-so great side• Not all Makefiles have uninstall targets, so you

have to remove files manually

• Leaving artifacts on the filesystem can cause really, really hard to debug problems later

• If the build process changes version to version, it can be painful to rollback

Page 41: Puppet Camp LA 2/19/2015

The not-so great side• Rebuilding the same source does not necessarily

get you the same byte-for-byte binary

• If the binaries aren’t identical, you can end up with bugs in some of the compiled binaries but not others

• Painful to recreate source builds inside of puppet

• Makes writing tests for manifests painful

Page 42: Puppet Camp LA 2/19/2015

Make a package• Install the same binary on every machine

• When the package is removed, all installed files are removed

• Versioning of build process built in (with most tools)

• Keep your puppet manifests about config management

• Your build steps are “factored out” into the package

Page 43: Puppet Camp LA 2/19/2015

Your new puppet manifest

package { 'redis': ensure => latest, }

Page 44: Puppet Camp LA 2/19/2015

Your package• Your build steps get encapsulated in the package

itself

• Makes iterating on the build more straight forward

• Don’t need to apply (potentially) a bunch of manifests to a machine every time you do a build

Page 45: Puppet Camp LA 2/19/2015

Duncan Hull, https://flic.kr/p/iVLZt

Page 46: Puppet Camp LA 2/19/2015

“How do I make a package?”

Page 47: Puppet Camp LA 2/19/2015

OZinOH, https://flic.kr/p/bRHn2v

Page 48: Puppet Camp LA 2/19/2015

Use tools!• debbuild

• rpmbuild

• fpm

• mock and pbuilder (more advanced)

Page 49: Puppet Camp LA 2/19/2015

Tradeoffs

• Takes time to learn new tools

• Takes time to understand packaging

• No one ever has enough time

Page 50: Puppet Camp LA 2/19/2015

BUT…

Page 51: Puppet Camp LA 2/19/2015

Tradeoffs

• Once you learn how to make packages you can build reproducible infrastructure much more easily

• You can use your prod environment in dev and test

• You can more easily build tests for your infrastructure with beaker/kitchen.ci

Page 52: Puppet Camp LA 2/19/2015

Duncan Hull, https://flic.kr/p/iVLZt

Page 53: Puppet Camp LA 2/19/2015

“How do I store and organize my packages?”

Page 54: Puppet Camp LA 2/19/2015

Package repositories

• Major linux distributions keep repositories of packages for users:

• EPEL

• Ubuntu / Debian official repositories

• You can store a package and its dependencies to make it easy to install them all on your infrastructure

Page 55: Puppet Camp LA 2/19/2015

OZinOH, https://flic.kr/p/bRHn2v

Page 56: Puppet Camp LA 2/19/2015

Package repositories• createrepo: creates yum repositories

• reprepro: creates apt repositories

• Many other free tools available!

• Read the documentation carefully. Lots of tricky options.

• I’ll show some examples to get you started!

Page 57: Puppet Camp LA 2/19/2015

createrepo

http://en.wikipedia.org/wiki/Yellowdog_Updater,_Modified#mediaviewer/File:Yum.png

Page 58: Puppet Camp LA 2/19/2015

createrepo• mkdir /var/www/myrepo

• cp /path/to/rpms/*.rpm /var/www/myrepo

• createrepo /var/www/myrepo

• gpg --detach-sign --armor /var/www/my/repo/repomd.xml

Page 59: Puppet Camp LA 2/19/2015

GPG is important• Using GPG to sign the generated repository

guarantees that you generated the repository.

• This is important.

• This means that no one else modified, removed, or inserted a package other than you.

• GPG signing the repository is not a very well known security measure, but it is incredibly important!

• This is NOT the same as using rpmsign/rpm --sign.

Page 60: Puppet Camp LA 2/19/2015

Secure YUM repos

• Sign repository metadata with GPG

• Sign packages with GPG (use rpmsign)

• Serve repositories over SSL

• Enable all the right options for SSL verification, repository GPG checking, AND package GPG checking.

Page 61: Puppet Camp LA 2/19/2015

Wouldn’t it be cool to do all that with Puppet instead?

Good news: you can!

Page 62: Puppet Camp LA 2/19/2015

createrepo via puppet

Puppet can create YUM repositories for you!

$ puppet module install palli-createrepo

Page 63: Puppet Camp LA 2/19/2015

createrepo { 'yumrepo': repository_dir => '/var/yumrepos/yumrepo', repo_cache_dir => '/var/cache/yumrepos/yumrepo' }

createrepo via puppet

Page 64: Puppet Camp LA 2/19/2015

You still need to GPG sign the repository yourself :(

exec { “gpg_sign_yumrepo”: command => “gpg --detach-sign --armor /var/yumrepos/yumrepo/repodata/repomd.xml“, }

Page 65: Puppet Camp LA 2/19/2015

Once the repository is created, it must be added to the client machines.

Page 66: Puppet Camp LA 2/19/2015

Add YUM repos with puppetyumrepo { 'my_repo': baseurl => "http://myurl.com/repo", gpgcheck => 1, repo_gpgcheck => 1, gpgkey => “http://myurl.com/gpg.pub.key”, sslverify => 1, sslcacert => “/etc/pki/tls/certs/ca-bundle.crt”, enabled => 1, }

most people never turn on repo_gpgcheck or sslverify, or set the ssl certificate path, but you should!!

Page 67: Puppet Camp LA 2/19/2015

But that’s not all!• You MUST have the ‘pygpgme’ package

installed on the system that will verify the signatures.

• Without pygpgme, yum will not be able to verify signatures!

• Some versions of CentOS / RHEL do not automatically install pygpgme with yum!!

Page 68: Puppet Camp LA 2/19/2015

Make sure to install pygpgme

package { 'pygpgme': ensure => latest, }

Page 69: Puppet Camp LA 2/19/2015

reprepro

APT

Page 70: Puppet Camp LA 2/19/2015

reprepro

• mkdir /var/www/myrepo

• mkdir /var/www/myrepo/conf

• Create a file named “distributions” in the conf directory

Page 71: Puppet Camp LA 2/19/2015

reprepro

Codename: precise Components: main Architectures: i386 amd64 SignWith: 7ABDB001

/var/www/myrepo/conf/distributions:

Page 72: Puppet Camp LA 2/19/2015

reprepro• You can add more sections if you need more code

names (lucid, trusty, etc).

• SignWith specifies which GPG key to use for signing repository metadata

• You can get your gpg key ID by looking at the output of gpg —list-keys

• This is not the same as using debsigs/debsign !!!

Page 73: Puppet Camp LA 2/19/2015

reprepro

import your Ubuntu 12.04 packages:

reprepro -b /var/www/myrepo/ includedeb precise filename.deb

Page 74: Puppet Camp LA 2/19/2015

Wouldn’t it be cool to do all that with Puppet instead?

Good news: you can!

Page 75: Puppet Camp LA 2/19/2015

reprepro via puppet

Puppet can create APT repositories for you!

$ puppet module install jtopjian-reprepro

Page 76: Puppet Camp LA 2/19/2015

# Base Directory shortcut $basedir = '/var/lib/apt/repo' !# Main reprepro class class { 'reprepro': basedir => $basedir, } !# Set up a repository reprepro::repository { 'localpkgs': ensure => present, basedir => $basedir, options => ['basedir .'], }

reprepro via puppet

Page 77: Puppet Camp LA 2/19/2015

# Create a distribution within that repository reprepro::distribution { 'precise': basedir => $basedir, repository => 'localpkgs', origin => 'Foobar', label => 'Foobar', suite => 'precise', architectures => 'amd64 i386', components => 'main contrib non-free', description => ‘My repo', sign_with => 'F4D5DAA8', not_automatic => 'No', }

reprepro via puppet

Page 78: Puppet Camp LA 2/19/2015

Once the repository is created, it must be added to the client machines.

Page 79: Puppet Camp LA 2/19/2015

Add APT repos with puppet

apt::source { 'myrepo': location => ‘http://myurl.com/repo', release => 'precise', repos => 'main', key => '7ABDB001', key_source => ‘http://myurl.com/gpg.pub.key', include_src => true, }

$ puppet module install puppetlabs-apt

Page 80: Puppet Camp LA 2/19/2015

But that’s not all!• You MUST have the ‘apt-transport-https’ package

installed on the system if your repository is served over HTTPS!

• Without apt-transport-https, you can’t install packages over HTTPS.

• You definitely want this.

Page 81: Puppet Camp LA 2/19/2015

Make sure to install apt-transport-https

package { ‘apt-transport-https‘: ensure => latest, }

Page 82: Puppet Camp LA 2/19/2015

Alosh Bennett, https://flic.kr/p/WJ7rE

Page 83: Puppet Camp LA 2/19/2015

Success• You can now use beaker/kitchen.ci/etc to test your

infrastructure.

• Determine if the packages you need are actually installed after your manifests are applied.

• Determine if the repositories you added are actually added after your manifests are applied.

• Don’t need to wait forever for Ruby, redis, et al to build during a test run.

Page 84: Puppet Camp LA 2/19/2015

BEST OF ALL !!!!• You can now run Puppet on your development

VM using the same manifests you use in production

• The manifests are applied and you are running the same exact binaries you run in production

• Won’t catch ALL production bugs, but getting closer to production during development is super useful

Page 85: Puppet Camp LA 2/19/2015

Summary• Creating package repositories can be tricky. Make

sure to GPG sign repository metadata.

• 99% of package repositories get this wrong.

• Carefully read the documentation of createrepo and reprepro.

• Make sure to install necessary libraries for verifying signatures and accessing repositories via HTTPS.

• Always serve up your repositories over HTTPS.

Page 86: Puppet Camp LA 2/19/2015

Use puppet to automate this.

Page 87: Puppet Camp LA 2/19/2015

?@packagecloudio

https://packagecloud.io [email protected]