Skip to content

Commit 2b92617

Browse files
committed
use watch instead of polling
Signed-off-by: itspooya <pooyadowlat@gmail.com>
1 parent 06bc039 commit 2b92617

File tree

9 files changed

+786
-135
lines changed

9 files changed

+786
-135
lines changed

.github/workflows/ci.yaml

Lines changed: 86 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,100 @@
11
name: ci
2+
3+
# Trigger configuration
24
on:
5+
# Run on pushes to master branch and tags
36
push:
7+
branches:
8+
- master
9+
tags:
10+
- 'v*'
11+
# Run on PRs targeting master branch
412
pull_request:
5-
create:
6-
tags: '*'
13+
branches:
14+
- master
15+
# Support manual trigger from Actions tab
16+
workflow_dispatch:
17+
18+
permissions:
19+
contents: read
20+
packages: write # Needed for pushing to container registries
721

822
jobs:
923
build:
1024
name: Build
1125
runs-on: ubuntu-latest
1226
steps:
13-
- uses: actions/checkout@v4
14-
- uses: actions/setup-go@v5
27+
- name: Checkout code
28+
uses: actions/checkout@v4
29+
with:
30+
fetch-depth: 0 # Needed for proper versioning
31+
32+
- name: Set up Go
33+
uses: actions/setup-go@v5
1534
with:
1635
go-version: '^1.22'
17-
- run: go install github.com/mattn/goveralls@latest
18-
- run: |
19-
make test
20-
make
21-
make build.docker
22-
- run: goveralls -coverprofile=profile.cov -service=github
36+
cache: true
37+
38+
- name: Run tests
39+
run: make test
40+
41+
- name: Build binary
42+
run: make
43+
44+
- name: Set up QEMU
45+
uses: docker/setup-qemu-action@v3
46+
47+
- name: Set up Docker Buildx
48+
uses: docker/setup-buildx-action@v3
49+
with:
50+
install: true
51+
52+
- name: Setup code coverage tooling
53+
run: go install github.com/mattn/goveralls@latest
54+
55+
- name: Submit code coverage
56+
run: goveralls -coverprofile=profile.cov -service=github
2357
env:
2458
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25-
- name: Push the latest Docker image
26-
run: |
27-
echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
28-
VERSION=latest make build.push
29-
if: github.ref == 'refs/heads/master'
30-
- name: Push the release Docker image
31-
run: |
32-
echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
33-
VERSION=${{ github.ref_name }} make build.push
34-
if: startsWith(github.ref, 'refs/tags/')
59+
60+
- name: Docker metadata
61+
id: meta
62+
uses: docker/metadata-action@v5
63+
with:
64+
images: |
65+
mikkeloscar/pdb-controller
66+
ghcr.io/${{ github.repository }}
67+
# Generate tags for:
68+
# - latest for master branch
69+
# - git tags
70+
# - branch name for other branches
71+
tags: |
72+
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
73+
type=semver,pattern={{version}}
74+
type=ref,event=branch
75+
76+
- name: Login to Docker Hub
77+
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')
78+
uses: docker/login-action@v3
79+
with:
80+
# Note: You need to add these secrets in your GitHub repository settings
81+
username: ${{ secrets.DOCKERHUB_USERNAME }}
82+
password: ${{ secrets.DOCKERHUB_PASSWORD }}
83+
84+
- name: Login to GitHub Container Registry
85+
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')
86+
uses: docker/login-action@v3
87+
with:
88+
registry: ghcr.io
89+
username: ${{ github.actor }}
90+
password: ${{ secrets.GITHUB_TOKEN }}
91+
92+
- name: Build and push Docker image
93+
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')
94+
uses: docker/bake-action@v4
95+
with:
96+
files: ./docker-bake.hcl
97+
push: true
98+
set: |
99+
*.tags=${{ steps.meta.outputs.tags }}
100+
*.platforms=linux/amd64,linux/arm64
Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,36 @@
11
name: golangci-lint
22
on:
33
push:
4-
tags:
5-
- v*
64
branches:
75
- master
86
- main
7+
tags:
8+
- v*
99
pull_request:
10+
11+
permissions:
12+
contents: read
13+
pull-requests: read
14+
1015
jobs:
1116
golangci:
1217
name: lint
1318
runs-on: ubuntu-latest
1419
steps:
15-
- uses: actions/checkout@v4
16-
- uses: actions/setup-go@v5
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Set up Go
26+
uses: actions/setup-go@v5
1727
with:
1828
go-version: '^1.22'
29+
cache: true
30+
1931
- name: golangci-lint
20-
uses: golangci/golangci-lint-action@v4
32+
uses: golangci/golangci-lint-action@v6
2133
with:
34+
version: v1.64
2235
args: --timeout=5m
36+
only-new-issues: true

Dockerfile

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
1-
ARG BASE_IMAGE=alpine:3.20
2-
FROM ${BASE_IMAGE}
3-
LABEL maintainer="Team Teapot @ Zalando SE <team-teapot@zalando.de>"
1+
FROM golang:1.22 as builder
42

53
ARG TARGETARCH
64

7-
# add binary
8-
ADD build/linux/${TARGETARCH}/pdb-controller /
5+
# Set working directory
6+
WORKDIR /app
7+
8+
# Copy go mod and sum files
9+
COPY go.mod go.sum ./
10+
11+
# Download all dependencies
12+
RUN go mod download
13+
14+
# Copy the source code
15+
COPY . .
16+
17+
# Build the application
18+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -a -installsuffix cgo -o pdb-controller .
19+
20+
# Use distroless as minimal base image
21+
FROM gcr.io/distroless/static:nonroot
22+
23+
LABEL maintainer="Team Teapot @ Zalando SE <team-teapot@zalando.de>"
24+
25+
# Copy the binary from builder stage
26+
COPY --from=builder /app/pdb-controller /
27+
28+
# Use non-root user
29+
USER nonroot:nonroot
930

