Skip to content

Commit 0fde90f

Browse files
author
Ali Kanso
committed
first commit
0 parents  commit 0fde90f

File tree

12 files changed

+962
-0
lines changed

12 files changed

+962
-0
lines changed

.gitignore

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Build directories
2+
build/**
3+
*build/**
4+
build-macOS
5+
build-windows
6+
bazel-*
7+
8+
9+
# ignore local global.json setting the dotnet version
10+
global.json
11+
12+
# cygwin temp
13+
.cyg*
14+
15+
# On windows, the directory for dependent libraries
16+
packages/
17+
18+
# Vagrant-related files. Only VagrantFile should be tracked by git.
19+
.vagrant
20+
.vagrant/**
21+
22+
# Ignore any ssh keys installed in repo root
23+
.ssh/**
24+
25+
# C# generated files
26+
obj/
27+
bin/
28+
out/
29+
*.trx
30+
31+
# Code coverage generated files
32+
.coverage*
33+
!.coveragerc
34+
coverage*.xml
35+
htmlcov
36+
37+
# vim files
38+
*.sw[l-p]
39+
40+
# Mac file generated via Finder
41+
*.DS_Store
42+
43+
# For PyCharm
44+
.idea/
45+
.run/
46+
47+
48+
# Anything in bin
49+
bin/
50+
51+
# Visual Studio Code
52+
**/.vscode/*
53+
!**/.vscode/launch.json.default
54+
!**/.vscode/tasks.json.default
55+
*.code-workspace
56+
!brain.code-workspace
57+
58+
# pyenv
59+
.python-version
60+
61+
# Manual test folder
62+
*.Manual/
63+
64+
# Xcode project files generated by CMake
65+
xcode
66+
67+
# DrawNumber
68+
**/DrawNumber/Makefile
69+
**/DrawNumber/.qmake.stash
70+
**/DrawNumber/*.o
71+
**/DrawNumber/moc_*
72+
**/DrawNumber/qrc_*
73+
**/DrawNumber/DrawNumber.app/*
74+
75+
# Publishing logs
76+
*.log
77+
78+
# Cached Qt path for CMake
79+
path-to-qt.cached
80+
81+
# API token and app ids for Hockey-App
82+
deployment-tokens.json
83+
84+
# Python artefacts
85+
*.whl
86+
87+
bde.egg-info/
88+
docs/
89+
90+
# .env file used in vscode to define local environment variables
91+
.env

Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#FROM mcr.microsoft.com/dotnet/sdk:5.0 as build <-- use this image for dotnet 5.0
2+
FROM mcr.microsoft.com/dotnet/sdk:3.1 as build
3+
WORKDIR /app
4+
# copy csproj and restore as distinct layers
5+
COPY *.csproj ./
6+
RUN dotnet restore
7+
8+
# copy and build everything else
9+
COPY *.sln ./
10+
COPY src/*.cs ./
11+
12+
13+
RUN dotnet publish -c Release -o out
14+
15+
# use runtime image
16+
#FROM mcr.microsoft.com/dotnet/runtime:5.0 # <-- use this image for dotnet 5.0
17+
FROM mcr.microsoft.com/dotnet/runtime:3.1
18+
WORKDIR /app
19+
COPY --from=build /app/out .
20+
ENTRYPOINT ["dotnet", "k8s-complete.dll"]

Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
# Image URL to use all building/pushing image targets
3+
4+
IMG ?=kube-complete-example:1.0
5+
6+
# Run against the configured Kubernetes cluster in ~/.kube/config
7+
run:
8+
dotnet run
9+
10+
# Build the docker image
11+
docker-build:
12+
docker build . -t ${IMG}
13+
14+
# Push the docker image
15+
docker-push:
16+
docker push ${IMG}
17+
18+
19+
# deploy to k8s
20+
deploy:
21+
kubectl apply -f config/
22+
23+
# clean up k8s created objects
24+
cleanup:
25+
kubectl delete -f config/

README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Introduction
2+
3+
This project is just to show a more complete example of using the K8s CSharp Client library.
4+
5+
It uses the most common patterns in deployments and pods such as setting environment variables, mounting volumes, using init containers, etc.
6+
7+
8+
![overview](./media/k8s-cs-example.png)
9+
10+
11+
# Using this example within a K8s cluster
12+
13+
all the instructions below assume you are in the top directory of the repo you cloned.
14+
15+
```
16+
tree -L 1
17+
.
18+
├── Dockerfile
19+
├── Makefile
20+
├── README.md
21+
├── config
22+
├── k8s-complete.csproj
23+
├── k8s-complete.sln
24+
└── src
25+
```
26+
27+
To see the CSharp definitions of all the objects, you can look into this [file](./src/Factory.cs).
28+
29+
## Build and push Docker image, and create the K8s pod
30+
31+
To run the code as a container (or K8s pod) and avoid deploying dotnet on your local machine, you can build the code using docker build.
32+
33+
The Makefile will run the docker commands.
34+
35+
Make sure you did docker login if you intend to push to your docker registry
36+
37+
```shell
38+
make docker-build
39+
make docker-push # optional
40+
make deploy
41+
```
42+
43+
# Getting started for developers
44+
45+
make sure kubeconfig exists in `~/.kube/config`, or `KUBECONFIG` env var is set to the kube config path.
46+
47+
The namespace is of the pods to monitor is specified as an environment variable = `NAMESPACE`.
48+
49+
50+
1. Install dotnet
51+
2. dotnet restore
52+
3. dotnet run
53+
54+
## To clean up when you no longer need this functionality
55+
56+
```
57+
To cleanup after, you can use:
58+
59+
```shell
60+
make cleanup
61+
```
62+
63+
## Manual testing
64+
65+
To test that the pod is deployed properly, you can create a pod that its container periodically exits (every 60 seconds):
66+
67+
```
68+
kubectl get po
69+
NAME READY STATUS RESTARTS AGE
70+
my-deployment-6f79b686c4-qcjrb 1/1 Running 0 27m
71+
my-deployment-6f79b686c4-kcdqm 1/1 Running 0 27m
72+
my-pod 1/1 Running 0 27m
73+
```
74+
75+
```
76+
kubectl exec -ti my-deployment-6f79b686c4-qcjrb -- env
77+
HOSTNAME=my-deployment-6f79b686c4-qcjrb
78+
key1=data1-from-configmap
79+
key2=data2-from-configmap
80+
SECRET_KEY=data-from-secret
81+
ENV1=regular-env1
82+
ENV2=regular-env2
83+
SECRET_KEY_TWO=more-data-from-secret
84+
ENVFROMSECRET=data-from-secret
85+
MY_POD_IP=10.1.93.59
86+
MY_NAMESPACE=default
87+
```
88+
89+
We should see all the env variables we set from the secret, configmap, and downward API
90+
91+
```
92+
kubectl exec -ti my-deployment-6f79b686c4-qcjrb -- curl http://localhost:80
93+
<!DOCTYPE html>< html >< head >< style >body {background - color: red;}</style></head><body><h1>The Red One</h1><p>This is red nginx http server</p></body></html>
94+
```
95+
96+
We should see nginx returning to content of the configmap we mounted as index.html
97+
98+
99+

config/job.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
apiVersion: batch/v1
2+
kind: Job
3+
metadata:
4+
name: kube-complete-example
5+
spec:
6+
template:
7+
spec:
8+
restartPolicy: OnFailure
9+
containers:
10+
- name: kube-complete-example
11+
image: kube-complete-example:1.0
12+
imagePullPolicy: IfNotPresent # available options: Always, IfNotPresent, Always
13+
env:
14+
- name: NAMESPACE
15+
value: "default" # change to match the namespace of your objects e.g. kube-system, if empty, "default" is used
16+
resources:
17+
limits:
18+
cpu: "0.2"
19+
memory: "200Mi"
20+
requests:
21+
cpu: "0.1"
22+
memory: "100Mi"

config/role-binding.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: rbac.authorization.k8s.io/v1
2+
# This role binding allows service account default to read pods in the "bonsai" namespace.
3+
# You need to already have a Role named "pod-reader" in that namespace.
4+
kind: RoleBinding
5+
metadata:
6+
name: super-binder
7+
namespace: default # <-- change to match your namespace
8+
subjects:
9+
# You can specify more than one "subject"
10+
- kind: ServiceAccount
11+
name: default
12+
namespace: default # <-- change to match your namespace
13+
roleRef:
14+
# "roleRef" specifies the binding to a Role / ClusterRole
15+
kind: Role #this must be Role or ClusterRole
16+
name: super-role # this must match the name of the Role or ClusterRole you wish to bind to
17+
apiGroup: rbac.authorization.k8s.io

config/role.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: rbac.authorization.k8s.io/v1
2+
kind: Role
3+
metadata:
4+
namespace: default # <-- change to match your namespace
5+
name: super-role
6+
rules:
7+
- apiGroups: ["*"]
8+
resources: ["*"] # <-- * is too strong for a permission, change to match only the resources you wish to manipulate
9+
verbs: ["create", "delete"]

k8s-complete.csproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
<RootNamespace>c_sharp</RootNamespace>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<PackageReference Include="KubernetesClient" Version="2.0.30" />
10+
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
11+
</ItemGroup>
12+
</Project>

k8s-complete.sln

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 15
4+
VisualStudioVersion = 15.0.26124.0
5+
MinimumVisualStudioVersion = 15.0.26124.0
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "k8s-complete", "k8s-complete.csproj", "{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Debug|x64 = Debug|x64
12+
Debug|x86 = Debug|x86
13+
Release|Any CPU = Release|Any CPU
14+
Release|x64 = Release|x64
15+
Release|x86 = Release|x86
16+
EndGlobalSection
17+
GlobalSection(SolutionProperties) = preSolution
18+
HideSolutionNode = FALSE
19+
EndGlobalSection
20+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
21+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Debug|Any CPU.Build.0 = Debug|Any CPU
23+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Debug|x64.ActiveCfg = Debug|Any CPU
24+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Debug|x64.Build.0 = Debug|Any CPU
25+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Debug|x86.ActiveCfg = Debug|Any CPU
26+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Debug|x86.Build.0 = Debug|Any CPU
27+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Release|Any CPU.Build.0 = Release|Any CPU
29+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Release|x64.ActiveCfg = Release|Any CPU
30+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Release|x64.Build.0 = Release|Any CPU
31+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Release|x86.ActiveCfg = Release|Any CPU
32+
{CFD182EA-A7D1-49EE-ADC5-AB6EAE0D2F36}.Release|x86.Build.0 = Release|Any CPU
33+
EndGlobalSection
34+
EndGlobal

media/k8s-cs-example.png

49.2 KB
Loading

0 commit comments

Comments
 (0)