Compare commits
219 Commits
Author | SHA1 | Date | |
---|---|---|---|
2cf23e3104 | |||
200e0d54a2 | |||
fc28bfc336 | |||
733ac8ffa9 | |||
70450a4882 | |||
71349c9a17 | |||
4014a1cccb | |||
c55844b80e | |||
a4fa9aed75 | |||
659001c9d7 | |||
07647fb720 | |||
161bd55ab2 | |||
4b67c7d6a6 | |||
e26921e3e1 | |||
f80a5755c3 | |||
feeea7e512 | |||
09ea2ca688 | |||
b7a8d7a4d5 | |||
9405eb821b | |||
708677caf1 | |||
d5cdae1f16 | |||
b7a9217d77 | |||
82633c6f61 | |||
7afbdb3e1e | |||
c14d9c5c97 | |||
48035e3a7e | |||
a257e61f60 | |||
9948863d3a | |||
3a3addb91e | |||
72b8830f62 | |||
e6ba73349e | |||
55e581be3b | |||
9cd7d66332 | |||
6ea7abf443 | |||
3254080a1c | |||
4ffe138dfa | |||
86b81a855a | |||
bde261bd06 | |||
2b75552d1c | |||
951face343 | |||
07d45e6b62 | |||
9a72de54de | |||
4313c13656 | |||
c880b24a80 | |||
29827711f1 | |||
ab6d204641 | |||
426b8913c0 | |||
970ecbb008 | |||
eb951f1c2a | |||
3378c9f385 | |||
4c820b853b | |||
a505a4c71f | |||
8727f88e41 | |||
c2a8d543fb | |||
4ddbd2bd2d | |||
f9f5143c93 | |||
fccd99c96c | |||
dc7cf7ecd8 | |||
169eb34a59 | |||
4deeaba335 | |||
a59e27cb6b | |||
617af4beda | |||
b3ed25ee35 | |||
c7072b48dc | |||
02dc9fbd3e | |||
c98e1d1b5b | |||
e907d55621 | |||
cb318931aa | |||
709ae1d244 | |||
73ce6aef97 | |||
6682a843b4 | |||
dc33a1971d | |||
ed6f8df784 | |||
43216436ab | |||
cdc25523bf | |||
b77780ebf7 | |||
f27bea574e | |||
c38cf5dd5c | |||
2985b129fc | |||
107cb7f549 | |||
6c30b3f263 | |||
0104396c50 | |||
eecaec2919 | |||
4a03d13d08 | |||
fcb5e77338 | |||
ece174da7c | |||
a94b893e2c | |||
5e2cb4d244 | |||
dff58023d9 | |||
9a8f95e73d | |||
766d3696c9 | |||
b88229a662 | |||
c00cea7b17 | |||
0c4f57a093 | |||
3a6069916d | |||
e6eda9d811 | |||
e8f0fb82fe | |||
19856cf692 | |||
3450865d3f | |||
deb532ce27 | |||
1bb4f88af1 | |||
dcc04e54f3 | |||
4020a93d7e | |||
a676c106d3 | |||
acbf44a1b4 | |||
baed5f0b32 | |||
8afd74ce1f | |||
f6e4a231cb | |||
3a5f5692ca | |||
9b37699d0d | |||
cc382f2412 | |||
9a8bf0e38a | |||
97dfdcd8fe | |||
a9f52060c9 | |||
8cf5fefe84 | |||
f73b941d8a | |||
fb8631cdf6 | |||
7859aee735 | |||
83c3ce7f8f | |||
309aaee427 | |||
349c8901f8 | |||
df9aba6298 | |||
8f0bd36155 | |||
2ae3ea9ee3 | |||
99115ad04b | |||
7747ff2572 | |||
fff400513b | |||
eb4bd36f73 | |||
2d20f0c024 | |||
b0793df293 | |||
ab213a7db0 | |||
9fb1814784 | |||
1ca50f3eea | |||
82f68ca395 | |||
3a675393dc | |||
9c41769dab | |||
dba29db58d | |||
e175ccdde0 | |||
9e2104c7d3 | |||
1d9502e01d | |||
c710c93c02 | |||
13c793fd0d | |||
1555d78155 | |||
fd8260b930 | |||
6769bb32b1 | |||
677b7ecd89 | |||
659fa0eddc | |||
501deecdd0 | |||
7fec254f62 | |||
835811ec84 | |||
b7fe368469 | |||
8b3f3c04cc | |||
ecd649846a | |||
27c2d7e9e2 | |||
f366863a99 | |||
5bb54ef6a2 | |||
f7dade867a | |||
5cbcec8968 | |||
62f34c6085 | |||
d908e86590 | |||
f9ce176211 | |||
1dab5b5d9c | |||
739608454d | |||
260dad8f10 | |||
c950bfface | |||
75b07ad40c | |||
bd84353fc9 | |||
9ee2fbc51c | |||
fa92d9c0e9 | |||
4aacec4542 | |||
6278b12af6 | |||
64e4de371e | |||
ad4958249f | |||
29f01d3e5b | |||
3fd7d91452 | |||
4ba1df5237 | |||
145c80e9ab | |||
ab0e06eae6 | |||
786ce8ddd7 | |||
f06de0735f | |||
6ff845a199 | |||
fe9e11b501 | |||
3c2eb52828 | |||
2838a7c304 | |||
2788a02096 | |||
8a2e1189fb | |||
bdd1c7bcb5 | |||
d81978625c | |||
2c93c997cf | |||
10337f2fcb | |||
6c41191646 | |||
7730cfd619 | |||
1853085ffe | |||
9247137e60 | |||
e8f048c71d | |||
6cb027dfab | |||
edde594bbe | |||
0707c8ea6f | |||
c0c2cd6e03 | |||
36c6de9abd | |||
c5debf013c | |||
f9cc8ae10c | |||
94dd02121b | |||
c360501854 | |||
8523f525aa | |||
b9a34b83d4 | |||
2a24c2e359 | |||
8d6cfd6e53 | |||
1f36df666d | |||
64dbf2e429 | |||
6881398941 | |||
57638124c5 | |||
ee2193d4cf | |||
eb56130433 | |||
5fbbcedebc | |||
18f2abad2f | |||
391dd97f95 | |||
44243eada9 | |||
34d0451585 |
@ -24,7 +24,17 @@ skip_list:
|
||||
# (Disabled in June 2021)
|
||||
- 'role-name'
|
||||
|
||||
- 'experimental'
|
||||
# [var-naming] "defaults/main.yml" File defines variable 'apiVersion' that violates variable naming standards
|
||||
# In Kubespray we use variables that use camelCase to match their k8s counterparts
|
||||
# (Disabled in June 2021)
|
||||
- 'var-naming'
|
||||
- 'var-spacing'
|
||||
|
||||
# [fqcn-builtins]
|
||||
# Roles in kubespray don't need fully qualified collection names
|
||||
# (Disabled in Feb 2023)
|
||||
- 'fqcn-builtins'
|
||||
exclude_paths:
|
||||
# Generated files
|
||||
- tests/files/custom_cni/cilium.yaml
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -12,6 +12,7 @@ contrib/offline/offline-files.tar.gz
|
||||
*.bak
|
||||
*.tfstate
|
||||
*.tfstate.backup
|
||||
*.lock.hcl
|
||||
.terraform/
|
||||
contrib/terraform/aws/credentials.tfvars
|
||||
.terraform.lock.hcl
|
||||
@ -113,3 +114,7 @@ roles/**/molecule/**/__pycache__/
|
||||
# Temp location used by our scripts
|
||||
scripts/tmp/
|
||||
tmp.md
|
||||
|
||||
# Ansible collection files
|
||||
kubernetes_sigs-kubespray*tar.gz
|
||||
ansible_collections
|
||||
|
@ -9,12 +9,12 @@ stages:
|
||||
- deploy-special
|
||||
|
||||
variables:
|
||||
KUBESPRAY_VERSION: v2.20.0
|
||||
KUBESPRAY_VERSION: v2.21.0
|
||||
FAILFASTCI_NAMESPACE: 'kargo-ci'
|
||||
GITLAB_REPOSITORY: 'kargo-ci/kubernetes-sigs-kubespray'
|
||||
ANSIBLE_FORCE_COLOR: "true"
|
||||
MAGIC: "ci check this"
|
||||
TEST_ID: "$CI_PIPELINE_ID-$CI_BUILD_ID"
|
||||
TEST_ID: "$CI_PIPELINE_ID-$CI_JOB_ID"
|
||||
CI_TEST_VARS: "./tests/files/${CI_JOB_NAME}.yml"
|
||||
CI_TEST_REGISTRY_MIRROR: "./tests/common/_docker_hub_registry_mirror.yml"
|
||||
CI_TEST_SETTING: "./tests/common/_kubespray_test_settings.yml"
|
||||
@ -34,7 +34,7 @@ variables:
|
||||
ANSIBLE_LOG_LEVEL: "-vv"
|
||||
RECOVER_CONTROL_PLANE_TEST: "false"
|
||||
RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[2:],kube_control_plane[1:]"
|
||||
TERRAFORM_VERSION: 1.0.8
|
||||
TERRAFORM_VERSION: 1.3.7
|
||||
ANSIBLE_MAJOR_VERSION: "2.11"
|
||||
PIPELINE_IMAGE: "$CI_REGISTRY_IMAGE/pipeline:${CI_PIPELINE_ID}-${CI_COMMIT_SHORT_SHA}"
|
||||
|
||||
|
@ -1,16 +1,40 @@
|
||||
---
|
||||
pipeline image:
|
||||
.build:
|
||||
stage: build
|
||||
image: docker:20.10.22-cli
|
||||
image:
|
||||
name: moby/buildkit:rootless
|
||||
entrypoint: [""]
|
||||
variables:
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
services:
|
||||
- name: docker:20.10.22-dind
|
||||
# See https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27300 for why this is required
|
||||
command: ["--tls=false"]
|
||||
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
|
||||
before_script:
|
||||
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
|
||||
- mkdir ~/.docker
|
||||
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
|
||||
|
||||
pipeline image:
|
||||
extends: .build
|
||||
script:
|
||||
# DOCKER_HOST is overwritten if we set it as a GitLab variable
|
||||
- DOCKER_HOST=tcp://docker:2375; docker build --network host --file pipeline.Dockerfile --tag $PIPELINE_IMAGE .
|
||||
- docker push $PIPELINE_IMAGE
|
||||
- |
|
||||
buildctl-daemonless.sh build \
|
||||
--frontend=dockerfile.v0 \
|
||||
--local context=. \
|
||||
--local dockerfile=. \
|
||||
--opt filename=./pipeline.Dockerfile \
|
||||
--output type=image,name=$PIPELINE_IMAGE,push=true \
|
||||
--import-cache type=registry,ref=$CI_REGISTRY_IMAGE/pipeline:cache
|
||||
rules:
|
||||
- if: '$CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH'
|
||||
|
||||
pipeline image and build cache:
|
||||
extends: .build
|
||||
script:
|
||||
- |
|
||||
buildctl-daemonless.sh build \
|
||||
--frontend=dockerfile.v0 \
|
||||
--local context=. \
|
||||
--local dockerfile=. \
|
||||
--opt filename=./pipeline.Dockerfile \
|
||||
--output type=image,name=$PIPELINE_IMAGE,push=true \
|
||||
--import-cache type=registry,ref=$CI_REGISTRY_IMAGE/pipeline:cache \
|
||||
--export-cache type=registry,ref=$CI_REGISTRY_IMAGE/pipeline:cache,mode=max
|
||||
rules:
|
||||
- if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
|
||||
|
@ -14,7 +14,7 @@ vagrant-validate:
|
||||
stage: unit-tests
|
||||
tags: [light]
|
||||
variables:
|
||||
VAGRANT_VERSION: 2.2.19
|
||||
VAGRANT_VERSION: 2.3.4
|
||||
script:
|
||||
- ./tests/scripts/vagrant-validate.sh
|
||||
except: ['triggers', 'master']
|
||||
@ -39,11 +39,28 @@ syntax-check:
|
||||
ANSIBLE_VERBOSITY: "3"
|
||||
script:
|
||||
- ansible-playbook --syntax-check cluster.yml
|
||||
- ansible-playbook --syntax-check playbooks/cluster.yml
|
||||
- ansible-playbook --syntax-check upgrade-cluster.yml
|
||||
- ansible-playbook --syntax-check playbooks/upgrade_cluster.yml
|
||||
- ansible-playbook --syntax-check reset.yml
|
||||
- ansible-playbook --syntax-check playbooks/reset.yml
|
||||
- ansible-playbook --syntax-check extra_playbooks/upgrade-only-k8s.yml
|
||||
except: ['triggers', 'master']
|
||||
|
||||
collection-build-install-sanity-check:
|
||||
extends: .job
|
||||
stage: unit-tests
|
||||
tags: [light]
|
||||
variables:
|
||||
ANSIBLE_COLLECTIONS_PATH: "./ansible_collections"
|
||||
script:
|
||||
- ansible-galaxy collection build
|
||||
- ansible-galaxy collection install kubernetes_sigs-kubespray-$(grep "^version:" galaxy.yml | awk '{print $2}').tar.gz
|
||||
- ansible-galaxy collection list $(egrep -i '(name:\s+|namespace:\s+)' galaxy.yml | awk '{print $2}' | tr '\n' '.' | sed 's|\.$||g') | grep "^kubernetes_sigs.kubespray"
|
||||
- test -f ansible_collections/kubernetes_sigs/kubespray/playbooks/cluster.yml
|
||||
- test -f ansible_collections/kubernetes_sigs/kubespray/playbooks/reset.yml
|
||||
except: ['triggers', 'master']
|
||||
|
||||
tox-inventory-builder:
|
||||
stage: unit-tests
|
||||
tags: [light]
|
||||
@ -75,6 +92,13 @@ check-readme-versions:
|
||||
script:
|
||||
- tests/scripts/check_readme_versions.sh
|
||||
|
||||
check-galaxy-version:
|
||||
stage: unit-tests
|
||||
tags: [light]
|
||||
image: python:3
|
||||
script:
|
||||
- tests/scripts/check_galaxy_version.sh
|
||||
|
||||
check-typo:
|
||||
stage: unit-tests
|
||||
tags: [light]
|
||||
|
@ -91,16 +91,6 @@ packet_fedora35-crio:
|
||||
stage: deploy-part2
|
||||
when: manual
|
||||
|
||||
packet_ubuntu16-canal-ha:
|
||||
stage: deploy-part2
|
||||
extends: .packet_periodic
|
||||
when: on_success
|
||||
|
||||
packet_ubuntu16-canal-sep:
|
||||
stage: deploy-special
|
||||
extends: .packet_pr
|
||||
when: manual
|
||||
|
||||
packet_ubuntu16-flannel-ha:
|
||||
stage: deploy-part2
|
||||
extends: .packet_pr
|
||||
@ -178,11 +168,6 @@ packet_fedora36-docker-weave:
|
||||
extends: .packet_pr
|
||||
when: on_success
|
||||
|
||||
packet_opensuse-canal:
|
||||
stage: deploy-part2
|
||||
extends: .packet_periodic
|
||||
when: on_success
|
||||
|
||||
packet_opensuse-docker-cilium:
|
||||
stage: deploy-part2
|
||||
extends: .packet_pr
|
||||
@ -216,7 +201,7 @@ packet_almalinux8-calico-ha-ebpf:
|
||||
extends: .packet_pr
|
||||
when: manual
|
||||
|
||||
packet_debian9-macvlan:
|
||||
packet_debian10-macvlan:
|
||||
stage: deploy-part2
|
||||
extends: .packet_pr
|
||||
when: manual
|
||||
@ -231,11 +216,6 @@ packet_centos7-multus-calico:
|
||||
extends: .packet_pr
|
||||
when: manual
|
||||
|
||||
packet_centos7-canal-ha:
|
||||
stage: deploy-part2
|
||||
extends: .packet_pr
|
||||
when: manual
|
||||
|
||||
packet_fedora36-docker-calico:
|
||||
stage: deploy-part2
|
||||
extends: .packet_periodic
|
||||
@ -268,6 +248,16 @@ packet_fedora36-kube-ovn:
|
||||
extends: .packet_periodic
|
||||
when: on_success
|
||||
|
||||
packet_debian11-custom-cni:
|
||||
stage: deploy-part2
|
||||
extends: .packet_pr
|
||||
when: manual
|
||||
|
||||
packet_debian11-kubelet-csr-approver:
|
||||
stage: deploy-part2
|
||||
extends: .packet_pr
|
||||
when: manual
|
||||
|
||||
# ### PR JOBS PART3
|
||||
# Long jobs (45min+)
|
||||
|
||||
|
@ -60,11 +60,11 @@ tf-validate-openstack:
|
||||
PROVIDER: openstack
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
|
||||
tf-validate-metal:
|
||||
tf-validate-equinix:
|
||||
extends: .terraform_validate
|
||||
variables:
|
||||
TF_VERSION: $TERRAFORM_VERSION
|
||||
PROVIDER: metal
|
||||
PROVIDER: equinix
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
|
||||
tf-validate-aws:
|
||||
@ -80,6 +80,12 @@ tf-validate-exoscale:
|
||||
TF_VERSION: $TERRAFORM_VERSION
|
||||
PROVIDER: exoscale
|
||||
|
||||
tf-validate-hetzner:
|
||||
extends: .terraform_validate
|
||||
variables:
|
||||
TF_VERSION: $TERRAFORM_VERSION
|
||||
PROVIDER: hetzner
|
||||
|
||||
tf-validate-vsphere:
|
||||
extends: .terraform_validate
|
||||
variables:
|
||||
@ -104,7 +110,7 @@ tf-validate-upcloud:
|
||||
# TF_VAR_number_of_k8s_nodes: "1"
|
||||
# TF_VAR_plan_k8s_masters: t1.small.x86
|
||||
# TF_VAR_plan_k8s_nodes: t1.small.x86
|
||||
# TF_VAR_facility: ewr1
|
||||
# TF_VAR_metro: ny
|
||||
# TF_VAR_public_key_path: ""
|
||||
# TF_VAR_operating_system: ubuntu_16_04
|
||||
#
|
||||
@ -118,7 +124,7 @@ tf-validate-upcloud:
|
||||
# TF_VAR_number_of_k8s_nodes: "1"
|
||||
# TF_VAR_plan_k8s_masters: t1.small.x86
|
||||
# TF_VAR_plan_k8s_nodes: t1.small.x86
|
||||
# TF_VAR_facility: ams1
|
||||
# TF_VAR_metro: am
|
||||
# TF_VAR_public_key_path: ""
|
||||
# TF_VAR_operating_system: ubuntu_18_04
|
||||
|
||||
|
@ -45,6 +45,11 @@ vagrant_ubuntu20-flannel:
|
||||
when: on_success
|
||||
allow_failure: false
|
||||
|
||||
vagrant_ubuntu20-flannel-collection:
|
||||
stage: deploy-part2
|
||||
extends: .vagrant
|
||||
when: on_success
|
||||
|
||||
vagrant_ubuntu16-kube-router-sep:
|
||||
stage: deploy-part2
|
||||
extends: .vagrant
|
||||
|
@ -1,5 +1,20 @@
|
||||
---
|
||||
repos:
|
||||
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-case-conflict
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-xml
|
||||
- id: check-merge-conflict
|
||||
- id: detect-private-key
|
||||
- id: end-of-file-fixer
|
||||
- id: forbid-new-submodules
|
||||
- id: requirements-txt-fixer
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
rev: v1.27.1
|
||||
hooks:
|
||||
@ -13,6 +28,14 @@ repos:
|
||||
args: [ -r, "~MD013,~MD029" ]
|
||||
exclude: "^.git"
|
||||
|
||||
- repo: https://github.com/jumanjihouse/pre-commit-hooks
|
||||
rev: 3.0.0
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
args: [ --severity, "error" ]
|
||||
exclude: "^.git"
|
||||
files: "\\.sh$"
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: ansible-lint
|
||||
|
@ -3,6 +3,8 @@ extends: default
|
||||
|
||||
ignore: |
|
||||
.git/
|
||||
# Generated file
|
||||
tests/files/custom_cni/cilium.yaml
|
||||
|
||||
rules:
|
||||
braces:
|
||||
|
60
Dockerfile
60
Dockerfile
@ -1,36 +1,44 @@
|
||||
# Use imutable image tags rather than mutable tags (like ubuntu:20.04)
|
||||
FROM ubuntu:focal-20220531
|
||||
|
||||
ARG ARCH=amd64
|
||||
ARG TZ=Etc/UTC
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
RUN apt update -y \
|
||||
&& apt install -y \
|
||||
curl python3 python3-pip sshpass \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Use imutable image tags rather than mutable tags (like ubuntu:22.04)
|
||||
FROM ubuntu:jammy-20230308
|
||||
# Some tools like yamllint need this
|
||||
# Pip needs this as well at the moment to install ansible
|
||||
# (and potentially other packages)
|
||||
# See: https://github.com/pypa/pip/issues/10219
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
ENV LANG=C.UTF-8 \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
PYTHONDONTWRITEBYTECODE=1
|
||||
WORKDIR /kubespray
|
||||
COPY *yml /kubespray/
|
||||
COPY roles /kubespray/roles
|
||||
COPY inventory /kubespray/inventory
|
||||
COPY library /kubespray/library
|
||||
COPY extra_playbooks /kubespray/extra_playbooks
|
||||
COPY *.yml ./
|
||||
COPY *.cfg ./
|
||||
COPY roles ./roles
|
||||
COPY contrib ./contrib
|
||||
COPY inventory ./inventory
|
||||
COPY library ./library
|
||||
COPY extra_playbooks ./extra_playbooks
|
||||
COPY playbooks ./playbooks
|
||||
COPY plugins ./plugins
|
||||
|
||||
RUN python3 -m pip install --no-cache-dir \
|
||||
RUN apt update -q \
|
||||
&& apt install -yq --no-install-recommends \
|
||||
curl \
|
||||
python3 \
|
||||
python3-pip \
|
||||
sshpass \
|
||||
vim \
|
||||
rsync \
|
||||
openssh-client \
|
||||
&& pip install --no-compile --no-cache-dir \
|
||||
ansible==5.7.1 \
|
||||
ansible-core==2.12.5 \
|
||||
cryptography==3.4.8 \
|
||||
jinja2==2.11.3 \
|
||||
netaddr==0.7.19 \
|
||||
MarkupSafe==1.1.1 \
|
||||
jinja2==3.1.2 \
|
||||
netaddr==0.8.0 \
|
||||
jmespath==1.0.1 \
|
||||
MarkupSafe==2.1.2 \
|
||||
ruamel.yaml==0.17.21 \
|
||||
&& KUBE_VERSION=$(sed -n 's/^kube_version: //p' roles/kubespray-defaults/defaults/main.yaml) \
|
||||
&& curl -LO https://storage.googleapis.com/kubernetes-release/release/$KUBE_VERSION/bin/linux/$ARCH/kubectl \
|
||||
&& chmod a+x kubectl \
|
||||
&& mv kubectl /usr/local/bin/kubectl
|
||||
&& curl -L https://dl.k8s.io/release/$KUBE_VERSION/bin/linux/$(dpkg --print-architecture)/kubectl -o /usr/local/bin/kubectl \
|
||||
&& echo $(curl -L https://dl.k8s.io/release/$KUBE_VERSION/bin/linux/$(dpkg --print-architecture)/kubectl.sha256) /usr/local/bin/kubectl | sha256sum --check \
|
||||
&& chmod a+x /usr/local/bin/kubectl \
|
||||
&& rm -rf /var/lib/apt/lists/* /var/log/* \
|
||||
&& find /usr -type d -name '*__pycache__' -prune -exec rm -rf {} \;
|
||||
|
@ -10,6 +10,7 @@ aliases:
|
||||
- cristicalin
|
||||
- liupeng0518
|
||||
- yankay
|
||||
- mzaian
|
||||
kubespray-reviewers:
|
||||
- holmsten
|
||||
- bozzo
|
||||
@ -21,6 +22,7 @@ aliases:
|
||||
- yankay
|
||||
- cyclinder
|
||||
- mzaian
|
||||
- mrfreezeex
|
||||
kubespray-emeritus_approvers:
|
||||
- riverzhang
|
||||
- atoms
|
||||
|
59
README.md
59
README.md
@ -34,6 +34,13 @@ CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inv
|
||||
cat inventory/mycluster/group_vars/all/all.yml
|
||||
cat inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
|
||||
|
||||
# Clean up old Kubernete cluster with Ansible Playbook - run the playbook as root
|
||||
# The option `--become` is required, as for example cleaning up SSL keys in /etc/,
|
||||
# uninstalling old packages and interacting with various systemd daemons.
|
||||
# Without --become the playbook will fail to run!
|
||||
# And be mind it will remove the current kubernetes cluster (if it's running)!
|
||||
ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root reset.yml
|
||||
|
||||
# Deploy Kubespray with Ansible Playbook - run the playbook as root
|
||||
# The option `--become` is required, as for example writing SSL keys in /etc/,
|
||||
# installing packages and interacting with various systemd daemons.
|
||||
@ -45,7 +52,7 @@ Note: When Ansible is already installed via system packages on the control node,
|
||||
Python packages installed via `sudo pip install -r requirements.txt` will go to
|
||||
a different directory tree (e.g. `/usr/local/lib/python2.7/dist-packages` on
|
||||
Ubuntu) from Ansible's (e.g. `/usr/lib/python2.7/dist-packages/ansible` still on
|
||||
buntu). As a consequence, the `ansible-playbook` command will fail with:
|
||||
Ubuntu). As a consequence, the `ansible-playbook` command will fail with:
|
||||
|
||||
```raw
|
||||
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
|
||||
@ -68,15 +75,19 @@ You will then need to use [bind mounts](https://docs.docker.com/storage/bind-mou
|
||||
to access the inventory and SSH key in the container, like this:
|
||||
|
||||
```ShellSession
|
||||
git checkout v2.20.0
|
||||
docker pull quay.io/kubespray/kubespray:v2.20.0
|
||||
git checkout v2.22.0
|
||||
docker pull quay.io/kubespray/kubespray:v2.22.0
|
||||
docker run --rm -it --mount type=bind,source="$(pwd)"/inventory/sample,dst=/inventory \
|
||||
--mount type=bind,source="${HOME}"/.ssh/id_rsa,dst=/root/.ssh/id_rsa \
|
||||
quay.io/kubespray/kubespray:v2.20.0 bash
|
||||
quay.io/kubespray/kubespray:v2.22.0 bash
|
||||
# Inside the container you may now run the kubespray playbooks:
|
||||
ansible-playbook -i /inventory/inventory.ini --private-key /root/.ssh/id_rsa cluster.yml
|
||||
```
|
||||
|
||||
#### Collection
|
||||
|
||||
See [here](docs/ansible_collection.md) if you wish to use this repository as an Ansible collection
|
||||
|
||||
### Vagrant
|
||||
|
||||
For Vagrant we need to install Python dependencies for provisioning tasks.
|
||||
@ -131,7 +142,7 @@ vagrant up
|
||||
## Supported Linux Distributions
|
||||
|
||||
- **Flatcar Container Linux by Kinvolk**
|
||||
- **Debian** Bullseye, Buster, Jessie, Stretch
|
||||
- **Debian** Bullseye, Buster
|
||||
- **Ubuntu** 16.04, 18.04, 20.04, 22.04
|
||||
- **CentOS/RHEL** 7, [8, 9](docs/centos.md#centos-8)
|
||||
- **Fedora** 35, 36
|
||||
@ -150,30 +161,29 @@ Note: Upstart/SysV init based OS types are not supported.
|
||||
## Supported Components
|
||||
|
||||
- Core
|
||||
- [kubernetes](https://github.com/kubernetes/kubernetes) v1.25.6
|
||||
- [kubernetes](https://github.com/kubernetes/kubernetes) v1.26.5
|
||||
- [etcd](https://github.com/etcd-io/etcd) v3.5.6
|
||||
- [docker](https://www.docker.com/) v20.10 (see note)
|
||||
- [containerd](https://containerd.io/) v1.6.15
|
||||
- [containerd](https://containerd.io/) v1.7.1
|
||||
- [cri-o](http://cri-o.io/) v1.24 (experimental: see [CRI-O Note](docs/cri-o.md). Only on fedora, ubuntu and centos based OS)
|
||||
- Network Plugin
|
||||
- [cni-plugins](https://github.com/containernetworking/plugins) v1.2.0
|
||||
- [calico](https://github.com/projectcalico/calico) v3.24.5
|
||||
- [canal](https://github.com/projectcalico/canal) (given calico/flannel versions)
|
||||
- [cilium](https://github.com/cilium/cilium) v1.12.1
|
||||
- [flannel](https://github.com/flannel-io/flannel) v0.20.2
|
||||
- [calico](https://github.com/projectcalico/calico) v3.25.1
|
||||
- [cilium](https://github.com/cilium/cilium) v1.13.0
|
||||
- [flannel](https://github.com/flannel-io/flannel) v0.21.4
|
||||
- [kube-ovn](https://github.com/alauda/kube-ovn) v1.10.7
|
||||
- [kube-router](https://github.com/cloudnativelabs/kube-router) v1.5.1
|
||||
- [multus](https://github.com/intel/multus-cni) v3.8
|
||||
- [multus](https://github.com/k8snetworkplumbingwg/multus-cni) v3.8
|
||||
- [weave](https://github.com/weaveworks/weave) v2.8.1
|
||||
- [kube-vip](https://github.com/kube-vip/kube-vip) v0.5.5
|
||||
- [kube-vip](https://github.com/kube-vip/kube-vip) v0.5.12
|
||||
- Application
|
||||
- [cert-manager](https://github.com/jetstack/cert-manager) v1.11.0
|
||||
- [cert-manager](https://github.com/jetstack/cert-manager) v1.11.1
|
||||
- [coredns](https://github.com/coredns/coredns) v1.9.3
|
||||
- [ingress-nginx](https://github.com/kubernetes/ingress-nginx) v1.5.1
|
||||
- [ingress-nginx](https://github.com/kubernetes/ingress-nginx) v1.7.1
|
||||
- [krew](https://github.com/kubernetes-sigs/krew) v0.4.3
|
||||
- [argocd](https://argoproj.github.io/) v2.5.7
|
||||
- [helm](https://helm.sh/) v3.10.3
|
||||
- [metallb](https://metallb.universe.tf/) v0.12.1
|
||||
- [argocd](https://argoproj.github.io/) v2.7.2
|
||||
- [helm](https://helm.sh/) v3.12.0
|
||||
- [metallb](https://metallb.universe.tf/) v0.13.9
|
||||
- [registry](https://github.com/distribution/distribution) v2.8.1
|
||||
- Storage Plugin
|
||||
- [cephfs-provisioner](https://github.com/kubernetes-incubator/external-storage) v2.1.0-k8s1.11
|
||||
@ -182,7 +192,7 @@ Note: Upstart/SysV init based OS types are not supported.
|
||||
- [azure-csi-plugin](https://github.com/kubernetes-sigs/azuredisk-csi-driver) v1.10.0
|
||||
- [cinder-csi-plugin](https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/cinder-csi-plugin/using-cinder-csi-plugin.md) v1.22.0
|
||||
- [gcp-pd-csi-plugin](https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver) v1.4.0
|
||||
- [local-path-provisioner](https://github.com/rancher/local-path-provisioner) v0.0.22
|
||||
- [local-path-provisioner](https://github.com/rancher/local-path-provisioner) v0.0.23
|
||||
- [local-volume-provisioner](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner) v2.5.0
|
||||
|
||||
## Container Runtime Notes
|
||||
@ -192,14 +202,14 @@ Note: Upstart/SysV init based OS types are not supported.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Minimum required version of Kubernetes is v1.23**
|
||||
- **Minimum required version of Kubernetes is v1.24**
|
||||
- **Ansible v2.11+, Jinja 2.11+ and python-netaddr is installed on the machine that will run Ansible commands**
|
||||
- The target servers must have **access to the Internet** in order to pull docker images. Otherwise, additional configuration is required (See [Offline Environment](docs/offline-environment.md))
|
||||
- The target servers are configured to allow **IPv4 forwarding**.
|
||||
- If using IPv6 for pods and services, the target servers are configured to allow **IPv6 forwarding**.
|
||||
- The **firewalls are not managed**, you'll need to implement your own rules the way you used to.
|
||||
in order to avoid any issue during deployment you should disable your firewall.
|
||||
- If kubespray is ran from non-root user account, correct privilege escalation method
|
||||
- If kubespray is run from non-root user account, correct privilege escalation method
|
||||
should be configured in the target servers. Then the `ansible_become` flag
|
||||
or command parameters `--become or -b` should be specified.
|
||||
|
||||
@ -222,8 +232,6 @@ You can choose among ten network plugins. (default: `calico`, except Vagrant use
|
||||
and overlay networks, with or without BGP. Calico uses the same engine to enforce network policy for hosts,
|
||||
pods, and (if using Istio and Envoy) applications at the service mesh layer.
|
||||
|
||||
- [canal](https://github.com/projectcalico/canal): a composition of calico and flannel plugins.
|
||||
|
||||
- [cilium](http://docs.cilium.io/en/latest/): layer 3/4 networking (as well as layer 7 to protect and secure application protocols), supports dynamic insertion of BPF bytecode into the Linux kernel to implement security services, networking and visibility logic.
|
||||
|
||||
- [weave](docs/weave.md): Weave is a lightweight container overlay network that doesn't require an external K/V database cluster.
|
||||
@ -240,6 +248,9 @@ You can choose among ten network plugins. (default: `calico`, except Vagrant use
|
||||
|
||||
- [multus](docs/multus.md): Multus is a meta CNI plugin that provides multiple network interface support to pods. For each interface Multus delegates CNI calls to secondary CNI plugins such as Calico, macvlan, etc.
|
||||
|
||||
- [custom_cni](roles/network-plugin/custom_cni/) : You can specify some manifests that will be applied to the clusters to bring you own CNI and use non-supported ones by Kubespray.
|
||||
See `tests/files/custom_cni/README.md` and `tests/files/custom_cni/values.yaml`for an example with a CNI provided by a Helm Chart.
|
||||
|
||||
The network plugin to use is defined by the variable `kube_network_plugin`. There is also an
|
||||
option to leverage built-in cloud provider networking instead.
|
||||
See also [Network checker](docs/netcheck.md).
|
||||
@ -265,7 +276,7 @@ See also [Network checker](docs/netcheck.md).
|
||||
|
||||
## CI Tests
|
||||
|
||||
[](https://gitlab.com/kargo-ci/kubernetes-sigs-kubespray/pipelines)
|
||||
[](https://gitlab.com/kargo-ci/kubernetes-sigs-kubespray/-/pipelines)
|
||||
|
||||
CI/end-to-end tests sponsored by: [CNCF](https://cncf.io), [Equinix Metal](https://metal.equinix.com/), [OVHcloud](https://www.ovhcloud.com/), [ELASTX](https://elastx.se/).
|
||||
|
||||
|
@ -60,7 +60,7 @@ release-notes --start-sha <The start commit-id> --end-sha <The end commit-id> --
|
||||
```
|
||||
|
||||
If the release note file(/tmp/kubespray-release-note) contains "### Uncategorized" pull requests, those pull requests don't have a valid kind label(`kind/feature`, etc.).
|
||||
It is necessary to put a valid label on each pull request and run the above release-notes command again to get a better release note)
|
||||
It is necessary to put a valid label on each pull request and run the above release-notes command again to get a better release note
|
||||
|
||||
## Container image creation
|
||||
|
||||
|
16
Vagrantfile
vendored
16
Vagrantfile
vendored
@ -10,6 +10,7 @@ Vagrant.require_version ">= 2.0.0"
|
||||
CONFIG = File.join(File.dirname(__FILE__), ENV['KUBESPRAY_VAGRANT_CONFIG'] || 'vagrant/config.rb')
|
||||
|
||||
FLATCAR_URL_TEMPLATE = "https://%s.release.flatcar-linux.net/amd64-usr/current/flatcar_production_vagrant.json"
|
||||
FEDORA35_MIRROR = "https://download.fedoraproject.org/pub/fedora/linux/releases/35/Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-35-1.2.x86_64.vagrant-libvirt.box"
|
||||
|
||||
# Uniq disk UUID for libvirt
|
||||
DISK_UUID = Time.now.utc.to_i
|
||||
@ -29,7 +30,7 @@ SUPPORTED_OS = {
|
||||
"almalinux8" => {box: "almalinux/8", user: "vagrant"},
|
||||
"almalinux8-bento" => {box: "bento/almalinux-8", user: "vagrant"},
|
||||
"rockylinux8" => {box: "generic/rocky8", user: "vagrant"},
|
||||
"fedora35" => {box: "fedora/35-cloud-base", user: "vagrant"},
|
||||
"fedora35" => {box: "fedora/35-cloud-base", user: "vagrant", box_url: FEDORA35_MIRROR},
|
||||
"fedora36" => {box: "fedora/36-cloud-base", user: "vagrant"},
|
||||
"opensuse" => {box: "opensuse/Leap-15.4.x86_64", user: "vagrant"},
|
||||
"opensuse-tumbleweed" => {box: "opensuse/Tumbleweed.x86_64", user: "vagrant"},
|
||||
@ -55,14 +56,14 @@ $subnet ||= "172.18.8"
|
||||
$subnet_ipv6 ||= "fd3c:b398:0698:0756"
|
||||
$os ||= "ubuntu1804"
|
||||
$network_plugin ||= "flannel"
|
||||
# Setting multi_networking to true will install Multus: https://github.com/intel/multus-cni
|
||||
# Setting multi_networking to true will install Multus: https://github.com/k8snetworkplumbingwg/multus-cni
|
||||
$multi_networking ||= "False"
|
||||
$download_run_once ||= "True"
|
||||
$download_force_cache ||= "False"
|
||||
# The first three nodes are etcd servers
|
||||
$etcd_instances ||= $num_instances
|
||||
$etcd_instances ||= [$num_instances, 3].min
|
||||
# The first two nodes are kube masters
|
||||
$kube_master_instances ||= $num_instances == 1 ? $num_instances : ($num_instances - 1)
|
||||
$kube_master_instances ||= [$num_instances, 2].min
|
||||
# All nodes are kube nodes
|
||||
$kube_node_instances ||= $num_instances
|
||||
# The following only works when using the libvirt provider
|
||||
@ -82,6 +83,13 @@ $playbook ||= "cluster.yml"
|
||||
|
||||
host_vars = {}
|
||||
|
||||
# throw error if os is not supported
|
||||
if ! SUPPORTED_OS.key?($os)
|
||||
puts "Unsupported OS: #{$os}"
|
||||
puts "Supported OS are: #{SUPPORTED_OS.keys.join(', ')}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
$box = SUPPORTED_OS[$os][:box]
|
||||
# if $inventory is not set, try to use example
|
||||
$inventory = "inventory/sample" if ! $inventory
|
||||
|
132
cluster.yml
132
cluster.yml
@ -1,131 +1,3 @@
|
||||
---
|
||||
- name: Check ansible version
|
||||
import_playbook: ansible_version.yml
|
||||
|
||||
- name: Ensure compatibility with old groups
|
||||
import_playbook: legacy_groups.yml
|
||||
|
||||
- hosts: bastion[0]
|
||||
gather_facts: False
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: bastion-ssh-config, tags: ["localhost", "bastion"] }
|
||||
|
||||
- hosts: k8s_cluster:etcd
|
||||
strategy: linear
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
gather_facts: false
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: bootstrap-os, tags: bootstrap-os}
|
||||
|
||||
- name: Gather facts
|
||||
tags: always
|
||||
import_playbook: facts.yml
|
||||
|
||||
- hosts: k8s_cluster:etcd
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: kubernetes/preinstall, tags: preinstall }
|
||||
- { role: "container-engine", tags: "container-engine", when: deploy_container_engine }
|
||||
- { role: download, tags: download, when: "not skip_downloads" }
|
||||
|
||||
- hosts: etcd:kube_control_plane
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- role: etcd
|
||||
tags: etcd
|
||||
vars:
|
||||
etcd_cluster_setup: true
|
||||
etcd_events_cluster_setup: "{{ etcd_events_cluster_enabled }}"
|
||||
when: etcd_deployment_type != "kubeadm"
|
||||
|
||||
- hosts: k8s_cluster
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- role: etcd
|
||||
tags: etcd
|
||||
vars:
|
||||
etcd_cluster_setup: false
|
||||
etcd_events_cluster_setup: false
|
||||
when:
|
||||
- etcd_deployment_type != "kubeadm"
|
||||
- kube_network_plugin in ["calico", "flannel", "canal", "cilium"] or cilium_deploy_additionally | default(false) | bool
|
||||
- kube_network_plugin != "calico" or calico_datastore == "etcd"
|
||||
|
||||
- hosts: k8s_cluster
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: kubernetes/node, tags: node }
|
||||
|
||||
- hosts: kube_control_plane
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: kubernetes/control-plane, tags: master }
|
||||
- { role: kubernetes/client, tags: client }
|
||||
- { role: kubernetes-apps/cluster_roles, tags: cluster-roles }
|
||||
|
||||
- hosts: k8s_cluster
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: kubernetes/kubeadm, tags: kubeadm}
|
||||
- { role: kubernetes/node-label, tags: node-label }
|
||||
- { role: network_plugin, tags: network }
|
||||
|
||||
- hosts: calico_rr
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: network_plugin/calico/rr, tags: ['network', 'calico_rr'] }
|
||||
|
||||
- hosts: kube_control_plane[0]
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: win_nodes/kubernetes_patch, tags: ["master", "win_nodes"] }
|
||||
|
||||
- hosts: kube_control_plane
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: kubernetes-apps/external_cloud_controller, tags: external-cloud-controller }
|
||||
- { role: kubernetes-apps/network_plugin, tags: network }
|
||||
- { role: kubernetes-apps/policy_controller, tags: policy-controller }
|
||||
- { role: kubernetes-apps/ingress_controller, tags: ingress-controller }
|
||||
- { role: kubernetes-apps/external_provisioner, tags: external-provisioner }
|
||||
- { role: kubernetes-apps, tags: apps }
|
||||
|
||||
- name: Apply resolv.conf changes now that cluster DNS is up
|
||||
hosts: k8s_cluster
|
||||
gather_facts: False
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
environment: "{{ proxy_disable_env }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults }
|
||||
- { role: kubernetes/preinstall, when: "dns_mode != 'none' and resolvconf_mode == 'host_resolvconf'", tags: resolvconf, dns_late: true }
|
||||
- name: Install Kubernetes
|
||||
ansible.builtin.import_playbook: playbooks/cluster.yml
|
||||
|
@ -31,4 +31,3 @@
|
||||
[k8s_cluster:children]
|
||||
kube_node
|
||||
kube_control_plane
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items: "{{ distro_extra_packages }} + [ 'rsyslog', 'openssh-server' ]"
|
||||
with_items: "{{ distro_extra_packages + [ 'rsyslog', 'openssh-server' ] }}"
|
||||
|
||||
- name: Start needed services
|
||||
service:
|
||||
|
@ -1,3 +1,3 @@
|
||||
configparser>=3.3.0
|
||||
ruamel.yaml>=0.15.88
|
||||
ipaddress
|
||||
ruamel.yaml>=0.15.88
|
||||
|
@ -1,3 +1,3 @@
|
||||
hacking>=0.10.2
|
||||
pytest>=2.8.0
|
||||
mock>=1.3.0
|
||||
pytest>=2.8.0
|
||||
|
@ -1,3 +1,2 @@
|
||||
#k8s_deployment_user: kubespray
|
||||
#k8s_deployment_user_pkey_path: /tmp/ssh_rsa
|
||||
|
||||
|
@ -41,4 +41,3 @@
|
||||
|
||||
# [network-storage:children]
|
||||
# gfs-cluster
|
||||
|
||||
|
@ -21,4 +21,3 @@
|
||||
{% endfor %}
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ This will install a Kubernetes cluster on Equinix Metal. It should work in all l
|
||||
The terraform configuration inspects variables found in
|
||||
[variables.tf](variables.tf) to create resources in your Equinix Metal project.
|
||||
There is a [python script](../terraform.py) that reads the generated`.tfstate`
|
||||
file to generate a dynamic inventory that is consumed by [cluster.yml](../../..//cluster.yml)
|
||||
file to generate a dynamic inventory that is consumed by [cluster.yml](../../../cluster.yml)
|
||||
to actually install Kubernetes with Kubespray.
|
||||
|
||||
### Kubernetes Nodes
|
||||
@ -60,16 +60,16 @@ Terraform will be used to provision all of the Equinix Metal resources with base
|
||||
Create an inventory directory for your cluster by copying the existing sample and linking the `hosts` script (used to build the inventory based on Terraform state):
|
||||
|
||||
```ShellSession
|
||||
cp -LRp contrib/terraform/metal/sample-inventory inventory/$CLUSTER
|
||||
cp -LRp contrib/terraform/equinix/sample-inventory inventory/$CLUSTER
|
||||
cd inventory/$CLUSTER
|
||||
ln -s ../../contrib/terraform/metal/hosts
|
||||
ln -s ../../contrib/terraform/equinix/hosts
|
||||
```
|
||||
|
||||
This will be the base for subsequent Terraform commands.
|
||||
|
||||
#### Equinix Metal API access
|
||||
|
||||
Your Equinix Metal API key must be available in the `PACKET_AUTH_TOKEN` environment variable.
|
||||
Your Equinix Metal API key must be available in the `METAL_AUTH_TOKEN` environment variable.
|
||||
This key is typically stored outside of the code repo since it is considered secret.
|
||||
If someone gets this key, they can startup/shutdown hosts in your project!
|
||||
|
||||
@ -80,10 +80,12 @@ The Equinix Metal Project ID associated with the key will be set later in `clust
|
||||
|
||||
For more information about the API, please see [Equinix Metal API](https://metal.equinix.com/developers/api/).
|
||||
|
||||
For more information about terraform provider authentication, please see [the equinix provider documentation](https://registry.terraform.io/providers/equinix/equinix/latest/docs).
|
||||
|
||||
Example:
|
||||
|
||||
```ShellSession
|
||||
export PACKET_AUTH_TOKEN="Example-API-Token"
|
||||
export METAL_AUTH_TOKEN="Example-API-Token"
|
||||
```
|
||||
|
||||
Note that to deploy several clusters within the same project you need to use [terraform workspace](https://www.terraform.io/docs/state/workspaces.html#using-workspaces).
|
||||
@ -101,7 +103,7 @@ This helps when identifying which hosts are associated with each cluster.
|
||||
While the defaults in variables.tf will successfully deploy a cluster, it is recommended to set the following values:
|
||||
|
||||
- cluster_name = the name of the inventory directory created above as $CLUSTER
|
||||
- metal_project_id = the Equinix Metal Project ID associated with the Equinix Metal API token above
|
||||
- equinix_metal_project_id = the Equinix Metal Project ID associated with the Equinix Metal API token above
|
||||
|
||||
#### Enable localhost access
|
||||
|
||||
@ -119,12 +121,13 @@ Once the Kubespray playbooks are run, a Kubernetes configuration file will be wr
|
||||
|
||||
In the cluster's inventory folder, the following files might be created (either by Terraform
|
||||
or manually), to prevent you from pushing them accidentally they are in a
|
||||
`.gitignore` file in the `terraform/metal` directory :
|
||||
`.gitignore` file in the `contrib/terraform/equinix` directory :
|
||||
|
||||
- `.terraform`
|
||||
- `.tfvars`
|
||||
- `.tfstate`
|
||||
- `.tfstate.backup`
|
||||
- `.lock.hcl`
|
||||
|
||||
You can still add them manually if you want to.
|
||||
|
||||
@ -135,7 +138,7 @@ plugins. This is accomplished as follows:
|
||||
|
||||
```ShellSession
|
||||
cd inventory/$CLUSTER
|
||||
terraform init ../../contrib/terraform/metal
|
||||
terraform -chdir=../../contrib/terraform/metal init -var-file=cluster.tfvars
|
||||
```
|
||||
|
||||
This should finish fairly quickly telling you Terraform has successfully initialized and loaded necessary modules.
|
||||
@ -146,7 +149,7 @@ You can apply the Terraform configuration to your cluster with the following com
|
||||
issued from your cluster's inventory directory (`inventory/$CLUSTER`):
|
||||
|
||||
```ShellSession
|
||||
terraform apply -var-file=cluster.tfvars ../../contrib/terraform/metal
|
||||
terraform -chdir=../../contrib/terraform/equinix apply -var-file=cluster.tfvars
|
||||
export ANSIBLE_HOST_KEY_CHECKING=False
|
||||
ansible-playbook -i hosts ../../cluster.yml
|
||||
```
|
||||
@ -156,7 +159,7 @@ ansible-playbook -i hosts ../../cluster.yml
|
||||
You can destroy your new cluster with the following command issued from the cluster's inventory directory:
|
||||
|
||||
```ShellSession
|
||||
terraform destroy -var-file=cluster.tfvars ../../contrib/terraform/metal
|
||||
terraform -chdir=../../contrib/terraform/equinix destroy -var-file=cluster.tfvars
|
||||
```
|
||||
|
||||
If you've started the Ansible run, it may also be a good idea to do some manual cleanup:
|
@ -1,62 +1,57 @@
|
||||
# Configure the Equinix Metal Provider
|
||||
provider "metal" {
|
||||
}
|
||||
|
||||
resource "metal_ssh_key" "k8s" {
|
||||
resource "equinix_metal_ssh_key" "k8s" {
|
||||
count = var.public_key_path != "" ? 1 : 0
|
||||
name = "kubernetes-${var.cluster_name}"
|
||||
public_key = chomp(file(var.public_key_path))
|
||||
}
|
||||
|
||||
resource "metal_device" "k8s_master" {
|
||||
depends_on = [metal_ssh_key.k8s]
|
||||
resource "equinix_metal_device" "k8s_master" {
|
||||
depends_on = [equinix_metal_ssh_key.k8s]
|
||||
|
||||
count = var.number_of_k8s_masters
|
||||
hostname = "${var.cluster_name}-k8s-master-${count.index + 1}"
|
||||
plan = var.plan_k8s_masters
|
||||
facilities = [var.facility]
|
||||
metro = var.metro
|
||||
operating_system = var.operating_system
|
||||
billing_cycle = var.billing_cycle
|
||||
project_id = var.metal_project_id
|
||||
project_id = var.equinix_metal_project_id
|
||||
tags = ["cluster-${var.cluster_name}", "k8s_cluster", "kube_control_plane", "etcd", "kube_node"]
|
||||
}
|
||||
|
||||
resource "metal_device" "k8s_master_no_etcd" {
|
||||
depends_on = [metal_ssh_key.k8s]
|
||||
resource "equinix_metal_device" "k8s_master_no_etcd" {
|
||||
depends_on = [equinix_metal_ssh_key.k8s]
|
||||
|
||||
count = var.number_of_k8s_masters_no_etcd
|
||||
hostname = "${var.cluster_name}-k8s-master-${count.index + 1}"
|
||||
plan = var.plan_k8s_masters_no_etcd
|
||||
facilities = [var.facility]
|
||||
metro = var.metro
|
||||
operating_system = var.operating_system
|
||||
billing_cycle = var.billing_cycle
|
||||
project_id = var.metal_project_id
|
||||
project_id = var.equinix_metal_project_id
|
||||
tags = ["cluster-${var.cluster_name}", "k8s_cluster", "kube_control_plane"]
|
||||
}
|
||||
|
||||
resource "metal_device" "k8s_etcd" {
|
||||
depends_on = [metal_ssh_key.k8s]
|
||||
resource "equinix_metal_device" "k8s_etcd" {
|
||||
depends_on = [equinix_metal_ssh_key.k8s]
|
||||
|
||||
count = var.number_of_etcd
|
||||
hostname = "${var.cluster_name}-etcd-${count.index + 1}"
|
||||
plan = var.plan_etcd
|
||||
facilities = [var.facility]
|
||||
metro = var.metro
|
||||
operating_system = var.operating_system
|
||||
billing_cycle = var.billing_cycle
|
||||
project_id = var.metal_project_id
|
||||
project_id = var.equinix_metal_project_id
|
||||
tags = ["cluster-${var.cluster_name}", "etcd"]
|
||||
}
|
||||
|
||||
resource "metal_device" "k8s_node" {
|
||||
depends_on = [metal_ssh_key.k8s]
|
||||
resource "equinix_metal_device" "k8s_node" {
|
||||
depends_on = [equinix_metal_ssh_key.k8s]
|
||||
|
||||
count = var.number_of_k8s_nodes
|
||||
hostname = "${var.cluster_name}-k8s-node-${count.index + 1}"
|
||||
plan = var.plan_k8s_nodes
|
||||
facilities = [var.facility]
|
||||
metro = var.metro
|
||||
operating_system = var.operating_system
|
||||
billing_cycle = var.billing_cycle
|
||||
project_id = var.metal_project_id
|
||||
project_id = var.equinix_metal_project_id
|
||||
tags = ["cluster-${var.cluster_name}", "k8s_cluster", "kube_node"]
|
||||
}
|
||||
|
15
contrib/terraform/equinix/output.tf
Normal file
15
contrib/terraform/equinix/output.tf
Normal file
@ -0,0 +1,15 @@
|
||||
output "k8s_masters" {
|
||||
value = equinix_metal_device.k8s_master.*.access_public_ipv4
|
||||
}
|
||||
|
||||
output "k8s_masters_no_etc" {
|
||||
value = equinix_metal_device.k8s_master_no_etcd.*.access_public_ipv4
|
||||
}
|
||||
|
||||
output "k8s_etcds" {
|
||||
value = equinix_metal_device.k8s_etcd.*.access_public_ipv4
|
||||
}
|
||||
|
||||
output "k8s_nodes" {
|
||||
value = equinix_metal_device.k8s_node.*.access_public_ipv4
|
||||
}
|
17
contrib/terraform/equinix/provider.tf
Normal file
17
contrib/terraform/equinix/provider.tf
Normal file
@ -0,0 +1,17 @@
|
||||
terraform {
|
||||
required_version = ">= 1.0.0"
|
||||
|
||||
provider_meta "equinix" {
|
||||
module_name = "kubespray"
|
||||
}
|
||||
required_providers {
|
||||
equinix = {
|
||||
source = "equinix/equinix"
|
||||
version = "~> 1.14"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Configure the Equinix Metal Provider
|
||||
provider "equinix" {
|
||||
}
|
@ -1,16 +1,19 @@
|
||||
# your Kubernetes cluster name here
|
||||
cluster_name = "mycluster"
|
||||
|
||||
# Your Equinix Metal project ID. See hhttps://metal.equinix.com/developers/docs/accounts/
|
||||
metal_project_id = "Example-API-Token"
|
||||
# Your Equinix Metal project ID. See https://metal.equinix.com/developers/docs/accounts/
|
||||
equinix_metal_project_id = "Example-Project-Id"
|
||||
|
||||
# The public SSH key to be uploaded into authorized_keys in bare metal Equinix Metal nodes provisioned
|
||||
# leave this value blank if the public key is already setup in the Equinix Metal project
|
||||
# Terraform will complain if the public key is setup in Equinix Metal
|
||||
public_key_path = "~/.ssh/id_rsa.pub"
|
||||
|
||||
# cluster location
|
||||
facility = "ewr1"
|
||||
# Equinix interconnected bare metal across our global metros.
|
||||
metro = "da"
|
||||
|
||||
# operating_system
|
||||
operating_system = "ubuntu_22_04"
|
||||
|
||||
# standalone etcds
|
||||
number_of_etcd = 0
|
@ -2,12 +2,12 @@ variable "cluster_name" {
|
||||
default = "kubespray"
|
||||
}
|
||||
|
||||
variable "metal_project_id" {
|
||||
variable "equinix_metal_project_id" {
|
||||
description = "Your Equinix Metal project ID. See https://metal.equinix.com/developers/docs/accounts/"
|
||||
}
|
||||
|
||||
variable "operating_system" {
|
||||
default = "ubuntu_20_04"
|
||||
default = "ubuntu_22_04"
|
||||
}
|
||||
|
||||
variable "public_key_path" {
|
||||
@ -19,8 +19,8 @@ variable "billing_cycle" {
|
||||
default = "hourly"
|
||||
}
|
||||
|
||||
variable "facility" {
|
||||
default = "dfw2"
|
||||
variable "metro" {
|
||||
default = "da"
|
||||
}
|
||||
|
||||
variable "plan_k8s_masters" {
|
||||
@ -54,4 +54,3 @@ variable "number_of_etcd" {
|
||||
variable "number_of_k8s_nodes" {
|
||||
default = 1
|
||||
}
|
||||
|
@ -15,17 +15,17 @@ machines = {
|
||||
"master-0" : {
|
||||
"node_type" : "master",
|
||||
"size" : "cx21",
|
||||
"image" : "ubuntu-20.04",
|
||||
"image" : "ubuntu-22.04",
|
||||
},
|
||||
"worker-0" : {
|
||||
"node_type" : "worker",
|
||||
"size" : "cx21",
|
||||
"image" : "ubuntu-20.04",
|
||||
"image" : "ubuntu-22.04",
|
||||
},
|
||||
"worker-1" : {
|
||||
"node_type" : "worker",
|
||||
"size" : "cx21",
|
||||
"image" : "ubuntu-20.04",
|
||||
"image" : "ubuntu-22.04",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ provider "hcloud" {}
|
||||
|
||||
module "kubernetes" {
|
||||
source = "./modules/kubernetes-cluster"
|
||||
#source = "./modules/kubernetes-cluster-flatcar"
|
||||
# source = "./modules/kubernetes-cluster-flatcar"
|
||||
|
||||
prefix = var.prefix
|
||||
|
||||
@ -26,10 +26,10 @@ module "kubernetes" {
|
||||
# Generate ansible inventory
|
||||
#
|
||||
|
||||
data "template_file" "inventory" {
|
||||
template = file("${path.module}/templates/inventory.tpl")
|
||||
|
||||
vars = {
|
||||
locals {
|
||||
inventory = templatefile(
|
||||
"${path.module}/templates/inventory.tpl",
|
||||
{
|
||||
connection_strings_master = join("\n", formatlist("%s ansible_user=ubuntu ansible_host=%s ip=%s etcd_member_name=etcd%d",
|
||||
keys(module.kubernetes.master_ip_addresses),
|
||||
values(module.kubernetes.master_ip_addresses).*.public_ip,
|
||||
@ -43,14 +43,15 @@ data "template_file" "inventory" {
|
||||
list_worker = join("\n", keys(module.kubernetes.worker_ip_addresses))
|
||||
network_id = module.kubernetes.network_id
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
resource "null_resource" "inventories" {
|
||||
provisioner "local-exec" {
|
||||
command = "echo '${data.template_file.inventory.rendered}' > ${var.inventory_file}"
|
||||
command = "echo '${local.inventory}' > ${var.inventory_file}"
|
||||
}
|
||||
|
||||
triggers = {
|
||||
template = data.template_file.inventory.rendered
|
||||
template = local.inventory
|
||||
}
|
||||
}
|
@ -15,12 +15,12 @@ resource "hcloud_ssh_key" "first" {
|
||||
public_key = var.ssh_public_keys.0
|
||||
}
|
||||
|
||||
resource "hcloud_server" "master" {
|
||||
resource "hcloud_server" "machine" {
|
||||
for_each = {
|
||||
for name, machine in var.machines :
|
||||
name => machine
|
||||
if machine.node_type == "master"
|
||||
}
|
||||
|
||||
name = "${var.prefix}-${each.key}"
|
||||
ssh_keys = [hcloud_ssh_key.first.id]
|
||||
# boot into rescue OS
|
||||
@ -34,7 +34,7 @@ resource "hcloud_server" "master" {
|
||||
timeout = "5m"
|
||||
private_key = file(var.ssh_private_key_path)
|
||||
}
|
||||
firewall_ids = [hcloud_firewall.machine.id]
|
||||
firewall_ids = each.value.node_type == "master" ? [hcloud_firewall.master.id] : [hcloud_firewall.worker.id]
|
||||
provisioner "file" {
|
||||
content = data.ct_config.machine-ignitions[each.key].rendered
|
||||
destination = "/root/ignition.json"
|
||||
@ -45,9 +45,9 @@ resource "hcloud_server" "master" {
|
||||
"set -ex",
|
||||
"apt update",
|
||||
"apt install -y gawk",
|
||||
"curl -fsSLO --retry-delay 1 --retry 60 --retry-connrefused --retry-max-time 60 --connect-timeout 20 https://raw.githubusercontent.com/kinvolk/init/flatcar-master/bin/flatcar-install",
|
||||
"curl -fsSLO --retry-delay 1 --retry 60 --retry-connrefused --retry-max-time 60 --connect-timeout 20 https://raw.githubusercontent.com/flatcar/init/flatcar-master/bin/flatcar-install",
|
||||
"chmod +x flatcar-install",
|
||||
"./flatcar-install -s -i /root/ignition.json",
|
||||
"./flatcar-install -s -i /root/ignition.json -C stable",
|
||||
"shutdown -r +1",
|
||||
]
|
||||
}
|
||||
@ -56,6 +56,7 @@ resource "hcloud_server" "master" {
|
||||
provisioner "remote-exec" {
|
||||
connection {
|
||||
host = self.ipv4_address
|
||||
private_key = file(var.ssh_private_key_path)
|
||||
timeout = "3m"
|
||||
user = var.user_flatcar
|
||||
}
|
||||
@ -66,65 +67,11 @@ resource "hcloud_server" "master" {
|
||||
}
|
||||
}
|
||||
|
||||
resource "hcloud_server_network" "master" {
|
||||
for_each = hcloud_server.master
|
||||
server_id = each.value.id
|
||||
subnet_id = hcloud_network_subnet.kubernetes.id
|
||||
}
|
||||
|
||||
resource "hcloud_server" "worker" {
|
||||
resource "hcloud_server_network" "machine" {
|
||||
for_each = {
|
||||
for name, machine in var.machines :
|
||||
name => machine
|
||||
if machine.node_type == "worker"
|
||||
name => hcloud_server.machine[name]
|
||||
}
|
||||
name = "${var.prefix}-${each.key}"
|
||||
ssh_keys = [hcloud_ssh_key.first.id]
|
||||
# boot into rescue OS
|
||||
rescue = "linux64"
|
||||
# dummy value for the OS because Flatcar is not available
|
||||
image = each.value.image
|
||||
server_type = each.value.size
|
||||
location = var.zone
|
||||
connection {
|
||||
host = self.ipv4_address
|
||||
timeout = "5m"
|
||||
private_key = file(var.ssh_private_key_path)
|
||||
}
|
||||
firewall_ids = [hcloud_firewall.machine.id]
|
||||
provisioner "file" {
|
||||
content = data.ct_config.machine-ignitions[each.key].rendered
|
||||
destination = "/root/ignition.json"
|
||||
}
|
||||
|
||||
provisioner "remote-exec" {
|
||||
inline = [
|
||||
"set -ex",
|
||||
"apt update",
|
||||
"apt install -y gawk",
|
||||
"curl -fsSLO --retry-delay 1 --retry 60 --retry-connrefused --retry-max-time 60 --connect-timeout 20 https://raw.githubusercontent.com/kinvolk/init/flatcar-master/bin/flatcar-install",
|
||||
"chmod +x flatcar-install",
|
||||
"./flatcar-install -s -i /root/ignition.json",
|
||||
"shutdown -r +1",
|
||||
]
|
||||
}
|
||||
|
||||
# optional:
|
||||
provisioner "remote-exec" {
|
||||
connection {
|
||||
host = self.ipv4_address
|
||||
timeout = "3m"
|
||||
user = var.user_flatcar
|
||||
}
|
||||
|
||||
inline = [
|
||||
"sudo hostnamectl set-hostname ${self.name}",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "hcloud_server_network" "worker" {
|
||||
for_each = hcloud_server.worker
|
||||
server_id = each.value.id
|
||||
subnet_id = hcloud_network_subnet.kubernetes.id
|
||||
}
|
||||
@ -134,25 +81,20 @@ data "ct_config" "machine-ignitions" {
|
||||
for name, machine in var.machines :
|
||||
name => machine
|
||||
}
|
||||
content = data.template_file.machine-configs[each.key].rendered
|
||||
}
|
||||
|
||||
data "template_file" "machine-configs" {
|
||||
for_each = {
|
||||
for name, machine in var.machines :
|
||||
name => machine
|
||||
}
|
||||
template = file("${path.module}/templates/machine.yaml.tmpl")
|
||||
|
||||
vars = {
|
||||
strict = false
|
||||
content = templatefile(
|
||||
"${path.module}/templates/machine.yaml.tmpl",
|
||||
{
|
||||
ssh_keys = jsonencode(var.ssh_public_keys)
|
||||
user_flatcar = jsonencode(var.user_flatcar)
|
||||
user_flatcar = var.user_flatcar
|
||||
name = each.key
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
resource "hcloud_firewall" "machine" {
|
||||
name = "${var.prefix}-machine-firewall"
|
||||
resource "hcloud_firewall" "master" {
|
||||
name = "${var.prefix}-master-firewall"
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
|
@ -1,20 +1,22 @@
|
||||
output "master_ip_addresses" {
|
||||
value = {
|
||||
for key, instance in hcloud_server.master :
|
||||
instance.name => {
|
||||
"private_ip" = hcloud_server_network.master[key].ip
|
||||
"public_ip" = hcloud_server.master[key].ipv4_address
|
||||
for name, machine in var.machines :
|
||||
name => {
|
||||
"private_ip" = hcloud_server_network.machine[name].ip
|
||||
"public_ip" = hcloud_server.machine[name].ipv4_address
|
||||
}
|
||||
if machine.node_type == "master"
|
||||
}
|
||||
}
|
||||
|
||||
output "worker_ip_addresses" {
|
||||
value = {
|
||||
for key, instance in hcloud_server.worker :
|
||||
instance.name => {
|
||||
"private_ip" = hcloud_server_network.worker[key].ip
|
||||
"public_ip" = hcloud_server.worker[key].ipv4_address
|
||||
for name, machine in var.machines :
|
||||
name => {
|
||||
"private_ip" = hcloud_server_network.machine[name].ip
|
||||
"public_ip" = hcloud_server.machine[name].ipv4_address
|
||||
}
|
||||
if machine.node_type == "worker"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
---
|
||||
variant: flatcar
|
||||
version: 1.0.0
|
||||
|
||||
passwd:
|
||||
users:
|
||||
- name: ${user_flatcar}
|
||||
ssh_authorized_keys: ${ssh_keys}
|
||||
|
||||
storage:
|
||||
files:
|
||||
- path: /home/core/works
|
||||
|
@ -5,6 +5,7 @@ terraform {
|
||||
}
|
||||
ct = {
|
||||
source = "poseidon/ct"
|
||||
version = "0.11.0"
|
||||
}
|
||||
null = {
|
||||
source = "hashicorp/null"
|
||||
|
@ -14,4 +14,3 @@ ssh_authorized_keys:
|
||||
%{ for ssh_public_key in ssh_public_keys ~}
|
||||
- ${ssh_public_key}
|
||||
%{ endfor ~}
|
||||
|
||||
|
@ -2,7 +2,7 @@ terraform {
|
||||
required_providers {
|
||||
hcloud = {
|
||||
source = "hetznercloud/hcloud"
|
||||
version = "1.31.1"
|
||||
version = "1.38.2"
|
||||
}
|
||||
}
|
||||
required_version = ">= 0.14"
|
||||
|
46
contrib/terraform/hetzner/sample-inventory/cluster.tfvars
Normal file
46
contrib/terraform/hetzner/sample-inventory/cluster.tfvars
Normal file
@ -0,0 +1,46 @@
|
||||
prefix = "default"
|
||||
zone = "hel1"
|
||||
network_zone = "eu-central"
|
||||
inventory_file = "inventory.ini"
|
||||
|
||||
ssh_public_keys = [
|
||||
# Put your public SSH key here
|
||||
"ssh-rsa I-did-not-read-the-docs",
|
||||
"ssh-rsa I-did-not-read-the-docs 2",
|
||||
]
|
||||
|
||||
ssh_private_key_path = "~/.ssh/id_rsa"
|
||||
|
||||
machines = {
|
||||
"master-0" : {
|
||||
"node_type" : "master",
|
||||
"size" : "cx21",
|
||||
"image" : "ubuntu-22.04",
|
||||
},
|
||||
"worker-0" : {
|
||||
"node_type" : "worker",
|
||||
"size" : "cx21",
|
||||
"image" : "ubuntu-22.04",
|
||||
},
|
||||
"worker-1" : {
|
||||
"node_type" : "worker",
|
||||
"size" : "cx21",
|
||||
"image" : "ubuntu-22.04",
|
||||
}
|
||||
}
|
||||
|
||||
nodeport_whitelist = [
|
||||
"0.0.0.0/0"
|
||||
]
|
||||
|
||||
ingress_whitelist = [
|
||||
"0.0.0.0/0"
|
||||
]
|
||||
|
||||
ssh_whitelist = [
|
||||
"0.0.0.0/0"
|
||||
]
|
||||
|
||||
api_server_whitelist = [
|
||||
"0.0.0.0/0"
|
||||
]
|
1
contrib/terraform/hetzner/sample-inventory/group_vars
Symbolic link
1
contrib/terraform/hetzner/sample-inventory/group_vars
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../inventory/sample/group_vars
|
@ -2,14 +2,11 @@ terraform {
|
||||
required_providers {
|
||||
hcloud = {
|
||||
source = "hetznercloud/hcloud"
|
||||
version = "1.31.1"
|
||||
version = "1.38.2"
|
||||
}
|
||||
null = {
|
||||
source = "hashicorp/null"
|
||||
}
|
||||
template = {
|
||||
source = "hashicorp/template"
|
||||
}
|
||||
}
|
||||
required_version = ">= 0.14"
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
output "k8s_masters" {
|
||||
value = metal_device.k8s_master.*.access_public_ipv4
|
||||
}
|
||||
|
||||
output "k8s_masters_no_etc" {
|
||||
value = metal_device.k8s_master_no_etcd.*.access_public_ipv4
|
||||
}
|
||||
|
||||
output "k8s_etcds" {
|
||||
value = metal_device.k8s_etcd.*.access_public_ipv4
|
||||
}
|
||||
|
||||
output "k8s_nodes" {
|
||||
value = metal_device.k8s_node.*.access_public_ipv4
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
|
||||
terraform {
|
||||
required_version = ">= 0.12"
|
||||
required_providers {
|
||||
metal = {
|
||||
source = "equinix/metal"
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,5 @@ terraform {
|
||||
source = "terraform-provider-openstack/openstack"
|
||||
}
|
||||
}
|
||||
experiments = [module_variable_optional_attrs]
|
||||
required_version = ">= 0.14.0"
|
||||
required_version = ">= 1.3.0"
|
||||
}
|
||||
|
@ -44,4 +44,3 @@ resource "openstack_networking_floatingip_v2" "k8s_nodes" {
|
||||
pool = var.floatingip_pool
|
||||
depends_on = [null_resource.dummy_dependency]
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,5 @@ terraform {
|
||||
version = "~> 1.17"
|
||||
}
|
||||
}
|
||||
experiments = [module_variable_optional_attrs]
|
||||
required_version = ">= 0.14.0"
|
||||
required_version = ">= 1.3.0"
|
||||
}
|
||||
|
@ -194,9 +194,19 @@ def parse_bool(string_form):
|
||||
else:
|
||||
raise ValueError('could not convert %r to a bool' % string_form)
|
||||
|
||||
def sanitize_groups(groups):
|
||||
_groups = []
|
||||
chars_to_replace = ['+', '-', '=', '.', '/', ' ']
|
||||
for i in groups:
|
||||
_i = i
|
||||
for char in chars_to_replace:
|
||||
_i = _i.replace(char, '_')
|
||||
_groups.append(_i)
|
||||
groups.clear()
|
||||
groups.extend(_groups)
|
||||
|
||||
@parses('metal_device')
|
||||
def metal_device(resource, tfvars=None):
|
||||
@parses('equinix_metal_device')
|
||||
def equinix_metal_device(resource, tfvars=None):
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
name = raw_attrs['hostname']
|
||||
groups = []
|
||||
@ -220,7 +230,7 @@ def metal_device(resource, tfvars=None):
|
||||
'ipv6_address': raw_attrs['network.1.address'],
|
||||
'public_ipv6': raw_attrs['network.1.address'],
|
||||
'private_ipv4': raw_attrs['network.2.address'],
|
||||
'provider': 'metal',
|
||||
'provider': 'equinix',
|
||||
}
|
||||
|
||||
if raw_attrs['operating_system'] == 'flatcar_stable':
|
||||
@ -228,13 +238,14 @@ def metal_device(resource, tfvars=None):
|
||||
attrs.update({'ansible_ssh_user': 'core'})
|
||||
|
||||
# add groups based on attrs
|
||||
groups.append('metal_operating_system=' + attrs['operating_system'])
|
||||
groups.append('metal_locked=%s' % attrs['locked'])
|
||||
groups.append('metal_state=' + attrs['state'])
|
||||
groups.append('metal_plan=' + attrs['plan'])
|
||||
groups.append('equinix_metal_operating_system_%s' % attrs['operating_system'])
|
||||
groups.append('equinix_metal_locked_%s' % attrs['locked'])
|
||||
groups.append('equinix_metal_state_%s' % attrs['state'])
|
||||
groups.append('equinix_metal_plan_%s' % attrs['plan'])
|
||||
|
||||
# groups specific to kubespray
|
||||
groups = groups + attrs['tags']
|
||||
sanitize_groups(groups)
|
||||
|
||||
return name, attrs, groups
|
||||
|
||||
@ -273,8 +284,6 @@ def openstack_host(resource, module_name):
|
||||
'network': parse_attr_list(raw_attrs, 'network'),
|
||||
'region': raw_attrs.get('region', ''),
|
||||
'security_groups': parse_list(raw_attrs, 'security_groups'),
|
||||
# ansible
|
||||
'ansible_ssh_port': 22,
|
||||
# workaround for an OpenStack bug where hosts have a different domain
|
||||
# after they're restarted
|
||||
'host_domain': 'novalocal',
|
||||
@ -289,6 +298,9 @@ def openstack_host(resource, module_name):
|
||||
if 'floating_ip' in raw_attrs:
|
||||
attrs['private_ipv4'] = raw_attrs['network.0.fixed_ip_v4']
|
||||
|
||||
if 'metadata.use_access_ip' in raw_attrs and raw_attrs['metadata.use_access_ip'] == "0":
|
||||
attrs.pop('access_ip')
|
||||
|
||||
try:
|
||||
if 'metadata.prefer_ipv6' in raw_attrs and raw_attrs['metadata.prefer_ipv6'] == "1":
|
||||
attrs.update({
|
||||
@ -307,7 +319,9 @@ def openstack_host(resource, module_name):
|
||||
|
||||
# attrs specific to Ansible
|
||||
if 'metadata.ssh_user' in raw_attrs:
|
||||
attrs['ansible_ssh_user'] = raw_attrs['metadata.ssh_user']
|
||||
attrs['ansible_user'] = raw_attrs['metadata.ssh_user']
|
||||
if 'metadata.ssh_port' in raw_attrs:
|
||||
attrs['ansible_port'] = raw_attrs['metadata.ssh_port']
|
||||
|
||||
if 'volume.#' in list(raw_attrs.keys()) and int(raw_attrs['volume.#']) > 0:
|
||||
device_index = 1
|
||||
@ -334,6 +348,8 @@ def openstack_host(resource, module_name):
|
||||
for group in attrs['metadata'].get('kubespray_groups', "").split(","):
|
||||
groups.append(group)
|
||||
|
||||
sanitize_groups(groups)
|
||||
|
||||
return name, attrs, groups
|
||||
|
||||
|
||||
|
@ -136,4 +136,8 @@ terraform destroy --var-file cluster-settings.tfvars \
|
||||
* `loadbalancer_plan`: Plan to use for load balancer *(development|production-small)*
|
||||
* `loadbalancers`: Ports to load balance and which machines to forward to. Key of this object will be used as the name of the load balancer frontends/backends
|
||||
* `port`: Port to load balance.
|
||||
* `target_port`: Port to the backend servers.
|
||||
* `backend_servers`: List of servers that traffic to the port should be forwarded to.
|
||||
* `server_groups`: Group servers together
|
||||
* `servers`: The servers that should be included in the group.
|
||||
* `anti_affinity`: If anti-affinity should be enabled, try to spread the VMs out on separate nodes.
|
||||
|
@ -121,6 +121,7 @@ loadbalancer_plan = "development"
|
||||
loadbalancers = {
|
||||
# "http" : {
|
||||
# "port" : 80,
|
||||
# "target_port" : 80,
|
||||
# "backend_servers" : [
|
||||
# "worker-0",
|
||||
# "worker-1",
|
||||
@ -128,3 +129,20 @@ loadbalancers = {
|
||||
# ]
|
||||
# }
|
||||
}
|
||||
|
||||
server_groups = {
|
||||
# "control-plane" = {
|
||||
# servers = [
|
||||
# "master-0"
|
||||
# ]
|
||||
# anti_affinity = true
|
||||
# },
|
||||
# "workers" = {
|
||||
# servers = [
|
||||
# "worker-0",
|
||||
# "worker-1",
|
||||
# "worker-2"
|
||||
# ]
|
||||
# anti_affinity = true
|
||||
# }
|
||||
}
|
@ -34,6 +34,8 @@ module "kubernetes" {
|
||||
loadbalancer_enabled = var.loadbalancer_enabled
|
||||
loadbalancer_plan = var.loadbalancer_plan
|
||||
loadbalancers = var.loadbalancers
|
||||
|
||||
server_groups = var.server_groups
|
||||
}
|
||||
|
||||
#
|
||||
|
@ -13,7 +13,7 @@ locals {
|
||||
lb_backend_servers = flatten([
|
||||
for lb_name, loadbalancer in var.loadbalancers : [
|
||||
for backend_server in loadbalancer.backend_servers : {
|
||||
port = loadbalancer.port
|
||||
port = loadbalancer.target_port
|
||||
lb_name = lb_name
|
||||
server_name = backend_server
|
||||
}
|
||||
@ -548,3 +548,11 @@ resource "upcloud_loadbalancer_static_backend_member" "lb_backend_member" {
|
||||
max_sessions = var.loadbalancer_plan == "production-small" ? 50000 : 1000
|
||||
enabled = true
|
||||
}
|
||||
|
||||
resource "upcloud_server_group" "server_groups" {
|
||||
for_each = var.server_groups
|
||||
title = each.key
|
||||
anti_affinity = each.value.anti_affinity
|
||||
labels = {}
|
||||
members = [for server in each.value.servers : merge(upcloud_server.master, upcloud_server.worker)[server].id]
|
||||
}
|
@ -90,6 +90,16 @@ variable "loadbalancers" {
|
||||
|
||||
type = map(object({
|
||||
port = number
|
||||
target_port = number
|
||||
backend_servers = list(string)
|
||||
}))
|
||||
}
|
||||
|
||||
variable "server_groups" {
|
||||
description = "Server groups"
|
||||
|
||||
type = map(object({
|
||||
anti_affinity = bool
|
||||
servers = list(string)
|
||||
}))
|
||||
}
|
@ -3,7 +3,7 @@ terraform {
|
||||
required_providers {
|
||||
upcloud = {
|
||||
source = "UpCloudLtd/upcloud"
|
||||
version = "~>2.5.0"
|
||||
version = "~>2.7.1"
|
||||
}
|
||||
}
|
||||
required_version = ">= 0.13"
|
||||
|
@ -122,6 +122,7 @@ loadbalancer_plan = "development"
|
||||
loadbalancers = {
|
||||
# "http" : {
|
||||
# "port" : 80,
|
||||
# "target_port" : 80,
|
||||
# "backend_servers" : [
|
||||
# "worker-0",
|
||||
# "worker-1",
|
||||
@ -129,3 +130,20 @@ loadbalancers = {
|
||||
# ]
|
||||
# }
|
||||
}
|
||||
|
||||
server_groups = {
|
||||
# "control-plane" = {
|
||||
# servers = [
|
||||
# "master-0"
|
||||
# ]
|
||||
# anti_affinity = true
|
||||
# },
|
||||
# "workers" = {
|
||||
# servers = [
|
||||
# "worker-0",
|
||||
# "worker-1",
|
||||
# "worker-2"
|
||||
# ]
|
||||
# anti_affinity = true
|
||||
# }
|
||||
}
|
@ -126,7 +126,19 @@ variable "loadbalancers" {
|
||||
|
||||
type = map(object({
|
||||
port = number
|
||||
target_port = number
|
||||
backend_servers = list(string)
|
||||
}))
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "server_groups" {
|
||||
description = "Server groups"
|
||||
|
||||
type = map(object({
|
||||
anti_affinity = bool
|
||||
servers = list(string)
|
||||
}))
|
||||
|
||||
default = {}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ terraform {
|
||||
required_providers {
|
||||
upcloud = {
|
||||
source = "UpCloudLtd/upcloud"
|
||||
version = "~>2.5.0"
|
||||
version = "~>2.7.1"
|
||||
}
|
||||
}
|
||||
required_version = ">= 0.13"
|
||||
|
@ -38,7 +38,7 @@
|
||||
* [Kylin Linux Advanced Server V10](docs/kylinlinux.md)
|
||||
* [Amazon Linux 2](docs/amazonlinux.md)
|
||||
* [UOS Linux](docs/uoslinux.md)
|
||||
* [openEuler notes](docs/openeuler.md))
|
||||
* [openEuler notes](docs/openeuler.md)
|
||||
* CRI
|
||||
* [Containerd](docs/containerd.md)
|
||||
* [Docker](docs/docker.md)
|
||||
|
252
docs/ansible.md
252
docs/ansible.md
@ -15,9 +15,6 @@ virtualenv --python=$(which python3) $VENVDIR
|
||||
source $VENVDIR/bin/activate
|
||||
cd $KUBESPRAYDIR
|
||||
pip install -U -r requirements-$ANSIBLE_VERSION.txt
|
||||
test -f requirements-$ANSIBLE_VERSION.yml && \
|
||||
ansible-galaxy role install -r requirements-$ANSIBLE_VERSION.yml && \
|
||||
ansible-galaxy collection -r requirements-$ANSIBLE_VERSION.yml
|
||||
```
|
||||
|
||||
### Ansible Python Compatibility
|
||||
@ -25,7 +22,7 @@ test -f requirements-$ANSIBLE_VERSION.yml && \
|
||||
Based on the table below and the available python version for your ansible host you should choose the appropriate ansible version to use with kubespray.
|
||||
|
||||
| Ansible Version | Python Version |
|
||||
| --------------- | -------------- |
|
||||
|-----------------|----------------|
|
||||
| 2.11 | 2.7,3.5-3.9 |
|
||||
| 2.12 | 3.8-3.10 |
|
||||
|
||||
@ -104,135 +101,134 @@ the `-e` runtime flags (most simple way) or other layers described in the docs.
|
||||
Kubespray uses only a few layers to override things (or expect them to
|
||||
be overridden for roles):
|
||||
|
||||
Layer | Comment
|
||||
------|--------
|
||||
**role defaults** | provides best UX to override things for Kubespray deployments
|
||||
inventory vars | Unused
|
||||
**inventory group_vars** | Expects users to use ``all.yml``,``k8s_cluster.yml`` etc. to override things
|
||||
inventory host_vars | Unused
|
||||
playbook group_vars | Unused
|
||||
playbook host_vars | Unused
|
||||
**host facts** | Kubespray overrides for internal roles' logic, like state flags
|
||||
play vars | Unused
|
||||
play vars_prompt | Unused
|
||||
play vars_files | Unused
|
||||
registered vars | Unused
|
||||
set_facts | Kubespray overrides those, for some places
|
||||
**role and include vars** | Provides bad UX to override things! Use extra vars to enforce
|
||||
block vars (only for tasks in block) | Kubespray overrides for internal roles' logic
|
||||
task vars (only for the task) | Unused for roles, but only for helper scripts
|
||||
**extra vars** (always win precedence) | override with ``ansible-playbook -e @foo.yml``
|
||||
| Layer | Comment |
|
||||
|----------------------------------------|------------------------------------------------------------------------------|
|
||||
| **role defaults** | provides best UX to override things for Kubespray deployments |
|
||||
| inventory vars | Unused |
|
||||
| **inventory group_vars** | Expects users to use ``all.yml``,``k8s_cluster.yml`` etc. to override things |
|
||||
| inventory host_vars | Unused |
|
||||
| playbook group_vars | Unused |
|
||||
| playbook host_vars | Unused |
|
||||
| **host facts** | Kubespray overrides for internal roles' logic, like state flags |
|
||||
| play vars | Unused |
|
||||
| play vars_prompt | Unused |
|
||||
| play vars_files | Unused |
|
||||
| registered vars | Unused |
|
||||
| set_facts | Kubespray overrides those, for some places |
|
||||
| **role and include vars** | Provides bad UX to override things! Use extra vars to enforce |
|
||||
| block vars (only for tasks in block) | Kubespray overrides for internal roles' logic |
|
||||
| task vars (only for the task) | Unused for roles, but only for helper scripts |
|
||||
| **extra vars** (always win precedence) | override with ``ansible-playbook -e @foo.yml`` |
|
||||
|
||||
## Ansible tags
|
||||
|
||||
The following tags are defined in playbooks:
|
||||
|
||||
| Tag name | Used for
|
||||
|--------------------------------|---------
|
||||
| annotate | Create kube-router annotation
|
||||
| apps | K8s apps definitions
|
||||
| asserts | Check tasks for download role
|
||||
| aws-ebs-csi-driver | Configuring csi driver: aws-ebs
|
||||
| azure-csi-driver | Configuring csi driver: azure
|
||||
| bastion | Setup ssh config for bastion
|
||||
| bootstrap-os | Anything related to host OS configuration
|
||||
| calico | Network plugin Calico
|
||||
| calico_rr | Configuring Calico route reflector
|
||||
| canal | Network plugin Canal
|
||||
| cephfs-provisioner | Configuring CephFS
|
||||
| cert-manager | Configuring certificate manager for K8s
|
||||
| cilium | Network plugin Cilium
|
||||
| cinder-csi-driver | Configuring csi driver: cinder
|
||||
| client | Kubernetes clients role
|
||||
| cloud-provider | Cloud-provider related tasks
|
||||
| cluster-roles | Configuring cluster wide application (psp ...)
|
||||
| cni | CNI plugins for Network Plugins
|
||||
| containerd | Configuring containerd engine runtime for hosts
|
||||
| container_engine_accelerator | Enable nvidia accelerator for runtimes
|
||||
| container-engine | Configuring container engines
|
||||
| container-runtimes | Configuring container runtimes
|
||||
| coredns | Configuring coredns deployment
|
||||
| crio | Configuring crio container engine for hosts
|
||||
| crun | Configuring crun runtime
|
||||
| csi-driver | Configuring csi driver
|
||||
| dashboard | Installing and configuring the Kubernetes Dashboard
|
||||
| dns | Remove dns entries when resetting
|
||||
| docker | Configuring docker engine runtime for hosts
|
||||
| download | Fetching container images to a delegate host
|
||||
| etcd | Configuring etcd cluster
|
||||
| etcd-secrets | Configuring etcd certs/keys
|
||||
| etchosts | Configuring /etc/hosts entries for hosts
|
||||
| external-cloud-controller | Configure cloud controllers
|
||||
| external-openstack | Cloud controller : openstack
|
||||
| external-provisioner | Configure external provisioners
|
||||
| external-vsphere | Cloud controller : vsphere
|
||||
| facts | Gathering facts and misc check results
|
||||
| files | Remove files when resetting
|
||||
| flannel | Network plugin flannel
|
||||
| gce | Cloud-provider GCP
|
||||
| gcp-pd-csi-driver | Configuring csi driver: gcp-pd
|
||||
| gvisor | Configuring gvisor runtime
|
||||
| helm | Installing and configuring Helm
|
||||
| ingress-controller | Configure ingress controllers
|
||||
| ingress_alb | AWS ALB Ingress Controller
|
||||
| init | Windows kubernetes init nodes
|
||||
| iptables | Flush and clear iptable when resetting
|
||||
| k8s-pre-upgrade | Upgrading K8s cluster
|
||||
| k8s-secrets | Configuring K8s certs/keys
|
||||
| k8s-gen-tokens | Configuring K8s tokens
|
||||
| kata-containers | Configuring kata-containers runtime
|
||||
| krew | Install and manage krew
|
||||
| kubeadm | Roles linked to kubeadm tasks
|
||||
| kube-apiserver | Configuring static pod kube-apiserver
|
||||
| kube-controller-manager | Configuring static pod kube-controller-manager
|
||||
| kube-vip | Installing and configuring kube-vip
|
||||
| kubectl | Installing kubectl and bash completion
|
||||
| kubelet | Configuring kubelet service
|
||||
| kube-ovn | Network plugin kube-ovn
|
||||
| kube-router | Network plugin kube-router
|
||||
| kube-proxy | Configuring static pod kube-proxy
|
||||
| localhost | Special steps for the localhost (ansible runner)
|
||||
| local-path-provisioner | Configure External provisioner: local-path
|
||||
| local-volume-provisioner | Configure External provisioner: local-volume
|
||||
| macvlan | Network plugin macvlan
|
||||
| master | Configuring K8s master node role
|
||||
| metallb | Installing and configuring metallb
|
||||
| metrics_server | Configuring metrics_server
|
||||
| netchecker | Installing netchecker K8s app
|
||||
| network | Configuring networking plugins for K8s
|
||||
| mounts | Umount kubelet dirs when reseting
|
||||
| multus | Network plugin multus
|
||||
| nginx | Configuring LB for kube-apiserver instances
|
||||
| node | Configuring K8s minion (compute) node role
|
||||
| nodelocaldns | Configuring nodelocaldns daemonset
|
||||
| node-label | Tasks linked to labeling of nodes
|
||||
| node-webhook | Tasks linked to webhook (grating access to resources)
|
||||
| nvidia_gpu | Enable nvidia accelerator for runtimes
|
||||
| oci | Cloud provider: oci
|
||||
| persistent_volumes | Configure csi volumes
|
||||
| persistent_volumes_aws_ebs_csi | Configuring csi driver: aws-ebs
|
||||
| persistent_volumes_cinder_csi | Configuring csi driver: cinder
|
||||
| persistent_volumes_gcp_pd_csi | Configuring csi driver: gcp-pd
|
||||
| persistent_volumes_openstack | Configuring csi driver: openstack
|
||||
| policy-controller | Configuring Calico policy controller
|
||||
| post-remove | Tasks running post-remove operation
|
||||
| post-upgrade | Tasks running post-upgrade operation
|
||||
| pre-remove | Tasks running pre-remove operation
|
||||
| pre-upgrade | Tasks running pre-upgrade operation
|
||||
| preinstall | Preliminary configuration steps
|
||||
| registry | Configuring local docker registry
|
||||
| reset | Tasks running doing the node reset
|
||||
| resolvconf | Configuring /etc/resolv.conf for hosts/apps
|
||||
| rbd-provisioner | Configure External provisioner: rdb
|
||||
| services | Remove services (etcd, kubelet etc...) when resetting
|
||||
| snapshot | Enabling csi snapshot
|
||||
| snapshot-controller | Configuring csi snapshot controller
|
||||
| upgrade | Upgrading, f.e. container images/binaries
|
||||
| upload | Distributing images/binaries across hosts
|
||||
| vsphere-csi-driver | Configuring csi driver: vsphere
|
||||
| weave | Network plugin Weave
|
||||
| win_nodes | Running windows specific tasks
|
||||
| youki | Configuring youki runtime
|
||||
| Tag name | Used for |
|
||||
|--------------------------------|-------------------------------------------------------|
|
||||
| annotate | Create kube-router annotation |
|
||||
| apps | K8s apps definitions |
|
||||
| asserts | Check tasks for download role |
|
||||
| aws-ebs-csi-driver | Configuring csi driver: aws-ebs |
|
||||
| azure-csi-driver | Configuring csi driver: azure |
|
||||
| bastion | Setup ssh config for bastion |
|
||||
| bootstrap-os | Anything related to host OS configuration |
|
||||
| calico | Network plugin Calico |
|
||||
| calico_rr | Configuring Calico route reflector |
|
||||
| cephfs-provisioner | Configuring CephFS |
|
||||
| cert-manager | Configuring certificate manager for K8s |
|
||||
| cilium | Network plugin Cilium |
|
||||
| cinder-csi-driver | Configuring csi driver: cinder |
|
||||
| client | Kubernetes clients role |
|
||||
| cloud-provider | Cloud-provider related tasks |
|
||||
| cluster-roles | Configuring cluster wide application (psp ...) |
|
||||
| cni | CNI plugins for Network Plugins |
|
||||
| containerd | Configuring containerd engine runtime for hosts |
|
||||
| container_engine_accelerator | Enable nvidia accelerator for runtimes |
|
||||
| container-engine | Configuring container engines |
|
||||
| container-runtimes | Configuring container runtimes |
|
||||
| coredns | Configuring coredns deployment |
|
||||
| crio | Configuring crio container engine for hosts |
|
||||
| crun | Configuring crun runtime |
|
||||
| csi-driver | Configuring csi driver |
|
||||
| dashboard | Installing and configuring the Kubernetes Dashboard |
|
||||
| dns | Remove dns entries when resetting |
|
||||
| docker | Configuring docker engine runtime for hosts |
|
||||
| download | Fetching container images to a delegate host |
|
||||
| etcd | Configuring etcd cluster |
|
||||
| etcd-secrets | Configuring etcd certs/keys |
|
||||
| etchosts | Configuring /etc/hosts entries for hosts |
|
||||
| external-cloud-controller | Configure cloud controllers |
|
||||
| external-openstack | Cloud controller : openstack |
|
||||
| external-provisioner | Configure external provisioners |
|
||||
| external-vsphere | Cloud controller : vsphere |
|
||||
| facts | Gathering facts and misc check results |
|
||||
| files | Remove files when resetting |
|
||||
| flannel | Network plugin flannel |
|
||||
| gce | Cloud-provider GCP |
|
||||
| gcp-pd-csi-driver | Configuring csi driver: gcp-pd |
|
||||
| gvisor | Configuring gvisor runtime |
|
||||
| helm | Installing and configuring Helm |
|
||||
| ingress-controller | Configure ingress controllers |
|
||||
| ingress_alb | AWS ALB Ingress Controller |
|
||||
| init | Windows kubernetes init nodes |
|
||||
| iptables | Flush and clear iptable when resetting |
|
||||
| k8s-pre-upgrade | Upgrading K8s cluster |
|
||||
| k8s-secrets | Configuring K8s certs/keys |
|
||||
| k8s-gen-tokens | Configuring K8s tokens |
|
||||
| kata-containers | Configuring kata-containers runtime |
|
||||
| krew | Install and manage krew |
|
||||
| kubeadm | Roles linked to kubeadm tasks |
|
||||
| kube-apiserver | Configuring static pod kube-apiserver |
|
||||
| kube-controller-manager | Configuring static pod kube-controller-manager |
|
||||
| kube-vip | Installing and configuring kube-vip |
|
||||
| kubectl | Installing kubectl and bash completion |
|
||||
| kubelet | Configuring kubelet service |
|
||||
| kube-ovn | Network plugin kube-ovn |
|
||||
| kube-router | Network plugin kube-router |
|
||||
| kube-proxy | Configuring static pod kube-proxy |
|
||||
| localhost | Special steps for the localhost (ansible runner) |
|
||||
| local-path-provisioner | Configure External provisioner: local-path |
|
||||
| local-volume-provisioner | Configure External provisioner: local-volume |
|
||||
| macvlan | Network plugin macvlan |
|
||||
| master | Configuring K8s master node role |
|
||||
| metallb | Installing and configuring metallb |
|
||||
| metrics_server | Configuring metrics_server |
|
||||
| netchecker | Installing netchecker K8s app |
|
||||
| network | Configuring networking plugins for K8s |
|
||||
| mounts | Umount kubelet dirs when reseting |
|
||||
| multus | Network plugin multus |
|
||||
| nginx | Configuring LB for kube-apiserver instances |
|
||||
| node | Configuring K8s minion (compute) node role |
|
||||
| nodelocaldns | Configuring nodelocaldns daemonset |
|
||||
| node-label | Tasks linked to labeling of nodes |
|
||||
| node-webhook | Tasks linked to webhook (grating access to resources) |
|
||||
| nvidia_gpu | Enable nvidia accelerator for runtimes |
|
||||
| oci | Cloud provider: oci |
|
||||
| persistent_volumes | Configure csi volumes |
|
||||
| persistent_volumes_aws_ebs_csi | Configuring csi driver: aws-ebs |
|
||||
| persistent_volumes_cinder_csi | Configuring csi driver: cinder |
|
||||
| persistent_volumes_gcp_pd_csi | Configuring csi driver: gcp-pd |
|
||||
| persistent_volumes_openstack | Configuring csi driver: openstack |
|
||||
| policy-controller | Configuring Calico policy controller |
|
||||
| post-remove | Tasks running post-remove operation |
|
||||
| post-upgrade | Tasks running post-upgrade operation |
|
||||
| pre-remove | Tasks running pre-remove operation |
|
||||
| pre-upgrade | Tasks running pre-upgrade operation |
|
||||
| preinstall | Preliminary configuration steps |
|
||||
| registry | Configuring local docker registry |
|
||||
| reset | Tasks running doing the node reset |
|
||||
| resolvconf | Configuring /etc/resolv.conf for hosts/apps |
|
||||
| rbd-provisioner | Configure External provisioner: rdb |
|
||||
| services | Remove services (etcd, kubelet etc...) when resetting |
|
||||
| snapshot | Enabling csi snapshot |
|
||||
| snapshot-controller | Configuring csi snapshot controller |
|
||||
| upgrade | Upgrading, f.e. container images/binaries |
|
||||
| upload | Distributing images/binaries across hosts |
|
||||
| vsphere-csi-driver | Configuring csi driver: vsphere |
|
||||
| weave | Network plugin Weave |
|
||||
| win_nodes | Running windows specific tasks |
|
||||
| youki | Configuring youki runtime |
|
||||
|
||||
Note: Use the ``bash scripts/gen_tags.sh`` command to generate a list of all
|
||||
tags found in the codebase. New tags will be listed with the empty "Used for"
|
||||
|
38
docs/ansible_collection.md
Normal file
38
docs/ansible_collection.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Ansible collection
|
||||
|
||||
Kubespray can be installed as an [Ansible collection](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html).
|
||||
|
||||
## Requirements
|
||||
|
||||
- An inventory file with the appropriate host groups. See the [README](../README.md#usage).
|
||||
- A `group_vars` directory. These group variables **need** to match the appropriate variable names under `inventory/local/group_vars`. See the [README](../README.md#usage).
|
||||
|
||||
## Usage
|
||||
|
||||
1. Add Kubespray to your requirements.yml file
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
- name: https://github.com/kubernetes-sigs/kubespray
|
||||
type: git
|
||||
version: v2.21.0
|
||||
```
|
||||
|
||||
2. Install your collection
|
||||
|
||||
```ShellSession
|
||||
ansible-galaxy install -r requirements.yml
|
||||
```
|
||||
|
||||
3. Create a playbook to install your Kubernetes cluster
|
||||
|
||||
```yaml
|
||||
- name: Install Kubernetes
|
||||
ansible.builtin.import_playbook: kubernetes_sigs.kubespray.cluster
|
||||
```
|
||||
|
||||
4. Update INVENTORY and PLAYBOOK so that they point to your inventory file and the playbook you created above, and then install Kubespray
|
||||
|
||||
```ShellSession
|
||||
ansible-playbook -i INVENTORY --become --become-user=root PLAYBOOK
|
||||
```
|
@ -7,7 +7,7 @@ The following table shows the impact of the CPU architecture on compatible featu
|
||||
- amd64 + arm64: Cluster with a mix of x86/amd64 and arm64 CPUs
|
||||
|
||||
| kube_network_plugin | amd64 | arm64 | amd64 + arm64 |
|
||||
| ------------------- | ----- | ----- | ------------- |
|
||||
|---------------------|-------|-------|---------------|
|
||||
| Calico | Y | Y | Y |
|
||||
| Weave | Y | Y | Y |
|
||||
| Flannel | Y | N | N |
|
||||
|
24
docs/aws.md
24
docs/aws.md
@ -67,15 +67,15 @@ export REGION="us-east-2"
|
||||
|
||||
Declare the cloud config variables for the `aws` provider as follows. Setting these variables are optional and depend on your use case.
|
||||
|
||||
Variable|Type|Comment
|
||||
---|---|---
|
||||
aws_zone|string|Force set the AWS zone. Recommended to leave blank.
|
||||
aws_vpc|string|The AWS VPC flag enables the possibility to run the master components on a different aws account, on a different cloud provider or on-premise. If the flag is set also the KubernetesClusterTag must be provided
|
||||
aws_subnet_id|string|SubnetID enables using a specific subnet to use for ELB's
|
||||
aws_route_table_id|string|RouteTableID enables using a specific RouteTable
|
||||
aws_role_arn|string|RoleARN is the IAM role to assume when interaction with AWS APIs
|
||||
aws_kubernetes_cluster_tag|string|KubernetesClusterTag is the legacy cluster id we'll use to identify our cluster resources
|
||||
aws_kubernetes_cluster_id|string|KubernetesClusterID is the cluster id we'll use to identify our cluster resources
|
||||
aws_disable_security_group_ingress|bool|The aws provider creates an inbound rule per load balancer on the node security group. However, this can run into the AWS security group rule limit of 50 if many LoadBalancers are created. This flag disables the automatic ingress creation. It requires that the user has setup a rule that allows inbound traffic on kubelet ports from the local VPC subnet (so load balancers can access it). E.g. 10.82.0.0/16 30000-32000.
|
||||
aws_elb_security_group|string|Only in Kubelet version >= 1.7 : AWS has a hard limit of 500 security groups. For large clusters creating a security group for each ELB can cause the max number of security groups to be reached. If this is set instead of creating a new Security group for each ELB this security group will be used instead.
|
||||
aws_disable_strict_zone_check|bool|During the instantiation of an new AWS cloud provider, the detected region is validated against a known set of regions. In a non-standard, AWS like environment (e.g. Eucalyptus), this check may be undesirable. Setting this to true will disable the check and provide a warning that the check was skipped. Please note that this is an experimental feature and work-in-progress for the moment.
|
||||
| Variable | Type | Comment |
|
||||
|------------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| aws_zone | string | Force set the AWS zone. Recommended to leave blank. |
|
||||
| aws_vpc | string | The AWS VPC flag enables the possibility to run the master components on a different aws account, on a different cloud provider or on-premise. If the flag is set also the KubernetesClusterTag must be provided |
|
||||
| aws_subnet_id | string | SubnetID enables using a specific subnet to use for ELB's |
|
||||
| aws_route_table_id | string | RouteTableID enables using a specific RouteTable |
|
||||
| aws_role_arn | string | RoleARN is the IAM role to assume when interaction with AWS APIs |
|
||||
| aws_kubernetes_cluster_tag | string | KubernetesClusterTag is the legacy cluster id we'll use to identify our cluster resources |
|
||||
| aws_kubernetes_cluster_id | string | KubernetesClusterID is the cluster id we'll use to identify our cluster resources |
|
||||
| aws_disable_security_group_ingress | bool | The aws provider creates an inbound rule per load balancer on the node security group. However, this can run into the AWS security group rule limit of 50 if many LoadBalancers are created. This flag disables the automatic ingress creation. It requires that the user has setup a rule that allows inbound traffic on kubelet ports from the local VPC subnet (so load balancers can access it). E.g. 10.82.0.0/16 30000-32000. |
|
||||
| aws_elb_security_group | string | Only in Kubelet version >= 1.7 : AWS has a hard limit of 500 security groups. For large clusters creating a security group for each ELB can cause the max number of security groups to be reached. If this is set instead of creating a new Security group for each ELB this security group will be used instead. |
|
||||
| aws_disable_strict_zone_check | bool | During the instantiation of an new AWS cloud provider, the detected region is validated against a known set of regions. In a non-standard, AWS like environment (e.g. Eucalyptus), this check may be undesirable. Setting this to true will disable the check and provide a warning that the check was skipped. Please note that this is an experimental feature and work-in-progress for the moment. |
|
||||
|
@ -14,7 +14,7 @@ If you want to deploy the Azure Disk storage class to provision volumes dynamica
|
||||
|
||||
Before creating the instances you must first set the `azure_csi_` variables in the `group_vars/all.yml` file.
|
||||
|
||||
All of the values can be retrieved using the azure cli tool which can be downloaded here: <https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest>
|
||||
All values can be retrieved using the azure cli tool which can be downloaded here: <https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest>
|
||||
|
||||
After installation you have to run `az login` to get access to your account.
|
||||
|
||||
@ -34,7 +34,7 @@ The name of the resource group your instances are in, a list of your resource gr
|
||||
|
||||
Or you can do `az vm list | grep resourceGroup` and get the resource group corresponding to the VMs of your cluster.
|
||||
|
||||
The resource group name is not case sensitive.
|
||||
The resource group name is not case-sensitive.
|
||||
|
||||
### azure\_csi\_vnet\_name
|
||||
|
||||
|
@ -10,7 +10,7 @@ Not all features are supported yet though, for a list of the current status have
|
||||
|
||||
Before creating the instances you must first set the `azure_` variables in the `group_vars/all/all.yml` file.
|
||||
|
||||
All of the values can be retrieved using the Azure CLI tool which can be downloaded here: <https://docs.microsoft.com/en-gb/cli/azure/install-azure-cli>
|
||||
All values can be retrieved using the Azure CLI tool which can be downloaded here: <https://docs.microsoft.com/en-gb/cli/azure/install-azure-cli>
|
||||
After installation you have to run `az login` to get access to your account.
|
||||
|
||||
### azure_cloud
|
||||
|
@ -187,7 +187,7 @@ The inventory above will deploy the following topology assuming that calico's
|
||||
|
||||
### Optional : Define default endpoint to host action
|
||||
|
||||
By default Calico blocks traffic from endpoints to the host itself by using an iptables DROP action. When using it in kubernetes the action has to be changed to RETURN (default in kubespray) or ACCEPT (see <https://github.com/projectcalico/felix/issues/660> and <https://github.com/projectcalico/calicoctl/issues/1389).> Otherwise all network packets from pods (with hostNetwork=False) to services endpoints (with hostNetwork=True) within the same node are dropped.
|
||||
By default Calico blocks traffic from endpoints to the host itself by using an iptables DROP action. When using it in kubernetes the action has to be changed to RETURN (default in kubespray) or ACCEPT (see <https://docs.tigera.io/calico/latest/network-policy/hosts/protect-hosts#control-default-behavior-of-workload-endpoint-to-host-traffic> ) Otherwise all network packets from pods (with hostNetwork=False) to services endpoints (with hostNetwork=True) within the same node are dropped.
|
||||
|
||||
To re-define default action please set the following variable in your inventory:
|
||||
|
||||
@ -376,12 +376,7 @@ Calico node, typha and kube-controllers need to be able to talk to the kubernete
|
||||
|
||||
Kubespray sets up the `kubernetes-services-endpoint` configmap based on the contents of the `loadbalancer_apiserver` inventory variable documented in [HA Mode](/docs/ha-mode.md).
|
||||
|
||||
If no external loadbalancer is used, Calico eBPF can also use the localhost loadbalancer option. In this case Calico Automatic Host Endpoints need to be enabled to allow services like `coredns` and `metrics-server` to communicate with the kubernetes host endpoint. See [this blog post](https://www.projectcalico.org/securing-kubernetes-nodes-with-calico-automatic-host-endpoints/) on enabling automatic host endpoints.
|
||||
|
||||
```yaml
|
||||
loadbalancer_apiserver_localhost: true
|
||||
use_localhost_as_kubeapi_loadbalancer: true
|
||||
```
|
||||
If no external loadbalancer is used, Calico eBPF can also use the localhost loadbalancer option. We are able to do so only if you use the same port for the localhost apiserver loadbalancer and the kube-apiserver. In this case Calico Automatic Host Endpoints need to be enabled to allow services like `coredns` and `metrics-server` to communicate with the kubernetes host endpoint. See [this blog post](https://www.projectcalico.org/securing-kubernetes-nodes-with-calico-automatic-host-endpoints/) on enabling automatic host endpoints.
|
||||
|
||||
### Tunneled versus Direct Server Return
|
||||
|
||||
|
@ -114,7 +114,7 @@ sudo apt-get install -y golang-cfssl
|
||||
|
||||
#### Create Root Certificate Authority (CA) Configuration File
|
||||
|
||||
The default TLS certificate expiry time period is `8760h` which is 5 years from the date the certificate is created.
|
||||
The default TLS certificate expiry time period is `8760h` which is 1 years from the date the certificate is created.
|
||||
|
||||
```shell
|
||||
$ cat > ca-config.json <<EOF
|
||||
|
193
docs/ci-setup.md
193
docs/ci-setup.md
@ -2,18 +2,19 @@
|
||||
|
||||
## Pipeline
|
||||
|
||||
1. unit-tests: fast jobs for fast feedback (linting, etc...)
|
||||
2. deploy-part1: small number of jobs to test if the PR works with default settings
|
||||
3. deploy-part2: slow jobs testing different platforms, OS, settings, CNI, etc...
|
||||
4. deploy-part3: very slow jobs (upgrades, etc...)
|
||||
1. build: build a docker image to be used in the pipeline
|
||||
2. unit-tests: fast jobs for fast feedback (linting, etc...)
|
||||
3. deploy-part1: small number of jobs to test if the PR works with default settings
|
||||
4. deploy-part2: slow jobs testing different platforms, OS, settings, CNI, etc...
|
||||
5. deploy-part3: very slow jobs (upgrades, etc...)
|
||||
|
||||
## Runners
|
||||
|
||||
Kubespray has 3 types of GitLab runners:
|
||||
|
||||
- packet runners: used for E2E jobs (usually long)
|
||||
- light runners: used for short lived jobs
|
||||
- auto scaling runners: used for on-demand resources, see [GitLab docs](https://docs.gitlab.com/runner/configuration/autoscale.html) for more info
|
||||
- packet runners: used for E2E jobs (usually long), running on Equinix Metal (ex-packet), on kubevirt managed VMs
|
||||
- light runners: used for short lived jobs, running on Equinix Metal (ex-packet), as managed pods
|
||||
- auto scaling runners (managed via docker-machine on Equinix Metal): used for on-demand resources, see [GitLab docs](https://docs.gitlab.com/runner/configuration/autoscale.html) for more info
|
||||
|
||||
## Vagrant
|
||||
|
||||
@ -25,3 +26,181 @@ In CI we have a set of overrides we use to ensure greater success of our CI jobs
|
||||
|
||||
- [Docker mirrors](/tests/common/_docker_hub_registry_mirror.yml)
|
||||
- [Test settings](/tests/common/_kubespray_test_settings.yml)
|
||||
|
||||
## CI Environment
|
||||
|
||||
The CI packet and light runners are deployed on a kubernetes cluster on Equinix Metal. The cluster is deployed with kubespray itself and maintained by the kubespray maintainers.
|
||||
|
||||
The following files are used for that inventory:
|
||||
|
||||
### cluster.tfvars
|
||||
|
||||
```ini
|
||||
# your Kubernetes cluster name here
|
||||
cluster_name = "ci"
|
||||
|
||||
# Your Equinix Metal project ID. See https://metal.equinix.com/developers/docs/accounts/
|
||||
equinix_metal_project_id = "_redacted_"
|
||||
|
||||
# The public SSH key to be uploaded into authorized_keys in bare metal Equinix Metal nodes provisioned
|
||||
# leave this value blank if the public key is already setup in the Equinix Metal project
|
||||
# Terraform will complain if the public key is setup in Equinix Metal
|
||||
public_key_path = "~/.ssh/id_rsa.pub"
|
||||
|
||||
# cluster location
|
||||
metro = "da"
|
||||
|
||||
# standalone etcds
|
||||
number_of_etcd = 0
|
||||
|
||||
plan_etcd = "t1.small.x86"
|
||||
|
||||
# masters
|
||||
number_of_k8s_masters = 1
|
||||
|
||||
number_of_k8s_masters_no_etcd = 0
|
||||
|
||||
plan_k8s_masters = "c3.small.x86"
|
||||
|
||||
plan_k8s_masters_no_etcd = "t1.small.x86"
|
||||
|
||||
# nodes
|
||||
number_of_k8s_nodes = 1
|
||||
|
||||
plan_k8s_nodes = "c3.medium.x86"
|
||||
```
|
||||
|
||||
### group_vars/all/mirrors.yml
|
||||
|
||||
```yaml
|
||||
---
|
||||
docker_registry_mirrors:
|
||||
- "https://mirror.gcr.io"
|
||||
|
||||
containerd_grpc_max_recv_message_size: 16777216
|
||||
containerd_grpc_max_send_message_size: 16777216
|
||||
|
||||
containerd_registries:
|
||||
"docker.io":
|
||||
- "https://mirror.gcr.io"
|
||||
- "https://registry-1.docker.io"
|
||||
|
||||
containerd_max_container_log_line_size: -1
|
||||
|
||||
crio_registries_mirrors:
|
||||
- prefix: docker.io
|
||||
insecure: false
|
||||
blocked: false
|
||||
location: registry-1.docker.io
|
||||
mirrors:
|
||||
- location: mirror.gcr.io
|
||||
insecure: false
|
||||
|
||||
netcheck_agent_image_repo: "{{ quay_image_repo }}/kubespray/k8s-netchecker-agent"
|
||||
netcheck_server_image_repo: "{{ quay_image_repo }}/kubespray/k8s-netchecker-server"
|
||||
|
||||
nginx_image_repo: "{{ quay_image_repo }}/kubespray/nginx"
|
||||
```
|
||||
|
||||
### group_vars/all/settings.yml
|
||||
|
||||
```yaml
|
||||
---
|
||||
# Networking setting
|
||||
kube_service_addresses: 172.30.0.0/18
|
||||
kube_pods_subnet: 172.30.64.0/18
|
||||
kube_network_plugin: calico
|
||||
# avoid overlap with CI jobs deploying nodelocaldns
|
||||
nodelocaldns_ip: 169.254.255.100
|
||||
|
||||
# ipip: False
|
||||
calico_ipip_mode: "Never"
|
||||
calico_vxlan_mode: "Never"
|
||||
calico_network_backend: "bird"
|
||||
calico_wireguard_enabled: True
|
||||
|
||||
# Cluster settings
|
||||
upgrade_cluster_setup: True
|
||||
force_certificate_regeneration: True
|
||||
|
||||
# Etcd settings
|
||||
etcd_deployment_type: "host"
|
||||
|
||||
# Kubernetes settings
|
||||
kube_controller_terminated_pod_gc_threshold: 100
|
||||
kubelet_enforce_node_allocatable: pods
|
||||
kubelet_preferred_address_types: 'InternalIP,ExternalIP,Hostname'
|
||||
kubelet_custom_flags:
|
||||
- "--serialize-image-pulls=true"
|
||||
- "--eviction-hard=memory.available<1Gi"
|
||||
- "--eviction-soft-grace-period=memory.available=30s"
|
||||
- "--eviction-soft=memory.available<2Gi"
|
||||
- "--system-reserved cpu=100m,memory=4Gi"
|
||||
- "--eviction-minimum-reclaim=memory.available=2Gi"
|
||||
|
||||
# DNS settings
|
||||
resolvconf_mode: none
|
||||
dns_min_replicas: 1
|
||||
upstream_dns_servers:
|
||||
- 1.1.1.1
|
||||
- 1.0.0.1
|
||||
|
||||
# Extensions
|
||||
ingress_nginx_enabled: True
|
||||
helm_enabled: True
|
||||
cert_manager_enabled: True
|
||||
metrics_server_enabled: True
|
||||
|
||||
# Enable ZSWAP
|
||||
kubelet_fail_swap_on: False
|
||||
kube_feature_gates:
|
||||
- "NodeSwap=True"
|
||||
```
|
||||
|
||||
## Aditional files
|
||||
|
||||
This section documents additional files used to complete a deployment of the kubespray CI, these files sit on the control-plane node and assume a working kubernetes cluster.
|
||||
|
||||
### /root/nscleanup.sh
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
kubectl=/usr/local/bin/kubectl
|
||||
|
||||
$kubectl get ns | grep -P "(\d.+-\d.+)" | awk 'match($3,/[0-9]+d/) {print $1}' | xargs -r $kubectl delete ns
|
||||
$kubectl get ns | grep -P "(\d.+-\d.+)" | awk 'match($3,/[3-9]+h/) {print $1}' | xargs -r $kubectl delete ns
|
||||
$kubectl get ns | grep Terminating | awk '{print $1}' | xargs -i $kubectl delete vmi/instance-1 vmi/instance-0 vmi/instance-2 -n {} --force --grace-period=0 &
|
||||
```
|
||||
|
||||
### /root/path-calico.sh
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
calicoctl patch felixconfig default -p '{"spec":{"allowIPIPPacketsFromWorkloads":true, "allowVXLANPacketsFromWorkloads": true}}'
|
||||
```
|
||||
|
||||
### /root/kubevirt/kubevirt.sh
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases | grep tag_name | grep -v -- '-rc' | sort -r | head -1 | awk -F': ' '{print $2}' | sed 's/,//' | xargs)
|
||||
echo $VERSION
|
||||
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml
|
||||
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml
|
||||
```
|
||||
|
||||
### /root/kubevirt/virtctl.sh
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
VERSION=$(kubectl get kubevirt.kubevirt.io/kubevirt -n kubevirt -o=jsonpath="{.status.observedKubeVirtVersion}")
|
||||
ARCH=$(uname -s | tr A-Z a-z)-$(uname -m | sed 's/x86_64/amd64/') || windows-amd64.exe
|
||||
echo ${ARCH}
|
||||
curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-${ARCH}
|
||||
chmod +x virtctl
|
||||
sudo install virtctl /usr/local/bin
|
||||
```
|
||||
|
25
docs/ci.md
25
docs/ci.md
@ -4,34 +4,32 @@ To generate this Matrix run `./tests/scripts/md-table/main.py`
|
||||
|
||||
## containerd
|
||||
|
||||
| OS / CNI | calico | canal | cilium | flannel | kube-ovn | kube-router | macvlan | weave |
|
||||
| OS / CNI | calico | cilium | custom_cni | flannel | kube-ovn | kube-router | macvlan | weave |
|
||||
|---| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
almalinux8 | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: |
|
||||
amazon | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
centos7 | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: | :white_check_mark: |
|
||||
debian10 | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||
debian11 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
debian9 | :x: | :x: | :x: | :x: | :x: | :x: | :white_check_mark: | :x: |
|
||||
centos7 | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: | :white_check_mark: |
|
||||
debian10 | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :white_check_mark: | :x: |
|
||||
debian11 | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||
fedora35 | :white_check_mark: | :x: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: |
|
||||
fedora36 | :x: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: |
|
||||
opensuse | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
opensuse | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
rockylinux8 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
rockylinux9 | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||
ubuntu16 | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: |
|
||||
ubuntu18 | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: |
|
||||
rockylinux9 | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
ubuntu16 | :x: | :x: | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: |
|
||||
ubuntu18 | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: |
|
||||
ubuntu20 | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: |
|
||||
ubuntu22 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
|
||||
## crio
|
||||
|
||||
| OS / CNI | calico | canal | cilium | flannel | kube-ovn | kube-router | macvlan | weave |
|
||||
| OS / CNI | calico | cilium | custom_cni | flannel | kube-ovn | kube-router | macvlan | weave |
|
||||
|---| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
almalinux8 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
amazon | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
centos7 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
debian10 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
debian11 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
debian9 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
fedora35 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
fedora36 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
opensuse | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
@ -44,17 +42,16 @@ ubuntu22 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
|
||||
## docker
|
||||
|
||||
| OS / CNI | calico | canal | cilium | flannel | kube-ovn | kube-router | macvlan | weave |
|
||||
| OS / CNI | calico | cilium | custom_cni | flannel | kube-ovn | kube-router | macvlan | weave |
|
||||
|---| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
almalinux8 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
amazon | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
centos7 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
debian10 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
debian11 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
debian9 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
fedora35 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
fedora36 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :white_check_mark: |
|
||||
opensuse | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||
opensuse | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
rockylinux8 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
rockylinux9 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
ubuntu16 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :white_check_mark: |
|
||||
|
@ -1,16 +1,59 @@
|
||||
# Cilium
|
||||
|
||||
## IP Address Management (IPAM)
|
||||
|
||||
IP Address Management (IPAM) is responsible for the allocation and management of IP addresses used by network endpoints (container and others) managed by Cilium. The default mode is "Cluster Scope".
|
||||
|
||||
You can set the following parameters, for example: cluster-pool, kubernetes:
|
||||
|
||||
```yml
|
||||
cilium_ipam_mode: cluster-pool
|
||||
```
|
||||
|
||||
### Set the cluster Pod CIDRs
|
||||
|
||||
Cluster Pod CIDRs use the kube_pods_subnet value by default.
|
||||
If your node network is in the same range you will lose connectivity to other nodes.
|
||||
Defaults to kube_pods_subnet if not set.
|
||||
You can set the following parameters:
|
||||
|
||||
```yml
|
||||
cilium_pool_cidr: 10.233.64.0/18
|
||||
```
|
||||
|
||||
When cilium_enable_ipv6 is used. Defaults to kube_pods_subnet_ipv6 if not set.
|
||||
you need to set the IPV6 value:
|
||||
|
||||
```yml
|
||||
cilium_pool_cidr_ipv6: fd85:ee78:d8a6:8607::1:0000/112
|
||||
```
|
||||
|
||||
### Set the Pod CIDR size of a node
|
||||
|
||||
When cilium IPAM uses the "Cluster Scope" mode, it will pre-allocate a segment of IP to each node,
|
||||
schedule the Pod to this node, and then allocate IP from here. cilium_pool_mask_size Specifies
|
||||
the size allocated from cluster Pod CIDR to node.ipam.podCIDRs.
|
||||
Defaults to kube_network_node_prefix if not set.
|
||||
|
||||
```yml
|
||||
cilium_pool_mask_size: "24"
|
||||
```
|
||||
|
||||
cilium_pool_mask_size Specifies the size allocated to node.ipam.podCIDRs from cluster Pod IPV6 CIDR. Defaults to kube_network_node_prefix_ipv6 if not set.
|
||||
|
||||
```yml
|
||||
cilium_pool_mask_size_ipv6: "120"
|
||||
```
|
||||
|
||||
## Kube-proxy replacement with Cilium
|
||||
|
||||
Cilium can run without kube-proxy by setting `cilium_kube_proxy_replacement`
|
||||
to `strict`.
|
||||
|
||||
Without kube-proxy, cilium needs to know the address of the kube-apiserver
|
||||
and this must be set globally for all cilium components (agents and operators).
|
||||
Hence, in this configuration in Kubespray, Cilium will always contact
|
||||
the external loadbalancer (even from a node in the control plane)
|
||||
and if there is no external load balancer It will ignore any local load
|
||||
balancer deployed by Kubespray and **only contacts the first master**.
|
||||
and this must be set globally for all Cilium components (agents and operators).
|
||||
We can only use the localhost apiserver loadbalancer in this mode
|
||||
whenever it uses the same port as the kube-apiserver (by default it does).
|
||||
|
||||
## Cilium Operator
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
## Provisioning
|
||||
|
||||
You can deploy instances in your cloud environment in several different ways. Examples include Terraform, Ansible (ec2 and gce modules), and manual creation.
|
||||
You can deploy instances in your cloud environment in several ways. Examples include Terraform, Ansible (ec2 and gce modules), and manual creation.
|
||||
|
||||
## Deploy kubernetes
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
CNI
|
||||
==============
|
||||
|
||||
This network plugin only unpacks CNI plugins version `cni_version` into `/opt/cni/bin` and instructs kubelet to use cni, that is adds following cli params:
|
||||
|
||||
`KUBELET_NETWORK_PLUGIN="--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"`
|
||||
This network plugin only unpacks CNI plugins version `cni_version` into `/opt/cni/bin` and instructs implementation of container runtime cri to use cni.
|
||||
|
||||
It's intended usage is for custom CNI configuration, e.g. manual routing tables + bridge + loopback CNI plugin outside kubespray scope. Furthermore, it's used for non-kubespray supported CNI plugins which you can install afterward.
|
||||
|
||||
|
@ -100,6 +100,15 @@ containerd_runc_runtime:
|
||||
...
|
||||
```
|
||||
|
||||
Config insecure-registry access to self hosted registries.
|
||||
|
||||
```yaml
|
||||
containerd_insecure_registries:
|
||||
"test.registry.io": "http://test.registry.io"
|
||||
"172.19.16.11:5000": "http://172.19.16.11:5000"
|
||||
"repo:5000": "http://repo:5000"
|
||||
```
|
||||
|
||||
[containerd]: https://containerd.io/
|
||||
[RuntimeClass]: https://kubernetes.io/docs/concepts/containers/runtime-class/
|
||||
[runtime classes in containerd]: https://github.com/containerd/containerd/blob/main/docs/cri/config.md#runtime-classes
|
||||
|
@ -40,21 +40,7 @@ crio_registries:
|
||||
insecure: false
|
||||
```
|
||||
|
||||
## Note about pids_limit
|
||||
|
||||
For heavily mult-threaded workloads like databases, the default of 1024 for pids-limit is too low.
|
||||
This parameter controls not just the number of processes but also the amount of threads
|
||||
(since a thread is technically a process with shared memory). See [cri-o#1921]
|
||||
|
||||
In order to increase the default `pids_limit` for cri-o based deployments you need to set the `crio_pids_limit`
|
||||
for your `k8s_cluster` ansible group or per node depending on the use case.
|
||||
|
||||
```yaml
|
||||
crio_pids_limit: 4096
|
||||
```
|
||||
|
||||
[CRI-O]: https://cri-o.io/
|
||||
[cri-o#1921]: https://github.com/cri-o/cri-o/issues/1921
|
||||
|
||||
## Note about user namespaces
|
||||
|
||||
|
@ -64,6 +64,10 @@ Custom options to be added to the kubernetes coredns plugin.
|
||||
|
||||
Extra domains to be forwarded to the kubernetes coredns plugin.
|
||||
|
||||
### coredns_rewrite_block
|
||||
|
||||
[Rewrite](https://coredns.io/plugins/rewrite/) plugin block to perform internal message rewriting.
|
||||
|
||||
### coredns_external_zones
|
||||
|
||||
Array of optional external zones to coredns forward queries to. It's injected into
|
||||
|
@ -10,7 +10,7 @@ dynamically from the Terraform state file.
|
||||
## Local Host Configuration
|
||||
|
||||
To perform this installation, you will need a localhost to run Terraform/Ansible (laptop, VM, etc) and an account with Equinix Metal.
|
||||
In this example, we're using an m1.large CentOS 7 OpenStack VM as the localhost to kickoff the Kubernetes installation.
|
||||
In this example, we are provisioning a m1.large CentOS7 OpenStack VM as the localhost for the Kubernetes installation.
|
||||
You'll need Ansible, Git, and PIP.
|
||||
|
||||
```bash
|
||||
|
@ -25,7 +25,7 @@ etcd_metrics_port: 2381
|
||||
```
|
||||
|
||||
To create a service `etcd-metrics` and associated endpoints in the `kube-system` namespace,
|
||||
define it's labels in the inventory with:
|
||||
define its labels in the inventory with:
|
||||
|
||||
```yaml
|
||||
etcd_metrics_service_labels:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Fedora CoreOS
|
||||
|
||||
Tested with stable version 34.20210611.3.0
|
||||
Tested with stable version 37.20230322.3.0
|
||||
|
||||
Because package installation with `rpm-ostree` requires a reboot, playbook may fail while bootstrap.
|
||||
Restart playbook again.
|
||||
|
@ -54,7 +54,7 @@ listen kubernetes-apiserver-https
|
||||
balance roundrobin
|
||||
```
|
||||
|
||||
Note: That's an example config managed elsewhere outside of Kubespray.
|
||||
Note: That's an example config managed elsewhere outside Kubespray.
|
||||
|
||||
And the corresponding example global vars for such a "cluster-aware"
|
||||
external LB with the cluster API access modes configured in Kubespray:
|
||||
@ -85,7 +85,7 @@ for it.
|
||||
|
||||
Note: TLS/SSL termination for externally accessed API endpoints' will **not**
|
||||
be covered by Kubespray for that case. Make sure your external LB provides it.
|
||||
Alternatively you may specify an externally load balanced VIPs in the
|
||||
Alternatively you may specify an external load balanced VIPs in the
|
||||
`supplementary_addresses_in_ssl_keys` list. Then, kubespray will add them into
|
||||
the generated cluster certificates as well.
|
||||
|
||||
|
@ -76,8 +76,6 @@ kube_controller_feature_gates: ["RotateKubeletServerCertificate=true"]
|
||||
|
||||
## kube-scheduler
|
||||
kube_scheduler_bind_address: 127.0.0.1
|
||||
kube_kubeadm_scheduler_extra_args:
|
||||
profiling: false
|
||||
# AppArmor-based OS
|
||||
# kube_scheduler_feature_gates: ["AppArmor=true"]
|
||||
|
||||
@ -119,7 +117,8 @@ Let's take a deep look to the resultant **kubernetes** configuration:
|
||||
* The `anonymous-auth` (on `kube-apiserver`) is set to `true` by default. This is fine, because it is considered safe if you enable `RBAC` for the `authorization-mode`.
|
||||
* The `enable-admission-plugins` has not the `PodSecurityPolicy` admission plugin. This because it is going to be definitely removed from **kubernetes** `v1.25`. For this reason we decided to set the newest `PodSecurity` (for more details, please take a look here: <https://kubernetes.io/docs/concepts/security/pod-security-admission/>). Then, we set the `EventRateLimit` plugin, providing additional configuration files (that are automatically created under the hood and mounted inside the `kube-apiserver` container) to make it work.
|
||||
* The `encryption-provider-config` provide encryption at rest. This means that the `kube-apiserver` encrypt data that is going to be stored before they reach `etcd`. So the data is completely unreadable from `etcd` (in case an attacker is able to exploit this).
|
||||
* The `rotateCertificates` in `KubeletConfiguration` is set to `true` along with `serverTLSBootstrap`. This could be used in alternative to `tlsCertFile` and `tlsPrivateKeyFile` parameters. Additionally it automatically generates certificates by itself, but you need to manually approve them or at least using an operator to do this (for more details, please take a look here: <https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/>).
|
||||
* The `rotateCertificates` in `KubeletConfiguration` is set to `true` along with `serverTLSBootstrap`. This could be used in alternative to `tlsCertFile` and `tlsPrivateKeyFile` parameters. Additionally it automatically generates certificates by itself. By default the CSRs are approved automatically via [kubelet-csr-approver](https://github.com/postfinance/kubelet-csr-approver). You can customize approval configuration by modifying Helm values via `kubelet_csr_approver_values`.
|
||||
See <https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/> for more information on the subject.
|
||||
* If you are installing **kubernetes** in an AppArmor-based OS (eg. Debian/Ubuntu) you can enable the `AppArmor` feature gate uncommenting the lines with the comment `# AppArmor-based OS` on top.
|
||||
* The `kubelet_systemd_hardening`, both with `kubelet_secure_addresses` setup a minimal firewall on the system. To better understand how these variables work, here's an explanatory image:
|
||||

|
||||
@ -136,5 +135,3 @@ ansible-playbook -v cluster.yml \
|
||||
```
|
||||
|
||||
**N.B.** The `vars.yaml` contains our general cluster information (SANs, load balancer, dns, etc..) and `hardening.yaml` is the file described above.
|
||||
|
||||
Once completed the cluster deployment, don't forget to approve the generated certificates (check them with `kubectl get csr`, approve with `kubectl certificate approve <csr_name>`). This action is necessary because the `secureTLSBootstrap` option and `RotateKubeletServerCertificate` feature gate for `kubelet` are enabled (CIS [4.2.11](https://www.tenable.com/audits/items/CIS_Kubernetes_v1.20_v1.0.0_Level_1_Worker.audit:05af3dfbca8e0c3fb3559c6c7de29191), [4.2.12](https://www.tenable.com/audits/items/CIS_Kubernetes_v1.20_v1.0.0_Level_1_Worker.audit:5351c76f8c5bff8f98c29a5200a35435)).
|
||||
|
@ -155,11 +155,11 @@ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/mast
|
||||
Using [NodePort](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport):
|
||||
|
||||
```console
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml
|
||||
```
|
||||
|
||||
!!! tip
|
||||
For extended notes regarding deployments on bare-metal, see [Bare-metal considerations](./baremetal.md).
|
||||
For extended notes regarding deployments on bare-metal, see [Bare-metal considerations](https://github.com/kubernetes/ingress-nginx/blob/main/docs/deploy/baremetal.md).
|
||||
|
||||
### Verify installation
|
||||
|
||||
|
@ -95,7 +95,7 @@
|
||||
ansible.builtin.import_playbook: 3d/kubespray/cluster.yml
|
||||
```
|
||||
|
||||
Or your could copy separate tasks from cluster.yml into your ansible repository.
|
||||
Or you could copy separate tasks from cluster.yml into your ansible repository.
|
||||
|
||||
11. Commit changes to your ansible repo. Keep in mind, that submodule folder is just a link to the git commit hash of your forked repo.
|
||||
|
||||
@ -170,7 +170,7 @@ If you made useful changes or fixed a bug in existent kubespray repo, use this f
|
||||
git push
|
||||
```
|
||||
|
||||
If your branch doesn't exists on github, git will propose you to use something like
|
||||
If your branch doesn't exist on github, git will propose you to use something like
|
||||
|
||||
```ShellSession
|
||||
git push --set-upstream origin fixes-name-date-index
|
||||
|
@ -4,7 +4,7 @@ Kube-OVN integrates the OVN-based Network Virtualization with Kubernetes. It off
|
||||
|
||||
For more information please check [Kube-OVN documentation](https://github.com/alauda/kube-ovn)
|
||||
|
||||
**Warning:** Kernel version (`cat /proc/version`) needs to be different than `3.10.0-862` or kube-ovn won't start and will print this message:
|
||||
**Warning:** Kernel version (`cat /proc/version`) needs to be different from `3.10.0-862` or kube-ovn won't start and will print this message:
|
||||
|
||||
```bash
|
||||
kernel version 3.10.0-862 has a nat related bug that will affect ovs function, please update to a version greater than 3.10.0-898
|
||||
|
@ -68,7 +68,7 @@ If you have other networking devices or SDN systems that talk BGP, kube-router w
|
||||
From a simple full node-to-node mesh to per-node peering configurations, most routing needs can be attained.
|
||||
The configuration is Kubernetes native (annotations) just like the rest of kube-router.
|
||||
|
||||
For more details please refer to the <https://github.com/cloudnativelabs/kube-router/blob/master/docs/bgp.md.>
|
||||
For more details please refer to the <https://github.com/cloudnativelabs/kube-router/blob/master/docs/bgp.md>.
|
||||
|
||||
Next options will set up annotations for kube-router, using `kubectl annotate` command.
|
||||
|
||||
|
@ -64,3 +64,9 @@ kube_vip_bgppeers:
|
||||
# kube_vip_bgp_peerpass:
|
||||
# kube_vip_bgp_peeras:
|
||||
```
|
||||
|
||||
If using [control plane load-balancing](https://kube-vip.io/docs/about/architecture/#control-plane-load-balancing):
|
||||
|
||||
```yaml
|
||||
kube_vip_lb_enable: true
|
||||
```
|
||||
|
@ -4,7 +4,7 @@ Distributed system such as Kubernetes are designed to be resilient to the
|
||||
failures. More details about Kubernetes High-Availability (HA) may be found at
|
||||
[Building High-Availability Clusters](https://kubernetes.io/docs/admin/high-availability/)
|
||||
|
||||
To have a simple view the most of parts of HA will be skipped to describe
|
||||
To have a simple view the most of the parts of HA will be skipped to describe
|
||||
Kubelet<->Controller Manager communication only.
|
||||
|
||||
By default the normal behavior looks like:
|
||||
|
195
docs/metallb.md
195
docs/metallb.md
@ -14,20 +14,21 @@ kube_proxy_strict_arp: true
|
||||
|
||||
## Install
|
||||
|
||||
You have to explicitly enable the MetalLB extension and set an IP address range from which to allocate LoadBalancer IPs.
|
||||
You have to explicitly enable the MetalLB extension.
|
||||
|
||||
```yaml
|
||||
metallb_enabled: true
|
||||
metallb_speaker_enabled: true
|
||||
metallb_avoid_buggy_ips: true
|
||||
metallb_ip_range:
|
||||
- 10.5.0.0/16
|
||||
```
|
||||
|
||||
By default only the MetalLB BGP speaker is allowed to run on control plane nodes. If you have a single node cluster or a cluster where control plane are also worker nodes you may need to enable tolerations for the MetalLB controller:
|
||||
|
||||
```yaml
|
||||
metallb_controller_tolerations:
|
||||
metallb_config:
|
||||
controller:
|
||||
nodeselector:
|
||||
kubernetes.io/os: linux
|
||||
tolerations:
|
||||
- key: "node-role.kubernetes.io/master"
|
||||
operator: "Equal"
|
||||
value: ""
|
||||
@ -38,67 +39,183 @@ metallb_controller_tolerations:
|
||||
effect: "NoSchedule"
|
||||
```
|
||||
|
||||
## BGP Mode
|
||||
|
||||
When operating in BGP Mode MetalLB needs to have defined upstream peers:
|
||||
If you'd like to set additional nodeSelector and tolerations values, you can do so in the following fasion:
|
||||
|
||||
```yaml
|
||||
metallb_protocol: bgp
|
||||
metallb_ip_range:
|
||||
- 10.5.0.0/16
|
||||
metallb_peers:
|
||||
- peer_address: 192.0.2.1
|
||||
peer_asn: 64512
|
||||
my_asn: 4200000000
|
||||
- peer_address: 192.0.2.2
|
||||
peer_asn: 64513
|
||||
my_asn: 4200000000
|
||||
metallb_config:
|
||||
controller:
|
||||
nodeselector:
|
||||
kubernetes.io/os: linux
|
||||
tolerations:
|
||||
- key: "node-role.kubernetes.io/control-plane"
|
||||
operator: "Equal"
|
||||
value: ""
|
||||
effect: "NoSchedule"
|
||||
speaker:
|
||||
nodeselector:
|
||||
kubernetes.io/os: linux
|
||||
tolerations:
|
||||
- key: "node-role.kubernetes.io/control-plane"
|
||||
operator: "Equal"
|
||||
value: ""
|
||||
effect: "NoSchedule"
|
||||
```
|
||||
|
||||
Some upstream BGP peers may require password authentication:
|
||||
## Pools
|
||||
|
||||
First you need to specify all of the pools you are going to use:
|
||||
|
||||
```yaml
|
||||
metallb_protocol: bgp
|
||||
metallb_ip_range:
|
||||
- 10.5.0.0/16
|
||||
metallb_peers:
|
||||
- peer_address: 192.0.2.1
|
||||
metallb_config:
|
||||
|
||||
address_pools:
|
||||
|
||||
primary:
|
||||
ip_range:
|
||||
- 192.0.1.0-192.0.1.254
|
||||
auto_assign: true
|
||||
|
||||
pool1:
|
||||
ip_range:
|
||||
- 192.0.2.1-192.0.2.1
|
||||
auto_assign: false # When set to false, you need to explicitly set the loadBalancerIP in the service!
|
||||
|
||||
pool2:
|
||||
ip_range:
|
||||
- 192.0.2.2-192.0.2.2
|
||||
auto_assign: false
|
||||
```
|
||||
|
||||
## Layer2 Mode
|
||||
|
||||
Pools that need to be configured in layer2 mode, need to be specified in a list:
|
||||
|
||||
```yaml
|
||||
metallb_config:
|
||||
|
||||
layer2:
|
||||
- primary
|
||||
```
|
||||
|
||||
## BGP Mode
|
||||
|
||||
When operating in BGP Mode MetalLB needs to have defined upstream peers and link the pool(s) specified above to the correct peer:
|
||||
|
||||
```yaml
|
||||
metallb_config:
|
||||
|
||||
layer3:
|
||||
defaults:
|
||||
|
||||
peer_port: 179 # The TCP port to talk to. Defaults to 179, you shouldn't need to set this in production.
|
||||
hold_time: 120s # Requested BGP hold time, per RFC4271.
|
||||
|
||||
communities:
|
||||
vpn-only: "1234:1"
|
||||
NO_ADVERTISE: "65535:65282"
|
||||
|
||||
metallb_peers:
|
||||
|
||||
peer1:
|
||||
peer_address: 192.0.2.1
|
||||
peer_asn: 64512
|
||||
my_asn: 4200000000
|
||||
communities:
|
||||
- vpn-only
|
||||
address_pool:
|
||||
- pool1
|
||||
|
||||
# (optional) The source IP address to use when establishing the BGP session. In most cases the source-address field should only be used with per-node peers, i.e. peers with node selectors which select only one node. CURRENTLY NOT SUPPORTED
|
||||
source_address: 192.0.2.2
|
||||
|
||||
# (optional) The router ID to use when connecting to this peer. Defaults to the node IP address.
|
||||
# Generally only useful when you need to peer with another BGP router running on the same machine as MetalLB.
|
||||
router_id: 1.2.3.4
|
||||
|
||||
# (optional) Password for TCPMD5 authenticated BGP sessions offered by some peers.
|
||||
password: "changeme"
|
||||
|
||||
peer2:
|
||||
peer_address: 192.0.2.2
|
||||
peer_asn: 64513
|
||||
my_asn: 4200000000
|
||||
communities:
|
||||
- NO_ADVERTISE
|
||||
address_pool:
|
||||
- pool2
|
||||
|
||||
# (optional) The source IP address to use when establishing the BGP session. In most cases the source-address field should only be used with per-node peers, i.e. peers with node selectors which select only one node. CURRENTLY NOT SUPPORTED
|
||||
source_address: 192.0.2.1
|
||||
|
||||
# (optional) The router ID to use when connecting to this peer. Defaults to the node IP address.
|
||||
# Generally only useful when you need to peer with another BGP router running on the same machine as MetalLB.
|
||||
router_id: 1.2.3.5
|
||||
|
||||
# (optional) Password for TCPMD5 authenticated BGP sessions offered by some peers.
|
||||
password: "changeme"
|
||||
```
|
||||
|
||||
When using calico >= 3.18 you can replace MetalLB speaker by calico Service LoadBalancer IP advertisement.
|
||||
See [calico service IPs advertisement documentation](https://docs.projectcalico.org/archive/v3.18/networking/advertise-service-ips#advertise-service-load-balancer-ip-addresses).
|
||||
In this scenario you should disable the MetalLB speaker and configure the `calico_advertise_service_loadbalancer_ips` to match your `metallb_ip_range`
|
||||
In this scenario you should disable the MetalLB speaker and configure the `calico_advertise_service_loadbalancer_ips` to match your `ip_range`
|
||||
|
||||
```yaml
|
||||
metallb_speaker_enabled: false
|
||||
metallb_avoid_buggy_ips: true
|
||||
metallb_ip_range:
|
||||
metallb_config:
|
||||
address_pools:
|
||||
primary:
|
||||
ip_range:
|
||||
- 10.5.0.0/16
|
||||
calico_advertise_service_loadbalancer_ips: "{{ metallb_ip_range }}"
|
||||
auto_assign: true
|
||||
layer2:
|
||||
- primary
|
||||
calico_advertise_service_loadbalancer_ips: "{{ metallb_config.address_pools.primary.ip_range }}"
|
||||
```
|
||||
|
||||
If you have additional loadbalancer IP pool in `metallb_additional_address_pools` , ensure to add them to the list.
|
||||
If you have additional loadbalancer IP pool in `metallb_config.address_pools` , ensure to add them to the list.
|
||||
|
||||
```yaml
|
||||
metallb_speaker_enabled: false
|
||||
metallb_ip_range:
|
||||
metallb_config:
|
||||
address_pools:
|
||||
primary:
|
||||
ip_range:
|
||||
- 10.5.0.0/16
|
||||
metallb_additional_address_pools:
|
||||
kube_service_pool_1:
|
||||
auto_assign: true
|
||||
pool1:
|
||||
ip_range:
|
||||
- 10.6.0.0/16
|
||||
protocol: "bgp"
|
||||
auto_assign: false
|
||||
avoid_buggy_ips: true
|
||||
kube_service_pool_2:
|
||||
auto_assign: true
|
||||
pool2:
|
||||
ip_range:
|
||||
- 10.10.0.0/16
|
||||
protocol: "bgp"
|
||||
auto_assign: false
|
||||
avoid_buggy_ips: true
|
||||
auto_assign: true
|
||||
layer2:
|
||||
- primary
|
||||
layer3:
|
||||
defaults:
|
||||
peer_port: 179
|
||||
hold_time: 120s
|
||||
communities:
|
||||
vpn-only: "1234:1"
|
||||
NO_ADVERTISE: "65535:65282"
|
||||
metallb_peers:
|
||||
peer1:
|
||||
peer_address: 10.6.0.1
|
||||
peer_asn: 64512
|
||||
my_asn: 4200000000
|
||||
communities:
|
||||
- vpn-only
|
||||
address_pool:
|
||||
- pool1
|
||||
peer2:
|
||||
peer_address: 10.10.0.1
|
||||
peer_asn: 64513
|
||||
my_asn: 4200000000
|
||||
communities:
|
||||
- NO_ADVERTISE
|
||||
address_pool:
|
||||
- pool2
|
||||
calico_advertise_service_loadbalancer_ips:
|
||||
- 10.5.0.0/16
|
||||
- 10.6.0.0/16
|
||||
|
@ -4,7 +4,7 @@ Multus is a meta CNI plugin that provides multiple network interface support to
|
||||
pods. For each interface, Multus delegates CNI calls to secondary CNI plugins
|
||||
such as Calico, macvlan, etc.
|
||||
|
||||
See [multus documentation](https://github.com/intel/multus-cni).
|
||||
See [multus documentation](https://github.com/k8snetworkplumbingwg/multus-cni).
|
||||
|
||||
## Multus installation
|
||||
|
||||
@ -71,4 +71,4 @@ You may now inspect the pod and see that there is an additional interface config
|
||||
kubectl exec -it samplepod -- ip a
|
||||
```
|
||||
|
||||
For more details on how to use Multus, please visit <https://github.com/intel/multus-cni>
|
||||
For more details on how to use Multus, please visit <https://github.com/k8snetworkplumbingwg/multus-cni>
|
||||
|
@ -138,7 +138,7 @@ Run `cluster.yml` with `--limit=kube_control_plane`
|
||||
|
||||
## Adding an etcd node
|
||||
|
||||
You need to make sure there are always an odd number of etcd nodes in the cluster. In such a way, this is always a replace or scale up operation. Either add two new nodes or remove an old one.
|
||||
You need to make sure there are always an odd number of etcd nodes in the cluster. In such a way, this is always a replacement or scale up operation. Either add two new nodes or remove an old one.
|
||||
|
||||
### 1) Add the new node running cluster.yml
|
||||
|
||||
|
@ -7,12 +7,13 @@ following artifacts in advance from another environment where has access to the
|
||||
* Some static files (zips and binaries)
|
||||
* OS packages (rpm/deb files)
|
||||
* Container images used by Kubespray. Exhaustive list depends on your setup
|
||||
* [Optional] Python packages used by Kubespray (only required if your OS doesn't provide all python packages/versions listed in `requirements.txt`)
|
||||
* [Optional] Python packages used by Kubespray (only required if your OS doesn't provide all python packages/versions
|
||||
listed in `requirements.txt`)
|
||||
* [Optional] Helm chart files (only required if `helm_enabled=true`)
|
||||
|
||||
Then you need to setup the following services on your offline environment:
|
||||
|
||||
* a HTTP reverse proxy/cache/mirror to serve some static files (zips and binaries)
|
||||
* an HTTP reverse proxy/cache/mirror to serve some static files (zips and binaries)
|
||||
* an internal Yum/Deb repository for OS packages
|
||||
* an internal container image registry that need to be populated with all container images used by Kubespray
|
||||
* [Optional] an internal PyPi server for python packages used by Kubespray
|
||||
@ -23,7 +24,8 @@ In addition, you can find some tools for offline deployment under [contrib/offli
|
||||
|
||||
## Configure Inventory
|
||||
|
||||
Once all artifacts are accessible from your internal network, **adjust** the following variables in [your inventory](/inventory/sample/group_vars/all/offline.yml) to match your environment:
|
||||
Once all artifacts are accessible from your internal network, **adjust** the following variables
|
||||
in [your inventory](/inventory/sample/group_vars/all/offline.yml) to match your environment:
|
||||
|
||||
```yaml
|
||||
# Registry overrides
|
||||
@ -49,7 +51,7 @@ runc_download_url: "{{ files_repo }}/runc.{{ image_arch }}"
|
||||
nerdctl_download_url: "{{ files_repo }}/nerdctl-{{ nerdctl_version }}-{{ ansible_system | lower }}-{{ image_arch }}.tar.gz"
|
||||
# Insecure registries for containerd
|
||||
containerd_insecure_registries:
|
||||
- "{{ registry_host }}"
|
||||
"{{ registry_addr }}":"{{ registry_host }}"
|
||||
|
||||
# CentOS/Redhat/AlmaLinux/Rocky Linux
|
||||
## Docker / Containerd
|
||||
@ -86,22 +88,33 @@ containerd_ubuntu_repo_repokey: 'YOURREPOKEY'
|
||||
For the OS specific settings, just define the one matching your OS.
|
||||
If you use the settings like the one above, you'll need to define in your inventory the following variables:
|
||||
|
||||
* `registry_host`: Container image registry. If you _don't_ use the same repository path for the container images that the ones defined in [Download's role defaults](https://github.com/kubernetes-sigs/kubespray/blob/master/roles/download/defaults/main.yml), you need to override the `*_image_repo` for these container images. If you want to make your life easier, use the same repository path, you won't have to override anything else.
|
||||
* `files_repo`: HTTP webserver or reverse proxy that is able to serve the files listed above. Path is not important, you can store them anywhere as long as it's accessible by kubespray. It's recommended to use `*_version` in the path so that you don't need to modify this setting everytime kubespray upgrades one of these components.
|
||||
* `yum_repo`/`debian_repo`/`ubuntu_repo`: OS package repository depending of your OS, should point to your internal repository. Adjust the path accordingly.
|
||||
* `registry_host`: Container image registry. If you _don't_ use the same repository path for the container images that
|
||||
the ones defined
|
||||
in [Download's role defaults](https://github.com/kubernetes-sigs/kubespray/blob/master/roles/download/defaults/main.yml)
|
||||
, you need to override the `*_image_repo` for these container images. If you want to make your life easier, use the
|
||||
same repository path, you won't have to override anything else.
|
||||
* `registry_addr`: Container image registry, but only have [domain or ip]:[port].
|
||||
* `files_repo`: HTTP webserver or reverse proxy that is able to serve the files listed above. Path is not important, you
|
||||
can store them anywhere as long as it's accessible by kubespray. It's recommended to use `*_version` in the path so
|
||||
that you don't need to modify this setting everytime kubespray upgrades one of these components.
|
||||
* `yum_repo`/`debian_repo`/`ubuntu_repo`: OS package repository depending on your OS, should point to your internal
|
||||
repository. Adjust the path accordingly.
|
||||
|
||||
## Install Kubespray Python Packages
|
||||
|
||||
### Recommended way: Kubespray Container Image
|
||||
|
||||
The easiest way is to use [kubespray container image](https://quay.io/kubespray/kubespray) as all the required packages are baked in the image.
|
||||
The easiest way is to use [kubespray container image](https://quay.io/kubespray/kubespray) as all the required packages
|
||||
are baked in the image.
|
||||
Just copy the container image in your private container image registry and you are all set!
|
||||
|
||||
### Manual installation
|
||||
|
||||
Look at the `requirements.txt` file and check if your OS provides all packages out-of-the-box (Using the OS package manager). For those missing, you need to either use a proxy that has Internet access (typically from a DMZ) or setup a PyPi server in your network that will host these packages.
|
||||
Look at the `requirements.txt` file and check if your OS provides all packages out-of-the-box (Using the OS package
|
||||
manager). For those missing, you need to either use a proxy that has Internet access (typically from a DMZ) or setup a
|
||||
PyPi server in your network that will host these packages.
|
||||
|
||||
If you're using a HTTP(S) proxy to download your python packages:
|
||||
If you're using an HTTP(S) proxy to download your python packages:
|
||||
|
||||
```bash
|
||||
sudo pip install --proxy=https://[username:password@]proxyserver:port -r requirements.txt
|
||||
@ -119,13 +132,15 @@ pip install -i https://pypiserver/pypi package_you_miss
|
||||
|
||||
## Run Kubespray as usual
|
||||
|
||||
Once all artifacts are in place and your inventory properly set up, you can run kubespray with the regular `cluster.yaml` command:
|
||||
Once all artifacts are in place and your inventory properly set up, you can run kubespray with the
|
||||
regular `cluster.yaml` command:
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventory/my_airgap_cluster/hosts.yaml -b cluster.yml
|
||||
```
|
||||
|
||||
If you use [Kubespray Container Image](#recommended-way:-kubespray-container-image), you can mount your inventory inside the container:
|
||||
If you use [Kubespray Container Image](#recommended-way:-kubespray-container-image), you can mount your inventory inside
|
||||
the container:
|
||||
|
||||
```bash
|
||||
docker run --rm -it -v path_to_inventory/my_airgap_cluster:inventory/my_airgap_cluster myprivateregisry.com/kubespray/kubespray:v2.14.0 ansible-playbook -i inventory/my_airgap_cluster/hosts.yaml -b cluster.yml
|
||||
|
@ -92,18 +92,18 @@ The new cloud provider is configured to have Octavia by default in Kubespray.
|
||||
- Available variables for configuring lbaas:
|
||||
|
||||
```yaml
|
||||
external_openstack_lbaas_create_monitor: false
|
||||
external_openstack_lbaas_monitor_delay: "1m"
|
||||
external_openstack_lbaas_monitor_timeout: "30s"
|
||||
external_openstack_lbaas_monitor_max_retries: "3"
|
||||
external_openstack_lbaas_provider: octavia
|
||||
external_openstack_lbaas_use_octavia: false
|
||||
external_openstack_lbaas_network_id: "Neutron network ID to create LBaaS VIP"
|
||||
external_openstack_lbaas_subnet_id: "Neutron subnet ID to create LBaaS VIP"
|
||||
external_openstack_lbaas_enabled: true
|
||||
external_openstack_lbaas_floating_network_id: "Neutron network ID to get floating IP from"
|
||||
external_openstack_lbaas_floating_subnet_id: "Neutron subnet ID to get floating IP from"
|
||||
external_openstack_lbaas_method: "ROUND_ROBIN"
|
||||
external_openstack_lbaas_method: ROUND_ROBIN
|
||||
external_openstack_lbaas_provider: amphora
|
||||
external_openstack_lbaas_subnet_id: "Neutron subnet ID to create LBaaS VIP"
|
||||
external_openstack_lbaas_network_id: "Neutron network ID to create LBaaS VIP"
|
||||
external_openstack_lbaas_manage_security_groups: false
|
||||
external_openstack_lbaas_create_monitor: false
|
||||
external_openstack_lbaas_monitor_delay: 5
|
||||
external_openstack_lbaas_monitor_max_retries: 1
|
||||
external_openstack_lbaas_monitor_timeout: 3
|
||||
external_openstack_lbaas_internal_lb: false
|
||||
|
||||
```
|
||||
|
70
docs/port-requirements.md
Normal file
70
docs/port-requirements.md
Normal file
@ -0,0 +1,70 @@
|
||||
# Port Requirements
|
||||
|
||||
To operate properly, Kubespray requires some ports to be opened. If the network is configured with firewall rules, it is needed to ensure infrastructure components can communicate with each other through specific ports.
|
||||
|
||||
Ensure the following ports required by Kubespray are open on the network and configured to allow access between hosts. Some ports are optional depending on the configuration and usage.
|
||||
|
||||
## Kubernetes
|
||||
|
||||
### Control plane
|
||||
|
||||
| Protocol | Port | Description |
|
||||
|----------|--------| ------------ |
|
||||
| TCP | 22 | ssh for ansible |
|
||||
| TCP | 2379 | etcd client port|
|
||||
| TCP | 2380 | etcd peer port |
|
||||
| TCP | 6443 | kubernetes api |
|
||||
| TCP | 10250 | kubelet api |
|
||||
| TCP | 10257 | kube-scheduler |
|
||||
| TCP | 10259 | kube-controller-manager |
|
||||
|
||||
### Worker node(s)
|
||||
|
||||
| Protocol | Port | Description |
|
||||
|----------|-------- | ------------ |
|
||||
| TCP | 22 | ssh for ansible |
|
||||
| TCP | 10250 | kubelet api |
|
||||
| TCP | 30000-32767| kube nodePort range |
|
||||
|
||||
refers to: [Kubernetes Docs](https://kubernetes.io/docs/reference/networking/ports-and-protocols/)
|
||||
|
||||
## Calico
|
||||
|
||||
If Calico is used, it requires:
|
||||
|
||||
| Protocol | Port | Description |
|
||||
|----------|-------- | ------------ |
|
||||
| TCP | 179 | Calico networking (BGP) |
|
||||
| UDP | 4789 | Calico CNI with VXLAN enabled |
|
||||
| TCP | 5473 | Calico CNI with Typha enabled |
|
||||
| UDP | 51820 | Calico with IPv4 Wireguard enabled |
|
||||
| UDP | 51821 | Calico with IPv6 Wireguard enabled |
|
||||
| IPENCAP / IPIP | - | Calico CNI with IPIP enabled |
|
||||
|
||||
refers to: [Calico Docs](https://docs.tigera.io/calico/latest/getting-started/kubernetes/requirements#network-requirements)
|
||||
|
||||
## Cilium
|
||||
|
||||
If Cilium is used, it requires:
|
||||
|
||||
| Protocol | Port | Description |
|
||||
|----------|-------- | ------------ |
|
||||
| TCP | 4240 | Cilium Health checks (``cilium-health``) |
|
||||
| TCP | 4244 | Hubble server |
|
||||
| TCP | 4245 | Hubble Relay |
|
||||
| UDP | 8472 | VXLAN overlay |
|
||||
| TCP | 9962 | Cilium-agent Prometheus metrics |
|
||||
| TCP | 9963 | Cilium-operator Prometheus metrics |
|
||||
| TCP | 9964 | Cilium-proxy Prometheus metrics |
|
||||
| UDP | 51871 | WireGuard encryption tunnel endpoint |
|
||||
| ICMP | - | health checks |
|
||||
|
||||
refers to: [Cilium Docs](https://docs.cilium.io/en/v1.13/operations/system_requirements/)
|
||||
|
||||
## Addons
|
||||
|
||||
| Protocol | Port | Description |
|
||||
|----------|-------- | ------------ |
|
||||
| TCP | 9100 | node exporter |
|
||||
| TCP/UDP | 7472 | metallb metrics ports |
|
||||
| TCP/UDP | 7946 | metallb L2 operating mode |
|
@ -272,7 +272,7 @@ scp $USERNAME@$IP_CONTROLLER_0:/etc/kubernetes/admin.conf kubespray-do.conf
|
||||
|
||||
This kubeconfig file uses the internal IP address of the controller node to
|
||||
access the API server. This kubeconfig file will thus not work of from
|
||||
outside of the VPC network. We will need to change the API server IP address
|
||||
outside the VPC network. We will need to change the API server IP address
|
||||
to the controller node his external IP address. The external IP address will be
|
||||
accepted in the
|
||||
TLS negotiation as we added the controllers external IP addresses in the SSL
|
||||
@ -482,7 +482,7 @@ nginx version: nginx/1.19.1
|
||||
|
||||
### Kubernetes services
|
||||
|
||||
#### Expose outside of the cluster
|
||||
#### Expose outside the cluster
|
||||
|
||||
In this section you will verify the ability to expose applications using a [Service](https://kubernetes.io/docs/concepts/services-networking/service/).
|
||||
|
||||
|
@ -17,7 +17,8 @@ versions. Here are all version vars for each component:
|
||||
* flannel_version
|
||||
* kubedns_version
|
||||
|
||||
:warning: [Attempting to upgrade from an older release straight to the latest release is unsupported and likely to break something](https://github.com/kubernetes-sigs/kubespray/issues/3849#issuecomment-451386515) :warning:
|
||||
> **Warning**
|
||||
> [Attempting to upgrade from an older release straight to the latest release is unsupported and likely to break something](https://github.com/kubernetes-sigs/kubespray/issues/3849#issuecomment-451386515)
|
||||
|
||||
See [Multiple Upgrades](#multiple-upgrades) for how to upgrade from older Kubespray release to the latest release
|
||||
|
||||
@ -95,7 +96,8 @@ ansible-playbook upgrade-cluster.yml -b -i inventory/sample/hosts.ini -e kube_ve
|
||||
|
||||
## Multiple upgrades
|
||||
|
||||
:warning: [Do not skip releases when upgrading--upgrade by one tag at a time.](https://github.com/kubernetes-sigs/kubespray/issues/3849#issuecomment-451386515) :warning:
|
||||
> **Warning**
|
||||
> [Do not skip releases when upgrading--upgrade by one tag at a time.](https://github.com/kubernetes-sigs/kubespray/issues/3849#issuecomment-451386515)
|
||||
|
||||
For instance, if you're on v2.6.0, then check out v2.7.0, run the upgrade, check out the next tag, and run the next upgrade, etc.
|
||||
|
||||
@ -147,7 +149,8 @@ Previous HEAD position was 05dabb7e Fix Bionic networking restart error #3430 (#
|
||||
HEAD is now at 9051aa52 Fix ubuntu-contiv test failed (#3808)
|
||||
```
|
||||
|
||||
:info: NOTE: Review changes between the sample inventory and your inventory when upgrading versions. :info:
|
||||
> **Note**
|
||||
> Review changes between the sample inventory and your inventory when upgrading versions.
|
||||
|
||||
Some deprecations between versions that mean you can't just upgrade straight from 2.7.0 to 2.8.0 if you started with the sample inventory.
|
||||
|
||||
@ -263,7 +266,8 @@ Previous HEAD position was 6f97687d Release 2.8 robust san handling (#4478)
|
||||
HEAD is now at a4e65c7c Upgrade to Ansible >2.7.0 (#4471)
|
||||
```
|
||||
|
||||
:warning: IMPORTANT: Some of the variable formats changed in the k8s_cluster.yml between 2.8.5 and 2.9.0 :warning:
|
||||
> **Warning**
|
||||
> IMPORTANT: Some variable formats changed in the k8s_cluster.yml between 2.8.5 and 2.9.0
|
||||
|
||||
If you do not keep your inventory copy up to date, **your upgrade will fail** and your first master will be left non-functional until fixed and re-run.
|
||||
|
||||
@ -398,4 +402,4 @@ Please note that **migrating container engines is not officially supported by Ku
|
||||
|
||||
As of Kubespray 2.18.0, containerd is already the default container engine. If you have the chance, it is advisable and safer to reset and redeploy the entire cluster with a new container engine.
|
||||
|
||||
* [Migrating from Docker do Containerd](upgrades/migrate_docker2containerd.md)
|
||||
* [Migrating from Docker to Containerd](upgrades/migrate_docker2containerd.md)
|
||||
|
@ -66,7 +66,7 @@ apt-get install pigz
|
||||
### 5) Run `cluster.yml` playbook with `--limit`
|
||||
|
||||
```commandline
|
||||
ansible-playbook cluster.yml -i inventory/sample/hosts.ini cluster.yml --limit=NODENAME
|
||||
ansible-playbook -i inventory/sample/hosts.ini cluster.yml --limit=NODENAME
|
||||
```
|
||||
|
||||
This effectively reinstalls containerd and seems to place all config files in the right place. When this completes, kubelet will immediately pick up the new container engine and start spinning up DaemonSets and kube-system Pods.
|
||||
|
21
docs/vars.md
21
docs/vars.md
@ -81,7 +81,7 @@ following default cluster parameters:
|
||||
bits in kube_pods_subnet dictates how many kube_nodes can be in cluster. Setting this > 25 will
|
||||
raise an assertion in playbooks if the `kubelet_max_pods` var also isn't adjusted accordingly
|
||||
(assertion not applicable to calico which doesn't use this as a hard limit, see
|
||||
[Calico IP block sizes](https://docs.projectcalico.org/reference/resources/ippool#block-sizes).
|
||||
[Calico IP block sizes](https://docs.projectcalico.org/reference/resources/ippool#block-sizes)).
|
||||
|
||||
* *enable_dual_stack_networks* - Setting this to true will provision both IPv4 and IPv6 networking for pods and services.
|
||||
|
||||
@ -199,17 +199,26 @@ Stack](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/dns-stack.m
|
||||
|
||||
* *kubelet_rotate_server_certificates* - Auto rotate the kubelet server certificates by requesting new certificates
|
||||
from the kube-apiserver when the certificate expiration approaches.
|
||||
**Note** that server certificates are **not** approved automatically. Approve them manually
|
||||
(`kubectl get csr`, `kubectl certificate approve`) or implement custom approving controller like
|
||||
[kubelet-rubber-stamp](https://github.com/kontena/kubelet-rubber-stamp).
|
||||
Note that enabling this also activates *kubelet_csr_approver* which approves automatically the CSRs.
|
||||
To customize its behavior, you can override the Helm values via *kubelet_csr_approver_values*.
|
||||
See [kubelet-csr-approver](https://github.com/postfinance/kubelet-csr-approver) for more information.
|
||||
|
||||
* *kubelet_streaming_connection_idle_timeout* - Set the maximum time a streaming connection can be idle before the connection is automatically closed.
|
||||
|
||||
* *kubelet_image_gc_high_threshold* - Set the percent of disk usage after which image garbage collection is always run.
|
||||
The percent is calculated by dividing this field value by 100, so this field must be between 0 and 100, inclusive.
|
||||
When specified, the value must be greater than imageGCLowThresholdPercent. Default: 85
|
||||
|
||||
* *kubelet_image_gc_low_threshold* - Set the percent of disk usage before which image garbage collection is never run.
|
||||
Lowest disk usage to garbage collect to.
|
||||
The percent is calculated by dividing this field value by 100, so the field value must be between 0 and 100, inclusive.
|
||||
When specified, the value must be less than imageGCHighThresholdPercent. Default: 80
|
||||
|
||||
* *kubelet_make_iptables_util_chains* - If `true`, causes the kubelet ensures a set of `iptables` rules are present on host.
|
||||
|
||||
* *kubelet_systemd_hardening* - If `true`, provides kubelet systemd service with security features for isolation.
|
||||
|
||||
**N.B.** To enable this feature, ensure you are using the **`cgroup v2`** on your system. Check it out with command: `sudo ls -l /sys/fs/cgroup/*.slice`. If directory does not exists, enable this with the following guide: [enable cgroup v2](https://rootlesscontaine.rs/getting-started/common/cgroup2/#enabling-cgroup-v2).
|
||||
**N.B.** To enable this feature, ensure you are using the **`cgroup v2`** on your system. Check it out with command: `sudo ls -l /sys/fs/cgroup/*.slice`. If directory does not exist, enable this with the following guide: [enable cgroup v2](https://rootlesscontaine.rs/getting-started/common/cgroup2/#enabling-cgroup-v2).
|
||||
|
||||
* *kubelet_secure_addresses* - By default *kubelet_systemd_hardening* set the **control plane** `ansible_host` IPs as the `kubelet_secure_addresses`. In case you have multiple interfaces in your control plane nodes and the `kube-apiserver` is not bound to the default interface, you can override them with this variable.
|
||||
Example:
|
||||
@ -243,7 +252,7 @@ node_taints:
|
||||
The auditing parameters can be tuned via the following variables (which default values are shown below):
|
||||
* `audit_log_path`: /var/log/audit/kube-apiserver-audit.log
|
||||
* `audit_log_maxage`: 30
|
||||
* `audit_log_maxbackups`: 1
|
||||
* `audit_log_maxbackups`: 10
|
||||
* `audit_log_maxsize`: 100
|
||||
* `audit_policy_file`: "{{ kube_config_dir }}/audit-policy/apiserver-audit-policy.yaml"
|
||||
|
||||
|
@ -15,7 +15,7 @@ To set the number of replicas for the vSphere CSI controller, you can change `vs
|
||||
You need to source the vSphere credentials you use to deploy your machines that will host Kubernetes.
|
||||
|
||||
| Variable | Required | Type | Choices | Default | Comment |
|
||||
|---------------------------------------------|----------|---------|----------------------------|---------------------------|---------------------------------------------------------------------------------------------------------------------|
|
||||
|-------------------------------------------------|----------|---------|-----------------|-------------------------|-----------------------------------------------------------------------------------------------------------------------------|
|
||||
| external_vsphere_vcenter_ip | TRUE | string | | | IP/URL of the vCenter |
|
||||
| external_vsphere_vcenter_port | TRUE | string | | "443" | Port of the vCenter API |
|
||||
| external_vsphere_insecure | TRUE | string | "true", "false" | "true" | set to "true" if the host above uses a self-signed cert |
|
||||
@ -33,7 +33,7 @@ You need to source the vSphere credentials you use to deploy your machines that
|
||||
| vsphere_csi_provisioner_image_tag | TRUE | string | | "v2.1.0" | CSI provisioner image tag to use |
|
||||
| vsphere_csi_node_driver_registrar_image_tag | TRUE | string | | "v1.1.0" | CSI node driver registrar image tag to use |
|
||||
| vsphere_csi_driver_image_tag | TRUE | string | | "v1.0.2" | CSI driver image tag to use |
|
||||
| vsphere_csi_resizer_tag | TRUE | string | | "v1.1.0" | CSI resizer image tag to use
|
||||
| vsphere_csi_resizer_tag | TRUE | string | | "v1.1.0" | CSI resizer image tag to use |
|
||||
| vsphere_csi_aggressive_node_drain | FALSE | boolean | | false | Enable aggressive node drain strategy |
|
||||
| vsphere_csi_aggressive_node_unreachable_timeout | FALSE | int | 300 | | Timeout till node will be drained when it in an unreachable state |
|
||||
| vsphere_csi_aggressive_node_not_ready_timeout | FALSE | int | 300 | | Timeout till node will be drained when it in not-ready state |
|
||||
@ -55,7 +55,7 @@ spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
storageClassName: Space-Efficient
|
||||
storageClassName: mongodb-sc
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
@ -87,7 +87,7 @@ You should see the PVC provisioned and bound:
|
||||
```ShellSession
|
||||
$ kubectl get pvc
|
||||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||||
csi-pvc-vsphere Bound pvc-dc7b1d21-ee41-45e1-98d9-e877cc1533ac 1Gi RWO Space-Efficient 10s
|
||||
csi-pvc-vsphere Bound pvc-dc7b1d21-ee41-45e1-98d9-e877cc1533ac 1Gi RWO mongodb-sc 10s
|
||||
```
|
||||
|
||||
And the volume mounted to the Nginx Pod (wait until the Pod is Running):
|
||||
|
@ -21,7 +21,7 @@ After this step you should have:
|
||||
|
||||
### Kubespray configuration
|
||||
|
||||
First in `inventory/sample/group_vars/all/all.yml` you must set the cloud provider to `external` and external_cloud_provider to `external_cloud_provider`.
|
||||
First in `inventory/sample/group_vars/all/all.yml` you must set the `cloud_provider` to `external` and `external_cloud_provider` to `vsphere`.
|
||||
|
||||
```yml
|
||||
cloud_provider: "external"
|
||||
@ -91,7 +91,7 @@ cloud_provider: vsphere
|
||||
Then, in the same file, you need to declare your vCenter credentials following the description below.
|
||||
|
||||
| Variable | Required | Type | Choices | Default | Comment |
|
||||
|------------------------------|----------|---------|----------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|------------------------------|----------|---------|----------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| vsphere_vcenter_ip | TRUE | string | | | IP/URL of the vCenter |
|
||||
| vsphere_vcenter_port | TRUE | integer | | | Port of the vCenter API. Commonly 443 |
|
||||
| vsphere_insecure | TRUE | integer | 1, 0 | | set to 1 if the host above uses a self-signed cert |
|
||||
|
47
galaxy.yml
Normal file
47
galaxy.yml
Normal file
@ -0,0 +1,47 @@
|
||||
---
|
||||
namespace: kubernetes_sigs
|
||||
description: Deploy a production ready Kubernetes cluster
|
||||
name: kubespray
|
||||
version: 2.21.0
|
||||
readme: README.md
|
||||
authors:
|
||||
- luksi1
|
||||
tags:
|
||||
- kubernetes
|
||||
- kubespray
|
||||
repository: https://github.com/kubernetes-sigs/kubespray
|
||||
build_ignore:
|
||||
- .github
|
||||
- '*.tar.gz'
|
||||
- extra_playbooks
|
||||
- inventory
|
||||
- scripts
|
||||
- test-infra
|
||||
- .ansible-lint
|
||||
- .editorconfig
|
||||
- .gitignore
|
||||
- .gitlab-ci
|
||||
- .gitlab-ci.yml
|
||||
- .gitmodules
|
||||
- .markdownlint.yaml
|
||||
- .nojekyll
|
||||
- .pre-commit-config.yaml
|
||||
- .yamllint
|
||||
- Dockerfile
|
||||
- FILES.json
|
||||
- MANIFEST.json
|
||||
- Makefile
|
||||
- Vagrantfile
|
||||
- _config.yml
|
||||
- ansible.cfg
|
||||
- requirements*txt
|
||||
- setup.cfg
|
||||
- setup.py
|
||||
- index.html
|
||||
- reset.yml
|
||||
- cluster.yml
|
||||
- scale.yml
|
||||
- recover-control-plane.yml
|
||||
- remove-node.yml
|
||||
- upgrade-cluster.yml
|
||||
- library
|
@ -21,11 +21,6 @@ bin_dir: /usr/local/bin
|
||||
# valid options are "nginx" or "haproxy"
|
||||
# loadbalancer_apiserver_type: nginx # valid values "nginx" or "haproxy"
|
||||
|
||||
## If the cilium is going to be used in strict mode, we can use the
|
||||
## localhost connection and not use the external LB. If this parameter is
|
||||
## not specified, the first node to connect to kubeapi will be used.
|
||||
# use_localhost_as_kubeapi_loadbalancer: true
|
||||
|
||||
## Local loadbalancer should use this port
|
||||
## And must be set port 6443
|
||||
loadbalancer_apiserver_port: 6443
|
||||
@ -138,3 +133,6 @@ ntp_servers:
|
||||
|
||||
## Used to control no_log attribute
|
||||
unsafe_show_logs: false
|
||||
|
||||
## If enabled it will allow kubespray to attempt setup even if the distribution is not supported. For unsupported distributions this can lead to unexpected failures in some cases.
|
||||
allow_unsupported_distribution_setup: false
|
||||
|
@ -18,9 +18,9 @@
|
||||
# quay_image_repo: "{{ registry_host }}"
|
||||
|
||||
## Kubernetes components
|
||||
# kubeadm_download_url: "{{ files_repo }}/storage.googleapis.com/kubernetes-release/release/{{ kubeadm_version }}/bin/linux/{{ image_arch }}/kubeadm"
|
||||
# kubectl_download_url: "{{ files_repo }}/storage.googleapis.com/kubernetes-release/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubectl"
|
||||
# kubelet_download_url: "{{ files_repo }}/storage.googleapis.com/kubernetes-release/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubelet"
|
||||
# kubeadm_download_url: "{{ files_repo }}/dl.k8s.io/release/{{ kubeadm_version }}/bin/linux/{{ image_arch }}/kubeadm"
|
||||
# kubectl_download_url: "{{ files_repo }}/dl.k8s.io/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubectl"
|
||||
# kubelet_download_url: "{{ files_repo }}/dl.k8s.io/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubelet"
|
||||
|
||||
## CNI Plugins
|
||||
# cni_download_url: "{{ files_repo }}/github.com/containernetworking/plugins/releases/download/{{ cni_version }}/cni-plugins-linux-{{ image_arch }}-{{ cni_version }}.tgz"
|
||||
@ -28,7 +28,7 @@
|
||||
## cri-tools
|
||||
# crictl_download_url: "{{ files_repo }}/github.com/kubernetes-sigs/cri-tools/releases/download/{{ crictl_version }}/crictl-{{ crictl_version }}-{{ ansible_system | lower }}-{{ image_arch }}.tar.gz"
|
||||
|
||||
## [Optional] etcd: only if you **DON'T** use etcd_deployment=host
|
||||
## [Optional] etcd: only if you use etcd_deployment=host
|
||||
# etcd_download_url: "{{ files_repo }}/github.com/etcd-io/etcd/releases/download/{{ etcd_version }}/etcd-{{ etcd_version }}-linux-{{ image_arch }}.tar.gz"
|
||||
|
||||
# [Optional] Calico: If using Calico network plugin
|
||||
@ -40,7 +40,7 @@
|
||||
# [Optional] Cilium: If using Cilium network plugin
|
||||
# ciliumcli_download_url: "{{ files_repo }}/github.com/cilium/cilium-cli/releases/download/{{ cilium_cli_version }}/cilium-linux-{{ image_arch }}.tar.gz"
|
||||
|
||||
# [Optional] Flannel: If using Falnnel network plugin
|
||||
# [Optional] Flannel: If using Flannel network plugin
|
||||
# flannel_cni_download_url: "{{ files_repo }}/kubernetes/flannel/{{ flannel_cni_version }}/flannel-{{ image_arch }}"
|
||||
|
||||
# [Optional] helm: only if you set helm_enabled: true
|
||||
@ -55,14 +55,16 @@
|
||||
# [Optional] cri-dockerd: only if you set container_manager: docker
|
||||
# cri_dockerd_download_url: "{{ files_repo }}/github.com/Mirantis/cri-dockerd/releases/download/v{{ cri_dockerd_version }}/cri-dockerd-{{ cri_dockerd_version }}.{{ image_arch }}.tgz"
|
||||
|
||||
# [Optional] runc: if you set container_manager to containerd or crio
|
||||
# runc_download_url: "{{ files_repo }}/github.com/opencontainers/runc/releases/download/{{ runc_version }}/runc.{{ image_arch }}"
|
||||
|
||||
# [Optional] cri-o: only if you set container_manager: crio
|
||||
# crio_download_base: "download.opensuse.org/repositories/devel:kubic:libcontainers:stable"
|
||||
# crio_download_crio: "http://{{ crio_download_base }}:/cri-o:/"
|
||||
# crio_download_url: "{{ files_repo }}/storage.googleapis.com/cri-o/artifacts/cri-o.{{ image_arch }}.{{ crio_version }}.tar.gz"
|
||||
# skopeo_download_url: "{{ files_repo }}/github.com/lework/skopeo-binary/releases/download/{{ skopeo_version }}/skopeo-linux-{{ image_arch }}"
|
||||
|
||||
# [Optional] runc,containerd: only if you set container_runtime: containerd
|
||||
# runc_download_url: "{{ files_repo }}/github.com/opencontainers/runc/releases/download/{{ runc_version }}/runc.{{ image_arch }}"
|
||||
# [Optional] containerd: only if you set container_runtime: containerd
|
||||
# containerd_download_url: "{{ files_repo }}/github.com/containerd/containerd/releases/download/v{{ containerd_version }}/containerd-{{ containerd_version }}-linux-{{ image_arch }}.tar.gz"
|
||||
# nerdctl_download_url: "{{ files_repo }}/github.com/containerd/nerdctl/releases/download/v{{ nerdctl_version }}/nerdctl-{{ nerdctl_version }}-{{ ansible_system | lower }}-{{ image_arch }}.tar.gz"
|
||||
|
||||
@ -70,6 +72,9 @@
|
||||
# gvisor_runsc_download_url: "{{ files_repo }}/storage.googleapis.com/gvisor/releases/release/{{ gvisor_version }}/{{ ansible_architecture }}/runsc"
|
||||
# gvisor_containerd_shim_runsc_download_url: "{{ files_repo }}/storage.googleapis.com/gvisor/releases/release/{{ gvisor_version }}/{{ ansible_architecture }}/containerd-shim-runsc-v1"
|
||||
|
||||
# [Optional] Krew: only if you set krew_enabled: true
|
||||
# krew_download_url: "{{ files_repo }}/github.com/kubernetes-sigs/krew/releases/download/{{ krew_version }}/krew-{{ host_os }}_{{ image_arch }}.tar.gz"
|
||||
|
||||
## CentOS/Redhat/AlmaLinux
|
||||
### For EL7, base and extras repo must be available, for EL8, baseos and appstream
|
||||
### By default we enable those repo automatically
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user