(WIP) socialization with vanilla dockerd

Change-type: minor
This commit is contained in:
ab77 2022-03-29 09:08:29 -07:00
parent 3be25c1563
commit 5a4898367b
No known key found for this signature in database
GPG Key ID: D094F44E5E29445A
10 changed files with 240 additions and 195 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
.DS_Store .DS_Store
.balena .balena
.env

View File

@ -20,16 +20,17 @@ x-default-healthcheck: &default-healthcheck
# (TBC) source from somewhere # (TBC) source from somewhere
x-default-environment: &default-environment x-default-environment: &default-environment
COMMON_REGION: us-east-1 COMMON_REGION: ${COMMON_REGION:-us-east-1}
COUNTRY: US COUNTRY: ${COUNTRY:-US}
DNS_TLD: balena.local DNS_TLD: ${DNS_TLD:-openbalena.local}
LOCALITY_NAME: Seattle LOCALITY_NAME: ${LOCALITY_NAME:-Seattle}
MDNS_TLD: balena.local MDNS_TLD: ${MDNS_TLD:-$DNS_TLD}
ORG_UNIT: openBalena ORG_UNIT: ${ORG_UNIT:-openBalena}
ORG: balena ORG: ${ORG:-balena}
PRODUCTION_MODE: 'false' PRODUCTION_MODE: ${PRODUCTION_MODE:-false}
STATE: Washington STATE: ${STATE:-Washington}
SUPERUSER_EMAIL: admin@balena.local SUPERUSER_EMAIL: ${SUPERUSER_EMAIL:-admin@$DNS_TLD}
VERBOSE: ${VERBOSE:-true}
x-default-healthcheck-trait: &with-default-healthcheck x-default-healthcheck-trait: &with-default-healthcheck
healthcheck: healthcheck:
@ -63,8 +64,16 @@ x-network-privileges-trait: &with-network-privileges
x-base-service-definition: &base-service x-base-service-definition: &base-service
restart: unless-stopped restart: unless-stopped
extends:
service: base
services: services:
# https://docs.docker.com/compose/extends/#extending-services
base:
build: src/alpine
env_file:
- .env
# https://github.com/balena-io/open-balena-api # https://github.com/balena-io/open-balena-api
api: api:
<<: [ <<: [
@ -73,7 +82,7 @@ services:
*with-default-privileges, *with-default-privileges,
*base-service, *base-service,
] ]
image: balena/open-balena-api:build-ab77-open-balena image: balena/open-balena-api:v0.204.1
depends_on: depends_on:
- db - db
- redis - redis
@ -100,6 +109,7 @@ services:
OAUTH_CALLBACK_PROTOCOL: https OAUTH_CALLBACK_PROTOCOL: https
PORT: 80 PORT: 80
REDIS_HOST: redis:6379 REDIS_HOST: redis:6379
REDIS_IS_CLUSTER: 'false'
SENTRY_CONFIG: ',' SENTRY_CONFIG: ','
TOKEN_AUTH_JWT_ALGO: ES256 TOKEN_AUTH_JWT_ALGO: ES256
TOKENS_CONFIG: API_SERVICE_API_KEY:hex,AUTH_RESINOS_REGISTRY_CODE:hex,COOKIE_SESSION_SECRET:hex,JSON_WEB_TOKEN_SECRET:hex,MIXPANEL_TOKEN:hex,SUPERUSER_PASSWORD:hex,TOKEN_AUTH_BUILDER_TOKEN:hex,VPN_GUEST_API_KEY:hex,VPN_SERVICE_API_KEY:hex,API_VPN_SERVICE_API_KEY:API_SERVICE_API_KEY,REGISTRY2_TOKEN:TOKEN_AUTH_BUILDER_TOKEN TOKENS_CONFIG: API_SERVICE_API_KEY:hex,AUTH_RESINOS_REGISTRY_CODE:hex,COOKIE_SESSION_SECRET:hex,JSON_WEB_TOKEN_SECRET:hex,MIXPANEL_TOKEN:hex,SUPERUSER_PASSWORD:hex,TOKEN_AUTH_BUILDER_TOKEN:hex,VPN_GUEST_API_KEY:hex,VPN_SERVICE_API_KEY:hex,API_VPN_SERVICE_API_KEY:API_SERVICE_API_KEY,REGISTRY2_TOKEN:TOKEN_AUTH_BUILDER_TOKEN
@ -112,10 +122,13 @@ services:
*with-default-privileges, *with-default-privileges,
*base-service, *base-service,
] ]
image: balena/open-balena-registry:build-ab77-open-balena image: balena/open-balena-registry:v2.24.4
volumes: volumes:
- certs-data:/certs - certs-data:/certs
- resin-data:/balena - resin-data:/balena
depends_on:
- redis
- s3
environment: environment:
<<: *default-environment <<: *default-environment
HOSTS_CONFIG: REGISTRY2_HOST:registry,REGISTRY2_TOKEN_AUTH_ISSUER:api,REGISTRY2_TOKEN_AUTH_REALM:api HOSTS_CONFIG: REGISTRY2_HOST:registry,REGISTRY2_TOKEN_AUTH_ISSUER:api,REGISTRY2_TOKEN_AUTH_REALM:api
@ -136,12 +149,12 @@ services:
*with-default-privileges, *with-default-privileges,
*base-service, *base-service,
] ]
image: balena/open-balena-vpn:v11.2.0 image: balena/open-balena-vpn:v11.2.5
depends_on: depends_on:
- api - api
environment: environment:
<<: *default-environment <<: *default-environment
HOSTS_CONFIG: VPN_HOST:vpn HOSTS_CONFIG: VPN_HOST:cloudlink
SENTRY_CONFIG: ',' SENTRY_CONFIG: ','
TOKENS_CONFIG: ',' TOKENS_CONFIG: ','
VPN_HAPROXY_USEPROXYPROTOCOL: 'true' VPN_HAPROXY_USEPROXYPROTOCOL: 'true'
@ -168,7 +181,7 @@ services:
*with-default-privileges, *with-default-privileges,
*base-service, *base-service,
] ]
image: balena/open-balena-s3:build-ab77-open-balena image: balena/open-balena-s3:v2.13.5
volumes: volumes:
- s3-data:/export - s3-data:/export
- certs-data:/certs - certs-data:/certs
@ -206,18 +219,17 @@ services:
net.ipv4.ip_unprivileged_port_start: 0 net.ipv4.ip_unprivileged_port_start: 0
healthcheck: healthcheck:
<<: *default-healthcheck <<: *default-healthcheck
# (TBC) always succeeds test: true | openssl s_client -connect localhost:443
test: true | openssl s_client -connect localhost:443 -servername ${DNS_TLD}
ports: ports:
# haproxy/http # haproxy/http
- 80 - "80:80/tcp"
# haproxy/tcp-router # haproxy/tcp-router
- 443 - "443:443/tcp"
# haproxy/stats # haproxy/stats
- 1936 - "1936:1936/tcp"
# postgresql/redis # postgresql/redis
- 5432 - "5432:5432/tcp"
- 6379 - "6379:6379/tcp"
environment: environment:
<<: *default-environment <<: *default-environment
LOGLEVEL: info LOGLEVEL: info
@ -227,8 +239,13 @@ services:
haproxy-sidecar: haproxy-sidecar:
<<: *base-service <<: *base-service
build: src/haproxy-sidecar build: src/haproxy-sidecar
volumes:
# FIXME: different on balenaOS
- /var/run/docker.sock:/var/run/docker.sock
environment: environment:
<<: *default-environment <<: *default-environment
# FIXME: different on balenaOS
DOCKER_HOST: unix:///var/run/docker.sock
# resolved internally as {{service}}.{{dns-tld-without-balena-device-uuid}} to haproxy service # resolved internally as {{service}}.{{dns-tld-without-balena-device-uuid}} to haproxy service
ALIASES: api,db,delta,redis,registry,s3,stats,tunnel,vpn ALIASES: api,db,delta,redis,registry,s3,stats,tunnel,vpn
labels: labels:
@ -238,22 +255,26 @@ services:
# https://github.com/balena-io/balena-mdns-publisher # https://github.com/balena-io/balena-mdns-publisher
mdns: mdns:
<<: [ <<: [
*with-default-volumes,
*with-default-healthcheck, *with-default-healthcheck,
*with-default-privileges, *with-default-privileges,
*base-service, *base-service,
] ]
image: balena/balena-mdns-publisher:build-ab77-open-balena image: balena/balena-mdns-publisher:v1.15.0
network_mode: host network_mode: host
labels: volumes:
io.balena.features.dbus: 1 - certs-data:/certs
- resin-data:/balena
- /var/run/dbus/system_bus_socket:/host/run/dbus/system_bus_socket
environment: environment:
<<: *default-environment <<: *default-environment
DBUS_SESSION_BUS_ADDRESS: unix:path=/host/run/dbus/system_bus_socket
HOSTS_CONFIG: ',' HOSTS_CONFIG: ','
# externally advertised mDNS names as {{service}}.{{mdns-tld}} # externally advertised mDNS names as {{service}}.{{mdns-tld}}
MDNS_SUBDOMAINS: api,ca,db,delta,minio,ocsp,redis,registry,s3,stats,tunnel,vpn MDNS_SUBDOMAINS: api,ca,db,delta,minio,ocsp,redis,registry,s3,stats,tunnel,vpn
SENTRY_CONFIG: ',' SENTRY_CONFIG: ','
TOKENS_CONFIG: ',' TOKENS_CONFIG: ','
labels:
io.balena.features.dbus: 1
# https://github.com/balena-io/cert-manager # https://github.com/balena-io/cert-manager
# https://certbot.eff.org/docs/using.html # https://certbot.eff.org/docs/using.html
@ -280,7 +301,7 @@ services:
# https://github.com/cloudflare/cfssl/blob/master/doc/api/intro.txt # https://github.com/cloudflare/cfssl/blob/master/doc/api/intro.txt
balena-ca: balena-ca:
<<: *base-service <<: *base-service
image: balena/ca-private:v0.0.5 image: balena/ca-private:v0.0.6
volumes: volumes:
- pki-data:/pki - pki-data:/pki
- certs-data:/certs - certs-data:/certs
@ -300,21 +321,22 @@ services:
# only relevant when running in AWS/EC2 # only relevant when running in AWS/EC2
tag-sidecar: tag-sidecar:
build: src/tag-sidecar build: src/tag-sidecar
restart: no restart: 'no'
environment: environment:
<<: *default-environment <<: *default-environment
ENABLED: 'true' ENABLED: 'true'
labels: labels:
io.balena.features.balena-api: 1 io.balena.features.balena-api: 1
# (WIP) https://github.com/balena-io-playground/balena-nested # (WIP) https://github.com/balena-io-playground/balena-nested => balenaVirt
balena-tests: balena-tests:
<<: [ <<: [
*with-default-volumes,
*with-default-privileges, *with-default-privileges,
*base-service, *base-service,
] ]
build: src/balena-tests build:
context: src/balena-tests
dockerfile: Dockerfile.amd64
command: /usr/sbin/balena.sh command: /usr/sbin/balena.sh
depends_on: depends_on:
- api - api
@ -328,28 +350,30 @@ services:
- certs-data:/certs - certs-data:/certs
- resin-data:/balena - resin-data:/balena
- builder-certs-client:/docker-pki/client - builder-certs-client:/docker-pki/client
- /lib/modules:/lib/modules
healthcheck: healthcheck:
test: /usr/sbin/docker-hc test: /usr/sbin/docker-hc
interval: 60s interval: 60s
timeout: 60s timeout: 60s
retries: 5 retries: 5
devices: devices:
# (TBC) not supported on AWS/EC2 unless using .metal instance classes|types # Nested virtualisation support required on the host
# only supported on AMIs built on AWS Nitro System # - not supported on AWS/EC2 unless using .metal instance classes|types
# - only supported on AMIs built on AWS Nitro System
# - otherwise run 'mknod /dev/kvm b 1 1' to create a dummy kvm device and endure
- /dev/kvm:/dev/kvm - /dev/kvm:/dev/kvm
- /dev/net/tun:/dev/net/tun - /dev/net/tun:/dev/net/tun
labels: labels:
io.balena.features.balena-api: 1 io.balena.features.balena-api: 1
io.balena.features.kernel-modules: 1 io.balena.features.kernel-modules: 1
io.balena.features.supervisor-api: 1 io.balena.features.supervisor-api: 1
io.balena.features.sysfs: 1
# https://hub.docker.com/_/docker # https://hub.docker.com/_/docker
# pseudo(builder) service
docker: docker:
<<: [ <<: [
*with-extended-privileges, *with-extended-privileges,
*with-network-privileges, *with-network-privileges,
*with-default-volumes,
*with-default-privileges, *with-default-privileges,
*base-service, *base-service,
] ]
@ -358,6 +382,7 @@ services:
- builder-data:/var/lib/docker - builder-data:/var/lib/docker
- builder-certs-ca:/docker-pki/ca - builder-certs-ca:/docker-pki/ca
- builder-certs-client:/docker-pki/client - builder-certs-client:/docker-pki/client
- /sys:/sys
environment: environment:
DOCKER_TLS_CERTDIR: /docker-pki DOCKER_TLS_CERTDIR: /docker-pki
healthcheck: healthcheck:

