Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revisionBoth sides next revision | ||
linux_faq:kubernetes_using_single_node_as_master_and_worker [2020/07/09 15:01] – [Ingress, Cert-Manager и сертификаты Let's Encrypt] admin | linux_faq:kubernetes_using_single_node_as_master_and_worker [2022/04/28 11:25] – [Single node Kubernetes setup - Ubuntu 18.04] admin | ||
---|---|---|---|
Line 8: | Line 8: | ||
| | ||
echo 'deb http:// | echo 'deb http:// | ||
- | curl -s https:// | + | |
- | | + | |
+ | gpg_keyring_path="/ | ||
+ | curl -fsSL " | ||
+ | |||
+ | cat <<EOF | sudo tee / | ||
+ | overlay | ||
+ | br_netfilter | ||
+ | EOF | ||
+ | |||
+ | sudo modprobe overlay | ||
+ | sudo modprobe br_netfilter | ||
+ | |||
+ | # Setup required sysctl params, these persist across reboots. | ||
+ | cat <<EOF | sudo tee / | ||
+ | net.bridge.bridge-nf-call-iptables | ||
+ | net.ipv4.ip_forward | ||
+ | net.bridge.bridge-nf-call-ip6tables = 1 | ||
+ | EOF | ||
+ | |||
+ | # Apply sysctl params without reboot | ||
+ | sudo sysctl --system | ||
sudo apt-get update | sudo apt-get update | ||
- | sudo apt-get install -y docker.io kubeadm kubelet | + | |
+ | sudo apt-get install -y containerd | ||
| | ||
- | | + | |
- | | + | |
- | | + | |
- | " | + | cat << EOF | sudo tee / |
- | " | + | [Unit] |
- | " | + | |
- | " | + | |
- | }, | + | |
- | " | + | |
- | | + | |
EOF | EOF | ||
| | ||
- | sudo mkdir -p /etc/systemd/system/docker.service.d | + | sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' |
+ | sudo service | ||
| | ||
- | # Enable services and restart docker. | ||
- | sudo systemctl daemon-reload | ||
- | sudo systemctl enable docker | ||
- | sudo systemctl restart docker | ||
- | sudo systemctl enable kubelet.service | ||
| | ||
- | sudo usermod -a -G docker $USER | ||
- | | ||
- | # To ensure that kubelet starts only after docker: | ||
- | cat << EOF | sudo tee / | ||
- | [Unit] | ||
- | After=docker.service | ||
- | EOF | ||
- | |||
# Kubernetes Cluster Init | # Kubernetes Cluster Init | ||
- | sudo kubeadm init --pod-network-cidr=10.244.0.0/ | + | sudo kubeadm init --cri-socket / |
| | ||
mkdir -p $HOME/.kube | mkdir -p $HOME/.kube | ||
Line 56: | Line 62: | ||
kubectl taint nodes --all node-role.kubernetes.io/ | kubectl taint nodes --all node-role.kubernetes.io/ | ||
+ | ====== Настройка манифестов компонентво кубера на слабых маишинках ====== | ||
+ | Я запускаю свой кластер в контейнере на сервере Proxmox, | ||
+ | Чтобы немного облегчить им жизнь и сделать поведение компонентов k8s более предсказуемым нужно увеличить таймауты **livenessProbe**, | ||
+ | Для этого - редактируем манифесты в директории **/ | ||
+ | < | ||
+ | livenessProbe: | ||
+ | failureThreshold: | ||
+ | initialDelaySeconds: | ||
+ | periodSeconds: | ||
+ | timeoutSeconds: | ||
+ | readinessProbe: | ||
+ | failureThreshold: | ||
+ | periodSeconds: | ||
+ | timeoutSeconds: | ||
+ | startupProbe: | ||
+ | failureThreshold: | ||
+ | initialDelaySeconds: | ||
+ | periodSeconds: | ||
+ | timeoutSeconds: | ||
+ | </ | ||
+ | И перезапускаем **kubelet**: | ||
+ | sudo service kubelet restart | ||
====== Изменение редактора kubectl edit ====== | ====== Изменение редактора kubectl edit ====== | ||
sudo awk -v line=' | sudo awk -v line=' | ||
Line 105: | Line 133: | ||
и в **spec.template.spec.containers.args** добавляем: | и в **spec.template.spec.containers.args** добавляем: | ||
< | < | ||
+ | Без этого параметра metrics-server не запустится, | ||
+ | < | ||
Все. Через некоторое время команды **kubectl top** начнут выдавать осмысленную информацию. \\ | Все. Через некоторое время команды **kubectl top** начнут выдавать осмысленную информацию. \\ | ||
Если этого не происходит, | Если этого не происходит, | ||
Line 114: | Line 144: | ||
С третьей версией **Helm** ничего в кластер ставить не нужно. Для использования достаточно бинарника и сконфигурированного **context** для доступа к кластеру. | С третьей версией **Helm** ничего в кластер ставить не нужно. Для использования достаточно бинарника и сконфигурированного **context** для доступа к кластеру. | ||
+ | ====== Обновление kubernetes ====== | ||
+ | смотрим какие версии **kubeadm** нам доступны | ||
+ | sudo apt-get update | ||
+ | apt-cache madison kubeadm | ||
+ | Разрешаем обновление **kubernetes-cni** и **kubeadm**: | ||
+ | sudo apt-mark unhold kubernetes-cni kubeadm | ||
+ | Ставим нужную версию **kubeadm**: | ||
+ | sudo apt-get install kubeadm=1.20.9-00 | ||
+ | Проверяем возможность апгрейда: | ||
+ | sudo kubeadm upgrade plan | ||
+ | Если у нас хост с **containerd** (без **docker**), | ||
+ | kubeadm.alpha.kubernetes.io/ | ||
+ | если этого не сделать - будет ошибка, | ||
+ | error execution phase preflight: docker is required for container runtime: exec: " | ||
+ | Обновляем: | ||
+ | sudo kubeadm upgrade apply v1.20.9 | ||
+ | Разрешаем обновление **kubelet** и **kubectl** | ||
+ | sudo apt-mark unhold kubelet kubectl | ||
+ | И обновляем их до нужной версии: | ||
+ | sudo apt-get install -y kubelet=1.20.9-00 kubectl=1.20.9-00 | ||
+ | Морозим обратно версии пакетов: | ||
+ | sudo apt-mark hold kube* | ||
+ | Апгрейдим всю систему: | ||
+ | sudo apt-get update && sudo apt-get upgrade | ||
====== Доступ к подам снаружи ====== | ====== Доступ к подам снаружи ====== | ||
Для доступа к сервисам, | Для доступа к сервисам, | ||
Line 122: | Line 176: | ||
https:// | https:// | ||
https:// | https:// | ||
- | kubectl create ns metallb-system | + | |
- | helm install | + | helm repo update |
- | При установке с помощью **helm** конфигурация хранится в **ConfigMap** с именем **metallb-config**, который лежит в том же неймспейсе куда установлен **metallb** (в данном случае - **metallb-system**). | + | |
- | < | + | helm upgrade |
- | kind: ConfigMap | + | |
- | metadata: | + | |
- | namespace: metallb-system | + | --set configInline.address-pools[0].addresses[0]="192.168.77.160-192.168.77.189" |
- | | + | |
- | data: | + | |
- | config: | | + | |
- | address-pools: | + | |
- | - name: default | + | |
- | protocol: layer2 | + | |
- | | + | |
- | - 192.168.77.160-192.168.77.189 | + | |
- | </ | + | |
==== Апгрейдим metallb ==== | ==== Апгрейдим metallb ==== | ||
helm repo update | helm repo update | ||
- | helm upgrade metallb | + | helm upgrade |
===== Ingress-controller ===== | ===== Ingress-controller ===== | ||
https:// | https:// | ||
Либо тоже самое можно сделать с помощью helm-чарта: | Либо тоже самое можно сделать с помощью helm-чарта: | ||
kubectl create ns ingress | kubectl create ns ingress | ||
+ | helm repo add ingress-nginx https:// | ||
+ | helm repo update | ||
+ | |||
#helm install stable/ | #helm install stable/ | ||
- | helm install | + | helm upgrade --install nginx -n ingress |
+ | | ||
--set controller.addHeaders." | --set controller.addHeaders." | ||
--set controller.addHeaders." | --set controller.addHeaders." | ||
Line 158: | Line 206: | ||
--set controller.addHeaders." | --set controller.addHeaders." | ||
Ну или без драконовских запретов (заголовки **Content-Security-Policy** влияют на все ресурсы за этим **ingress-controller** и что-то может просто не заработать): | Ну или без драконовских запретов (заголовки **Content-Security-Policy** влияют на все ресурсы за этим **ingress-controller** и что-то может просто не заработать): | ||
- | helm upgrade | + | helm upgrade --install |
- | --set controller.service.externalTrafficPolicy=Local \ | + | |
+ | --set controller.service.externalTrafficPolicy=Cluster | ||
--set controller.service.loadBalancerIP=192.168.77.160 \ | --set controller.service.loadBalancerIP=192.168.77.160 \ | ||
--set controller.addHeaders." | --set controller.addHeaders." | ||
Line 166: | Line 215: | ||
--set controller.addHeaders." | --set controller.addHeaders." | ||
- | В результате - в неймспейсе **ingress** появится сервис **http-https-nginx-ingress-controller**, | + | В результате - в неймспейсе **ingress** появится сервис **nginx-ingress-nginx-controller**, |
Теперь можно создавать **ingress**' | Теперь можно создавать **ingress**' | ||
+ | ==== Мониторинг nginx ingess ==== | ||
+ | В кластере нужно развернуть **CRD** и оператор **prometheus**: | ||
+ | \\ | ||
+ | **nginx-ingress-monitoring-values.yaml** | ||
+ | < | ||
+ | controller: | ||
+ | metrics: | ||
+ | port: 10254 | ||
+ | enabled: true | ||
+ | service: | ||
+ | annotations: | ||
+ | prometheus.io/ | ||
+ | prometheus.io/ | ||
+ | servicePort: | ||
+ | type: ClusterIP | ||
+ | |||
+ | serviceMonitor: | ||
+ | enabled: true | ||
+ | additionalLabels: | ||
+ | jobLabel: nginx-ingress | ||
+ | namespace: " | ||
+ | namespaceSelector: | ||
+ | matchNames: | ||
+ | - ingress | ||
+ | scrapeInterval: | ||
+ | |||
+ | prometheusRule: | ||
+ | enabled: true | ||
+ | namespace: ingress | ||
+ | rules: | ||
+ | - alert: NGINXConfigFailed | ||
+ | expr: count(nginx_ingress_controller_config_last_reload_successful == 0) > 0 | ||
+ | for: 1s | ||
+ | labels: | ||
+ | severity: critical | ||
+ | annotations: | ||
+ | description: | ||
+ | summary: uninstall the latest ingress changes to allow config reloads to resume | ||
+ | - alert: NGINXCertificateExpiry | ||
+ | expr: (avg(nginx_ingress_controller_ssl_expire_time_seconds) by (host) - time()) < 604800 | ||
+ | for: 1s | ||
+ | labels: | ||
+ | severity: critical | ||
+ | annotations: | ||
+ | description: | ||
+ | summary: renew expiring certificates to avoid downtime | ||
+ | - alert: NGINXTooMany500s | ||
+ | expr: 100 * ( sum( nginx_ingress_controller_requests{status=~" | ||
+ | for: 1m | ||
+ | labels: | ||
+ | severity: warning | ||
+ | annotations: | ||
+ | description: | ||
+ | summary: More than 5% of all requests returned 5XX, this requires your attention | ||
+ | - alert: NGINXTooMany400s | ||
+ | expr: 100 * ( sum( nginx_ingress_controller_requests{status=~" | ||
+ | for: 1m | ||
+ | labels: | ||
+ | severity: warning | ||
+ | annotations: | ||
+ | description: | ||
+ | summary: More than 5% of all requests returned 4XX, this requires your attention | ||
+ | </ | ||
+ | helm upgrade --reuse-values -n ingress nginx ingress-nginx/ | ||
===== Cert manager ===== | ===== Cert manager ===== | ||
https:// | https:// | ||
https:// | https:// | ||
Устанавливаем: | Устанавливаем: | ||
- | < | + | < |
- | kubectl apply --validate=false -f https:// | + | |
- | + | ||
- | # Create the namespace for cert-manager | + | |
- | kubectl create namespace cert-manager | + | |
- | + | ||
- | # Add the Jetstack Helm repository | + | |
helm repo add jetstack https:// | helm repo add jetstack https:// | ||
- | |||
- | # Update your local Helm chart repository cache | ||
helm repo update | helm repo update | ||
- | # Install the cert-manager Helm chart | + | helm upgrade --install \ |
- | helm install \ | + | |
- | --name cert-manager \ | + | |
--namespace cert-manager \ | --namespace cert-manager \ | ||
- | --version v0.11.0 | + | --create-namespace |
- | | + | --set installCRDs=true \ |
+ | --version v1.5.4 | ||
</ | </ | ||
https:// | https:// | ||
Создаем издателя **Let' | Создаем издателя **Let' | ||
- | < | + | < |
+ | apiVersion: cert-manager.io/ | ||
kind: ClusterIssuer | kind: ClusterIssuer | ||
metadata: | metadata: | ||
Line 204: | Line 310: | ||
# certificates, | # certificates, | ||
email: mike@autosys.tk | email: mike@autosys.tk | ||
- | server: https:// | + | server: https:// |
privateKeySecretRef: | privateKeySecretRef: | ||
# Secret resource used to store the account' | # Secret resource used to store the account' | ||
Line 213: | Line 319: | ||
ingress: | ingress: | ||
class: nginx | class: nginx | ||
+ | EOF | ||
</ | </ | ||
Смотрим на его состояние: | Смотрим на его состояние: | ||
Line 227: | Line 334: | ||
==== Апгрейдим cert-manager ==== | ==== Апгрейдим cert-manager ==== | ||
helm repo update | helm repo update | ||
- | helm upgrade --namespace cert-manager cert-manager jetstack/ | + | helm upgrade --namespace cert-manager cert-manager jetstack/ |
===== Ingress, Cert-Manager и сертификаты Let's Encrypt ===== | ===== Ingress, Cert-Manager и сертификаты Let's Encrypt ===== | ||
< | < | ||
< | < | ||
https:// | https:// | ||
+ | https:// | ||
Итак, у нас установлен **MetalLB**, | Итак, у нас установлен **MetalLB**, | ||
В результате, | В результате, | ||
Line 264: | Line 372: | ||
В результате, | В результате, | ||
\\ | \\ | ||
- | Теперь нужно сконфигурировать **ACME Issuer** - это сущность, | + | Теперь нужно сконфигурировать **ACME Issuer** - это сущность, |
- | < | + | https:// |
+ | < | ||
+ | kubectl apply -f - << EOF | ||
+ | apiVersion: cert-manager.io/ | ||
kind: ClusterIssuer | kind: ClusterIssuer | ||
metadata: | metadata: | ||
name: letsencrypt | name: letsencrypt | ||
- | namespace: cert-manager | ||
spec: | spec: | ||
acme: | acme: | ||
Line 276: | Line 386: | ||
# certificates, | # certificates, | ||
email: mike@autosys.tk | email: mike@autosys.tk | ||
- | server: https:// | + | server: https:// |
privateKeySecretRef: | privateKeySecretRef: | ||
- | # Secret resource used to store the account' | + | # Secret resource |
- | name: letsencrypt-cert-issuer-account-key | + | name: letsencrypt-issuer-account-key |
# Add a single challenge solver, HTTP01 using nginx | # Add a single challenge solver, HTTP01 using nginx | ||
solvers: | solvers: | ||
Line 285: | Line 395: | ||
ingress: | ingress: | ||
class: nginx | class: nginx | ||
+ | EOF | ||
</ | </ | ||
После того, как создан **Issuer** (в данном случае - **ClusterIssuer** с именем **letsencrypt**) можно добавить в манифест ингресса информацию о нем. Редактируем ресурс **Ingress** и приводим секцию **annotations** к виду: | После того, как создан **Issuer** (в данном случае - **ClusterIssuer** с именем **letsencrypt**) можно добавить в манифест ингресса информацию о нем. Редактируем ресурс **Ingress** и приводим секцию **annotations** к виду: |