1031
ENTRYPOINT ["/pdb-controller"]

Makefile

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,31 @@ build/linux/arm64/$(BINARY): $(SOURCES)
4545
build/osx/$(BINARY): $(SOURCES)
4646
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build $(BUILD_FLAGS) -o build/osx/$(BINARY) -ldflags "$(LDFLAGS)" .
4747

48-
build.docker: build.linux
49-
docker build --rm -t "$(IMAGE):$(TAG)" -f $(DOCKERFILE) --build-arg TARGETARCH= .
48+
# Build single-arch Docker image (amd64 by default)
49+
build.docker:
50+
docker build --rm -t "$(IMAGE):$(TAG)" -f $(DOCKERFILE) --build-arg TARGETARCH=amd64 .
5051

52+
# Build multi-architecture images using Docker Bake
53+
build.docker.multiarch:
54+
docker buildx bake --set *.tags="$(IMAGE):$(TAG)" --set *.platforms="linux/amd64,linux/arm64"
55+
56+
# Single architecture builds for development purposes
57+
build.docker.amd64:
58+
docker build --rm -t "$(IMAGE):$(TAG)" -f $(DOCKERFILE) --build-arg TARGETARCH=amd64 --platform linux/amd64 .
59+
60+
build.docker.arm64:
61+
docker build --rm -t "$(IMAGE):$(TAG)" -f $(DOCKERFILE) --build-arg TARGETARCH=arm64 --platform linux/arm64 .
62+
63+
# Push the single architecture image
5164
build.push: build.docker
5265
docker push "$(IMAGE):$(TAG)"
66+
67+
# Build and push multi-architecture images in one step using Docker Bake
68+
build.push.multiarch:
69+
VERSION="$(TAG)" REGISTRY="$(shell echo $(IMAGE) | cut -d/ -f1)" IMAGE_NAME="$(shell echo $(IMAGE) | cut -d/ -f2)" \
70+
docker buildx bake --file docker-bake.hcl --push
71+
72+
# Build and push multi-architecture images to GitHub Container Registry
73+
build.push.multiarch.ghcr:
74+
VERSION="$(TAG)" GHCR_REPOSITORY="itspooya/$(BINARY)" \
75+
docker buildx bake --file docker-bake.hcl --push

README.md

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ and was created for lack of an alternative.
1010

1111
## How it works
1212

13-
The controller simply gets all Pod Disruption Budgets for each namespace and
14-
compares them to Deployments and StatefulSets. For any resource with more than
15-
1 replica and no matching Pod Disruption Budget, a default PDB will be created:
13+
The controller uses Kubernetes informers and watch functionality to detect changes in Deployments, StatefulSets and PodDisruptionBudgets. It automatically gets all Pod Disruption Budgets for each namespace and compares them to Deployments and StatefulSets. For any resource with more than 1 replica and no matching Pod Disruption Budget, a default PDB will be created:
1614

1715
```yaml
1816
apiVersion: policy/v1beta1
@@ -59,6 +57,78 @@ Assuming Go has been setup with module support it can be built simply by running
5957
$ make
6058
```
6159

60+
### Docker Image
61+
62+
The controller is packaged as a Docker image using a multi-stage build with Google's distroless base image for enhanced security and reduced image size.
63+
64+
#### Available Container Registries
65+
66+
Images are available from multiple registries for redundancy and flexibility:
67+
68+
* Docker Hub: `mikkeloscar/pdb-controller`
69+
* GitHub Container Registry: `ghcr.io/itspooya/pdb-controller`
70+
71+
To pull the latest image:
72+
73+
```sh
74+
# From Docker Hub
75+
docker pull mikkeloscar/pdb-controller:latest
76+
77+
# From GitHub Container Registry
78+
docker pull ghcr.io/itspooya/pdb-controller:latest
79+
```
80+
81+
#### Building Docker Images
82+
83+
##### Single Architecture Image (amd64)
84+
85+
```sh
86+
make build.docker
87+
```
88+
89+
##### Multi-Architecture Image (amd64 and arm64)
90+
91+
```sh
92+
make build.docker.multiarch
93+
```
94+
95+
##### Architecture-Specific Images for Development
96+
97+
```sh
98+
make build.docker.amd64
99+
make build.docker.arm64
100+
```
101+
102+
#### Building and Pushing Images
103+
104+
##### Push Single Architecture Image
105+
106+
```sh
107+
make build.push
108+
```
109+
110+
##### Push Multi-Architecture Image
111+
112+
```sh
113+
# Push to Docker Hub
114+
make build.push.multiarch
115+
116+
# Push to GitHub Container Registry
117+
make build.push.multiarch.ghcr
118+
```
119+
120+
##### Custom Version Tag
121+
122+
```sh
123+
# For Docker Hub
124+
VERSION=v1.2.3 make build.push.multiarch
125+
126+
# For GitHub Container Registry
127+
VERSION=v1.2.3 make build.push.multiarch.ghcr
128+
```
129+
130+
The multi-architecture build process uses Docker Buildx with Docker Bake for an optimized building experience.
131+
62132
## Setup
63133

64134
The `pdb-controller` can be run as a deployment in the cluster. See
@@ -70,10 +140,6 @@ Deploy it by running:
70140
$ kubectl apply -f docs/deployment.yaml
71141
```
72142

73-
## TODO
74-
75-
* [ ] Instead of long polling, add a Watch feature.
76-
77143
## LICENSE
78144

79145
See [LICENSE](LICENSE) file.

0 commit comments

Comments
 (0)