Установка kubernetes на CentOS 8

Файлы, используемые в видео.

Установка докера

cat > install-docker-ce8.sh << EOF2
#!/bin/bash

dnf install tc ipvsadm -y

systemctl stop NetworkManager.service
systemctl disable NetworkManager.service
dnf install network-scripts

dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
dnf install docker-ce --nobest -y

mkdir /etc/docker

cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ],
  "iptables": false
 } 
EOF 
mkdir -p /etc/systemd/system/docker.service.d 
systemctl daemon-reload 
systemctl enable docker 
systemctl restart docker 
EOF2 

chmod +x install-docker-ce8.sh

Установка kubernetes

cat >  install-k8s-ce8.sh << EOF2
#!/bin/bash

iptables -P FORWARD ACCEPT

cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

sysctl --system

cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable kubelet.service
EOF2

chmod +x install-k8s-ce8.sh

Инициализация кластера:

kubeadm init --pod-network-cidr=10.244.0.0/16

Создание токена на присоединения ноды:

kubeadm token create --print-join-command

Подготовка ноды к обслуживанию:

kubectl drain node2.kryukov.biz --ignore-daemonsets

Возврат ноды из обслуживания:

kubectl uncordon node2.kryukov.biz

kuberentes: pod, replicaset, deployment, service

Деплой контейнера в кубернетес: Pod — ReplicaSet — Deployment

Как использовать Service (ClusterIP, NodePort)

Что бы понять всю прелесть автоматизации, сначала делаем все руками.

Kubernetes dasboard. Не все так просто…

Dashboard в kubernetes. Изначально планировал показать подключение дашборда в рамках предыдущего видео. И обычно, для доступа к нему достаточно двух команд в командной строке, но не в случае kubespray 2.12.

Установка последнего дашборда, права доступа и прочие мелочи.

Kubernetes добавление, удаление node

Добавление, удаление ноды в кубернетес.

Добавляем при помощи kubespray. Удаляем руками.

В начале видео было заявлено включение дашборда. Но «в жизни все не так как на самом деле». Пришлось разбираться с глючным дашбордом, ставить новый и править доступы. Все это заняло достаточный кусок времени. Пришлось выносить в отдельное видео.

Вакансии Системный администратор Linux

В дружественной компании открыты вакансии Сисадминов Linux. Компания надежная. Работа удаленная, т.е. кандидат может проживать в любом регионе России. Работы много, кризис на работу не влияет, даже увеличил её (работы) количество.

Системный администратор Linux

Обязанности:

  • Администрирование и поддержка информационных систем: микросервисы, WEB приложения.
  • Участие в релизах, выполнение регламентных работ (несколько раз в месяц работы могут быть после 20:00 по Москве)

Требования:

  • Уверенные знания принципов работы сетей TCP/IP (как минимум умение пользоваться базовыми программами типа tcpdump, traceroute и прочих. Понимание возможных ошибок и путей их устранения).
  • Хорошие знания nginx (настройка, поиск неисправностей, мониторинг ошибок).
  • Понимание работы приложений java (настройка запуска, мониторинг, умение читать java логи, понимание основных ошибок).
  • Грамотная речь и письмо.
  • Способность к обучению, инициативность.
  • Плюсом при собеседовании являются знания:
    • ansible, haproxy, docker, prometheus, elasticsearch, git, kubernetes.
    • Понимание процессов DevOps.
    • Базовые знания PostgreeSQL (выполнение простых SQL запросов).

Условия:

  • Удаленная работа (по желанию, возможно в офисе м. Павелецкая).
  • Официальное трудоустройство.
  • Возможности профессионального и карьерного роста.

Системный администратор Alfresco

Обязанности:

  • Администрирование и поддержка Alfresco Community Editions.
  • Администрирование и поддержка информационных систем: микросервисы, WEB приложения.

Требования:

  • Опыт работы с Alfresco Community Editions.
  • Понимание работы приложений java (настройка запуска, мониторинг, умение читать java логи, понимание основных ошибок).
  • Уверенные знания принципов работы сетей TCP/IP.
  • Грамотная речь и письмо.
  • Способность к обучению, инициативность.
  • Плюсом при собеседовании являются знания:
    • ansible, docker, prometheus, elasticsearch.
    • работа с файловыми системами Linux, в том числе сетевыми и распределенными.
    • знание LVM.

Условия:

  • Удаленная работа (по желанию, возможно в офисе м. Павелецкая).
  • Официальное трудоустройство.
  • Возможности профессионального и карьерного роста.

Так же есть вакансии:

  • в службу поддержки первой линии,
  • задачи в области тестирования и мониторинга.

Ссылки на резюме (желательно на hh.ru) присылайте на мыло arturkryukov@krlb.ru

Elasticsearch и ошибка «failed to parse field [time] of type [date]»

В один прекрасный день, elastic может сойти с ума. Перестать принимать информацию в индекс и начать кидать в логи ошибки типа:

failed to parse field [time] of type [date]

Проблема в автоматическом распознавании содержимого полей. Особенно это касается поля, в котором содержится дата и время. Тот самый прекрасный день настал, когда наши программеры немножечко изменили формат даты. И этот формат не стал совпадать с форматом, который эластик использует по умолчанию.

