From 6c35536c77e1a9a9cfb69154c5d97618d0e6ff8d Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Fri, 10 Feb 2017 17:15:13 +1100 Subject: [PATCH] containers: an instrumented Java application standalone container Adds the sample pcp-java-app container to the build, which shows how to run a Java service in a container with pmcd, pmdammv, and Parfait instrumentation all in place alongside it. Several other aspects of pcp-base and other standalone containers are tidied up here. Using the Dockerfile COPY directive seems to result in much simpler, clearer Dockerfiles - so more use is made of it now. Improved notes on using docker inspect to extract the docker run command (see comments at head of each Dockerfile) avoiding having to specify it in multiple places. Switched to using ENV to avoid any direct editing of installed configuration files, for PCP_USER and PCP_GROUP. --- build/containers/GNUmakefile | 1 + build/containers/pcp-apache/Dockerfile | 67 +++++------ build/containers/pcp-apache/status.conf | 5 + build/containers/pcp-base/Dockerfile | 148 +++++++++++------------- build/containers/pcp-base/GNUmakefile | 12 +- build/containers/pcp-base/bash_profile | 2 + build/containers/pcp-base/pcp.repo | 39 +++++++ build/containers/pcp-java-app/Dockerfile | 26 +++++ build/containers/{ => pcp-java-app}/GNUmakefile | 32 ++--- build/containers/pcp-java-app/acme.service | 12 ++ build/containers/pcp-nginx/Dockerfile | 69 +++++------ build/containers/pcp-nginx/status.conf | 7 ++ 12 files changed, 236 insertions(+), 184 deletions(-) rewrite build/containers/pcp-apache/Dockerfile (73%) create mode 100644 build/containers/pcp-apache/status.conf rewrite build/containers/pcp-base/Dockerfile (73%) create mode 100644 build/containers/pcp-base/bash_profile create mode 100644 build/containers/pcp-base/pcp.repo create mode 100644 build/containers/pcp-java-app/Dockerfile copy build/containers/{ => pcp-java-app}/GNUmakefile (57%) create mode 100644 build/containers/pcp-java-app/acme.service rewrite build/containers/pcp-nginx/Dockerfile (76%) create mode 100644 build/containers/pcp-nginx/status.conf diff --git a/build/containers/GNUmakefile b/build/containers/GNUmakefile index ca41fa8e6..3bcdbb733 100644 --- a/build/containers/GNUmakefile +++ b/build/containers/GNUmakefile @@ -28,6 +28,7 @@ SUBDIRS = \ pcp-pmwebd \ \ pcp-standalone \ + pcp-java-app \ pcp-apache \ pcp-nginx \ # end diff --git a/build/containers/pcp-apache/Dockerfile b/build/containers/pcp-apache/Dockerfile dissimilarity index 73% index 483a77278..de2018c15 100644 --- a/build/containers/pcp-apache/Dockerfile +++ b/build/containers/pcp-apache/Dockerfile @@ -1,38 +1,29 @@ -# -# Sample Dockerfile starting the Apache web server with a minimal pmcd -# -# $ docker build -t pcp-apache . -# -# $ sudo mkdir -p /run/containers/pcp-apache -# $ sudo chown pcp:pcp /run/containers/pcp-apache -# -# $ docker run -ti --tmpfs /run --tmpfs /tmp -p 80:80 \ -# -v /run/containers/pcp-apache:/run/pcp \ -# -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -# pcp-apache -# -# $ pminfo --fetch --host unix:/run/containers/pcp-apache/pmcd.socket -# - -FROM pcp-standalone:latest -ENV NAME pcp-apache -ENV IMAGE pcp-apache - -RUN dnf -y install httpd pcp-pmda-apache && dnf clean all -RUN . /etc/pcp.conf && touch $PCP_PMDAS_DIR/apache/.NeedInstall -RUN rm -f /etc/httpd/conf.d/status.conf; \ - echo 'ExtendedStatus on' >> /etc/httpd/conf.d/status.conf; \ - echo '' >> /etc/httpd/conf.d/status.conf; \ - echo ' SetHandler server-status' >> /etc/httpd/conf.d/status.conf; \ - echo ' Allow from all' >> /etc/httpd/conf.d/status.conf; \ - echo '' >> /etc/httpd/conf.d/status.conf -RUN systemctl enable httpd -EXPOSE 80 - -LABEL RUN docker run -it --tmpfs /run --tmpfs /tmp -p 80:80 \ - -v /run/containers/pcp-apache:/run/pcp \ - -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ - --name=pcp-apache pcp-apache - -STOPSIGNAL SIGRTMIN+3 -CMD ["/sbin/init"] +# +# Sample Dockerfile starting the Apache web server with a minimal pmcd +# +# Build: $ docker build -t pcp-apache . +# Name: $ sudo mkdir -p /run/containers/pcp-apache +# Run: $ `docker inspect --format='{{.Config.Labels.RUN}}' pcp-apache` +# Observe: $ pminfo --host local:/run/containers/pcp-apache/pmcd.socket \ +# --fetch proc network apache +# + +FROM pcp-standalone:latest +ENV NAME pcp-apache +ENV IMAGE pcp-apache + +RUN dnf -y install httpd pcp-pmda-apache && dnf clean all +RUN . /etc/pcp.conf && touch $PCP_PMDAS_DIR/apache/.NeedInstall +COPY status.conf /etc/httpd/conf.d/status.conf +RUN systemctl enable httpd +EXPOSE 80 + +LABEL RUN docker run \ +--publish 80:80 \ +--tmpfs=/run --tmpfs=/tmp \ +--volume=/run/containers/pcp-apache:/run/pcp \ +--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \ +--name=pcp-apache pcp-apache + +STOPSIGNAL SIGRTMIN+3 +CMD ["/sbin/init"] diff --git a/build/containers/pcp-apache/status.conf b/build/containers/pcp-apache/status.conf new file mode 100644 index 000000000..67b05d22d --- /dev/null +++ b/build/containers/pcp-apache/status.conf @@ -0,0 +1,5 @@ +ExtendedStatus on + + SetHandler server-status + Allow from all + diff --git a/build/containers/pcp-base/Dockerfile b/build/containers/pcp-base/Dockerfile dissimilarity index 73% index 2f7a35cea..f05d80784 100644 --- a/build/containers/pcp-base/Dockerfile +++ b/build/containers/pcp-base/Dockerfile @@ -1,79 +1,69 @@ -# Copyright (c) 2015 Red Hat. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# Dockerfile to build the pcp container image. This is based on -# Fedora rawhide and is intended as the base image for all other -# PCP containers, i.e. layered. -# -FROM fedora:latest -MAINTAINER PCP Development Team - -# update the Fedora base image and clean the dnf cache -# (normally disabled during development) -RUN dnf -y install createrepo.noarch && dnf -y update && dnf clean all - -# Set up a repo for latest bintray packages to be installed. This is the -# default. Note that this repo specifies enabled=1. All container images -# based on pcp-base will use the default enabled repo to install pcp -# packages, so to use e.g. the pcp-devel repo instead, just edit the -# appropriate enabled flag to specify the repo you want to use by default. -# You only need to change this in the pcp-base Dockerfile since all -# others are based on pcp-base and thus inherit the default repo settings. -RUN fver=`awk '{print $3}' /etc/redhat-release`;\ -echo -e '[pcp-bintray]\nname=PCP Bintray Yum Repository\n\ -baseurl=https://dl.bintray.com/pcp/f'$fver'\ngpgcheck = 0\nenabled = 1'\ ->/etc/yum.repos.d/pcp-bintray.repo - -# Set up a repo for local packages to be installed. This is only for use -# during development. To use this repo, change enabled=0 to enabled=1. -# Here we expect $(TOPDIR)/build/rpm to have the PCP RPMS to be -# installed in the container image, i.e. from the current Makepkgs build. -RUN mkdir -p /tmp/RPMS; \ -echo -e '[pcp-devel]\nname=PCP Development Yum Repository\n\ -baseurl=file:///tmp/RPMS\ngpgcheck = 0\nenabled = 0'\ ->/etc/yum.repos.d/pcp-devel.repo -COPY RPMS/*.rpm /tmp/RPMS/ -RUN createrepo /tmp/RPMS - -# -# Install minimal pcp (i.e. pcp-conf) and it's dependencies, clean the cache. -# This is intended as the base image for all other PCP containers. The -# bintray repo is enabled by default, see comments above. -RUN dnf -y install pcp-conf && dnf clean all - -# -# Run in the container as root - avoids PCP_USER mismatches -RUN sed -i -e 's/PCP_USER=.*$/PCP_USER=root/' -e 's/PCP_GROUP=.*$/PCP_GROUP=root/' /etc/pcp.conf - -# -# Since this can be invoked as an interactive container, set the bash prompt. -# All containers layered on pcp-base inherit this, with their own name. -RUN echo export PS1='"[$PCP_CONTAINER_IMAGE] "' >> /root/.bash_profile -RUN echo PATH=/usr/bin:$PATH >> /root/.bash_profile - -# -# Denote this as a container environment, for rc scripts -ENV PCP_CONTAINER_IMAGE pcp-base -ENV NAME pcp-base -ENV IMAGE pcp-base - -# -# The RUN label is used by 'atomic' command, e.g. atomic run pcp -# Other platforms without the 'atomic' command can use docker inspect to -# extract it and use it in a script. -LABEL RUN docker run -it --privileged --net=host --pid=host --ipc=host -v /sys:/sys:ro -v /etc/localtime:/etc/localtime:ro -v /var/lib/docker:/var/lib/docker:ro -v /run:/run -v /var/log:/var/log -v /dev/log:/dev/log --name=pcp-base pcp-base - -# -# The command to run (bash). When this command exits, then the container exits. -# This is the default command and parameters and can be overridden by passing -# additional parameters to docker run. -CMD ["/bin/bash", "-l"] +# +# Dockerfile to build the base container image. This uses a specific +# Fedora version, and is intended as the base image for all the other +# PCP containers (i.e. they are layered on top of this one). +# +# Build: $ docker build -t pcp-base . +# Debug: $ `docker inspect --format='{{.Config.Labels.RUN}}' pcp-base` +# +FROM fedora:25 +MAINTAINER PCP Development Team +ENV NAME pcp-base +ENV IMAGE pcp-base + +# Update the Fedora base image and clean the dnf cache +# (normally disabled during development) +# +RUN dnf -y install createrepo.noarch && dnf -y update && dnf clean all + +# Set up a repo for bintray packages to be installed. This is the default. +# Note that this repo specifies enabled=1. All container images +# based on pcp-base will use the default enabled repo to install +# packages, so to use e.g. the pcp-devel repo instead, just edit +# the enabled flag to specify an alternate repo you want to use. +# +COPY pcp.repo /etc/yum.repos.d/pcp.repo + +# Set up a repo for local packages to be installed. This is only for use +# during development. To use this repo, change enabled=0 to enabled=1. +# Here we expect $(TOPDIR)/build/containers/RPMS to contain packages to be +# available for the container image, e.g. from $(TOPDIR)/Makepkgs builds. +# +#RUN mkdir -p /root/rpmbuild/RPMS +#COPY RPMS/*.rpm /root/rpmbuild/RPMS/ +#RUN createrepo /root/rpmbuild/RPMS + +# Install minimal pcp (i.e. pcp-conf) and it's dependencies, clean the cache. +# This is intended as the base image for all other PCP containers. The +# bintray repo is enabled by default, see comments above. +RUN dnf -y install pcp-conf && dnf clean all + +# Run in the container as root - avoids host/container user mismatches +ENV PCP_USER root +ENV PCP_GROUP root + +# Denote this as a container environment, for rc scripts +ENV PCP_CONTAINER_IMAGE pcp-base + +# Since this can be invoked as an interactive container, setup bash. +COPY bash_profile /root/.bash_profile + +# RUN labels are used by the 'atomic' command, e.g. atomic run pcp-base +# Without this command, one can use docker inspect (see "Debug:" above). +# +LABEL RUN docker run \ +--interactive --tty \ +--privileged --net=host --pid=host --ipc=host \ +--volume=/run:/run \ +--volume=/sys:/sys:ro \ +--volume=/etc/localtime:/etc/localtime:ro \ +--volume=/var/lib/docker:/var/lib/docker:ro \ +--volume=/var/log:/var/log \ +--volume=/dev/log:/dev/log \ +--name=pcp-base pcp-base + +# The command to run (bash). When this command exits, then the container exits. +# This is the default command and parameters, mainly for debugging, and usually +# would be overridden by higher layers of the container build. +# +CMD ["/bin/bash", "-l"] diff --git a/build/containers/pcp-base/GNUmakefile b/build/containers/pcp-base/GNUmakefile index 28af0b328..07e71b22b 100644 --- a/build/containers/pcp-base/GNUmakefile +++ b/build/containers/pcp-base/GNUmakefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2015 Red Hat. +# Copyright (c) 2015,2017 Red Hat. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -11,15 +11,15 @@ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # - TOPDIR = ../../.. include $(TOPDIR)/src/include/builddefs -include ./GNUlocaldefs -# Directory containing PCP RPMs to be installed in the base container. -# The default is the RPMs just build by the Makepkgs script. These packages +# PCP RPMs to optionally be installed in the base container, for testing. +# The default is the RPMs just built by the Makepkgs script. These packages # will also be used to build all containers layered on pcp-base. -PACKAGES=../../rpm +# +PACKAGES=$(shell echo ../../rpm/*.rpm) CONTAINER = pcp-base LDIRT = $(CONTAINER)-$(CONTAINER_VERSION).$(CONTAINER_ARCH).tgz RPMS @@ -30,7 +30,7 @@ default default_pcp install install_pcp: pack_pcp: RPMS $(CONTAINER)-$(CONTAINER_VERSION).$(CONTAINER_ARCH).tgz RPMS: # Docker build runs createrepo RPMS - @echo Using PCP RPMS from $(PACKAGES) + @echo Adding PCP RPMS from $(PACKAGES) cp -a $(PACKAGES) RPMS # rule to build $(CONTAINER).tgz from Dockerfile diff --git a/build/containers/pcp-base/bash_profile b/build/containers/pcp-base/bash_profile new file mode 100644 index 000000000..d09864e86 --- /dev/null +++ b/build/containers/pcp-base/bash_profile @@ -0,0 +1,2 @@ +export PS1="[$PCP_CONTAINER_IMAGE] " +PATH=/usr/bin:$PATH diff --git a/build/containers/pcp-base/pcp.repo b/build/containers/pcp-base/pcp.repo new file mode 100644 index 000000000..dca9da4f4 --- /dev/null +++ b/build/containers/pcp-base/pcp.repo @@ -0,0 +1,39 @@ +[pcp-bintray] +name=Performance Co-Pilot Bintray Repository +baseurl=https://dl.bintray.com/pcp/f25 +gpgkey=https://bintray.com/user/downloadSubjectPublicKey?username=pcp +repo_gpgcheck=0 +gpgcheck=1 +enabled=1 + +[pcp-devel] +name=Performance Co-Pilot Development Packages +baseurl=file:///root/rpmbuild/RPMS +gpgcheck=0 +enabled=0 + +[nathans-copr] +name=Copr repo for early UoM and Parfait Packages +baseurl=https://copr-be.cloud.fedoraproject.org/results/nathans/pcp.io/fedora-24-x86_64/ +gpgkey=https://copr-be.cloud.fedoraproject.org/results/nathans/pcp.io/pubkey.gpg +skip_if_unavailable=True +type=rpm-md +gpgcheck=1 +repo_gpgcheck=0 +enabled=1 +enabled_metadata=1 + +#[uom-bintray] +#name=Units Of Measurement Bintray RPM Repository +#baseurl=https://dl.bintray.com/uom/f25 +#skip_if_unavailable=True +#gpgcheck=0 +#enabled=1 + +#[parfait-bintray] +#name=Parfait Bintray RPM Repository +#baseurl=https://dl.bintray.com/parfait/f25 +#skip_if_unavailable=True +#gpgcheck=0 +#enabled=1 + diff --git a/build/containers/pcp-java-app/Dockerfile b/build/containers/pcp-java-app/Dockerfile new file mode 100644 index 000000000..7e341a016 --- /dev/null +++ b/build/containers/pcp-java-app/Dockerfile @@ -0,0 +1,26 @@ +# +# Sample Dockerfile starting the Java ACME Factory example application +# +# Build: $ docker build -t pcp-java-app . +# Name: $ sudo mkdir -p /run/containers/pcp-java-app +# Run: $ `docker inspect --format='{{.Config.Labels.RUN}}' pcp-java-app` +# Observe: $ pminfo --host=local:/run/containers/pcp-java-app/pmcd.socket \ +# --fetch proc network mmv.acme +# + +FROM pcp-standalone:latest +ENV NAME pcp-java-app +ENV IMAGE pcp-java-app + +RUN dnf -y install pcp-parfait-agent parfait-examples && dnf clean all +COPY acme.service /usr/lib/systemd/system/acme.service +RUN systemctl enable acme + +LABEL RUN docker run \ +--tmpfs=/run --tmpfs=/tmp \ +--volume=/run/containers/pcp-java-app:/run/pcp \ +--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \ +--name=pcp-java-app pcp-java-app + +STOPSIGNAL SIGRTMIN+3 +CMD ["/sbin/init"] diff --git a/build/containers/GNUmakefile b/build/containers/pcp-java-app/GNUmakefile similarity index 57% copy from build/containers/GNUmakefile copy to build/containers/pcp-java-app/GNUmakefile index ca41fa8e6..fb584ec75 100644 --- a/build/containers/GNUmakefile +++ b/build/containers/pcp-java-app/GNUmakefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2015,2017 Red Hat. +# Copyright (c) 2017 Red Hat. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -12,28 +12,18 @@ # for more details. # -TOPDIR = ../.. -BUILDDEFS = $(TOPDIR)/src/include/builddefs - -include $(BUILDDEFS) +TOPDIR = ../../.. +include $(TOPDIR)/src/include/builddefs -include ./GNUlocaldefs -SUBDIRS = \ - pcp-base \ - pcp-collector \ - pcp-monitor \ - pcp-pmlogger \ - pcp-pmie \ - pcp-testsuite \ - pcp-pmwebd \ - \ - pcp-standalone \ - pcp-apache \ - pcp-nginx \ - # end +CONTAINER = pcp-java-app +LDIRT = $(CONTAINER)-$(CONTAINER_VERSION).$(CONTAINER_ARCH).tgz -default default_pcp install install_pcp pack_pcp: $(SUBDIRS) - $(SUBDIRS_MAKERULE) +default default_pcp install install_pcp: -include $(BUILDRULES) +pack pack_pcp: $(CONTAINER)-$(CONTAINER_VERSION).$(CONTAINER_ARCH).tgz +# rule to build $(CONTAINER)-$(CONTAINER_VERSION).$(CONTAINER_ARCH).tgz from Dockerfile +include ../GNUlocalrules + +include $(BUILDRULES) diff --git a/build/containers/pcp-java-app/acme.service b/build/containers/pcp-java-app/acme.service new file mode 100644 index 000000000..71b92c230 --- /dev/null +++ b/build/containers/pcp-java-app/acme.service @@ -0,0 +1,12 @@ +[Unit] +Description=Instrumented Java Service +Documentation=man:parfait(1) +After=local-fs.target network.target pmcd.service + +[Service] +Type=simple +Restart=always +ExecStart=/usr/bin/java -Dparfait.name=acme -javaagent:/usr/share/java/parfait/parfait.jar -jar /usr/share/java/parfait/acme.jar Main + +[Install] +WantedBy=multi-user.target diff --git a/build/containers/pcp-nginx/Dockerfile b/build/containers/pcp-nginx/Dockerfile dissimilarity index 76% index 3600a1be3..1a632fa79 100644 --- a/build/containers/pcp-nginx/Dockerfile +++ b/build/containers/pcp-nginx/Dockerfile @@ -1,40 +1,29 @@ -# -# Sample Dockerfile starting the Nginx web server with a minimal pmcd -# -# $ docker build -t pcp-nginx . -# -# $ sudo mkdir -p /run/containers/pcp-nginx -# $ sudo chown pcp:pcp /run/containers/pcp-nginx -# -# $ docker run -ti --tmpfs /run --tmpfs /tmp -p 80:80 \ -# -v /run/containers/pcp-nginx:/run/pcp \ -# -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -# pcp-nginx -# -# $ pminfo --fetch --host unix:/run/containers/pcp-nginx/pmcd.socket -# - -FROM pcp-standalone:latest -ENV NAME pcp-nginx -ENV IMAGE pcp-nginx - -RUN dnf -y install nginx pcp-pmda-nginx && dnf clean all -RUN . /etc/pcp.conf && touch $PCP_PMDAS_DIR/nginx/.NeedInstall -RUN rm -f /etc/nginx/default.d/status.conf; \ - echo 'location /nginx_status {' >> /etc/nginx/default.d/status.conf; \ - echo ' stub_status on;' >> /etc/nginx/default.d/status.conf; \ - echo ' access_log off;' >> /etc/nginx/default.d/status.conf; \ - echo ' allow 127.0.0.1;' >> /etc/nginx/default.d/status.conf; \ - echo ' allow ::1;' >> /etc/nginx/default.d/status.conf; \ - echo ' deny all;' >> /etc/nginx/default.d/status.conf; \ - echo '}' >> /etc/nginx/default.d/status.conf -RUN systemctl enable nginx -EXPOSE 80 - -LABEL RUN docker run -it --tmpfs /run --tmpfs /tmp -p 80:80 \ - -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ - -v /run/containers/pcp-nginx:/run/pcp \ - --name=pcp-nginx pcp-nginx - -STOPSIGNAL SIGRTMIN+3 -CMD ["/sbin/init"] +# +# Sample Dockerfile starting the Nginx web server with a minimal pmcd +# +# Build: $ docker build -t pcp-nginx . +# Name: $ sudo mkdir -p /run/containers/pcp-nginx +# Run: $ `docker inspect --format='{{.Config.Labels.RUN}}' pcp-nginx` +# Observe: $ pminfo --host=local:/run/containers/pcp-nginx/pmcd.socket \ +# --fetch proc network nginx +# + +FROM pcp-standalone:latest +ENV NAME pcp-nginx +ENV IMAGE pcp-nginx + +RUN dnf -y install nginx pcp-pmda-nginx && dnf clean all +RUN . /etc/pcp.conf && touch $PCP_PMDAS_DIR/nginx/.NeedInstall +COPY status.conf /etc/nginx/default.d/status.conf +RUN systemctl enable nginx +EXPOSE 80 + +LABEL RUN docker run \ +--publish 80:80 \ +--tmpfs=/run --tmpfs=/tmp \ +--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \ +--volume=/run/containers/pcp-nginx:/run/pcp \ +--name=pcp-nginx pcp-nginx + +STOPSIGNAL SIGRTMIN+3 +CMD ["/sbin/init"] diff --git a/build/containers/pcp-nginx/status.conf b/build/containers/pcp-nginx/status.conf new file mode 100644 index 000000000..3517939b5 --- /dev/null +++ b/build/containers/pcp-nginx/status.conf @@ -0,0 +1,7 @@ +location /nginx_status { + stub_status on; + access_log off; + allow 127.0.0.1; + allow ::1; + deny all; +} -- 2.11.4.GIT