Установка Kubernetes на Hetzner Cloud

от автора

В данной статье я хотел бы рассказать об установке Kubernetes на Hetzner Cloud.

На моем рабочем компьютере установлен Ubuntu Linux 18.04 и все примеры будут подразумевать использование данной операционной системы.

Для работы с Hetzner Cloud и построения кластера Kubernetes мы будем использовать утилиту hetzner-kube. Установим ее на свой локальный компьютер.

$ wget https://github.com/xetys/hetzner-kube/releases/download/0.3.1/hetzner-kube-linux-amd64 $ chmod a+x ./hetzner-kube-linux-amd64  $ sudo mv ./hetzner-kube-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/master/deploy/mandatory.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 deployment "default-http-backend" created service "default-http-backend" created configmap "nginx-configuration" created configmap "tcp-services" created configmap "udp-services" created serviceaccount "nginx-ingress-serviceaccount" created clusterrole "nginx-ingress-clusterrole" created role "nginx-ingress-role" created rolebinding "nginx-ingress-role-nisa-binding" created clusterrolebinding "nginx-ingress-clusterrole-nisa-binding" created deployment "nginx-ingress-controller" created

Добавляем сервис ingress-nginx, который будет обрабатывать запросы на портах 80 (http) и 443 (https) и перенаправлять их дальше на наше приложение. Вместо X.X.X.X указываем список внешних IP наших нод в кластере Kubernetes, которые будут обрабатывать запросы из Интернета (это могут быть как master, так и worker ноды, поскольку LoadBalancer в Hetzner Cloud на данный момент времени отсутствует).

Создаем файл с именем ingress-nginx.yaml и следующим содержимым:

apiVersion: v1 kind: Service metadata:   name: ingress-nginx   namespace: ingress-nginx spec:   type:   ports:   - name: http     port: 80     targetPort: 80     protocol: TCP   - name: https     port: 443     targetPort: 443     protocol: TCP   selector:     app: ingress-nginx   externalIPs:   - X.X.X.X   - X.X.X.X
$ kubectl apply -f ingress-nginx.yaml  service "ingress-nginx" configured

Проверяем что nginx-ingress-controller и default-http-backend поды запущены.

$ kubectl get pods -n ingress-nginx  NAME                                        READY     STATUS    RESTARTS   AGE default-http-backend-55c6c69b88-hvl4x       1/1       Running   0          51m nginx-ingress-controller-6658c97f58-d6jkg   1/1       Running   0          51m

Добавляем А записи в ваш домен и ждем пока информация о них появится в ДНС. Например:

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 --- 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: extensions/v1beta1 kind: Deployment metadata:   name: echoserver   namespace: echoserver spec:   replicas: 1   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


ссылка на оригинал статьи https://habr.com/post/419323/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *