This talk aims to cover a breadth of topics about package management and Chef, starting with some fundamentals and continuing on to more advanced techniques and tips.
This talk will begin by explaining why packages and package management are fundamental tenants to managing infrastructure. We'll examine why the common practice of simply running "make install" in a Chef recipe is a bad idea and what users can do when they see recipes like this in the wild.
An extremely common problem with package management is misconfiguration of package repositories and client software. Most of the existing documentation available does not cover all of the configuration required to correctly setup and access package repositories securely and lots of configurations are simply copy-and-pasted from unreliable sources.
In order to combat some of this, the talk will continue by examining some common Chef resources for controlling package repositories with care to carefully go over commonly misunderstood and misused options. We'll examine how to generate secure package repositories, what options must be set in Chef recipes to access repositories securely, and what bugs you may bump into in your infrastructure that may prevent you from securely accessing package repositories.
Finally, this talk will wrap up with some concluding tips, tricks, and thoughts about packaging and how to use it to carefully manage infrastructure.
https://youtu.be/-HJ7EZ85THU
3. hi, I’m joe!
• i think these things are cool:
• computer programs
• reproducible builds / infrastructure
• automation
• configuration management
• tahdig*
* an rice food
4. 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.
• it’s a perfect companion to Chef Delivery
6. “packagecloud:enterprise has solved the problem
of distributing public and private package
repositories. We’re extremely satisfied with the
support and we trust it with all the GitLab Omnibus
package downloads of more than 1TB per week."
Sytse Sijbrandij, CEO & Founder
9. Why?
• Central to maintaining, building, and testing
infrastructure.
• Packages are a primitive in Chef.
• 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!
10. 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 Chef
11. What is a package?
Beck Gusler, https://flic.kr/p/4A15jm
12. 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)
14. 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
17. 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
18. 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!
20. Common package types
• There are lots more! (ruby gems, npm, java,
python, …)
• Some packaging systems also have source
packages.
21. 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.
22. Install packages with chef
Use the ‘package’ resource to install packages:
package "zlib1g" do
action :install
end
23. Install packages with chef
Specify the version you want by setting ‘version’:
package "zlib1g" do
version "1:1.2.8-1"
action :install
end
24. 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.
26. Dependencies
• Installing 1 package is as easy as:
• dpkg -i filename.deb
• rpm -ivh filename.rpm
• Of course, you should use chef instead :D
• But what if your program needs other programs?
• For example: nginx depends on libssl, zlib, …
29. 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.
31. • yum (Yellowdog Updater, Modified)
• Common on RHEL, CentOS, Fedora, …
• Used for installing, removing, configuring, and
querying RPM packages and dependencies.
Common package managers
33. Common package managers
• APT (Advanced Package Tool)
• Common on Debian, Ubuntu, KNOPPIX, …
• Used for installing, removing, configuring, and
querying Debian packages and dependencies.
34. Install packages with chef
• When you install packages with chef, chef will
automatically detect which package manager to
use.
• You won’t need to worry about which command
to run, or what options to pass; chef will take
care of that for you!
35. Summary
• package managers help you install software and
associated dependencies
• easily remove, upgrade, and query packages
• Chef will automatically detect the system’s
package manager when you install a package.
37. 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?
38. Common (not great) solution
• A common solution to this sort of problem is
building redis (or ruby, or …) from source in your
chef cookbook
• Like this….
39. execute ‘compile redis' do
cwd ‘/tmp/redis’
command ‘make clean && make’
end
!
execute ‘install redis' do
cwd ‘/tmp/redis’
command ‘make install’
end
Common (not great) solution
40. Why?
• It’s easy!
• ./configure && make && make install
• It works!
• I’m using chef so it’s reproducible!
41. 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?
42. 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
43. 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 chef
• Makes writing tests for cookbooks painful
44. 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 chef cookbooks about config management
• Your build steps are “factored out” into the package
45. Your new chef recipe
package "redis" do
action :install
end
46. Your package
• Your build steps get encapsulated in the package
itself
• Makes iterating on the build more straight forward
• Don’t need to run (potentially) a huge number of
cookbooks every time you do a build
53. 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 kitchen.ci
56. 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
58. 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!
61. 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.
62. 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.
63. Wouldn’t it be cool to do all
that with Chef instead?
Good news: you can!
64. createrepo via chef
Chef can create YUM repositories for you!
$ knife cookbook site install yumrepo_server
65. yumrepo_server 'creates my yum repo' do
action :create
dir 'relative/yum/repo/path'
remote_source "http://upstream.com/path"
packages %w(pkg1.rpm pkg2.rpm pkg3.rpm)
end
createrepo via chef
66. You still need to GPG sign
the repository yourself :(
execute ‘gpg sign yum metadata' do
cwd ‘relative/yum/repo/path/repodata’
command ‘gpg --detach-sign —armor repomd.xml’
end
68. Add YUM repos with chef
most people never turn on repo_gpgcheck or
sslverify, or set the ssl certificate path, but you
should!!
yum_repository ‘my_repo' do
description “packagecloud.io is better than this”
baseurl “https://myurl.com/repo“
gpgkey ‘http://myurl.com/gpg.pub.key'
gpgcheck true
repo_gpgcheck true
sslverify true
sslcacert “/etc/pki/tls/certs/ca-bundle.crt”
action :create
end
69. 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!!
70. Make sure to install pygpgme
package "pygpgme" do
action :install
end
74. 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 !!!
80. Add APT repos with chef
apt_repository 'repo' do
uri ‘http://repo.com/ubuntu/'
arch 'amd64'
distribution 'precise'
components ['main']
key ‘http://repo.com/ubuntu/archive.key'
end
$ knife cookbook site install apt
81. 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.
82. Make sure to install apt-transport-https
package “apt-transport-https“ do
action :install
end
84. Success
• You can now use kitchen.ci to test your
infrastructure.
• Determine if the packages you need are actually
installed after your cookbooks have run.
• Determine if the repositories you added are
actually added after your cookbooks have run.
• Don’t need to wait forever for Ruby, redis, et al to
build during a test run.
85. BEST OF ALL !!!!
• You can now run Chef on your development VM
using the same cookbooks you use in
production
• The cookbooks 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
86. 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.
87. Use chef to automate your
infrastructure.
Use packagecloud.io to
deliver software.