Представям ви урок за генериране на достъп до Kubernetes клъстери с помощта на Dex, dex-k8s-authenticator и GitHub.

Локален мем от рускоговорящия чат на Kubernetes в
Въведение
Използваме Kubernetes за създаване на динамични среди за екипа от разработчици и QA. По този начин искаме да им предоставим достъп до клъстера както за дашборда, така и за kubectl. За разлика от OpenShift, ваниловият Kubernetes няма вградена автентикация, затова използваме външни инструменти за тази цел.
В тази конфигурация използваме:
- — уеб приложение за генериране на конфигурация за kubectl
- — доставчик на OpenID Connect
- GitHub — просто защото използваме GitHub в нашата компания
Опитахме се да използваме Google OIDC, но за съжаление не успяхме И така, как работи нашият процес на удостоверяване в Kubernetes в визуализация:
Няколко подробности и по точки:

Процес на авторизация
Потребителят се вписва в dex-k8s-authenticator (
- login.k8s.example.com
dex-k8s-authenticator пренасочва заявката към Dex () - dex.k8s.example.com
Dex пренасочва към страницата за удостоверяване в GitHub) - GitHub генерира необходимата информация за удостоверяване и я връща на Dex
- Dex предава получената информация на dex-k8s-authenticator
- Потребителят получава OIDC токен от GitHub
- dex-k8s-authenticator добавя токена в kubeconfig
- kubectl предава токена на KubeAPIServer
- KubeAPIServer на база на предадения токен връща достъп до kubectl
- Потребителят получава достъп от kubectl
- Подготовителни действия
Разбира се, вече имаме инсталиран Kubernetes клъстер (
k8s.example.com), както и предварително инсталиран HELM. Също така имаме организация в GitHub (super-org).Ако нямате HELM, инсталацията е
много проста .
Прехвърлете на страницата с настройки на организацията, (
) и създайте ново приложение (Authorized OAuth App):https://github.com/organizations/super-org/settings/applicationsСъздаване на ново приложение в GitHub

