mirror of
https://github.com/kubernetes-sigs/kubespray.git
synced 2026-03-25 19:18:29 +03:00
Compare commits
90 Commits
6afa269786
...
component_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0e559d449 | ||
|
|
dd75b88960 | ||
|
|
2f2e0c6163 | ||
|
|
ae8c2a44ac | ||
|
|
78e3f64527 | ||
|
|
166bf4e329 | ||
|
|
c8b1d271a3 | ||
|
|
4d45cb0f74 | ||
|
|
7b0e730624 | ||
|
|
a0a164375d | ||
|
|
32d990d1e4 | ||
|
|
b6aa645f5e | ||
|
|
e3737592f5 | ||
|
|
22fb8f8c98 | ||
|
|
bf18b142d0 | ||
|
|
558764dac6 | ||
|
|
37e321c8bf | ||
|
|
f4ccdb5e72 | ||
|
|
fcecaf6943 | ||
|
|
37f7a86014 | ||
|
|
fff7f10a85 | ||
|
|
dc09298f7e | ||
|
|
680db0c921 | ||
|
|
9977d4dc10 | ||
|
|
1b6129566b | ||
|
|
c3404c3685 | ||
|
|
fba8708486 | ||
|
|
8dacb9cd16 | ||
|
|
df3f0a2341 | ||
|
|
62e90b3122 | ||
|
|
6b5cc5bdfb | ||
|
|
a277cfdee7 | ||
|
|
bc5528f585 | ||
|
|
2740c13c0c | ||
|
|
52b68bccad | ||
|
|
82c4c0afdf | ||
|
|
63a43cf6db | ||
|
|
666a3a9500 | ||
|
|
28f9c126bf | ||
|
|
d41b629be3 | ||
|
|
851abbc2e3 | ||
|
|
17c72367bc | ||
|
|
d91c7d7576 | ||
|
|
14b20ad2a2 | ||
|
|
72cb1356ef | ||
|
|
51304d57e2 | ||
|
|
a0d7bef90e | ||
|
|
a1ec88e290 | ||
|
|
c9ff62944e | ||
|
|
20ab9179af | ||
|
|
5be35c811a | ||
|
|
ad522d4aab | ||
|
|
9c511069cc | ||
|
|
ed270fcab4 | ||
|
|
0615929727 | ||
|
|
48c25d9ebf | ||
|
|
0bffcacbe7 | ||
|
|
c857252225 | ||
|
|
a0f00761ac | ||
|
|
3a3e5d6954 | ||
|
|
2d6e508084 | ||
|
|
6d850a0dc5 | ||
|
|
6a517e165e | ||
|
|
aaaf82f308 | ||
|
|
e80087df93 | ||
|
|
b7491b957b | ||
|
|
5cf8f3eefc | ||
|
|
1cbccf40a5 | ||
|
|
bcdd702e19 | ||
|
|
20693afe82 | ||
|
|
1bbcfd8dd6 | ||
|
|
8d948f918f | ||
|
|
4d8d1b8aff | ||
|
|
d80318301d | ||
|
|
31cce09fbc | ||
|
|
9a90c9d6c8 | ||
|
|
b9e1e8577f | ||
|
|
5d1dd83b07 | ||
|
|
b203586d6b | ||
|
|
88df61357b | ||
|
|
2edf176294 | ||
|
|
39744146b4 | ||
|
|
118b2dce02 | ||
|
|
4c5eda9f1e | ||
|
|
2512e0c50c | ||
|
|
633d39448e | ||
|
|
4d87ac1032 | ||
|
|
2342d0cd57 | ||
|
|
e6a5266bad | ||
|
|
57f7c44718 |
@@ -1,5 +1,4 @@
|
|||||||
---
|
---
|
||||||
parseable: true
|
|
||||||
skip_list:
|
skip_list:
|
||||||
# see https://docs.ansible.com/ansible-lint/rules/default_rules.html for a list of all default rules
|
# see https://docs.ansible.com/ansible-lint/rules/default_rules.html for a list of all default rules
|
||||||
|
|
||||||
@@ -34,6 +33,8 @@ skip_list:
|
|||||||
# Disable run-once check with free strategy
|
# Disable run-once check with free strategy
|
||||||
# (Disabled in June 2023 after ansible upgrade; FIXME)
|
# (Disabled in June 2023 after ansible upgrade; FIXME)
|
||||||
- 'run-once[task]'
|
- 'run-once[task]'
|
||||||
|
|
||||||
|
- 'jinja[spacing]'
|
||||||
exclude_paths:
|
exclude_paths:
|
||||||
# Generated files
|
# Generated files
|
||||||
- tests/files/custom_cni/cilium.yaml
|
- tests/files/custom_cni/cilium.yaml
|
||||||
|
|||||||
6
.github/workflows/auto-label-os.yml
vendored
6
.github/workflows/auto-label-os.yml
vendored
@@ -13,16 +13,16 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
|
|
||||||
- name: Parse issue form
|
- name: Parse issue form
|
||||||
uses: stefanbuck/github-issue-parser@2ea9b35a8c584529ed00891a8f7e41dc46d0441e
|
uses: stefanbuck/github-issue-parser@10dcc54158ba4c137713d9d69d70a2da63b6bda3
|
||||||
id: issue-parser
|
id: issue-parser
|
||||||
with:
|
with:
|
||||||
template-path: .github/ISSUE_TEMPLATE/bug-report.yaml
|
template-path: .github/ISSUE_TEMPLATE/bug-report.yaml
|
||||||
|
|
||||||
- name: Set labels based on OS field
|
- name: Set labels based on OS field
|
||||||
uses: redhat-plumbers-in-action/advanced-issue-labeler@e38e6809c5420d038eed380d49ee9a6ca7c92dbf
|
uses: redhat-plumbers-in-action/advanced-issue-labeler@b80ae64e3e156e9c111b075bfa04b295d54e8e2e
|
||||||
with:
|
with:
|
||||||
issue-form: ${{ steps.issue-parser.outputs.jsonString }}
|
issue-form: ${{ steps.issue-parser.outputs.jsonString }}
|
||||||
section: os
|
section: os
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ jobs:
|
|||||||
outputs:
|
outputs:
|
||||||
branches: ${{ steps.get-branches.outputs.data }}
|
branches: ${{ steps.get-branches.outputs.data }}
|
||||||
steps:
|
steps:
|
||||||
- uses: octokit/graphql-action@abaeca7ba4f0325d63b8de7ef943c2418d161b93
|
- uses: octokit/graphql-action@ddde8ebb2493e79f390e6449c725c21663a67505
|
||||||
id: get-branches
|
id: get-branches
|
||||||
with:
|
with:
|
||||||
query: |
|
query: |
|
||||||
query get_release_branches($owner:String!, $name:String!) {
|
query get_release_branches($owner:String!, $name:String!) {
|
||||||
repository(owner:$owner, name:$name) {
|
repository(owner:$owner, name:$name) {
|
||||||
refs(refPrefix: "refs/heads/",
|
refs(refPrefix: "refs/heads/",
|
||||||
first: 1, # TODO increment once we have release branch with the new checksums format
|
first: 2, # TODO increment once we have release branch with the new checksums format
|
||||||
query: "release-",
|
query: "release-",
|
||||||
orderBy: {
|
orderBy: {
|
||||||
field: ALPHABETICAL,
|
field: ALPHABETICAL,
|
||||||
|
|||||||
6
.github/workflows/upgrade-patch-versions.yml
vendored
6
.github/workflows/upgrade-patch-versions.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
update-patch-versions:
|
update-patch-versions:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||||
with:
|
with:
|
||||||
ref: ${{ inputs.branch }}
|
ref: ${{ inputs.branch }}
|
||||||
- uses: actions/setup-python@v6
|
- uses: actions/setup-python@v6
|
||||||
@@ -22,14 +22,14 @@ jobs:
|
|||||||
- run: update-hashes
|
- run: update-hashes
|
||||||
env:
|
env:
|
||||||
API_KEY: ${{ secrets.GITHUB_TOKEN }}
|
API_KEY: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- uses: actions/cache@v4
|
- uses: actions/cache@v5
|
||||||
with:
|
with:
|
||||||
key: pre-commit-hook-propagate
|
key: pre-commit-hook-propagate
|
||||||
path: |
|
path: |
|
||||||
~/.cache/pre-commit
|
~/.cache/pre-commit
|
||||||
- run: pre-commit run --all-files propagate-ansible-variables
|
- run: pre-commit run --all-files propagate-ansible-variables
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
- uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412
|
- uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0
|
||||||
with:
|
with:
|
||||||
commit-message: Patch versions updates
|
commit-message: Patch versions updates
|
||||||
title: Patch versions updates - ${{ inputs.branch }}
|
title: Patch versions updates - ${{ inputs.branch }}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ pr:
|
|||||||
- fedora39-kube-router
|
- fedora39-kube-router
|
||||||
- openeuler24-calico
|
- openeuler24-calico
|
||||||
- rockylinux9-cilium
|
- rockylinux9-cilium
|
||||||
|
- rockylinux10-cilium
|
||||||
- ubuntu22-calico-all-in-one
|
- ubuntu22-calico-all-in-one
|
||||||
- ubuntu22-calico-all-in-one-upgrade
|
- ubuntu22-calico-all-in-one-upgrade
|
||||||
- ubuntu24-calico-etcd-datastore
|
- ubuntu24-calico-etcd-datastore
|
||||||
@@ -127,6 +128,7 @@ pr_extended:
|
|||||||
- debian12-docker
|
- debian12-docker
|
||||||
- debian13-calico
|
- debian13-calico
|
||||||
- rockylinux9-calico
|
- rockylinux9-calico
|
||||||
|
- rockylinux10-calico
|
||||||
- ubuntu22-all-in-one-docker
|
- ubuntu22-all-in-one-docker
|
||||||
- ubuntu24-all-in-one-docker
|
- ubuntu24-all-in-one-docker
|
||||||
- ubuntu24-calico-all-in-one
|
- ubuntu24-calico-all-in-one
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ terraform_validate:
|
|||||||
- hetzner
|
- hetzner
|
||||||
- vsphere
|
- vsphere
|
||||||
- upcloud
|
- upcloud
|
||||||
- nifcloud
|
|
||||||
|
|
||||||
.terraform_apply:
|
.terraform_apply:
|
||||||
extends: .terraform_install
|
extends: .terraform_install
|
||||||
@@ -89,11 +88,10 @@ tf-elastx_cleanup:
|
|||||||
- ./scripts/openstack-cleanup/main.py
|
- ./scripts/openstack-cleanup/main.py
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
tf-elastx_ubuntu20-calico:
|
tf-elastx_ubuntu24-calico:
|
||||||
extends: .terraform_apply
|
extends: .terraform_apply
|
||||||
stage: deploy-part1
|
stage: deploy-part1
|
||||||
when: on_success
|
when: on_success
|
||||||
allow_failure: true
|
|
||||||
variables:
|
variables:
|
||||||
<<: *elastx_variables
|
<<: *elastx_variables
|
||||||
PROVIDER: openstack
|
PROVIDER: openstack
|
||||||
@@ -116,5 +114,5 @@ tf-elastx_ubuntu20-calico:
|
|||||||
TF_VAR_az_list_node: '["sto1"]'
|
TF_VAR_az_list_node: '["sto1"]'
|
||||||
TF_VAR_flavor_k8s_master: 3f73fc93-ec61-4808-88df-2580d94c1a9b # v1-standard-2
|
TF_VAR_flavor_k8s_master: 3f73fc93-ec61-4808-88df-2580d94c1a9b # v1-standard-2
|
||||||
TF_VAR_flavor_k8s_node: 3f73fc93-ec61-4808-88df-2580d94c1a9b # v1-standard-2
|
TF_VAR_flavor_k8s_node: 3f73fc93-ec61-4808-88df-2580d94c1a9b # v1-standard-2
|
||||||
TF_VAR_image: ubuntu-20.04-server-latest
|
TF_VAR_image: ubuntu-24.04-server-latest
|
||||||
TF_VAR_k8s_allowed_remote_ips: '["0.0.0.0/0"]'
|
TF_VAR_k8s_allowed_remote_ips: '["0.0.0.0/0"]'
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ vagrant:
|
|||||||
policy: pull-push # TODO: change to "pull" when not on main
|
policy: pull-push # TODO: change to "pull" when not on main
|
||||||
stage: deploy-extended
|
stage: deploy-extended
|
||||||
rules:
|
rules:
|
||||||
- if: $PR_LABELS =~ /.*(ci-extended|ci-full).*/
|
- if: $PR_LABELS =~ /.*ci-full.*/
|
||||||
when: on_success
|
when: on_success
|
||||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PIPELINE_SCHEDULE_DESCRIPTION == "daily-ci"
|
- if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PIPELINE_SCHEDULE_DESCRIPTION == "daily-ci"
|
||||||
when: on_success
|
when: on_success
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ RUN --mount=type=bind,source=requirements.txt,target=requirements.txt \
|
|||||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||||
|
|
||||||
RUN OS_ARCHITECTURE=$(dpkg --print-architecture) \
|
RUN OS_ARCHITECTURE=$(dpkg --print-architecture) \
|
||||||
&& curl -L "https://dl.k8s.io/release/v1.34.2/bin/linux/${OS_ARCHITECTURE}/kubectl" -o /usr/local/bin/kubectl \
|
&& curl -L "https://dl.k8s.io/release/v1.34.6/bin/linux/${OS_ARCHITECTURE}/kubectl" -o /usr/local/bin/kubectl \
|
||||||
&& echo "$(curl -L "https://dl.k8s.io/release/v1.34.2/bin/linux/${OS_ARCHITECTURE}/kubectl.sha256")" /usr/local/bin/kubectl | sha256sum --check \
|
&& echo "$(curl -L "https://dl.k8s.io/release/v1.34.6/bin/linux/${OS_ARCHITECTURE}/kubectl.sha256")" /usr/local/bin/kubectl | sha256sum --check \
|
||||||
&& chmod a+x /usr/local/bin/kubectl
|
&& chmod a+x /usr/local/bin/kubectl
|
||||||
|
|
||||||
COPY *.yml ./
|
COPY *.yml ./
|
||||||
|
|||||||
24
README.md
24
README.md
@@ -22,7 +22,7 @@ Ensure you have installed Docker then
|
|||||||
```ShellSession
|
```ShellSession
|
||||||
docker run --rm -it --mount type=bind,source="$(pwd)"/inventory/sample,dst=/inventory \
|
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 \
|
--mount type=bind,source="${HOME}"/.ssh/id_rsa,dst=/root/.ssh/id_rsa \
|
||||||
quay.io/kubespray/kubespray:v2.29.0 bash
|
quay.io/kubespray/kubespray:v2.30.0 bash
|
||||||
# Inside the container you may now run the kubespray playbooks:
|
# Inside the container you may now run the kubespray playbooks:
|
||||||
ansible-playbook -i /inventory/inventory.ini --private-key /root/.ssh/id_rsa cluster.yml
|
ansible-playbook -i /inventory/inventory.ini --private-key /root/.ssh/id_rsa cluster.yml
|
||||||
```
|
```
|
||||||
@@ -89,13 +89,13 @@ vagrant up
|
|||||||
- **Flatcar Container Linux by Kinvolk**
|
- **Flatcar Container Linux by Kinvolk**
|
||||||
- **Debian** Bookworm, Bullseye, Trixie
|
- **Debian** Bookworm, Bullseye, Trixie
|
||||||
- **Ubuntu** 22.04, 24.04
|
- **Ubuntu** 22.04, 24.04
|
||||||
- **CentOS/RHEL** [8, 9](docs/operating_systems/rhel.md#rhel-8)
|
- **CentOS Stream / RHEL** [9, 10](docs/operating_systems/rhel.md#rhel-8)
|
||||||
- **Fedora** 39, 40
|
- **Fedora** 39, 40
|
||||||
- **Fedora CoreOS** (see [fcos Note](docs/operating_systems/fcos.md))
|
- **Fedora CoreOS** (see [fcos Note](docs/operating_systems/fcos.md))
|
||||||
- **openSUSE** Leap 15.x/Tumbleweed
|
- **openSUSE** Leap 15.x/Tumbleweed
|
||||||
- **Oracle Linux** [8, 9](docs/operating_systems/rhel.md#rhel-8)
|
- **Oracle Linux** [9, 10](docs/operating_systems/rhel.md#rhel-8)
|
||||||
- **Alma Linux** [8, 9](docs/operating_systems/rhel.md#rhel-8)
|
- **Alma Linux** [9, 10](docs/operating_systems/rhel.md#rhel-8)
|
||||||
- **Rocky Linux** [8, 9](docs/operating_systems/rhel.md#rhel-8)
|
- **Rocky Linux** [9, 10](docs/operating_systems/rhel.md#rhel-8) (experimental in 10: see [Rocky Linux 10 notes](docs/operating_systems/rhel.md#rocky-linux-10))
|
||||||
- **Kylin Linux Advanced Server V10** (experimental: see [kylin linux notes](docs/operating_systems/kylinlinux.md))
|
- **Kylin Linux Advanced Server V10** (experimental: see [kylin linux notes](docs/operating_systems/kylinlinux.md))
|
||||||
- **Amazon Linux 2** (experimental: see [amazon linux notes](docs/operating_systems/amazonlinux.md))
|
- **Amazon Linux 2** (experimental: see [amazon linux notes](docs/operating_systems/amazonlinux.md))
|
||||||
- **UOS Linux** (experimental: see [uos linux notes](docs/operating_systems/uoslinux.md))
|
- **UOS Linux** (experimental: see [uos linux notes](docs/operating_systems/uoslinux.md))
|
||||||
@@ -111,20 +111,20 @@ Note:
|
|||||||
<!-- BEGIN ANSIBLE MANAGED BLOCK -->
|
<!-- BEGIN ANSIBLE MANAGED BLOCK -->
|
||||||
|
|
||||||
- Core
|
- Core
|
||||||
- [kubernetes](https://github.com/kubernetes/kubernetes) 1.34.2
|
- [kubernetes](https://github.com/kubernetes/kubernetes) 1.34.6
|
||||||
- [etcd](https://github.com/etcd-io/etcd) 3.5.25
|
- [etcd](https://github.com/etcd-io/etcd) 3.5.28
|
||||||
- [docker](https://www.docker.com/) 28.3
|
- [docker](https://www.docker.com/) 28.3
|
||||||
- [containerd](https://containerd.io/) 2.1.5
|
- [containerd](https://containerd.io/) 2.2.2
|
||||||
- [cri-o](http://cri-o.io/) 1.34.2 (experimental: see [CRI-O Note](docs/CRI/cri-o.md). Only on fedora, ubuntu and centos based OS)
|
- [cri-o](http://cri-o.io/) 1.34.6 (experimental: see [CRI-O Note](docs/CRI/cri-o.md). Only on fedora, ubuntu and centos based OS)
|
||||||
- Network Plugin
|
- Network Plugin
|
||||||
- [cni-plugins](https://github.com/containernetworking/plugins) 1.8.0
|
- [cni-plugins](https://github.com/containernetworking/plugins) 1.8.0
|
||||||
- [calico](https://github.com/projectcalico/calico) 3.30.5
|
- [calico](https://github.com/projectcalico/calico) 3.30.7
|
||||||
- [cilium](https://github.com/cilium/cilium) 1.18.4
|
- [cilium](https://github.com/cilium/cilium) 1.18.6
|
||||||
- [flannel](https://github.com/flannel-io/flannel) 0.27.3
|
- [flannel](https://github.com/flannel-io/flannel) 0.27.3
|
||||||
- [kube-ovn](https://github.com/alauda/kube-ovn) 1.12.21
|
- [kube-ovn](https://github.com/alauda/kube-ovn) 1.12.21
|
||||||
- [kube-router](https://github.com/cloudnativelabs/kube-router) 2.1.1
|
- [kube-router](https://github.com/cloudnativelabs/kube-router) 2.1.1
|
||||||
- [multus](https://github.com/k8snetworkplumbingwg/multus-cni) 4.2.2
|
- [multus](https://github.com/k8snetworkplumbingwg/multus-cni) 4.2.2
|
||||||
- [kube-vip](https://github.com/kube-vip/kube-vip) 0.8.0
|
- [kube-vip](https://github.com/kube-vip/kube-vip) 1.0.3
|
||||||
- Application
|
- Application
|
||||||
- [cert-manager](https://github.com/jetstack/cert-manager) 1.15.3
|
- [cert-manager](https://github.com/jetstack/cert-manager) 1.15.3
|
||||||
- [coredns](https://github.com/coredns/coredns) 1.12.1
|
- [coredns](https://github.com/coredns/coredns) 1.12.1
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ The Kubespray Project is released on an as-needed basis. The process is as follo
|
|||||||
1. The release issue is closed
|
1. The release issue is closed
|
||||||
1. An announcement email is sent to `dev@kubernetes.io` with the subject `[ANNOUNCE] Kubespray $VERSION is released`
|
1. An announcement email is sent to `dev@kubernetes.io` with the subject `[ANNOUNCE] Kubespray $VERSION is released`
|
||||||
1. The topic of the #kubespray channel is updated with `vX.Y.Z is released! | ...`
|
1. The topic of the #kubespray channel is updated with `vX.Y.Z is released! | ...`
|
||||||
1. Create/Update Issue for upgradeing kubernetes and [k8s-conformance](https://github.com/cncf/k8s-conformance)
|
1. Create/Update Issue for upgrading kubernetes and [k8s-conformance](https://github.com/cncf/k8s-conformance)
|
||||||
|
|
||||||
## Major/minor releases and milestones
|
## Major/minor releases and milestones
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ function create_container_image_tar() {
|
|||||||
|
|
||||||
kubectl describe cronjobs,jobs,pods --all-namespaces | grep " Image:" | awk '{print $2}' | sort | uniq > "${IMAGES}"
|
kubectl describe cronjobs,jobs,pods --all-namespaces | grep " Image:" | awk '{print $2}' | sort | uniq > "${IMAGES}"
|
||||||
# NOTE: etcd and pause cannot be seen as pods.
|
# NOTE: etcd and pause cannot be seen as pods.
|
||||||
# The pause image is used for --pod-infra-container-image option of kubelet.
|
|
||||||
kubectl cluster-info dump | grep -E "quay.io/coreos/etcd:|registry.k8s.io/pause:" | sed s@\"@@g >> "${IMAGES}"
|
kubectl cluster-info dump | grep -E "quay.io/coreos/etcd:|registry.k8s.io/pause:" | sed s@\"@@g >> "${IMAGES}"
|
||||||
else
|
else
|
||||||
echo "Getting images from file \"${IMAGES_FROM_FILE}\""
|
echo "Getting images from file \"${IMAGES_FROM_FILE}\""
|
||||||
|
|||||||
5
contrib/terraform/nifcloud/.gitignore
vendored
5
contrib/terraform/nifcloud/.gitignore
vendored
@@ -1,5 +0,0 @@
|
|||||||
*.tfstate*
|
|
||||||
.terraform.lock.hcl
|
|
||||||
.terraform
|
|
||||||
|
|
||||||
sample-inventory/inventory.ini
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
# Kubernetes on NIFCLOUD with Terraform
|
|
||||||
|
|
||||||
Provision a Kubernetes cluster on [NIFCLOUD](https://pfs.nifcloud.com/) using Terraform and Kubespray
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The setup looks like following
|
|
||||||
|
|
||||||
```text
|
|
||||||
Kubernetes cluster
|
|
||||||
+----------------------------+
|
|
||||||
+---------------+ | +--------------------+ |
|
|
||||||
| | | | +--------------------+ |
|
|
||||||
| API server LB +---------> | | | |
|
|
||||||
| | | | | Control Plane/etcd | |
|
|
||||||
+---------------+ | | | node(s) | |
|
|
||||||
| +-+ | |
|
|
||||||
| +--------------------+ |
|
|
||||||
| ^ |
|
|
||||||
| | |
|
|
||||||
| v |
|
|
||||||
| +--------------------+ |
|
|
||||||
| | +--------------------+ |
|
|
||||||
| | | | |
|
|
||||||
| | | Worker | |
|
|
||||||
| | | node(s) | |
|
|
||||||
| +-+ | |
|
|
||||||
| +--------------------+ |
|
|
||||||
+----------------------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
* Terraform 1.3.7
|
|
||||||
|
|
||||||
## Quickstart
|
|
||||||
|
|
||||||
### Export Variables
|
|
||||||
|
|
||||||
* Your NIFCLOUD credentials:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export NIFCLOUD_ACCESS_KEY_ID=<YOUR ACCESS KEY>
|
|
||||||
export NIFCLOUD_SECRET_ACCESS_KEY=<YOUR SECRET ACCESS KEY>
|
|
||||||
```
|
|
||||||
|
|
||||||
* The SSH KEY used to connect to the instance:
|
|
||||||
* FYI: [Cloud Help(SSH Key)](https://pfs.nifcloud.com/help/ssh.htm)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export TF_VAR_SSHKEY_NAME=<YOUR SSHKEY NAME>
|
|
||||||
```
|
|
||||||
|
|
||||||
* The IP address to connect to bastion server:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export TF_VAR_working_instance_ip=$(curl ifconfig.me)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create The Infrastructure
|
|
||||||
|
|
||||||
* Run terraform:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
terraform init
|
|
||||||
terraform apply -var-file ./sample-inventory/cluster.tfvars
|
|
||||||
```
|
|
||||||
|
|
||||||
### Setup The Kubernetes
|
|
||||||
|
|
||||||
* Generate cluster configuration file:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./generate-inventory.sh > sample-inventory/inventory.ini
|
|
||||||
```
|
|
||||||
|
|
||||||
* Export Variables:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
BASTION_IP=$(terraform output -json | jq -r '.kubernetes_cluster.value.bastion_info | to_entries[].value.public_ip')
|
|
||||||
API_LB_IP=$(terraform output -json | jq -r '.kubernetes_cluster.value.control_plane_lb')
|
|
||||||
CP01_IP=$(terraform output -json | jq -r '.kubernetes_cluster.value.control_plane_info | to_entries[0].value.private_ip')
|
|
||||||
export ANSIBLE_SSH_ARGS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ProxyCommand=\"ssh root@${BASTION_IP} -W %h:%p\""
|
|
||||||
```
|
|
||||||
|
|
||||||
* Set ssh-agent"
|
|
||||||
|
|
||||||
```bash
|
|
||||||
eval `ssh-agent`
|
|
||||||
ssh-add <THE PATH TO YOUR SSH KEY>
|
|
||||||
```
|
|
||||||
|
|
||||||
* Run cluster.yml playbook:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ./../../../
|
|
||||||
ansible-playbook -i contrib/terraform/nifcloud/inventory/inventory.ini cluster.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
### Connecting to Kubernetes
|
|
||||||
|
|
||||||
* [Install kubectl](https://kubernetes.io/docs/tasks/tools/) on the localhost
|
|
||||||
* Fetching kubeconfig file:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
mkdir -p ~/.kube
|
|
||||||
scp -o ProxyCommand="ssh root@${BASTION_IP} -W %h:%p" root@${CP01_IP}:/etc/kubernetes/admin.conf ~/.kube/config
|
|
||||||
```
|
|
||||||
|
|
||||||
* Rewrite /etc/hosts
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo echo "${API_LB_IP} lb-apiserver.kubernetes.local" >> /etc/hosts
|
|
||||||
```
|
|
||||||
|
|
||||||
* Run kubectl
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl get node
|
|
||||||
```
|
|
||||||
|
|
||||||
## Variables
|
|
||||||
|
|
||||||
* `region`: Region where to run the cluster
|
|
||||||
* `az`: Availability zone where to run the cluster
|
|
||||||
* `private_ip_bn`: Private ip address of bastion server
|
|
||||||
* `private_network_cidr`: Subnet of private network
|
|
||||||
* `instances_cp`: Machine to provision as Control Plane. Key of this object will be used as part of the machine' name
|
|
||||||
* `private_ip`: private ip address of machine
|
|
||||||
* `instances_wk`: Machine to provision as Worker Node. Key of this object will be used as part of the machine' name
|
|
||||||
* `private_ip`: private ip address of machine
|
|
||||||
* `instance_key_name`: The key name of the Key Pair to use for the instance
|
|
||||||
* `instance_type_bn`: The instance type of bastion server
|
|
||||||
* `instance_type_wk`: The instance type of worker node
|
|
||||||
* `instance_type_cp`: The instance type of control plane
|
|
||||||
* `image_name`: OS image used for the instance
|
|
||||||
* `working_instance_ip`: The IP address to connect to bastion server
|
|
||||||
* `accounting_type`: Accounting type. (1: monthly, 2: pay per use)
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generates a inventory file based on the terraform output.
|
|
||||||
# After provisioning a cluster, simply run this command and supply the terraform state file
|
|
||||||
# Default state file is terraform.tfstate
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
TF_OUT=$(terraform output -json)
|
|
||||||
|
|
||||||
CONTROL_PLANES=$(jq -r '.kubernetes_cluster.value.control_plane_info | to_entries[]' <(echo "${TF_OUT}"))
|
|
||||||
WORKERS=$(jq -r '.kubernetes_cluster.value.worker_info | to_entries[]' <(echo "${TF_OUT}"))
|
|
||||||
mapfile -t CONTROL_PLANE_NAMES < <(jq -r '.key' <(echo "${CONTROL_PLANES}"))
|
|
||||||
mapfile -t WORKER_NAMES < <(jq -r '.key' <(echo "${WORKERS}"))
|
|
||||||
|
|
||||||
API_LB=$(jq -r '.kubernetes_cluster.value.control_plane_lb' <(echo "${TF_OUT}"))
|
|
||||||
|
|
||||||
echo "[all]"
|
|
||||||
# Generate control plane hosts
|
|
||||||
i=1
|
|
||||||
for name in "${CONTROL_PLANE_NAMES[@]}"; do
|
|
||||||
private_ip=$(jq -r '. | select( .key=='"\"${name}\""' ) | .value.private_ip' <(echo "${CONTROL_PLANES}"))
|
|
||||||
echo "${name} ansible_user=root ansible_host=${private_ip} access_ip=${private_ip} ip=${private_ip} etcd_member_name=etcd${i}"
|
|
||||||
i=$(( i + 1 ))
|
|
||||||
done
|
|
||||||
|
|
||||||
# Generate worker hosts
|
|
||||||
for name in "${WORKER_NAMES[@]}"; do
|
|
||||||
private_ip=$(jq -r '. | select( .key=='"\"${name}\""' ) | .value.private_ip' <(echo "${WORKERS}"))
|
|
||||||
echo "${name} ansible_user=root ansible_host=${private_ip} access_ip=${private_ip} ip=${private_ip}"
|
|
||||||
done
|
|
||||||
|
|
||||||
API_LB=$(jq -r '.kubernetes_cluster.value.control_plane_lb' <(echo "${TF_OUT}"))
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[all:vars]"
|
|
||||||
echo "upstream_dns_servers=['8.8.8.8','8.8.4.4']"
|
|
||||||
echo "loadbalancer_apiserver={'address':'${API_LB}','port':'6443'}"
|
|
||||||
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[kube_control_plane]"
|
|
||||||
for name in "${CONTROL_PLANE_NAMES[@]}"; do
|
|
||||||
echo "${name}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[etcd]"
|
|
||||||
for name in "${CONTROL_PLANE_NAMES[@]}"; do
|
|
||||||
echo "${name}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[kube_node]"
|
|
||||||
for name in "${WORKER_NAMES[@]}"; do
|
|
||||||
echo "${name}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[k8s_cluster:children]"
|
|
||||||
echo "kube_control_plane"
|
|
||||||
echo "kube_node"
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
provider "nifcloud" {
|
|
||||||
region = var.region
|
|
||||||
}
|
|
||||||
|
|
||||||
module "kubernetes_cluster" {
|
|
||||||
source = "./modules/kubernetes-cluster"
|
|
||||||
|
|
||||||
availability_zone = var.az
|
|
||||||
prefix = "dev"
|
|
||||||
|
|
||||||
private_network_cidr = var.private_network_cidr
|
|
||||||
|
|
||||||
instance_key_name = var.instance_key_name
|
|
||||||
instances_cp = var.instances_cp
|
|
||||||
instances_wk = var.instances_wk
|
|
||||||
image_name = var.image_name
|
|
||||||
|
|
||||||
instance_type_bn = var.instance_type_bn
|
|
||||||
instance_type_cp = var.instance_type_cp
|
|
||||||
instance_type_wk = var.instance_type_wk
|
|
||||||
|
|
||||||
private_ip_bn = var.private_ip_bn
|
|
||||||
|
|
||||||
additional_lb_filter = [var.working_instance_ip]
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "nifcloud_security_group_rule" "ssh_from_bastion" {
|
|
||||||
security_group_names = [
|
|
||||||
module.kubernetes_cluster.security_group_name.bastion
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = 22
|
|
||||||
to_port = 22
|
|
||||||
protocol = "TCP"
|
|
||||||
cidr_ip = var.working_instance_ip
|
|
||||||
}
|
|
||||||
@@ -1,301 +0,0 @@
|
|||||||
#################################################
|
|
||||||
##
|
|
||||||
## Local variables
|
|
||||||
##
|
|
||||||
locals {
|
|
||||||
# e.g. east-11 is 11
|
|
||||||
az_num = reverse(split("-", var.availability_zone))[0]
|
|
||||||
# e.g. east-11 is e11
|
|
||||||
az_short_name = "${substr(reverse(split("-", var.availability_zone))[1], 0, 1)}${local.az_num}"
|
|
||||||
|
|
||||||
# Port used by the protocol
|
|
||||||
port_ssh = 22
|
|
||||||
port_kubectl = 6443
|
|
||||||
port_kubelet = 10250
|
|
||||||
|
|
||||||
# calico: https://docs.tigera.io/calico/latest/getting-started/kubernetes/requirements#network-requirements
|
|
||||||
port_bgp = 179
|
|
||||||
port_vxlan = 4789
|
|
||||||
port_etcd = 2379
|
|
||||||
}
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## General
|
|
||||||
##
|
|
||||||
|
|
||||||
# data
|
|
||||||
data "nifcloud_image" "this" {
|
|
||||||
image_name = var.image_name
|
|
||||||
}
|
|
||||||
|
|
||||||
# private lan
|
|
||||||
resource "nifcloud_private_lan" "this" {
|
|
||||||
private_lan_name = "${var.prefix}lan"
|
|
||||||
availability_zone = var.availability_zone
|
|
||||||
cidr_block = var.private_network_cidr
|
|
||||||
accounting_type = var.accounting_type
|
|
||||||
}
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## Bastion
|
|
||||||
##
|
|
||||||
resource "nifcloud_security_group" "bn" {
|
|
||||||
group_name = "${var.prefix}bn"
|
|
||||||
description = "${var.prefix} bastion"
|
|
||||||
availability_zone = var.availability_zone
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "nifcloud_instance" "bn" {
|
|
||||||
|
|
||||||
instance_id = "${local.az_short_name}${var.prefix}bn01"
|
|
||||||
security_group = nifcloud_security_group.bn.group_name
|
|
||||||
instance_type = var.instance_type_bn
|
|
||||||
|
|
||||||
user_data = templatefile("${path.module}/templates/userdata.tftpl", {
|
|
||||||
private_ip_address = var.private_ip_bn
|
|
||||||
ssh_port = local.port_ssh
|
|
||||||
hostname = "${local.az_short_name}${var.prefix}bn01"
|
|
||||||
})
|
|
||||||
|
|
||||||
availability_zone = var.availability_zone
|
|
||||||
accounting_type = var.accounting_type
|
|
||||||
image_id = data.nifcloud_image.this.image_id
|
|
||||||
key_name = var.instance_key_name
|
|
||||||
|
|
||||||
network_interface {
|
|
||||||
network_id = "net-COMMON_GLOBAL"
|
|
||||||
}
|
|
||||||
network_interface {
|
|
||||||
network_id = nifcloud_private_lan.this.network_id
|
|
||||||
ip_address = "static"
|
|
||||||
}
|
|
||||||
|
|
||||||
# The image_id changes when the OS image type is demoted from standard to public.
|
|
||||||
lifecycle {
|
|
||||||
ignore_changes = [
|
|
||||||
image_id,
|
|
||||||
user_data,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## Control Plane
|
|
||||||
##
|
|
||||||
resource "nifcloud_security_group" "cp" {
|
|
||||||
group_name = "${var.prefix}cp"
|
|
||||||
description = "${var.prefix} control plane"
|
|
||||||
availability_zone = var.availability_zone
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "nifcloud_instance" "cp" {
|
|
||||||
for_each = var.instances_cp
|
|
||||||
|
|
||||||
instance_id = "${local.az_short_name}${var.prefix}${each.key}"
|
|
||||||
security_group = nifcloud_security_group.cp.group_name
|
|
||||||
instance_type = var.instance_type_cp
|
|
||||||
user_data = templatefile("${path.module}/templates/userdata.tftpl", {
|
|
||||||
private_ip_address = each.value.private_ip
|
|
||||||
ssh_port = local.port_ssh
|
|
||||||
hostname = "${local.az_short_name}${var.prefix}${each.key}"
|
|
||||||
})
|
|
||||||
|
|
||||||
availability_zone = var.availability_zone
|
|
||||||
accounting_type = var.accounting_type
|
|
||||||
image_id = data.nifcloud_image.this.image_id
|
|
||||||
key_name = var.instance_key_name
|
|
||||||
|
|
||||||
network_interface {
|
|
||||||
network_id = "net-COMMON_GLOBAL"
|
|
||||||
}
|
|
||||||
network_interface {
|
|
||||||
network_id = nifcloud_private_lan.this.network_id
|
|
||||||
ip_address = "static"
|
|
||||||
}
|
|
||||||
|
|
||||||
# The image_id changes when the OS image type is demoted from standard to public.
|
|
||||||
lifecycle {
|
|
||||||
ignore_changes = [
|
|
||||||
image_id,
|
|
||||||
user_data,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "nifcloud_load_balancer" "this" {
|
|
||||||
load_balancer_name = "${local.az_short_name}${var.prefix}cp"
|
|
||||||
accounting_type = var.accounting_type
|
|
||||||
balancing_type = 1 // Round-Robin
|
|
||||||
load_balancer_port = local.port_kubectl
|
|
||||||
instance_port = local.port_kubectl
|
|
||||||
instances = [for v in nifcloud_instance.cp : v.instance_id]
|
|
||||||
filter = concat(
|
|
||||||
[for k, v in nifcloud_instance.cp : v.public_ip],
|
|
||||||
[for k, v in nifcloud_instance.wk : v.public_ip],
|
|
||||||
var.additional_lb_filter,
|
|
||||||
)
|
|
||||||
filter_type = 1 // Allow
|
|
||||||
}
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## Worker
|
|
||||||
##
|
|
||||||
resource "nifcloud_security_group" "wk" {
|
|
||||||
group_name = "${var.prefix}wk"
|
|
||||||
description = "${var.prefix} worker"
|
|
||||||
availability_zone = var.availability_zone
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "nifcloud_instance" "wk" {
|
|
||||||
for_each = var.instances_wk
|
|
||||||
|
|
||||||
instance_id = "${local.az_short_name}${var.prefix}${each.key}"
|
|
||||||
security_group = nifcloud_security_group.wk.group_name
|
|
||||||
instance_type = var.instance_type_wk
|
|
||||||
user_data = templatefile("${path.module}/templates/userdata.tftpl", {
|
|
||||||
private_ip_address = each.value.private_ip
|
|
||||||
ssh_port = local.port_ssh
|
|
||||||
hostname = "${local.az_short_name}${var.prefix}${each.key}"
|
|
||||||
})
|
|
||||||
|
|
||||||
availability_zone = var.availability_zone
|
|
||||||
accounting_type = var.accounting_type
|
|
||||||
image_id = data.nifcloud_image.this.image_id
|
|
||||||
key_name = var.instance_key_name
|
|
||||||
|
|
||||||
network_interface {
|
|
||||||
network_id = "net-COMMON_GLOBAL"
|
|
||||||
}
|
|
||||||
network_interface {
|
|
||||||
network_id = nifcloud_private_lan.this.network_id
|
|
||||||
ip_address = "static"
|
|
||||||
}
|
|
||||||
|
|
||||||
# The image_id changes when the OS image type is demoted from standard to public.
|
|
||||||
lifecycle {
|
|
||||||
ignore_changes = [
|
|
||||||
image_id,
|
|
||||||
user_data,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## Security Group Rule: Kubernetes
|
|
||||||
##
|
|
||||||
|
|
||||||
# ssh
|
|
||||||
resource "nifcloud_security_group_rule" "ssh_from_bastion" {
|
|
||||||
security_group_names = [
|
|
||||||
nifcloud_security_group.wk.group_name,
|
|
||||||
nifcloud_security_group.cp.group_name,
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = local.port_ssh
|
|
||||||
to_port = local.port_ssh
|
|
||||||
protocol = "TCP"
|
|
||||||
source_security_group_name = nifcloud_security_group.bn.group_name
|
|
||||||
}
|
|
||||||
|
|
||||||
# kubectl
|
|
||||||
resource "nifcloud_security_group_rule" "kubectl_from_worker" {
|
|
||||||
security_group_names = [
|
|
||||||
nifcloud_security_group.cp.group_name,
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = local.port_kubectl
|
|
||||||
to_port = local.port_kubectl
|
|
||||||
protocol = "TCP"
|
|
||||||
source_security_group_name = nifcloud_security_group.wk.group_name
|
|
||||||
}
|
|
||||||
|
|
||||||
# kubelet
|
|
||||||
resource "nifcloud_security_group_rule" "kubelet_from_worker" {
|
|
||||||
security_group_names = [
|
|
||||||
nifcloud_security_group.cp.group_name,
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = local.port_kubelet
|
|
||||||
to_port = local.port_kubelet
|
|
||||||
protocol = "TCP"
|
|
||||||
source_security_group_name = nifcloud_security_group.wk.group_name
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "nifcloud_security_group_rule" "kubelet_from_control_plane" {
|
|
||||||
security_group_names = [
|
|
||||||
nifcloud_security_group.wk.group_name,
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = local.port_kubelet
|
|
||||||
to_port = local.port_kubelet
|
|
||||||
protocol = "TCP"
|
|
||||||
source_security_group_name = nifcloud_security_group.cp.group_name
|
|
||||||
}
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## Security Group Rule: calico
|
|
||||||
##
|
|
||||||
|
|
||||||
# vslan
|
|
||||||
resource "nifcloud_security_group_rule" "vxlan_from_control_plane" {
|
|
||||||
security_group_names = [
|
|
||||||
nifcloud_security_group.wk.group_name,
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = local.port_vxlan
|
|
||||||
to_port = local.port_vxlan
|
|
||||||
protocol = "UDP"
|
|
||||||
source_security_group_name = nifcloud_security_group.cp.group_name
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "nifcloud_security_group_rule" "vxlan_from_worker" {
|
|
||||||
security_group_names = [
|
|
||||||
nifcloud_security_group.cp.group_name,
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = local.port_vxlan
|
|
||||||
to_port = local.port_vxlan
|
|
||||||
protocol = "UDP"
|
|
||||||
source_security_group_name = nifcloud_security_group.wk.group_name
|
|
||||||
}
|
|
||||||
|
|
||||||
# bgp
|
|
||||||
resource "nifcloud_security_group_rule" "bgp_from_control_plane" {
|
|
||||||
security_group_names = [
|
|
||||||
nifcloud_security_group.wk.group_name,
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = local.port_bgp
|
|
||||||
to_port = local.port_bgp
|
|
||||||
protocol = "TCP"
|
|
||||||
source_security_group_name = nifcloud_security_group.cp.group_name
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "nifcloud_security_group_rule" "bgp_from_worker" {
|
|
||||||
security_group_names = [
|
|
||||||
nifcloud_security_group.cp.group_name,
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = local.port_bgp
|
|
||||||
to_port = local.port_bgp
|
|
||||||
protocol = "TCP"
|
|
||||||
source_security_group_name = nifcloud_security_group.wk.group_name
|
|
||||||
}
|
|
||||||
|
|
||||||
# etcd
|
|
||||||
resource "nifcloud_security_group_rule" "etcd_from_worker" {
|
|
||||||
security_group_names = [
|
|
||||||
nifcloud_security_group.cp.group_name,
|
|
||||||
]
|
|
||||||
type = "IN"
|
|
||||||
from_port = local.port_etcd
|
|
||||||
to_port = local.port_etcd
|
|
||||||
protocol = "TCP"
|
|
||||||
source_security_group_name = nifcloud_security_group.wk.group_name
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
output "control_plane_lb" {
|
|
||||||
description = "The DNS name of LB for control plane"
|
|
||||||
value = nifcloud_load_balancer.this.dns_name
|
|
||||||
}
|
|
||||||
|
|
||||||
output "security_group_name" {
|
|
||||||
description = "The security group used in the cluster"
|
|
||||||
value = {
|
|
||||||
bastion = nifcloud_security_group.bn.group_name,
|
|
||||||
control_plane = nifcloud_security_group.cp.group_name,
|
|
||||||
worker = nifcloud_security_group.wk.group_name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output "private_network_id" {
|
|
||||||
description = "The private network used in the cluster"
|
|
||||||
value = nifcloud_private_lan.this.id
|
|
||||||
}
|
|
||||||
|
|
||||||
output "bastion_info" {
|
|
||||||
description = "The basion information in cluster"
|
|
||||||
value = { (nifcloud_instance.bn.instance_id) : {
|
|
||||||
instance_id = nifcloud_instance.bn.instance_id,
|
|
||||||
unique_id = nifcloud_instance.bn.unique_id,
|
|
||||||
private_ip = nifcloud_instance.bn.private_ip,
|
|
||||||
public_ip = nifcloud_instance.bn.public_ip,
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
|
|
||||||
output "worker_info" {
|
|
||||||
description = "The worker information in cluster"
|
|
||||||
value = { for v in nifcloud_instance.wk : v.instance_id => {
|
|
||||||
instance_id = v.instance_id,
|
|
||||||
unique_id = v.unique_id,
|
|
||||||
private_ip = v.private_ip,
|
|
||||||
public_ip = v.public_ip,
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
|
|
||||||
output "control_plane_info" {
|
|
||||||
description = "The control plane information in cluster"
|
|
||||||
value = { for v in nifcloud_instance.cp : v.instance_id => {
|
|
||||||
instance_id = v.instance_id,
|
|
||||||
unique_id = v.unique_id,
|
|
||||||
private_ip = v.private_ip,
|
|
||||||
public_ip = v.public_ip,
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## IP Address
|
|
||||||
##
|
|
||||||
configure_private_ip_address () {
|
|
||||||
cat << EOS > /etc/netplan/01-netcfg.yaml
|
|
||||||
network:
|
|
||||||
version: 2
|
|
||||||
renderer: networkd
|
|
||||||
ethernets:
|
|
||||||
ens192:
|
|
||||||
dhcp4: yes
|
|
||||||
dhcp6: yes
|
|
||||||
dhcp-identifier: mac
|
|
||||||
ens224:
|
|
||||||
dhcp4: no
|
|
||||||
dhcp6: no
|
|
||||||
addresses: [${private_ip_address}]
|
|
||||||
EOS
|
|
||||||
netplan apply
|
|
||||||
}
|
|
||||||
configure_private_ip_address
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## SSH
|
|
||||||
##
|
|
||||||
configure_ssh_port () {
|
|
||||||
sed -i 's/^#*Port [0-9]*/Port ${ssh_port}/' /etc/ssh/sshd_config
|
|
||||||
}
|
|
||||||
configure_ssh_port
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## Hostname
|
|
||||||
##
|
|
||||||
hostnamectl set-hostname ${hostname}
|
|
||||||
|
|
||||||
#################################################
|
|
||||||
##
|
|
||||||
## Disable swap files genereated by systemd-gpt-auto-generator
|
|
||||||
##
|
|
||||||
systemctl mask "dev-sda3.swap"
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
terraform {
|
|
||||||
required_version = ">=1.3.7"
|
|
||||||
required_providers {
|
|
||||||
nifcloud = {
|
|
||||||
source = "nifcloud/nifcloud"
|
|
||||||
version = ">= 1.8.0, < 2.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
variable "availability_zone" {
|
|
||||||
description = "The availability zone"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "prefix" {
|
|
||||||
description = "The prefix for the entire cluster"
|
|
||||||
type = string
|
|
||||||
validation {
|
|
||||||
condition = length(var.prefix) <= 5
|
|
||||||
error_message = "Must be a less than 5 character long."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "private_network_cidr" {
|
|
||||||
description = "The subnet of private network"
|
|
||||||
type = string
|
|
||||||
validation {
|
|
||||||
condition = can(cidrnetmask(var.private_network_cidr))
|
|
||||||
error_message = "Must be a valid IPv4 CIDR block address."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "private_ip_bn" {
|
|
||||||
description = "Private IP of bastion server"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instances_cp" {
|
|
||||||
type = map(object({
|
|
||||||
private_ip = string
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instances_wk" {
|
|
||||||
type = map(object({
|
|
||||||
private_ip = string
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instance_key_name" {
|
|
||||||
description = "The key name of the Key Pair to use for the instance"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instance_type_bn" {
|
|
||||||
description = "The instance type of bastion server"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instance_type_wk" {
|
|
||||||
description = "The instance type of worker"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instance_type_cp" {
|
|
||||||
description = "The instance type of control plane"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "image_name" {
|
|
||||||
description = "The name of image"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "additional_lb_filter" {
|
|
||||||
description = "Additional LB filter"
|
|
||||||
type = list(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "accounting_type" {
|
|
||||||
type = string
|
|
||||||
default = "1"
|
|
||||||
validation {
|
|
||||||
condition = anytrue([
|
|
||||||
var.accounting_type == "1", // Monthly
|
|
||||||
var.accounting_type == "2", // Pay per use
|
|
||||||
])
|
|
||||||
error_message = "Must be a 1 or 2."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
output "kubernetes_cluster" {
|
|
||||||
value = module.kubernetes_cluster
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
region = "jp-west-1"
|
|
||||||
az = "west-11"
|
|
||||||
|
|
||||||
instance_key_name = "deployerkey"
|
|
||||||
|
|
||||||
instance_type_bn = "e-medium"
|
|
||||||
instance_type_cp = "e-medium"
|
|
||||||
instance_type_wk = "e-medium"
|
|
||||||
|
|
||||||
private_network_cidr = "192.168.30.0/24"
|
|
||||||
instances_cp = {
|
|
||||||
"cp01" : { private_ip : "192.168.30.11/24" }
|
|
||||||
"cp02" : { private_ip : "192.168.30.12/24" }
|
|
||||||
"cp03" : { private_ip : "192.168.30.13/24" }
|
|
||||||
}
|
|
||||||
instances_wk = {
|
|
||||||
"wk01" : { private_ip : "192.168.30.21/24" }
|
|
||||||
"wk02" : { private_ip : "192.168.30.22/24" }
|
|
||||||
}
|
|
||||||
private_ip_bn = "192.168.30.10/24"
|
|
||||||
|
|
||||||
image_name = "Ubuntu Server 22.04 LTS"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../inventory/sample/group_vars
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
terraform {
|
|
||||||
required_version = ">=1.3.7"
|
|
||||||
required_providers {
|
|
||||||
nifcloud = {
|
|
||||||
source = "nifcloud/nifcloud"
|
|
||||||
version = "1.8.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
variable "region" {
|
|
||||||
description = "The region"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "az" {
|
|
||||||
description = "The availability zone"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "private_ip_bn" {
|
|
||||||
description = "Private IP of bastion server"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "private_network_cidr" {
|
|
||||||
description = "The subnet of private network"
|
|
||||||
type = string
|
|
||||||
validation {
|
|
||||||
condition = can(cidrnetmask(var.private_network_cidr))
|
|
||||||
error_message = "Must be a valid IPv4 CIDR block address."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instances_cp" {
|
|
||||||
type = map(object({
|
|
||||||
private_ip = string
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instances_wk" {
|
|
||||||
type = map(object({
|
|
||||||
private_ip = string
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instance_key_name" {
|
|
||||||
description = "The key name of the Key Pair to use for the instance"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instance_type_bn" {
|
|
||||||
description = "The instance type of bastion server"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instance_type_wk" {
|
|
||||||
description = "The instance type of worker"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "instance_type_cp" {
|
|
||||||
description = "The instance type of control plane"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "image_name" {
|
|
||||||
description = "The name of image"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "working_instance_ip" {
|
|
||||||
description = "The IP address to connect to bastion server."
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "accounting_type" {
|
|
||||||
type = string
|
|
||||||
default = "2"
|
|
||||||
validation {
|
|
||||||
condition = anytrue([
|
|
||||||
var.accounting_type == "1", // Monthly
|
|
||||||
var.accounting_type == "2", // Pay per use
|
|
||||||
])
|
|
||||||
error_message = "Must be a 1 or 2."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -281,9 +281,9 @@ For your cluster, edit `inventory/$CLUSTER/cluster.tfvars`.
|
|||||||
|`k8s_allowed_remote_ips_ipv6` | List of IPv6 CIDR allowed to initiate a SSH connection, empty by default |
|
|`k8s_allowed_remote_ips_ipv6` | List of IPv6 CIDR allowed to initiate a SSH connection, empty by default |
|
||||||
|`k8s_allowed_egress_ipv6_ips` | List of IPv6 CIDRs allowed for egress traffic, `["::/0"]` by default |
|
|`k8s_allowed_egress_ipv6_ips` | List of IPv6 CIDRs allowed for egress traffic, `["::/0"]` by default |
|
||||||
|`worker_allowed_ports` | List of ports to open on worker nodes, `[{ "protocol" = "tcp", "port_range_min" = 30000, "port_range_max" = 32767, "remote_ip_prefix" = "0.0.0.0/0"}]` by default |
|
|`worker_allowed_ports` | List of ports to open on worker nodes, `[{ "protocol" = "tcp", "port_range_min" = 30000, "port_range_max" = 32767, "remote_ip_prefix" = "0.0.0.0/0"}]` by default |
|
||||||
|`worker_allowed_ports_ipv6` | List of ports to open on worker nodes for IPv6 CIDR blocks, `[{ "protocol" = "tcp", "port_range_min" = 30000, "port_range_max" = 32767, "remote_ip_prefix" = "::/0"}]` by default |
|
|`worker_allowed_ports_ipv6` | List of ports to open on worker nodes for IPv6 CIDR blocks, `[{ "protocol" = "tcp", "port_range_min" = 30000, "port_range_max" = 32767, "remote_ip_prefix" = "::/0"}, { "protocol" = "ipv6-icmp", "port_range_min" = 0, "port_range_max" = 0, "remote_ip_prefix" = "::/0"}]` by default |
|
||||||
|`master_allowed_ports` | List of ports to open on master nodes, expected format is `[{ "protocol" = "tcp", "port_range_min" = 443, "port_range_max" = 443, "remote_ip_prefix" = "0.0.0.0/0"}]`, empty by default |
|
|`master_allowed_ports` | List of ports to open on master nodes, expected format is `[{ "protocol" = "tcp", "port_range_min" = 443, "port_range_max" = 443, "remote_ip_prefix" = "0.0.0.0/0"}]`, empty by default |
|
||||||
|`master_allowed_ports_ipv6` | List of ports to open on master nodes for IPv6 CIDR blocks, expected format is `[{ "protocol" = "tcp", "port_range_min" = 443, "port_range_max" = 443, "remote_ip_prefix" = "::/0"}]`, empty by default |
|
|`master_allowed_ports_ipv6` | List of ports to open on master nodes for IPv6 CIDR blocks, `[{ "protocol" = "ipv6-icmp", "port_range_min" = 0, "port_range_max" = 0, "remote_ip_prefix" = "::/0"}]` by default |
|
||||||
|`node_root_volume_size_in_gb` | Size of the root volume for nodes, 0 to use ephemeral storage |
|
|`node_root_volume_size_in_gb` | Size of the root volume for nodes, 0 to use ephemeral storage |
|
||||||
|`master_root_volume_size_in_gb` | Size of the root volume for masters, 0 to use ephemeral storage |
|
|`master_root_volume_size_in_gb` | Size of the root volume for masters, 0 to use ephemeral storage |
|
||||||
|`master_volume_type` | Volume type of the root volume for control_plane, 'Default' by default |
|
|`master_volume_type` | Volume type of the root volume for control_plane, 'Default' by default |
|
||||||
|
|||||||
@@ -271,7 +271,14 @@ variable "master_allowed_ports" {
|
|||||||
variable "master_allowed_ports_ipv6" {
|
variable "master_allowed_ports_ipv6" {
|
||||||
type = list(any)
|
type = list(any)
|
||||||
|
|
||||||
default = []
|
default = [
|
||||||
|
{
|
||||||
|
"protocol" = "ipv6-icmp"
|
||||||
|
"port_range_min" = 0
|
||||||
|
"port_range_max" = 0
|
||||||
|
"remote_ip_prefix" = "::/0"
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "worker_allowed_ports" {
|
variable "worker_allowed_ports" {
|
||||||
@@ -297,6 +304,12 @@ variable "worker_allowed_ports_ipv6" {
|
|||||||
"port_range_max" = 32767
|
"port_range_max" = 32767
|
||||||
"remote_ip_prefix" = "::/0"
|
"remote_ip_prefix" = "::/0"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"protocol" = "ipv6-icmp"
|
||||||
|
"port_range_min" = 0
|
||||||
|
"port_range_max" = 0
|
||||||
|
"remote_ip_prefix" = "::/0"
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
# Cilium
|
# Cilium
|
||||||
|
|
||||||
|
## Unprivileged agent configuration
|
||||||
|
|
||||||
|
By default, Cilium is installed with `securityContext.privileged: false`. You need to set the `kube_owner` variable to `root` in the inventory:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
kube_owner: root
|
||||||
|
```
|
||||||
|
|
||||||
## IP Address Management (IPAM)
|
## 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".
|
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".
|
||||||
@@ -237,7 +245,7 @@ cilium_operator_extra_volume_mounts:
|
|||||||
## Choose Cilium version
|
## Choose Cilium version
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
cilium_version: "1.18.4"
|
cilium_version: "1.18.6"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Add variable to config
|
## Add variable to config
|
||||||
|
|||||||
@@ -65,9 +65,8 @@ In kubespray, the default runtime name is "runc", and it can be configured with
|
|||||||
containerd_runc_runtime:
|
containerd_runc_runtime:
|
||||||
name: runc
|
name: runc
|
||||||
type: "io.containerd.runc.v2"
|
type: "io.containerd.runc.v2"
|
||||||
engine: ""
|
|
||||||
root: ""
|
|
||||||
options:
|
options:
|
||||||
|
Root: ""
|
||||||
SystemdCgroup: "false"
|
SystemdCgroup: "false"
|
||||||
BinaryName: /usr/local/bin/my-runc
|
BinaryName: /usr/local/bin/my-runc
|
||||||
base_runtime_spec: cri-base.json
|
base_runtime_spec: cri-base.json
|
||||||
|
|||||||
@@ -45,10 +45,7 @@ Kubespray expects users to use one of the following variables sources for settin
|
|||||||
| - inventory host_vars | host specific vars overrides, group_vars is usually more practical |
|
| - inventory host_vars | host specific vars overrides, group_vars is usually more practical |
|
||||||
| **extra vars** (always win precedence) | override with ``ansible-playbook -e @foo.yml`` |
|
| **extra vars** (always win precedence) | override with ``ansible-playbook -e @foo.yml`` |
|
||||||
|
|
||||||
[!IMPORTANT]
|
> Extra vars are best used to override kubespray internal variables, for instances, roles/vars/. Those vars are usually **not expected** (by Kubespray developers) to be modified by end users, and not part of Kubespray interface. Thus they can change, disappear, or break stuff unexpectedly.
|
||||||
Extra vars are best used to override kubespray internal variables, for instances, roles/vars/.
|
|
||||||
Those vars are usually **not expected** (by Kubespray developers) to be modified by end users, and not part of Kubespray
|
|
||||||
interface. Thus they can change, disappear, or break stuff unexpectedly.
|
|
||||||
|
|
||||||
## Ansible tags
|
## Ansible tags
|
||||||
|
|
||||||
@@ -196,11 +193,11 @@ 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:
|
to access the inventory and SSH key in the container, like this:
|
||||||
|
|
||||||
```ShellSession
|
```ShellSession
|
||||||
git checkout v2.29.0
|
git checkout v2.30.0
|
||||||
docker pull quay.io/kubespray/kubespray:v2.29.0
|
docker pull quay.io/kubespray/kubespray:v2.30.0
|
||||||
docker run --rm -it --mount type=bind,source="$(pwd)"/inventory/sample,dst=/inventory \
|
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 \
|
--mount type=bind,source="${HOME}"/.ssh/id_rsa,dst=/root/.ssh/id_rsa \
|
||||||
quay.io/kubespray/kubespray:v2.29.0 bash
|
quay.io/kubespray/kubespray:v2.30.0 bash
|
||||||
# Inside the container you may now run the kubespray playbooks:
|
# Inside the container you may now run the kubespray playbooks:
|
||||||
ansible-playbook -i /inventory/inventory.ini --private-key /root/.ssh/id_rsa cluster.yml
|
ansible-playbook -i /inventory/inventory.ini --private-key /root/.ssh/id_rsa cluster.yml
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ fedora39 | :white_check_mark: | :x: | :x: | :x: | :x: | :white_check_mark: | :x
|
|||||||
fedora40 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
fedora40 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
flatcar4081 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
flatcar4081 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
openeuler24 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
openeuler24 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
|
rockylinux10 | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||||
rockylinux9 | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
rockylinux9 | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||||
ubuntu20 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
|
||||||
ubuntu22 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
ubuntu22 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
ubuntu24 | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: |
|
ubuntu24 | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: |
|
||||||
|
|
||||||
@@ -33,8 +33,8 @@ fedora39 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
|||||||
fedora40 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
fedora40 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
flatcar4081 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
flatcar4081 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
openeuler24 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
openeuler24 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
|
rockylinux10 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
rockylinux9 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
rockylinux9 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
ubuntu20 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
|
||||||
ubuntu22 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
ubuntu22 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
ubuntu24 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
ubuntu24 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ fedora39 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
|||||||
fedora40 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
fedora40 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
flatcar4081 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
flatcar4081 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
openeuler24 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
openeuler24 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
|
rockylinux10 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
rockylinux9 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
rockylinux9 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
ubuntu20 | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
|
||||||
ubuntu22 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
ubuntu22 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
ubuntu24 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
ubuntu24 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ metallb_enabled: true
|
|||||||
metallb_speaker_enabled: true
|
metallb_speaker_enabled: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
By default, MetalLB resources are deployed into the `metallb-system` namespace. You can override this namespace using a variable.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
metallb_namespace: woodenlb-system
|
||||||
|
```
|
||||||
|
|
||||||
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:
|
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
|
```yaml
|
||||||
|
|||||||
@@ -38,3 +38,11 @@ you need to ensure they are using iptables-nft.
|
|||||||
An example how k8s do the autodetection can be found [in this PR](https://github.com/kubernetes/kubernetes/pull/82966)
|
An example how k8s do the autodetection can be found [in this PR](https://github.com/kubernetes/kubernetes/pull/82966)
|
||||||
|
|
||||||
The kernel version is lower than the kubernetes 1.32 system validation, please refer to the [kernel requirements](../operations/kernel-requirements.md).
|
The kernel version is lower than the kubernetes 1.32 system validation, please refer to the [kernel requirements](../operations/kernel-requirements.md).
|
||||||
|
|
||||||
|
## Rocky Linux 10
|
||||||
|
|
||||||
|
(Experimental in Kubespray CI)
|
||||||
|
|
||||||
|
The official Rocky Linux 10 cloud image does not include `kernel-module-extra`. Both Kube Proxy and CNI rely on this package, and since it relates to kernel version compatibility (which may require VM reboots, etc.), we haven't found an ideal solution.
|
||||||
|
|
||||||
|
However, some users report that it doesn't affect them (minimal version). Therefore, the Kubespray CI Rocky Linux 10 image is built by Kubespray maintainers using `diskimage-builder`. For detailed methods, please refer to [the comments](https://github.com/kubernetes-sigs/kubespray/pull/12355#issuecomment-3705400093).
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
namespace: kubernetes_sigs
|
namespace: kubernetes_sigs
|
||||||
description: Deploy a production ready Kubernetes cluster
|
description: Deploy a production ready Kubernetes cluster
|
||||||
name: kubespray
|
name: kubespray
|
||||||
version: 2.30.0
|
version: 2.30.1
|
||||||
readme: README.md
|
readme: README.md
|
||||||
authors:
|
authors:
|
||||||
- The Kubespray maintainers (https://kubernetes.slack.com/channels/kubespray)
|
- The Kubespray maintainers (https://kubernetes.slack.com/channels/kubespray)
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
loadSidebar: 'docs/_sidebar.md',
|
loadSidebar: 'docs/_sidebar.md',
|
||||||
repo: 'https://github.com/kubernetes-sigs/kubespray',
|
repo: 'https://github.com/kubernetes-sigs/kubespray',
|
||||||
auto2top: true,
|
auto2top: true,
|
||||||
|
noCompileLinks: ['.*\.ini'],
|
||||||
logo: '/logo/logo-clear.png'
|
logo: '/logo/logo-clear.png'
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -11,15 +11,15 @@
|
|||||||
# containerd_runc_runtime:
|
# containerd_runc_runtime:
|
||||||
# name: runc
|
# name: runc
|
||||||
# type: "io.containerd.runc.v2"
|
# type: "io.containerd.runc.v2"
|
||||||
# engine: ""
|
# options:
|
||||||
# root: ""
|
# Root: ""
|
||||||
|
|
||||||
# containerd_additional_runtimes:
|
# containerd_additional_runtimes:
|
||||||
# Example for Kata Containers as additional runtime:
|
# Example for Kata Containers as additional runtime:
|
||||||
# - name: kata
|
# - name: kata
|
||||||
# type: "io.containerd.kata.v2"
|
# type: "io.containerd.kata.v2"
|
||||||
# engine: ""
|
# options:
|
||||||
# root: ""
|
# Root: ""
|
||||||
|
|
||||||
# containerd_grpc_max_recv_message_size: 16777216
|
# containerd_grpc_max_recv_message_size: 16777216
|
||||||
# containerd_grpc_max_send_message_size: 16777216
|
# containerd_grpc_max_send_message_size: 16777216
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ local_release_dir: "/tmp/releases"
|
|||||||
# Random shifts for retrying failed ops like pushing/downloading
|
# Random shifts for retrying failed ops like pushing/downloading
|
||||||
retry_stagger: 5
|
retry_stagger: 5
|
||||||
|
|
||||||
# This is the user that owns tha cluster installation.
|
# This is the user that owns the cluster installation.
|
||||||
|
# Note: cilium needs to set kube_owner to root https://kubespray.io/#/docs/CNI/cilium?id=unprivileged-agent-configuration
|
||||||
kube_owner: kube
|
kube_owner: kube
|
||||||
|
|
||||||
# This is the group that the cert creation scripts chgrp the
|
# This is the group that the cert creation scripts chgrp the
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ cilium_l2announcements: false
|
|||||||
#
|
#
|
||||||
# Only effective when monitor aggregation is set to "medium" or higher.
|
# Only effective when monitor aggregation is set to "medium" or higher.
|
||||||
# cilium_monitor_aggregation_flags: "all"
|
# cilium_monitor_aggregation_flags: "all"
|
||||||
# Kube Proxy Replacement mode (strict/partial)
|
# Kube Proxy Replacement mode (true/false)
|
||||||
# cilium_kube_proxy_replacement: partial
|
# cilium_kube_proxy_replacement: false
|
||||||
|
|
||||||
# If upgrading from Cilium < 1.5, you may want to override some of these options
|
# If upgrading from Cilium < 1.5, you may want to override some of these options
|
||||||
# to prevent service disruptions. See also:
|
# to prevent service disruptions. See also:
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1 \
|
|||||||
&& pip install --no-compile --no-cache-dir pip -U \
|
&& pip install --no-compile --no-cache-dir pip -U \
|
||||||
&& pip install --no-compile --no-cache-dir -r tests/requirements.txt \
|
&& pip install --no-compile --no-cache-dir -r tests/requirements.txt \
|
||||||
&& pip install --no-compile --no-cache-dir -r requirements.txt \
|
&& pip install --no-compile --no-cache-dir -r requirements.txt \
|
||||||
&& curl -L https://dl.k8s.io/release/v1.34.2/bin/linux/$(dpkg --print-architecture)/kubectl -o /usr/local/bin/kubectl \
|
&& curl -L https://dl.k8s.io/release/v1.34.6/bin/linux/$(dpkg --print-architecture)/kubectl -o /usr/local/bin/kubectl \
|
||||||
&& echo $(curl -L https://dl.k8s.io/release/v1.34.2/bin/linux/$(dpkg --print-architecture)/kubectl.sha256) /usr/local/bin/kubectl | sha256sum --check \
|
&& echo $(curl -L https://dl.k8s.io/release/v1.34.6/bin/linux/$(dpkg --print-architecture)/kubectl.sha256) /usr/local/bin/kubectl | sha256sum --check \
|
||||||
&& chmod a+x /usr/local/bin/kubectl \
|
&& chmod a+x /usr/local/bin/kubectl \
|
||||||
# Install Vagrant
|
# Install Vagrant
|
||||||
&& curl -LO https://releases.hashicorp.com/vagrant/${VAGRANT_VERSION}/vagrant_${VAGRANT_VERSION}-1_$(dpkg --print-architecture).deb \
|
&& curl -LO https://releases.hashicorp.com/vagrant/${VAGRANT_VERSION}/vagrant_${VAGRANT_VERSION}-1_$(dpkg --print-architecture).deb \
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
- name: Gather and compute network facts
|
- name: Gather and compute network facts
|
||||||
import_role:
|
import_role:
|
||||||
name: network_facts
|
name: network_facts
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
- name: Gather minimal facts
|
- name: Gather minimal facts
|
||||||
setup:
|
setup:
|
||||||
gather_subset: '!all'
|
gather_subset: '!all'
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
- { role: kubernetes-apps/kubelet-csr-approver, tags: kubelet-csr-approver }
|
- { role: kubernetes-apps/kubelet-csr-approver, tags: kubelet-csr-approver }
|
||||||
- { role: container-engine, tags: "container-engine", when: deploy_container_engine }
|
- { role: container-engine, tags: "container-engine", when: deploy_container_engine }
|
||||||
- { role: kubernetes/node, tags: node }
|
- { role: kubernetes/node, tags: node }
|
||||||
- { role: kubernetes/control-plane, tags: master, upgrade_cluster_setup: true }
|
- { role: kubernetes/control-plane, tags: control-plane, upgrade_cluster_setup: true }
|
||||||
- { role: kubernetes/client, tags: client }
|
- { role: kubernetes/client, tags: client }
|
||||||
- { role: kubernetes/node-label, tags: node-label }
|
- { role: kubernetes/node-label, tags: node-label }
|
||||||
- { role: kubernetes/node-taint, tags: node-taint }
|
- { role: kubernetes/node-taint, tags: node-taint }
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
environment: "{{ proxy_disable_env }}"
|
environment: "{{ proxy_disable_env }}"
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray_defaults }
|
- { role: kubespray_defaults }
|
||||||
- { role: win_nodes/kubernetes_patch, tags: ["master", "win_nodes"] }
|
- { role: win_nodes/kubernetes_patch, tags: ["control-plane", "win_nodes"] }
|
||||||
|
|
||||||
- name: Install Calico Route Reflector
|
- name: Install Calico Route Reflector
|
||||||
hosts: calico_rr
|
hosts: calico_rr
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ ansible==10.7.0
|
|||||||
# Needed for community.crypto module
|
# Needed for community.crypto module
|
||||||
cryptography==46.0.3
|
cryptography==46.0.3
|
||||||
# Needed for jinja2 json_query templating
|
# Needed for jinja2 json_query templating
|
||||||
jmespath==1.0.1
|
jmespath==1.1.0
|
||||||
# Needed for ansible.utils.ipaddr
|
# Needed for ansible.utils.ipaddr
|
||||||
netaddr==1.3.0
|
netaddr==1.3.0
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ platforms:
|
|||||||
vm_memory: 512
|
vm_memory: 512
|
||||||
provisioner:
|
provisioner:
|
||||||
name: ansible
|
name: ansible
|
||||||
|
env:
|
||||||
|
ANSIBLE_ROLES_PATH: ../../../
|
||||||
config_options:
|
config_options:
|
||||||
defaults:
|
defaults:
|
||||||
callbacks_enabled: profile_tasks
|
callbacks_enabled: profile_tasks
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ platforms:
|
|||||||
vm_memory: 512
|
vm_memory: 512
|
||||||
provisioner:
|
provisioner:
|
||||||
name: ansible
|
name: ansible
|
||||||
|
env:
|
||||||
|
ANSIBLE_ROLES_PATH: ../../../
|
||||||
config_options:
|
config_options:
|
||||||
defaults:
|
defaults:
|
||||||
callbacks_enabled: profile_tasks
|
callbacks_enabled: profile_tasks
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ platforms:
|
|||||||
vm_memory: 512
|
vm_memory: 512
|
||||||
provisioner:
|
provisioner:
|
||||||
name: ansible
|
name: ansible
|
||||||
|
env:
|
||||||
|
ANSIBLE_ROLES_PATH: ../../../
|
||||||
config_options:
|
config_options:
|
||||||
defaults:
|
defaults:
|
||||||
callbacks_enabled: profile_tasks
|
callbacks_enabled: profile_tasks
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ containerd_snapshotter: "overlayfs"
|
|||||||
containerd_runc_runtime:
|
containerd_runc_runtime:
|
||||||
name: runc
|
name: runc
|
||||||
type: "io.containerd.runc.v2"
|
type: "io.containerd.runc.v2"
|
||||||
engine: ""
|
|
||||||
root: ""
|
|
||||||
base_runtime_spec: cri-base.json
|
base_runtime_spec: cri-base.json
|
||||||
options:
|
options:
|
||||||
|
Root: ""
|
||||||
SystemdCgroup: "{{ containerd_use_systemd_cgroup | ternary('true', 'false') }}"
|
SystemdCgroup: "{{ containerd_use_systemd_cgroup | ternary('true', 'false') }}"
|
||||||
BinaryName: "{{ bin_dir }}/runc"
|
BinaryName: "{{ bin_dir }}/runc"
|
||||||
|
|
||||||
@@ -24,8 +23,8 @@ containerd_additional_runtimes: []
|
|||||||
# Example for Kata Containers as additional runtime:
|
# Example for Kata Containers as additional runtime:
|
||||||
# - name: kata
|
# - name: kata
|
||||||
# type: "io.containerd.kata.v2"
|
# type: "io.containerd.kata.v2"
|
||||||
# engine: ""
|
# options:
|
||||||
# root: ""
|
# Root: ""
|
||||||
|
|
||||||
containerd_base_runtime_spec_rlimit_nofile: 65535
|
containerd_base_runtime_spec_rlimit_nofile: 65535
|
||||||
|
|
||||||
@@ -36,8 +35,8 @@ containerd_default_base_runtime_spec_patch:
|
|||||||
hard: "{{ containerd_base_runtime_spec_rlimit_nofile }}"
|
hard: "{{ containerd_base_runtime_spec_rlimit_nofile }}"
|
||||||
soft: "{{ containerd_base_runtime_spec_rlimit_nofile }}"
|
soft: "{{ containerd_base_runtime_spec_rlimit_nofile }}"
|
||||||
|
|
||||||
# Can help reduce disk usage
|
# Only for containerd < 2.1; discard unpacked layers to save disk space
|
||||||
# https://github.com/containerd/containerd/discussions/6295
|
# https://github.com/containerd/containerd/blob/release/2.1/docs/cri/config.md#image-pull-configuration-since-containerd-v21
|
||||||
containerd_discard_unpacked_layers: true
|
containerd_discard_unpacked_layers: true
|
||||||
|
|
||||||
containerd_base_runtime_specs:
|
containerd_base_runtime_specs:
|
||||||
|
|||||||
@@ -52,8 +52,6 @@ oom_score = {{ containerd_oom_score }}
|
|||||||
{% for runtime in [containerd_runc_runtime] + containerd_additional_runtimes %}
|
{% for runtime in [containerd_runc_runtime] + containerd_additional_runtimes %}
|
||||||
[plugins."io.containerd.cri.v1.runtime".containerd.runtimes.{{ runtime.name }}]
|
[plugins."io.containerd.cri.v1.runtime".containerd.runtimes.{{ runtime.name }}]
|
||||||
runtime_type = "{{ runtime.type }}"
|
runtime_type = "{{ runtime.type }}"
|
||||||
runtime_engine = "{{ runtime.engine }}"
|
|
||||||
runtime_root = "{{ runtime.root }}"
|
|
||||||
{% if runtime.base_runtime_spec is defined %}
|
{% if runtime.base_runtime_spec is defined %}
|
||||||
base_runtime_spec = "{{ containerd_cfg_dir }}/{{ runtime.base_runtime_spec }}"
|
base_runtime_spec = "{{ containerd_cfg_dir }}/{{ runtime.base_runtime_spec }}"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -78,7 +76,9 @@ oom_score = {{ containerd_oom_score }}
|
|||||||
|
|
||||||
[plugins."io.containerd.cri.v1.images"]
|
[plugins."io.containerd.cri.v1.images"]
|
||||||
snapshotter = "{{ containerd_snapshotter }}"
|
snapshotter = "{{ containerd_snapshotter }}"
|
||||||
|
{% if containerd_discard_unpacked_layers and containerd_version is version('2.1.0', '<') %}
|
||||||
discard_unpacked_layers = {{ containerd_discard_unpacked_layers | lower }}
|
discard_unpacked_layers = {{ containerd_discard_unpacked_layers | lower }}
|
||||||
|
{% endif %}
|
||||||
image_pull_progress_timeout = "{{ containerd_image_pull_progress_timeout }}"
|
image_pull_progress_timeout = "{{ containerd_image_pull_progress_timeout }}"
|
||||||
[plugins."io.containerd.cri.v1.images".pinned_images]
|
[plugins."io.containerd.cri.v1.images".pinned_images]
|
||||||
sandbox = "{{ pod_infra_image_repo }}:{{ pod_infra_image_tag }}"
|
sandbox = "{{ pod_infra_image_repo }}:{{ pod_infra_image_tag }}"
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
{% if crio_registry_auth is defined and crio_registry_auth|length %}
|
{% if crio_registry_auth is defined and crio_registry_auth|length %}
|
||||||
{
|
{
|
||||||
{% for reg in crio_registry_auth %}
|
|
||||||
"auths": {
|
"auths": {
|
||||||
|
{% for reg in crio_registry_auth %}
|
||||||
"{{ reg.registry }}": {
|
"{{ reg.registry }}": {
|
||||||
"auth": "{{ (reg.username + ':' + reg.password) | string | b64encode }}"
|
"auth": "{{ (reg.username + ':' + reg.password) | string | b64encode }}"
|
||||||
}
|
|
||||||
{% if not loop.last %}
|
{% if not loop.last %}
|
||||||
},
|
},
|
||||||
{% else %}
|
{% else %}
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{% else %}
|
{% else %}
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
group: "{{ etcd_cert_group }}"
|
group: "{{ etcd_cert_group }}"
|
||||||
state: directory
|
state: directory
|
||||||
owner: "{{ etcd_owner }}"
|
owner: "{{ etcd_owner }}"
|
||||||
mode: "{{ etcd_cert_dir_mode }}"
|
mode: "0700"
|
||||||
recurse: true
|
|
||||||
|
|
||||||
- name: "Gen_certs | create etcd script dir (on {{ groups['etcd'][0] }})"
|
- name: "Gen_certs | create etcd script dir (on {{ groups['etcd'][0] }})"
|
||||||
file:
|
file:
|
||||||
@@ -145,15 +144,6 @@
|
|||||||
- ('k8s_cluster' in group_names) and
|
- ('k8s_cluster' in group_names) and
|
||||||
sync_certs | default(false) and inventory_hostname not in groups['etcd']
|
sync_certs | default(false) and inventory_hostname not in groups['etcd']
|
||||||
|
|
||||||
- name: Gen_certs | check certificate permissions
|
|
||||||
file:
|
|
||||||
path: "{{ etcd_cert_dir }}"
|
|
||||||
group: "{{ etcd_cert_group }}"
|
|
||||||
state: directory
|
|
||||||
owner: "{{ etcd_owner }}"
|
|
||||||
mode: "{{ etcd_cert_dir_mode }}"
|
|
||||||
recurse: true
|
|
||||||
|
|
||||||
# This is a hack around the fact kubeadm expect the same certs path on all kube_control_plane
|
# This is a hack around the fact kubeadm expect the same certs path on all kube_control_plane
|
||||||
# TODO: fix certs generation to have the same file everywhere
|
# TODO: fix certs generation to have the same file everywhere
|
||||||
# OR work with kubeadm on node-specific config
|
# OR work with kubeadm on node-specific config
|
||||||
|
|||||||
@@ -32,23 +32,16 @@ DNS.{{ counter["dns"] }} = {{ hostvars[host]['etcd_access_address'] }}{{ increme
|
|||||||
{# This will always expand to inventory_hostname, which can be a completely arbitrary name, that etcd will not know or care about, hence this line is (probably) redundant. #}
|
{# This will always expand to inventory_hostname, which can be a completely arbitrary name, that etcd will not know or care about, hence this line is (probably) redundant. #}
|
||||||
DNS.{{ counter["dns"] }} = {{ host }}{{ increment(counter, 'dns') }}
|
DNS.{{ counter["dns"] }} = {{ host }}{{ increment(counter, 'dns') }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if apiserver_loadbalancer_domain_name is defined %}
|
|
||||||
DNS.{{ counter["dns"] }} = {{ apiserver_loadbalancer_domain_name }}{{ increment(counter, 'dns') }}
|
|
||||||
{% endif %}
|
|
||||||
{% for etcd_alt_name in etcd_cert_alt_names %}
|
{% for etcd_alt_name in etcd_cert_alt_names %}
|
||||||
DNS.{{ counter["dns"] }} = {{ etcd_alt_name }}{{ increment(counter, 'dns') }}
|
DNS.{{ counter["dns"] }} = {{ etcd_alt_name }}{{ increment(counter, 'dns') }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for host in groups['etcd'] %}
|
{% for host in groups['etcd'] %}
|
||||||
{% if hostvars[host]['access_ip'] is defined %}
|
{% for address in hostvars[host]['main_access_ips'] %}
|
||||||
IP.{{ counter["ip"] }} = {{ hostvars[host]['access_ip'] }}{{ increment(counter, 'ip') }}
|
IP.{{ counter["ip"] }} = {{ address }}{{ increment(counter, 'ip') }}
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
{% if hostvars[host]['access_ip6'] is defined %}
|
{% for address in hostvars[host]['main_ips'] %}
|
||||||
IP.{{ counter["ip"] }} = {{ hostvars[host]['access_ip6'] }}{{ increment(counter, 'ip') }}
|
IP.{{ counter["ip"] }} = {{ address }}{{ increment(counter, 'ip') }}
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
{% if ipv6_stack %}
|
|
||||||
IP.{{ counter["ip"] }} = {{ hostvars[host]['ip6'] | default(hostvars[host]['fallback_ip6']) }}{{ increment(counter, 'ip') }}
|
|
||||||
{% endif %}
|
|
||||||
IP.{{ counter["ip"] }} = {{ hostvars[host]['main_ip'] }}{{ increment(counter, 'ip') }}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for cert_alt_ip in etcd_cert_alt_ips %}
|
{% for cert_alt_ip in etcd_cert_alt_ips %}
|
||||||
IP.{{ counter["ip"] }} = {{ cert_alt_ip }}{{ increment(counter, 'ip') }}
|
IP.{{ counter["ip"] }} = {{ cert_alt_ip }}{{ increment(counter, 'ip') }}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ etcd_backup_retention_count: -1
|
|||||||
force_etcd_cert_refresh: true
|
force_etcd_cert_refresh: true
|
||||||
etcd_config_dir: /etc/ssl/etcd
|
etcd_config_dir: /etc/ssl/etcd
|
||||||
etcd_cert_dir: "{{ etcd_config_dir }}/ssl"
|
etcd_cert_dir: "{{ etcd_config_dir }}/ssl"
|
||||||
etcd_cert_dir_mode: "0700"
|
|
||||||
etcd_cert_group: root
|
etcd_cert_group: root
|
||||||
# Note: This does not set up DNS entries. It simply adds the following DNS
|
# Note: This does not set up DNS entries. It simply adds the following DNS
|
||||||
# entries to the certificate
|
# entries to the certificate
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
metallb_enabled: false
|
metallb_enabled: false
|
||||||
metallb_log_level: info
|
metallb_log_level: info
|
||||||
|
metallb_namespace: "metallb-system"
|
||||||
metallb_port: "7472"
|
metallb_port: "7472"
|
||||||
metallb_memberlist_port: "7946"
|
metallb_memberlist_port: "7946"
|
||||||
metallb_speaker_enabled: "{{ metallb_enabled }}"
|
metallb_speaker_enabled: "{{ metallb_enabled }}"
|
||||||
|
|||||||
@@ -26,6 +26,16 @@ rules:
|
|||||||
verbs:
|
verbs:
|
||||||
- watch
|
- watch
|
||||||
- list
|
- list
|
||||||
|
# Services are monitored for service LoadBalancer IP allocation
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources:
|
||||||
|
- services
|
||||||
|
- services/status
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- update
|
||||||
|
- watch
|
||||||
{% elif calico_datastore == "kdd" %}
|
{% elif calico_datastore == "kdd" %}
|
||||||
# Nodes are watched to monitor for deletions.
|
# Nodes are watched to monitor for deletions.
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
@@ -104,4 +114,14 @@ rules:
|
|||||||
- update
|
- update
|
||||||
# watch for changes
|
# watch for changes
|
||||||
- watch
|
- watch
|
||||||
|
# Services are monitored for service LoadBalancer IP allocation
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources:
|
||||||
|
- services
|
||||||
|
- services/status
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- update
|
||||||
|
- watch
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
# disable upgrade cluster
|
# disable upgrade cluster
|
||||||
upgrade_cluster_setup: false
|
upgrade_cluster_setup: false
|
||||||
|
|
||||||
|
# Number of retries (with 5 seconds interval) to check that new control plane nodes
|
||||||
|
# are in Ready condition after joining
|
||||||
|
control_plane_node_become_ready_tries: 24
|
||||||
# By default the external API listens on all interfaces, this can be changed to
|
# By default the external API listens on all interfaces, this can be changed to
|
||||||
# listen on a specific address/interface.
|
# listen on a specific address/interface.
|
||||||
# NOTE: If you specific address/interface and use loadbalancer_apiserver_localhost
|
# NOTE: If you specific address/interface and use loadbalancer_apiserver_localhost
|
||||||
@@ -240,6 +243,10 @@ auto_renew_certificates_systemd_calendar: "Mon *-*-1,2,3,4,5,6,7 03:00:00"
|
|||||||
# we can opt out from the default behavior by setting kubeadm_upgrade_auto_cert_renewal to false
|
# we can opt out from the default behavior by setting kubeadm_upgrade_auto_cert_renewal to false
|
||||||
kubeadm_upgrade_auto_cert_renewal: true
|
kubeadm_upgrade_auto_cert_renewal: true
|
||||||
|
|
||||||
|
# Add Subject Alternative Names to the Kubernetes apiserver certificates.
|
||||||
|
# Useful if you access the API from multiples load balancers, for instance.
|
||||||
|
supplementary_addresses_in_ssl_keys: []
|
||||||
|
|
||||||
# Bash alias of kubectl to interact with Kubernetes cluster much easier
|
# Bash alias of kubectl to interact with Kubernetes cluster much easier
|
||||||
# kubectl_alias: k
|
# kubectl_alias: k
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
- name: Kubeadm | Check api is up
|
- name: Kubeadm | Check api is up
|
||||||
uri:
|
uri:
|
||||||
url: "https://{{ ip | default(fallback_ip) }}:{{ kube_apiserver_port }}/healthz"
|
url: "https://{{ main_ip | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}/healthz"
|
||||||
validate_certs: false
|
validate_certs: false
|
||||||
when: ('kube_control_plane' in group_names)
|
when: ('kube_control_plane' in group_names)
|
||||||
register: _result
|
register: _result
|
||||||
|
|||||||
@@ -11,24 +11,23 @@
|
|||||||
tags:
|
tags:
|
||||||
- facts
|
- facts
|
||||||
|
|
||||||
- name: Upload certificates so they are fresh and not expired
|
- name: Obtain kubeadm certificate key for joining control planes nodes
|
||||||
command: >-
|
|
||||||
{{ bin_dir }}/kubeadm init phase
|
|
||||||
--config {{ kube_config_dir }}/kubeadm-config.yaml
|
|
||||||
upload-certs
|
|
||||||
--upload-certs
|
|
||||||
register: kubeadm_upload_cert
|
|
||||||
when:
|
when:
|
||||||
- inventory_hostname == first_kube_control_plane
|
|
||||||
- not kube_external_ca_mode
|
- not kube_external_ca_mode
|
||||||
|
|
||||||
- name: Parse certificate key if not set
|
|
||||||
set_fact:
|
|
||||||
kubeadm_certificate_key: "{{ hostvars[first_kube_control_plane]['kubeadm_upload_cert'].stdout_lines[-1] | trim }}"
|
|
||||||
run_once: true
|
run_once: true
|
||||||
when:
|
block:
|
||||||
- hostvars[first_kube_control_plane]['kubeadm_upload_cert'] is defined
|
- name: Upload certificates so they are fresh and not expired
|
||||||
- hostvars[first_kube_control_plane]['kubeadm_upload_cert'] is not skipped
|
command: >-
|
||||||
|
{{ bin_dir }}/kubeadm init phase
|
||||||
|
--config {{ kube_config_dir }}/kubeadm-config.yaml
|
||||||
|
upload-certs
|
||||||
|
--upload-certs
|
||||||
|
register: kubeadm_upload_cert
|
||||||
|
delegate_to: "{{ first_kube_control_plane }}"
|
||||||
|
|
||||||
|
- name: Parse certificate key if not set
|
||||||
|
set_fact:
|
||||||
|
kubeadm_certificate_key: "{{ kubeadm_upload_cert.stdout_lines[-1] | trim }}"
|
||||||
|
|
||||||
- name: Wait for k8s apiserver
|
- name: Wait for k8s apiserver
|
||||||
wait_for:
|
wait_for:
|
||||||
@@ -99,3 +98,18 @@
|
|||||||
when:
|
when:
|
||||||
- inventory_hostname != first_kube_control_plane
|
- inventory_hostname != first_kube_control_plane
|
||||||
- kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists
|
- kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists
|
||||||
|
|
||||||
|
- name: Wait for new control plane nodes to be Ready
|
||||||
|
when: kubeadm_already_run.stat.exists
|
||||||
|
run_once: true
|
||||||
|
command: >
|
||||||
|
{{ kubectl }} get nodes --selector node-role.kubernetes.io/control-plane
|
||||||
|
-o jsonpath-as-json="{.items[*].status.conditions[?(@.type == 'Ready')]}"
|
||||||
|
register: control_plane_node_ready_conditions
|
||||||
|
retries: "{{ control_plane_node_become_ready_tries }}"
|
||||||
|
delay: 5
|
||||||
|
delegate_to: "{{ groups['kube_control_plane'][0] }}"
|
||||||
|
until: >
|
||||||
|
control_plane_node_ready_conditions.stdout
|
||||||
|
| from_json | selectattr('status', '==', 'True')
|
||||||
|
| length == (groups['kube_control_plane'] | length)
|
||||||
|
|||||||
@@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
- name: Kubeadm | aggregate all SANs
|
- name: Kubeadm | aggregate all SANs
|
||||||
set_fact:
|
set_fact:
|
||||||
apiserver_sans: "{{ (sans_base + groups['kube_control_plane'] + sans_lb + sans_lb_ip + sans_supp + sans_access_ip + sans_ip + sans_ipv4_address + sans_ipv6_address + sans_override + sans_hostname + sans_fqdn + sans_kube_vip_address) | unique }}"
|
apiserver_sans: "{{ _apiserver_sans | flatten | select | unique }}"
|
||||||
vars:
|
vars:
|
||||||
sans_base:
|
_apiserver_sans:
|
||||||
- "kubernetes"
|
- "kubernetes"
|
||||||
- "kubernetes.default"
|
- "kubernetes.default"
|
||||||
- "kubernetes.default.svc"
|
- "kubernetes.default.svc"
|
||||||
@@ -36,17 +36,17 @@
|
|||||||
- "localhost"
|
- "localhost"
|
||||||
- "127.0.0.1"
|
- "127.0.0.1"
|
||||||
- "::1"
|
- "::1"
|
||||||
sans_lb: "{{ [apiserver_loadbalancer_domain_name] if apiserver_loadbalancer_domain_name is defined else [] }}"
|
- "{{ apiserver_loadbalancer_domain_name | d('') }}"
|
||||||
sans_lb_ip: "{{ [loadbalancer_apiserver.address] if loadbalancer_apiserver is defined and loadbalancer_apiserver.address is defined else [] }}"
|
- "{{ loadbalancer_apiserver.address | d('') }}"
|
||||||
sans_supp: "{{ supplementary_addresses_in_ssl_keys if supplementary_addresses_in_ssl_keys is defined else [] }}"
|
- "{{ supplementary_addresses_in_ssl_keys }}"
|
||||||
sans_access_ip: "{{ groups['kube_control_plane'] | map('extract', hostvars, 'main_access_ip') | list | select('defined') | list }}"
|
- "{{ groups['kube_control_plane'] | map('extract', hostvars, 'main_access_ip') }}"
|
||||||
sans_ip: "{{ groups['kube_control_plane'] | map('extract', hostvars, 'main_ip') | list | select('defined') | list }}"
|
- "{{ groups['kube_control_plane'] | map('extract', hostvars, 'main_ip') }}"
|
||||||
sans_ipv4_address: "{{ groups['kube_control_plane'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list | select('defined') | list }}"
|
- "{{ groups['kube_control_plane'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | select('defined') }}"
|
||||||
sans_ipv6_address: "{{ groups['kube_control_plane'] | map('extract', hostvars, ['ansible_default_ipv6', 'address']) | list | select('defined') | list }}"
|
- "{{ groups['kube_control_plane'] | map('extract', hostvars, ['ansible_default_ipv6', 'address']) | select('defined') }}"
|
||||||
sans_override: "{{ [kube_override_hostname] if kube_override_hostname else [] }}"
|
- "{{ groups['kube_control_plane'] | map('extract', hostvars, 'ansible_hostname') }}"
|
||||||
sans_hostname: "{{ groups['kube_control_plane'] | map('extract', hostvars, ['ansible_hostname']) | list | select('defined') | list }}"
|
- "{{ groups['kube_control_plane'] | map('extract', hostvars, 'ansible_fqdn') }}"
|
||||||
sans_fqdn: "{{ groups['kube_control_plane'] | map('extract', hostvars, ['ansible_fqdn']) | list | select('defined') | list }}"
|
- "{{ kube_override_hostname }}"
|
||||||
sans_kube_vip_address: "{{ [kube_vip_address] if kube_vip_address is defined and kube_vip_address else [] }}"
|
- "{{ kube_vip_address }}"
|
||||||
tags: facts
|
tags: facts
|
||||||
|
|
||||||
- name: Create audit-policy directory
|
- name: Create audit-policy directory
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
# Nginx LB(default), If kubeadm_config_api_fqdn is defined, use other LB by kubeadm controlPlaneEndpoint.
|
# Nginx LB(default), If kubeadm_config_api_fqdn is defined, use other LB by kubeadm controlPlaneEndpoint.
|
||||||
- name: Set kubeadm_config_api_fqdn define
|
- name: Set kubeadm_config_api_fqdn define
|
||||||
set_fact:
|
set_fact:
|
||||||
kubeadm_config_api_fqdn: "{{ apiserver_loadbalancer_domain_name | default('lb-apiserver.kubernetes.local') }}"
|
kubeadm_config_api_fqdn: "{{ apiserver_loadbalancer_domain_name }}"
|
||||||
when: loadbalancer_apiserver is defined
|
when: loadbalancer_apiserver is defined
|
||||||
|
|
||||||
- name: Kubeadm | Create kubeadm config
|
- name: Kubeadm | Create kubeadm config
|
||||||
@@ -179,9 +179,10 @@
|
|||||||
timeout -k {{ kubeadm_init_timeout }} {{ kubeadm_init_timeout }}
|
timeout -k {{ kubeadm_init_timeout }} {{ kubeadm_init_timeout }}
|
||||||
{{ bin_dir }}/kubeadm init
|
{{ bin_dir }}/kubeadm init
|
||||||
--config={{ kube_config_dir }}/kubeadm-config.yaml
|
--config={{ kube_config_dir }}/kubeadm-config.yaml
|
||||||
--ignore-preflight-errors={{ kubeadm_ignore_preflight_errors | join(',') }}
|
--ignore-preflight-errors={{ _ignore_errors | flatten | join(',') }}
|
||||||
--skip-phases={{ kubeadm_init_phases_skip | join(',') }}
|
--skip-phases={{ kubeadm_init_phases_skip | join(',') }}
|
||||||
{{ kube_external_ca_mode | ternary('', '--upload-certs') }}
|
{{ kube_external_ca_mode | ternary('', '--upload-certs') }}
|
||||||
|
_ignore_errors: "{{ kubeadm_ignore_preflight_errors }}"
|
||||||
environment:
|
environment:
|
||||||
PATH: "{{ bin_dir }}:{{ ansible_env.PATH }}"
|
PATH: "{{ bin_dir }}:{{ ansible_env.PATH }}"
|
||||||
notify: Control plane | restart kubelet
|
notify: Control plane | restart kubelet
|
||||||
@@ -195,6 +196,15 @@
|
|||||||
# This retry task is separated from 1st task to show log of failure of 1st task.
|
# This retry task is separated from 1st task to show log of failure of 1st task.
|
||||||
- name: Kubeadm | Initialize first control plane node (retry)
|
- name: Kubeadm | Initialize first control plane node (retry)
|
||||||
command: "{{ kubeadm_init_first_control_plane_cmd }}"
|
command: "{{ kubeadm_init_first_control_plane_cmd }}"
|
||||||
|
vars:
|
||||||
|
_errors_from_first_try:
|
||||||
|
- 'FileAvailable--etc-kubernetes-manifests-kube-controller-manager.yaml'
|
||||||
|
- 'FileAvailable--etc-kubernetes-manifests-kube-scheduler.yaml'
|
||||||
|
- 'FileAvailable--etc-kubernetes-manifests-kube-apiserver.yaml'
|
||||||
|
- 'Port-10250'
|
||||||
|
_ignore_errors:
|
||||||
|
- "{{ kubeadm_ignore_preflight_errors }}"
|
||||||
|
- "{{ _errors_from_first_try if 'all' not in kubeadm_ignore_preflight_errors else [] }}"
|
||||||
register: kubeadm_init
|
register: kubeadm_init
|
||||||
retries: 2
|
retries: 2
|
||||||
until: kubeadm_init is succeeded or "field is immutable" in kubeadm_init.stderr
|
until: kubeadm_init is succeeded or "field is immutable" in kubeadm_init.stderr
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ echo "## Check Expiration before renewal ##"
|
|||||||
{{ bin_dir }}/kubeadm certs check-expiration
|
{{ bin_dir }}/kubeadm certs check-expiration
|
||||||
|
|
||||||
days_buffer=7 # set a time margin, because we should not renew at the last moment
|
days_buffer=7 # set a time margin, because we should not renew at the last moment
|
||||||
calendar={{ auto_renew_certificates_systemd_calendar }}
|
|
||||||
next_time=$(systemctl show k8s-certs-renew.timer -p NextElapseUSecRealtime --value)
|
next_time=$(systemctl show k8s-certs-renew.timer -p NextElapseUSecRealtime --value)
|
||||||
|
|
||||||
if [ "${next_time}" == "" ]; then
|
if [ "${next_time}" == "" ]; then
|
||||||
|
|||||||
@@ -3,9 +3,19 @@
|
|||||||
file:
|
file:
|
||||||
path: "{{ kubeadm_patches_dir }}"
|
path: "{{ kubeadm_patches_dir }}"
|
||||||
state: directory
|
state: directory
|
||||||
mode: "0640"
|
mode: "0750"
|
||||||
when: kubeadm_patches | length > 0
|
when: kubeadm_patches | length > 0
|
||||||
|
|
||||||
|
- name: Kubeadm | List existing kubeadm patches
|
||||||
|
find:
|
||||||
|
paths:
|
||||||
|
- "{{ kubeadm_patches_dir }}"
|
||||||
|
file_type: file
|
||||||
|
use_regex: true
|
||||||
|
patterns:
|
||||||
|
- '^(kube-apiserver|kube-controller-manager|kube-scheduler|etcd|kubeletconfiguration)[0-9]+\+(strategic|json|merge).yaml$'
|
||||||
|
register: existing_kubeadm_patches
|
||||||
|
|
||||||
- name: Kubeadm | Copy kubeadm patches from inventory files
|
- name: Kubeadm | Copy kubeadm patches from inventory files
|
||||||
copy:
|
copy:
|
||||||
content: "{{ item.patch | to_yaml }}"
|
content: "{{ item.patch | to_yaml }}"
|
||||||
@@ -15,3 +25,13 @@
|
|||||||
loop: "{{ kubeadm_patches }}"
|
loop: "{{ kubeadm_patches }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
index_var: suffix
|
index_var: suffix
|
||||||
|
register: current_kubeadm_patches
|
||||||
|
|
||||||
|
- name: Kubeadm | Delete old patches
|
||||||
|
loop: "{{ existing_kubeadm_patches.files | map(attribute='path') |
|
||||||
|
difference(
|
||||||
|
current_kubeadm_patches.results | map(attribute='dest')
|
||||||
|
) }}"
|
||||||
|
file:
|
||||||
|
state: absent
|
||||||
|
path: "{{ item }}"
|
||||||
|
|||||||
@@ -61,8 +61,6 @@ eviction_hard_control_plane: {}
|
|||||||
kubelet_status_update_frequency: 10s
|
kubelet_status_update_frequency: 10s
|
||||||
|
|
||||||
# kube-vip
|
# kube-vip
|
||||||
kube_vip_version: 0.8.0
|
|
||||||
|
|
||||||
kube_vip_arp_enabled: false
|
kube_vip_arp_enabled: false
|
||||||
kube_vip_interface:
|
kube_vip_interface:
|
||||||
kube_vip_services_interface:
|
kube_vip_services_interface:
|
||||||
@@ -80,7 +78,6 @@ kube_vip_bgp_peeraddress:
|
|||||||
kube_vip_bgp_peerpass:
|
kube_vip_bgp_peerpass:
|
||||||
kube_vip_bgp_peeras: 65000
|
kube_vip_bgp_peeras: 65000
|
||||||
kube_vip_bgppeers:
|
kube_vip_bgppeers:
|
||||||
kube_vip_address:
|
|
||||||
kube_vip_enableServicesElection: false
|
kube_vip_enableServicesElection: false
|
||||||
kube_vip_lb_enable: false
|
kube_vip_lb_enable: false
|
||||||
kube_vip_leasename: plndr-cp-lock
|
kube_vip_leasename: plndr-cp-lock
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ frontend healthz
|
|||||||
frontend kube_api_frontend
|
frontend kube_api_frontend
|
||||||
bind 127.0.0.1:{{ loadbalancer_apiserver_port|default(kube_apiserver_port) }}
|
bind 127.0.0.1:{{ loadbalancer_apiserver_port|default(kube_apiserver_port) }}
|
||||||
{% if ipv6_stack -%}
|
{% if ipv6_stack -%}
|
||||||
bind [::1]:{{ loadbalancer_apiserver_port|default(kube_apiserver_port) }};
|
bind [::1]:{{ loadbalancer_apiserver_port|default(kube_apiserver_port) }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
mode tcp
|
mode tcp
|
||||||
option tcplog
|
option tcplog
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Inspired by https://github.com/kube-vip/kube-vip/blob/v0.8.0/pkg/kubevip/config_generator.go#L103
|
# Inspired by https://github.com/kube-vip/kube-vip/blob/v1.0.3/pkg/kubevip/config_generator.go#L103
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
@@ -27,7 +27,7 @@ spec:
|
|||||||
value: {{ kube_vip_services_interface | string | to_json }}
|
value: {{ kube_vip_services_interface | string | to_json }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if kube_vip_cidr %}
|
{% if kube_vip_cidr %}
|
||||||
- name: vip_cidr
|
- name: vip_{{ "subnet" if kube_vip_version is version('0.9.0', '>=') else "cidr" }}
|
||||||
value: {{ kube_vip_cidr | string | to_json }}
|
value: {{ kube_vip_cidr | string | to_json }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if kube_vip_dns_mode %}
|
{% if kube_vip_dns_mode %}
|
||||||
@@ -113,6 +113,8 @@ spec:
|
|||||||
add:
|
add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
- NET_RAW
|
- NET_RAW
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
{% endif %}
|
{% endif %}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /etc/kubernetes/admin.conf
|
- mountPath: /etc/kubernetes/admin.conf
|
||||||
|
|||||||
@@ -74,8 +74,34 @@
|
|||||||
- not is_fedora_coreos
|
- not is_fedora_coreos
|
||||||
- not ansible_os_family in ["Flatcar", "Flatcar Container Linux by Kinvolk"]
|
- not ansible_os_family in ["Flatcar", "Flatcar Container Linux by Kinvolk"]
|
||||||
|
|
||||||
- name: Set timezone
|
- name: Gather selinux facts
|
||||||
|
ansible.builtin.setup:
|
||||||
|
gather_subset: selinux
|
||||||
|
when:
|
||||||
|
- ntp_timezone
|
||||||
|
- ansible_os_family == "RedHat"
|
||||||
|
|
||||||
|
- name: Put SELinux in permissive mode, logging actions that would be blocked.
|
||||||
|
ansible.posix.selinux:
|
||||||
|
policy: targeted
|
||||||
|
state: permissive
|
||||||
|
when:
|
||||||
|
- ntp_timezone
|
||||||
|
- ansible_os_family == "RedHat"
|
||||||
|
- ansible_facts.selinux.status == 'enabled'
|
||||||
|
- ansible_facts.selinux.mode == 'enforcing'
|
||||||
|
|
||||||
|
- name: Set ntp_timezone
|
||||||
community.general.timezone:
|
community.general.timezone:
|
||||||
name: "{{ ntp_timezone }}"
|
name: "{{ ntp_timezone }}"
|
||||||
when:
|
when:
|
||||||
- ntp_timezone
|
- ntp_timezone
|
||||||
|
|
||||||
|
- name: Re-enable SELinux
|
||||||
|
ansible.posix.selinux:
|
||||||
|
policy: targeted
|
||||||
|
state: "{{ preinstall_selinux_state }}"
|
||||||
|
when:
|
||||||
|
- ntp_timezone
|
||||||
|
- ansible_os_family == "RedHat"
|
||||||
|
- ansible_facts.selinux.status == 'enabled'
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ flannel_version: 0.27.3
|
|||||||
flannel_cni_version: 1.7.1-flannel1
|
flannel_cni_version: 1.7.1-flannel1
|
||||||
cni_version: "{{ (cni_binary_checksums['amd64'] | dict2items)[0].key }}"
|
cni_version: "{{ (cni_binary_checksums['amd64'] | dict2items)[0].key }}"
|
||||||
|
|
||||||
cilium_version: "1.18.4"
|
cilium_version: "1.18.6"
|
||||||
cilium_cli_version: "{{ (ciliumcli_binary_checksums['amd64'] | dict2items)[0].key }}"
|
cilium_cli_version: "{{ (ciliumcli_binary_checksums['amd64'] | dict2items)[0].key }}"
|
||||||
cilium_enable_hubble: false
|
cilium_enable_hubble: false
|
||||||
|
|
||||||
@@ -265,8 +265,9 @@ multus_image_tag: "v{{ multus_version }}"
|
|||||||
external_openstack_cloud_controller_image_repo: "{{ kube_image_repo }}/provider-os/openstack-cloud-controller-manager"
|
external_openstack_cloud_controller_image_repo: "{{ kube_image_repo }}/provider-os/openstack-cloud-controller-manager"
|
||||||
external_openstack_cloud_controller_image_tag: "v1.32.0"
|
external_openstack_cloud_controller_image_tag: "v1.32.0"
|
||||||
|
|
||||||
|
kube_vip_version: 1.0.3
|
||||||
kube_vip_image_repo: "{{ github_image_repo }}/kube-vip/kube-vip{{ '-iptables' if kube_vip_lb_fwdmethod == 'masquerade' else '' }}"
|
kube_vip_image_repo: "{{ github_image_repo }}/kube-vip/kube-vip{{ '-iptables' if kube_vip_lb_fwdmethod == 'masquerade' else '' }}"
|
||||||
kube_vip_image_tag: v0.8.9
|
kube_vip_image_tag: "v{{ kube_vip_version }}"
|
||||||
nginx_image_repo: "{{ docker_image_repo }}/library/nginx"
|
nginx_image_repo: "{{ docker_image_repo }}/library/nginx"
|
||||||
nginx_image_tag: 1.28.0-alpine
|
nginx_image_tag: 1.28.0-alpine
|
||||||
haproxy_image_repo: "{{ docker_image_repo }}/library/haproxy"
|
haproxy_image_repo: "{{ docker_image_repo }}/library/haproxy"
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ ignore_assert_errors: false
|
|||||||
# kube-vip
|
# kube-vip
|
||||||
kube_vip_enabled: false
|
kube_vip_enabled: false
|
||||||
kube_vip_lb_fwdmethod: local
|
kube_vip_lb_fwdmethod: local
|
||||||
|
kube_vip_address:
|
||||||
|
|
||||||
# nginx-proxy configure
|
# nginx-proxy configure
|
||||||
nginx_config_dir: "/etc/nginx"
|
nginx_config_dir: "/etc/nginx"
|
||||||
@@ -642,18 +643,18 @@ first_kube_control_plane_address: "{{ hostvars[groups['kube_control_plane'][0]][
|
|||||||
loadbalancer_apiserver_localhost: "{{ loadbalancer_apiserver is not defined }}"
|
loadbalancer_apiserver_localhost: "{{ loadbalancer_apiserver is not defined }}"
|
||||||
loadbalancer_apiserver_type: "nginx"
|
loadbalancer_apiserver_type: "nginx"
|
||||||
# applied if only external loadbalancer_apiserver is defined, otherwise ignored
|
# applied if only external loadbalancer_apiserver is defined, otherwise ignored
|
||||||
apiserver_loadbalancer_domain_name: "lb-apiserver.kubernetes.local"
|
apiserver_loadbalancer_domain_name: "{{ 'localhost' if loadbalancer_apiserver_localhost else (loadbalancer_apiserver.address | d(undef())) }}"
|
||||||
kube_apiserver_global_endpoint: |-
|
kube_apiserver_global_endpoint: |-
|
||||||
{% if loadbalancer_apiserver is defined -%}
|
{% if loadbalancer_apiserver is defined -%}
|
||||||
https://{{ apiserver_loadbalancer_domain_name }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
|
https://{{ apiserver_loadbalancer_domain_name | ansible.utils.ipwrap }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
|
||||||
{%- elif loadbalancer_apiserver_localhost and (loadbalancer_apiserver_port is not defined or loadbalancer_apiserver_port == kube_apiserver_port) -%}
|
{%- elif loadbalancer_apiserver_localhost -%}
|
||||||
https://localhost:{{ kube_apiserver_port }}
|
https://localhost:{{ loadbalancer_apiserver_port | default(kube_apiserver_port) }}
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
https://{{ first_kube_control_plane_address | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}
|
https://{{ first_kube_control_plane_address | ansible.utils.ipwrap }}:{{ kube_apiserver_port }}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
kube_apiserver_endpoint: |-
|
kube_apiserver_endpoint: |-
|
||||||
{% if loadbalancer_apiserver is defined -%}
|
{% if loadbalancer_apiserver is defined -%}
|
||||||
https://{{ apiserver_loadbalancer_domain_name }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
|
https://{{ apiserver_loadbalancer_domain_name | ansible.utils.ipwrap }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
|
||||||
{%- elif ('kube_control_plane' not in group_names) and loadbalancer_apiserver_localhost -%}
|
{%- elif ('kube_control_plane' not in group_names) and loadbalancer_apiserver_localhost -%}
|
||||||
https://localhost:{{ loadbalancer_apiserver_port | default(kube_apiserver_port) }}
|
https://localhost:{{ loadbalancer_apiserver_port | default(kube_apiserver_port) }}
|
||||||
{%- elif 'kube_control_plane' in group_names -%}
|
{%- elif 'kube_control_plane' in group_names -%}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ kube_next: "{{ ((kube_version | split('.'))[1] | int) + 1 }}"
|
|||||||
kube_major_next_version: "1.{{ kube_next }}"
|
kube_major_next_version: "1.{{ kube_next }}"
|
||||||
|
|
||||||
pod_infra_supported_versions:
|
pod_infra_supported_versions:
|
||||||
'1.34': '3.10'
|
'1.34': '3.10.1'
|
||||||
'1.33': '3.10'
|
'1.33': '3.10'
|
||||||
'1.32': '3.10'
|
'1.32': '3.10'
|
||||||
|
|
||||||
|
|||||||
5
roles/network_facts/defaults/main.yml
Normal file
5
roles/network_facts/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
# Additional string host to inject into NO_PROXY
|
||||||
|
additional_no_proxy: ""
|
||||||
|
additional_no_proxy_list: "{{ additional_no_proxy | split(',') }}"
|
||||||
|
no_proxy_exclude_workers: false
|
||||||
@@ -1,59 +1,63 @@
|
|||||||
---
|
---
|
||||||
- name: Set facts variables
|
- name: Gather node IPs
|
||||||
tags:
|
setup:
|
||||||
- always
|
gather_subset: '!all,!min,network'
|
||||||
block:
|
filter: "ansible_default_ip*"
|
||||||
- name: Gather ansible_default_ipv4
|
when: ansible_default_ipv4 is not defined or ansible_default_ipv6 is not defined
|
||||||
setup:
|
ignore_unreachable: true
|
||||||
gather_subset: '!all,network'
|
|
||||||
filter: "ansible_default_ipv4"
|
|
||||||
when: ansible_default_ipv4 is not defined
|
|
||||||
ignore_unreachable: true
|
|
||||||
# Set 127.0.0.1 as fallback IP if we do not have host facts for host
|
|
||||||
# ansible_default_ipv4 isn't what you think.
|
|
||||||
# https://medium.com/opsops/ansible-default-ipv4-is-not-what-you-think-edb8ab154b10
|
|
||||||
# TODO: discard this and update all the location relying on it in "looping on hostvars" templates
|
|
||||||
- name: Set fallback_ip
|
|
||||||
set_fact:
|
|
||||||
fallback_ip: "{{ ansible_default_ipv4.address | d('127.0.0.1') }}"
|
|
||||||
when: fallback_ip is not defined
|
|
||||||
|
|
||||||
- name: Gather ansible_default_ipv6
|
- name: Set computed IPs variables
|
||||||
setup:
|
vars:
|
||||||
gather_subset: '!all,network'
|
fallback_ip: "{{ ansible_default_ipv4.address | d('127.0.0.1') }}"
|
||||||
filter: "ansible_default_ipv6"
|
fallback_ip6: "{{ ansible_default_ipv6.address | d('::1') }}"
|
||||||
when: ansible_default_ipv6 is not defined
|
# Set 127.0.0.1 as fallback IP if we do not have host facts for host
|
||||||
ignore_unreachable: true
|
# ansible_default_ipv4 isn't what you think.
|
||||||
- name: Set fallback_ip6
|
_ipv4: "{{ ip | default(fallback_ip) }}"
|
||||||
set_fact:
|
_access_ipv4: "{{ access_ip | default(_ipv4) }}"
|
||||||
fallback_ip6: "{{ ansible_default_ipv6.address | d('::1') }}"
|
_ipv6: "{{ ip6 | default(fallback_ip6) }}"
|
||||||
when: fallback_ip6 is not defined
|
_access_ipv6: "{{ access_ip6 | default(_ipv6) }}"
|
||||||
|
_access_ips:
|
||||||
|
- "{{ _access_ipv4 if ipv4_stack }}"
|
||||||
|
- "{{ _access_ipv6 if ipv6_stack }}"
|
||||||
|
_ips:
|
||||||
|
- "{{ _ipv4 if ipv4_stack }}"
|
||||||
|
- "{{ _ipv6 if ipv6_stack }}"
|
||||||
|
set_fact:
|
||||||
|
cacheable: true
|
||||||
|
main_access_ip: "{{ _access_ipv4 if ipv4_stack else _access_ipv6 }}"
|
||||||
|
main_ip: "{{ _ipv4 if ipv4_stack else _ipv6 }}"
|
||||||
|
# Mixed IPs - for dualstack
|
||||||
|
main_access_ips: "{{ _access_ips | select }}"
|
||||||
|
main_ips: "{{ _ips | select }}"
|
||||||
|
|
||||||
- name: Set main access ip(access_ip based on ipv4_stack/ipv6_stack options).
|
- name: Set no_proxy to all assigned cluster IPs and hostnames
|
||||||
set_fact:
|
when:
|
||||||
cacheable: true
|
- http_proxy is defined or https_proxy is defined
|
||||||
main_access_ip: >-
|
- no_proxy is not defined
|
||||||
{%- if ipv4_stack -%}
|
vars:
|
||||||
{{ access_ip | default(ip | default(fallback_ip)) }}
|
groups_with_no_proxy:
|
||||||
{%- else -%}
|
- kube_control_plane
|
||||||
{{ access_ip6 | default(ip6 | default(fallback_ip6)) }}
|
- "{{ '' if no_proxy_exclude_workers else 'kube_node' }}" # TODO: exclude by a boolean in inventory rather than global variable
|
||||||
{%- endif -%}
|
- etcd
|
||||||
|
- calico_rr
|
||||||
- name: Set main ip(ip based on ipv4_stack/ipv6_stack options).
|
hosts_with_no_proxy: "{{ groups_with_no_proxy | select | map('extract', groups) | select('defined') | flatten }}"
|
||||||
set_fact:
|
_hostnames: "{{ (hosts_with_no_proxy +
|
||||||
cacheable: true
|
(hosts_with_no_proxy | map('extract', hostvars, morekeys=['ansible_hostname'])
|
||||||
main_ip: "{{ (ip | default(fallback_ip)) if ipv4_stack else (ip6 | default(fallback_ip6)) }}"
|
| select('defined')))
|
||||||
|
| unique }}"
|
||||||
- name: Set main access ips(mixed ips for dualstack).
|
no_proxy_prepare:
|
||||||
set_fact:
|
- "{{ apiserver_loadbalancer_domain_name | d('') }}"
|
||||||
main_access_ips: ["{{ (main_access_ip + ',' + (access_ip6 | default(ip6 | default(fallback_ip6)))) if (ipv4_stack and ipv6_stack) else main_access_ip }}"]
|
- "{{ loadbalancer_apiserver.address if loadbalancer_apiserver is defined else '' }}"
|
||||||
|
- "{{ hosts_with_no_proxy | map('extract', hostvars, morekeys=['main_access_ip']) }}"
|
||||||
- name: Set main ips(mixed ips for dualstack).
|
- "{{ _hostnames }}"
|
||||||
set_fact:
|
- "{{ _hostnames | map('regex_replace', '$', '.' + dns_domain ) }}"
|
||||||
main_ips: ["{{ (main_ip + ',' + (ip6 | default(fallback_ip6))) if (ipv4_stack and ipv6_stack) else main_ip }}"]
|
- "{{ additional_no_proxy_list }}"
|
||||||
|
- 127.0.0.1
|
||||||
- name: Set no_proxy
|
- localhost
|
||||||
import_tasks: no_proxy.yml
|
- "{{ kube_service_subnets }}"
|
||||||
when:
|
- "{{ kube_pods_subnets }}"
|
||||||
- http_proxy is defined or https_proxy is defined
|
- svc
|
||||||
- no_proxy is not defined
|
- "svc.{{ dns_domain }}"
|
||||||
|
set_fact:
|
||||||
|
no_proxy: "{{ no_proxy_prepare | select | flatten | unique | join(',') }}"
|
||||||
|
run_once: true
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Set no_proxy to all assigned cluster IPs and hostnames
|
|
||||||
set_fact:
|
|
||||||
# noqa: jinja[spacing]
|
|
||||||
no_proxy_prepare: >-
|
|
||||||
{%- if loadbalancer_apiserver is defined -%}
|
|
||||||
{{ apiserver_loadbalancer_domain_name | default('') }},
|
|
||||||
{{ loadbalancer_apiserver.address | default('') }},
|
|
||||||
{%- endif -%}
|
|
||||||
{%- if no_proxy_exclude_workers | default(false) -%}
|
|
||||||
{% set cluster_or_control_plane = 'kube_control_plane' %}
|
|
||||||
{%- else -%}
|
|
||||||
{% set cluster_or_control_plane = 'k8s_cluster' %}
|
|
||||||
{%- endif -%}
|
|
||||||
{%- for item in (groups[cluster_or_control_plane] + groups['etcd'] | default([]) + groups['calico_rr'] | default([])) | unique -%}
|
|
||||||
{{ hostvars[item]['main_access_ip'] }},
|
|
||||||
{%- if item != hostvars[item].get('ansible_hostname', '') -%}
|
|
||||||
{{ hostvars[item]['ansible_hostname'] }},
|
|
||||||
{{ hostvars[item]['ansible_hostname'] }}.{{ dns_domain }},
|
|
||||||
{%- endif -%}
|
|
||||||
{{ item }},{{ item }}.{{ dns_domain }},
|
|
||||||
{%- endfor -%}
|
|
||||||
{%- if additional_no_proxy is defined -%}
|
|
||||||
{{ additional_no_proxy }},
|
|
||||||
{%- endif -%}
|
|
||||||
127.0.0.1,localhost,{{ kube_service_subnets }},{{ kube_pods_subnets }},svc,svc.{{ dns_domain }}
|
|
||||||
delegate_to: localhost
|
|
||||||
connection: local
|
|
||||||
delegate_facts: true
|
|
||||||
become: false
|
|
||||||
run_once: true
|
|
||||||
|
|
||||||
- name: Populates no_proxy to all hosts
|
|
||||||
set_fact:
|
|
||||||
no_proxy: "{{ hostvars.localhost.no_proxy_prepare }}"
|
|
||||||
# noqa: jinja[spacing]
|
|
||||||
proxy_env: "{{ proxy_env | combine({
|
|
||||||
'no_proxy': hostvars.localhost.no_proxy_prepare,
|
|
||||||
'NO_PROXY': hostvars.localhost.no_proxy_prepare
|
|
||||||
}) }}"
|
|
||||||
@@ -61,6 +61,7 @@
|
|||||||
executable: /bin/bash
|
executable: /bin/bash
|
||||||
register: calico_version_on_server
|
register: calico_version_on_server
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
check_mode: false
|
||||||
|
|
||||||
- name: Assert that current calico version is enough for upgrade
|
- name: Assert that current calico version is enough for upgrade
|
||||||
assert:
|
assert:
|
||||||
|
|||||||
@@ -177,6 +177,9 @@ rules:
|
|||||||
- blockaffinities
|
- blockaffinities
|
||||||
- caliconodestatuses
|
- caliconodestatuses
|
||||||
- tiers
|
- tiers
|
||||||
|
- stagednetworkpolicies
|
||||||
|
- stagedglobalnetworkpolicies
|
||||||
|
- stagedkubernetesnetworkpolicies
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
|
|||||||
@@ -215,3 +215,17 @@ rules:
|
|||||||
- calico-cni-plugin
|
- calico-cni-plugin
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
|
{% if calico_version is version('3.29.0', '>=') %}
|
||||||
|
---
|
||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: calico-tier-getter
|
||||||
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- "projectcalico.org"
|
||||||
|
resources:
|
||||||
|
- "tiers"
|
||||||
|
verbs:
|
||||||
|
- "get"
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -26,3 +26,18 @@ subjects:
|
|||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: calico-cni-plugin
|
name: calico-cni-plugin
|
||||||
namespace: kube-system
|
namespace: kube-system
|
||||||
|
{% if calico_version is version('3.29.0', '>=') %}
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: calico-tier-getter
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: calico-tier-getter
|
||||||
|
subjects:
|
||||||
|
- apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: User
|
||||||
|
name: system:kube-controller-manager
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ metadata:
|
|||||||
namespace: kube-system
|
namespace: kube-system
|
||||||
name: kubernetes-services-endpoint
|
name: kubernetes-services-endpoint
|
||||||
data:
|
data:
|
||||||
{% if calico_bpf_enabled %}
|
{% if calico_bpf_enabled or loadbalancer_apiserver_localhost %}
|
||||||
KUBERNETES_SERVICE_HOST: "{{ kube_apiserver_global_endpoint | urlsplit('hostname') }}"
|
KUBERNETES_SERVICE_HOST: "{{ kube_apiserver_global_endpoint | urlsplit('hostname') }}"
|
||||||
KUBERNETES_SERVICE_PORT: "{{ kube_apiserver_global_endpoint | urlsplit('port') }}"
|
KUBERNETES_SERVICE_PORT: "{{ kube_apiserver_global_endpoint | urlsplit('port') }}"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
---
|
---
|
||||||
cilium_min_version_required: "1.15"
|
cilium_min_version_required: "1.15"
|
||||||
|
|
||||||
# remove migrate after 2.29 released
|
|
||||||
cilium_remove_old_resources: false
|
|
||||||
# Log-level
|
# Log-level
|
||||||
cilium_debug: false
|
cilium_debug: false
|
||||||
|
|
||||||
|
|||||||
@@ -30,13 +30,6 @@
|
|||||||
when:
|
when:
|
||||||
- cilium_identity_allocation_mode == "kvstore"
|
- cilium_identity_allocation_mode == "kvstore"
|
||||||
|
|
||||||
- name: Cilium | Enable portmap addon
|
|
||||||
template:
|
|
||||||
src: 000-cilium-portmap.conflist.j2
|
|
||||||
dest: /etc/cni/net.d/000-cilium-portmap.conflist
|
|
||||||
mode: "0644"
|
|
||||||
when: cilium_enable_portmap
|
|
||||||
|
|
||||||
- name: Cilium | Render values
|
- name: Cilium | Render values
|
||||||
template:
|
template:
|
||||||
src: values.yaml.j2
|
src: values.yaml.j2
|
||||||
|
|||||||
@@ -5,10 +5,5 @@
|
|||||||
- name: Cilium install
|
- name: Cilium install
|
||||||
include_tasks: install.yml
|
include_tasks: install.yml
|
||||||
|
|
||||||
# Remove after 2.29 released
|
|
||||||
- name: Cilium remove old resources
|
|
||||||
when: cilium_remove_old_resources
|
|
||||||
include_tasks: remove_old_resources.yml
|
|
||||||
|
|
||||||
- name: Cilium apply
|
- name: Cilium apply
|
||||||
include_tasks: apply.yml
|
include_tasks: apply.yml
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
---
|
|
||||||
# Remove after 2.29 released
|
|
||||||
- name: Cilium | Delete Old Resource
|
|
||||||
command: |
|
|
||||||
{{ kubectl }} delete {{ item.kind | lower }} {{ item.name }} \
|
|
||||||
{{ '-n kube-system' if item.kind not in ['ClusterRole', 'ClusterRoleBinding'] else '' }} \
|
|
||||||
loop:
|
|
||||||
- { kind: ServiceAccount, name: cilium }
|
|
||||||
- { kind: ServiceAccount, name: cilium-operator }
|
|
||||||
- { kind: ServiceAccount, name: hubble-generate-certs }
|
|
||||||
- { kind: ServiceAccount, name: hubble-relay }
|
|
||||||
- { kind: ServiceAccount, name: hubble-ui }
|
|
||||||
- { kind: Service, name: hubble-metrics }
|
|
||||||
- { kind: Service, name: hubble-relay-metrics }
|
|
||||||
- { kind: Service, name: hubble-relay }
|
|
||||||
- { kind: Service, name: hubble-ui }
|
|
||||||
- { kind: Service, name: hubble-peer }
|
|
||||||
- { kind: Deployment, name: cilium-operator }
|
|
||||||
- { kind: Deployment, name: hubble-relay }
|
|
||||||
- { kind: Deployment, name: hubble-ui }
|
|
||||||
- { kind: DaemonSet, name: cilium }
|
|
||||||
- { kind: CronJob, name: hubble-generate-certs }
|
|
||||||
- { kind: Job, name: hubble-generate-certs }
|
|
||||||
- { kind: ConfigMap, name: cilium-config }
|
|
||||||
- { kind: ConfigMap, name: ip-masq-agent }
|
|
||||||
- { kind: ConfigMap, name: hubble-relay-config }
|
|
||||||
- { kind: ConfigMap, name: hubble-ui-nginx }
|
|
||||||
- { kind: ClusterRole, name: cilium }
|
|
||||||
- { kind: ClusterRole, name: cilium-operator }
|
|
||||||
- { kind: ClusterRole, name: hubble-generate-certs }
|
|
||||||
- { kind: ClusterRole, name: hubble-relay }
|
|
||||||
- { kind: ClusterRole, name: hubble-ui }
|
|
||||||
- { kind: ClusterRoleBinding, name: cilium }
|
|
||||||
- { kind: ClusterRoleBinding, name: cilium-operator }
|
|
||||||
- { kind: ClusterRoleBinding, name: hubble-generate-certs }
|
|
||||||
- { kind: ClusterRoleBinding, name: hubble-relay }
|
|
||||||
- { kind: ClusterRoleBinding, name: hubble-ui }
|
|
||||||
- { kind: Secret, name: hubble-ca-secret }
|
|
||||||
- { kind: Secret, name: hubble-relay-client-certs }
|
|
||||||
- { kind: Secret, name: hubble-server-certs }
|
|
||||||
register: patch_result
|
|
||||||
when: inventory_hostname == groups['kube_control_plane'][0]
|
|
||||||
failed_when:
|
|
||||||
- patch_result.rc != 0
|
|
||||||
- "'not found' not in patch_result.stderr"
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"cniVersion": "0.3.1",
|
|
||||||
"name": "cilium-portmap",
|
|
||||||
"plugins": [
|
|
||||||
{
|
|
||||||
"type": "cilium-cni"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "portmap",
|
|
||||||
"capabilities": { "portMappings": true }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -7,8 +7,8 @@ image:
|
|||||||
repository: {{ cilium_image_repo }}
|
repository: {{ cilium_image_repo }}
|
||||||
tag: {{ cilium_image_tag }}
|
tag: {{ cilium_image_tag }}
|
||||||
|
|
||||||
k8sServiceHost: "auto"
|
k8sServiceHost: "{{ kube_apiserver_global_endpoint | urlsplit('hostname') }}"
|
||||||
k8sServicePort: "auto"
|
k8sServicePort: "{{ kube_apiserver_global_endpoint | urlsplit('port') }}"
|
||||||
|
|
||||||
ipv4:
|
ipv4:
|
||||||
enabled: {{ cilium_enable_ipv4 | to_json }}
|
enabled: {{ cilium_enable_ipv4 | to_json }}
|
||||||
@@ -56,6 +56,9 @@ bpf:
|
|||||||
cni:
|
cni:
|
||||||
exclusive: {{ cilium_cni_exclusive | to_json }}
|
exclusive: {{ cilium_cni_exclusive | to_json }}
|
||||||
logFile: {{ cilium_cni_log_file }}
|
logFile: {{ cilium_cni_log_file }}
|
||||||
|
{% if cilium_enable_portmap %}
|
||||||
|
chainingMode: portmap
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
autoDirectNodeRoutes: {{ cilium_auto_direct_node_routes | to_json }}
|
autoDirectNodeRoutes: {{ cilium_auto_direct_node_routes | to_json }}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,10 @@
|
|||||||
- "{{ bin_dir }}/etcdctl"
|
- "{{ bin_dir }}/etcdctl"
|
||||||
- member
|
- member
|
||||||
- remove
|
- remove
|
||||||
- "{{ '%x' | format(((etcd_members.stdout | from_json).members | selectattr('peerURLs.0', '==', etcd_peer_url))[0].ID) }}"
|
- "{{ '%x' | format(etcd_removed_nodes[0].ID) }}"
|
||||||
|
vars:
|
||||||
|
etcd_removed_nodes: "{{ (etcd_members.stdout | from_json).members | selectattr('peerURLs.0', '==', etcd_peer_url) }}"
|
||||||
|
# This should always have at most one member, since the etcd_peer_url should be unique in the etcd cluster
|
||||||
|
when: etcd_removed_nodes != []
|
||||||
register: etcd_removal_output
|
register: etcd_removal_output
|
||||||
changed_when: "'Removed member' in etcd_removal_output.stdout"
|
changed_when: "'Removed member' in etcd_removal_output.stdout"
|
||||||
|
|||||||
@@ -432,16 +432,6 @@
|
|||||||
- files
|
- files
|
||||||
- dns
|
- dns
|
||||||
|
|
||||||
# TODO: remove after release 2.29
|
|
||||||
- name: Reset | remove host entries from /etc/hosts
|
|
||||||
blockinfile:
|
|
||||||
path: "/etc/hosts"
|
|
||||||
state: absent
|
|
||||||
marker: "# Ansible inventory hosts {mark}"
|
|
||||||
tags:
|
|
||||||
- files
|
|
||||||
- dns
|
|
||||||
|
|
||||||
- name: Reset | include file with reset tasks specific to the network_plugin if exists
|
- name: Reset | include file with reset tasks specific to the network_plugin if exists
|
||||||
include_role:
|
include_role:
|
||||||
name: "network_plugin/{{ kube_network_plugin }}"
|
name: "network_plugin/{{ kube_network_plugin }}"
|
||||||
|
|||||||
@@ -6,14 +6,6 @@
|
|||||||
# -> nothing depending on facts or similar cluster state
|
# -> nothing depending on facts or similar cluster state
|
||||||
# Checks depending on current state (of the nodes or the cluster)
|
# Checks depending on current state (of the nodes or the cluster)
|
||||||
# should be in roles/kubernetes/preinstall/tasks/0040-verify-settings.yml
|
# should be in roles/kubernetes/preinstall/tasks/0040-verify-settings.yml
|
||||||
- name: Stop if removed tags are used
|
|
||||||
assert:
|
|
||||||
msg: The tag 'master' is removed. Use 'control-plane' instead
|
|
||||||
that:
|
|
||||||
- ('master' not in ansible_run_tags)
|
|
||||||
- ('master' not in ansible_skip_tags)
|
|
||||||
# TODO: Remove checks after next release
|
|
||||||
|
|
||||||
- name: Stop if kube_control_plane group is empty
|
- name: Stop if kube_control_plane group is empty
|
||||||
assert:
|
assert:
|
||||||
that: groups.get( 'kube_control_plane' )
|
that: groups.get( 'kube_control_plane' )
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "kubespray_component_hash_update"
|
name = "kubespray_component_hash_update"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"more_itertools",
|
"more_itertools",
|
||||||
"ruamel.yaml",
|
"ruamel.yaml",
|
||||||
|
|||||||
@@ -126,15 +126,20 @@ def download_hash(downloads: {str: {str: Any}}) -> None:
|
|||||||
releases, tags = map(
|
releases, tags = map(
|
||||||
dict, partition(lambda r: r[1].get("tags", False), downloads.items())
|
dict, partition(lambda r: r[1].get("tags", False), downloads.items())
|
||||||
)
|
)
|
||||||
repos = {
|
unique_release_ids = list(dict.fromkeys(
|
||||||
"with_releases": [r["graphql_id"] for r in releases.values()],
|
r["graphql_id"] for r in releases.values()
|
||||||
"with_tags": [t["graphql_id"] for t in tags.values()],
|
))
|
||||||
}
|
unique_tag_ids = list(dict.fromkeys(
|
||||||
|
t["graphql_id"] for t in tags.values()
|
||||||
|
))
|
||||||
response = s.post(
|
response = s.post(
|
||||||
"https://api.github.com/graphql",
|
"https://api.github.com/graphql",
|
||||||
json={
|
json={
|
||||||
"query": files(__package__).joinpath("list_releases.graphql").read_text(),
|
"query": files(__package__).joinpath("list_releases.graphql").read_text(),
|
||||||
"variables": repos,
|
"variables": {
|
||||||
|
"with_releases": unique_release_ids,
|
||||||
|
"with_tags": unique_tag_ids,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
headers={
|
headers={
|
||||||
"Authorization": f"Bearer {os.environ['API_KEY']}",
|
"Authorization": f"Bearer {os.environ['API_KEY']}",
|
||||||
@@ -155,31 +160,30 @@ def download_hash(downloads: {str: {str: Any}}) -> None:
|
|||||||
except InvalidVersion:
|
except InvalidVersion:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
repos = response.json()["data"]
|
resp_data = response.json()["data"]
|
||||||
github_versions = dict(
|
release_versions_by_id = {
|
||||||
zip(
|
gql_id: {
|
||||||
chain(releases.keys(), tags.keys()),
|
v
|
||||||
[
|
for r in repo["releases"]["nodes"]
|
||||||
{
|
if not r["isPrerelease"]
|
||||||
v
|
and (v := valid_version(r["tagName"])) is not None
|
||||||
for r in repo["releases"]["nodes"]
|
}
|
||||||
if not r["isPrerelease"]
|
for gql_id, repo in zip(unique_release_ids, resp_data["with_releases"])
|
||||||
and (v := valid_version(r["tagName"])) is not None
|
}
|
||||||
}
|
tag_versions_by_id = {
|
||||||
for repo in repos["with_releases"]
|
gql_id: {
|
||||||
]
|
v
|
||||||
+ [
|
for t in repo["refs"]["nodes"]
|
||||||
{
|
if (v := valid_version(t["name"].removeprefix("release-")))
|
||||||
v
|
is not None
|
||||||
for t in repo["refs"]["nodes"]
|
}
|
||||||
if (v := valid_version(t["name"].removeprefix("release-")))
|
for gql_id, repo in zip(unique_tag_ids, resp_data["with_tags"])
|
||||||
is not None
|
}
|
||||||
}
|
github_versions = {}
|
||||||
for repo in repos["with_tags"]
|
for name, info in releases.items():
|
||||||
],
|
github_versions[name] = release_versions_by_id[info["graphql_id"]]
|
||||||
strict=True,
|
for name, info in tags.items():
|
||||||
)
|
github_versions[name] = tag_versions_by_id[info["graphql_id"]]
|
||||||
)
|
|
||||||
|
|
||||||
components_supported_arch = {
|
components_supported_arch = {
|
||||||
component.removesuffix("_checksums"): [a for a in archs.keys()]
|
component.removesuffix("_checksums"): [a for a in archs.keys()]
|
||||||
|
|||||||
@@ -5,42 +5,38 @@ import logging
|
|||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
|
|
||||||
DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
|
log = logging.getLogger(__name__)
|
||||||
PAUSE_SECONDS = 5
|
|
||||||
|
|
||||||
log = logging.getLogger('openstack-cleanup')
|
parser = argparse.ArgumentParser(description="Cleanup OpenStack resources")
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Cleanup OpenStack resources')
|
parser.add_argument(
|
||||||
|
"--hours",
|
||||||
parser.add_argument('-v', '--verbose', action='store_true',
|
type=int,
|
||||||
help='Increase verbosity')
|
default=4,
|
||||||
parser.add_argument('--hours', type=int, default=4,
|
help="Age (in hours) of VMs to cleanup (default: 4h)",
|
||||||
help='Age (in hours) of VMs to cleanup (default: 4h)')
|
)
|
||||||
parser.add_argument('--dry-run', action='store_true',
|
parser.add_argument("--dry-run", action="store_true", help="Do not delete anything")
|
||||||
help='Do not delete anything')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
oldest_allowed = datetime.datetime.now() - datetime.timedelta(hours=args.hours)
|
oldest_allowed = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(
|
||||||
|
hours=args.hours
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
print('Running in dry-run mode')
|
log.info("Running in dry-run mode")
|
||||||
else:
|
|
||||||
print('This will delete resources... (ctrl+c to cancel)')
|
|
||||||
time.sleep(PAUSE_SECONDS)
|
|
||||||
|
|
||||||
conn = openstack.connect()
|
conn = openstack.connect()
|
||||||
|
|
||||||
print('Servers...')
|
log.info("Deleting servers...")
|
||||||
map_if_old(conn.compute.delete_server,
|
map_if_old(conn.compute.delete_server, conn.compute.servers())
|
||||||
conn.compute.servers())
|
|
||||||
|
|
||||||
print('Ports...')
|
log.info("Deleting ports...")
|
||||||
try:
|
try:
|
||||||
map_if_old(conn.network.delete_port,
|
map_if_old(conn.network.delete_port, conn.network.ports())
|
||||||
conn.network.ports())
|
|
||||||
except openstack.exceptions.ConflictException as ex:
|
except openstack.exceptions.ConflictException as ex:
|
||||||
# Need to find subnet-id which should be removed from a router
|
# Need to find subnet-id which should be removed from a router
|
||||||
for sn in conn.network.subnets():
|
for sn in conn.network.subnets():
|
||||||
@@ -48,40 +44,41 @@ def main():
|
|||||||
fn_if_old(conn.network.delete_subnet, sn)
|
fn_if_old(conn.network.delete_subnet, sn)
|
||||||
except openstack.exceptions.ConflictException:
|
except openstack.exceptions.ConflictException:
|
||||||
for r in conn.network.routers():
|
for r in conn.network.routers():
|
||||||
print("Deleting subnet %s from router %s", sn, r)
|
log.info("Deleting subnet %s from router %s", sn, r)
|
||||||
try:
|
try:
|
||||||
conn.network.remove_interface_from_router(
|
conn.network.remove_interface_from_router(r, subnet_id=sn.id)
|
||||||
r, subnet_id=sn.id)
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print("Failed to delete subnet from router as %s", ex)
|
log.error("Failed to delete subnet from router", exc_info=True)
|
||||||
|
|
||||||
for ip in conn.network.ips():
|
for ip in conn.network.ips():
|
||||||
fn_if_old(conn.network.delete_ip, ip)
|
fn_if_old(conn.network.delete_ip, ip)
|
||||||
|
|
||||||
# After removing unnecessary subnet from router, retry to delete ports
|
# After removing unnecessary subnet from router, retry to delete ports
|
||||||
map_if_old(conn.network.delete_port,
|
map_if_old(conn.network.delete_port, conn.network.ports())
|
||||||
conn.network.ports())
|
|
||||||
|
|
||||||
print('Security groups...')
|
log.info("Deleting security groups...")
|
||||||
try:
|
try:
|
||||||
map_if_old(conn.network.delete_security_group,
|
map_if_old(conn.network.delete_security_group, conn.network.security_groups())
|
||||||
conn.network.security_groups())
|
|
||||||
except openstack.exceptions.ConflictException as ex:
|
except openstack.exceptions.ConflictException as ex:
|
||||||
# Need to delete port when security groups is in used
|
# Need to delete port when security groups is in used
|
||||||
map_if_old(conn.network.delete_port,
|
map_if_old(conn.network.delete_port, conn.network.ports())
|
||||||
conn.network.ports())
|
map_if_old(conn.network.delete_security_group, conn.network.security_groups())
|
||||||
map_if_old(conn.network.delete_security_group,
|
|
||||||
conn.network.security_groups())
|
|
||||||
|
|
||||||
print('Subnets...')
|
log.info("Deleting Subnets...")
|
||||||
map_if_old(conn.network.delete_subnet,
|
map_if_old(conn.network.delete_subnet, conn.network.subnets())
|
||||||
conn.network.subnets())
|
|
||||||
|
|
||||||
print('Networks...')
|
log.info("Deleting networks...")
|
||||||
for n in conn.network.networks():
|
for n in conn.network.networks():
|
||||||
if not n.is_router_external:
|
if not n.is_router_external:
|
||||||
fn_if_old(conn.network.delete_network, n)
|
fn_if_old(conn.network.delete_network, n)
|
||||||
|
|
||||||
|
log.info("Deleting keypairs...")
|
||||||
|
map_if_old(
|
||||||
|
conn.compute.delete_keypair,
|
||||||
|
(conn.compute.get_keypair(x.name) for x in conn.compute.keypairs()),
|
||||||
|
# LIST API for keypairs does not give us a created_at (WTF)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# runs the given fn to all elements of the that are older than allowed
|
# runs the given fn to all elements of the that are older than allowed
|
||||||
def map_if_old(fn, items):
|
def map_if_old(fn, items):
|
||||||
@@ -91,15 +88,19 @@ def map_if_old(fn, items):
|
|||||||
|
|
||||||
# run the given fn function only if the passed item is older than allowed
|
# run the given fn function only if the passed item is older than allowed
|
||||||
def fn_if_old(fn, item):
|
def fn_if_old(fn, item):
|
||||||
created_at = datetime.datetime.strptime(item.created_at, DATE_FORMAT)
|
created_at = datetime.datetime.fromisoformat(item.created_at)
|
||||||
|
if created_at.tzinfo is None:
|
||||||
|
created_at = created_at.replace(tzinfo=datetime.timezone.utc)
|
||||||
|
# Handle TZ unaware object by assuming UTC
|
||||||
|
# Can't compare to oldest_allowed otherwise
|
||||||
if item.name == "default": # skip default security group
|
if item.name == "default": # skip default security group
|
||||||
return
|
return
|
||||||
if created_at < oldest_allowed:
|
if created_at < oldest_allowed:
|
||||||
print('Will delete %(name)s (%(id)s)' % item)
|
log.info("Will delete %s %s)", item.name, item.id)
|
||||||
if not args.dry_run:
|
if not args.dry_run:
|
||||||
fn(item)
|
fn(item)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
# execute only if run as a script
|
# execute only if run as a script
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -118,6 +118,10 @@ images:
|
|||||||
converted: true
|
converted: true
|
||||||
tag: "latest"
|
tag: "latest"
|
||||||
|
|
||||||
|
# rockylinux-10-extra:
|
||||||
|
# default cloud image doesn't included `kernel-modules-extra`. How to build RockyLinux 10 + `kernel-module-extra` with dib
|
||||||
|
# https://github.com/kubernetes-sigs/kubespray/pull/12355#issuecomment-3705400093
|
||||||
|
|
||||||
debian-10:
|
debian-10:
|
||||||
filename: debian-10-openstack-amd64.qcow2
|
filename: debian-10-openstack-amd64.qcow2
|
||||||
url: https://cdimage.debian.org/cdimage/openstack/current-10/debian-10-openstack-amd64.qcow2
|
url: https://cdimage.debian.org/cdimage/openstack/current-10/debian-10-openstack-amd64.qcow2
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
cloud_image: debian-13
|
cloud_image: debian-13
|
||||||
|
|
||||||
# Kubespray settings
|
# Kubespray settings
|
||||||
|
gateway_api_enabled: true
|
||||||
|
|
||||||
dns_mode: coredns_dual
|
dns_mode: coredns_dual
|
||||||
kube_asymmetric_encryption_algorithm: "RSA-3072"
|
kube_asymmetric_encryption_algorithm: "RSA-3072"
|
||||||
|
|||||||
10
tests/files/rockylinux10-calico.yml
Normal file
10
tests/files/rockylinux10-calico.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
# Instance settings
|
||||||
|
cloud_image: rockylinux-10-extra
|
||||||
|
vm_memory: 3072
|
||||||
|
|
||||||
|
# Kubespray settings
|
||||||
|
metrics_server_enabled: true
|
||||||
|
dashboard_namespace: "kube-dashboard"
|
||||||
|
dashboard_enabled: true
|
||||||
|
loadbalancer_apiserver_type: haproxy
|
||||||
1
tests/files/rockylinux10-cilium
Normal file
1
tests/files/rockylinux10-cilium
Normal file
@@ -0,0 +1 @@
|
|||||||
|
RESET_CHECK=true
|
||||||
33
tests/files/rockylinux10-cilium.yml
Normal file
33
tests/files/rockylinux10-cilium.yml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
# Instance settings
|
||||||
|
cloud_image: rockylinux-10-extra
|
||||||
|
vm_memory: 3072
|
||||||
|
|
||||||
|
# Kubespray settings
|
||||||
|
kube_network_plugin: cilium
|
||||||
|
|
||||||
|
cilium_kube_proxy_replacement: true
|
||||||
|
|
||||||
|
kube_owner: root
|
||||||
|
|
||||||
|
# Node Feature Discovery
|
||||||
|
node_feature_discovery_enabled: true
|
||||||
|
kube_asymmetric_encryption_algorithm: "ECDSA-P256"
|
||||||
|
|
||||||
|
# Testing no_proxy setup
|
||||||
|
# The proxy is not intended to be accessed at all, we're only testing
|
||||||
|
# the no_proxy construction
|
||||||
|
https_proxy: "http://some-proxy.invalid"
|
||||||
|
http_proxy: "http://some-proxy.invalid"
|
||||||
|
additional_no_proxy_list:
|
||||||
|
- github.com
|
||||||
|
- githubusercontent.com
|
||||||
|
- k8s.io
|
||||||
|
- rockylinux.org
|
||||||
|
- docker.io
|
||||||
|
- googleapis.com
|
||||||
|
- quay.io
|
||||||
|
- pkg.dev
|
||||||
|
- amazonaws.com
|
||||||
|
- cilium.io
|
||||||
|
skip_http_proxy_on_os_packages: true
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
sonobuoy_enabled: true
|
|
||||||
pkg_install_retries: 25
|
|
||||||
retry_stagger: 10
|
|
||||||
|
|
||||||
# Ignore ping errors
|
|
||||||
ignore_assert_errors: true
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
-r ../requirements.txt
|
-r ../requirements.txt
|
||||||
distlib==0.4.0 # required for building collections
|
distlib==0.4.0 # required for building collections
|
||||||
molecule==25.1.0
|
molecule==25.12.0
|
||||||
pytest-testinfra==10.2.2
|
pytest-testinfra==10.2.2
|
||||||
|
|||||||
Reference in New Issue
Block a user