Какой формат используется можно увидеть в mapping интересующего вас индекса:

GET /index-name/_mapping

Следующая засада, вы не можете на лету поменять тип поля в индексе. Только путем пересоздания индекса с нуля.

И самое противное. Если вы используете группу индексов в IndexPattern, сбойный индекс вылетит из поиска по проблемному полю.

Вобщем проблем с такими «прыгающими» типами полей  будет чертовски много. Поэтому, рекомендую «гвоздями» прибивать тип поля в индексе.

Например, в индексе есть поле, содержащее дату. В Elastic такие поля могут попасть под шаблон (mapping) по умолчанию для даты и в индексе появится поле типа date. Потом программеры поменяют формат даты и поле перестает подходить под шаблон. Эластик будет считать что это поле типа text и тупо перестает добавлять информацию в индекс.

Если вы не планируете в дальнейшем использовать поле для поиска, самое простое решение привести его к типу text. В дальнейшем, смена формата даты никоим образом не повлияет на работу индекса.

Создание шаблона для индекса или группы индексов.

Посмотреть все шаблоны можно так:

GET _template

Посмотреть конкретный шаблон:

GET _template/template_name

Создать шаблон:

PUT _template/template_name
{
	"order" : 0,
	"index_patterns" : [
	  "index-name-*"
	],
	"settings" : {
	  "index" : {
		"number_of_shards" : "1"
	  }
	},
	"mappings" : { 
		"properties": {
			"time": {
          			"type" : "text",
         			"fields" : {
            				"keyword" : {
              					"ignore_above" : 256,
              					"type" : "keyword"
            				}
         			}
			}
		}
	},
	"aliases" : { }
}

Параметр index-patterns определяет шаблон именён индексов к которым будет применяться данный template. Т.е. если будет создан индекс с , например, именем index-name-2020.04.01, то шаблон будет к нему применен. И в дальнейшем в списке mappings вы увидите, что поле time будет иметь тип text.

Так же в этом шаблоне ограничивается количество шардов единицей. По умолчанию у вновь создаваемого шаблона значение этого параметра равно 3. Такое ограничение имеет смысл для небольших индексов. Максимальное количество шардов на сервер ограничено и при большом количестве индексов имеет смысл на один индекс давать один шард.

OpenVPN and OpenLDAP, not MD5 hash password

Собственно коронавирус, пользователи стаями потянулись на удалёнку. Пришла пора VPN серверов.

Достаточно стандартное решение OpenVPN + OpenLDAP позволяет управлять доступом пользователей к vpn серверу. Конфигурируется незамысловато, в интернет есть куча готовых советов как это делать. У меня в старой wiki была статейка как приготовить OpenVPN. Предупреждаю, статейка старинная, но еще рабочая.

Но в процессе настройки нашел забавную особенность:

Если в OpenLDAP для хеширования пароля используется не MD5, то плагин openvpn-auth-ldap будет давать ошибку.

А в случае MD5 — все работает как часы.

Попытался было заглянуть в исходники модуля. И понял, что современный С (или что они там использовали) далеко ушел от классического Керниган&Ритчи 🙂 Поэтому вот, пришлось возвращаться к MD5.

Если кто разбирается в современном С и норм владеет английским, скажите авторам, что: «Хьюстон, у нас проблемы».

З.Ы. Странно как то. Но оно заработало с разными типами хешей. И ведь ничего не трогал.

Kubernetes, включение RBAC на namespace

Создадим namespace artur, доступ к которому будем разрешать пользователю artur:

# kubectl create namespace artur

Как создавать пользователя было описано тут.

Создаём файл с описанием role и rolebindig — 01. yaml следующего содержания:

---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: artur # namespace к которому применяются огранияения
      name: artur-role
    rules:
    - apiGroups: [""] # "" indicates the core API group
      resources: ["pods", "services", "replicationcontrollers"]
      verbs: ["create", "get", "update", "list", "delete"]
    - apiGroups: [""]
      resources: ["pods/log"]
      verbs: ["get", "list"]
    - apiGroups: [""]
      resources: ["pods/exec"]
      verbs: ["create"]
    - apiGroups: ["apps"]
      resources: ["deployments","daemonsets","replicasets","statefulsets"]
      verbs: ["create", "get", "update", "patch", "list", "delete", "deploy"]
    - apiGroups: ["autoscaling"]
      resources: ["horizontalpodautoscalers"]
      verbs: ["create", "get", "update", "list", "delete"]
   - apiGroups: ["batch"]
     resources: ["jobs","cronjobs"]
     verbs: ["create", "get", "update", "list", "delete"]
--- apiVersion: rbac.authorization.k8s.io/v1 
kind: RoleBinding 
metadata:
 name: artur-rb
 namespace: artur
subjects: 
- kind: User
  name: artur
  apiGroup: rbac.authorization.k8s.io 
roleRef:
 kind: Role
 name: artur-role
 apiGroup: rbac.authorization.k8s.io

Создаем роли и биндинги в кубернетес.

# cubectl apply -f 01.yaml

Всё, что тут написано — это художественная обработка материалов доброго человека.