Попълнете полетата с необходимите URL адреси, например:
Homepage URL:
- Authorization callback URL:
https://dex.k8s.example.com - Внимавайте с линковете, важно е да не загубите слешовете.
https://dex.k8s.example.com/callback
В отговор на попълнената форма, GitHub ще генерира
Client secret Client ID и , запазете ги на безопасно място, те ще ни трябват (например, ние използвамеза съхранение на тайни): Client ID: 1ab2c3d4e5f6g7h8 Client secret: 98z76y54x32w1
Подгответе DNS записи за субдомените , както и SSL сертификати за ингресите. dex-k8s-authenticator пренасочва заявката към Dex ( и Dex пренасочва към страницата за удостоверяване в GitHub, както и SSL сертификати за ингресите.
Ще създадем SSL сертификати:
cat <<EOF | kubectl create -f -
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: cert-auth-dex
namespace: kube-system
spec:
secretName: cert-auth-dex
dnsNames:
- dex.k8s.example.com
acme:
config:
- http01:
ingressClass: nginx
domains:
- dex.k8s.example.com
issuerRef:
name: le-clusterissuer
kind: ClusterIssuer
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: cert-auth-login
namespace: kube-system
spec:
secretName: cert-auth-login
dnsNames:
- login.k8s.example.com
acme:
config:
- http01:
ingressClass: nginx
domains:
- login.k8s.example.com
issuerRef:
name: le-clusterissuer
kind: ClusterIssuer
EOF
kubectl describe certificates cert-auth-dex -n kube-system
kubectl describe certificates cert-auth-login -n kube-system ClusterIssuer с име le-clusterissuer вече трябва да съществува, а ако не — ще го създадем с HELM:
helm install --namespace kube-system -n cert-manager stable/cert-manager
cat << EOF | kubectl create -f -
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: le-clusterissuer
namespace: kube-system
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: k8s-admin@example.com
privateKeySecretRef:
name: le-clusterissuer
http01: {}
EOFКонфигурация на KubeAPIServer
За да работи kubeAPIServer, е необходимо да конфигурирате OIDC и да актуализирате кластера:
kops edit cluster
...
kubeAPIServer:
anonymousAuth: false
authorizationMode: RBAC
oidcClientID: dex-k8s-authenticator
oidcGroupsClaim: groups
oidcIssuerURL: https://dex.k8s.example.com/
oidcUsernameClaim: email
kops update cluster --yes
kops rolling-update cluster --yesИзползваме за разгръщане на клъстери, но аналогично работи и за .
Конфигурация на Dex и dex-k8s-authenticator
За да работи Dex, е необходимо да имате сертификат и ключ от Kubernetes сървъра, ще го вземем оттам:
sudo cat /srv/kubernetes/ca.{crt,key}
-----BEGIN CERTIFICATE-----
AAAAAAAAAAABBBBBBBBBBCCCCCC
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
DDDDDDDDDDDEEEEEEEEEEFFFFFF
-----END RSA PRIVATE KEY-----Ще клонираме репозитория dex-k8s-authenticator:
git clone git@github.com:mintel/dex-k8s-authenticator.git
cd dex-k8s-authenticator/С помощта на values файлове можем гъвкаво да конфигурираме променливи за нашите .
Нека опишем конфигурацията за Dex:
cat << EOF values-dex.yml
global:
deployEnv: prod
tls:
certificate: |-
-----BEGIN CERTIFICATE-----
AAAAAAAAAAABBBBBBBBBBCCCCCC
-----END CERTIFICATE-----
key: |-
-----BEGIN RSA PRIVATE KEY-----
DDDDDDDDDDDEEEEEEEEEEFFFFFF
-----END RSA PRIVATE KEY-----
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
path: /
hosts:
- dex.k8s.example.com
tls:
- secretName: cert-auth-dex
hosts:
- dex.k8s.example.com
serviceAccount:
create: true
name: dex-auth-sa
config: |
issuer: https://dex.k8s.example.com/
storage: # https://github.com/dexidp/dex/issues/798
type: sqlite3
config:
file: /var/dex.db
web:
http: 0.0.0.0:5556
frontend:
theme: "coreos"
issuer: "Example Co"
issuerUrl: "https://example.com"
logoUrl: https://example.com/images/logo-250x25.png
expiry:
signingKeys: "6h"
idTokens: "24h"
logger:
level: debug
format: json
oauth2:
responseTypes: ["code", "token", "id_token"]
skipApprovalScreen: true
connectors:
- type: github
id: github
name: GitHub
config:
clientID: $GITHUB_CLIENT_ID
clientSecret: $GITHUB_CLIENT_SECRET
redirectURI: https://dex.k8s.example.com/callback
orgs:
- name: super-org
teams:
- team-red
staticClients:
- id: dex-k8s-authenticator
name: dex-k8s-authenticator
secret: generatedLongRandomPhrase
redirectURIs:
- https://login.k8s.example.com/callback/
envSecrets:
GITHUB_CLIENT_ID: "1ab2c3d4e5f6g7h8"
GITHUB_CLIENT_SECRET: "98z76y54x32w1"
EOF
И за dex-k8s-authenticator:
cat << EOF values-auth.yml
global:
deployEnv: prod
dexK8sAuthenticator:
clusters:
- name: k8s.example.com
short_description: "k8s cluster"
description: "Kubernetes cluster"
issuer: https://dex.k8s.example.com/
k8s_master_uri: https://api.k8s.example.com
client_id: dex-k8s-authenticator
client_secret: generatedLongRandomPhrase
redirect_uri: https://login.k8s.example.com/callback/
k8s_ca_pem: |
-----BEGIN CERTIFICATE-----
AAAAAAAAAAABBBBBBBBBBCCCCCC
-----END CERTIFICATE-----
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
path: /
hosts:
- login.k8s.example.com
tls:
- secretName: cert-auth-login
hosts:
- login.k8s.example.com
EOFНека инсталираме Dex и dex-k8s-authenticator:
helm install -n dex --namespace kube-system --values values-dex.yml charts/dex
helm install -n dex-auth --namespace kube-system --values values-auth.yml charts/dex-k8s-authenticatorНека проверим работоспособността на услугите (Dex трябва да върне код 400, а dex-k8s-authenticator — код 200):
curl -sI https://dex.k8s.example.com/callback | head -1
HTTP/2 400
curl -sI https://login.k8s.example.com/ | head -1
HTTP/2 200RBAC конфигурация
Създаваме ClusterRole за групата, в нашия случай с права само за четене:
cat << EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-read-all
rules:
-
apiGroups:
- ""
- apps
- autoscaling
- batch
- extensions
- policy
- rbac.authorization.k8s.io
- storage.k8s.io
resources:
- componentstatuses
- configmaps
- cronjobs
- daemonsets
- deployments
- events
- endpoints
- horizontalpodautoscalers
- ingress
- ingresses
- jobs
- limitranges
- namespaces
- nodes
- pods
- pods/log
- pods/exec
- persistentvolumes
- persistentvolumeclaims
- resourcequotas
- replicasets
- replicationcontrollers
- serviceaccounts
- services
- statefulsets
- storageclasses
- clusterroles
- roles
verbs:
- get
- watch
- list
- nonResourceURLs: ["*"]
verbs:
- get
- watch
- list
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
EOFНека създадем конфигурация за ClusterRoleBinding:
cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: dex-cluster-auth
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-read-all
subjects:
kind: Group
name: "super-org:team-red"
EOFСега сме готови за тестване.
Тестове
Преминете на страницата за вход (https://login.k8s.example.com) и влезте с вашия GitHub акаунт:

Страница за удостоверяване

Страница за удостоверяване, пренасочена към GitHub

Следвайте генерираната инструкция, за да получите достъп
След като копираме текста от уеб страницата, можем да използваме kubectl за управление на ресурсите на нашия клъстер:
kubectl get po
NAME READY STATUS RESTARTS AGE
mypod 1/1 Running 0 3d
kubectl delete po mypod
Error from server (Forbidden): pods "mypod" is forbidden: User "amet@example.com" cannot delete pods in the namespace "default" И това работи, всички потребители на GitHub в нашата организация могат да виждат ресурси и да влизат в подовете, но нямат права за тяхното изменение.
Източник: habr.com
