Kubernetes для бедных. Настраиваем доступ по HTTP

Мы собрали кластер Kubernetes и установили менеджер пакетов Helm.

Теперь установим и настроим контроллер входящего трафика HTTP и менеджер сертификатов с поддержкой Let's Encrypt.

Ingress controller

Поскольку решение бюджетное, изображать отказоустойчивость будет обычный DNS RR на два адреса. Трафик будем принимать в обход сервиса прямо на контейнеры контроллера, запущенные с неизолированной сетью, т.е. het=host, чтобы контроллер видел реальные адреса клиентов. Если использовать сервис, трафик будет попадать в контейнеры после NAT и в логах вместо клиентских окажутся внутренние адреса узлов. Перед установкой контроллера пометим два рабочих узла кластера, например так:

kubectl label node node1 remizov.org/ingress=true
kubectl label node node2 remizov.org/ingress=true

Названия и значения меток могут быть любыми допустимыми, главное - упомянуть те же самые в nodeSelector в переменных установки.

Теперь установим Ingress controller на базе nginx при помощи helm:

cat <<EOF > values.yml
controller:
  replicaCount: 2
  hostNetwork: true
  nodeSelector:
    remizov.org/ingress: "true"
  service:
    type: ClusterIP
rbac:
  create: true
EOF

helm install --namespace kube-system -n ingress stable/nginx-ingress -f values.yml

Убедимся, что контроллеры встали на те узлы, на которые нужно, и привязаны к внешним адресам:

$ kubectl -n kube-system get po -o wide -l app=nginx-ingress,component=controller
NAME                                                READY     STATUS    RESTARTS   AGE       IP                NODE
ingress-nginx-ingress-controller-76b496fcb6-2tbls   1/1       Running   0          2m        195.201.22.121   node1
ingress-nginx-ingress-controller-76b496fcb6-dv42r   1/1       Running   0          2m        195.201.22.122   node2

Менеджер сертификатов

Менеджер сертификатов устанавливается так же при помощи helm:

helm install --namespace kube-system -n cert-manager stable/cert-manager

Создадим два центра сертификации: letsencrypt-staging для тестов и letsencrypt-v01 - для боя:

$ cat <<EOF | kubectl create -f -
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    email: user@example.com
    http01: {}
    privateKeySecretRef:
      name: letsencrypt-staging
    server: https://acme-staging.api.letsencrypt.org/directory
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-v01
spec:
  acme:
    email: user@example.com
    http01: {}
    privateKeySecretRef:
      name: letsencrypt-v01
    server: https://acme-v01.api.letsencrypt.org/directory
EOF

clusterissuer "letsencrypt-staging" created
clusterissuer "letsencrypt-v01" created

Проверка HTTPS

С этого этапа понадобится доступ к публичной зоне DNS, чтобы Let's Encrypt смогли достучаться до нашего кластера и проверить запрос на сертификат. Пусть это зона example.org. Заведём запись www2.example.org. A 195.201.22.121, так, чтобы запросы попадали на контроллер ingress. После того, как запись станет выдаваться на запросы DNS, создадим правило ingress:

$ cat <<EOF | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-staging
  name: www2-example-org
spec:
  rules:
  - host: www2.example.org
    http:
      paths:
      - backend:
          serviceName: ingress-nginx-ingress-default-backend
          servicePort: 80
        path: /
  tls:
  - hosts:
    - www2.example.org
    secretName: www2-example-org-tls
EOF

Центр сертификации определяется аннотацией certmanager.k8s.io/cluster-issuer. Сейчас выберем тестовый. Имя для сертификата выбирается из секции tls:. Если всё прошло нормально, при запросе к https://www2.example.org будет отдаваться недействительный сертификат, выписанный центром Fake LE Intermediate X1:

$ curl -kv https://www2.example.org

* Hostname was NOT found in DNS cache
*   Trying 195.201.22.121...
* Connected to www2.example.org (195.201.22.121) port 443 (#0)
. . .
* Server certificate:
*    subject: CN=www2.example.org
*    start date: 2018-05-04 19:16:17 GMT
*    expire date: 2018-08-02 19:16:17 GMT
*    issuer: CN=Fake LE Intermediate X1
*    SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* SSLv2, Unknown (23):
. . .

Теперь всё готово для того, чтобы разместить в кластере реальный веб-сервис.