บทความนี้ได้เขียนขึ้นเพื่อขยายความแล้ว
ในบทความนี้ ฉันจะบอกวิธีติดตั้งและกำหนดค่า:
- พวงกุญแจ เป็นโครงการโอเพ่นซอร์ส ซึ่งมีทางเข้าจุดเดียวสำหรับแอปพลิเคชัน ทำงานร่วมกับโปรโตคอลมากมาย รวมถึง LDAP และ OpenID ที่เราสนใจ
- ยามเฝ้าประตู - แอปพลิเคชันพร็อกซีย้อนกลับที่ให้คุณรวมการอนุญาตผ่าน Keycloak
- ทางเดิน - แอปพลิเคชันที่สร้างการกำหนดค่าสำหรับ kubectl ซึ่งคุณสามารถเข้าสู่ระบบและเชื่อมต่อกับ Kubernetes API ผ่าน OpenID
วิธีการทำงานของสิทธิ์ใน Kubernetes
เราสามารถจัดการสิทธิ์ของผู้ใช้ / กลุ่มโดยใช้ RBAC มีการสร้างบทความมากมายเกี่ยวกับเรื่องนี้แล้ว ฉันจะไม่พูดถึงรายละเอียดนี้ ปัญหาคือคุณสามารถใช้ RBAC เพื่อจำกัดสิทธิ์ของผู้ใช้ได้ แต่ Kubernetes ไม่รู้อะไรเกี่ยวกับผู้ใช้เลย ปรากฎว่าเราต้องการกลไกการส่งผู้ใช้ใน Kubernetes ในการทำเช่นนี้เราจะเพิ่มผู้ให้บริการใน Kuberntes OpenID ซึ่งจะบอกว่าผู้ใช้ดังกล่าวมีอยู่จริงและ Kubernetes จะให้สิทธิ์แก่เขา
การอบรม
- คุณต้องใช้คลัสเตอร์ Kubernetes หรือ minikube
- Active Directory
- โดเมน:
keycloak.example.org
kubernetes-dashboard.example.org
gangway.example.org - ใบรับรองสำหรับโดเมนหรือใบรับรองที่ลงนามเอง
ฉันจะไม่พูดถึงวิธีการสร้างใบรับรองที่ลงนามเอง คุณต้องสร้างใบรับรอง 2 ใบ นี่คือไคลเอ็นต์ root (Certificate Authority) และ wildcard สำหรับโดเมน *.example.org
หลังจากที่คุณได้รับ / ออกใบรับรอง จะต้องเพิ่มไคลเอนต์ใน Kubernetes เราจึงสร้างความลับสำหรับสิ่งนี้:
kubectl create secret tls tls-keycloak --cert=example.org.crt --key=example.org.pem
ต่อไปเราจะใช้สำหรับตัวควบคุม Ingress ของเรา
การติดตั้ง Keycloak
ฉันตัดสินใจว่าวิธีที่ง่ายที่สุดคือใช้โซลูชันสำเร็จรูปสำหรับสิ่งนี้ ซึ่งก็คือแผนที่หางเสือ
ติดตั้งที่เก็บและอัปเดต:
helm repo add codecentric https://codecentric.github.io/helm-charts
helm repo update
สร้างไฟล์ keycloak.yml โดยมีเนื้อหาดังต่อไปนี้:
keycloak.yml
keycloak:
# Имя администратора
username: "test_admin"
# Пароль администратор
password: "admin"
# Эти флаги нужны что бы позволить загружать в Keycloak скрипты прямо через web морду. Это нам
понадобиться что бы починить один баг, о котором ниже.
extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled"
# Включаем ingress, указываем имя хоста и сертификат который мы предварительно сохранили в secrets
ingress:
enabled: true
path: /
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/affinity: cookie
hosts:
- keycloak.example.org
tls:
- hosts:
- keycloak.example.org
secretName: tls-keycloak
# Keycloak для своей работы требует базу данных, в тестовых целях я разворачиваю Postgresql прямо в Kuberntes, в продакшене так лучше не делать!
persistence:
deployPostgres: true
dbVendor: postgres
postgresql:
postgresUser: keycloak
postgresPassword: ""
postgresDatabase: keycloak
persistence:
enabled: true
การตั้งค่าสหพันธ์
จากนั้นไปที่เว็บอินเตอร์เฟส
คลิกที่มุมซ้าย เพิ่มอาณาจักร
คีย์
ความคุ้มค่า
Name
Kubernetes
ชื่อที่แสดง
Kubernetes
ปิดใช้งานการยืนยันอีเมลของผู้ใช้:
ขอบเขตไคลเอ็นต์ —> อีเมล —> ผู้ทำแผนที่ —> ยืนยันอีเมลแล้ว (ลบ)
เราตั้งค่าสหพันธรัฐเพื่อนำเข้าผู้ใช้จาก ActiveDirectory ฉันจะทิ้งภาพหน้าจอไว้ด้านล่าง ฉันคิดว่ามันจะชัดเจนขึ้น
สหพันธ์ผู้ใช้ —> เพิ่มผู้ให้บริการ… —> ldap
การตั้งค่าสหพันธ์
หากทุกอย่างเรียบร้อยแล้วหลังจากกดปุ่ม ซิงโครไนซ์ผู้ใช้ทั้งหมด คุณจะเห็นข้อความเกี่ยวกับการนำเข้าผู้ใช้ที่สำเร็จ
ต่อไปเราต้องแมปกลุ่มของเรา
สหพันธ์ผู้ใช้ --> ldap_localhost --> Mappers --> Create
การสร้างตัวทำแผนที่
การตั้งค่าไคลเอนต์
จำเป็นต้องสร้างไคลเอนต์ ในแง่ของ Keycloak นี่คือแอปพลิเคชันที่จะได้รับอนุญาตจากเขา ฉันจะเน้นจุดสำคัญในภาพหน้าจอเป็นสีแดง
ลูกค้า —> สร้าง
การตั้งค่าไคลเอนต์
มาสร้างขอบเขตสำหรับกลุ่ม:
ขอบเขตลูกค้า —> สร้าง
สร้างขอบเขต
และตั้งค่าผู้ทำแผนที่สำหรับพวกเขา:
ขอบเขตลูกค้า —> กลุ่ม —> ผู้ทำแผนที่ —> สร้าง
นักทำแผนที่
เพิ่มการแมปของกลุ่มของเราในขอบเขตไคลเอนต์เริ่มต้น:
ลูกค้า —> kubernetes —> ขอบเขตลูกค้า —> ขอบเขตลูกค้าเริ่มต้น
เลือก กลุ่ม в ขอบเขตไคลเอนต์ที่มีอยู่กด เพิ่มรายการที่เลือก
เราได้รับความลับ (และเขียนลงในเธรด) ซึ่งเราจะใช้สำหรับการอนุญาตใน Keycloak:
ลูกค้า —> kubernetes —> ข้อมูลประจำตัว —> ความลับ
การตั้งค่าเสร็จสมบูรณ์ แต่ฉันมีข้อผิดพลาดเมื่อฉันได้รับข้อผิดพลาด 403 หลังจากให้สิทธิ์สำเร็จแล้ว
แก้ไข:
ขอบเขตไคลเอนต์ —> บทบาท —> ผู้ทำแผนที่ —> สร้าง
ผู้ทำแผนที่
รหัสสคริปต์
// add current client-id to token audience
token.addAudience(token.getIssuedFor());
// return token issuer as dummy result assigned to iss again
token.getIssuer();
การกำหนดค่า Kubernetes
เราจำเป็นต้องระบุว่าใบรับรองรูทของเราจากเว็บไซต์อยู่ที่ใด และผู้ให้บริการ OIDC อยู่ที่ใด
ในการดำเนินการนี้ ให้แก้ไขไฟล์ /etc/kubernetes/manifests/kube-apiserver.yaml
kube-apiserver.yaml
...
spec:
containers:
- command:
- kube-apiserver
...
- --oidc-ca-file=/var/lib/minikube/certs/My_Root.crt
- --oidc-client-id=kubernetes
- --oidc-groups-claim=groups
- --oidc-issuer-url=https://keycloak.example.org/auth/realms/kubernetes
- --oidc-username-claim=email
...
อัปเดตการกำหนดค่า kubeadm ในคลัสเตอร์:
kubeadmconfig
kubectl edit -n kube-system configmaps kubeadm-config
...
data:
ClusterConfiguration: |
apiServer:
extraArgs:
oidc-ca-file: /var/lib/minikube/certs/My_Root.crt
oidc-client-id: kubernetes
oidc-groups-claim: groups
oidc-issuer-url: https://keycloak.example.org/auth/realms/kubernetes
oidc-username-claim: email
...
การตั้งค่า auth-proxy
คุณสามารถใช้ keycloak gatekeeper เพื่อป้องกันเว็บแอปพลิเคชันของคุณ นอกจากข้อเท็จจริงที่ว่า reverse proxy นี้จะให้สิทธิ์แก่ผู้ใช้ก่อนที่จะแสดงเพจ มันยังจะส่งข้อมูลเกี่ยวกับคุณไปยังแอปพลิเคชันปลายทางในส่วนหัวอีกด้วย ดังนั้น หากแอปพลิเคชันของคุณรองรับ OpenID ผู้ใช้จะได้รับอนุญาตทันที พิจารณาตัวอย่าง Kubernetes Dashboard
การติดตั้งแดชบอร์ด Kubernetes
helm install stable/kubernetes-dashboard --name dashboard -f values_dashboard.yaml
value_dashboard.yaml
enableInsecureLogin: true
service:
externalPort: 80
rbac:
clusterAdminRole: true
create: true
serviceAccount:
create: true
name: 'dashboard-test'
การตั้งค่าสิทธิ์การเข้าถึง:
มาสร้าง ClusterRoleBinding ที่จะให้สิทธิ์ผู้ดูแลระบบคลัสเตอร์ (ผู้ดูแลระบบคลัสเตอร์ ClusterRole มาตรฐาน) สำหรับผู้ใช้ในกลุ่ม DataOPS
kubectl apply -f rbac.yaml
rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dataops_group
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: DataOPS
ติดตั้งผู้รักษาประตูคีย์เสื้อคลุม:
helm repo add gabibbo97 https://gabibbo97.github.io/charts/
helm repo update
helm install gabibbo97/keycloak-gatekeeper --version 2.1.0 --name keycloak-gatekeeper -f values_proxy.yaml
ค่า_proxy.yaml
# Включаем ingress
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
path: /
hosts:
- kubernetes-dashboard.example.org
tls:
- secretName: tls-keycloak
hosts:
- kubernetes-dashboard.example.org
# Говорим где мы будем авторизовываться у OIDC провайдера
discoveryURL: "https://keycloak.example.org/auth/realms/kubernetes"
# Имя клиента которого мы создали в Keycloak
ClientID: "kubernetes"
# Secret который я просил записать
ClientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
# Куда перенаправить в случае успешной авторизации. Формат <SCHEMA>://<SERVICE_NAME>.><NAMESAPCE>.<CLUSTER_NAME>
upstreamURL: "http://dashboard-kubernetes-dashboard.default.svc.cluster.local"
# Пропускаем проверку сертификата, если у нас самоподписанный
skipOpenidProviderTlsVerify: true
# Настройка прав доступа, пускаем на все path если мы в группе DataOPS
rules:
- "uri=/*|groups=DataOPS"
หลังจากนั้นเมื่อคุณพยายามที่จะไปที่
การติดตั้งทางเดิน
เพื่อความสะดวก คุณสามารถเพิ่มทางเดินที่จะสร้างไฟล์ปรับแต่งสำหรับ kubectl ซึ่งเราจะเข้าสู่ Kubernetes ภายใต้ผู้ใช้ของเรา
helm install --name gangway stable/gangway -f values_gangway.yaml
value_gangway.yaml
gangway:
# Произвольное имя кластера
clusterName: "my-k8s"
# Где у нас OIDC провайдер
authorizeURL: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/auth"
tokenURL: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/token"
audience: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/userinfo"
# Теоритически сюда можно добавить groups которые мы замапили
scopes: ["openid", "profile", "email", "offline_access"]
redirectURL: "https://gangway.example.org/callback"
# Имя клиента
clientID: "kubernetes"
# Секрет
clientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
# Если оставить дефолтное значние, то за имя пользователя будет братья <b>Frist name</b> <b>Second name</b>, а при "sub" его логин
usernameClaim: "sub"
# Доменное имя или IP адресс API сервера
apiServerURL: "https://192.168.99.111:8443"
# Включаем Ingress
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-buffer-size: "64k"
path: /
hosts:
- gangway.example.org
tls:
- secretName: tls-keycloak
hosts:
- gangway.example.org
# Если используем самоподписанный сертификат, то его(открытый корневой сертификат) надо указать.
trustedCACert: |-
-----BEGIN CERTIFICATE-----
MIIDVzCCAj+gAwIBAgIBATANBgkqhkiG9w0BAQsFADA1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRGF0YU9QUzEUMBIGA1UEAxMLbXkgcm9vdCBrZXkwHhcNMjAwMjE0MDkxODAwWhcNMzAwMjE0MDkxODAwWjA1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRGF0YU9QUzEUMBIGA1UEAxMLbXkgcm9vdCBrZXkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDyP749PqqIRwNSqaK6qr0Zsi03G4PTCUlgaYTPZuMrwUVPK8xX2dWWs9MPRMOdXpgr8aSTZnVfmelIlVz4D7o2vK5rfmAe9GPcK0WbwKwXyhFU0flS9sU/g46ogHFrk03SZxQAeJhMLfEmAJm8LF5HghtGDs3t4uwGsB95o+lqPLiBvxRB8ZS3jSpYpvPgXAuZWKdZUQ3UUZf0X3hGLp7uIcIwJ7i4MduOGaQEO4cePeEJy9aDAO6qV78YmHbyh9kaW+1DL/Sgq8NmTgHGV6UOnAPKHTnMKXl6KkyUz8uLBGIdVhPxrlzG1EzXresJbJenSZ+FZqm3oLqZbw54Yp5hAgMBAAGjcjBwMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHISTOU/6BQqqnOZj+1xJfxpjiG0MAsGA1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAAcwHgYJYIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAQEAj7HC8ObibwOLT4ZYmISJZwub9lcE0AZ5cWkPW39j/syhdbbqjK/6jy2D3WUEbR+s1Vson5Ov7JhN5In2yfZ/ByDvBnoj7CP8Q/ZMjTJgwN7j0rgmEb3CTZvnDPAz8Ijw3FP0cjxfoZ1Z0V2F44Ry7gtLJWr06+MztXVyto3aIz1/XbMQnXYlzc3c3B5yUQIy44Ce5aLRVsAjmXNqVRmDJ2QPNLicvrhnUJsO0zFWI+zZ2hc4Ge1RotCrjfOc9hQY63jZJ17myCZ6QCD7yzMzAob4vrgmkD4q7tpGrhPY/gDcE+lUNhC7DO3l0oPy2wsnT2TEn87eyWmDiTFG9zWDew==
-----END CERTIFICATE-----
ดูเหมือนว่านี้ ให้คุณดาวน์โหลดไฟล์ config ได้ทันทีและสร้างโดยใช้ชุดคำสั่ง:
ที่มา: will.com