📜 ⬆️ ⬇️

Installing Kubernetes on Hetzner Cloud

In this article, I would like to talk about installing Kubernetes on the Hetzner Cloud.

Ubuntu Linux 18.04 is installed on my work computer and all the examples will involve the use of this operating system.

We will use the hetzner-kube utility to work with Hetzner Cloud and build Kubernetes cluster. Install it on your local computer.
')
$ 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 

To use the hetzner-kube utility and its authorization in the Hetzner Cloud, you must create the Token API through the Hetzner Cloud Console https://console.hetzner.cloud . At the top, select Select a project -> Default, select the Access item in the left menu, then go to the API tokens section, click on the Generate API Token button.

As a result, the Token API will be generated and it will need to be specified in the configuration of the hetzner-kube utility.

 $ hetzner-kube context add k8s Token: <PASTE TOKEN HERE> added context 'k8s' 

Next, we need to generate an SSH key that will be used to access the servers in the Hetzner Cloud. To do this, use the ssh-keygen utility:

 $ 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]-----+ 

As a result, two files ~ / .ssh / id_rsa (private key) and ~ / .ssh / id_rsa.pub (public key) will be created in your home directory.

Add a public ssh key to Hetzner Cloud:

 $ hetzner-kube ssh-key add --name k8s sshKeyAdd called SSH key k8s(95430) created 

Building the Kubernetes cluster directly is very easy:

 $ 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! 

This command will automatically create virtual servers in Hetzner Cloud and install the specified number of master / worker nodes of the Kubernetes cluster on them. By default, CX11 virtual servers will be used.

Later, using the hetzner-kube utility, it is also easy to change the Kubernetes cluster configuration by adding a worker node. For example, add 2 worker nodes:

 $ hetzner-kube cluster add-worker --name k8s --nodes 2 

Unfortunately, it is not possible to change the configuration of the master node using the hetzner-kube utility without completely re-creating the Kubernetes cluster at this point in time.

To work with Kubernetes cluster, the utility kubectl is used. Detailed instructions for installing it for different operating systems can be found at the following link .

In order to work with the created Kubernetes cluster using the kubectl command, you must save the locally configuration of the created cluster as follows:

 $ hetzner-kube cluster kubeconfig k8s create file kubeconfig configured 

The configuration file is saved in ~ / .kube / config.

Now we come to the most interesting part - configuring the resulting Kubernetes cluster.

To begin with, we will create the basic resources needed for future application deployment. More information can be found at the following link .

 $ 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 

We add the ingress-nginx service, which will process requests on ports 80 (http) and 443 (https) and redirect them further to our application. Instead of XXXX, we specify the list of external IPs of our nodes in the Kubernetes cluster, which will process requests from the Internet (these can be either master or worker nodes, since LoadBalancer is not available in Hetzner Cloud at this time).

Create a file called ingress-nginx.yaml and the following contents:

 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: - XXXX - XXXX 


 $ kubectl apply -f ingress-nginx.yaml service "ingress-nginx" configured 


We check that nginx-ingress-controller and default-http-backend are running.

 $ 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 


Add A record to your domain and wait until the information about them appears in DNS. For example:

 Type: A Name: echo.example.com Value: XXXX 


If you entered several external IP addresses in ingress-nginx.yaml, you can create several identical DNS records with these IP addresses. In this case, requests for your domain will be distributed between these IP addresses and load balancing will occur.

In this example, to work with https, we will generate a self-signed SSL certificate.

 $ 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 (eg 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> 


Now add our application. As an example, the simple echoserver is selected. Create a file called app.yaml and the following contents:

 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 


That's all)) Check the result:

 $ 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 

Source: https://habr.com/ru/post/419323/


All Articles