3
src/alpine/Dockerfile Normal file
View File

@ -0,0 +1,3 @@
FROM alpine
CMD sleep infinity

@ -1 +1 @@
Subproject commit ca356fd97235243e0a4323c83663c0e651ba1c60 Subproject commit cf30f4061d7cd2a041c83b85db03a998c847f7a1

View File

@ -1,3 +1,3 @@
FROM balena/cert-manager:v0.0.14 FROM balena/cert-manager:v0.0.15
COPY *.json /opt/ COPY *.json /opt/

View File

@ -7,7 +7,13 @@ set -ea
which curl || apk add curl --no-cache which curl || apk add curl --no-cache
which jq || apk add jq --no-cache which jq || apk add jq --no-cache
network="${BALENA_APP_ID}_default" if docker inspect "${BALENA_APP_UUID}_default" --format "{{.ID}}"; then
network="${BALENA_APP_UUID}_default"
elif docker inspect "${BALENA_APP_ID}_default" --format "{{.ID}}"; then
network="${BALENA_APP_ID}_default"
else
network=open-balena_default
fi
# shellcheck disable=SC2153 # shellcheck disable=SC2153
for alias in ${ALIASES//,/ }; do for alias in ${ALIASES//,/ }; do
@ -16,28 +22,32 @@ for alias in ${ALIASES//,/ }; do
done done
while true; do while true; do
while [ "$(curl --silent --retry 3 --fail \ if [[ -n $BALENA_SUPERVISOR_ADDRESS ]] && [[ -n $BALENA_SUPERVISOR_API_KEY ]]; then
while [[ "$(curl --silent --retry 3 --fail \
"${BALENA_SUPERVISOR_ADDRESS}/v1/device?apikey=${BALENA_SUPERVISOR_API_KEY}" \ "${BALENA_SUPERVISOR_ADDRESS}/v1/device?apikey=${BALENA_SUPERVISOR_API_KEY}" \
-H "Content-Type:application/json" | jq -r '.update_pending')" = 'true' ]; do -H "Content-Type:application/json" | jq -r '.update_pending')" =~ true ]]; do
sleep "$(( (RANDOM % 3) + 3 ))s" sleep "$(( (RANDOM % 3) + 3 ))s"
done done
sleep "$(( (RANDOM % 5) + 5 ))s" sleep "$(( (RANDOM % 5) + 5 ))s"
fi
while [ "$(docker ps \ while [[ "$(docker ps \
--filter "name=haproxy_" \ --filter "name=haproxy" \
--filter "expose=1936/tcp" \
--filter "status=running" \ --filter "status=running" \
--filter "network=${network}" \ --filter "network=${network}" \
--format "{{.ID}}")" = '' ]; do --format "{{.ID}}")" == '' ]]; do
sleep "$(( (RANDOM % 3) + 3 ))s" sleep "$(( (RANDOM % 3) + 3 ))s"
done done
haproxy="$(docker ps \ haproxy="$(docker ps \
--filter "name=haproxy_" \ --filter "name=haproxy" \
--filter "expose=1936/tcp" \
--filter "status=running" \ --filter "status=running" \
--filter "network=${network}" \ --filter "network=${network}" \
--format "{{.ID}}")" --format "{{.ID}}")"
if ! [ "${restarted}" = "${haproxy}" ]; then if ! [[ $restarted == "${haproxy}" ]]; then
docker network disconnect "${network}" "${haproxy}" docker network disconnect "${network}" "${haproxy}"
# shellcheck disable=SC2086 # shellcheck disable=SC2086

View File

@ -5,6 +5,7 @@ global
# https://www.haproxy.com/blog/introduction-to-haproxy-logging/ # https://www.haproxy.com/blog/introduction-to-haproxy-logging/
log stdout format raw daemon "${LOGLEVEL}" log stdout format raw daemon "${LOGLEVEL}"
log stderr format raw daemon "${LOGLEVEL}" log stderr format raw daemon "${LOGLEVEL}"
ssl-default-bind-options ssl-min-ver TLSv1.3
defaults defaults
default-server init-addr last,libc,none default-server init-addr last,libc,none
@ -53,11 +54,14 @@ frontend http
# https://www.haproxy.com/blog/haproxy-log-customization/ # https://www.haproxy.com/blog/haproxy-log-customization/
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r" log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
acl api_dead nbsrv(api-backend) lt 1
acl registry_dead nbsrv(registry-backend) lt 1
monitor-uri /ping
monitor fail if api_dead registry_dead
acl host-api-backend hdr_beg(host) -i "api." acl host-api-backend hdr_beg(host) -i "api."
# default public device URL(s) always go to the API # default public device URL(s) always go to the API
acl host-pdu-default hdr_beg(host) -i "${BALENA_DEVICE_UUID}" acl host-pdu-default hdr(host) -m reg -i "\.?([0-9a-f]{32}|${BALENA_DEVICE_UUID})\.(devices|balena-?(.*)-devices)\."
http-request add-header X-Forwarded-Proto http if host-api-backend
http-request add-header X-Forwarded-Proto https if host-pdu-default
use_backend api-backend if host-api-backend || host-pdu-default use_backend api-backend if host-api-backend || host-pdu-default
acl host-registry-backend hdr_beg(host) -i "registry." acl host-registry-backend hdr_beg(host) -i "registry."

View File

@ -20,15 +20,16 @@ get_aws_meta() {
fi fi
} }
which curl || apk add curl --no-cache if [[ -n $BALENA_API_URL ]] && [ -n $BALENA_DEVICE_UUID ]] && [[ -n $BALENA_API_KEY ]]; then
which jq || apk add jq --no-cache which curl || apk add curl --no-cache
which jq || apk add jq --no-cache
device_id="$(curl_with_opts \ device_id="$(curl_with_opts \
"${BALENA_API_URL}/v6/device?\$filter=uuid%20eq%20'${BALENA_DEVICE_UUID}'" \ "${BALENA_API_URL}/v6/device?\$filter=uuid%20eq%20'${BALENA_DEVICE_UUID}'" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-H "Authorization: Bearer ${BALENA_API_KEY}" | jq -r .d[].id)" -H "Authorization: Bearer ${BALENA_API_KEY}" | jq -r .d[].id)"
for key in $(curl_with_opts http://169.254.169.254/latest/meta-data \ for key in $(curl_with_opts http://169.254.169.254/latest/meta-data \
| grep -Ev 'iam|metrics|identity-credentials|network|events'); do | grep -Ev 'iam|metrics|identity-credentials|network|events'); do
for kv in $(get_aws_meta "http://169.254.169.254/latest/meta-data/${key}"); do for kv in $(get_aws_meta "http://169.254.169.254/latest/meta-data/${key}"); do
tag_key="$(echo "${kv}" | awk -F';' '{print $1}')" tag_key="$(echo "${kv}" | awk -F';' '{print $1}')"
@ -39,4 +40,5 @@ for key in $(curl_with_opts http://169.254.169.254/latest/meta-data \
-H "Authorization: Bearer ${BALENA_API_KEY}" \ -H "Authorization: Bearer ${BALENA_API_KEY}" \
--data "{\"device\":\"${device_id}\",\"tag_key\":\"${tag_key}\",\"value\":\"${value}\"}" --data "{\"device\":\"${device_id}\",\"tag_key\":\"${tag_key}\",\"value\":\"${value}\"}"
done done
done done
fi