Обновлено 21/08/2020. С момента написания статьи прошло чуть больше года и ряд примеров перестали работать — технологии развиваются, поэтому немного дополнил и переделал примеры.
В данной статье я хотел бы рассказать об установке Kubernetes на Hetzner Cloud.
На моем рабочем компьютере установлен Ubuntu Linux 18.04 и все примеры будут подразумевать использование данной операционной системы.
Для работы с Hetzner Cloud и построения кластера Kubernetes мы будем использовать утилиту hetzner-kube. Установим ее на свой локальный компьютер.
Для работы утилиты hetzner-kube и ее авторизации в Hetzner Cloud необходимо создать API Token через Hetzner Cloud Console https://console.hetzner.cloud. Вверху выбираем Select a project -> Default, в левом меню выбираем пункт Access, далее переходим в раздел API tokens, нажимаем на кнопку Generate API Token.
В результате будет сгенерирован API Token и его необходимо будет указать в конфигурации утилиты hetzner-kube.
Далее нам необходимо сгенерировать SSH ключ, который будет использоваться для доступа к серверам в Hetzner Cloud. Для этого воспользуемся утилитой ssh-keygen:
В результате в вашем домашнем каталоге будет создано два файла ~/.ssh/id_rsa (приватный ключ) и ~/.ssh/id_rsa.pub (публичный ключ).
Добавим публичный ssh ключ в Hetzner Cloud:
Непосредственно построение кластера Kubernetes выполняется очень легко:
Данная команда автоматически создаст виртуальные сервера в Hetzner Cloud и установит на них указанное количество master/worker нод кластера Kubernetes. По-умолчанию, будут использованы CX11 виртуальные сервера.
В дальнейшем, с помощью утилиты hetzner-kube, также легко изменить конфигурацию кластера Kubernetes добавляя worker ноды. Например, добавим 2 worker ноды:
К сожалению, изменить конфигурацию master нод с помощью утилиты hetzner-kube без полного пересоздания кластера Kubernetes на данный момент времени не представляется возможным.
Для работы с Kubernetes кластером используется утилита kubectl. Подробную инструкцию по ее установке для разных операционных систем можно найти по следующей ссылке.
Для того, чтобы работать с созданным кластером Kubernetes с помощью команды kubectl, необходимо сохранить локально конфигурацию созданного кластера следующим образом:
Файл с конфигурацией сохраняется в ~/.kube/config.
Теперь переходим к самому интересному — конфигурированию полученного кластера Kubernetes.
Для начала создадим базовые ресурсы необходимые для будущего развертывания приложений. Более подробную информацию вы сможете найти по следующей ссылке.
Далее необходимо, чтобы нам ingress контроллер был доступен из Интернета. Для этого с помощью утилиты kubectl редактируем service/ingress-nginx и добавляем в него список публичных IP адресов worker/master нод нашего Кубернетес кластера (только те, которые мы хотим использовать для обработки входящих запросов из Интернета).
и добавляем следующий раздел в YAML манифест
Добавляем А записи в ваш домен и ждем пока информация о них появится в ДНС. Например:
Если в ingress-nginx.yaml вы указали несколько внешних IP адресов, то можно создать несколько одинаковых DNS записей с этими IP адресами. В этом случае запросы на ваш домен будут распределяться между этими IP адресами и будет происходить балансировка нагрузки.
В данном примере для работы https сгенерируем самоподписанный SSL сертификат.
Теперь добавляем наше приложение. В качестве примера выбран простой echoserver. Создаем файл с именем app.yaml и следующим содержимым:
На этом все )) Проверяем результат:
В данной статье я хотел бы рассказать об установке Kubernetes на Hetzner Cloud.
На моем рабочем компьютере установлен Ubuntu Linux 18.04 и все примеры будут подразумевать использование данной операционной системы.
Для работы с Hetzner Cloud и построения кластера Kubernetes мы будем использовать утилиту hetzner-kube. Установим ее на свой локальный компьютер.
$ wget https://github.com/xetys/hetzner-kube/releases/download/0.5.1/hetzner-kube-0.5.1-linux-amd64 $ chmod a+x ./hetzner-kube-0.5.1-linux-amd64 $ sudo mv ./hetzner-kube-0.5.1-linux-amd64 /usr/local/bin/hetzner-kube
Для работы утилиты hetzner-kube и ее авторизации в Hetzner Cloud необходимо создать API Token через Hetzner Cloud Console https://console.hetzner.cloud. Вверху выбираем Select a project -> Default, в левом меню выбираем пункт Access, далее переходим в раздел API tokens, нажимаем на кнопку Generate API Token.
В результате будет сгенерирован API Token и его необходимо будет указать в конфигурации утилиты hetzner-kube.
$ hetzner-kube context add k8s Token: <PASTE TOKEN HERE> added context 'k8s'
Далее нам необходимо сгенерировать SSH ключ, который будет использоваться для доступа к серверам в Hetzner Cloud. Для этого воспользуемся утилитой ssh-keygen:
$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (~/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in ~/.ssh/id_rsa. Your public key has been saved in ~/.ssh/id_rsa.pub. The key fingerprint is: SHA256:1bwptZ8lPiAhtA37/2U1G7HsC+aE7qMVCtVIfN3OLzk lx4241@LX4241-LINUX The key's randomart image is: +---[RSA 2048]----+ | +. . . | | ..*o+ . . | | +o=.+ o. | | .+ o +.oo| | .S +.= .*+| | . .+o+E+*| | . o.+==o| | o.+..+.| | .oo.... | +----[SHA256]-----+
В результате в вашем домашнем каталоге будет создано два файла ~/.ssh/id_rsa (приватный ключ) и ~/.ssh/id_rsa.pub (публичный ключ).
Добавим публичный ssh ключ в Hetzner Cloud:
$ hetzner-kube ssh-key add --name k8s sshKeyAdd called SSH key k8s(95430) created
Непосредственно построение кластера Kubernetes выполняется очень легко:
$ hetzner-kube cluster create --name k8s --ssh-key k8s --master-count 1 --worker-count 1 2018/08/02 13:57:57 Creating new cluster NAME:k8s MASTERS: 1 WORKERS: 1 ETCD NODES: 0 HA: false ISOLATED ETCD: false 2018/08/02 13:57:58 creating server 'k8s-master-01'... --- [======================================] 100% 2018/08/02 13:58:18 Created node 'k8s-master-01' with IP 159.69.54.228 2018/08/02 13:58:18 creating server 'k8s-worker-01'... --- [======================================] 100% 2018/08/02 13:58:37 Created node 'k8s-worker-01' with IP 159.69.51.140 2018/08/02 13:58:37 sleep for 10s... k8s-master-01 : complete! 100.0% [==============] k8s-worker-01 : complete! 100.0% [==============] 2018/08/02 14:02:50 Cluster successfully created!
Данная команда автоматически создаст виртуальные сервера в Hetzner Cloud и установит на них указанное количество master/worker нод кластера Kubernetes. По-умолчанию, будут использованы CX11 виртуальные сервера.
В дальнейшем, с помощью утилиты hetzner-kube, также легко изменить конфигурацию кластера Kubernetes добавляя worker ноды. Например, добавим 2 worker ноды:
$ hetzner-kube cluster add-worker --name k8s --nodes 2
К сожалению, изменить конфигурацию master нод с помощью утилиты hetzner-kube без полного пересоздания кластера Kubernetes на данный момент времени не представляется возможным.
Для работы с Kubernetes кластером используется утилита kubectl. Подробную инструкцию по ее установке для разных операционных систем можно найти по следующей ссылке.
Для того, чтобы работать с созданным кластером Kubernetes с помощью команды kubectl, необходимо сохранить локально конфигурацию созданного кластера следующим образом:
$ hetzner-kube cluster kubeconfig k8s create file kubeconfig configured
Файл с конфигурацией сохраняется в ~/.kube/config.
Теперь переходим к самому интересному — конфигурированию полученного кластера Kubernetes.
Для начала создадим базовые ресурсы необходимые для будущего развертывания приложений. Более подробную информацию вы сможете найти по следующей ссылке.
$ curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.34.1/deploy/static/provider/baremetal/deploy.yaml | kubectl apply -f - % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 6170 100 6170 0 0 13987 0 --:--:-- --:--:-- --:--:-- 14022 namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created role.rbac.authorization.k8s.io/nginx-ingress-role created rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created deployment.apps/nginx-ingress-controller created limitrange/ingress-nginx created
Далее необходимо, чтобы нам ingress контроллер был доступен из Интернета. Для этого с помощью утилиты kubectl редактируем service/ingress-nginx и добавляем в него список публичных IP адресов worker/master нод нашего Кубернетес кластера (только те, которые мы хотим использовать для обработки входящих запросов из Интернета).
$ kubectl -n ingress-nginx edit service/ingress-nginx
и добавляем следующий раздел в YAML манифест
spec: externalIPs: - X.X.X.X - Y.Y.Y.Y
Добавляем А записи в ваш домен и ждем пока информация о них появится в ДНС. Например:
Type: A Name: echo.example.com Value: X.X.X.X
Если в ingress-nginx.yaml вы указали несколько внешних IP адресов, то можно создать несколько одинаковых DNS записей с этими IP адресами. В этом случае запросы на ваш домен будут распределяться между этими IP адресами и будет происходить балансировка нагрузки.
В данном примере для работы https сгенерируем самоподписанный SSL сертификат.
$ openssl req -newkey rsa:2048 -nodes -keyout echo.example.com.key -x509 -days 365 -out echo.example.com.crt Generating a 2048 bit RSA private key ..+++ .............+++ writing new private key to 'echo.example.com.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:UA State or Province Name (full name) [Some-State]:Kyiv Locality Name (eg, city) []:Kyiv Organization Name (eg, company) [Internet Widgits Pty Ltd]:Super Company Ltd Organizational Unit Name (eg, section) []:echo.example.com Common Name (e.g. server FQDN or YOUR name) []:echo.example.com Email Address []:info@echo.example.com $ cat echo.example.com.key | base64 | tr -d '\n' <YOUR PRIVATE KEY> $ cat echo.example.com.crt | base64 | tr -d '\n' <YOUR CERTIFICATE>
Теперь добавляем наше приложение. В качестве примера выбран простой echoserver. Создаем файл с именем app.yaml и следующим содержимым:
apiVersion: v1 kind: Namespace metadata: name: echoserver --- apiVersion: v1 kind: Secret metadata: name: echo.example.com-tls namespace: echoserver type: kubernetes.io/tls data: tls.crt: <YOUR CERTIFICATE> tls.key: <YOUR PRIVATE KEY> --- apiVersion: apps/v1 kind: Deployment metadata: name: echoserver namespace: echoserver spec: replicas: 1 selector: matchLabels: app: echoserver template: metadata: labels: app: echoserver spec: containers: - image: gcr.io/google_containers/echoserver:1.0 imagePullPolicy: Always name: echoserver ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: echoserver namespace: echoserver spec: ports: - name: http port: 80 targetPort: 8080 protocol: TCP selector: app: echoserver --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: echoserver namespace: echoserver annotations: kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - echo.example.com secretName: echo.example.com-tls rules: - host: echo.example.com http: paths: - path: / backend: serviceName: echoserver servicePort: 80
$ kubectl apply -f app.yaml namespace "echoserver" configured deployment "echoserver" unchanged service "echoserver" configured ingress "echoserver" unchanged
На этом все )) Проверяем результат:
$ curl https://echo.example.com/ CLIENT VALUES: client_address=('10.244.3.2', 32860) (10.244.3.2) command=GET path=/ real path=/ query= request_version=HTTP/1.1 SERVER VALUES: server_version=BaseHTTP/0.6 sys_version=Python/3.5.0 protocol_version=HTTP/1.0 HEADERS RECEIVED: Accept=*/* Connection=close Host=echo.example.com User-Agent=curl/7.58.0 X-Forwarded-For=10.244.0.0 X-Forwarded-Host=echo.example.com X-Forwarded-Port=80 X-Forwarded-Proto=http X-Original-URI=/ X-Real-IP=10.244.0.0 X-Request-ID=7a4f4aabf9a0043ea2b1ca91bd1a3adf X-Scheme=http
