init
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.env
|
15
dokuwiki/docker-compose.yml
Normal file
15
dokuwiki/docker-compose.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
version: '3.7'
|
||||||
|
services:
|
||||||
|
dokuwiki:
|
||||||
|
image: bitnami/dokuwiki
|
||||||
|
ports:
|
||||||
|
- '8080:80'
|
||||||
|
environment:
|
||||||
|
- DOKUWIKI_USERNAME=admin
|
||||||
|
- DOKUWIKI_PASSWORD=admin
|
||||||
|
- DOKUWIKI_WIKI_NAME=amega-wiki
|
||||||
|
volumes:
|
||||||
|
- data:/bitnami'
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
data:
|
751
k8s-infra/cluster.rkestate
Normal file
751
k8s-infra/cluster.rkestate
Normal file
File diff suppressed because one or more lines are too long
42
k8s-infra/cluster.yml
Normal file
42
k8s-infra/cluster.yml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
cluster_name: k8s-stage
|
||||||
|
name: k8s-stage
|
||||||
|
# kubernetes_version: v1.19.9-rancher1-1
|
||||||
|
|
||||||
|
enable_cluster_alerting: false
|
||||||
|
enable_cluster_monitoring: false
|
||||||
|
ignore_docker_version: true
|
||||||
|
|
||||||
|
nodes:
|
||||||
|
- address: 192.168.1.10
|
||||||
|
hostname_override: node1
|
||||||
|
user: root
|
||||||
|
labels:
|
||||||
|
worker: yes
|
||||||
|
location: nsk
|
||||||
|
role: [controlplane, worker, etcd]
|
||||||
|
|
||||||
|
services:
|
||||||
|
etcd:
|
||||||
|
snapshot: true
|
||||||
|
creation: 6h
|
||||||
|
retention: 30h
|
||||||
|
kube-controller:
|
||||||
|
extra_args:
|
||||||
|
terminated-pod-gc-threshold: 100
|
||||||
|
kubelet:
|
||||||
|
extra_args:
|
||||||
|
max-pods: 250
|
||||||
|
volume-plugin-dir: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
|
||||||
|
# For prometheus
|
||||||
|
authorization-mode: Webhook
|
||||||
|
authentication-token-webhook: true
|
||||||
|
extra_binds:
|
||||||
|
- /usr/libexec/kubernetes/kubelet-plugins/volume/exec:/usr/libexec/kubernetes/kubelet-plugins/volume/exec
|
||||||
|
# kube-api:
|
||||||
|
# extra_args:
|
||||||
|
# feature-gates: "ServiceAccountIssuerDiscovery=false,RemoveSelfLink=false"
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
provider: nginx
|
||||||
|
options:
|
||||||
|
use-forwarded-headers: "true"
|
19
k8s-infra/kube_config_cluster.yml
Normal file
19
k8s-infra/kube_config_cluster.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Config
|
||||||
|
clusters:
|
||||||
|
- cluster:
|
||||||
|
api-version: v1
|
||||||
|
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM0VENDQWNtZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFTTVJBd0RnWURWUVFERXdkcmRXSmwKTFdOaE1CNFhEVEl4TURrek1ERTBNREExT0ZvWERUTXhNRGt5T0RFME1EQTFPRm93RWpFUU1BNEdBMVVFQXhNSAphM1ZpWlMxallUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU42LzU5cW5Mc1pECk9BMVdjYlhSTXFGV2dsdW1QVnpmbkhUTTVJNzhiMFg4aElEc3lvcm8xSUNnTTZHTkZueThEZ0RzRFVYYWNETFUKL2U4U1o0Q2tFUjZlcVJlMnBJUitETk5SWUpHY1p6Z09HWVY4TlZIeXNaYkFFcGNuWkdTeTBUQnVWWmt4US8wRgpmU0NHRVVpeHc3VjJmL1ZsaVIvbjNZeUNORFRDeUxxVTlKaStqNEVORWVHc1VKUmxOekNCRHFDMGhQMGZNNHp4CmNKRzMrWVJKdDI0L3g2NnNHVGl0WXVYZFFhUUNHdjI1TEN0Y1lSRWgyUWtUVkZzWGlBZFp1bXloTCt4b1VzRzgKU1NpT1RXVk5PMmkwU0JEdXFOT2FERG1BOWZ5ejEwYklHSW1QUHM5dkx1ME9HT1MzOHNpaGJFZmlkVmJzNkdCWAp0cXN2Rm84cVMzTUNBd0VBQWFOQ01FQXdEZ1lEVlIwUEFRSC9CQVFEQWdLa01BOEdBMVVkRXdFQi93UUZNQU1CCkFmOHdIUVlEVlIwT0JCWUVGQmpRNUFQekhUOWRUdG9OSHVWNVFsUnFtcVc3TUEwR0NTcUdTSWIzRFFFQkN3VUEKQTRJQkFRQmR6Zzg2dkZ4bGlxbnovd2pORjUzKzR5cVduQUViMDhyK254MEdMVExodTBNaG5PcFRzWTUva3FLWgovandkck4yRTVCZURHdjA5bHVtUjVRSnRzM0R1bUx4d0lqNm9OTE1Eb2lxQ21kZXlKNlh3SHIzb2VucEFmOG1jCis4U3NPR0tLWlFvRGNxdnA4MVhNNWtiRmFZdVZ5d0tUQ09kR1pPVEFFWFBIWXloS2dhcWtkQ2pNdEsrQjlKY3AKanpwQ0hFRnFIN1YwSDZGbDRnT3dnZHJHTUc0bTA0cUNDSkNCV1RMNG4yL0Z2S3gwOHcyTHluSG12VmlJY0QxZQp0ZUM2dEN4VVMvaTNZV0ROQTh2RS9hRlp0ck82T0Y5dnVuQlNZZVpjZzJUN3ZJUWVBUk4vR2NWR01na21FV2t2CmxCYXNKK2V4RjBYUG1lY1hPbXVKRUdXS2dUQWsKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||||
|
server: "https://192.168.1.10:6443"
|
||||||
|
name: "k8s-stage"
|
||||||
|
contexts:
|
||||||
|
- context:
|
||||||
|
cluster: "k8s-stage"
|
||||||
|
user: "kube-admin-k8s-stage"
|
||||||
|
name: "k8s-stage"
|
||||||
|
current-context: "k8s-stage"
|
||||||
|
users:
|
||||||
|
- name: "kube-admin-k8s-stage"
|
||||||
|
user:
|
||||||
|
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURDakNDQWZLZ0F3SUJBZ0lJUWdybjJWYm5rQjh3RFFZSktvWklodmNOQVFFTEJRQXdFakVRTUE0R0ExVUUKQXhNSGEzVmlaUzFqWVRBZUZ3MHlNVEE1TXpBeE5EQXdOVGhhRncwek1UQTVNamd4TkRBMU1EVmFNQzR4RnpBVgpCZ05WQkFvVERuTjVjM1JsYlRwdFlYTjBaWEp6TVJNd0VRWURWUVFERXdwcmRXSmxMV0ZrYldsdU1JSUJJakFOCkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXhyY2taQVlmV0VWOE9RN2d2dm5SVGFnaFFCOCsKOGJJQ043OHh6K3dpbTUvNWhLL0pUWG44cVZLZ2JuVFFuZTJHSU9GV0JyK29oNkxoVjdHS0tpV1k5WmFEbzExRAplRWY5OERlWng2Y2VqZUh3dktwbDROdXZGZllRYU9mdm9jTG52VEdGNzlPSHF6TTU0cWc3Ry9YQXliYVVXWTk1CkVWaWtCSXIzM1RUTE1FR0pyaTI1V1VLazE0UEpFV0lqSjB2VEI5cm1sK3cycXFLT1lJM2ZDMllET0ZxeHZ5ZE4KeEM0ajhpUEhlYnVDSmNmbzdHcXh3bEYyL3FsZzdwNk1SWlRmeElBb1dWdk1tOXdkWHFoRndla0RqWHlpV3FDeQpiNUE5NHBTNGVia09qelY2cExUa016OTVTL2Y2ZzRJRVZqbDBnSGRlcE9LTms0M1hKMkh0cjFPazJ3SURBUUFCCm8wZ3dSakFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUhBd0l3SHdZRFZSMGoKQkJnd0ZvQVVHTkRrQS9NZFAxMU8yZzBlNVhsQ1ZHcWFwYnN3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUMyNApmMW8yckJHZGZ3U0FJMVVya0VsaTFqTzRhV3pGWHhmeng2NHJTbE9jSjIrZmpYRFNDc3ozbEhrdEFSMEM3eTBoCjRUMGZ5WWZDQ2FLQ1YwcE9VUVJVRDZJNzRiajEvOHNzYXNKYXAwbmZwY2Z3THFkME1jamZnZXkxMkpNelNTNGEKMEhiNFFCU3RHd1pBd3FwTEh3SndIVTc4bkRCUW5jdnlrVjUzNzNWYjVlUHBERHZYL2hNK3Nud2M0aHhrTlArMgpyRzY2U3VJZnRCZTZWZGk4UFBLakpITDVJZGlFdU8raHdQOW1GN21nTnY2My96dnlWTmVpVFNYWlluL3ZrTWlWCjZ1WnI0a3M4QjA1RHpQVVlPR1pUN2w2YUVoaUx5L0VWS1N5eE92dG5YNGxFcUlHZ2hsbkhHaGhUSDBPdnRHYkIKblJScnluQkFZb0w2Y2tUTnN6MD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||||
|
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb1FJQkFBS0NBUUVBeHJja1pBWWZXRVY4T1E3Z3Z2blJUYWdoUUI4KzhiSUNONzh4eit3aW01LzVoSy9KClRYbjhxVktnYm5UUW5lMkdJT0ZXQnIrb2g2TGhWN0dLS2lXWTlaYURvMTFEZUVmOThEZVp4NmNlamVId3ZLcGwKNE51dkZmWVFhT2Z2b2NMbnZUR0Y3OU9IcXpNNTRxZzdHL1hBeWJhVVdZOTVFVmlrQklyMzNUVExNRUdKcmkyNQpXVUtrMTRQSkVXSWpKMHZUQjlybWwrdzJxcUtPWUkzZkMyWURPRnF4dnlkTnhDNGo4aVBIZWJ1Q0pjZm83R3F4CndsRjIvcWxnN3A2TVJaVGZ4SUFvV1Z2TW05d2RYcWhGd2VrRGpYeWlXcUN5YjVBOTRwUzRlYmtPanpWNnBMVGsKTXo5NVMvZjZnNElFVmpsMGdIZGVwT0tOazQzWEoySHRyMU9rMndJREFRQUJBb0lCQUVCZVlOWlp1VnVSbm95cApDaG95dUI3c29HQ3gvbVN5WWMrSENtNnNzZ1V4UzlVMFVBUGR5UDljT1lXdUowbVJBRXEwVTNaNkxQQkt6YTNuClg3Y0pXTVBzenBWamg1QjEyWWN2cTR1bDBkcnAzbDV1My9OM2xmNktKNFNqNU5iRVdPYkxIUFN6MDVXY1VWcmYKWGM1UHkvUkxSVURCbmRrRm1wT3lKRm91V01jM1VVV09RbFIzUzFaKzBSeUp3TnFMVCtaK2VzQnZ6NzV1eGNMVQpxSUdUUjg4RmtvNFUxYjZxQ1BMRk1Da0k3ZENZZ1BSTndhZkRjT0JaTlpHcFM5VGxkRjFnbGJCenlldlk3Rk1jCm1iK056ejlGN0JRVXRzR0VlR3M1TGN5b3A0WEFNVDQrMjRoZEJIZmlqZ0pOZnVTL2E0TmtiY0RaTGFNY1UxSlEKaUVWZUQxRUNnWUVBMXhaN1hHK3N2K21oa1hPVktZUWVJODlMRXB6citZMUdLaUpzZGdTcFJFdUg5Sy9iaEx5MgpZQm5OdTBwTnZWTDlJdE5mUTZnWDJRQ0RnTGl4eGU5VXIrOVpZOEZDNllLeWxPK0UwTmxjNUR3Y1RHakRkV3pOCjNEVVNwZ3dBa0tzVjhObTNYWmVuWG51ZGc2Wm1EbnBqMm0reEVOWTY5UlJQTzVYT2xTeUxWVWtDZ1lFQTdJTnIKVUJYREYvbzMxem1JTElqbVl1MFhtTnMzLzB3a3ZMQWhpZkhMSFk5dkU0Q3VqL3YwUkQxRW9xRmZleE9ScmhRagozOGF3L2tsR095WWhGN3VSR1hRRVdjKzdSK1EvMC9Kd0FqemJZMjBNczlYL21LZjlHUFFxbnJtRWxuWmd2Yi94CmJ1N3diVHozNGlxTHZxWlpXdVFNYitzeTk2elEzYVRsVStHbGZRTUNmMDRpM0syMzVBblQxZDRCSHk3MXovMHkKVVJOeDdrZTZDc05EdmlNaGpseEJGQ0xQdis5NG5zaEtsM0p5aThzN1dycE1EMCtFd1NVVUNyRzRadHlCRlVMVQpzS1NNa01KRHVKeGladDE0R1ViUWozY3lsODhRdDdoSGozN0MzWEd3dFVmSno5TXdSSjBPU3lxSVNJcjU2MHh2ClJ1UFc3NVFZeksvWXZETjAreWtDZ1lCSTdYejVoTHhUZUdRZmlTM2tEWko4am43b016QmhHQ2w3eFJPU1pXd3MKQVQ1TzFTNytWc0pMQ0ZsUmpGRFVzb1FKR1V5Mmc1MnZ5d2hNMU1UL2ZHYVJZcVMwek1rQ3NlNjhlOVR0MjdZSwpRbVhZVGZReUxocHN4MTBjOURkZDdjS0d2OWpDVEFyMnBBWUxSdk13SmpzSE82cGFHRHZ2QXVxa2JXUUpLVnJOCjRRS0JnUUNNSExYdFJGejl0bTRPNHVLck1FMlJnS0UvTXc5RDBISHBURS8rWUgzT0ZkenVxVjV6RW8wOW5PWXcKSjBuWFd4SURxWmo3VGlEWDdWdlM3R2FtQnkzWHhDTXBnMDVIbXN2RWRCTEhDdWpVaVBBcExMaDBDYUJJaXgyOQphbWtHZDZPRzRlY2o0dHBqOHFRRjFJWndSWDNaY3pvK0VaZWJ0bzdObVpoNU0vL3BvUT09Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
|
18
traefik-repo/readme.MD
Normal file
18
traefik-repo/readme.MD
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Traefik docker + api clients
|
||||||
|
|
||||||
|
- [Сам traefik](traefik/readme.MD) + сервис traefik-api для отдачи готовых сертификатов на сторону
|
||||||
|
- [клиент](traefik-api-client/readme.MD) для получения сертификатов через traefik-api по токену
|
||||||
|
- [клиент](traefik-ssh-client/readme.MD) для получаения сертификатов через ssh
|
||||||
|
- [пример](traefik-k8s/readme.MD) деплоя в k8s с автоматическим управлением DNS
|
||||||
|
|
||||||
|
## Видео к курсу
|
||||||
|
|
||||||
|
- [видео]
|
||||||
|
- [презентация]
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
|
||||||
|
- **Vassiliy Yegorov** [vasyakrg](https://github.com/vasyakrg)
|
||||||
|
- [сайт](https://realmanual.ru)
|
||||||
|
- [канал в телеге](https://t.me/realmanual)
|
||||||
|
- [чат в телеге для вопросов](https://t.me/realmanual_group)
|
12
traefik-repo/traefik-api-client/.env.example
Normal file
12
traefik-repo/traefik-api-client/.env.example
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
API_SERVER=https://traefik-api.domain.ru/api/v1/certman/getcerts
|
||||||
|
|
||||||
|
TOKEN=
|
||||||
|
DOMAIN=
|
||||||
|
|
||||||
|
DEBUG=false
|
||||||
|
|
||||||
|
CERT_NAME=cert.pem
|
||||||
|
KEY_NAME=key.pem
|
||||||
|
|
||||||
|
PATH_TO_COPY=/etc/letsencrypt
|
||||||
|
SERVICE_RESTART=nginx
|
3
traefik-repo/traefik-api-client/.gitignore
vendored
Normal file
3
traefik-repo/traefik-api-client/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.env
|
||||||
|
*.pem
|
||||||
|
*.bak
|
73
traefik-repo/traefik-api-client/getcert.sh
Normal file
73
traefik-repo/traefik-api-client/getcert.sh
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "[ START ] on $(date +'%d-%m-%Y_%H-%M')"
|
||||||
|
|
||||||
|
function checkMD() {
|
||||||
|
local new=$1
|
||||||
|
local old=$2
|
||||||
|
|
||||||
|
[[ ! -f ${old} ]] && return 1
|
||||||
|
|
||||||
|
$(diff $old $new > /dev/null)
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ ! -f .env ]] && {
|
||||||
|
cp .env.example .env
|
||||||
|
apt update && apt install jq curl -y
|
||||||
|
[[ ! $? -eq 0 ]] && exit 1
|
||||||
|
|
||||||
|
echo "Init complete, please check env in .env and rerun script again"
|
||||||
|
echo "==="
|
||||||
|
cat .env
|
||||||
|
echo "==="
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
source .env
|
||||||
|
|
||||||
|
CP=0
|
||||||
|
case ${DEBUG} in
|
||||||
|
true) DEBUG_CURL="-v";;
|
||||||
|
false) DEBUG_CURL="-s";;
|
||||||
|
*) DEBUG_CURL="-s";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[[ ! -z $1 ]] && DOMAIN=$1
|
||||||
|
|
||||||
|
[[ ! -d ${PATH_TO_COPY} ]] && {
|
||||||
|
echo "Dir for cert nof found, created"
|
||||||
|
mkdir $PATH_TO_COPY || exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
CERT=$(curl ${DEBUG_CURL} $API_SERVER -X POST -H "Authorization: Bearer $TOKEN" --form "domain=$DOMAIN" | jq -r '.data.chain')
|
||||||
|
[[ ! $? -eq 0 ]] && exit 1
|
||||||
|
echo -e $CERT > $CERT_NAME
|
||||||
|
|
||||||
|
KEY=$(curl ${DEBUG_CURL} $API_SERVER -X POST -H "Authorization: Bearer $TOKEN" --form "domain=$DOMAIN" | jq -r '.data.key')
|
||||||
|
[[ ! $? -eq 0 ]] && exit 1
|
||||||
|
echo -e $KEY > $KEY_NAME
|
||||||
|
|
||||||
|
CERTS=( $CERT_NAME $KEY_NAME )
|
||||||
|
|
||||||
|
for FILE in ${CERTS[*]}; do
|
||||||
|
if ! checkMD $FILE $PATH_TO_COPY/$FILE; then
|
||||||
|
cp $PATH_TO_COPY/$FILE $PATH_TO_COPY/$FILE.bak
|
||||||
|
cp $FILE $PATH_TO_COPY/$FILE
|
||||||
|
[[ $? -eq 0 ]] && ((CP=CP+1))
|
||||||
|
echo "$FILE updated"
|
||||||
|
else
|
||||||
|
echo "update $FILE not needed"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ ! $CP == 0 ]] && {
|
||||||
|
systemctl restart $SERVICE_RESTART
|
||||||
|
[[ ! $? -eq 0 ]] && echo "service not restarted, restart manually"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "delete tempary files"
|
||||||
|
rm $CERT_NAME $KEY_NAME
|
||||||
|
|
||||||
|
echo "[ END ] on $(date +'%d-%m-%Y_%H-%M')"
|
||||||
|
echo ""
|
30
traefik-repo/traefik-api-client/readme.MD
Normal file
30
traefik-repo/traefik-api-client/readme.MD
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Traefik-client
|
||||||
|
|
||||||
|
- Вытягивает с [traefik-api](../traefik/readme.MD) сертификаты и перезапускает нужный сервис
|
||||||
|
|
||||||
|
1. Можно запустить с указанием домена, это переназначит поведение, указанное в `.env`
|
||||||
|
|
||||||
|
**Пример**:
|
||||||
|
|
||||||
|
```
|
||||||
|
./getcert.sh domain.ru
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Первый запуск создаст `.env` и заполнит его дефолтными параметрами, после чего скрипт завершит работу и попросит дозаполнить переменные.
|
||||||
|
|
||||||
|
**Нужно указать:**
|
||||||
|
|
||||||
|
```
|
||||||
|
API_SERVER=https://traefik-api.domain.ru/api/v1/certman/getcerts - полный путь к АПИ и методу
|
||||||
|
TOKEN= - токен
|
||||||
|
DOMAIN= - домен, сертификаты которого надо захватить
|
||||||
|
DEBUG=false - определяет уровень логирования curl
|
||||||
|
CERT_NAME=cert.pem - определяет имя файла создаваемого в нужной точке на сервере
|
||||||
|
KEY_NAME=key.pem - определяет имя файла создаваемого в нужной точке на сервере
|
||||||
|
PATH_TO_COPY=/etc/letsencrypt - определяет точку, куда нужно сложить сертификаты, без / на конце
|
||||||
|
SERVICE_RESTART=nginx - определяет какой сервис нужно рестартануть после подмены ключей
|
||||||
|
```
|
||||||
|
|
||||||
|
## Примечания
|
||||||
|
- Ключи не заменяются, если они идентичны.
|
||||||
|
- Сервис не перезапустится, если ключи не изменялись с моменты последнего импорта.
|
6
traefik-repo/traefik-k8s/1.ingress-controller.yaml
Normal file
6
traefik-repo/traefik-k8s/1.ingress-controller.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: IngressClass
|
||||||
|
metadata:
|
||||||
|
name: traefik-lb
|
||||||
|
spec:
|
||||||
|
controller: traefik.io/ingress-controller
|
71
traefik-repo/traefik-k8s/2.external-dns.yaml
Normal file
71
traefik-repo/traefik-k8s/2.external-dns.yaml
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: external-dns
|
||||||
|
namespace: external-dns
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: external-dns
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: external-dns
|
||||||
|
spec:
|
||||||
|
serviceAccountName: external-dns
|
||||||
|
containers:
|
||||||
|
- name: external-dns
|
||||||
|
image: k8s.gcr.io/external-dns/external-dns:v0.7.6
|
||||||
|
args:
|
||||||
|
- --source=ingress # ingress is also possible, or service
|
||||||
|
- --domain-filter=domain.ru # (optional) limit to only example.com domains; change to match the zone created above.
|
||||||
|
- --provider=hetzner # [link](https://github.com/kubernetes-sigs/external-dns)
|
||||||
|
- --txt-owner-id=bttrm-eks-dev-1-external-dns # Key from you mind
|
||||||
|
- --log-level=info
|
||||||
|
- --interval=30s
|
||||||
|
env:
|
||||||
|
- name: HETZNER_TOKEN
|
||||||
|
value: "" # real token from API Dashboard
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: external-dns
|
||||||
|
namespace: external-dns
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: external-dns
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["services","endpoints","pods"]
|
||||||
|
verbs: ["get","watch","list"]
|
||||||
|
- apiGroups: ["extensions","networking.k8s.io"]
|
||||||
|
resources: ["ingresses"]
|
||||||
|
verbs: ["get","watch","list"]
|
||||||
|
- apiGroups: ["networking.k8s.io"]
|
||||||
|
resources: ["ingresses"]
|
||||||
|
verbs: ["get", "list", "update", "patch"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["pods"]
|
||||||
|
verbs: ["get","watch","list"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["nodes"]
|
||||||
|
verbs: ["list"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: external-dns-viewer
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: external-dns
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: external-dns
|
||||||
|
namespace: external-dns
|
102
traefik-repo/traefik-k8s/3.deploy.yaml
Normal file
102
traefik-repo/traefik-k8s/3.deploy.yaml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: nginx
|
||||||
|
namespace: test
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: nginx
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: nginx
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: nginx-service
|
||||||
|
namespace: test
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: nginx
|
||||||
|
type: NodePort
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
||||||
|
nodePort: 31080
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: nginx-endpoint
|
||||||
|
namespace: test
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/service.serversscheme: "http"
|
||||||
|
traefik.ingress.kubernetes.io/service.passhostheader: "true"
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
clusterIP: None
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Endpoints
|
||||||
|
metadata:
|
||||||
|
name: nginx-endpoint
|
||||||
|
namespace: test
|
||||||
|
subsets:
|
||||||
|
- addresses:
|
||||||
|
- ip: 192.168.1.201
|
||||||
|
ports:
|
||||||
|
- port: 31080
|
||||||
|
- addresses:
|
||||||
|
- ip: 192.168.1.202
|
||||||
|
ports:
|
||||||
|
- port: 31080
|
||||||
|
- addresses:
|
||||||
|
- ip: 192.168.1.203
|
||||||
|
ports:
|
||||||
|
- port: 31080
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
baremetal-ingress: traefik-nsk
|
||||||
|
annotations:
|
||||||
|
kubernetes.io/ingress.class: traefik-lb
|
||||||
|
external-dns.alpha.kubernetes.io/hostname: lb.domain.ru
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: https
|
||||||
|
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||||
|
traefik.ingress.kubernetes.io/router.tls.certresolver: letsEncrypt
|
||||||
|
name: nginx-ingress
|
||||||
|
namespace: test
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: lb.domain.ru
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- pathType: Prefix
|
||||||
|
path: "/"
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: nginx-endpoint
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
---
|
5
traefik-repo/traefik-k8s/readme.MD
Normal file
5
traefik-repo/traefik-k8s/readme.MD
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Пример деплоя в связке с Traefik
|
||||||
|
|
||||||
|
- создаем ингресс-контроллер
|
||||||
|
- подключаем сервис для автоматического управления внешним DNS
|
||||||
|
- деплоим приложение, учитывая то, что там надо запустить еще один сервис (без селектора на приложение) и переопределить для него эндпоинты с адресами нод кластера и нод-портами на них
|
16
traefik-repo/traefik-ssh-client/getcert.sh
Normal file
16
traefik-repo/traefik-ssh-client/getcert.sh
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source .env
|
||||||
|
|
||||||
|
echo "[ START ] on $(date +'%d-%m-%Y_%H-%M')"
|
||||||
|
|
||||||
|
scp ${REMOTE_TRAEFIK}:${REMOTE_PATH}/${DOMAIN}/cert.pem ${DEST_PATH}/${PEM}
|
||||||
|
[ ! $? ] && exit 1
|
||||||
|
scp ${REMOTE_TRAEFIK}:${REMOTE_PATH}/${DOMAIN}/privkey.pem ${DEST_PATH}/${KEY}
|
||||||
|
[ ! $? ] && exit 1
|
||||||
|
|
||||||
|
systemctl restart $SERVICE_RESTART
|
||||||
|
[[ ! $? -eq 0 ]] && echo "service not restarted, you need restart manually"
|
||||||
|
|
||||||
|
echo "[ END ]"
|
||||||
|
echo ""
|
23
traefik-repo/traefik-ssh-client/readme.MD
Normal file
23
traefik-repo/traefik-ssh-client/readme.MD
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Traefik-client
|
||||||
|
|
||||||
|
- Вытягивает с [traefik-api](../traefik/readme.MD) сертификаты через `ssh`.
|
||||||
|
- Перезапускает нужный сервис
|
||||||
|
|
||||||
|
1. Заполняем `.env` файл нужными значениями.
|
||||||
|
2. Генерируем на машине, которой нужны сертификаты, ssh-ключ, чтобы ходить на машину с `traefik`
|
||||||
|
|
||||||
|
```
|
||||||
|
ssh-keygen
|
||||||
|
```
|
||||||
|
|
||||||
|
3. копируем их на машину с `traefik`
|
||||||
|
|
||||||
|
```
|
||||||
|
ssh-copy-id root@traefik_ip
|
||||||
|
```
|
||||||
|
|
||||||
|
4. настраиваем `crontab` на регулярные обновления
|
||||||
|
|
||||||
|
```
|
||||||
|
30 07 * *\1 * cd /srv/services/traefik-client/ && ./getcert.sh
|
||||||
|
```
|
3
traefik-repo/traefik/.env.example
Normal file
3
traefik-repo/traefik/.env.example
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
DOMAIN=traefik.domain.ru
|
||||||
|
DOMAIN_API=traefik-api.domain.ru
|
||||||
|
ADMIN_TOKEN=123123
|
7
traefik-repo/traefik/.gitignore
vendored
Normal file
7
traefik-repo/traefik/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
acme.json
|
||||||
|
stdout.log
|
||||||
|
certs/*
|
||||||
|
api/logs/*
|
||||||
|
/logs/*
|
||||||
|
basic.auth
|
||||||
|
.env
|
3
traefik-repo/traefik/data/basic.auth.example
Normal file
3
traefik-repo/traefik/data/basic.auth.example
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# admin \ admin
|
||||||
|
|
||||||
|
admin:$apr1$edqYaaX4$LcYGU242kPrNQVKBZpQ8x.
|
6
traefik-repo/traefik/data/custom/middlewares.yml
Normal file
6
traefik-repo/traefik/data/custom/middlewares.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
redirect-to-https:
|
||||||
|
redirectScheme:
|
||||||
|
scheme: https
|
||||||
|
permanent: true
|
15
traefik-repo/traefik/data/custom/pve.domainru.yml.example
Normal file
15
traefik-repo/traefik/data/custom/pve.domainru.yml.example
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
tcp:
|
||||||
|
routers:
|
||||||
|
pve:
|
||||||
|
entryPoints:
|
||||||
|
- https
|
||||||
|
rule: "HostSNI(`pve.domain.ru`)"
|
||||||
|
service: pve-service
|
||||||
|
tls:
|
||||||
|
certResolver: letsEncrypt
|
||||||
|
passthrough: true
|
||||||
|
services:
|
||||||
|
pve-service:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- address: 192.168.1.2:8006
|
32
traefik-repo/traefik/data/custom/rke.domain.ru.yml.example
Normal file
32
traefik-repo/traefik/data/custom/rke.domain.ru.yml.example
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
http:
|
||||||
|
routers:
|
||||||
|
rke:
|
||||||
|
entryPoints:
|
||||||
|
- https
|
||||||
|
rule: Host(`rke.domain.ru`)
|
||||||
|
service: rke-service
|
||||||
|
tls:
|
||||||
|
certResolver: letsEncrypt
|
||||||
|
services:
|
||||||
|
rke-service:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://192.168.9.200
|
||||||
|
passHostHeader: true
|
||||||
|
|
||||||
|
tcp:
|
||||||
|
routers:
|
||||||
|
rke-api:
|
||||||
|
entryPoints:
|
||||||
|
- k8s-api
|
||||||
|
rule: "HostSNI(`*`)"
|
||||||
|
service: rke-api-service
|
||||||
|
tls:
|
||||||
|
passthrough: true
|
||||||
|
services:
|
||||||
|
rke-api-service:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- address: 192.168.9.201:6443
|
||||||
|
- address: 192.168.9.202:6443
|
||||||
|
- address: 192.168.9.203:6443
|
@@ -0,0 +1,20 @@
|
|||||||
|
http:
|
||||||
|
routers:
|
||||||
|
s3-minio:
|
||||||
|
entryPoints:
|
||||||
|
- https
|
||||||
|
rule: Host(`s3.domain.ru`)
|
||||||
|
service: s3-minio-service
|
||||||
|
tls:
|
||||||
|
certResolver: letsEncrypt
|
||||||
|
services:
|
||||||
|
s3-minio-service:
|
||||||
|
loadBalancer:
|
||||||
|
healthCheck:
|
||||||
|
path: /health/live
|
||||||
|
scheme: http
|
||||||
|
servers:
|
||||||
|
- url: http://192.168.1.3:9000
|
||||||
|
- url: http://192.168.1.4:9000
|
||||||
|
- url: http://192.168.1.5:9000
|
||||||
|
- url: http://192.168.1.6:9000
|
54
traefik-repo/traefik/data/traefik.yml
Normal file
54
traefik-repo/traefik/data/traefik.yml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
global:
|
||||||
|
checkNewVersion: true
|
||||||
|
|
||||||
|
# pilot:
|
||||||
|
# token: ""
|
||||||
|
|
||||||
|
serversTransport:
|
||||||
|
insecureSkipVerify: true
|
||||||
|
|
||||||
|
api:
|
||||||
|
dashboard: true
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
http:
|
||||||
|
address: ":80"
|
||||||
|
https:
|
||||||
|
address: ":443"
|
||||||
|
# k8s-api:
|
||||||
|
# address: ":6443"
|
||||||
|
# metrics:
|
||||||
|
# address: ":8082"
|
||||||
|
|
||||||
|
# metrics:
|
||||||
|
# prometheus:
|
||||||
|
# entryPoint: metrics
|
||||||
|
|
||||||
|
providers:
|
||||||
|
docker:
|
||||||
|
endpoint: "unix:///var/run/docker.sock"
|
||||||
|
exposedByDefault: false
|
||||||
|
# file:
|
||||||
|
# directory: /custom
|
||||||
|
# watch: true
|
||||||
|
# kubernetesIngress:
|
||||||
|
# endpoint: "https://rke.domain.ru/k8s/clusters/c-xxxxx"
|
||||||
|
# token: "" # Token from Rancher
|
||||||
|
# ingressClass: "traefik-lb"
|
||||||
|
# ingressEndpoint:
|
||||||
|
# ip: "" # you external IP
|
||||||
|
|
||||||
|
certificatesResolvers:
|
||||||
|
letsEncrypt:
|
||||||
|
acme:
|
||||||
|
email: vasyakrg@gmail.com
|
||||||
|
storage: acme.json
|
||||||
|
httpChallenge:
|
||||||
|
entryPoint: http
|
||||||
|
hetzner:
|
||||||
|
acme:
|
||||||
|
email: vasyakrg@gmail.com
|
||||||
|
storage: acme-hetzner.json
|
||||||
|
dnsChallenge:
|
||||||
|
provider: hetzner
|
||||||
|
delayBeforeCheck: 30
|
66
traefik-repo/traefik/docker-compose.yml
Normal file
66
traefik-repo/traefik/docker-compose.yml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
version: '3.7'
|
||||||
|
services:
|
||||||
|
traefik:
|
||||||
|
image: traefik
|
||||||
|
container_name: traefik
|
||||||
|
restart: unless-stopped
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
- 443:443
|
||||||
|
# - 6443:6443
|
||||||
|
environment:
|
||||||
|
- HETZNER_API_KEY: ${HETZNER_API_KEY}
|
||||||
|
volumes:
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
- ./data/traefik.yml:/traefik.yml:ro
|
||||||
|
- ./data/acme.json:/acme.json
|
||||||
|
# - ./data/custom/:/custom/:ro
|
||||||
|
# - ./data/basic.auth:/basic.auth
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.traefik.entrypoints=https"
|
||||||
|
- "traefik.http.routers.traefik.rule=Host(`${DOMAIN}`)"
|
||||||
|
- "traefik.http.routers.traefik.tls=true"
|
||||||
|
- "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
|
||||||
|
- "traefik.http.routers.traefik.service=api@internal"
|
||||||
|
- "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"
|
||||||
|
# - "traefik.http.routers.traefik.middlewares=traefik-auth"
|
||||||
|
# - "traefik.http.middlewares.traefik-auth.basicAuth.usersFile=/basic.auth"
|
||||||
|
|
||||||
|
# global redirect to https
|
||||||
|
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
|
||||||
|
- "traefik.http.routers.http-catchall.entrypoints=http"
|
||||||
|
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
|
||||||
|
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
|
||||||
|
networks:
|
||||||
|
- webproxy
|
||||||
|
|
||||||
|
# api:
|
||||||
|
# image: vasyakrg/traefik-api:latest
|
||||||
|
# container_name: traefik_api
|
||||||
|
# restart: unless-stopped
|
||||||
|
# labels:
|
||||||
|
# - "traefik.enable=true"
|
||||||
|
# - "traefik.http.routers.traefik-api.entrypoints=https"
|
||||||
|
# - "traefik.http.routers.traefik-api.rule=Host(`${DOMAIN_API}`)"
|
||||||
|
# - "traefik.http.routers.traefik-api.tls=true"
|
||||||
|
# - "traefik.http.routers.traefik-api.tls.certresolver=letsEncrypt"
|
||||||
|
# - "traefik.http.services.traefik-api-service.loadbalancer.server.port=80"
|
||||||
|
# - "traefik.docker.network=webproxy"
|
||||||
|
# environment:
|
||||||
|
# APP_DEBUG: "true"
|
||||||
|
# APP_ENV: "production"
|
||||||
|
# APP_URL: "${DOMAIN_API}"
|
||||||
|
# ADMIN_TOKEN: ${ADMIN_TOKEN}
|
||||||
|
# volumes:
|
||||||
|
# - ./logs:/var/log/apache2
|
||||||
|
# - ./certs:/etc/letsencrypt/live/
|
||||||
|
# networks:
|
||||||
|
# - webproxy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
webproxy:
|
||||||
|
name: webproxy
|
30
traefik-repo/traefik/dumper.sh
Normal file
30
traefik-repo/traefik/dumper.sh
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
FOLDER_EXPORT=${1:-certs}
|
||||||
|
|
||||||
|
# get name - .letsEncrypt.Certificates | .[0] | .domain.main
|
||||||
|
# get key - .letsEncrypt.Certificates | .[0] | .key
|
||||||
|
# get cert - .letsEncrypt.Certificates | .[0] | .certificate
|
||||||
|
|
||||||
|
ACME=data/acme.json
|
||||||
|
|
||||||
|
LENGTH=$(cat ${ACME} | jq '.letsEncrypt.Certificates | length')
|
||||||
|
|
||||||
|
mkdir -p ${FOLDER_EXPORT}
|
||||||
|
|
||||||
|
i=1
|
||||||
|
while [ $i != ${LENGTH} ]
|
||||||
|
do
|
||||||
|
|
||||||
|
name=$(cat ${ACME} | jq -r ".letsEncrypt.Certificates | .[${i}] | .domain.main")
|
||||||
|
key=$(cat ${ACME} | jq -r ".letsEncrypt.Certificates | .[${i}] | .key")
|
||||||
|
cert=$(cat ${ACME} | jq -r ".letsEncrypt.Certificates | .[${i}] | .certificate")
|
||||||
|
|
||||||
|
echo "export ${name}"
|
||||||
|
mkdir -p ${FOLDER_EXPORT}/${name}
|
||||||
|
echo $key | base64 --decode > ${FOLDER_EXPORT}/${name}/privkey.pem
|
||||||
|
echo $cert | base64 --decode > ${FOLDER_EXPORT}/${name}/cert.pem
|
||||||
|
echo "null" > ${FOLDER_EXPORT}/${name}/fullchain.pem
|
||||||
|
|
||||||
|
((i++))
|
||||||
|
done
|
6
traefik-repo/traefik/init.sh
Executable file
6
traefik-repo/traefik/init.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
[ ! -f .env ] && cp .env.example .env
|
||||||
|
|
||||||
|
touch data/acme.json
|
||||||
|
chmod 600 data/acme.json
|
22
traefik-repo/traefik/pve-update.sh
Normal file
22
traefik-repo/traefik/pve-update.sh
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DOMAIN=pve.domain.ru
|
||||||
|
|
||||||
|
PEM=pveproxy-ssl.pem
|
||||||
|
KEY=pveproxy-ssl.key
|
||||||
|
DEST_PATH=/etc/pve/local
|
||||||
|
|
||||||
|
SERVICE_RESTART=pveproxy
|
||||||
|
|
||||||
|
echo "[ START ] on $(date +'%d-%m-%Y_%H-%M')"
|
||||||
|
|
||||||
|
cp certs/${DOMAIN}/cert.pem ${DEST_PATH}/${PEM}
|
||||||
|
cp certs/${DOMAIN}/privkey.pem ${DEST_PATH}/${KEY}
|
||||||
|
|
||||||
|
SERVICE_RESTART=pveproxy
|
||||||
|
|
||||||
|
systemctl restart $SERVICE_RESTART
|
||||||
|
[[ ! $? -eq 0 ]] && echo "service not restarted, restart manually"
|
||||||
|
|
||||||
|
echo "[ END ] on $(date +'%d-%m-%Y_%H-%M')"
|
||||||
|
echo ""
|
135
traefik-repo/traefik/readme.MD
Normal file
135
traefik-repo/traefik/readme.MD
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# Traefik server for docker
|
||||||
|
|
||||||
|
- поднимает траефик в докере
|
||||||
|
- позволяет выпускать наружу другие сервисы как в докере, так и из локальной сети подставляя валидные SSL сертификаты
|
||||||
|
- traefik-api умеет отдавать сертификаты по запросу через `токен`
|
||||||
|
|
||||||
|
## Настройка
|
||||||
|
|
||||||
|
- заполнить `.env` из `.env.example`
|
||||||
|
- запустить `./init.sh` (делается первый и единственный раз)
|
||||||
|
- запустить сервис
|
||||||
|
|
||||||
|
```
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
- добавить в крон дампер, который из файла `acme.json` вытягивает и раскладывает сертификаты по папкам с названием доменов (нужно, что бы корректно работал `traefik-api`)
|
||||||
|
|
||||||
|
```
|
||||||
|
25 07 * *\1 * cd /srv/services/traefik/ && ./dumper.sh >> /var/log/traefik_api.log
|
||||||
|
```
|
||||||
|
|
||||||
|
**Внимание!**, что бы правильно работал `dumper.sh` в системе должна быть установлена утилита `jq`
|
||||||
|
|
||||||
|
```
|
||||||
|
apt install jq - для Debian\Ubuntu
|
||||||
|
brew install jq - для MacOS
|
||||||
|
```
|
||||||
|
|
||||||
|
## Внешняя защита
|
||||||
|
|
||||||
|
- Так как сам сервис trafik доступен из вне, его так же логично закрыть хотя бы basic auth
|
||||||
|
- в файле docker-compose.yml раскомментим строки:
|
||||||
|
|
||||||
|
```
|
||||||
|
- ./data/basic.auth:/basic.auth
|
||||||
|
- "traefik.http.middlewares.traefik-auth.basicAuth.usersFile=/basic.auth"
|
||||||
|
- "traefik.http.routers.traefik.middlewares=traefik-auth"
|
||||||
|
```
|
||||||
|
|
||||||
|
в папку `data` сгенерим файлик `basic.auth` c логином и паролем
|
||||||
|
|
||||||
|
```
|
||||||
|
htpasswd -c data/basic.auth admin
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Докерные сервисы
|
||||||
|
|
||||||
|
- запускаем нужный контейнер с правильно выставленными `лейблами`
|
||||||
|
- контейнер должен быть в том числе подключен к сети `webproxy`
|
||||||
|
|
||||||
|
**Пример**:
|
||||||
|
|
||||||
|
```
|
||||||
|
version: '3.7'
|
||||||
|
services:
|
||||||
|
grafana:
|
||||||
|
container_name: grafana
|
||||||
|
image: grafana/grafana:latest
|
||||||
|
restart: always
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.grafana.entrypoints=https"
|
||||||
|
- "traefik.http.routers.grafana.rule=Host(`grafana.domain.ru`)"
|
||||||
|
- "traefik.http.routers.grafana.tls=true"
|
||||||
|
- "traefik.http.routers.grafana.tls.certresolver=letsEncrypt"
|
||||||
|
- "traefik.http.services.grafana-service.loadbalancer.server.port=3000"
|
||||||
|
- "traefik.docker.network=webproxy"
|
||||||
|
environment:
|
||||||
|
- GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD}
|
||||||
|
- GF_SECURITY_ADMIN_USER=${GF_SECURITY_ADMIN_USER}
|
||||||
|
- GF_AUTH_ANONYMOUS_ENABLED=false
|
||||||
|
- GF_USERS_ALLOW_SIGN_UP=false
|
||||||
|
- GF_USERS_ALLOW_ORG_CREATE=false
|
||||||
|
volumes:
|
||||||
|
- grafana:/var/lib/grafana
|
||||||
|
expose:
|
||||||
|
- 3000
|
||||||
|
networks:
|
||||||
|
- grafana_net
|
||||||
|
- webproxy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Кастомные сервисы
|
||||||
|
|
||||||
|
- примеры кастомных сервисов (читать - сервисы не в докере, а в локальной сети) лежат в папке `data/custom`
|
||||||
|
- файл должен иметь вид `name.yml` и содержать в себе правильный контекст (проверить ошибки применения можно через `docker log <traefik_container>`)
|
||||||
|
- перезапускать траефик, что бы применить новые файлы `не нужно!`
|
||||||
|
- если сервис больше не нужен, файл удаляется руками или переносится в папку disabled (опять же траефик применяет изменения налету)
|
||||||
|
|
||||||
|
## Traefik API
|
||||||
|
|
||||||
|
- Позволяет отдавать сертификаты в [traefik-api-client](../traefik-api-client/readme.MD) или по запросу
|
||||||
|
- В `.env` в переменной `ADMIN_TOKEN` указываем наш стойкий токен
|
||||||
|
|
||||||
|
### Методы для работы с API:
|
||||||
|
|
||||||
|
#### авторизация:
|
||||||
|
|
||||||
|
```
|
||||||
|
'headers' => [
|
||||||
|
'Authorization' => 'Bearer ' . $TOKEN,
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### проверка, что у traefik есть нужный домен:
|
||||||
|
|
||||||
|
```
|
||||||
|
curl -s --request POST 'https://traefik-api.domain.ru/api/v1/certman/getdomain' \
|
||||||
|
--header 'Authorization: Bearer <token>' \
|
||||||
|
--form 'domain=domain.ru'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### запрос ключей:
|
||||||
|
|
||||||
|
```
|
||||||
|
curl -s --request POST 'https://traefik-api.domain.ru/api/v1/certman/getcerts' \
|
||||||
|
--header 'Authorization: Bearer <token>' \
|
||||||
|
--form 'domain=domain.ru'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### корректный вывод будет такой:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"data": {
|
||||||
|
"crt": "-----BEGIN CERTIFICATE-----\\...\\-----END CERTIFICATE-----",
|
||||||
|
"key": "-----BEGIN PRIVATE KEY-----\\...\\-----END PRIVATE KEY-----",
|
||||||
|
"chain": "-----BEGIN CERTIFICATE-----\\...\\-----END CERTIFICATE-----"
|
||||||
|
},
|
||||||
|
"message": "OK"
|
||||||
|
}
|
||||||
|
```
|
Reference in New Issue
Block a user