mirror of
https://github.com/furyhawk/cloudy.git
synced 2026-05-20 23:21:07 +00:00
Compare commits
593 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c53891d82 | |||
| 2de0510059 | |||
| 13511a796c | |||
| 0e4160f6d6 | |||
| 9ab631a925 | |||
| bb05c00b6f | |||
| 13ea3288f7 | |||
| 669ce4e88a | |||
| 0b2241ceb7 | |||
| 4003e830cf | |||
| 9250b3e22a | |||
| 6c4117ab95 | |||
| cfb0a1d437 | |||
| f25426a1ca | |||
| e325544c58 | |||
| 1332c86ecc | |||
| 548ac28dc2 | |||
| 042f04601c | |||
| e0a042608a | |||
| f7deab4509 | |||
| e8bcbe8dd2 | |||
| 909c7ebaa1 | |||
| 433d6bf70b | |||
| 6a9b1b8112 | |||
| 0abfad7c4b | |||
| 96edc58a2a | |||
| b7e9ef7a16 | |||
| 9a3a640cce | |||
| f7d685a9ac | |||
| 7145e1d0a5 | |||
| 650038dfa1 | |||
| 34cfefc62c | |||
| 04a5f0b646 | |||
| b86190dcf6 | |||
| b99ab02fcc | |||
| 7519ef532d | |||
| eeb3d6d739 | |||
| 77e42d3a56 | |||
| b6613aaeaf | |||
| 7014b5c549 | |||
| bef52b0abc | |||
| 3f95800825 | |||
| 0a656dcaf2 | |||
| fd6318ec86 | |||
| 69be15e39c | |||
| 742770dfe9 | |||
| 85c8a1c0b9 | |||
| baa28bf66c | |||
| c48fa3d0df | |||
| aca10f2250 | |||
| c6634cddac | |||
| efc9a8a0f4 | |||
| 832da6ee78 | |||
| b3936a3cab | |||
| b096120482 | |||
| c339952965 | |||
| 91197e3931 | |||
| 1f1aed480f | |||
| c3d1638fd4 | |||
| 33fa78e117 | |||
| 77e8704c8e | |||
| e1e89dc89b | |||
| 1f662db288 | |||
| 1742641296 | |||
| c27fee72ba | |||
| c20d2be439 | |||
| 4549a213e2 | |||
| 8587141c69 | |||
| e65cf2ce2c | |||
| 44c0436216 | |||
| 4cf1c47db2 | |||
| f7beeb1cff | |||
| cd0c596797 | |||
| 4687bb7bd5 | |||
| 1af0192a5c | |||
| b912e18028 | |||
| 86dfa5cb00 | |||
| f9813a249e | |||
| a083b71a27 | |||
| a9fa3c95e3 | |||
| 78400a13db | |||
| c21af9193f | |||
| b8a32d8c8f | |||
| 4273819a2e | |||
| cd9ead5c82 | |||
| d22242efff | |||
| 712980805d | |||
| d559799d77 | |||
| 7ec7902a79 | |||
| 556d94bcb0 | |||
| fba2477179 | |||
| ff6e294e1e | |||
| 6bef5ab9f0 | |||
| 3b3b8a5e6c | |||
| 57e39cbe04 | |||
| 49a09cd242 | |||
| e9c2fe368e | |||
| 1dcd0bf9d1 | |||
| 88e6b245c4 | |||
| bee079297d | |||
| 9ffda8fd78 | |||
| 51aed951fe | |||
| f10011b208 | |||
| 93238eb93f | |||
| 3ed591777c | |||
| ffa781d8c9 | |||
| 54e110241c | |||
| 8723f1b7f5 | |||
| b1b01f3ab3 | |||
| b5aead95bf | |||
| eccede0bb7 | |||
| 5950d8aa94 | |||
| 385c0cf657 | |||
| 5cfdcaea13 | |||
| 5a34437ec8 | |||
| 8a69f1dd93 | |||
| 20778b55ee | |||
| 8f3654125c | |||
| 61962528c6 | |||
| 8fc754abf3 | |||
| 2925eae450 | |||
| 75eff71896 | |||
| 824181aeee | |||
| 263ef13da5 | |||
| 4321affbb4 | |||
| ab436a34b2 | |||
| 09f8f49a10 | |||
| f2f383e845 | |||
| cdf266c9bb | |||
| e3ac1fa602 | |||
| 0df1163756 | |||
| 016ac4af28 | |||
| 3f9cf3b5e9 | |||
| 38a5dcbd21 | |||
| 67072c1d4e | |||
| 696570784f | |||
| 7c71871fd6 | |||
| a213005361 | |||
| 1daaaef3c1 | |||
| 6df3148f18 | |||
| 2ac2b20a97 | |||
| c03e49b389 | |||
| 399fbd46f7 | |||
| 52c186a9fb | |||
| 93303473bf | |||
| 1c046417be | |||
| 1fb6393649 | |||
| 0fc8c7ab07 | |||
| ea9874fe77 | |||
| ffdd167352 | |||
| a577d491ef | |||
| 71f405a399 | |||
| d6b4123e8a | |||
| 8e2d8149df | |||
| fcad744044 | |||
| be7bf40bb9 | |||
| 24f0c918ad | |||
| cbbade2b61 | |||
| 2008e12b6f | |||
| 922a5e9e96 | |||
| 16c1fa0efa | |||
| fb5a5ba603 | |||
| 8e433ae621 | |||
| c7dc9d396a | |||
| d9c7dc5347 | |||
| 19e4f99816 | |||
| 67a0273ad1 | |||
| 238298aed1 | |||
| 939388388f | |||
| 2e3833964d | |||
| 9d5acaaa92 | |||
| f01c505e6c | |||
| 9dd0e5eea7 | |||
| 206481ca1f | |||
| 824c662932 | |||
| 6f66b51f99 | |||
| 31a831f309 | |||
| 57a22f9e54 | |||
| 52954927be | |||
| d033fdfa9b | |||
| 4edb624a0c | |||
| 5388e9bca5 | |||
| 5859b98a20 | |||
| 52ec39de79 | |||
| 955b4dab13 | |||
| a1ee9aba41 | |||
| ec1f356620 | |||
| 533ffdd370 | |||
| 5ce74f062d | |||
| 66716f5780 | |||
| 043c9687c7 | |||
| 4f0b4cfe5d | |||
| eaed4624cd | |||
| 420556ce83 | |||
| e1c2da5cdb | |||
| 97540b24aa | |||
| e3735adcc8 | |||
| ff2b99ec00 | |||
| 9d627b2fc2 | |||
| 3948b03cc8 | |||
| 3384ddad47 | |||
| 3d40106eba | |||
| 77111f8982 | |||
| 72dccbe8f6 | |||
| 7abd917fcf | |||
| f37ea41632 | |||
| 1934d62697 | |||
| 0b891864ea | |||
| ecae976f3b | |||
| b82705c3a7 | |||
| 05f0945e7f | |||
| 7f94212785 | |||
| 1f6ddc377c | |||
| 24591c299a | |||
| 4521b58c17 | |||
| 488c614ae7 | |||
| 04a0a70368 | |||
| 3d14f85c68 | |||
| ec7b22974e | |||
| 8877e0110d | |||
| 3c13802cf2 | |||
| 06014f6cf6 | |||
| 066654b5c4 | |||
| 4a2c93e0c4 | |||
| b534308953 | |||
| 54e3d576d5 | |||
| 0e3f8abb45 | |||
| 3a0c706c5f | |||
| e9f517509d | |||
| df53a0535a | |||
| b879f3fffa | |||
| 65c273c3cd | |||
| 36b4567ff8 | |||
| 08eb39102f | |||
| 369db072df | |||
| 8827aebdf3 | |||
| d29d92bc7a | |||
| b9abc98083 | |||
| b193e19a50 | |||
| 4e01a93d1c | |||
| 34a9767106 | |||
| 1f6ee088ab | |||
| d1324ffcff | |||
| 0c6fd323e2 | |||
| 5bcd951bcf | |||
| c7dbc5ae01 | |||
| 69785d0494 | |||
| 8482b3597c | |||
| 7006bb492a | |||
| c710b9f2cf | |||
| 87123c7099 | |||
| 726df40e69 | |||
| 48d404df5e | |||
| da21662f01 | |||
| b03de66552 | |||
| 89c6700999 | |||
| c5e4bbab0b | |||
| 1d3bbc61fb | |||
| f53362d8aa | |||
| 32cd8fedae | |||
| 2166d4854d | |||
| 4762e28af4 | |||
| 1cf3f085c6 | |||
| 69f216848a | |||
| 6d531e0a25 | |||
| 87ed73492a | |||
| 48f58ee330 | |||
| 85f972b5eb | |||
| 3df3c0d9e7 | |||
| 3f87ed3d0a | |||
| b3ef40e93b | |||
| e857335c91 | |||
| 18145a20db | |||
| b920f77921 | |||
| 8efffa1b12 | |||
| 6c40facaef | |||
| dfb8118633 | |||
| 55d1605502 | |||
| d8ad3ab882 | |||
| c84b7d1123 | |||
| db87a4667d | |||
| d02bf24203 | |||
| b99ae77c13 | |||
| 131206ad9e | |||
| c8fa799e14 | |||
| 8f154ac98e | |||
| 009c0dd43b | |||
| 8aa492c959 | |||
| 6a21e8dedb | |||
| f4dec48ebb | |||
| 5d0daaefee | |||
| 0b5e11e215 | |||
| 6435f003af | |||
| c427d73c0c | |||
| c5de666c86 | |||
| c14f197bc2 | |||
| 1babac4ce0 | |||
| 6189697822 | |||
| d3ff8215e6 | |||
| 699aa5757f | |||
| 75bb1e4675 | |||
| 95ed547bbd | |||
| f20b1c88f4 | |||
| 84b0cb09fb | |||
| 8706b82009 | |||
| eed8d7ea81 | |||
| 60dbc44c1d | |||
| ba1bddb49d | |||
| be0e430b00 | |||
| b1866b26e7 | |||
| d9f2b4cad7 | |||
| 1d54a1bd44 | |||
| cc771e0b13 | |||
| 26e72dd3f1 | |||
| 481faa0acd | |||
| 0ae1fcd304 | |||
| 19daea6767 | |||
| d421a749e9 | |||
| 820191346b | |||
| 2da4bdc13e | |||
| 7ca0e8e5ad | |||
| d4037c7218 | |||
| d9498c66c7 | |||
| 1f0b71fab1 | |||
| 69ab87e4ed | |||
| 535bde66a8 | |||
| fd36ee6bf8 | |||
| fb1a0b3de8 | |||
| 3da059216c | |||
| f2fc0f64b3 | |||
| ef3cdf6f62 | |||
| db36090358 | |||
| 42d6e0da78 | |||
| 860ff9e065 | |||
| 1ec132b37f | |||
| 3564c6f79b | |||
| 4380cf28e7 | |||
| 179f618469 | |||
| 8112288dac | |||
| a296c9bf5e | |||
| f8cd764815 | |||
| 012a1dd117 | |||
| 6301da7603 | |||
| 9741508af3 | |||
| 4ac2ce24b8 | |||
| 996c713510 | |||
| e44e9da832 | |||
| 4c10573dab | |||
| 8460e24fd0 | |||
| b216198cd4 | |||
| 0f12eda873 | |||
| f5466aa013 | |||
| f21dbf79ea | |||
| be2ea7fc74 | |||
| 16e5b73622 | |||
| 9e30f385cc | |||
| 1281266ff5 | |||
| b6713b2830 | |||
| a8dac32320 | |||
| 08c09e0c6d | |||
| 90a93c4e8f | |||
| 54085449d9 | |||
| d3ef4cd14a | |||
| a896598eb0 | |||
| d97924e7e7 | |||
| 70f3a007fc | |||
| 18bd556c9d | |||
| deb80f24fe | |||
| 9a2e4be6af | |||
| 57348087a6 | |||
| a7969b768c | |||
| 5fbfbc9ad1 | |||
| 53353a603b | |||
| b38a01d6cd | |||
| 440337deb8 | |||
| 2ed6934cb2 | |||
| 3d37c3bdb8 | |||
| 8de0961975 | |||
| f931ec0cd6 | |||
| c3c10ce7e5 | |||
| 03b89d752e | |||
| 655109e5c8 | |||
| aabc4d229a | |||
| f6934952cf | |||
| a251d57742 | |||
| b4cc4923b3 | |||
| cf412bdf47 | |||
| c4e56cf5b1 | |||
| f1a3b1c169 | |||
| ec0f9f8a54 | |||
| b02f26aaf3 | |||
| aad0ed4146 | |||
| bbf07c84c5 | |||
| 0b98735261 | |||
| b5266d8b4b | |||
| 89f6fb35b8 | |||
| 3cbed2908a | |||
| b097fad335 | |||
| 47384c4b66 | |||
| 4ffd4dda5a | |||
| 825697c134 | |||
| 15c1396ebb | |||
| b7a474ae08 | |||
| cecd6bca5e | |||
| c07c840de4 | |||
| bc34e91fe6 | |||
| 20888af2b9 | |||
| 7872289630 | |||
| 30bc4fabfc | |||
| 0d02f5b7b6 | |||
| 44b9ca3b24 | |||
| 98f75b9fbd | |||
| dc5c78c507 | |||
| c76c18289a | |||
| 23ad772a53 | |||
| 926479d1ac | |||
| d7229e498a | |||
| 3cf60db048 | |||
| 6c4de20629 | |||
| 1ff9a29fb0 | |||
| 895abd694b | |||
| c70beefd40 | |||
| 55861d7c9a | |||
| dd004334b3 | |||
| 1999c7fde2 | |||
| 3377771e35 | |||
| 9562f5d7ce | |||
| 9b169236c6 | |||
| 3ef9b6860e | |||
| 5d5a13d5ff | |||
| 57d78b025b | |||
| 0d1a635f69 | |||
| 2e7c5e2cbe | |||
| 6b0e9b56b0 | |||
| c893b10540 | |||
| d789cdcbe3 | |||
| 2d30694f6e | |||
| 36c017bb70 | |||
| fbc5b9146d | |||
| ff1659e969 | |||
| 0f8fcc4dc0 | |||
| e458e92573 | |||
| 7b2bb828af | |||
| 2e8408fb11 | |||
| d407fcbe1a | |||
| 8df524c9d5 | |||
| bf693e7236 | |||
| b4d5b540c3 | |||
| 5ec576bebf | |||
| e547ae4667 | |||
| 0b164d534c | |||
| 2a8bfd86d0 | |||
| f4b8809853 | |||
| 24265ed8f6 | |||
| 5284bcd5e6 | |||
| 4e696a8fee | |||
| 5d893eafb4 | |||
| 8f1d81e650 | |||
| 16d137ff59 | |||
| 743d5a898c | |||
| 0b9dfc3b3c | |||
| 95850da1b4 | |||
| 39df4583d3 | |||
| 83a36ad4f2 | |||
| a17d0cd2e2 | |||
| 458fe871f4 | |||
| 1e59b91a0e | |||
| 4c79bccd85 | |||
| ff31f5c064 | |||
| 0360e165f4 | |||
| a36f9aebd5 | |||
| 7ed3d9ad64 | |||
| 69059e51df | |||
| 7013e9b26b | |||
| daba05d362 | |||
| c24f5bf91d | |||
| be341414f9 | |||
| c4ec0ad966 | |||
| 3876bd145c | |||
| 5342ed08b3 | |||
| 09934995cb | |||
| 568f9a83f5 | |||
| 3e510c8733 | |||
| c08306ecc2 | |||
| 8da24cf80a | |||
| 374d07f979 | |||
| 5e17ef2ea9 | |||
| 7645dd739e | |||
| 656548d4b0 | |||
| 5d7a350afe | |||
| 2e3099476e | |||
| a05c289aff | |||
| 347b9b9d76 | |||
| 0b06931427 | |||
| afa53aa747 | |||
| 91200fe37e | |||
| 895f1d0aef | |||
| f0a1969e73 | |||
| cd14a1ce23 | |||
| 3ddbbbb255 | |||
| d0483114dc | |||
| 722b942079 | |||
| 86d8b19ae3 | |||
| 63b190ccbd | |||
| 0bb60245dc | |||
| b70e7111ae | |||
| 788ec952fd | |||
| 038bf3e8d9 | |||
| 1cc77c6609 | |||
| dfd071150f | |||
| b55afab109 | |||
| cbbbe695ec | |||
| 6f3d3bbe49 | |||
| 3baf43ad74 | |||
| e2784f41fe | |||
| 1ac98da285 | |||
| 03463c6b88 | |||
| a1112357b8 | |||
| 10676c0754 | |||
| 1e581d71fb | |||
| a345319737 | |||
| f865ba6f16 | |||
| 8820fbe01e | |||
| 1775c937e6 | |||
| ee71215ac2 | |||
| 9819c38624 | |||
| 6aa7ede93a | |||
| c17d692c8a | |||
| e0269dc14b | |||
| 8d588eafb2 | |||
| cf899cd7fd | |||
| afcfc90cac | |||
| a29da08055 | |||
| 9f62b79b6f | |||
| b63e5af186 | |||
| 93bbfbbcdd | |||
| 4a02eba0e2 | |||
| f3d52b27b2 | |||
| 59115a58f5 | |||
| 049acd29cb | |||
| c5c9ee31f4 | |||
| 0ca80b1741 | |||
| 7c4d216817 | |||
| 9b1fafa848 | |||
| dc55872b5d | |||
| 77c90d7823 | |||
| ee7fddeed6 | |||
| 4e64a2b76a | |||
| 30cd9df16e | |||
| 333b00eeef | |||
| 6f1d04afc3 | |||
| 16310a21ba | |||
| c14a7ad35e | |||
| 47a0e912bb | |||
| 7c92ed044b | |||
| b64e4984af | |||
| 6348bb0fbb | |||
| 8e88b8bcbb | |||
| 73d0a36254 | |||
| b01df6af62 | |||
| feff445ab3 | |||
| ce1cfbf4c7 | |||
| daa40c6aa4 | |||
| 297c05742f | |||
| 65462229e5 | |||
| 1a13d29542 | |||
| 110a0dd411 | |||
| 1f14327c68 | |||
| cfd4e9150e | |||
| ed57ba4dc4 | |||
| 522c210f5a | |||
| 5b94503537 | |||
| 7772353d7c | |||
| 8c2f258d5d | |||
| 2cdb147b14 | |||
| 374ca7fb09 | |||
| 5c54f73210 | |||
| f550849d8e | |||
| a833562205 | |||
| 22080087c0 | |||
| 2e6c9886be | |||
| 5c77d4afa3 | |||
| fe0b34a752 | |||
| 2c76f7ec39 | |||
| d9f5c2d75e | |||
| f7a6f7c4c6 | |||
| 716b662e4a | |||
| 8a865c6e38 | |||
| 95d0b36384 | |||
| 792e6a1a9d | |||
| 2965012b23 | |||
| 927238f955 | |||
| f74c0b4342 |
+110
-10
@@ -1,15 +1,20 @@
|
|||||||
# Environment variables for docker-compose.yml
|
# Environment variables for docker-compose.yml
|
||||||
|
PUID=1000
|
||||||
LOG_LEVEL="DEBUG"
|
PGID=1000
|
||||||
|
LOG_LEVEL="INFO"
|
||||||
NETWORK="web"
|
NETWORK="web"
|
||||||
TZ="Asia/Singapore"
|
TZ="Asia/Singapore"
|
||||||
## dashboard configs
|
## dashboard configs
|
||||||
HOST="furyhawk.lol"
|
HOST="localhost"
|
||||||
|
# TLD="lol"
|
||||||
|
# LOCALDOMAIN="$(hostname).${TLD}"
|
||||||
|
# DOMAIN="$(hostname).${TLD}"
|
||||||
|
# DOMAINNAME="$(hostname).${TLD}"
|
||||||
|
HOSTNAME="node00"
|
||||||
|
# media directory for jellyfin
|
||||||
|
MEDIADIR="/var/media"
|
||||||
# subdomain for dashboard.
|
# subdomain for dashboard.
|
||||||
DASHBOARD_HOST="dashboard.furyhawk.lol"
|
DASHBOARD_HOST="dashboard.example.lol"
|
||||||
|
|
||||||
# log file path on host machine
|
|
||||||
LOG_PATH=./logs
|
|
||||||
|
|
||||||
## TLS configs
|
## TLS configs
|
||||||
CERT_PATH=./certs
|
CERT_PATH=./certs
|
||||||
@@ -26,8 +31,8 @@ OSRM_ALGORITHM="mld"
|
|||||||
OSRM_THREADS=2
|
OSRM_THREADS=2
|
||||||
OSRM_PORT=5000
|
OSRM_PORT=5000
|
||||||
OSRM_PROFILE="/opt/car.lua"
|
OSRM_PROFILE="/opt/car.lua"
|
||||||
OSRM_MAP_NAME=${OSRM_MAP_NAME}
|
OSRM_MAP_NAME=""
|
||||||
OSRM_GEOFABRIK_PATH=${OSRM_GEOFABRIK_PATH}
|
OSRM_GEOFABRIK_PATH=""
|
||||||
# Notify OSRM Manager to restart without stopping container
|
# Notify OSRM Manager to restart without stopping container
|
||||||
OSRM_NOTIFY_FILEPATH="/data/osrm_notify.txt"
|
OSRM_NOTIFY_FILEPATH="/data/osrm_notify.txt"
|
||||||
|
|
||||||
@@ -43,7 +48,7 @@ POSTGRES_PASSWORD=12345678
|
|||||||
PGADMIN_DEFAULT_EMAIL=youremail.com
|
PGADMIN_DEFAULT_EMAIL=youremail.com
|
||||||
PGADMIN_DEFAULT_PASSWORD=12345678
|
PGADMIN_DEFAULT_PASSWORD=12345678
|
||||||
|
|
||||||
DATABASE__HOSTNAME=furyhawk.lol
|
DATABASE__HOSTNAME=example.lol
|
||||||
DATABASE__USERNAME=admin
|
DATABASE__USERNAME=admin
|
||||||
DATABASE__PASSWORD=12345678
|
DATABASE__PASSWORD=12345678
|
||||||
DATABASE__PORT=5432
|
DATABASE__PORT=5432
|
||||||
@@ -58,6 +63,27 @@ MINIO_ROOT_PASSWORD=123456
|
|||||||
|
|
||||||
NEO4J_PASSWORD=12345678
|
NEO4J_PASSWORD=12345678
|
||||||
|
|
||||||
|
SEARXNG_SECRET=ultrasecretkey
|
||||||
|
|
||||||
|
#echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env
|
||||||
|
AUTHENTIK_SECRET_KEY=
|
||||||
|
AUTHENTIK_ERROR_REPORTING__ENABLED=true
|
||||||
|
# SMTP Host Emails are sent to
|
||||||
|
AUTHENTIK_EMAIL__HOST=localhost
|
||||||
|
AUTHENTIK_EMAIL__PORT=25
|
||||||
|
# Optionally authenticate (don't add quotation marks to your password)
|
||||||
|
AUTHENTIK_EMAIL__USERNAME=
|
||||||
|
AUTHENTIK_EMAIL__PASSWORD=
|
||||||
|
# Use StartTLS
|
||||||
|
AUTHENTIK_EMAIL__USE_TLS=false
|
||||||
|
# Use SSL
|
||||||
|
AUTHENTIK_EMAIL__USE_SSL=false
|
||||||
|
AUTHENTIK_EMAIL__TIMEOUT=10
|
||||||
|
# Email address authentik will send from, should have a correct @domain
|
||||||
|
AUTHENTIK_EMAIL__FROM=authentik@localhost
|
||||||
|
COMPOSE_PORT_HTTP=80
|
||||||
|
COMPOSE_PORT_HTTPS=443
|
||||||
|
|
||||||
#=====================================================================#
|
#=====================================================================#
|
||||||
# LibreChat Configuration #
|
# LibreChat Configuration #
|
||||||
#=====================================================================#
|
#=====================================================================#
|
||||||
@@ -482,3 +508,77 @@ REDLIB_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION=off
|
|||||||
REDLIB_DEFAULT_HIDE_SCORE=off
|
REDLIB_DEFAULT_HIDE_SCORE=off
|
||||||
# Enable fixed navbar by default
|
# Enable fixed navbar by default
|
||||||
REDLIB_DEFAULT_FIXED_NAVBAR=on
|
REDLIB_DEFAULT_FIXED_NAVBAR=on
|
||||||
|
|
||||||
|
# outline
|
||||||
|
NODE_ENV=production
|
||||||
|
|
||||||
|
# Generate a hex-encoded 32-byte random key. You should use `openssl rand -hex 32`
|
||||||
|
# in your terminal to generate a random value.
|
||||||
|
OUTLINE_SECRET_KEY=00b5677d3ce6c106f3d95ec830f9530f9014a2620d16fe60ed867a30c4964c5e
|
||||||
|
|
||||||
|
# Generate a unique random key. The format is not important but you could still use
|
||||||
|
# `openssl rand -hex 32` in your terminal to produce this.
|
||||||
|
OUTLINE_UTILS_SECRET=4b8235fdc01295571bd0946abb5eaf7c131f1a652386c98b658bbc4b1b4e3540
|
||||||
|
|
||||||
|
# For production point these at your databases, in development the default
|
||||||
|
# should work out of the box.
|
||||||
|
DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE__HOSTNAME}:5432/outline
|
||||||
|
# DATABASE_CONNECTION_POOL_MIN=
|
||||||
|
# DATABASE_CONNECTION_POOL_MAX=
|
||||||
|
# Uncomment this to disable SSL for connecting to Postgres
|
||||||
|
# PGSSLMODE=disable
|
||||||
|
|
||||||
|
# For redis you can either specify an ioredis compatible url like this
|
||||||
|
REDIS_URL=redis://tasks.redis:6379
|
||||||
|
# or alternatively, if you would like to provide additional connection options,
|
||||||
|
# use a base64 encoded JSON connection option object. Refer to the ioredis documentation
|
||||||
|
# for a list of available options.
|
||||||
|
# Example: Use Redis Sentinel for high availability
|
||||||
|
# {"sentinels":[{"host":"sentinel-0","port":26379},{"host":"sentinel-1","port":26379}],"name":"mymaster"}
|
||||||
|
# REDIS_URL=ioredis://eyJzZW50aW5lbHMiOlt7Imhvc3QiOiJzZW50aW5lbC0wIiwicG9ydCI6MjYzNzl9LHsiaG9zdCI6InNlbnRpbmVsLTEiLCJwb3J0IjoyNjM3OX1dLCJuYW1lIjoibXltYXN0ZXIifQ==
|
||||||
|
|
||||||
|
# URL should point to the fully qualified, publicly accessible URL. If using a
|
||||||
|
# proxy the port in URL and PORT may be different.
|
||||||
|
OUTLINE_URL=https://outline.${DOMAIN}
|
||||||
|
OUTLINE_PORT=3000
|
||||||
|
|
||||||
|
# See [documentation](docs/SERVICES.md) on running a separate collaboration
|
||||||
|
# server, for normal operation this does not need to be set.
|
||||||
|
COLLABORATION_URL=
|
||||||
|
|
||||||
|
# Specify what storage system to use. Possible value is one of "s3" or "local".
|
||||||
|
# For "local", the avatar images and document attachments will be saved on local disk.
|
||||||
|
FILE_STORAGE=local
|
||||||
|
|
||||||
|
# If "local" is configured for FILE_STORAGE above, then this sets the parent directory under
|
||||||
|
# which all attachments/images go. Make sure that the process has permissions to create
|
||||||
|
# this path and also to write files to it.
|
||||||
|
FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data
|
||||||
|
|
||||||
|
# Maximum allowed size for the uploaded attachment.
|
||||||
|
FILE_STORAGE_UPLOAD_MAX_SIZE=262144000
|
||||||
|
|
||||||
|
# Override the maximum size of document imports, generally this should be lower
|
||||||
|
# than the document attachment maximum size.
|
||||||
|
FILE_STORAGE_IMPORT_MAX_SIZE=
|
||||||
|
|
||||||
|
# Override the maximum size of workspace imports, these can be especially large
|
||||||
|
# and the files are temporary being automatically deleted after a period of time.
|
||||||
|
FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE=
|
||||||
|
|
||||||
|
# –––––––––––––– AUTHENTICATION ––––––––––––––
|
||||||
|
|
||||||
|
# Third party signin credentials, at least ONE OF EITHER Google, Slack,
|
||||||
|
# or Microsoft is required for a working installation or you'll have no sign-in
|
||||||
|
# options.
|
||||||
|
|
||||||
|
# To configure Google auth, you'll need to create an OAuth Client ID at
|
||||||
|
# => https://console.cloud.google.com/apis/credentials
|
||||||
|
#
|
||||||
|
# When configuring the Client ID, add an Authorized redirect URI:
|
||||||
|
# https://<URL>/auth/google.callback
|
||||||
|
GOOGLE_CLIENT_ID=
|
||||||
|
GOOGLE_CLIENT_SECRET=
|
||||||
|
|
||||||
|
SLACK_CLIENT_ID=
|
||||||
|
SLACK_CLIENT_SECRET=
|
||||||
+12
-1
@@ -120,7 +120,7 @@ celerybeat.pid
|
|||||||
*.sage.py
|
*.sage.py
|
||||||
|
|
||||||
# Environments
|
# Environments
|
||||||
.env
|
.env*
|
||||||
.env_encoded
|
.env_encoded
|
||||||
.venv
|
.venv
|
||||||
env/
|
env/
|
||||||
@@ -165,6 +165,7 @@ cython_debug/
|
|||||||
# production.yml
|
# production.yml
|
||||||
|
|
||||||
cache/
|
cache/
|
||||||
|
config/
|
||||||
data-node/
|
data-node/
|
||||||
meili_data*/
|
meili_data*/
|
||||||
privatebin-data/
|
privatebin-data/
|
||||||
@@ -172,3 +173,13 @@ privatebin-data/
|
|||||||
minio-data/
|
minio-data/
|
||||||
usersfile
|
usersfile
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
fstab
|
||||||
|
|
||||||
|
kubernetes/talos/kubeconfig.yaml
|
||||||
|
kubernetes/talos/kubeconfig
|
||||||
|
kubernetes/talos/config
|
||||||
|
kubernetes/talos/_out/
|
||||||
|
kubernetes/config/
|
||||||
|
kubernetes/_out/
|
||||||
|
swarm/seafile/seafile-data/
|
||||||
|
swarm/seafile/seafile-mysql/db/
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
[submodule "LibreChat"]
|
|
||||||
path = LibreChat
|
|
||||||
url = https://github.com/furyhawk/LibreChat.git
|
|
||||||
[submodule "emqx-docker"]
|
|
||||||
path = emqx-docker
|
|
||||||
url = https://github.com/furyhawk/emqx-docker.git
|
|
||||||
|
|||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"makefile.configureOnOpen": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
- This repository is primarily infrastructure-as-code for Docker Compose, Docker Swarm, Kubernetes, Helm, and Ansible.
|
||||||
|
- There is also a small Python Flask service in `webhook/` and a Streamlit app in `src/`.
|
||||||
|
- Prefer narrow, low-risk edits. Many files are deployment manifests where a small typo can break production behavior.
|
||||||
|
|
||||||
|
## Agent Priorities
|
||||||
|
- Preserve the existing structure and conventions of the file you are editing.
|
||||||
|
- Favor minimal diffs over broad refactors.
|
||||||
|
- Do not rotate secrets, change domains, or alter deployment targets unless the task explicitly requires it.
|
||||||
|
- Treat `archive/` as historical unless the task explicitly mentions it.
|
||||||
|
- When changing runtime configuration, update only the active path (`compose/`, `swarm/`, `cluster/`, `ansible/`, `webhook/`, `src/`) relevant to the request.
|
||||||
|
|
||||||
|
## Rule Files
|
||||||
|
- No `.cursor/rules/` directory was found.
|
||||||
|
- No `.cursorrules` file was found.
|
||||||
|
- No `.github/copilot-instructions.md` file was found.
|
||||||
|
- This file therefore acts as the main agent guidance for the repository.
|
||||||
|
|
||||||
|
## Repository Areas
|
||||||
|
- `makefile`: top-level operator commands for Compose and Swarm deploys.
|
||||||
|
- `compose.yml` + `compose/`: Docker Compose configuration assembled via `include:`.
|
||||||
|
- `swarm/`: Docker Swarm stacks, environment-driven labels, and Traefik config.
|
||||||
|
- `cluster/`: Kubernetes manifests and Helm charts.
|
||||||
|
- `ansible/`: playbooks and RKE2 automation.
|
||||||
|
- `webhook/`: Poetry-managed Flask app.
|
||||||
|
- `src/`: Streamlit app and Python requirements.
|
||||||
|
- `scripts/`: setup, build, and smoke-test scripts.
|
||||||
|
|
||||||
|
## Build Commands
|
||||||
|
- Full local compose stack: `make serve`
|
||||||
|
- Stop local compose stack: `make down`
|
||||||
|
- Validate merged compose config: `docker compose -f compose.yml config`
|
||||||
|
- Bring local compose stack up manually: `docker compose -f compose.yml up -d --build --pull always`
|
||||||
|
- Legacy CI-style compose build path: `./scripts/build.sh`
|
||||||
|
- Local Streamlit app only: `streamlit run src/app.py`
|
||||||
|
- Local webhook app only: `cd webhook && poetry run python http_server.py`
|
||||||
|
- Swarm core deploy: `make deploy-core`
|
||||||
|
- Swarm app deploy: `make deploy-apps`
|
||||||
|
- Swarm services deploy: `make deploy-services`
|
||||||
|
- Ansible RKE2 cluster bootstrap: `cd ansible/rke2 && ansible-playbook site.yaml -i inventory/hosts.ini --key-file ~/.ssh/id_rsa -K`
|
||||||
|
|
||||||
|
## Lint And Validation Commands
|
||||||
|
- There is no repo-wide lint target or CI workflow checked into the repository.
|
||||||
|
- There are no configured `ruff`, `black`, `flake8`, `mypy`, `yamllint`, `ansible-lint`, or `pytest` configs in the root.
|
||||||
|
- Use syntax and render validation that matches the area you changed.
|
||||||
|
- Compose validation: `docker compose -f compose.yml config`
|
||||||
|
- Swarm file validation: `docker stack deploy --compose-file ./swarm/<stack>.yml <stack> --dry-run` is not available in Docker Swarm, so use `docker compose config` patterns where possible and review label/env interpolation carefully.
|
||||||
|
- Helm chart render check: `helm template test-release cluster/coder-chart`
|
||||||
|
- Helm chart lint check: `helm lint cluster/coder-chart`
|
||||||
|
- Helm dependency check for `cluster/code-server`: `helm dependency update cluster/code-server`
|
||||||
|
- Kubernetes manifest spot check: `kubectl apply --dry-run=client -f <file>`
|
||||||
|
- Ansible syntax check: `ansible-playbook --syntax-check <playbook> -i <inventory>`
|
||||||
|
- Python webhook dependency install: `cd webhook && poetry install`
|
||||||
|
- Python webhook quick import/run check: `cd webhook && poetry run python http_server.py`
|
||||||
|
|
||||||
|
## Test Commands
|
||||||
|
- Main end-to-end smoke test script: `./scripts/test.sh`
|
||||||
|
- Legacy CI path: `./scripts/travis.sh`
|
||||||
|
- The smoke test expects a populated `.env`, reachable hosts, and a running local Traefik/Compose environment.
|
||||||
|
- It verifies redirects and dashboard auth using values from `.env`.
|
||||||
|
- Helm chart test hook exists for `cluster/coder-chart`; after install, run: `helm test <release-name>`
|
||||||
|
- There are example/test deployment files under `test/`, but no unified automated test runner is wired to them.
|
||||||
|
- There are currently no checked-in Python unit tests for `webhook/` or `src/`.
|
||||||
|
|
||||||
|
## Running A Single Test
|
||||||
|
- There is no first-class single-test command for the main smoke suite in `./scripts/test.sh`; it is a single shell script.
|
||||||
|
- To run one smoke assertion, copy the relevant `curl` command from `./scripts/test.sh` and execute it directly.
|
||||||
|
- For Helm, the narrowest useful check is a single chart render/lint:
|
||||||
|
- `helm lint cluster/coder-chart`
|
||||||
|
- `helm template test-release cluster/coder-chart`
|
||||||
|
- For a single Kubernetes manifest, use: `kubectl apply --dry-run=client -f path/to/file.yaml`
|
||||||
|
- For a single Ansible playbook, use: `ansible-playbook --syntax-check path/to/playbook.yml -i inventory`
|
||||||
|
- If Python tests are added later, the expected targeted form would be: `cd webhook && poetry run pytest path/to/test_file.py::test_name`
|
||||||
|
- Do not claim pytest support exists today unless you also add the test dependency and test files.
|
||||||
|
|
||||||
|
## Working Safely With Config
|
||||||
|
- Many YAML files interpolate env vars like `${DOMAINNAME}`, `${POSTGRES_PASSWORD}`, or `${VAR?Variable not set}`.
|
||||||
|
- Preserve existing variable names exactly; accidental renames will break deployments.
|
||||||
|
- Prefer existing anchors and aliases, such as `x-environment` blocks, over duplicating env declarations.
|
||||||
|
- Preserve quoting style when editing Traefik labels or shell-sensitive strings.
|
||||||
|
- Be careful with `$` escaping inside labels and regex replacements.
|
||||||
|
- Avoid changing published ports, hostnames, or Traefik router rules unless explicitly requested.
|
||||||
|
|
||||||
|
## Code Style: General
|
||||||
|
- Match the local style of the file you touch rather than imposing a new formatter.
|
||||||
|
- Keep YAML keys, Helm templates, and Ansible tasks visually aligned and easy to scan.
|
||||||
|
- Prefer small, direct changes over restructuring files.
|
||||||
|
- Keep comments only when they explain a non-obvious operational constraint.
|
||||||
|
- Reuse existing naming patterns like `api_server`, `postgres_db`, `streamlit-fin`, and `deploy-core`.
|
||||||
|
- Preserve file-specific indentation conventions: YAML uses spaces, Make uses tabs for recipe lines, shell scripts use the existing shell style.
|
||||||
|
|
||||||
|
## Imports
|
||||||
|
- In Python, keep imports at the top of the file.
|
||||||
|
- Prefer standard library imports first, then third-party imports.
|
||||||
|
- Avoid unused imports.
|
||||||
|
- Follow the existing concise import style unless you are already refactoring the file for readability.
|
||||||
|
- When touching `webhook/http_server.py` or `src/app.py`, it is acceptable to improve import ordering if part of a necessary edit.
|
||||||
|
|
||||||
|
## Formatting
|
||||||
|
- YAML: two-space indentation, no tab characters.
|
||||||
|
- Helm templates: preserve current whitespace trimming markers like `{{-` and `-}}`.
|
||||||
|
- Python: use four-space indentation even though some existing files are inconsistent.
|
||||||
|
- Shell: keep `set -e` or `set -ev` when present; do not remove safety flags casually.
|
||||||
|
- Markdown: keep bullets short and operational.
|
||||||
|
- Do not introduce large-scale formatting churn in files that are otherwise working.
|
||||||
|
|
||||||
|
## Types And Data Shapes
|
||||||
|
- Python code in this repo is lightly typed today; there is no mypy configuration.
|
||||||
|
- Add type hints when they clarify new or changed Python logic, but do not force a repo-wide typing conversion.
|
||||||
|
- For YAML, respect the existing scalar style and only quote when interpolation, special characters, or parser ambiguity require it.
|
||||||
|
- Keep environment values as strings unless the target format clearly expects booleans or integers.
|
||||||
|
- In Helm values and templates, preserve the expected shape of objects and lists; changing key structure is usually a breaking change.
|
||||||
|
|
||||||
|
## Naming Conventions
|
||||||
|
- Docker Compose services commonly use snake_case or hyphenated names already established in the file; follow the surrounding pattern.
|
||||||
|
- Ansible task names should be descriptive imperative phrases.
|
||||||
|
- Kubernetes resource names should stay lowercase and DNS-safe.
|
||||||
|
- Python function names should be `snake_case`.
|
||||||
|
- Python constants and environment variable names should be uppercase.
|
||||||
|
- Keep public-facing hostnames and router names consistent with nearby services.
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
- Do not swallow errors silently in new Python code.
|
||||||
|
- Avoid bare `except:`; catch specific exceptions where practical.
|
||||||
|
- Return clear HTTP responses in Flask handlers.
|
||||||
|
- In shell scripts, prefer failing fast over ignoring command failures.
|
||||||
|
- In Ansible, use `register`, `when`, and `changed_when` intentionally; do not mark tasks changed without a reason.
|
||||||
|
- In deployment config, prefer explicit required vars like `${VAR?Variable not set}` for critical settings.
|
||||||
|
|
||||||
|
## Python-Specific Notes
|
||||||
|
- `webhook/http_server.py` currently uses minimal Flask code and would benefit from improved formatting and more explicit error handling when modified.
|
||||||
|
- `src/app.py` contains Streamlit logic with some inconsistent spacing and a bare `except:`; fix such issues only when your change touches that area.
|
||||||
|
- Preserve current runtime entrypoints unless the task explicitly changes startup behavior.
|
||||||
|
|
||||||
|
## Ansible-Specific Notes
|
||||||
|
- Prefer fully qualified module names such as `ansible.builtin.command` where the surrounding file already uses them.
|
||||||
|
- Keep playbooks idempotent where possible.
|
||||||
|
- Avoid unnecessary `shell` usage when `command`, `template`, `copy`, or dedicated modules work.
|
||||||
|
- Respect existing inventory and variable layout under `ansible/rke2/inventory/`.
|
||||||
|
- Be cautious with `become_user`, `changed_when`, and cluster bootstrap sequencing.
|
||||||
|
|
||||||
|
## Helm And Kubernetes Notes
|
||||||
|
- Render Helm templates locally before making broad chart changes.
|
||||||
|
- Preserve helper usage like `include`, `toYaml`, `nindent`, and existing label helpers.
|
||||||
|
- Avoid renaming values keys unless you also update every template consumer.
|
||||||
|
- Maintain probe, volume, and securityContext structure unless there is a concrete reason to change them.
|
||||||
|
- For plain manifests, keep apiVersion, kind, metadata, and spec ordering consistent with nearby files.
|
||||||
|
|
||||||
|
## Docker And Traefik Notes
|
||||||
|
- Traefik labels are heavily used and are sensitive to quoting and interpolation.
|
||||||
|
- Keep router, middleware, and service label names consistent across related files.
|
||||||
|
- Prefer extending shared env blocks and shared network definitions over one-off duplication.
|
||||||
|
- Be careful with `host-gateway`, mounted Docker sockets, and certificate storage paths.
|
||||||
|
- Do not commit real secrets into compose, swarm, or manifest files.
|
||||||
|
|
||||||
|
## When Unsure
|
||||||
|
- Validate the smallest affected surface first.
|
||||||
|
- Prefer commands that only render or syntax-check before commands that deploy.
|
||||||
|
- If a task spans multiple deployment systems, confirm which path is active before editing all of them.
|
||||||
|
- Document assumptions in the final response if the repo does not provide a definitive source of truth.
|
||||||
+1
-1
Submodule LibreChat updated: 9c57a0465d...026961f719
@@ -3,9 +3,10 @@
|
|||||||
# Webapp + Streamlit + Traefik + Docker
|
# Webapp + Streamlit + Traefik + Docker
|
||||||
This simple project uses Traefik as a reverse proxy to a Streamlit application and handles SSL certs with Lets Encrypt.
|
This simple project uses Traefik as a reverse proxy to a Streamlit application and handles SSL certs with Lets Encrypt.
|
||||||
|
|
||||||
- [Chat](https://chat.furyhawk.lol/): Chat with AI.
|
- [AI](https://bot.furyhawk.lol/): OpenwebUI.
|
||||||
|
- ~~[Chat](https://chat.furyhawk.lol/): Chat with AI.~~
|
||||||
- [Stock Analysis Assistant](https://fin.furyhawk.lol/): AI assistant using GROQ and llama3.
|
- [Stock Analysis Assistant](https://fin.furyhawk.lol/): AI assistant using GROQ and llama3.
|
||||||
- [Redlib](https://redlib.furyhawk.lol/): Reddit libre.
|
- ~~[Redlib](https://redlib.furyhawk.lol/): Reddit libre.~~
|
||||||
- [Blog](https://info.furyhawk.lol/)
|
- [Blog](https://info.furyhawk.lol/)
|
||||||
- [Beyond All Information](https://bai.furyhawk.lol/): analyse your [Beyond All Reason](https://www.beyondallreason.info/) games.
|
- [Beyond All Information](https://bai.furyhawk.lol/): analyse your [Beyond All Reason](https://www.beyondallreason.info/) games.
|
||||||
- [CheatSheets](https://cheat.furyhawk.lol/): Collection of cheatsheets.
|
- [CheatSheets](https://cheat.furyhawk.lol/): Collection of cheatsheets.
|
||||||
@@ -17,19 +18,31 @@ This simple project uses Traefik as a reverse proxy to a Streamlit application a
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
- Docker Compose
|
- Docker Compose
|
||||||
- Build for ARM64 platform
|
- Build for ARM64/x86 platform
|
||||||
|
|
||||||
## Production Deployment
|
## Production Deployment
|
||||||
1. In `compose/traefik/traefik.yml`, change `example@test.com` to your email.
|
1. `git clone https://github.com/furyhawk/cloudy.git`
|
||||||
2. In `compose/traefik/traefik.yml`, change `example.com` to your domain.
|
2. `cd cloudy`
|
||||||
3. `sudo apt-get install build-essential`
|
3. `git submodule update --init --recursive`
|
||||||
4. `mdkir ~/st-sync`
|
4. In `compose/traefik/traefik.yml`, change `example@test.com` to your email.
|
||||||
5. `mdkir ~/.thelounge`
|
5. In `compose/traefik/traefik.yml`, change `example.com` to your domain.
|
||||||
6. `touch cache/bar_cache.sqlite`
|
6. `sudo apt-get install build-essential` (if not already installed) to use makefile.
|
||||||
7. `touch cache/short_cache.sqlite`
|
7. `mkdir ~/st-sync` syncthing folder.
|
||||||
8. `cp .env.example .env`
|
8. `mkdir ~/site` public site folder.
|
||||||
9. `cp usersfile.example usersfile`
|
9. `mkdir ./compose/config` to store config.
|
||||||
10. `make serve`
|
10. `cp .env.example ./compose/.env && cp .env ~/config/.env`
|
||||||
|
11. `cp ./compose/config/conf.php ~/config/conf.php`
|
||||||
|
12. `cp usersfile.example ./compose/usersfile`
|
||||||
|
13. `make serve`
|
||||||
|
|
||||||
|
## Docker Swarm Deployment
|
||||||
|
```
|
||||||
|
docker swarm init
|
||||||
|
docker network create -d overlay --attachable traefik-public
|
||||||
|
make deploy-core
|
||||||
|
|
||||||
|
docker service logs core_traefik --details
|
||||||
|
```
|
||||||
|
|
||||||
### Notes:
|
### Notes:
|
||||||
```yaml
|
```yaml
|
||||||
@@ -43,3 +56,29 @@ This simple project uses Traefik as a reverse proxy to a Streamlit application a
|
|||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### TODO:
|
||||||
|
|
||||||
|
middleware:
|
||||||
|
```
|
||||||
|
# Enable HTTP Strict Transport Security (HSTS) to force clients to always connect via HTTPS
|
||||||
|
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||||
|
|
||||||
|
# Enable cross-site filter (XSS) and tell browser to block detected attacks
|
||||||
|
X-XSS-Protection "1; mode=block"
|
||||||
|
|
||||||
|
# Prevent some browsers from MIME-sniffing a response away from the declared Content-Type
|
||||||
|
X-Content-Type-Options "nosniff"
|
||||||
|
|
||||||
|
# Disable some features
|
||||||
|
Permissions-Policy "accelerometer=(),ambient-light-sensor=(),autoplay=(),camera=(),encrypted-media=(),focus-without-user-activation=(),geolocation=(),gyroscope=(),magnetometer=(),microphone=(),midi=(),payment=(),picture-in-picture=(),speaker=(),sync-xhr=(),usb=(),vr=()"
|
||||||
|
|
||||||
|
# Disable some features (legacy)
|
||||||
|
Feature-Policy "accelerometer 'none';ambient-light-sensor 'none'; autoplay 'none';camera 'none';encrypted-media 'none';focus-without-user-activation 'none'; geolocation 'none';gyroscope 'none';magnetometer 'none';microphone 'none';midi 'none';payment 'none';picture-in-picture 'none'; speaker 'none';sync-xhr 'none';usb 'none';vr 'none'"
|
||||||
|
|
||||||
|
# Referer
|
||||||
|
Referrer-Policy "no-referrer"
|
||||||
|
|
||||||
|
# X-Robots-Tag
|
||||||
|
X-Robots-Tag "noindex, noarchive, nofollow"
|
||||||
|
```
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
devservers:
|
||||||
|
hosts:
|
||||||
|
node09:
|
||||||
|
ansible_host: 101.100.172.55
|
||||||
|
ansible_port: 9991
|
||||||
|
node00:
|
||||||
|
ansible_host: 101.100.172.55
|
||||||
|
ansible_port: 9999
|
||||||
|
node01:
|
||||||
|
ansible_host: 101.100.172.55
|
||||||
|
ansible_port: 9998
|
||||||
|
|
||||||
|
debian:
|
||||||
|
hosts:
|
||||||
|
node00:
|
||||||
|
ansible_host: 101.100.172.55
|
||||||
|
ansible_port: 9999
|
||||||
|
node01:
|
||||||
|
ansible_host: 101.100.172.55
|
||||||
|
ansible_port: 9998
|
||||||
|
|
||||||
|
local:
|
||||||
|
hosts:
|
||||||
|
node00:
|
||||||
|
ansible_host: 192.168.50.114
|
||||||
|
ansible_port: 22
|
||||||
|
node01:
|
||||||
|
ansible_host: 192.168.50.68
|
||||||
|
ansible_port: 22
|
||||||
|
node02:
|
||||||
|
ansible_host: 192.168.50.56
|
||||||
|
ansible_port: 22
|
||||||
|
|
||||||
|
test:
|
||||||
|
hosts:
|
||||||
|
node05:
|
||||||
|
ansible_host: 192.168.50.205
|
||||||
|
ansible_port: 22
|
||||||
|
node09:
|
||||||
|
ansible_host: 192.168.50.209
|
||||||
|
ansible_port: 22
|
||||||
|
|
||||||
|
dev:
|
||||||
|
hosts:
|
||||||
|
dev301:
|
||||||
|
ansible_host: 192.168.50.71
|
||||||
|
dev302:
|
||||||
|
ansible_host: 192.168.50.170
|
||||||
|
|
||||||
|
prod:
|
||||||
|
hosts:
|
||||||
|
dc00:
|
||||||
|
ansible_host: 192.168.50.210
|
||||||
|
ansible_user: user
|
||||||
|
dc01:
|
||||||
|
ansible_host: 192.168.50.201
|
||||||
|
ansible_user: user
|
||||||
|
dc02:
|
||||||
|
ansible_host: 192.168.50.202
|
||||||
|
ansible_user: user
|
||||||
|
dc03:
|
||||||
|
ansible_host: 192.168.50.203
|
||||||
|
ansible_user: user
|
||||||
|
dc04:
|
||||||
|
ansible_host: 192.168.50.204
|
||||||
|
ansible_user: user
|
||||||
|
dc05:
|
||||||
|
ansible_host: 192.168.50.205
|
||||||
|
ansible_user: user
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
docker:
|
||||||
|
hosts:
|
||||||
|
docker01:
|
||||||
|
ansible_host: 192.168.200.222
|
||||||
|
ansible_user: 'ubuntu'
|
||||||
|
ansible_become: true
|
||||||
|
ansible_become_method: sudo
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
- name: Install Docker on Ubuntu
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- docker_install
|
||||||
|
- portainer_deploy
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Restart Docker
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: docker
|
||||||
|
state: restarted
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
- name: Ensure apt is using HTTPS
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
loop:
|
||||||
|
- apt-transport-https
|
||||||
|
- ca-certificates
|
||||||
|
- curl
|
||||||
|
- software-properties-common
|
||||||
|
|
||||||
|
- name: Add Docker GPG key
|
||||||
|
ansible.builtin.apt_key:
|
||||||
|
url: "https://download.docker.com/linux/ubuntu/gpg"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add Docker repository
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: "{{ docker_apt_repository }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install Docker CE
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: docker-ce
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Configure Docker daemon options
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/docker_daemon.json.j2"
|
||||||
|
dest: "/etc/docker/daemon.json"
|
||||||
|
owner: 'root'
|
||||||
|
group: 'root'
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
notify: Restart Docker
|
||||||
|
|
||||||
|
- name: Ensure Docker service is enabled and running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: docker
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"storage-driver": "{{ docker_daemon_options['storage-driver'] }}"
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
docker_apt_release_channel: "stable"
|
||||||
|
docker_apt_repository: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
|
||||||
|
docker_daemon_options:
|
||||||
|
storage-driver: "overlay2"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: Start Portainer
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: /home/ubuntu/docker-compose/portainer
|
||||||
|
state: present
|
||||||
|
restarted: true
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
- name: Ensure docker-compose is installed
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: docker-compose
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Ensure Docker service is running
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: docker
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: Setup Portainer directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /home/ubuntu/docker-compose/portainer
|
||||||
|
state: directory
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
|
||||||
|
- name: Deploy Portainer using Docker Compose
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/docker_compose.yaml.j2"
|
||||||
|
dest: "/home/ubuntu/docker-compose/portainer/docker-compose.yaml"
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
notify:
|
||||||
|
- Start Portainer
|
||||||
|
|
||||||
|
- name: Run Portainer docker-compose up
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: /home/ubuntu/docker-compose/portainer
|
||||||
|
state: present
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
version: '3.3'
|
||||||
|
services:
|
||||||
|
portainer:
|
||||||
|
image: portainer/portainer-ce:{{ portainer_version }}
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- portainer_data:/data
|
||||||
|
ports:
|
||||||
|
- "9000:9000"
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
portainer_data:
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
portainer_version: "latest"
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
- name: Deploy Docker Container with Docker Compose
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Ensure Docker is installed
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: docker
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Ensure Docker service is running
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: docker
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: Create a directory for Docker Compose files
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /home/ubuntu/ansible-docker/docker-compose
|
||||||
|
state: directory
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
|
||||||
|
- name: Create a directory for Nginx website files
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /home/ubuntu/docker/nginx/web
|
||||||
|
state: directory
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
|
||||||
|
- name: Copy docker-compose to remote host
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /home/ubuntu/nginx/docker-compose.yaml
|
||||||
|
dest: /home/ubuntu/ansible-docker/docker-compose/docker-compose.yaml
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
|
||||||
|
- name: Copy Nginx website folder to remote host # copies a folder - note no file extension
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /home/ubuntu/nginx/website
|
||||||
|
dest: /home/ubuntu/docker/nginx/web
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
|
||||||
|
- name: Start Docker Compose
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: /home/ubuntu/ansible-docker/docker-compose
|
||||||
|
state: present
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
- name: Undo Docker Compose Deployment
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Stop Docker Container
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: /home/ubuntu/ansible-docker/docker-compose
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Remove Docker Compose file
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /home/ubuntu/ansible-docker/docker-compose/docker-compose.yml
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Remove Docker Compose directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /home/ubuntu/ansible-docker
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Remove Website directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /home/ubuntu/docker/nginx/web
|
||||||
|
state: absent
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
docker:
|
||||||
|
hosts:
|
||||||
|
docker01:
|
||||||
|
ansible_host: 192.168.200.50
|
||||||
|
ansible_user: 'ubuntu'
|
||||||
|
ansible_become: true
|
||||||
|
ansible_become_method: sudo
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
version: "3.9"
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: nginx
|
||||||
|
container_name: jimsgarage
|
||||||
|
volumes:
|
||||||
|
- /home/ubuntu/docker/nginx/templates:/etc/nginx/templates
|
||||||
|
- /home/ubuntu/docker/nginx/web/website:/usr/share/nginx/html
|
||||||
|
environment:
|
||||||
|
- NGINX_HOST=nginx.jimsgarage.co.uk
|
||||||
|
- NGINX_PORT=80
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.nginx.entrypoints=http"
|
||||||
|
- "traefik.http.routers.nginx.rule=Host(`nginx.jimsgarage.co.uk`)"
|
||||||
|
- "traefik.http.middlewares.nginx-https-redirect.redirectscheme.scheme=https"
|
||||||
|
- "traefik.http.routers.nginx.middlewares=nginx-https-redirect"
|
||||||
|
- "traefik.http.routers.nginx-secure.entrypoints=https"
|
||||||
|
- "traefik.http.routers.nginx-secure.rule=Host(`nginx.jimsgarage.co.uk`)"
|
||||||
|
- "traefik.http.routers.nginx-secure.tls=true"
|
||||||
|
- "traefik.http.routers.nginx-secure.service=nginx"
|
||||||
|
- "traefik.http.services.nginx.loadbalancer.server.port=80"
|
||||||
|
- "traefik.docker.network=proxy"
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 148 KiB |
@@ -0,0 +1,108 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Jim's Garage Ansible Demo</title>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
||||||
|
<style>
|
||||||
|
.hero {
|
||||||
|
background: url(Jims-Garage-1.png) no-repeat center center;
|
||||||
|
background-size: cover;
|
||||||
|
height: 400px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: white;
|
||||||
|
text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.features {
|
||||||
|
margin-top: 50px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature {
|
||||||
|
padding: 20px;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background-color: #333;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Navigation Bar -->
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||||
|
<a class="navbar-brand" href="#">My Webpage</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
|
<ul class="navbar-nav ml-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#home">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#features">Features</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#contact">Contact</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<div class="hero" id="home">
|
||||||
|
<h1>Welcome to Jim's Garage Ansible Demo</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Features Section -->
|
||||||
|
<div class="container features" id="features">
|
||||||
|
<h2>Our Features</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="feature">
|
||||||
|
<i class="fas fa-cogs fa-3x"></i>
|
||||||
|
<h4>Feature 1</h4>
|
||||||
|
<p>Dynamic and interactive elements.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="feature">
|
||||||
|
<i class="fas fa-bolt fa-3x"></i>
|
||||||
|
<h4>Feature 2</h4>
|
||||||
|
<p>Responsive design and transitions.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="feature">
|
||||||
|
<i class="fas fa-heart fa-3x"></i>
|
||||||
|
<h4>Feature 3</h4>
|
||||||
|
<p>Engaging user experiences.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Footer Section -->
|
||||||
|
<div class="footer">
|
||||||
|
<p>© 2024 My Webpage. All rights reserved.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
- name: Update Windows, Arch Linux, and Ubuntu
|
||||||
|
hosts: all
|
||||||
|
tasks:
|
||||||
|
- name: Gather facts
|
||||||
|
ansible.builtin.setup:
|
||||||
|
|
||||||
|
- name: Update Windows
|
||||||
|
when: ansible_facts['os_family'] == 'Windows'
|
||||||
|
ansible.windows.win_updates:
|
||||||
|
category_names:
|
||||||
|
- SecurityUpdates
|
||||||
|
- UpdateRollups
|
||||||
|
- CriticalUpdates
|
||||||
|
state: installed
|
||||||
|
register: win_update_result
|
||||||
|
|
||||||
|
- name: Check if Windows requires a reboot
|
||||||
|
when: win_update_result.changed and win_update_result.reboot_required | default(false)
|
||||||
|
ansible.windows.win_reboot:
|
||||||
|
reboot_timeout: 600
|
||||||
|
register: win_reboot_result
|
||||||
|
|
||||||
|
- name: Update Arch Linux
|
||||||
|
when: ansible_facts['os_family'] == 'Arch'
|
||||||
|
community.general.pacman:
|
||||||
|
update_cache: true
|
||||||
|
upgrade: true
|
||||||
|
register: arch_update_result
|
||||||
|
|
||||||
|
- name: Check if Arch Linux requires a reboot
|
||||||
|
when: ansible_facts['os_family'] == 'Arch' and arch_update_result.changed
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /run/reboot-required
|
||||||
|
register: arch_reboot_required
|
||||||
|
|
||||||
|
- name: Reboot Arch Linux if required
|
||||||
|
when: arch_reboot_required.stat.exists | default(false)
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
reboot_timeout: 600
|
||||||
|
|
||||||
|
- name: Update Ubuntu
|
||||||
|
when: ansible_facts['os_family'] == 'Debian'
|
||||||
|
ansible.builtin.apt:
|
||||||
|
upgrade: dist
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Check if a reboot is required on Ubuntu
|
||||||
|
when: ansible_facts['os_family'] == 'Debian'
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /var/run/reboot-required
|
||||||
|
register: ubuntu_reboot_required
|
||||||
|
|
||||||
|
- name: Reboot Ubuntu if required
|
||||||
|
when: ubuntu_reboot_required.stat.exists | default(false)
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
reboot_timeout: 600
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
arch:
|
||||||
|
hosts:
|
||||||
|
arch01:
|
||||||
|
ansible_host: 192.168.200.214
|
||||||
|
ansible_user: 'root'
|
||||||
|
ansible_python_interpreter: /usr/bin/python3
|
||||||
|
|
||||||
|
docker:
|
||||||
|
hosts:
|
||||||
|
docker01:
|
||||||
|
ansible_host: 192.168.200.50
|
||||||
|
ansible_user: 'ubuntu'
|
||||||
|
ansible_become: true
|
||||||
|
ansible_become_method: sudo
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: ansible.utils
|
||||||
|
- name: community.general
|
||||||
|
- name: ansible.posix
|
||||||
|
- name: kubernetes.core
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
os: "linux"
|
||||||
|
arch: "amd64"
|
||||||
|
|
||||||
|
kube_vip_version: "v0.8.0"
|
||||||
|
vip_interface: eth0
|
||||||
|
vip: 192.168.3.50
|
||||||
|
|
||||||
|
metallb_version: v0.13.12
|
||||||
|
lb_range: 192.168.3.80-192.168.3.90
|
||||||
|
lb_pool_name: first-pool
|
||||||
|
|
||||||
|
rke2_version: "v1.29.4+rke2r1"
|
||||||
|
rke2_install_dir: "/usr/local/bin"
|
||||||
|
rke2_binary_url: "https://github.com/rancher/rke2/releases/download/{{ rke2_version }}/rke2.linux-amd64"
|
||||||
|
|
||||||
|
ansible_user: ubuntu
|
||||||
|
ansible_become: true
|
||||||
|
ansible_become_method: sudo
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# Make sure Ansible host has access to these devices
|
||||||
|
# Good idea to snapshot all machines and deploy uing cloud-init
|
||||||
|
|
||||||
|
[servers]
|
||||||
|
server1 ansible_host=192.168.3.21
|
||||||
|
server2 ansible_host=192.168.3.22
|
||||||
|
server3 ansible_host=192.168.3.23
|
||||||
|
|
||||||
|
[agents]
|
||||||
|
agent1 ansible_host=192.168.3.24
|
||||||
|
agent2 ansible_host=192.168.3.25
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copy agent config to all agents - we need to change agent2 & 3 later with the token
|
||||||
|
- name: Deploy RKE2 Agent Configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-agent-config.j2
|
||||||
|
dest: /etc/rancher/rke2/config.yaml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['agents']
|
||||||
|
|
||||||
|
# Check agents have restarted to pick up config
|
||||||
|
- name: Ensure RKE2 agents are enabled and running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: rke2-agent
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
write-kubeconfig-mode: "0644"
|
||||||
|
token: {{ hostvars['server1']['token'] }}
|
||||||
|
server: https://{{ hostvars['server1']['ansible_host'] }}:9345
|
||||||
|
node-label:
|
||||||
|
- "agent=true"
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# Copy server config with token to all servers except server 1 (this has token)
|
||||||
|
- name: Deploy RKE2 server Configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-server-config.j2
|
||||||
|
dest: /etc/rancher/rke2/config.yaml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname != groups['servers'][0]
|
||||||
|
|
||||||
|
# Keep checking the cluster API until it's functioning (deployed)
|
||||||
|
- name: Wait for cluster API to be ready (can take 5-10 mins depending on internet/hardware)
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "kubectl get nodes"
|
||||||
|
register: kubectl_output
|
||||||
|
until: "'connection refused' not in kubectl_output.stderr"
|
||||||
|
retries: 120
|
||||||
|
delay: 10
|
||||||
|
changed_when: true
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Use kubectl to deploy yaml. Perhaps this can be added to the manifest folder initially
|
||||||
|
- name: Apply kube vip configuration file
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml apply -f https://kube-vip.io/manifests/rbac.yaml
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Apply the kube-vip configration. Perhaps this can be added to the manifest folder initially
|
||||||
|
- name: Apply kube vip configuration file
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Check that additional servers are restarted
|
||||||
|
- name: Ensure additional RKE2 servers are enabled and running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: rke2-server
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
when: inventory_hostname != groups['servers'][0]
|
||||||
|
|
||||||
|
# enable additional servers
|
||||||
|
- name: Ensure RKE2 server is enabled and running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: rke2-server
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
when: inventory_hostname != groups['servers'][0]
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
write-kubeconfig-mode: "0644"
|
||||||
|
token: {{ hostvars['server1']['token'] }}
|
||||||
|
server: https://{{ hostvars['server1']['ansible_host'] }}:9345
|
||||||
|
tls-san:
|
||||||
|
- {{ vip }}
|
||||||
|
- {{ hostvars['server1']['ansible_host'] }}
|
||||||
|
- {{ hostvars['server2']['ansible_host'] }}
|
||||||
|
- {{ hostvars['server3']['ansible_host'] }}
|
||||||
|
node-label:
|
||||||
|
- server=true
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# Wait for Server 1 to be ready before continuing with metallb deployment
|
||||||
|
- name: Wait for k8s nodes with node label 'server=true' to be ready, otherwise we cannot start metallb deployment
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "kubectl wait --for=condition=Ready nodes --selector server=true --timeout=600s"
|
||||||
|
register: nodes_ready
|
||||||
|
retries: 120
|
||||||
|
delay: 10
|
||||||
|
changed_when: true
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Create namespace so that we can deploy metallb
|
||||||
|
- name: Apply metallb namespace
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Apply metallb manifest
|
||||||
|
- name: Apply metallb manifest
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/{{ metallb_version }}/config/manifests/metallb-native.yaml
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Wait for metallb deployment pods to be alive before deploying metallb manifests
|
||||||
|
- name: Wait for metallb pods to be ready, otherwise we cannot start metallb deployment
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "kubectl wait --namespace metallb-system --for=condition=ready pod --selector=component=controller --timeout=1800s"
|
||||||
|
changed_when: true
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Apply L2 Advertisement for metallb
|
||||||
|
- name: Apply metallb L2 Advertisement
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl apply -f https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/l2Advertisement.yaml
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Deploy metal IP Pool to Server 1
|
||||||
|
- name: Copy metallb IPPool to server 1
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/metallb-ippool.j2
|
||||||
|
dest: /home/{{ ansible_user }}/ippool.yaml
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: '0755'
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# don't think this will work as nodes are no execute, might need agents first
|
||||||
|
- name: Apply metallb ipppool
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl apply -f /home/{{ ansible_user }}/ippool.yaml
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: IPAddressPool
|
||||||
|
metadata:
|
||||||
|
name: {{ lb_pool_name }}
|
||||||
|
namespace: metallb-system
|
||||||
|
spec:
|
||||||
|
addresses:
|
||||||
|
- {{ lb_range }}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Create directory to deploy kube-vip manifest
|
||||||
|
- name: Create directory for Kube VIP Manifest
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/var/lib/rancher/rke2/server/manifests"
|
||||||
|
state: directory
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['servers']
|
||||||
|
|
||||||
|
# Copy kube-vip to server 1 manifest folder for auto deployment at bootstrap
|
||||||
|
- name: Deploy Kube VIP Configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/kube-vip-config.j2
|
||||||
|
dest: /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: kube-vip-ds
|
||||||
|
app.kubernetes.io/version: {{ kube_vip_version }}
|
||||||
|
name: kube-vip-ds
|
||||||
|
namespace: kube-system
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: kube-vip-ds
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: kube-vip-ds
|
||||||
|
app.kubernetes.io/version: {{ kube_vip_version }}
|
||||||
|
spec:
|
||||||
|
affinity:
|
||||||
|
nodeAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
nodeSelectorTerms:
|
||||||
|
- matchExpressions:
|
||||||
|
- key: node-role.kubernetes.io/master
|
||||||
|
operator: Exists
|
||||||
|
- matchExpressions:
|
||||||
|
- key: node-role.kubernetes.io/control-plane
|
||||||
|
operator: Exists
|
||||||
|
containers:
|
||||||
|
- args:
|
||||||
|
- manager
|
||||||
|
env:
|
||||||
|
- name: vip_arp
|
||||||
|
value: "true"
|
||||||
|
- name: port
|
||||||
|
value: "6443"
|
||||||
|
- name: vip_interface
|
||||||
|
value: {{ vip_interface }}
|
||||||
|
- name: vip_cidr
|
||||||
|
value: "32"
|
||||||
|
- name: cp_enable
|
||||||
|
value: "true"
|
||||||
|
- name: cp_namespace
|
||||||
|
value: kube-system
|
||||||
|
- name: vip_ddns
|
||||||
|
value: "false"
|
||||||
|
- name: svc_enable
|
||||||
|
value: "false"
|
||||||
|
- name: svc_leasename
|
||||||
|
value: plndr-svcs-lock
|
||||||
|
- name: vip_leaderelection
|
||||||
|
value: "true"
|
||||||
|
- name: vip_leasename
|
||||||
|
value: plndr-cp-lock
|
||||||
|
- name: vip_leaseduration
|
||||||
|
value: "5"
|
||||||
|
- name: vip_renewdeadline
|
||||||
|
value: "3"
|
||||||
|
- name: vip_retryperiod
|
||||||
|
value: "1"
|
||||||
|
- name: address
|
||||||
|
value: {{ vip }}
|
||||||
|
- name: prometheus_server
|
||||||
|
value: :2112
|
||||||
|
image: ghcr.io/kube-vip/kube-vip:{{ kube_vip_version }}
|
||||||
|
imagePullPolicy: Always
|
||||||
|
name: kube-vip
|
||||||
|
resources: {}
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- NET_RAW
|
||||||
|
hostNetwork: true
|
||||||
|
serviceAccountName: kube-vip
|
||||||
|
tolerations:
|
||||||
|
- effect: NoSchedule
|
||||||
|
operator: Exists
|
||||||
|
- effect: NoExecute
|
||||||
|
operator: Exists
|
||||||
|
updateStrategy: {}
|
||||||
|
status:
|
||||||
|
currentNumberScheduled: 0
|
||||||
|
desiredNumberScheduled: 0
|
||||||
|
numberMisscheduled: 0
|
||||||
|
numberReady: 0
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
- name: Enable IPv4 forwarding
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv4.ip_forward
|
||||||
|
value: "1"
|
||||||
|
state: present
|
||||||
|
reload: true
|
||||||
|
tags: sysctl
|
||||||
|
|
||||||
|
- name: Enable IPv6 forwarding
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv6.conf.all.forwarding
|
||||||
|
value: "1"
|
||||||
|
state: present
|
||||||
|
reload: true
|
||||||
|
tags: sysctl
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# Create a directory to download RKE2 binary to
|
||||||
|
- name: Create directory for RKE2 binary
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ rke2_install_dir }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
# Download the RKE2 binary
|
||||||
|
- name: Download RKE2 binary
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ rke2_binary_url }}"
|
||||||
|
dest: "{{ rke2_install_dir }}/rke2"
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
# Set permissions on the RKE2 binary
|
||||||
|
- name: Set executable permissions on the RKE2 binary
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ rke2_install_dir }}/rke2"
|
||||||
|
mode: '0755'
|
||||||
|
state: file
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
- name: Create directory for RKE2 config
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/etc/rancher/rke2"
|
||||||
|
state: directory
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Create directory for RKE2 token
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/var/lib/rancher/rke2/server"
|
||||||
|
state: directory
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
# Copy server config to server 1 for bootstrap - we need to change server2 & 3 later with the token
|
||||||
|
- name: Deploy RKE2 server Configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-server-config.j2
|
||||||
|
dest: /etc/rancher/rke2/config.yaml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['servers']
|
||||||
|
|
||||||
|
- name: Create systemd service file for RKE2 server
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-server.service.j2
|
||||||
|
dest: /etc/systemd/system/rke2-server.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['servers']
|
||||||
|
|
||||||
|
- name: Create systemd service file for RKE2 agent
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-agent.service.j2
|
||||||
|
dest: /etc/systemd/system/rke2-agent.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['agents']
|
||||||
|
|
||||||
|
# we enable the first server to generate tokens etc, copy this afterwards to other servers
|
||||||
|
- name: Ensure RKE2 server is enabled and running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: rke2-server
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
when: inventory_hostname in groups['servers'][0]
|
||||||
|
|
||||||
|
# wait for node token to be availale so that we can copy it, we need this to join other nodes
|
||||||
|
- name: Wait for node-token
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
path: /var/lib/rancher/rke2/server/node-token
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# wait for kubectl to be downloaded, part of the rke2 installation
|
||||||
|
- name: Wait for kubectl
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
path: /var/lib/rancher/rke2/bin/kubectl
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# copy kubectl to usr bin so that all users can run kubectl commands
|
||||||
|
- name: Copy kubectl to user bin
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /var/lib/rancher/rke2/bin/kubectl
|
||||||
|
dest: /usr/local/bin/kubectl
|
||||||
|
mode: '0755'
|
||||||
|
remote_src: true
|
||||||
|
become: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# wait for the kubectl copy to complete
|
||||||
|
- name: Wait for kubectl
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
path: /usr/local/bin/kubectl
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# modify token access
|
||||||
|
- name: Register node-token file access mode
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /var/lib/rancher/rke2/server
|
||||||
|
register: p
|
||||||
|
|
||||||
|
- name: Change file access for node-token
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /var/lib/rancher/rke2/server
|
||||||
|
mode: "g+rx,o+rx"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Save token as variable
|
||||||
|
- name: Fetch the token from the first server node
|
||||||
|
ansible.builtin.slurp:
|
||||||
|
src: /var/lib/rancher/rke2/server/token
|
||||||
|
register: rke2_token
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
run_once: true
|
||||||
|
|
||||||
|
# convert token to fact
|
||||||
|
- name: Save Master node-token for later
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
token: "{{ rke2_token.content | b64decode | regex_replace('\n', '') }}"
|
||||||
|
|
||||||
|
# revert token file access
|
||||||
|
- name: Restore node-token file access
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /var/lib/rancher/rke2/server
|
||||||
|
mode: "{{ p.stat.mode }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# check .kube folder exists so that we can use kubectl (config resides here)
|
||||||
|
- name: Ensure .kube directory exists in user's home
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/home/{{ ansible_user }}/.kube"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
become: true
|
||||||
|
|
||||||
|
# copy kubectl config file to .kube folder
|
||||||
|
- name: Copy config file to user home directory
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /etc/rancher/rke2/rke2.yaml
|
||||||
|
dest: "/home/{{ ansible_user }}/.kube/config"
|
||||||
|
remote_src: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
mode: "u=rw,g=,o="
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# change IP from local to server 1 IP
|
||||||
|
- name: Replace IP address with server1
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: /home/{{ ansible_user }}/.kube/config
|
||||||
|
regexp: '127.0.0.1'
|
||||||
|
replace: "{{ hostvars['server1']['ansible_host'] }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# rke2-agent.service.j2
|
||||||
|
[Unit]
|
||||||
|
Description=RKE2 Agent
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/local/bin/rke2 agent
|
||||||
|
KillMode=process
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
write-kubeconfig-mode: "0644"
|
||||||
|
tls-san:
|
||||||
|
- {{ vip }}
|
||||||
|
- {{ hostvars['server1']['ansible_host'] }}
|
||||||
|
- {{ hostvars['server2']['ansible_host'] }}
|
||||||
|
- {{ hostvars['server3']['ansible_host'] }}
|
||||||
|
node-label:
|
||||||
|
- server=true
|
||||||
|
disable:
|
||||||
|
- rke2-ingress-nginx
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# rke2-server.service.j2
|
||||||
|
[Unit]
|
||||||
|
Description=RKE2 server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/local/bin/rke2 server
|
||||||
|
KillMode=process
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# Hello, thanks for using my playbook, hopefully you can help to improve it.
|
||||||
|
# Things that need adding: (there are many more)
|
||||||
|
# 1) Support different OS & architectures
|
||||||
|
# 2) Support multiple CNIs
|
||||||
|
# 3) Improve the wait logic
|
||||||
|
# 4) Use kubernetes Ansible plugins more sensibly
|
||||||
|
# 5) Optimise flow logic
|
||||||
|
# 6) Clean up
|
||||||
|
|
||||||
|
###############################################################
|
||||||
|
# MAKE SURE YOU CHANGE group_vars/all.yaml VARIABLES!!!!!!!!!!!
|
||||||
|
###############################################################
|
||||||
|
|
||||||
|
# bootstraps first server and copies configs for others/agents
|
||||||
|
- name: Prepare all nodes
|
||||||
|
hosts: servers,agents
|
||||||
|
gather_facts: true # enables us to gather lots of useful variables: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
|
||||||
|
roles:
|
||||||
|
- prepare-nodes
|
||||||
|
|
||||||
|
# creates directories for download and then downloads RKE2 and changes permissions
|
||||||
|
- name: Download RKE2
|
||||||
|
hosts: servers,agents
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- rke2-download
|
||||||
|
|
||||||
|
# Creates RKE2 bootstrap manifests folder and copies kube-vip template over (configured with variables)
|
||||||
|
- name: Deploy Kube VIP
|
||||||
|
hosts: servers
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- kube-vip
|
||||||
|
|
||||||
|
# bootstraps the first server, copies configs to nodes, saves token to use later
|
||||||
|
- name: Prepare RKE2 on Servers and Agents
|
||||||
|
hosts: servers,agents
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- rke2-prepare
|
||||||
|
|
||||||
|
# Adds additional servers using the token from the previous task
|
||||||
|
- name: Add additional RKE2 Servers
|
||||||
|
hosts: servers
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- add-server
|
||||||
|
|
||||||
|
# Adds agents to the cluster
|
||||||
|
- name: Add additional RKE2 Agents
|
||||||
|
hosts: agents
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- add-agent
|
||||||
|
|
||||||
|
# Finish kube-vip, add metallb
|
||||||
|
- name: Apply manifests after cluster is created
|
||||||
|
hosts: servers
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- apply-manifests
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
- name: Deploy Docker Container with Docker Compose
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Include variables file
|
||||||
|
ansible.builtin.include_vars: myvars.yaml
|
||||||
|
|
||||||
|
- name: Ensure Docker is installed
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: docker
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Ensure Docker service is running
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: docker
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: Create a directory for Docker Compose files
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /home/ubuntu/ansible-docker/docker-compose
|
||||||
|
state: directory
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
|
||||||
|
- name: Create a directory for Nginx website files
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /home/ubuntu/docker/nginx/web
|
||||||
|
state: directory
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
|
||||||
|
- name: Copy docker-compose to remote host
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /home/ubuntu/nginx/docker-compose.yaml
|
||||||
|
dest: /home/ubuntu/ansible-docker/docker-compose/docker-compose.yaml
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
|
||||||
|
- name: Copy Nginx website folder to remote host # copies a folder - note no file extension
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /home/ubuntu/nginx/website
|
||||||
|
dest: /home/ubuntu/docker/nginx/web
|
||||||
|
mode: '0755' # Optional file permissions
|
||||||
|
owner: ubuntu # Optional ownership
|
||||||
|
group: ubuntu # Optional group ownership
|
||||||
|
|
||||||
|
- name: Replace old name with new name (requires Ansible >= 2.4)
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: /home/ubuntu/docker/nginx/web/website/index.html
|
||||||
|
regexp: "Jim's Garage"
|
||||||
|
replace: "{{ website_name }}"
|
||||||
|
|
||||||
|
- name: Access and print secret
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: /home/ubuntu/docker/nginx/web/website/index.html
|
||||||
|
regexp: "Our Features"
|
||||||
|
replace: "{{ api_key }}"
|
||||||
|
|
||||||
|
- name: Start Docker Compose
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: /home/ubuntu/ansible-docker/docker-compose
|
||||||
|
state: present
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
password
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
api_key: SuperSecretPassword
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
|
||||||
|
vars:
|
||||||
|
omz_install_zsh: true
|
||||||
|
users:
|
||||||
|
- name: "user"
|
||||||
|
group: "user"
|
||||||
|
settings: ""
|
||||||
|
tasks:
|
||||||
|
- name: Run ansible-role-oh-my-zsh.
|
||||||
|
include_role:
|
||||||
|
name: "ctorgalson.oh-my-zsh"
|
||||||
|
vars:
|
||||||
|
omz_user: "{{ item }}"
|
||||||
|
# Only create `.zshrc` for user 'user'; item.settings will be
|
||||||
|
# appended to `.zshrc` for the user 'user'.
|
||||||
|
omz_zshrc_create: "{{ (item.name == 'user') | ternary(true, false) }}"
|
||||||
|
omz_plugins:
|
||||||
|
- "kubectl"
|
||||||
|
- "git"
|
||||||
|
with_items: "{{ users }}"
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
# Ansible Role Oh My ZSH
|
||||||
|
|
||||||
|
This is a basic Ansible role to enable and configure Oh My Zsh on Fedora,
|
||||||
|
Ubuntu, or MacOS. It should also work on many other \*nix variants. It
|
||||||
|
performs the following tasks:
|
||||||
|
|
||||||
|
- Install and minimally configure Zsh:
|
||||||
|
- make sure it exists,
|
||||||
|
- set it as the default shell for the user specified by the role.
|
||||||
|
- Install Oh My Zsh for each specified user (in `~/.oh-my-zsh` by default).
|
||||||
|
- Configure (Oh My) Zsh by optionally creating a `.zshrc` file for each
|
||||||
|
specified user.
|
||||||
|
- Alternately, configure Zsh by adding a block of lines to individual
|
||||||
|
users' `.zshrc` files.
|
||||||
|
|
||||||
|
## Role variables
|
||||||
|
|
||||||
|
| Variable name | Default value | Description |
|
||||||
|
|----------------|---------------|-------------|
|
||||||
|
| `omz_install_zsh` | `false` | Defines whether or not the role should attempt to install Zsh. |
|
||||||
|
| `omz_user` | `[]` | The user to install/configure (Oh My) Zsh for. See below for its properties. |
|
||||||
|
| `omz_user.name` | `-` | The name of the user. |
|
||||||
|
| `omz_user.group` | `-` | The group of the user |
|
||||||
|
| `omz_user.settings` | `-` | Extra settings (as a mult-line string) such as variable exports or aliases to add to the user's `.zshrc` file. Only used if `omz_zshrc_create` is `true`. |
|
||||||
|
| `omz_git_repository` | `https://github.com/robbyrussell/oh-my-zsh.git` | The git repo to clone Oh My Zsh from. |
|
||||||
|
| `omz_install_directory` | `.oh-my-zsh` | The name of the directory to clone Oh My Zsh into. |
|
||||||
|
| `omz_zshrc_create` | `true` | Whether or not to create `.zshrc`. If `true`, will create `.zshrc` from a template. |
|
||||||
|
| `omz_zshrc_template` | `templates/zshrc.zsh-template.j2` | The template used to create the user's `.zshrc` file when `omz_zshrc_create` is `true`. |
|
||||||
|
| `omz_zshrc_backup` | `true` | Whether or not to create backup the existing `.zshrc` files when the role changes it. |
|
||||||
|
| `omz_zsh_theme` | `robbyrussell` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_case_sensitive` | `false` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_hyphen_insensitive` | `false` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_disable_auto_update` | `false` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_update_zsh_days` | `13` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_disable_ls_colors` | `false` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_disable_auto_title` | `false` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_enable_correction` | `false` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_completion_waiting_dots` | `false` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_disable_untracked_files_dirty` | `false` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_hist_stamps` | `mm/dd/yyyy` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_zsh_custom` | `$ZSH/custom` | See `templates/zshrc.zsh-template`. |
|
||||||
|
| `omz_plugins` | `[]` | A list of Oh My Zsh plugins to enable. |
|
||||||
|
|
||||||
|
## Role task files
|
||||||
|
|
||||||
|
### `main.yml`: task coordination
|
||||||
|
|
||||||
|
This file includes files that peform specific subsets of tasks.
|
||||||
|
|
||||||
|
### `zsh.yml`: Zsh setup
|
||||||
|
|
||||||
|
This task installs and sets zsh as the default shell for a user.
|
||||||
|
|
||||||
|
#### Variables used
|
||||||
|
|
||||||
|
- `omz_user`
|
||||||
|
|
||||||
|
### `oh-my-zsh-install.yml`: Oh My Zsh installation
|
||||||
|
|
||||||
|
This task clones the Oh My Zsh repository into the user directory of each
|
||||||
|
specified user and sets the appropriate permissions on the directory.
|
||||||
|
|
||||||
|
#### Variables used
|
||||||
|
|
||||||
|
- `omz_user`
|
||||||
|
- `omz_install_directory`
|
||||||
|
- `omz_git_repository`
|
||||||
|
- `omz_install_path`
|
||||||
|
|
||||||
|
### `oh-my-zsh-zshrc.yml`: Oh My Zsh configuration
|
||||||
|
|
||||||
|
This task creates the user a `.zshrc` file containing global values for various
|
||||||
|
Oh My Zsh options based on [the `.zshrc` template in the oh-my-zsh repository](https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/templates/zshrc.zsh-template).
|
||||||
|
The task can be configured to back up any existing `.zshrc` file.
|
||||||
|
|
||||||
|
This task only runs when `omz_zshrc_create` is set to `true`.
|
||||||
|
|
||||||
|
#### Variables used
|
||||||
|
|
||||||
|
- `omz_user`
|
||||||
|
- `omz_zshrc_template`
|
||||||
|
- `omz_zshrc_backup`
|
||||||
|
|
||||||
|
### `zsh-zshrc.yml`: final Zsh configuration
|
||||||
|
|
||||||
|
This task adds individual lines to the `.zshrc` file. This is useful for adding
|
||||||
|
Zsh settings on an already-existing `.zshrc` file without creating it
|
||||||
|
from scratch.
|
||||||
|
|
||||||
|
This task only runs when `omz_zshrc_create` is set to `false`.
|
||||||
|
|
||||||
|
#### Variables used
|
||||||
|
|
||||||
|
- `omz_user`
|
||||||
|
- `omz_zshrc_backup`
|
||||||
|
|
||||||
|
## Sample playbook
|
||||||
|
|
||||||
|
---
|
||||||
|
- name: Playbook
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
|
||||||
|
vars:
|
||||||
|
omz_install_zsh: true
|
||||||
|
users:
|
||||||
|
- name: "lorem"
|
||||||
|
group: "lorem"
|
||||||
|
settings: ""
|
||||||
|
- name: "ipsum"
|
||||||
|
group: "ipsum"
|
||||||
|
settings: |
|
||||||
|
export PATH="/usr/local/sbin:$path"
|
||||||
|
alias l="ls -AF"
|
||||||
|
tasks:
|
||||||
|
- name: Run ansible-role-oh-my-zsh.
|
||||||
|
include_role:
|
||||||
|
name: "ansible-role-oh-my-zsh"
|
||||||
|
vars:
|
||||||
|
omz_user: "{{ item }}"
|
||||||
|
# Only create `.zshrc` for user 'lorem'; item.settings will be
|
||||||
|
# appended to `.zshrc` for the user 'ipsum'.
|
||||||
|
omz_zshrc_create: "{{ (item.name == 'lorem') | ternary(true, false) }}"
|
||||||
|
omz_plugins:
|
||||||
|
- "autojump"
|
||||||
|
- "git"
|
||||||
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook -i inventory playbooks/ansible-role-oh-my-zsh/playbook.yml -l 'dev303' -K
|
||||||
|
```
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
# Role vars.
|
||||||
|
omz_install_zsh: false
|
||||||
|
|
||||||
|
# User vars.
|
||||||
|
omz_user: []
|
||||||
|
# - name: "someuser"
|
||||||
|
# group: "somegroup"
|
||||||
|
# settings: |
|
||||||
|
# export PATH="/usr/local/sbin:$path"
|
||||||
|
# alias l="ls -AF"
|
||||||
|
|
||||||
|
# Oh My ZSH vars.
|
||||||
|
omz_git_repository: "https://github.com/robbyrussell/oh-my-zsh.git"
|
||||||
|
omz_install_directory: ".oh-my-zsh"
|
||||||
|
|
||||||
|
# Oh My ZSH template vars.
|
||||||
|
omz_zshrc_create: true
|
||||||
|
omz_zshrc_template: "templates/zshrc.zsh-template.j2"
|
||||||
|
omz_custom_theme_template: "templates/custom.zsh-theme.j2"
|
||||||
|
omz_zshrc_backup: true
|
||||||
|
omz_zshrc_force: true
|
||||||
|
omz_zsh_theme: "robbyrussell"
|
||||||
|
omz_case_sensitive: false
|
||||||
|
omz_hyphen_insensitive: false
|
||||||
|
omz_disable_auto_update: false
|
||||||
|
omz_update_zsh_days: 13
|
||||||
|
omz_disable_ls_colors: false
|
||||||
|
omz_disable_auto_title: false
|
||||||
|
omz_enable_correction: false
|
||||||
|
omz_completion_waiting_dots: false
|
||||||
|
omz_disable_untracked_files_dirty: false
|
||||||
|
omz_hist_stamps: "mm/dd/yyyy"
|
||||||
|
omz_zsh_custom: "$ZSH/custom"
|
||||||
|
omz_plugins: []
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
# Make sure zsh is installed and set to the user's default shell.
|
||||||
|
- name: "OMZ | include zsh.yml tasks."
|
||||||
|
include_tasks: "zsh.yml"
|
||||||
|
tags:
|
||||||
|
- "zsh"
|
||||||
|
- "configure"
|
||||||
|
- "configurezsh"
|
||||||
|
|
||||||
|
# Install oh-my-zsh.
|
||||||
|
- name: "OMZ | include oh-my-zsh.yml tasks."
|
||||||
|
include_tasks: oh-my-zsh-install.yml
|
||||||
|
tags:
|
||||||
|
- "oh-my-zsh"
|
||||||
|
- "install"
|
||||||
|
- "installohmyzsh"
|
||||||
|
|
||||||
|
# Configure oh-my-zsh with a custom .zshrc template if omz_zshrc_create
|
||||||
|
# is set to 'true'.
|
||||||
|
- name: "OMZ | include oh-my-zsh-zshrc.yml tasks."
|
||||||
|
include_tasks: oh-my-zsh-zshrc.yml
|
||||||
|
tags:
|
||||||
|
- "oh-my-zsh"
|
||||||
|
- "configure"
|
||||||
|
- "configureohmyzsh"
|
||||||
|
|
||||||
|
# Finally, add exports etc to .zshrc /last/ (i.e. so they get added to whaterver
|
||||||
|
# .zshrc exists.
|
||||||
|
- name: "OMZ | include zsh-zshrc.yml tasks."
|
||||||
|
include_tasks: zsh-zshrc.yml
|
||||||
|
tags:
|
||||||
|
- "zsh"
|
||||||
|
- "configure"
|
||||||
|
- "configurezsh"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
- name: "OMZ | establish install location."
|
||||||
|
set_fact:
|
||||||
|
omz_install_path: "/{{ omz_user_home_dir }}/{{ omz_user.name }}/{{ omz_install_directory }}"
|
||||||
|
|
||||||
|
- name: "OMZ | clone Oh My ZSH repo for user."
|
||||||
|
git:
|
||||||
|
repo: "{{ omz_git_repository }}"
|
||||||
|
dest: "{{ omz_install_path }}"
|
||||||
|
update: "true"
|
||||||
|
accept_hostkey: "true"
|
||||||
|
version: "master"
|
||||||
|
register: "omz_clone"
|
||||||
|
|
||||||
|
- name: "OMZ | set ownership on newly cloned repository."
|
||||||
|
file:
|
||||||
|
path: "{{ omz_install_path }}"
|
||||||
|
owner: "{{ omz_user.name }}"
|
||||||
|
group: "{{ omz_user.group }}"
|
||||||
|
recurse: "true"
|
||||||
|
when: "omz_clone is changed"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: "OMZ | derive user .zshrc path."
|
||||||
|
set_fact:
|
||||||
|
omz_user_zshrc_path: "/{{ omz_user_home_dir }}/{{ omz_user.name }}/.zshrc"
|
||||||
|
|
||||||
|
- name: "OMZ | template .zshrc into place if required."
|
||||||
|
template:
|
||||||
|
src: "{{ omz_zshrc_template }}"
|
||||||
|
dest: "{{ omz_user_zshrc_path }}"
|
||||||
|
owner: "{{ omz_user.name }}"
|
||||||
|
group: "{{ omz_user.group }}"
|
||||||
|
backup: "{{ omz_zshrc_backup }}"
|
||||||
|
force: "{{ omz_zshrc_force }}"
|
||||||
|
when: "omz_zshrc_create"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
# Note that we assume this file exists! lineinfile will fail if the file is
|
||||||
|
# not present.
|
||||||
|
- name: "OMZ | export vars to .zshrc if required."
|
||||||
|
blockinfile:
|
||||||
|
dest: "{{ omz_user_zshrc_path }}"
|
||||||
|
block: "{{ omz_user.settings }}"
|
||||||
|
backup: "{{ omz_zshrc_backup }}"
|
||||||
|
when:
|
||||||
|
- "omz_user.settings is defined"
|
||||||
|
# Don't flag this line for checking if the value is empty--checking for an
|
||||||
|
# empty value makes perfect sense.
|
||||||
|
- "omz_user.settings != ''" # noqa 602
|
||||||
|
- "not omz_zshrc_create"
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
- name: "OMZ | establish home directory."
|
||||||
|
set_fact:
|
||||||
|
omz_user_home_dir: "{{ (ansible_system == 'Darwin') | ternary('Users', 'home') }}"
|
||||||
|
|
||||||
|
- name: "OMZ | ensure zsh is installed."
|
||||||
|
block:
|
||||||
|
- name: "OMZ | install zsh for Linux."
|
||||||
|
package:
|
||||||
|
name: "zsh"
|
||||||
|
state: "present"
|
||||||
|
when:
|
||||||
|
- "ansible_system == 'Linux'"
|
||||||
|
- "omz_install_zsh"
|
||||||
|
|
||||||
|
- name: "OMZ | install zsh for macOS."
|
||||||
|
homebrew:
|
||||||
|
name: "zsh"
|
||||||
|
state: "present"
|
||||||
|
when:
|
||||||
|
- "ansible_system == 'Darwin'"
|
||||||
|
- "omz_install_zsh"
|
||||||
|
|
||||||
|
- name: "OMZ | get zsh installed path."
|
||||||
|
shell: "command -v zsh"
|
||||||
|
register: omz_zsh_installed_path
|
||||||
|
changed_when: "false"
|
||||||
|
|
||||||
|
- name: "OMZ | get user shell to zsh."
|
||||||
|
user:
|
||||||
|
name: "{{ omz_user.name }}"
|
||||||
|
shell: "{{ omz_zsh_installed_path.stdout }}"
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
# vim:ft=zsh ts=2 sw=2 sts=2
|
||||||
|
#
|
||||||
|
# agnoster's Theme - https://gist.github.com/3712874
|
||||||
|
# A Powerline-inspired theme for ZSH
|
||||||
|
#
|
||||||
|
# # README
|
||||||
|
#
|
||||||
|
# In order for this theme to render correctly, you will need a
|
||||||
|
# [Powerline-patched font](https://github.com/Lokaltog/powerline-fonts).
|
||||||
|
# Make sure you have a recent version: the code points that Powerline
|
||||||
|
# uses changed in 2012, and older versions will display incorrectly,
|
||||||
|
# in confusing ways.
|
||||||
|
#
|
||||||
|
# In addition, I recommend the
|
||||||
|
# [Solarized theme](https://github.com/altercation/solarized/) and, if you're
|
||||||
|
# using it on Mac OS X, [iTerm 2](https://iterm2.com/) over Terminal.app -
|
||||||
|
# it has significantly better color fidelity.
|
||||||
|
#
|
||||||
|
# If using with "light" variant of the Solarized color schema, set
|
||||||
|
# SOLARIZED_THEME variable to "light". If you don't specify, we'll assume
|
||||||
|
# you're using the "dark" variant.
|
||||||
|
#
|
||||||
|
# # Goals
|
||||||
|
#
|
||||||
|
# The aim of this theme is to only show you *relevant* information. Like most
|
||||||
|
# prompts, it will only show git information when in a git working directory.
|
||||||
|
# However, it goes a step further: everything from the current user and
|
||||||
|
# hostname to whether the last call exited with an error to whether background
|
||||||
|
# jobs are running in this shell will all be displayed automatically when
|
||||||
|
# appropriate.
|
||||||
|
|
||||||
|
### Segment drawing
|
||||||
|
# A few utility functions to make it easy and re-usable to draw segmented prompts
|
||||||
|
|
||||||
|
CURRENT_BG='NONE'
|
||||||
|
|
||||||
|
case ${SOLARIZED_THEME:-dark} in
|
||||||
|
light) CURRENT_FG='black';;
|
||||||
|
*) CURRENT_FG='white';;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Special Powerline characters
|
||||||
|
|
||||||
|
() {
|
||||||
|
local LC_ALL="" LC_CTYPE="en_US.UTF-8"
|
||||||
|
# NOTE: This segment separator character is correct. In 2012, Powerline changed
|
||||||
|
# the code points they use for their special characters. This is the new code point.
|
||||||
|
# If this is not working for you, you probably have an old version of the
|
||||||
|
# Powerline-patched fonts installed. Download and install the new version.
|
||||||
|
# Do not submit PRs to change this unless you have reviewed the Powerline code point
|
||||||
|
# history and have new information.
|
||||||
|
# This is defined using a Unicode escape sequence so it is unambiguously readable, regardless of
|
||||||
|
# what font the user is viewing this source code in. Do not replace the
|
||||||
|
# escape sequence with a single literal character.
|
||||||
|
# Do not change this! Do not make it '\u2b80'; that is the old, wrong code point.
|
||||||
|
SEGMENT_SEPARATOR=$'\ue0b0'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Begin a segment
|
||||||
|
# Takes two arguments, background and foreground. Both can be omitted,
|
||||||
|
# rendering default background/foreground.
|
||||||
|
prompt_segment() {
|
||||||
|
local bg fg
|
||||||
|
[[ -n $1 ]] && bg="%K{$1}" || bg="%k"
|
||||||
|
[[ -n $2 ]] && fg="%F{$2}" || fg="%f"
|
||||||
|
if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then
|
||||||
|
echo -n " %{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%} "
|
||||||
|
else
|
||||||
|
echo -n "%{$bg%}%{$fg%} "
|
||||||
|
fi
|
||||||
|
CURRENT_BG=$1
|
||||||
|
[[ -n $3 ]] && echo -n $3
|
||||||
|
}
|
||||||
|
|
||||||
|
# End the prompt, closing any open segments
|
||||||
|
prompt_end() {
|
||||||
|
if [[ -n $CURRENT_BG ]]; then
|
||||||
|
echo -n " %{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR"
|
||||||
|
else
|
||||||
|
echo -n "%{%k%}"
|
||||||
|
fi
|
||||||
|
echo -n "%{%f%}"
|
||||||
|
CURRENT_BG=''
|
||||||
|
}
|
||||||
|
|
||||||
|
### Prompt components
|
||||||
|
# Each component will draw itself, and hide itself if no information needs to be shown
|
||||||
|
|
||||||
|
# Context: user@hostname (who am I and where am I)
|
||||||
|
prompt_context() {
|
||||||
|
if [[ "$USERNAME" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
|
||||||
|
prompt_segment black default "%(!.%{%F{yellow}%}.)%n@%m"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git: branch/detached head, dirty status
|
||||||
|
prompt_git() {
|
||||||
|
(( $+commands[git] )) || return
|
||||||
|
if [[ "$(git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local PL_BRANCH_CHAR
|
||||||
|
() {
|
||||||
|
local LC_ALL="" LC_CTYPE="en_US.UTF-8"
|
||||||
|
PL_BRANCH_CHAR=$'\ue0a0' #
|
||||||
|
}
|
||||||
|
local ref dirty mode repo_path
|
||||||
|
|
||||||
|
if [[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]]; then
|
||||||
|
repo_path=$(git rev-parse --git-dir 2>/dev/null)
|
||||||
|
dirty=$(parse_git_dirty)
|
||||||
|
ref=$(git symbolic-ref HEAD 2> /dev/null) || ref="➦ $(git rev-parse --short HEAD 2> /dev/null)"
|
||||||
|
if [[ -n $dirty ]]; then
|
||||||
|
prompt_segment yellow black
|
||||||
|
else
|
||||||
|
prompt_segment green $CURRENT_FG
|
||||||
|
fi
|
||||||
|
|
||||||
|
local ahead behind
|
||||||
|
ahead=$(git log --oneline @{upstream}.. 2>/dev/null)
|
||||||
|
behind=$(git log --oneline ..@{upstream} 2>/dev/null)
|
||||||
|
if [[ -n "$ahead" ]] && [[ -n "$behind" ]]; then
|
||||||
|
PL_BRANCH_CHAR=$'\u21c5'
|
||||||
|
elif [[ -n "$ahead" ]]; then
|
||||||
|
PL_BRANCH_CHAR=$'\u21b1'
|
||||||
|
elif [[ -n "$behind" ]]; then
|
||||||
|
PL_BRANCH_CHAR=$'\u21b0'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -e "${repo_path}/BISECT_LOG" ]]; then
|
||||||
|
mode=" <B>"
|
||||||
|
elif [[ -e "${repo_path}/MERGE_HEAD" ]]; then
|
||||||
|
mode=" >M<"
|
||||||
|
elif [[ -e "${repo_path}/rebase" || -e "${repo_path}/rebase-apply" || -e "${repo_path}/rebase-merge" || -e "${repo_path}/../.dotest" ]]; then
|
||||||
|
mode=" >R>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
setopt promptsubst
|
||||||
|
autoload -Uz vcs_info
|
||||||
|
|
||||||
|
zstyle ':vcs_info:*' enable git
|
||||||
|
zstyle ':vcs_info:*' get-revision true
|
||||||
|
zstyle ':vcs_info:*' check-for-changes true
|
||||||
|
zstyle ':vcs_info:*' stagedstr '✚'
|
||||||
|
zstyle ':vcs_info:*' unstagedstr '±'
|
||||||
|
zstyle ':vcs_info:*' formats ' %u%c'
|
||||||
|
zstyle ':vcs_info:*' actionformats ' %u%c'
|
||||||
|
vcs_info
|
||||||
|
echo -n "${${ref:gs/%/%%}/refs\/heads\//$PL_BRANCH_CHAR }${vcs_info_msg_0_%% }${mode}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_bzr() {
|
||||||
|
(( $+commands[bzr] )) || return
|
||||||
|
|
||||||
|
# Test if bzr repository in directory hierarchy
|
||||||
|
local dir="$PWD"
|
||||||
|
while [[ ! -d "$dir/.bzr" ]]; do
|
||||||
|
[[ "$dir" = "/" ]] && return
|
||||||
|
dir="${dir:h}"
|
||||||
|
done
|
||||||
|
|
||||||
|
local bzr_status status_mod status_all revision
|
||||||
|
if bzr_status=$(bzr status 2>&1); then
|
||||||
|
status_mod=$(echo -n "$bzr_status" | head -n1 | grep "modified" | wc -m)
|
||||||
|
status_all=$(echo -n "$bzr_status" | head -n1 | wc -m)
|
||||||
|
revision=${$(bzr log -r-1 --log-format line | cut -d: -f1):gs/%/%%}
|
||||||
|
if [[ $status_mod -gt 0 ]] ; then
|
||||||
|
prompt_segment yellow black "bzr@$revision ✚"
|
||||||
|
else
|
||||||
|
if [[ $status_all -gt 0 ]] ; then
|
||||||
|
prompt_segment yellow black "bzr@$revision"
|
||||||
|
else
|
||||||
|
prompt_segment green black "bzr@$revision"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_hg() {
|
||||||
|
(( $+commands[hg] )) || return
|
||||||
|
local rev st branch
|
||||||
|
if $(hg id >/dev/null 2>&1); then
|
||||||
|
if $(hg prompt >/dev/null 2>&1); then
|
||||||
|
if [[ $(hg prompt "{status|unknown}") = "?" ]]; then
|
||||||
|
# if files are not added
|
||||||
|
prompt_segment red white
|
||||||
|
st='±'
|
||||||
|
elif [[ -n $(hg prompt "{status|modified}") ]]; then
|
||||||
|
# if any modification
|
||||||
|
prompt_segment yellow black
|
||||||
|
st='±'
|
||||||
|
else
|
||||||
|
# if working copy is clean
|
||||||
|
prompt_segment green $CURRENT_FG
|
||||||
|
fi
|
||||||
|
echo -n ${$(hg prompt "☿ {rev}@{branch}"):gs/%/%%} $st
|
||||||
|
else
|
||||||
|
st=""
|
||||||
|
rev=$(hg id -n 2>/dev/null | sed 's/[^-0-9]//g')
|
||||||
|
branch=$(hg id -b 2>/dev/null)
|
||||||
|
if `hg st | grep -q "^\?"`; then
|
||||||
|
prompt_segment red black
|
||||||
|
st='±'
|
||||||
|
elif `hg st | grep -q "^[MA]"`; then
|
||||||
|
prompt_segment yellow black
|
||||||
|
st='±'
|
||||||
|
else
|
||||||
|
prompt_segment green $CURRENT_FG
|
||||||
|
fi
|
||||||
|
echo -n "☿ ${rev:gs/%/%%}@${branch:gs/%/%%}" $st
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Dir: current working directory
|
||||||
|
prompt_dir() {
|
||||||
|
prompt_segment blue $CURRENT_FG '%~'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Virtualenv: current working virtualenv
|
||||||
|
prompt_virtualenv() {
|
||||||
|
if [[ -n "$VIRTUAL_ENV" && -n "$VIRTUAL_ENV_DISABLE_PROMPT" ]]; then
|
||||||
|
prompt_segment blue black "(${VIRTUAL_ENV:t:gs/%/%%})"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Status:
|
||||||
|
# - was there an error
|
||||||
|
# - am I root
|
||||||
|
# - are there background jobs?
|
||||||
|
prompt_status() {
|
||||||
|
local -a symbols
|
||||||
|
|
||||||
|
[[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘"
|
||||||
|
[[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡"
|
||||||
|
[[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙"
|
||||||
|
|
||||||
|
[[ -n "$symbols" ]] && prompt_segment black default "$symbols"
|
||||||
|
}
|
||||||
|
|
||||||
|
#AWS Profile:
|
||||||
|
# - display current AWS_PROFILE name
|
||||||
|
# - displays yellow on red if profile name contains 'production' or
|
||||||
|
# ends in '-prod'
|
||||||
|
# - displays black on green otherwise
|
||||||
|
prompt_aws() {
|
||||||
|
[[ -z "$AWS_PROFILE" || "$SHOW_AWS_PROMPT" = false ]] && return
|
||||||
|
case "$AWS_PROFILE" in
|
||||||
|
*-prod|*production*) prompt_segment red yellow "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
|
||||||
|
*) prompt_segment green black "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
## Main prompt
|
||||||
|
build_prompt() {
|
||||||
|
RETVAL=$?
|
||||||
|
prompt_status
|
||||||
|
prompt_virtualenv
|
||||||
|
prompt_aws
|
||||||
|
prompt_context
|
||||||
|
prompt_dir
|
||||||
|
prompt_git
|
||||||
|
prompt_bzr
|
||||||
|
prompt_hg
|
||||||
|
prompt_end
|
||||||
|
}
|
||||||
|
|
||||||
|
PROMPT='%{%f%b%k%}$(build_prompt) '
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
# Managed by Ansible. This file may be overwritten when playbooks are run!
|
||||||
|
|
||||||
|
# If you come from bash you might have to change your $PATH.
|
||||||
|
# export PATH=$HOME/bin:/usr/local/bin:$PATH
|
||||||
|
|
||||||
|
# Path to your oh-my-zsh installation.
|
||||||
|
export ZSH=/{{ omz_user_home_dir }}/{{ omz_user.name }}/{{ omz_install_directory }}
|
||||||
|
|
||||||
|
# Set name of the theme to load. Optionally, if you set this to "random"
|
||||||
|
# it'll load a random theme each time that oh-my-zsh is loaded.
|
||||||
|
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
|
||||||
|
ZSH_THEME="{{ omz_zsh_theme }}"
|
||||||
|
|
||||||
|
# Uncomment the following line to use case-sensitive completion.
|
||||||
|
CASE_SENSITIVE="{{ omz_case_sensitive }}"
|
||||||
|
|
||||||
|
# Uncomment the following line to use hyphen-insensitive completion. Case
|
||||||
|
# sensitive completion must be off. _ and - will be interchangeable.
|
||||||
|
HYPHEN_INSENSITIVE="{{ omz_hyphen_insensitive }}"
|
||||||
|
|
||||||
|
# Uncomment the following line to disable bi-weekly auto-update checks.
|
||||||
|
DISABLE_AUTO_UPDATE="{{ omz_disable_auto_update }}"
|
||||||
|
|
||||||
|
# Uncomment the following line to change how often to auto-update (in days).
|
||||||
|
export UPDATE_ZSH_DAYS={{ omz_update_zsh_days }}
|
||||||
|
|
||||||
|
# Uncomment the following line to disable colors in ls.
|
||||||
|
DISABLE_LS_COLORS="{{ omz_disable_ls_colors }}"
|
||||||
|
|
||||||
|
# Uncomment the following line to disable auto-setting terminal title.
|
||||||
|
DISABLE_AUTO_TITLE="{{ omz_disable_auto_title }}"
|
||||||
|
|
||||||
|
# Uncomment the following line to enable command auto-correction.
|
||||||
|
ENABLE_CORRECTION="{{ omz_enable_correction }}"
|
||||||
|
|
||||||
|
# Uncomment the following line to display red dots whilst waiting for completion.
|
||||||
|
COMPLETION_WAITING_DOTS="{{ omz_completion_waiting_dots }}"
|
||||||
|
|
||||||
|
# Uncomment the following line if you want to disable marking untracked files
|
||||||
|
# under VCS as dirty. This makes repository status check for large repositories
|
||||||
|
# much, much faster.
|
||||||
|
DISABLE_UNTRACKED_FILES_DIRTY="{{ omz_disable_untracked_files_dirty }}"
|
||||||
|
|
||||||
|
# Uncomment the following line if you want to change the command execution time
|
||||||
|
# stamp shown in the history command output.
|
||||||
|
# The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
|
||||||
|
HIST_STAMPS="{{ omz_hist_stamps }}"
|
||||||
|
|
||||||
|
# Would you like to use another custom folder than $ZSH/custom?
|
||||||
|
ZSH_CUSTOM={{ omz_zsh_custom }}
|
||||||
|
|
||||||
|
# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
|
||||||
|
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
|
||||||
|
# Example format: plugins=(rails git textmate ruby lighthouse)
|
||||||
|
# Add wisely, as too many plugins slow down shell startup.
|
||||||
|
plugins=({{ omz_plugins | join(" ") }})
|
||||||
|
|
||||||
|
source $ZSH/oh-my-zsh.sh
|
||||||
|
|
||||||
|
# User configuration
|
||||||
|
|
||||||
|
# export MANPATH="/usr/local/man:$MANPATH"
|
||||||
|
|
||||||
|
# You may need to manually set your language environment
|
||||||
|
# export LANG=en_US.UTF-8
|
||||||
|
|
||||||
|
# Preferred editor for local and remote sessions
|
||||||
|
# if [[ -n $SSH_CONNECTION ]]; then
|
||||||
|
# export EDITOR='vim'
|
||||||
|
# else
|
||||||
|
# export EDITOR='mvim'
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# Compilation flags
|
||||||
|
# export ARCHFLAGS="-arch x86_64"
|
||||||
|
|
||||||
|
# ssh
|
||||||
|
# export SSH_KEY_PATH="~/.ssh/dsa_id"
|
||||||
|
|
||||||
|
# Set personal aliases, overriding those provided by oh-my-zsh libs,
|
||||||
|
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
|
||||||
|
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
|
||||||
|
# For a full list of active aliases, run `alias`.
|
||||||
|
#
|
||||||
|
# Example aliases
|
||||||
|
# alias zshconfig="mate ~/.zshrc"
|
||||||
|
# alias ohmyzsh="mate ~/.oh-my-zsh"
|
||||||
|
|
||||||
|
{{ omz_user.settings }}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: ansible.utils
|
||||||
|
- name: community.general
|
||||||
|
- name: ansible.posix
|
||||||
|
- name: kubernetes.core
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
os: "linux"
|
||||||
|
arch: "amd64"
|
||||||
|
|
||||||
|
talos_version: v1.7.5
|
||||||
|
talosctl_version: v1.7.5
|
||||||
|
control_plane_ip: 192.168.50.195
|
||||||
|
|
||||||
|
control_plane_2: 192.168.50.196
|
||||||
|
control_plane_3: 192.168.50.197
|
||||||
|
|
||||||
|
worker_1: 192.168.50.198
|
||||||
|
worker_2: 192.168.50.199
|
||||||
|
|
||||||
|
config_directory: "/home/{{ ansible_user }}/.talos"
|
||||||
|
config_file: "/home/{{ ansible_user }}/.talos/talosconfig"
|
||||||
|
|
||||||
|
kube_vip_version: "v0.8.0"
|
||||||
|
vip_interface: null
|
||||||
|
vip: 192.168.50.220
|
||||||
|
|
||||||
|
metallb_version: v0.13.12
|
||||||
|
lb_range: 192.168.50.240-192.168.50.250
|
||||||
|
lb_pool_name: first-pool
|
||||||
|
|
||||||
|
ansible_user: ubuntu
|
||||||
|
ansible_become: true
|
||||||
|
ansible_become_method: sudo
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Make sure Ansible host has access to these devices
|
||||||
|
# Good idea to snapshot all machines and deploy uing cloud-template
|
||||||
|
[ansible]
|
||||||
|
127.0.0.1 ansible_connection=local
|
||||||
|
|
||||||
|
[servers]
|
||||||
|
server1 ansible_host=192.168.50.195
|
||||||
|
server2 ansible_host=192.168.50.196
|
||||||
|
server3 ansible_host=192.168.50.197
|
||||||
|
|
||||||
|
[agents]
|
||||||
|
agent1 ansible_host=192.168.50.198
|
||||||
|
agent2 ansible_host=192.168.50.199
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
# Generate Machine Configurations. This is using the qemu agent as per: https://www.talos.dev/v1.7/talos-guides/install/virtualized-platforms/proxmox/
|
||||||
|
- name: Apply config to first worker
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: talosctl apply-config --insecure --nodes {{ worker_1 }} --file {{ config_directory }}/worker.yaml
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Apply config to second worker
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: talosctl apply-config --insecure --nodes {{ worker_2 }} --file {{ config_directory }}/worker.yaml
|
||||||
|
changed_when: true
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
# Generate Machine Configurations. This is using the qemu agent as per: https://www.talos.dev/v1.7/talos-guides/install/virtualized-platforms/proxmox/
|
||||||
|
- name: Apply config to first node
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: talosctl apply-config --insecure --nodes {{ control_plane_ip }} --file {{ config_directory }}/controlplane.yaml
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Apply config to second node
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: talosctl apply-config --insecure --nodes {{ control_plane_2 }} --file {{ config_directory }}/controlplane.yaml
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Apply config to first node
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: talosctl apply-config --insecure --nodes {{ control_plane_3 }} --file {{ config_directory }}/controlplane.yaml
|
||||||
|
changed_when: true
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: Check that the config file doesn't already exist
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ config_file }}"
|
||||||
|
register: stat_result
|
||||||
|
|
||||||
|
# Generate Machine Configurations. This is using the qemu agent as per: https://www.talos.dev/v1.7/talos-guides/install/virtualized-platforms/proxmox/
|
||||||
|
- name: Generate config for cluster
|
||||||
|
when: "not stat_result.stat.exists"
|
||||||
|
ansible.builtin.command: talosctl gen config talos-proxmox-cluster https://{{ control_plane_ip }}:6443 --output-dir {{ config_directory }} --install-image factory.talos.dev/installer/770f94a47e708326b61f3e641bb733dc879c544dee1972e74763798fe93a1f6d:{{ talos_version }}
|
||||||
|
changed_when: true
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
# Update TalosCTL
|
||||||
|
- name: Update TalosCTL configs
|
||||||
|
ansible.builtin.command: talosctl config endpoint {{ control_plane_ip }} --talosconfig {{ config_file }}
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Update TalosCTL configs
|
||||||
|
ansible.builtin.command: talosctl config node {{ control_plane_ip }} --talosconfig {{ config_file }}
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
#################################
|
||||||
|
# WAIT FOR REBOOT & BOOTSTRAP #
|
||||||
|
#################################
|
||||||
|
- name: Keep trying to bootstrap
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "talosctl bootstrap --talosconfig {{ config_file }}"
|
||||||
|
register: bootstrap_result
|
||||||
|
retries: 10
|
||||||
|
delay: 30
|
||||||
|
until: bootstrap_result.rc == 0
|
||||||
|
changed_when: bootstrap_result.rc == 0
|
||||||
|
|
||||||
|
# Grab Kubeconfig
|
||||||
|
- name: Get Kubeconfig
|
||||||
|
ansible.builtin.command: talosctl kubeconfig . --talosconfig {{ config_file }}
|
||||||
|
changed_when: true
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
# Ansible Playbook to install Talos
|
||||||
|
- name: Download talosctl for Linux (amd64)
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://github.com/siderolabs/talos/releases/download/{{ talosctl_version }}/talosctl-linux-amd64
|
||||||
|
dest: /usr/local/bin/talosctl
|
||||||
|
mode: '0755' # Make the binary executable
|
||||||
|
register: download_result # Register the result for debugging or verification
|
||||||
|
|
||||||
|
- name: Display download result
|
||||||
|
ansible.builtin.debug:
|
||||||
|
var: download_result # Display the result of the download task
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# Hello, thanks for using my playbook, hopefully you can help to improve it.
|
||||||
|
|
||||||
|
# Install TalosCTL on Ansible node
|
||||||
|
- name: Install TalosCTL
|
||||||
|
hosts: ansible
|
||||||
|
gather_facts: true # enables us to gather lots of useful variables: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- install-talosctl
|
||||||
|
|
||||||
|
# Configure Cluster Configuration
|
||||||
|
- name: Configure Cluster
|
||||||
|
hosts: ansible
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- configure-cluster
|
||||||
|
|
||||||
|
# Apply Cluster Configuration
|
||||||
|
- name: Configure Cluster
|
||||||
|
hosts: ansible
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- apply-config
|
||||||
|
|
||||||
|
# Configure TalosCTL
|
||||||
|
- name: Configure TalosCTL
|
||||||
|
hosts: ansible
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- configure-talosctl
|
||||||
|
|
||||||
|
# Add Workers
|
||||||
|
- name: Add Workers
|
||||||
|
hosts: ansible
|
||||||
|
gather_facts: true
|
||||||
|
roles:
|
||||||
|
- add-workers
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Add to Hosts File (change ansible_user if required)
|
||||||
|
```
|
||||||
|
[all:vars]
|
||||||
|
ansible_user='user'
|
||||||
|
ansible_become=yes
|
||||||
|
ansible_become_method=sudo
|
||||||
|
|
||||||
|
ansible-playbook site.yaml -i inventory/hosts.ini --key-file ~/.ssh/id_rsa -K
|
||||||
|
```
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
gather_facts: yes
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Perform a distro upgrade
|
||||||
|
ansible.builtin.apt:
|
||||||
|
upgrade: dist
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Check if a reboot is required
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /var/run/reboot-required
|
||||||
|
get_checksum: no
|
||||||
|
register: reboot_required_file
|
||||||
|
|
||||||
|
- name: Reboot the server (if necessary)
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
when: reboot_required_file.stat.exists == true
|
||||||
|
|
||||||
|
- name: Remove dependencies that are no longer needed
|
||||||
|
ansible.builtin.apt:
|
||||||
|
autoremove: yes
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
- name: Update APT package list and upgrade packages
|
||||||
|
# hosts: "dc00,dc01,dc02,dc03,dc04,dc05,dc09"
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
become_method: su
|
||||||
|
|
||||||
|
vars:
|
||||||
|
ansible_user: user
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Update APT package list
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
upgrade: dist
|
||||||
|
|
||||||
|
- name: Check if a reboot is required.
|
||||||
|
stat:
|
||||||
|
path: /var/run/reboot-required
|
||||||
|
register: reboot_required_file
|
||||||
|
|
||||||
|
- name: Reboot the server (if required).
|
||||||
|
debug:
|
||||||
|
msg: "Ansible Version: {{ reboot_required_file.stdout }}"
|
||||||
|
when: reboot_required_file.stat.exists == true
|
||||||
|
|
||||||
|
- name: Remove dependencies that are no longer required.
|
||||||
|
apt:
|
||||||
|
autoremove: yes
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Update apt repo and cache on all Debian/Ubuntu boxes
|
||||||
|
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
|
||||||
|
|
||||||
|
- name: Upgrade all packages on servers
|
||||||
|
apt: upgrade=dist force_apt_get=yes
|
||||||
|
|
||||||
|
- name: Check if a reboot is needed on all servers
|
||||||
|
register: reboot_required_file
|
||||||
|
stat: path=/var/run/reboot-required get_checksum=false
|
||||||
|
|
||||||
|
- name: Reboot the box if kernel updated
|
||||||
|
reboot:
|
||||||
|
msg: "Reboot initiated by Ansible for kernel updates"
|
||||||
|
connect_timeout: 5
|
||||||
|
reboot_timeout: 300
|
||||||
|
pre_reboot_delay: 0
|
||||||
|
post_reboot_delay: 30
|
||||||
|
test_command: uptime
|
||||||
|
when: reboot_required_file.stat.exists
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
x86_64:
|
||||||
|
hosts:
|
||||||
|
dc00:
|
||||||
|
ansible_host: 192.168.50.210
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: su
|
||||||
|
dc09:
|
||||||
|
ansible_host: 192.168.50.209
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: su
|
||||||
|
arm64:
|
||||||
|
hosts:
|
||||||
|
dc01:
|
||||||
|
ansible_host: 192.168.50.201
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
dc02:
|
||||||
|
ansible_host: 192.168.50.202
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
dc03:
|
||||||
|
ansible_host: 192.168.50.203
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
dc04:
|
||||||
|
ansible_host: 192.168.50.204
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
dc05:
|
||||||
|
ansible_host: 192.168.50.205
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
node07:
|
||||||
|
ansible_host: 192.168.50.207
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
node08:
|
||||||
|
ansible_host: 192.168.50.208
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
|
||||||
|
prod:
|
||||||
|
children:
|
||||||
|
x86_64:
|
||||||
|
arm64:
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
backend:
|
||||||
|
hosts:
|
||||||
|
nfs:
|
||||||
|
ansible_host: 192.168.50.225
|
||||||
|
ansible_user: root
|
||||||
|
ansible_become_method: su
|
||||||
|
swarm:
|
||||||
|
ansible_host: 192.168.50.220
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
firewall:
|
||||||
|
ansible_host: 192.168.50.170
|
||||||
|
ansible_user: root
|
||||||
|
ansible_become_method: su
|
||||||
|
|
||||||
|
dev:
|
||||||
|
hosts:
|
||||||
|
dev301:
|
||||||
|
ansible_host: 192.168.50.71
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
dev302:
|
||||||
|
ansible_host: 192.168.1.10
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
dev303:
|
||||||
|
ansible_host: 192.168.50.30
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become_method: sudo
|
||||||
|
|
||||||
|
virtual:
|
||||||
|
children:
|
||||||
|
backend:
|
||||||
|
dev:
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Ansible
|
||||||
|
|
||||||
|
## Update all packages
|
||||||
|
```bash
|
||||||
|
ansible-playbook -i inventory playbooks/update/update-noreboot.yml -l '!node08' -K
|
||||||
|
ansible-playbook -i inventory playbooks/update/update-noreboot.yml -l 'prod' -K
|
||||||
|
```
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: ansible.utils
|
||||||
|
- name: community.general
|
||||||
|
- name: ansible.posix
|
||||||
|
- name: kubernetes.core
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
tls-san:
|
||||||
|
- 192.168.50.190
|
||||||
|
- 192.168.50.209
|
||||||
|
-
|
||||||
|
-
|
||||||
|
write-kubeconfig-mode: 0644
|
||||||
|
disable:
|
||||||
|
- rke2-ingress-nginx
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
os: "linux"
|
||||||
|
# arch: "amd64"
|
||||||
|
# Set your timezone
|
||||||
|
system_timezone: "Asia/Singapore"
|
||||||
|
|
||||||
|
kube_vip_version: "v0.8.1"
|
||||||
|
vip_interface: null
|
||||||
|
vip: 192.168.50.210
|
||||||
|
|
||||||
|
metallb_version: v0.14.5
|
||||||
|
lb_range: 192.168.50.190-192.168.50.199
|
||||||
|
lb_pool_name: first-pool
|
||||||
|
|
||||||
|
rke2_version: "v1.28.11+rke2r1"
|
||||||
|
rke2_install_dir: "/usr/local/bin"
|
||||||
|
rke2_binary_url: "https://github.com/rancher/rke2/releases/download/{{ rke2_version }}"
|
||||||
|
|
||||||
|
ansible_user: user
|
||||||
|
ansible_become: true
|
||||||
|
ansible_become_method: sudo
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Make sure Ansible host has access to these devices
|
||||||
|
# Good idea to snapshot all machines and deploy uing cloud-init
|
||||||
|
|
||||||
|
[servers]
|
||||||
|
server1 ansible_host=192.168.50.132
|
||||||
|
|
||||||
|
[agents]
|
||||||
|
agent1 ansible_host=192.168.50.131
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: kube-vip-ds
|
||||||
|
app.kubernetes.io/version: v0.8.1
|
||||||
|
name: kube-vip-ds
|
||||||
|
namespace: kube-system
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: kube-vip-ds
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: kube-vip-ds
|
||||||
|
app.kubernetes.io/version: v0.8.1
|
||||||
|
spec:
|
||||||
|
affinity:
|
||||||
|
nodeAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
nodeSelectorTerms:
|
||||||
|
- matchExpressions:
|
||||||
|
- key: node-role.kubernetes.io/master
|
||||||
|
operator: Exists
|
||||||
|
- matchExpressions:
|
||||||
|
- key: node-role.kubernetes.io/control-plane
|
||||||
|
operator: Exists
|
||||||
|
containers:
|
||||||
|
- args:
|
||||||
|
- manager
|
||||||
|
env:
|
||||||
|
- name: vip_arp
|
||||||
|
value: "true"
|
||||||
|
- name: port
|
||||||
|
value: "6443"
|
||||||
|
- name: vip_interface
|
||||||
|
value: null
|
||||||
|
- name: vip_cidr
|
||||||
|
value: "32"
|
||||||
|
- name: cp_enable
|
||||||
|
value: "true"
|
||||||
|
- name: cp_namespace
|
||||||
|
value: kube-system
|
||||||
|
- name: vip_ddns
|
||||||
|
value: "false"
|
||||||
|
- name: svc_enable
|
||||||
|
value: "false"
|
||||||
|
- name: svc_leasename
|
||||||
|
value: plndr-svcs-lock
|
||||||
|
- name: vip_leaderelection
|
||||||
|
value: "true"
|
||||||
|
- name: vip_leasename
|
||||||
|
value: plndr-cp-lock
|
||||||
|
- name: vip_leaseduration
|
||||||
|
value: "5"
|
||||||
|
- name: vip_renewdeadline
|
||||||
|
value: "3"
|
||||||
|
- name: vip_retryperiod
|
||||||
|
value: "1"
|
||||||
|
- name: address
|
||||||
|
value: "192.168.50.210"
|
||||||
|
- name: prometheus_server
|
||||||
|
value: :2112
|
||||||
|
image: ghcr.io/kube-vip/kube-vip:v0.8.1
|
||||||
|
imagePullPolicy: Always
|
||||||
|
name: kube-vip
|
||||||
|
resources: {}
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- NET_RAW
|
||||||
|
hostNetwork: true
|
||||||
|
serviceAccountName: kube-vip
|
||||||
|
tolerations:
|
||||||
|
- effect: NoSchedule
|
||||||
|
operator: Exists
|
||||||
|
- effect: NoExecute
|
||||||
|
operator: Exists
|
||||||
|
updateStrategy: {}
|
||||||
|
status:
|
||||||
|
currentNumberScheduled: 0
|
||||||
|
desiredNumberScheduled: 0
|
||||||
|
numberMisscheduled: 0
|
||||||
|
numberReady: 0
|
||||||
|
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo -e " \033[33;2m __ _ _ ___ \033[0m"
|
||||||
|
echo -e " \033[33;2m \ \(_)_ __ ___( )__ / _ \__ _ _ __ __ _ __ _ ___ \033[0m"
|
||||||
|
echo -e " \033[33;2m \ \ | '_ \` _ \/ __| / /_\/ _\` | '__/ _\` |/ _\` |/ _ \ \033[0m"
|
||||||
|
echo -e " \033[33;2m /\_/ / | | | | | \__ \ / /_\\ (_| | | | (_| | (_| | __/ \033[0m"
|
||||||
|
echo -e " \033[33;2m \___/|_|_| |_| |_|___/ \____/\__,_|_| \__,_|\__, |\___| \033[0m"
|
||||||
|
echo -e " \033[33;2m |___/ \033[0m"
|
||||||
|
echo -e " \033[35;2m __ _ \033[0m"
|
||||||
|
echo -e " \033[35;2m / / ___ _ __ __ _| |__ ___ _ __ _ __ \033[0m"
|
||||||
|
echo -e " \033[35;2m / / / _ \| '_ \ / _\` | '_ \ / _ \| '__| '_ \ \033[0m"
|
||||||
|
echo -e " \033[35;2m / /__| (_) | | | | (_| | | | | (_) | | | | | | \033[0m"
|
||||||
|
echo -e " \033[35;2m \____/\___/|_| |_|\__, |_| |_|\___/|_| |_| |_| \033[0m"
|
||||||
|
echo -e " \033[35;2m |___/ \033[0m"
|
||||||
|
echo -e " \033[36;2m \033[0m"
|
||||||
|
echo -e " \033[32;2m https://youtube.com/@jims-garage \033[0m"
|
||||||
|
echo -e " \033[32;2m \033[0m"
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# YOU SHOULD ONLY NEED TO EDIT THIS SECTION #
|
||||||
|
#############################################
|
||||||
|
|
||||||
|
# THIS SCRIPT IS FOR RKE2, NOT K3S!
|
||||||
|
# THIS SCRIPT IS FOR RKE2, NOT K3S!
|
||||||
|
# THIS SCRIPT IS FOR RKE2, NOT K3S!
|
||||||
|
|
||||||
|
# Set the IP addresses of master1
|
||||||
|
master1=192.168.50.209
|
||||||
|
|
||||||
|
# Set the IP addresses of your Longhorn nodes
|
||||||
|
longhorn1=192.168.50.205
|
||||||
|
|
||||||
|
# User of remote machines
|
||||||
|
user=furyhawk
|
||||||
|
|
||||||
|
# Interface used on remotes
|
||||||
|
interface=eth0
|
||||||
|
|
||||||
|
# Set the virtual IP address (VIP)
|
||||||
|
vip=192.168.50.210
|
||||||
|
|
||||||
|
# Array of longhorn nodes
|
||||||
|
storage=($longhorn1)
|
||||||
|
|
||||||
|
#ssh certificate name variable
|
||||||
|
certName=id_rsa
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# DO NOT EDIT BELOW #
|
||||||
|
#############################################
|
||||||
|
# For testing purposes - in case time is wrong due to VM snapshots
|
||||||
|
sudo timedatectl set-ntp off
|
||||||
|
sudo timedatectl set-ntp on
|
||||||
|
|
||||||
|
# add ssh keys for all nodes
|
||||||
|
for node in "${storage[@]}"; do
|
||||||
|
ssh-copy-id $user@$node
|
||||||
|
done
|
||||||
|
|
||||||
|
# add open-iscsi - needed for Debian and non-cloud Ubuntu
|
||||||
|
if ! command -v sudo service open-iscsi status &> /dev/null
|
||||||
|
then
|
||||||
|
echo -e " \033[31;5mOpen-ISCSI not found, installing\033[0m"
|
||||||
|
sudo apt install open-iscsi
|
||||||
|
else
|
||||||
|
echo -e " \033[32;5mOpen-ISCSI already installed\033[0m"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 1: Add new longhorn nodes to cluster (note: label added)
|
||||||
|
# Set token variable needed for RKE2 (not required for K3S)
|
||||||
|
token=`cat token`
|
||||||
|
for newnode in "${storage[@]}"; do
|
||||||
|
ssh -tt $user@$newnode -i ~/.ssh/$certName sudo su <<EOF
|
||||||
|
mkdir -p /etc/rancher/rke2
|
||||||
|
touch /etc/rancher/rke2/config.yaml
|
||||||
|
echo "token: $token" >> /etc/rancher/rke2/config.yaml
|
||||||
|
echo "server: https://$vip:9345" >> /etc/rancher/rke2/config.yaml
|
||||||
|
echo "node-label:" >> /etc/rancher/rke2/config.yaml
|
||||||
|
echo " - longhorn=true" >> /etc/rancher/rke2/config.yaml
|
||||||
|
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sh -
|
||||||
|
systemctl enable rke2-agent.service
|
||||||
|
systemctl start rke2-agent.service
|
||||||
|
exit
|
||||||
|
EOF
|
||||||
|
echo -e " \033[32;5mLonghorn node joined successfully!\033[0m"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Step 2: Install Longhorn (using modified Official to pin to Longhorn Nodes)
|
||||||
|
# kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.2/deploy/longhorn.yaml
|
||||||
|
kubectl apply -f https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/Longhorn/longhorn.yaml
|
||||||
|
kubectl get pods \
|
||||||
|
--namespace longhorn-system \
|
||||||
|
--watch
|
||||||
|
|
||||||
|
# Step 3: Print out confirmation
|
||||||
|
|
||||||
|
kubectl get nodes
|
||||||
|
kubectl get svc -n longhorn-system
|
||||||
|
|
||||||
|
echo -e " \033[32;5mHappy Kubing! Access Longhorn through Rancher UI\033[0m"
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: kube-vip
|
||||||
|
namespace: kube-system
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
rbac.authorization.kubernetes.io/autoupdate: "true"
|
||||||
|
name: system:kube-vip-role
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["services/status"]
|
||||||
|
verbs: ["update"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["services", "endpoints"]
|
||||||
|
verbs: ["list","get","watch", "update"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["nodes"]
|
||||||
|
verbs: ["list","get","watch", "update", "patch"]
|
||||||
|
- apiGroups: ["coordination.k8s.io"]
|
||||||
|
resources: ["leases"]
|
||||||
|
verbs: ["list", "get", "watch", "update", "create"]
|
||||||
|
- apiGroups: ["discovery.k8s.io"]
|
||||||
|
resources: ["endpointslices"]
|
||||||
|
verbs: ["list","get","watch", "update"]
|
||||||
|
---
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: system:kube-vip-binding
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: system:kube-vip-role
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: kube-vip
|
||||||
|
namespace: kube-system
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
# RKE2 playbook
|
||||||
|
|
||||||
|
/etc/hosts
|
||||||
|
```
|
||||||
|
127.0.0.1 localhost
|
||||||
|
127.0.1.1 c1.local c1
|
||||||
|
|
||||||
|
# The following lines are desirable for IPv6 capable hosts
|
||||||
|
::1 localhost ip6-localhost ip6-loopback
|
||||||
|
ff02::1 ip6-allnodes
|
||||||
|
ff02::2 ip6-allrouters
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export LC_ALL=en_US.UTF-8
|
||||||
|
ansible-playbook site.yaml -i inventory/hosts.ini --key-file ~/.ssh/id_rsa -K
|
||||||
|
k get pods --all-namespaces
|
||||||
|
kubectl create namespace cattle-system
|
||||||
|
# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.1/cert-manager.crds.yaml
|
||||||
|
# install helm
|
||||||
|
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
|
||||||
|
sudo apt-get install apt-transport-https --yes
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install helm
|
||||||
|
|
||||||
|
helm repo add jetstack https://charts.jetstack.io --force-update
|
||||||
|
helm repo update
|
||||||
|
helm install \
|
||||||
|
cert-manager jetstack/cert-manager \
|
||||||
|
--namespace cert-manager \
|
||||||
|
--create-namespace \
|
||||||
|
--version v1.15.2 \
|
||||||
|
--set crds.enabled=true
|
||||||
|
```
|
||||||
|
NAME: cert-manager
|
||||||
|
LAST DEPLOYED: Sat Aug 3 21:38:31 2024
|
||||||
|
NAMESPACE: cert-manager
|
||||||
|
STATUS: deployed
|
||||||
|
REVISION: 1
|
||||||
|
TEST SUITE: None
|
||||||
|
NOTES:
|
||||||
|
cert-manager v1.15.2 has been deployed successfully!
|
||||||
|
|
||||||
|
In order to begin issuing certificates, you will need to set up a ClusterIssuer
|
||||||
|
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
|
||||||
|
|
||||||
|
More information on the different types of issuers and how to configure them
|
||||||
|
can be found in our documentation:
|
||||||
|
|
||||||
|
https://cert-manager.io/docs/configuration/
|
||||||
|
|
||||||
|
For information on how to configure cert-manager to automatically provision
|
||||||
|
Certificates for Ingress resources, take a look at the `ingress-shim`
|
||||||
|
documentation:
|
||||||
|
|
||||||
|
https://cert-manager.io/docs/usage/ingress/
|
||||||
|
|
||||||
|
|
||||||
|
https://www.suse.com/suse-rancher/support-matrix/all-supported-versions/rancher-v2-8-5/
|
||||||
|
```bash
|
||||||
|
kubectl get pods --namespace cert-manager
|
||||||
|
kubectl create namespace cattle-system
|
||||||
|
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
|
||||||
|
helm install rancher rancher-latest/rancher \
|
||||||
|
--namespace cattle-system \
|
||||||
|
--set hostname=rancher.local \
|
||||||
|
--set bootstrapPassword=admin
|
||||||
|
```
|
||||||
|
If you provided your own bootstrap password during installation, browse to https://rancher.local to get started.
|
||||||
|
|
||||||
|
If this is the first time you installed Rancher, get started by running this command and clicking the URL it generates:
|
||||||
|
|
||||||
|
```
|
||||||
|
echo https://rancher.local/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}')
|
||||||
|
```
|
||||||
|
https://node03/dashboard/?setup=admin
|
||||||
|
|
||||||
|
To get just the bootstrap password on its own, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}{{ "\n" }}'
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo service open-iscsi status
|
||||||
|
sudo apt install open-iscsi
|
||||||
|
kubectl -n cattle-system get deploy rancher
|
||||||
|
|
||||||
|
kubectl -n cattle-system rollout status deploy/rancher
|
||||||
|
kubectl -n cattle-system get deploy rancher
|
||||||
|
kubectl get svc -n cattle-system
|
||||||
|
kubectl expose deployment rancher --name=rancher-lb --port=443 --type=LoadBalancer -n cattle-system
|
||||||
|
kubectl get svc -n cattle-system
|
||||||
|
# kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.2/deploy/longhorn.yaml
|
||||||
|
# k delete -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.2/deploy/longhorn.yaml
|
||||||
|
helm repo add longhorn https://charts.longhorn.io
|
||||||
|
helm repo update
|
||||||
|
k apply -f longhorn.yaml
|
||||||
|
helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace --version 1.6.2
|
||||||
|
kubectl get pods \
|
||||||
|
--namespace longhorn-system \
|
||||||
|
--watch
|
||||||
|
kubectl -n longhorn-system get pod
|
||||||
|
kubectl get svc
|
||||||
|
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.1/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
|
||||||
|
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.1/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml
|
||||||
|
helm repo add traefik https://traefik.github.io/charts
|
||||||
|
helm install traefik traefik/traefik --create-namespace -n 'traefik' -f traefik.yaml
|
||||||
|
helm list -n traefik
|
||||||
|
kubectl -n traefik port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name -A) 9000:9000 --address 0.0.0.0
|
||||||
|
# Update repository
|
||||||
|
helm repo update
|
||||||
|
# See current Chart & Traefik version
|
||||||
|
helm search repo traefik/traefik
|
||||||
|
# Update CRDs (Traefik Proxy v3 CRDs)
|
||||||
|
kubectl apply --server-side --force-conflicts -k https://github.com/traefik/traefik-helm-chart/traefik/crds/
|
||||||
|
# Upgrade Traefik
|
||||||
|
helm upgrade traefik traefik/traefik
|
||||||
|
```
|
||||||
Executable
+260
@@ -0,0 +1,260 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo -e " \033[33;5m __ _ _ ___ \033[0m"
|
||||||
|
echo -e " \033[33;5m \ \(_)_ __ ___( )__ / _ \__ _ _ __ __ _ __ _ ___ \033[0m"
|
||||||
|
echo -e " \033[33;5m \ \ | '_ \` _ \/ __| / /_\/ _\` | '__/ _\` |/ _\` |/ _ \ \033[0m"
|
||||||
|
echo -e " \033[33;5m /\_/ / | | | | | \__ \ / /_\\ (_| | | | (_| | (_| | __/ \033[0m"
|
||||||
|
echo -e " \033[33;5m \___/|_|_| |_| |_|___/ \____/\__,_|_| \__,_|\__, |\___| \033[0m"
|
||||||
|
echo -e " \033[33;5m |___/ \033[0m"
|
||||||
|
|
||||||
|
echo -e " \033[36;5m ___ _ _____ ___ \033[0m"
|
||||||
|
echo -e " \033[36;5m | _ \ |/ / __|_ ) \033[0m"
|
||||||
|
echo -e " \033[36;5m | / ' <| _| / / \033[0m"
|
||||||
|
echo -e " \033[36;5m |_|_\_|\_\___/___| \033[0m"
|
||||||
|
echo -e " \033[36;5m \033[0m"
|
||||||
|
echo -e " \033[32;5m https://youtube.com/@jims-garage \033[0m"
|
||||||
|
echo -e " \033[32;5m \033[0m"
|
||||||
|
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# YOU SHOULD ONLY NEED TO EDIT THIS SECTION #
|
||||||
|
#############################################
|
||||||
|
|
||||||
|
# Version of Kube-VIP to deploy
|
||||||
|
KVVERSION="v0.6.3"
|
||||||
|
|
||||||
|
# Set the IP addresses of the admin, masters, and workers nodes
|
||||||
|
admin=192.168.50.143
|
||||||
|
master1=192.168.50.132
|
||||||
|
worker1=192.168.50.131
|
||||||
|
|
||||||
|
# User of remote machines
|
||||||
|
user=furyhawk
|
||||||
|
|
||||||
|
# Interface used on remotes
|
||||||
|
interface=eth0
|
||||||
|
|
||||||
|
# Set the virtual IP address (VIP)
|
||||||
|
vip=192.168.50.190
|
||||||
|
|
||||||
|
# Array of all master nodes
|
||||||
|
allmasters=($master1)
|
||||||
|
|
||||||
|
# Array of master nodes
|
||||||
|
masters=($master2 $master3)
|
||||||
|
|
||||||
|
# Array of worker nodes
|
||||||
|
workers=($worker1)
|
||||||
|
|
||||||
|
# Array of all
|
||||||
|
all=($master1 $worker1)
|
||||||
|
|
||||||
|
# Array of all minus master1
|
||||||
|
allnomaster1=($master2 $master3 $worker1)
|
||||||
|
|
||||||
|
#Loadbalancer IP range
|
||||||
|
lbrange=192.168.3.191-192.168.3.199
|
||||||
|
|
||||||
|
#ssh certificate name variable
|
||||||
|
certName=id_rsa
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# DO NOT EDIT BELOW #
|
||||||
|
#############################################
|
||||||
|
# For testing purposes - in case time is wrong due to VM snapshots
|
||||||
|
sudo timedatectl set-ntp off
|
||||||
|
sudo timedatectl set-ntp on
|
||||||
|
|
||||||
|
# Move SSH certs to ~/.ssh and change permissions
|
||||||
|
cp /home/$user/{$certName,$certName.pub} /home/$user/.ssh
|
||||||
|
chmod 600 /home/$user/.ssh/$certName
|
||||||
|
chmod 644 /home/$user/.ssh/$certName.pub
|
||||||
|
|
||||||
|
# Install Kubectl if not already present
|
||||||
|
if ! command -v kubectl version &> /dev/null
|
||||||
|
then
|
||||||
|
echo -e " \033[31;5mKubectl not found, installing\033[0m"
|
||||||
|
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||||
|
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||||||
|
else
|
||||||
|
echo -e " \033[32;5mKubectl already installed\033[0m"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create SSH Config file to ignore checking (don't use in production!)
|
||||||
|
sed -i '1s/^/StrictHostKeyChecking no\n/' ~/.ssh/config
|
||||||
|
|
||||||
|
#add ssh keys for all nodes
|
||||||
|
for node in "${all[@]}"; do
|
||||||
|
ssh-copy-id $user@$node
|
||||||
|
done
|
||||||
|
|
||||||
|
# Step 1: Create Kube VIP
|
||||||
|
# create RKE2's self-installing manifest dir
|
||||||
|
sudo mkdir -p /var/lib/rancher/rke2/server/manifests
|
||||||
|
# Install the kube-vip deployment into rke2's self-installing manifest folder
|
||||||
|
curl -sO https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/kube-vip
|
||||||
|
cat kube-vip | sed 's/$interface/'$interface'/g; s/$vip/'$vip'/g' > $HOME/kube-vip.yaml
|
||||||
|
sudo mv kube-vip.yaml /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||||
|
|
||||||
|
# Find/Replace all k3s entries to represent rke2
|
||||||
|
sudo sed -i 's/k3s/rke2/g' /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||||
|
# copy kube-vip.yaml to home directory
|
||||||
|
sudo cp /var/lib/rancher/rke2/server/manifests/kube-vip.yaml ~/kube-vip.yaml
|
||||||
|
# change owner
|
||||||
|
sudo chown $user:$user kube-vip.yaml
|
||||||
|
# make kube folder to run kubectl later
|
||||||
|
mkdir ~/.kube
|
||||||
|
|
||||||
|
# create the rke2 config file
|
||||||
|
sudo mkdir -p /etc/rancher/rke2
|
||||||
|
touch config.yaml
|
||||||
|
echo "tls-san:" >> config.yaml
|
||||||
|
echo " - $vip" >> config.yaml
|
||||||
|
echo " - $master1" >> config.yaml
|
||||||
|
echo "write-kubeconfig-mode: 0644" >> config.yaml
|
||||||
|
echo "disable:" >> config.yaml
|
||||||
|
echo " - rke2-ingress-nginx" >> config.yaml
|
||||||
|
# copy config.yaml to rancher directory
|
||||||
|
sudo cp ~/config.yaml /etc/rancher/rke2/config.yaml
|
||||||
|
|
||||||
|
# update path with rke2-binaries
|
||||||
|
echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> ~/.bashrc ; echo 'export PATH=${PATH}:/var/lib/rancher/rke2/bin' >> ~/.bashrc ; echo 'alias k=kubectl' >> ~/.bashrc ; source ~/.bashrc ;
|
||||||
|
|
||||||
|
# Step 2: Copy kube-vip.yaml and certs to all masters
|
||||||
|
for newnode in "${allmasters[@]}"; do
|
||||||
|
scp -i ~/.ssh/$certName $HOME/kube-vip.yaml $user@$newnode:~/kube-vip.yaml
|
||||||
|
scp -i ~/.ssh/$certName $HOME/config.yaml $user@$newnode:~/config.yaml
|
||||||
|
scp -i ~/.ssh/$certName ~/.ssh/{$certName,$certName.pub} $user@$newnode:~/.ssh
|
||||||
|
echo -e " \033[32;5mCopied successfully!\033[0m"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Step 3: Connect to Master1 and move kube-vip.yaml and config.yaml. Then install RKE2, copy token back to admin machine. We then use the token to bootstrap additional masternodes
|
||||||
|
ssh -tt $user@$master1 -i ~/.ssh/$certName sudo su <<EOF
|
||||||
|
mkdir -p /var/lib/rancher/rke2/server/manifests
|
||||||
|
mv kube-vip.yaml /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||||
|
mkdir -p /etc/rancher/rke2
|
||||||
|
mv config.yaml /etc/rancher/rke2/config.yaml
|
||||||
|
echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> ~/.bashrc ; echo 'export PATH=${PATH}:/var/lib/rancher/rke2/bin' >> ~/.bashrc ; echo 'alias k=kubectl' >> ~/.bashrc ; source ~/.bashrc ;
|
||||||
|
curl -sfL https://get.rke2.io | sh -
|
||||||
|
systemctl enable rke2-server.service
|
||||||
|
systemctl start rke2-server.service
|
||||||
|
echo "StrictHostKeyChecking no" > ~/.ssh/config
|
||||||
|
ssh-copy-id -i /home/$user/.ssh/$certName $user@$admin
|
||||||
|
scp -i /home/$user/.ssh/$certName /var/lib/rancher/rke2/server/token $user@$admin:~/token
|
||||||
|
scp -i /home/$user/.ssh/$certName /etc/rancher/rke2/rke2.yaml $user@$admin:~/.kube/rke2.yaml
|
||||||
|
exit
|
||||||
|
EOF
|
||||||
|
echo -e " \033[32;5mMaster1 Completed\033[0m"
|
||||||
|
|
||||||
|
# Step 4: Set variable to the token we just extracted, set kube config location
|
||||||
|
token=`cat token`
|
||||||
|
sudo cat ~/.kube/rke2.yaml | sed 's/127.0.0.1/'$master1'/g' > $HOME/.kube/config
|
||||||
|
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||||
|
export KUBECONFIG=${HOME}/.kube/config
|
||||||
|
sudo cp ~/.kube/config /etc/rancher/rke2/rke2.yaml
|
||||||
|
kubectl get nodes
|
||||||
|
|
||||||
|
# Step 5: Install kube-vip as network LoadBalancer - Install the kube-vip Cloud Provider
|
||||||
|
kubectl apply -f https://kube-vip.io/manifests/rbac.yaml
|
||||||
|
kubectl apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
|
||||||
|
|
||||||
|
# Step 6: Add other Masternodes, note we import the token we extracted from step 3
|
||||||
|
# for newnode in "${masters[@]}"; do
|
||||||
|
# ssh -tt $user@$newnode -i ~/.ssh/$certName sudo su <<EOF
|
||||||
|
# mkdir -p /etc/rancher/rke2
|
||||||
|
# touch /etc/rancher/rke2/config.yaml
|
||||||
|
# echo "token: $token" >> /etc/rancher/rke2/config.yaml
|
||||||
|
# echo "server: https://$master1:9345" >> /etc/rancher/rke2/config.yaml
|
||||||
|
# echo "tls-san:" >> /etc/rancher/rke2/config.yaml
|
||||||
|
# echo " - $vip" >> /etc/rancher/rke2/config.yaml
|
||||||
|
# echo " - $master1" >> /etc/rancher/rke2/config.yaml
|
||||||
|
# echo " - $master2" >> /etc/rancher/rke2/config.yaml
|
||||||
|
# echo " - $master3" >> /etc/rancher/rke2/config.yaml
|
||||||
|
# curl -sfL https://get.rke2.io | sh -
|
||||||
|
# systemctl enable rke2-server.service
|
||||||
|
# systemctl start rke2-server.service
|
||||||
|
# exit
|
||||||
|
# EOF
|
||||||
|
# echo -e " \033[32;5mMaster node joined successfully!\033[0m"
|
||||||
|
# done
|
||||||
|
|
||||||
|
kubectl get nodes
|
||||||
|
|
||||||
|
# Step 7: Add Workers
|
||||||
|
for newnode in "${workers[@]}"; do
|
||||||
|
ssh -tt $user@$newnode -i ~/.ssh/$certName sudo su <<EOF
|
||||||
|
mkdir -p /etc/rancher/rke2
|
||||||
|
touch /etc/rancher/rke2/config.yaml
|
||||||
|
echo "token: $token" >> /etc/rancher/rke2/config.yaml
|
||||||
|
echo "server: https://$vip:9345" >> /etc/rancher/rke2/config.yaml
|
||||||
|
echo "node-label:" >> /etc/rancher/rke2/config.yaml
|
||||||
|
echo " - worker=true" >> /etc/rancher/rke2/config.yaml
|
||||||
|
echo " - longhorn=true" >> /etc/rancher/rke2/config.yaml
|
||||||
|
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sh -
|
||||||
|
systemctl enable rke2-agent.service
|
||||||
|
systemctl start rke2-agent.service
|
||||||
|
exit
|
||||||
|
EOF
|
||||||
|
echo -e " \033[32;5mWorker node joined successfully!\033[0m"
|
||||||
|
done
|
||||||
|
|
||||||
|
kubectl get nodes
|
||||||
|
|
||||||
|
# Step 8: Install Metallb
|
||||||
|
echo -e " \033[32;5mDeploying Metallb\033[0m"
|
||||||
|
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
|
||||||
|
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml
|
||||||
|
# Download ipAddressPool and configure using lbrange above
|
||||||
|
curl -sO https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/ipAddressPool
|
||||||
|
cat ipAddressPool | sed 's/$lbrange/'$lbrange'/g' > $HOME/ipAddressPool.yaml
|
||||||
|
|
||||||
|
# Step 9: Deploy IP Pools and l2Advertisement
|
||||||
|
echo -e " \033[32;5mAdding IP Pools, waiting for Metallb to be available first. This can take a long time as we're likely being rate limited for container pulls...\033[0m"
|
||||||
|
kubectl wait --namespace metallb-system \
|
||||||
|
--for=condition=ready pod \
|
||||||
|
--selector=component=controller \
|
||||||
|
--timeout=1800s
|
||||||
|
kubectl apply -f ipAddressPool.yaml
|
||||||
|
kubectl apply -f https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/l2Advertisement.yaml
|
||||||
|
|
||||||
|
# Step 10: Install Rancher (Optional - Delete if not required)
|
||||||
|
#Install Helm
|
||||||
|
echo -e " \033[32;5mInstalling Helm\033[0m"
|
||||||
|
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||||
|
chmod 700 get_helm.sh
|
||||||
|
./get_helm.sh
|
||||||
|
|
||||||
|
# Add Rancher Helm Repo & create namespace
|
||||||
|
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
|
||||||
|
kubectl create namespace cattle-system
|
||||||
|
|
||||||
|
# Install Cert-Manager
|
||||||
|
echo -e " \033[32;5mDeploying Cert-Manager\033[0m"
|
||||||
|
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.crds.yaml
|
||||||
|
helm repo add jetstack https://charts.jetstack.io
|
||||||
|
helm repo update
|
||||||
|
helm install cert-manager jetstack/cert-manager \
|
||||||
|
--namespace cert-manager \
|
||||||
|
--create-namespace \
|
||||||
|
--version v1.13.2
|
||||||
|
kubectl get pods --namespace cert-manager
|
||||||
|
|
||||||
|
# Install Rancher
|
||||||
|
echo -e " \033[32;5mDeploying Rancher\033[0m"
|
||||||
|
helm install rancher rancher-latest/rancher \
|
||||||
|
--namespace cattle-system \
|
||||||
|
--set hostname=rancher.my.org \
|
||||||
|
--set bootstrapPassword=admin
|
||||||
|
kubectl -n cattle-system rollout status deploy/rancher
|
||||||
|
kubectl -n cattle-system get deploy rancher
|
||||||
|
|
||||||
|
# Add Rancher LoadBalancer
|
||||||
|
kubectl get svc -n cattle-system
|
||||||
|
kubectl expose deployment rancher --name=rancher-lb --port=443 --type=LoadBalancer -n cattle-system
|
||||||
|
while [[ $(kubectl get svc -n cattle-system 'jsonpath={..status.conditions[?(@.type=="Pending")].status}') = "True" ]]; do
|
||||||
|
sleep 5
|
||||||
|
echo -e " \033[32;5mWaiting for LoadBalancer to come online\033[0m"
|
||||||
|
done
|
||||||
|
kubectl get svc -n cattle-system
|
||||||
|
|
||||||
|
echo -e " \033[32;5mAccess Rancher from the IP above - Password is admin!\033[0m"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copy agent config to all agents - we need to change agent2 & 3 later with the token
|
||||||
|
- name: Deploy RKE2 Agent Configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-agent-config.j2
|
||||||
|
dest: /etc/rancher/rke2/config.yaml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['agents']
|
||||||
|
|
||||||
|
# Check agents have restarted to pick up config
|
||||||
|
- name: Ensure RKE2 agents are enabled and running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: rke2-agent
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
write-kubeconfig-mode: "0644"
|
||||||
|
token: {{ hostvars['server1']['token'] }}
|
||||||
|
server: https://{{ hostvars['server1']['ansible_host'] }}:9345
|
||||||
|
node-label:
|
||||||
|
- "agent=true"
|
||||||
|
- "longhorn=true"
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# Copy server config with token to all servers except server 1 (this has token)
|
||||||
|
- name: Deploy RKE2 server Configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-server-config.j2
|
||||||
|
dest: /etc/rancher/rke2/config.yaml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname != groups['servers'][0]
|
||||||
|
|
||||||
|
# Keep checking the cluster API until it's functioning (deployed)
|
||||||
|
- name: Wait for cluster API to be ready (can take 5-10 mins depending on internet/hardware)
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "kubectl get nodes"
|
||||||
|
register: kubectl_output
|
||||||
|
until: "'connection refused' not in kubectl_output.stderr"
|
||||||
|
retries: 120
|
||||||
|
delay: 10
|
||||||
|
changed_when: true
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Use kubectl to deploy yaml. Perhaps this can be added to the manifest folder initially
|
||||||
|
- name: Apply kube vip configuration file
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml apply -f https://kube-vip.io/manifests/rbac.yaml
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Apply the kube-vip configration. Perhaps this can be added to the manifest folder initially
|
||||||
|
- name: Apply kube vip configuration file
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Check that additional servers are restarted
|
||||||
|
- name: Ensure additional RKE2 servers are enabled and running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: rke2-server
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
when: inventory_hostname != groups['servers'][0]
|
||||||
|
|
||||||
|
# enable additional servers
|
||||||
|
- name: Ensure RKE2 server is enabled and running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: rke2-server
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
when: inventory_hostname != groups['servers'][0]
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
write-kubeconfig-mode: "0644"
|
||||||
|
token: {{ hostvars['server1']['token'] }}
|
||||||
|
server: https://{{ hostvars['server1']['ansible_host'] }}:9345
|
||||||
|
tls-san:
|
||||||
|
- {{ vip }}
|
||||||
|
- {{ hostvars['server1']['ansible_host'] }}
|
||||||
|
node-label:
|
||||||
|
- server=true
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# Wait for Server 1 to be ready before continuing with metallb deployment
|
||||||
|
- name: Wait for k8s nodes with node label 'server=true' to be ready, otherwise we cannot start metallb deployment
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "kubectl wait --for=condition=Ready nodes --selector server=true --timeout=600s"
|
||||||
|
register: nodes_ready
|
||||||
|
retries: 120
|
||||||
|
delay: 10
|
||||||
|
changed_when: true
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Create namespace so that we can deploy metallb
|
||||||
|
- name: Apply metallb namespace
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Apply metallb manifest
|
||||||
|
- name: Apply metallb manifest
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/{{ metallb_version }}/config/manifests/metallb-native.yaml
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Wait for metallb deployment pods to be alive before deploying metallb manifests
|
||||||
|
- name: Wait for metallb pods to be ready, otherwise we cannot start metallb deployment
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "kubectl wait --namespace metallb-system --for=condition=ready pod --selector=component=controller --timeout=1800s"
|
||||||
|
changed_when: true
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Apply L2 Advertisement for metallb
|
||||||
|
- name: Apply metallb L2 Advertisement
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl apply -f https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/l2Advertisement.yaml
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Deploy metal IP Pool to Server 1
|
||||||
|
- name: Copy metallb IPPool to server 1
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/metallb-ippool.j2
|
||||||
|
dest: /home/{{ ansible_user }}/ippool.yaml
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: '0755'
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# don't think this will work as nodes are no execute, might need agents first
|
||||||
|
- name: Apply metallb ipppool
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: kubectl apply -f /home/{{ ansible_user }}/ippool.yaml
|
||||||
|
become_user: "{{ ansible_user }}"
|
||||||
|
changed_when: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: metallb.io/v1beta1
|
||||||
|
kind: IPAddressPool
|
||||||
|
metadata:
|
||||||
|
name: {{ lb_pool_name }}
|
||||||
|
namespace: metallb-system
|
||||||
|
spec:
|
||||||
|
addresses:
|
||||||
|
- {{ lb_range }}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Create directory to deploy kube-vip manifest
|
||||||
|
- name: Create directory for Kube VIP Manifest
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/var/lib/rancher/rke2/server/manifests"
|
||||||
|
state: directory
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['servers']
|
||||||
|
|
||||||
|
# Copy kube-vip to server 1 manifest folder for auto deployment at bootstrap
|
||||||
|
- name: Deploy Kube VIP Configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/kube-vip-config.j2
|
||||||
|
dest: /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: kube-vip-ds
|
||||||
|
app.kubernetes.io/version: {{ kube_vip_version }}
|
||||||
|
name: kube-vip-ds
|
||||||
|
namespace: kube-system
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: kube-vip-ds
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: kube-vip-ds
|
||||||
|
app.kubernetes.io/version: {{ kube_vip_version }}
|
||||||
|
spec:
|
||||||
|
affinity:
|
||||||
|
nodeAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
nodeSelectorTerms:
|
||||||
|
- matchExpressions:
|
||||||
|
- key: node-role.kubernetes.io/master
|
||||||
|
operator: Exists
|
||||||
|
- matchExpressions:
|
||||||
|
- key: node-role.kubernetes.io/control-plane
|
||||||
|
operator: Exists
|
||||||
|
containers:
|
||||||
|
- args:
|
||||||
|
- manager
|
||||||
|
env:
|
||||||
|
- name: vip_arp
|
||||||
|
value: "true"
|
||||||
|
- name: port
|
||||||
|
value: "6443"
|
||||||
|
- name: vip_interface
|
||||||
|
value: {{ vip_interface }}
|
||||||
|
- name: vip_cidr
|
||||||
|
value: "32"
|
||||||
|
- name: cp_enable
|
||||||
|
value: "true"
|
||||||
|
- name: cp_namespace
|
||||||
|
value: kube-system
|
||||||
|
- name: vip_ddns
|
||||||
|
value: "false"
|
||||||
|
- name: svc_enable
|
||||||
|
value: "false"
|
||||||
|
- name: svc_leasename
|
||||||
|
value: plndr-svcs-lock
|
||||||
|
- name: vip_leaderelection
|
||||||
|
value: "true"
|
||||||
|
- name: vip_leasename
|
||||||
|
value: plndr-cp-lock
|
||||||
|
- name: vip_leaseduration
|
||||||
|
value: "5"
|
||||||
|
- name: vip_renewdeadline
|
||||||
|
value: "3"
|
||||||
|
- name: vip_retryperiod
|
||||||
|
value: "1"
|
||||||
|
- name: address
|
||||||
|
value: {{ vip }}
|
||||||
|
- name: prometheus_server
|
||||||
|
value: :2112
|
||||||
|
image: ghcr.io/kube-vip/kube-vip:{{ kube_vip_version }}
|
||||||
|
imagePullPolicy: Always
|
||||||
|
name: kube-vip
|
||||||
|
resources: {}
|
||||||
|
securityContext:
|
||||||
|
capabilities:
|
||||||
|
add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- NET_RAW
|
||||||
|
hostNetwork: true
|
||||||
|
serviceAccountName: kube-vip
|
||||||
|
tolerations:
|
||||||
|
- effect: NoSchedule
|
||||||
|
operator: Exists
|
||||||
|
- effect: NoExecute
|
||||||
|
operator: Exists
|
||||||
|
updateStrategy: {}
|
||||||
|
status:
|
||||||
|
currentNumberScheduled: 0
|
||||||
|
desiredNumberScheduled: 0
|
||||||
|
numberMisscheduled: 0
|
||||||
|
numberReady: 0
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
- name: Enable IPv4 forwarding
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv4.ip_forward
|
||||||
|
value: "1"
|
||||||
|
state: present
|
||||||
|
reload: true
|
||||||
|
tags: sysctl
|
||||||
|
|
||||||
|
- name: Enable IPv6 forwarding
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv6.conf.all.forwarding
|
||||||
|
value: "1"
|
||||||
|
state: present
|
||||||
|
reload: true
|
||||||
|
tags: sysctl
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# Create a directory to download RKE2 binary to
|
||||||
|
- name: Create directory for RKE2 binary
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ rke2_install_dir }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
# Download the RKE2 binary
|
||||||
|
- name: Download RKE2 amd64 binary
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ rke2_binary_url }}/rke2.linux-amd64"
|
||||||
|
dest: "{{ rke2_install_dir }}/rke2"
|
||||||
|
mode: '0755'
|
||||||
|
when: ansible_facts.architecture == "x86_64"
|
||||||
|
|
||||||
|
- name: Download RKE2 arm64 binary
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ rke2_binary_url }}/rke2.linux-arm64"
|
||||||
|
dest: "{{ rke2_install_dir }}/rke2"
|
||||||
|
mode: '0755'
|
||||||
|
when:
|
||||||
|
- ( ansible_facts.architecture is search("arm") and
|
||||||
|
ansible_facts.userspace_bits == "64" ) or
|
||||||
|
ansible_facts.architecture is search("aarch64")
|
||||||
|
|
||||||
|
# Set permissions on the RKE2 binary
|
||||||
|
- name: Set executable permissions on the RKE2 binary
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ rke2_install_dir }}/rke2"
|
||||||
|
mode: '0755'
|
||||||
|
state: file
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
- name: Create directory for RKE2 config
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/etc/rancher/rke2"
|
||||||
|
state: directory
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Create directory for RKE2 token
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/var/lib/rancher/rke2/server"
|
||||||
|
state: directory
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
# Copy server config to server 1 for bootstrap - we need to change server2 & 3 later with the token
|
||||||
|
- name: Deploy RKE2 server Configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-server-config.j2
|
||||||
|
dest: /etc/rancher/rke2/config.yaml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['servers']
|
||||||
|
|
||||||
|
- name: Create systemd service file for RKE2 server
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-server.service.j2
|
||||||
|
dest: /etc/systemd/system/rke2-server.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['servers']
|
||||||
|
|
||||||
|
- name: Create systemd service file for RKE2 agent
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: templates/rke2-agent.service.j2
|
||||||
|
dest: /etc/systemd/system/rke2-agent.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
when: inventory_hostname in groups['agents']
|
||||||
|
|
||||||
|
# we enable the first server to generate tokens etc, copy this afterwards to other servers
|
||||||
|
- name: Ensure RKE2 server is enabled and running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: rke2-server
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
when: inventory_hostname in groups['servers'][0]
|
||||||
|
|
||||||
|
# wait for node token to be availale so that we can copy it, we need this to join other nodes
|
||||||
|
- name: Wait for node-token
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
path: /var/lib/rancher/rke2/server/node-token
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# wait for kubectl to be downloaded, part of the rke2 installation
|
||||||
|
- name: Wait for kubectl
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
path: /var/lib/rancher/rke2/bin/kubectl
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# copy kubectl to usr bin so that all users can run kubectl commands
|
||||||
|
- name: Copy kubectl to user bin
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /var/lib/rancher/rke2/bin/kubectl
|
||||||
|
dest: /usr/local/bin/kubectl
|
||||||
|
mode: '0755'
|
||||||
|
remote_src: true
|
||||||
|
become: true
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# wait for the kubectl copy to complete
|
||||||
|
- name: Wait for kubectl
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
path: /usr/local/bin/kubectl
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# modify token access
|
||||||
|
- name: Register node-token file access mode
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /var/lib/rancher/rke2/server
|
||||||
|
register: p
|
||||||
|
|
||||||
|
- name: Change file access for node-token
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /var/lib/rancher/rke2/server
|
||||||
|
mode: "g+rx,o+rx"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# Save token as variable
|
||||||
|
- name: Fetch the token from the first server node
|
||||||
|
ansible.builtin.slurp:
|
||||||
|
src: /var/lib/rancher/rke2/server/token
|
||||||
|
register: rke2_token
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
run_once: true
|
||||||
|
|
||||||
|
# convert token to fact
|
||||||
|
- name: Save Master node-token for later
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
token: "{{ rke2_token.content | b64decode | regex_replace('\n', '') }}"
|
||||||
|
|
||||||
|
# revert token file access
|
||||||
|
- name: Restore node-token file access
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /var/lib/rancher/rke2/server
|
||||||
|
mode: "{{ p.stat.mode }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# check .kube folder exists so that we can use kubectl (config resides here)
|
||||||
|
- name: Ensure .kube directory exists in user's home
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/home/{{ ansible_user }}/.kube"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
become: true
|
||||||
|
|
||||||
|
# copy kubectl config file to .kube folder
|
||||||
|
- name: Copy config file to user home directory
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /etc/rancher/rke2/rke2.yaml
|
||||||
|
dest: "/home/{{ ansible_user }}/.kube/config"
|
||||||
|
remote_src: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
mode: "u=rw,g=,o="
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
|
|
||||||
|
# change IP from local to server 1 IP
|
||||||
|
- name: Replace IP address with server1
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: /home/{{ ansible_user }}/.kube/config
|
||||||
|
regexp: '127.0.0.1'
|
||||||
|
replace: "{{ hostvars['server1']['ansible_host'] }}"
|
||||||
|
when: inventory_hostname == groups['servers'][0]
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# rke2-agent.service.j2
|
||||||
|
[Unit]
|
||||||
|
Description=RKE2 Agent
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/local/bin/rke2 agent
|
||||||
|
KillMode=process
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
write-kubeconfig-mode: "0644"
|
||||||
|
tls-san:
|
||||||
|
- {{ vip }}
|
||||||
|
- {{ hostvars['server1']['ansible_host'] }}
|
||||||
|
node-label:
|
||||||
|
- server=true
|
||||||
|
disable:
|
||||||
|
- rke2-ingress-nginx
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# rke2-server.service.j2
|
||||||
|
[Unit]
|
||||||
|
Description=RKE2 server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/local/bin/rke2 server
|
||||||
|
KillMode=process
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user