Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental: CentOS base container #50

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -18,3 +18,10 @@ Used by both K8s Helm chart [stackstorm-ha](https://github.com/StackStorm/stacks
- `make push` - push the Docker images for all the required StackStorm components to the private docker registry.
The following ENV vars can be passed to control the push:
- `DOCKER_TAG` (optional, ex: `2.8.0`) - tag pushed to the docker registry, defaults to ST2_VERSION when not set

## Experimental
Dockerfiles to build and push CentOS/RPM based Stackstorm images

This builds a "all-in-one" container. Services can be started/stopped for each Stackstorm component.

This is initially for review, discussion, and verifying an alternative pathway.
Comment on lines +22 to +27
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI for someone who wants to try it or may need CentOS8 Docker images and provide feedback ℹ️

162 changes: 162 additions & 0 deletions centos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# StackStorm CentOS Docker Container

This is a fork off of the the StackStorm container (https://github.com/StackStorm/st2-dockerfiles) to change the OS to CentOS instead of Ubuntu. It fixes the systemd errors associated with a CentOS container and runs the container in a non-privileged environment.

## Disclaimer
This is an experimental release of the CentOS container. The container is not guaranteed to be in a stable condition.

## TL;DR

Open `https://localhost` in a browser. The default password is `admin:admin`. The password can be changed in `conf/stackstorm.env`

## Usage

### Prerequisites
* Docker Engine 1.13.0+

### development

Stackstorm Docs link

Packs should be developed in their own repository. This is to allow StackStorm the ability to install the packs in a production environment. Eventually submodules of these packs will be added to the `packs/` directory. No packs will be allowed in the master branch unless they are submodules.


### systemd fix
There are four fixes to allowing systemd to work inside a container.
1. Mounting /run as a tmpfs
2. Mounting the /sys/fs/cgroup as a read-only volume inside the Container
3. Removing all default systemd wants and only enabling services necessary to the application
4. Entrypoint is /sbin/init
Comment on lines +24 to +29
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good info, very helpful to have it all together 👍

In the past, we tried to avoid this path as cgroup mounting is not always an option for the broader use.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appreciate the comments; I am not beholden to this approach, this is just what we figured out that worked. Open to better ideas.


## Known Issues

## Kubernetes Deployments
Below are Helm Chart snippets to run this container
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's nice to have some K8s hints!


### Values yaml
Sample of some expected Helm Values yaml
```
logLevel: INFO

# mongodb:
# host:
# mongodbDatabase:
# userName:
# password:

# rabbitmq:
# host:
# secret:
# name:
# userKey:
# passKey:

# redis:
# host:
# secret:
# name:
# passKey:

stackstorm:
# base image
image:
registry: "docker.io"
repository: "stackstorm/st2/all-in-one-st2"
tag: "3.5.0-1"
pullPolicy: "IfNotPresent"
user: "stackstorm"
password: "stanley"

# for st2web
dnsresolver:
image:
registry: docker.io
repository: janeczku/go-dnsmasq
tag: release-1.0.7

# components scaling
actionrunner:
replicas: 4
api:
replicas: 1
auth:
replicas: 1
scheduler:
replicas: 4
rulesengine:
replicas: 2
web:
replicas: 2
timersengine:
replicas: 1
stream:
replicas: 2
sensor:
replicas: 1
notifier:
replicas: 2
garbagecollector:
replicas: 1
workflowengine:
replicas: 4

st2conf:
docker: |+
[actionrunner]


# rbac:
# assignments:
# mappings:
# roles:
```


### Deployment
In the Deployment yaml for `containers`, the command to run a ST2 Component, the `st2api` as an example:

`st2api`
```
containers:
- name: st2api
image: {{ .Values.stackstorm.image.registry }}/{{ .Values.stackstorm.image.repository }}:{{ .Values.stackstorm.image.tag }}
imagePullPolicy: {{ .Values.stackstorm.image.pullPolicy }}
command:
- /opt/stackstorm/st2/bin/st2api
- --config-file=/etc/st2/st2.conf
- --config-file=/etc/st2/st2.docker.conf
- --config-file=/etc/st2/st2.user.conf
env:
value: st2api
ports:
- containerPort: 9101
protocol: TCP
name: http
```


`st2web` example:
```
containers:
- name: st2web
image: {{ .Values.stackstorm.image.registry }}/{{ .Values.stackstorm.image.repository }}:{{ .Values.stackstorm.image.tag }}
imagePullPolicy: {{ .Values.stackstorm.image.pullPolicy }}
command:
- /bin/bash
- -c
- ST2WEB_TEMPLATE='/etc/nginx/conf.d/st2-https.template' && envsubst '${ST2_AUTH_URL} ${ST2_API_URL} ${ST2_STREAM_URL}' < ${ST2WEB_TEMPLATE} > /etc/nginx/conf.d/st2.conf && exec nginx -g 'daemon off;'
env:
- name: ST2_SERVICE
value: st2web
ports:
- containerPort: 443
- name: dns-resolver
image: {{ .Values.stackstorm.dnsresolver.image.registry }}/{{ .Values.stackstorm.dnsresolver.image.repository }}:{{ .Values.stackstorm.dnsresolver.image.tag }}
imagePullPolicy: {{ .Values.stackstorm.image.pullPolicy }}
env:
- name: DNSMASQ_ENABLE_SEARCH
value: "1"
ports:
- containerPort: 53
protocol: UDP
```
216 changes: 216 additions & 0 deletions centos/base/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
FROM centos:8 AS base

# Installs all necessary development packages for a full python compilation.
RUN dnf update -y \
&& dnf groupinstall -y "development tools" \
&& dnf install epel-release -y \
&& dnf -y install dnf-plugins-core -y \
&& dnf config-manager --set-enabled powertools -y \
&& dnf install -y \
wget \
gcc \
openssl-devel \
bzip2-devel \
libffi \
libffi-devel \
epel-release \
crudini \
wget \
zlib-devel \
ncurses-devel \
sqlite-devel \
readline-devel \
tk-devel \
gdbm-devel \
libpcap-devel \
xz-devel \
expat-devel \
diffutils

## Installs Python3.7 from source - this is for running Packs with Python other than 3.6
RUN wget https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tar.xz \
&& tar -xf ./Python-3.7.6.tar.xz \
&& cd ./Python-3.7.6 \
&& ./configure \
--enable-optimizations \
--with-ensurepip=install \
# --enable-loadable-sqlite-extensions \
# --enable-shared \
# --with-system-expat \
# --with-system-ffi \
&& make -j "$(nproc)" \
&& cd ..
Comment on lines +30 to +42
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI Python 3.7 is not supported by stackstorm, not sure how it behaves even for packs
as we test with python 3.6 and 3.8.

I undersand this happens because there is no py3.6+ in EL8 package available, but building python from sources might be a non-stable approach in this scenario.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could really be any version of python. We have been running a separate python since early stackstorm at py2.x; so we built our packs with the 'major' python version at the time, py3.7.

though stackstorm itself runs with the py3.6 that the rpm installs with it.

yes, it would be great if there were updated EL8 packages for python (3.7, 3.8, etc...)


FROM centos:8 AS release

ENV container docker

ARG ST2_VERSION
ARG ST2CHATOPS_VERSION
ARG ST2WEB_VERSION

RUN : "${ST2_VERSION:?Docker build argument needs to be set and non-empty.}"

LABEL maintainer="StackStorm <info@stackstorm.com>"
LABEL com.stackstorm.vendor="StackStorm"
LABEL com.stackstorm.support="Community"
LABEL com.stackstorm.version="${ST2_VERSION}"
LABEL com.stackstorm.name="StackStorm K8s HA CentOS"
LABEL com.stackstorm.description="Docker CentOS image, optimized to run StackStorm \
components and core services with Highly Available requirements in Kubernetes environment"
LABEL com.stackstorm.url="https://stackstorm.com/#product"



ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8

RUN dnf update -y \
&& dnf install -y \
make \
glibc-langpack-en \
glibc-locale-source \
glibc-langpack-en \
glibc-locale-source \
openssl \
epel-release \
sudo \
wget \
git \
httpd-tools \
systemd \
bind \
bind-utils \
gcc \
openldap-devel \
gettext \
patch \
diffutils \
zlib-devel \
&& localedef --no-archive -i en_US -f UTF-8 en_US.UTF-8 \
&& curl -s https://packagecloud.io/install/repositories/StackStorm/stable/script.rpm.sh | bash \
&& curl -sL https://rpm.nodesource.com/setup_14.x | bash - \
&& dnf install -y \
st2-${ST2_VERSION} \
st2web-${ST2WEB_VERSION} \
st2chatops-${ST2CHATOPS_VERSION} \
crudini \
&& dnf clean expire-cache -y \
&& dnf clean all


COPY --from=base /Python-3.7.6 /Python-3.7.6

RUN cd /Python-3.7.6 \
&& make -j "$(nproc)" altinstall \
&& cd .. \
&& rm -rf /Python-3.7.6

ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8 \
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt

ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8

# Add custom st2 empty config file, used to override original st2.conf
COPY conf/st2.docker.conf /etc/st2/
COPY conf/st2.user.conf /etc/st2/
# Overrides $ST2_CONF for st2ctl to inject several config files
COPY conf/st2ctl /etc/default/
COPY conf/logging.docker.conf /etc/st2/

# Creats the encryption key for the datastore
RUN mkdir -p /etc/st2/keys \
&& st2-generate-symmetric-crypto-key --key-path /etc/st2/keys/datastore_key.json \
&& usermod -a -G st2 st2 && chgrp st2 /etc/st2/keys && chmod o-r /etc/st2/keys \
&& chgrp st2 /etc/st2/keys/datastore_key.json && chmod o-r /etc/st2/keys/datastore_key.json

# Creates stanley user
RUN mkdir -p /home/stanley/.ssh && chmod 0700 /home/stanley/.ssh \
&& ssh-keygen -f /home/stanley/.ssh/stanley_rsa -P "" \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note that generating SSH key for stanley and bundle it in a Docker image would be a dangerous way.
Though fine for a demo image.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, should do this in a separate built process

&& cat /home/stanley/.ssh/stanley_rsa.pub >> /home/stanley/.ssh/authorized_keys \
&& chown -R stanley:stanley /home/stanley/.ssh \
&& echo "stanley ALL=(ALL) NOPASSWD: SETENV: ALL" >> /etc/sudoers.d/st2 \
&& chmod 0440 /etc/sudoers.d/st2 \
&& sed -i -r "s/^Defaults\s+\+?requiretty/# Defaults +requiretty/g" /etc/sudoers

RUN dnf install dnf-plugins-core epel-release -y
# Generates nginx ssl key
RUN rpm --import http://nginx.org/keys/nginx_signing.key \
&& yum-config-manager --add-repo http://nginx.org/packages/centos/7/x86_64 \
#&& dnf update -y \
&& dnf --disablerepo='epel' install -y nginx \
&& mkdir -p /etc/ssl/st2 \
&& openssl req -x509 -newkey rsa:2048 -keyout /etc/ssl/st2/st2.key -out /etc/ssl/st2/st2.crt \
-days 365 -nodes -subj "/C=US/ST=California/L=Palo Alto/O=StackStorm/OU=Information \
Technology/CN=$(hostname)"

# Copys all in one nginx config
COPY conf/st2-base.cnf /etc/nginx/conf.d/st2-base.cnf
COPY conf/nginx.conf /etc/nginx/nginx.conf

# Setup 1ppc nginx
COPY conf/st2-https.template /etc/nginx/conf.d/st2-https.template
COPY conf/st2.conf-https.patch /tmp
RUN patch /etc/nginx/conf.d/st2-https.template < /tmp/st2.conf-https.patch

# Systemd requires a SIGRTMIN+3 signal to terminate properly.
STOPSIGNAL SIGRTMIN+3

# Remove unnecessary systemd targets
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;

# named (dns server) service
RUN systemctl enable named.service

# Adds the run directory for systemd. This directory will need to run as a
# tmpfs directory for systemd to properly work.
VOLUME /run

# Systemd enabling all st2 components to run at container start time.
# Results tracker removed https://github.com/StackStorm/st2/issues/5070
RUN systemctl enable \
st2actionrunner \
st2api \
st2auth \
st2garbagecollector \
st2notifier \
st2rulesengine \
st2sensorcontainer \
st2scheduler \
st2workflowengine \
st2timersengine \
st2workflowengine \
nginx

# Systemd runs as user st2. This changes the log files to allow st2 to run
RUN chown -R st2 /var/log/st2

# Opens ssh and https ports.
EXPOSE 22 443

# Used by all stackstorm services
VOLUME ["/etc/st2"]
WORKDIR /opt/stackstorm

COPY bin/entrypoint.sh /st2-docker/bin/entrypoint.sh

ENTRYPOINT ["/st2-docker/bin/entrypoint.sh"]

# For all-in-one docker-compose development
RUN mkdir /opt/stackstorm/packs.dev

# Update oslo/crudini
RUN source /opt/stackstorm/st2/bin/activate && pip install --upgrade oslo.config
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any more context behind updating the oslo.config?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we needed this for crudini; I'll check again...

COPY conf/st2.conf /etc/st2/st2.conf
RUN pip3.7 install virtualenv
Loading