Любая помощь очень ценится.
Отказ от ответственности: Это далеко не производственная установка, и она нацелена, главным образом, на то, чтобы пролить некоторый свет на общие части и кусочки, чтобы помочь вам сориентироваться вокруг. Кроме того, это будет довольно стена текста.
Цель: запустить JupyterHub через https в кластере kubernetes.
Первоначальное рассмотрение: запуск обоих nginx и JupyterHub не совсем соответствует философии k8s. Контейнеры должны быть размещены вместе в одной капсуле только в том случае, если они естественным образом масштабируются вместе. Вот это не тот случай. Отсюда предложение запускать их отдельно ...
Создание минимального примера для JupyterHub в кластере k8s.
Шаг 1. Создайте пространство имен для этого примера
Это довольно просто и просто здесь как дополнительная гарантия, чтобы не путать вещи.
Файл манифеста: ns-example.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ns-example
просто: kubectl create -f ns-example.yaml
и пространство имен там. Отныне ресурсы могут быть легко созданы / удалены таким образом.
Шаг 2. Создание базовой настройки JupyterHub
Для достижения этой цели используется jupyterhub/jupyterhub
публичный официальный образ докера. Никакой настройки или чего-то еще, просто иметь простой многопользовательский JupyterHub и отвечать на него, чтобы мы могли заключить его в оболочку службы.
Мы начинаем с обслуживания, ничего особенного, просто удобное имя и порт 8000, доступный для локального кластера. Официальная документация рекомендует, чтобы службы были созданы перед ресурсами sts / deploy / pod, поэтому мы согласны с этим.
Файл манифеста: svc-jupyterhub.yaml
apiVersion: v1
kind: Service
metadata:
namespace: ns-example
name: svc-jupyterhub
labels:
name: jupyterhub
spec:
selector:
name: jupyterhub
ports:
- protocol: TCP
port: 8000
targetPort: 8000
Теперь для фактического развертывания JupyterHub, который будет представлен вышеупомянутым сервисом. Опять же, ничего особенного, это просто имитация значения по умолчанию docker run -p 8000:8000 -d --name jupyterhub jupyterhub/jupyterhub jupyterhub
, как отмечено в в официальном репозитории JupyterHub . Это без каких-либо настроек, просто в качестве основного примера ...
Файл манифеста: dep-jupyterhub.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
namespace: ns-example
name: dep-jupyterhub
labels:
name: jupyterhub
spec:
replicas: 1
template:
metadata:
labels:
name: jupyterhub
spec:
containers:
- name: jupyterhub
image: jupyterhub/jupyterhub
command: ['jupyterhub']
ports:
- containerPort: 8000
Примечание: для моего локального тестового запуска первоначальное извлечение образа из сети заняло довольно много минут, но мммм ...
После создания этих ресурсов JupterHub должен быть запущен и работать, но виден только в локальном кластере k8s.
Шаг 3: Создание сервера nginx
Теперь нам не хватает nginx для предоставления и завершения TLS вокруг нашего JupyterHub. Есть и другие способы создания шкуры для кошки, но так как вы поделились только частью настроек для своего nginx, вот некоторые, опять же, отрывочные, части для начала.
Чтобы создать минимальный nginx и имитировать TLS, нам понадобятся некоторые файлы конфигурации.
Мы начнем с nginx.conf
файла, который будет содержать нашу конфигурацию nginx. Это естественный кандидат на ConfigMap. Кроме того, обратите внимание, что это ни в коем случае не является идеальной, полной или готовой к установке настройкой - это всего лишь быстрый способ взлома nginx, например, для запуска. Есть повторы, это может и должно быть оптимизировано , перенаправление на порт 80 не работает должным образом, так как это приведет к переброске на несуществующий домен, если домен для сервера является воображаемым, подстановочный сертификат самоподписан, yada Яда, Яда ... Но это иллюстрирует идею: nginx завершает TLS и отправляет трафик восходящему сервису вокруг JupyterHub.
Файл манифеста: cm-nginx.yaml
kind: ConfigMap
apiVersion: v1
metadata:
namespace: ns-example
name: cm-nginx
data:
nginx.conf: |
# Exmaple nginx configuration file
#
# Commented out parts are left for pointers
upstream jupyterhub {
server svc-jupyterhub:8000 fail_timeout=0;
}
# jupyterhub.my-domain.com https request sent to upstream jupyterhub proxy
server {
listen 443 ssl;
server_name jupyterhub.my-domain.com;
ssl_certificate /etc/nginx/ssl/wildcard.my-domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.my-domain.com.key;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jupyterhub;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
}
}
# redicrection from http to https for jupyterhub.my-domain.com
# this obviously doesn't work since my-domain.com is not pointing to our server
server {
listen 80;
server_name jyputerhub.my-domain.com;
# root /nowhere;
# rewrite ^ https://jupyterhub.my-domain.com$request_uri permanent;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jupyterhub;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
}
}
# if none of named servers is matched on http...
# this obviously doesn't work since my-domain.com is not pointing to our server
server {
listen 80 default_server;
# root /nowhere;
# rewrite ^ https://jupyterhub.my-domain.com permanent;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jupyterhub;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
}
}
# if none of named server is matched on https...
# this obviously doesn't work since my-domain.com is not pointing to our server
server {
listen 443 default_server;
ssl_certificate /etc/nginx/ssl/wildcard.my-domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.my-domain.com.key;
# root /nowhere;
# rewrite ^ https://juputerhub.my-domain.com permanent;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jupyterhub;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
}
}
Теперь нам нужны эти сертификаты, например, для работы ...
Конечно, сертификаты (особенно закрытые ключи) являются идеальными кандидатами на ресурсы Secret k8s, но это самозаверяющий сертификат (созданный на лету только для этого поста) для несуществующего примера домена ... Далее, я бы Я хотел бы проиллюстрировать ConfigMap с двумя файлами здесь и, наконец, но, возможно, самое важное - мне лень набирать еще две команды, чтобы получить все в base64, например, ради. Так что здесь все снова идет как ConfigMap ... (да, вместо этого он должен быть Secret, и да, РЕАЛЬНЫЙ сертификат / ключ не должен быть открытым, но pssst, никому не говорите) ...
Файл манифеста: cm-wildcard-certificate-my-domain-com.yaml
kind: ConfigMap
apiVersion: v1
metadata:
namespace: ns-example
name: cm-wildcard-certificate-my-domain-com
data:
wildcard.my-domain.com.key: |
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCtU3Yk+tKSnPFC
l+0Iutma0xI79MiWEf8Z2vacyfgMUNvthqFxTfTIeeySzzFh1KVx8pYJbfL1Gkxx
iDfYZbKwQxhlV363bx8J+j2YnIIQ4uZGQ0MlxMlb65e0JfLayLOIffo7vSPqqBDa
6MY4qjqVuiJ7zW9/X9h+38Y76fHyEzde03cHihKnkW0smNKZcwYBLz5oa1D39zv5
WTqQrq+2GXEGfHvArDc06azbAm3o55iRmFPhIWEJcX6oCs0nd5jLIpycy43ayIKv
HvjEmChDnsrQDkMImFk0nDsMn0Leu0DAsyPopm3TIGqoPwZY4Sk+zn7ttjU/6VUI
pndJDVd5AgMBAAECggEAH6mTd4XqWaYZ3JRsVJ/tiH7uYc2Bpwh6lXqOem3axkUv
J+DkNRKMmOLM+LSozLpPztUF24seSvAW7tZ3fSx2zAQ1vK2TFGdUQDpabjqI+BS7
BDLdXVTpg8Ux3VLhXl4zjceVorwWh5NUIOlM7KUMNrXd/se0iowzvFmcmO1PqWzU
O6KI5EKz6LTUpEU/7RSl+wt/Ix4yTRYblkHlzWL1GXmQ50HYFZtC3iFEk4H4yDiQ
Z4VI+gGSpQGKDBQdR9OIXc3seVPOPnSd5NjDXQU8IR36VWHE8xG6k9/+TeU8r9ue
zNecjieWbFny4UE+uELXdeaRcmH+M8MTrKDApDj+QQKBgQDZ0WdOZ1O8QqILMwuR
Up2+oT88A6JZjfUICpDlsXgCaitT4YyBXkBwQyyQiTVspo6+ENHSBS584JdmjRpe
rqXazlwimY0vdINcm4O1279gmHOGaKffLzik1AKNSQEm52rNhle8xoXWD/cmLjvc
NYgzpPPFIWwXG0dniCCnbfR8tQKBgQDLtXpuckotb8guCGThFn6nb01Hcsit9OfC
QG9KXd8fpRV+YKqKF2wx1KeVgMoXMbmT78LRl0wArCQZsh16cqS/abH8S5k2v9jx
L5q+YYVcXC1U7Oolekoddob8af0qp4FnVDjRU9GiMtv2UQoX4yoX4kHkdWZqqFNr
q12VlksuNQKBgQCC6odq6lO7zVjT3mRPfhZto0D8czq7FMV3hdI9HAODgAh2rBPl
FZ8pWlaIsM85dIpK1pUl5BNi3yJgcuKskdAByRI7gYsIQMFLgfUR8vf9uOOGn5R2
Yk1rVDoMbRqSJXld+ib1wWRjmsjzW8qCunIYiEYz77il0rGCGqF1wHK4GQKBgQCN
RCTLQua9667efWO31GmwozbsPWV9fUDbLOQApmh9AXaOVWruqJ+XTumIe++pdgpD
1Rk9T7adIMNILoTSzX4CX8HWPHbbyN8hIuok7GwXSLUHF+SoaM3M8M1bbgTq9459
oaJlR8MwwCRaBIkDV71xIq6fR+rmPCTdndEgU0F/oQKBgQCWC1K5FySXxaxzomsZ
eM3Ey6cQ36QnidjuHAEiEcaJ+E/YmG/s9MPbLCRI8tn6KGvOW3zKzrHXOsoeXsMU
SCmRUpB0J5PqVbbTdj12kggX3x6I7TIkXucopCA3Nparhlnqx7amski2EB/EVE0C
YWkjEAMUCquUmJeEg2dELIiGOw==
-----END PRIVATE KEY-----
wildcard.my-domain.com.crt: |
-----BEGIN CERTIFICATE-----
MIIDNjCCAh4CCQCUtoVaGZH/NDANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCTlkxCzAJBgNVBAcMAk5ZMQwwCgYDVQQKDANOL0ExDDAKBgNV
BAsMA04vQTEYMBYGA1UEAwwPKi5teS1kb21haW4uY29tMB4XDTE4MDgyODA5Mzkz
N1oXDTIyMDUyNDA5MzkzN1owXTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQsw
CQYDVQQHDAJOWTEMMAoGA1UECgwDTi9BMQwwCgYDVQQLDANOL0ExGDAWBgNVBAMM
DyoubXktZG9tYWluLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AK1TdiT60pKc8UKX7Qi62ZrTEjv0yJYR/xna9pzJ+AxQ2+2GoXFN9Mh57JLPMWHU
pXHylglt8vUaTHGIN9hlsrBDGGVXfrdvHwn6PZicghDi5kZDQyXEyVvrl7Ql8trI
s4h9+ju9I+qoENroxjiqOpW6InvNb39f2H7fxjvp8fITN17TdweKEqeRbSyY0plz
BgEvPmhrUPf3O/lZOpCur7YZcQZ8e8CsNzTprNsCbejnmJGYU+EhYQlxfqgKzSd3
mMsinJzLjdrIgq8e+MSYKEOeytAOQwiYWTScOwyfQt67QMCzI+imbdMgaqg/Bljh
KT7Ofu22NT/pVQimd0kNV3kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAI+G44qo6
BPTC+bLm+2SAlr6oEC09JZ8Q/0m8Se1MLJnzhIXrWJZIdvEB1TtXPYDChz8TPKTd
QQCh7xNPZahMkVQWwbsknNCPdaLp0SAHMNs3nfTQjZ3cE/RRITqFkT0LGSjXkhtj
dTZdzKvcP8YEYnDhNn3ZBK04djEsAoIyordRATFQh1B7/0I3BsUAwItDEwH+Mv5G
rvSYkoi+yw7/koijxJHDbH0+WXYdcsmbWrMEh6H92Z64TMOFS+N6ZQRsNvzfiSwZ
KM2yEtU9c74CPKS+UleQLjDufk8epmNHx6+80aHj7R9z3mbw4dL7yKwlbGws2GAW
TE+Fk0HB+9W7fw==
-----END CERTIFICATE-----
Теперь нам нужен сервис вокруг nginx.
Есть и другие способы снятия шкуры с кошки, но здесь, опять же, для простоты, взят самый простой - подход NodePort. Вы можете использовать вход, вы можете использовать externalIP или еще много чего, но это пример, поэтому NodePort это так.
Файл манифеста: svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
namespace: ns-example
name: svc-nginx
labels:
name: nginx
spec:
type:
NodePort
selector:
name: nginx
ports:
- protocol: TCP
name: http-port
port: 80
targetPort: 80
- protocol: TCP
name: ssl-port
port: 443
targetPort: 443
Наконец, после того, как все создано, мы можем запустить наше развертывание nginx. Опять же, ничего особенного, просто склеить все ConfigMaps с официальным изображением nginx (да, это плохая идея использовать «последние» или опустить теги для изображения докера, как это было сделано здесь, но, опять же, это пример, и имейте в виду, чтобы не быть укушенным этим при развертывании производства ...)
Файл манифеста: dep-nginx.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
namespace: ns-example
name: dep-nginx
labels:
name: nginx
annotations:
ingress.kubernetes.io/secure-backends: "true"
kubernetes.io/tls-acme: "true"
spec:
replicas: 1
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/conf.d
name: nginx-conf
- mountPath: /etc/nginx/ssl
name: wildcard-certificate
volumes:
- name: nginx-conf
configMap:
name: cm-nginx
items:
- key: nginx.conf
path: nginx.conf
- name: wildcard-certificate
configMap:
name: cm-wildcard-certificate-my-domain-com
Заключительные ноты:
- Как уже упоминалось ранее, они не предназначены для использования в производстве, множество мелких деталей от обработки ресурсов до управления версиями может откусить вас назад. Это всего лишь пример.
- Сертификаты являются самозаверяющими, и браузеры будут жаловаться на это, если вы перейдете на nginx.
- Все было вставлено из проверенной установки на DockerCE Edge версии 18.06.0-ce-mac69 (26398) и 1.9.3 k8s, поэтому должно быть более или менее безошибочно.
- При вводе
kubectl get cm,deploy,svc,pod -n ns-example -o wide
должна отображаться вся информация о том (из каких портов целевой браузер будет представлять особый интерес для svc-nginx).
- Наконец, так как все заключено в файлы манифеста yaml, очистка - это просто вопрос упорядоченного удаления ресурсов (заботясь о последнем удалении пространства имен).