Pengantar Otorisasi Kubernetes Konsul Hashicorp


Itu benar, setelah rilis Konsul Hashicorp 1.5.0 pada awal Mei 2019 di Konsul, Anda dapat mengotorisasi aplikasi dan layanan yang berjalan di Kubernet secara asli.


Dalam tutorial ini, kita akan selangkah demi selangkah membuat POC (Proof of concept, PoC - proof of concept) - mendemonstrasikan fitur baru ini. Pengetahuan dasar tentang Kubernetes dan Konsul Hashicorp diharapkan dari Anda. Dan meskipun Anda Anda dapat menggunakan platform cloud apa pun atau lingkungan di tempat, dalam panduan ini kami akan menggunakan Platform Cloud Google.


Ulasan


Jika kita beralih ke dokumentasi Konsul tentang metode otorisasi , kami akan mendapatkan tinjauan singkat tentang tujuan dan kasus penggunaannya, serta beberapa rincian teknis dan gambaran umum umum dari logika. Saya sangat merekomendasikan membacanya setidaknya sekali sebelum melanjutkan, karena saya akan menjelaskan dan mengunyah semuanya sekarang.



Gambar 1: Ikhtisar Metode Resmi Konsul Resmi


Mari kita lihat dokumentasi untuk metode otorisasi Kubernetes tertentu .


Tentu saja, ada informasi yang bermanfaat, tetapi tidak ada panduan tentang bagaimana sebenarnya menggunakan semua ini. Karena itu, seperti orang waras, Anda menjelajahi internet untuk mendapatkan panduan. Dan kemudian ... Dikalahkan. Itu terjadi. Mari kita perbaiki.


Sebelum kita melanjutkan untuk membuat POC kita, mari kita kembali ke gambaran umum metode otorisasi Konsul (Gambar 1) dan memperbaikinya dalam konteks Kubernetes.


Arsitektur


Dalam panduan ini, kami akan membuat server Konsul pada mesin terpisah yang akan berinteraksi dengan kluster Kubernetes dengan klien Konsul diinstal. Kemudian kita akan membuat aplikasi boneka di perapian dan menggunakan metode otorisasi khusus untuk membaca dari gudang Konsul / nilai nilai kami.


Diagram di bawah ini menunjukkan secara rinci arsitektur yang kita buat dalam panduan ini, serta logika metode otorisasi, yang akan dijelaskan nanti.



Gambar 2: Tinjauan umum metode otorisasi di Kubernetes


Catatan singkat: Server konsul tidak perlu tinggal di luar cluster Kubernetes agar bisa berfungsi. Tapi ya, dia bisa melakukan ini dan itu.


Jadi, dengan mengambil diagram ikhtisar Konsul (Skema 1) dan menerapkan Kubernet ke dalamnya, kita mendapatkan diagram di atas (Skema 2), dan di sini logikanya adalah sebagai berikut:


  1. Setiap pod akan memiliki akun layanan terlampir yang berisi token JWT yang dihasilkan dan dikenal oleh Kubernetes. Token ini juga dimasukkan ke dalam sub secara default.
  2. Aplikasi atau layanan kami di dalam perapian memulai perintah untuk memasuki klien Konsul kami. Permintaan untuk masuk juga akan menunjukkan token kami dan nama metode otorisasi yang dibuat khusus (seperti Kubernetes). Langkah No. 2 ini sesuai dengan langkah 1 skema Konsul (Skema 1).
  3. Klien Konsul kami kemudian akan meneruskan permintaan ini ke server Konsul kami.
  4. SIHIR! Di sinilah server Konsul memverifikasi keaslian permintaan, mengumpulkan informasi tentang identitas permintaan dan membandingkannya dengan aturan yang telah ditentukan sebelumnya yang terkait. Di bawah ini adalah diagram lain untuk menggambarkan ini. Langkah ini sesuai dengan langkah 3, 4 dan 5 dari diagram ikhtisar Konsul (Skema 1).
  5. Server Konsul kami menghasilkan token Konsul dengan izin sesuai dengan aturan metode otorisasi yang kami tentukan (yang kami tentukan) mengenai identitas pemohon. Kemudian dia akan mengirim token ini kembali. Ini sesuai dengan langkah 6 skema Konsul (Skema 1).
  6. Klien Konsul kami mengalihkan token ke aplikasi atau layanan yang meminta.

Aplikasi atau layanan kami sekarang dapat menggunakan token Konsul ini untuk berkomunikasi dengan data Konsul kami, sebagaimana ditentukan oleh hak istimewa token.


Keajaiban terungkap!


Bagi Anda yang tidak senang hanya dengan kelinci di topi dan ingin tahu cara kerjanya ... biarkan saya "tunjukkan seberapa dalam lubang kelinci itu ."


Seperti disebutkan sebelumnya, langkah "ajaib" kami (Skema 2: Langkah 4) adalah bahwa server Konsul memverifikasi keaslian permintaan, mengumpulkan informasi tentang permintaan tersebut dan membandingkannya dengan aturan yang telah ditentukan sebelumnya yang terkait. Langkah ini sesuai dengan langkah 3, 4 dan 5 dari diagram ikhtisar Konsul (Skema 1). Di bawah ini adalah diagram (Skema 3), yang tujuannya adalah untuk dengan jelas menunjukkan apa yang sebenarnya terjadi di bawah tenda metode otorisasi Kubernetes tertentu.



Skema 3: Keajaiban terungkap!


  1. Sebagai titik awal, klien Konsul kami mengalihkan permintaan login ke server Konsul kami dengan token akun Kubernetes dan nama spesifik dari instance metode otorisasi yang dibuat sebelumnya. Langkah ini sesuai dengan langkah 3 dalam penjelasan sirkuit sebelumnya.
  2. Sekarang server Konsul (atau pemimpin) perlu memverifikasi keaslian token yang diterima. Oleh karena itu, ia akan berkonsultasi dengan kluster Kubernetes (melalui klien Konsul) dan, dengan izin yang sesuai, kami akan mencari tahu apakah token itu asli dan kepada siapa pemiliknya.
  3. Kemudian permintaan yang diverifikasi kembali ke pemimpin Konsul, dan server Konsul mencari contoh metode otorisasi dengan nama yang ditentukan dari permintaan login (dan ketik Kubernetes).
  4. Pemimpin konsul menentukan contoh spesifik dari metode otorisasi (jika ditemukan) dan membaca sekumpulan aturan yang mengikat yang dilampirkan padanya. Dia kemudian membaca aturan-aturan ini dan membandingkannya dengan atribut identitas yang diverifikasi.
  5. Tada! Lanjutkan ke langkah 5 dalam penjelasan sirkuit sebelumnya.

Jalankan Consul-server pada mesin virtual biasa


Mulai sekarang, saya terutama akan memberikan instruksi untuk membuat POC ini, seringkali dalam poin, tanpa seluruh kalimat yang jelas. Juga, seperti disebutkan sebelumnya, saya akan menggunakan GCP untuk membuat seluruh infrastruktur, tetapi Anda dapat membuat infrastruktur yang sama di tempat lain.


  • Mulai mesin virtual (instance / server).


  • Buat aturan untuk firewall (grup keamanan di AWS):
  • Saya suka menetapkan nama mesin yang sama untuk aturan dan tag jaringan, dalam hal ini adalah "skywiz-consul-server-poc".
  • Temukan alamat IP komputer lokal Anda dan tambahkan ke daftar alamat IP sumber sehingga kami dapat mengakses antarmuka pengguna (UI).
  • Buka port 8500 untuk UI. Klik Buat. Kami akan segera mengubah firewall ini.
  • Tambahkan aturan untuk firewall ke instance. Kembali ke dasbor VM di server Konsul dan tambahkan "skywiz-consul-server-poc" ke bidang tag jaringan. Klik Simpan.


  • Instal Konsul di mesin virtual, periksa di sini. Ingat bahwa Anda memerlukan versi Konsul ≥ 1,5 [tautan]
  • Buat Konsul simpul tunggal - konfigurasinya adalah sebagai berikut.

groupadd --system consul useradd -s /sbin/nologin --system -g consul consul mkdir -p /var/lib/consul chown -R consul:consul /var/lib/consul chmod -R 775 /var/lib/consul mkdir /etc/consul.d chown -R consul:consul /etc/consul.d 

  • Untuk panduan lebih rinci tentang cara menginstal Konsul dan mengatur sekelompok 3 simpul, lihat di sini .
  • Buat file /etc/consul.d/agent.json sebagai berikut [ tautan ]:

 ### /etc/consul.d/agent.json { "acl" : { "enabled": true, "default_policy": "deny", "enable_token_persistence": true } } 

  • Luncurkan server Konsul kami:

 consul agent \ -server \ -ui \ -client 0.0.0.0 \ -data-dir=/var/lib/consul \ -bootstrap-expect=1 \ -config-dir=/etc/consul.d 

  • Anda akan melihat banyak output dan berakhir dengan "... pembaruan diblokir oleh ACL".
  • Temukan alamat IP eksternal dari server Konsul dan buka browser dengan alamat IP ini pada port 8500. Pastikan UI terbuka.
  • Coba tambahkan pasangan kunci / nilai. Pasti ada kesalahan. Ini karena kami memuat server Konsul menggunakan ACL dan menolak semua aturan.
  • Kembali ke shell Anda di server Konsul dan mulai proses di latar belakang atau dengan beberapa cara lain agar bisa berfungsi, dan masukkan yang berikut ini:

 consul acl bootstrap 

  • Temukan nilai "SecretID" dan kembali ke UI. Pada tab ACL, masukkan pengidentifikasi rahasia token yang baru saja Anda salin. Salin SecretID di tempat lain, kita akan membutuhkannya nanti.
  • Sekarang tambahkan pasangan kunci / nilai. Untuk POC ini, tambahkan berikut ini: kunci: "custom-ns / test_key", nilai: "Saya di folder custom-ns!"

Luncurkan Kubernetes Cluster untuk aplikasi kami dengan Klien Konsul sebagai Daemonset


  • Buat cluster K8s (Kubernetes). Kami akan membuatnya di zona yang sama dengan server untuk akses yang lebih cepat, dan karenanya kami dapat menggunakan subnet yang sama untuk koneksi yang mudah dengan alamat IP internal. Kami akan menyebutnya skywiz-app-with-consul-client-poc.


  • Sebagai catatan, berikut ini adalah panduan bagus yang saya temui ketika mengatur cluster Konsul POC dengan Consul Connect.
  • Kami juga akan menggunakan grafik helm Hashicorp dengan file nilai yang diperluas.
  • Instal dan konfigurasikan Helm. Langkah-langkah konfigurasi:

 kubectl create serviceaccount tiller --namespace kube-system kubectl create clusterrolebinding tiller-admin-binding \ --clusterrole=cluster-admin --serviceaccount=kube-system:tiller ./helm init --service-account=tiller ./helm update 


 ### poc-helm-consul-values.yaml global: enabled: false image: "consul:latest" # Expose the Consul UI through this LoadBalancer ui: enabled: false # Allow Consul to inject the Connect proxy into Kubernetes containers connectInject: enabled: false # Configure a Consul client on Kubernetes nodes. GRPC listener is required for Connect. client: enabled: true join: ["<PRIVATE_IP_CONSUL_SERVER>"] extraConfig: | { "acl" : { "enabled": true, "default_policy": "deny", "enable_token_persistence": true } } # Minimal Consul configuration. Not suitable for production. server: enabled: false # Sync Kubernetes and Consul services syncCatalog: enabled: false 

  • Terapkan grafik helm:

 ./helm install -f poc-helm-consul-values.yaml ./consul-helm - name skywiz-app-with-consul-client-poc 

  • Ketika mencoba memulai, itu akan memerlukan izin untuk server Konsul, jadi mari kita tambahkan mereka.
  • Perhatikan "Rentang alamat Pod" yang terletak di dasbor kluster dan kembali ke aturan kami untuk firewall skywiz-consul-server-poc.
  • Tambahkan rentang alamat untuk IPA ke daftar alamat IP dan buka port 8301 dan 8300.


  • Pergi ke UI Konsul, dan dalam beberapa menit Anda akan melihat bahwa cluster kami akan muncul pada tab node.


Konfigurasikan metode otorisasi dengan mengintegrasikan Konsul dengan Kubernetes


  • Kembali ke shell server Konsul dan ekspor token yang Anda simpan sebelumnya:

 export CONSUL_HTTP_TOKEN=<SecretID> 

  • Kami membutuhkan informasi dari cluster Kubernetes kami untuk membuat contoh metode auth:
  • kubernet-host

 kubectl get endpoints | grep kubernetes 

  • kubernetes-service-account-jwt

 kubectl get sa <helm_deployment_name>-consul-client -o yaml | grep "\- name:" kubectl get secret <secret_name_from_prev_command> -o yaml | grep token: 

  • Token dikodekan dalam base64, jadi dekripsi menggunakan alat favorit Anda [ tautan ]
  • kubernetes-ca-cert

 kubectl get secret <secret_name_from_prev_command> -o yaml | grep ca.crt: 

  • Ambil sertifikat "ca.crt" (setelah decoding dengan base64) dan tuliskan ke file "ca.crt".
  • Sekarang buat instance metode auth, mengganti placeholder dengan nilai yang baru saja Anda terima.

 consul acl auth-method create \ -type "kubernetes" \ -name "auth-method-skywiz-consul-poc" \ -description "This is an auth method using kubernetes for the cluster skywiz-app-with-consul-client-poc" \ -kubernetes-host "<k8s_endpoint_retrieved earlier>" \ -kubernetes-ca-cert=@ca.crt \ -kubernetes-service-account- jwt="<decoded_token_retrieved_earlier>" 

  • Selanjutnya, kita perlu membuat aturan dan melampirkannya ke peran baru. Anda dapat menggunakan UI Konsul untuk bagian ini, tetapi kami akan menggunakan baris perintah.
  • Tulis aturan

 ### kv-custom-ns-policy.hcl key_prefix "custom-ns/" { policy = "write" } 

  • Terapkan aturannya

 consul acl policy create \ -name kv-custom-ns-policy \ -description "This is an example policy for kv at custom-ns/" \ -rules @kv-custom-ns-policy.hcl 

  • Temukan pengidentifikasi aturan yang baru Anda buat dari output.
  • Buat peran dengan aturan baru.

 consul acl role create \ -name "custom-ns-role" \ -description "This is an example role for custom-ns namespace" \ -policy-id <policy_id> 


 consul acl binding-rule create \ -method=auth-method-skywiz-consul-poc \ -bind-type=role \ -bind-name='custom-ns-role' \ -selector='serviceaccount.namespace=="custom-ns"' 

Konfigurasi terakhir


Hak akses


  • Buat izin. Kami perlu memberikan izin kepada Konsul untuk memverifikasi dan mengidentifikasi identitas token akun layanan K8.
  • Tulis [tautan] berikut ke file:

 ###skywiz-poc-consul-server_rbac.yaml --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: review-tokens namespace: default subjects: - kind: ServiceAccount name: skywiz-app-with-consul-client-poc-consul-client namespace: default roleRef: kind: ClusterRole name: system:auth-delegator apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: service-account-getter namespace: default rules: - apiGroups: [""] resources: ["serviceaccounts"] verbs: ["get"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: get-service-accounts namespace: default subjects: - kind: ServiceAccount name: skywiz-app-with-consul-client-poc-consul-client namespace: default roleRef: kind: ClusterRole name: service-account-getter apiGroup: rbac.authorization.k8s.io 

  • Buat hak akses

 kubectl create -f skywiz-poc-consul-server_rbac.yaml 

Terhubung ke Klien Konsul


  • Seperti disebutkan di sini , ada beberapa opsi untuk menghubungkan ke daemonset, tetapi kita akan beralih ke solusi sederhana berikut:
  • Terapkan file berikut [ tautan ].

 ### poc-consul-client-ds-svc.yaml apiVersion: v1 kind: Service metadata: name: consul-ds-client spec: selector: app: consul chart: consul-helm component: client hasDNS: "true" release: skywiz-app-with-consul-client-poc ports: - protocol: TCP port: 80 targetPort: 8500 

  • Kemudian gunakan perintah bawaan berikut untuk membuat configmap [ tautan ]. Harap perhatikan bahwa kami merujuk pada nama layanan kami, ganti jika perlu.

 cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: labels: addonmanager.kubernetes.io/mode: EnsureExists name: kube-dns namespace: kube-system data: stubDomains: | {"consul": ["$(kubectl get svc consul-ds-client -o jsonpath='{.spec.clusterIP}')"]} EOF 

Menguji metode auth


Sekarang mari kita lihat keajaiban dalam aksi!


  • Buat beberapa folder kunci lagi dengan kunci tingkat atas yang sama (mis. <new_folder> / sample_key) dan nilai pilihan Anda. Buat kebijakan dan peran yang sesuai untuk jalur utama baru. Kami akan melakukan binding nanti.


Tes namespace khusus:


  • Buat namespace kami sendiri:

 kubectl create namespace custom-ns 

  • Buat di bawah di namespace baru kami. Tulis konfigurasi untuk perapian.

 ###poc-ubuntu-custom-ns.yaml apiVersion: v1 kind: Pod metadata: name: poc-ubuntu-custom-ns namespace: custom-ns spec: containers: - name: poc-ubuntu-custom-ns image: ubuntu command: ["/bin/bash", "-ec", "sleep infinity"] restartPolicy: Never 

  • Buat di bawah:

 kubectl create -f poc-ubuntu-custom-ns.yaml 

  • Setelah wadah dimulai, pergi ke sana dan instal keriting.

 kubectl exec poc-ubuntu-custom-ns -n custom-ns -it /bin/bash apt-get update && apt-get install curl -y 

  • Sekarang kami akan mengirim permintaan untuk masuk ke Konsul menggunakan metode otorisasi yang kami buat sebelumnya [ tautan ].
  • Untuk melihat token yang dimasukkan dari akun layanan Anda:

 cat /run/secrets/kubernetes.io/serviceaccount/token 

  • Tuliskan yang berikut ke file di dalam wadah:

 ### payload.json { "AuthMethod": "auth-method-test", "BearerToken": "<jwt_token>" } 

  • Login!

 curl \ --request POST \ --data @payload.json \ consul-ds-client.default.svc.cluster.local/v1/acl/login 

  • Untuk menyelesaikan langkah-langkah di atas pada satu baris (karena kami akan menjalankan beberapa tes), Anda dapat melakukan hal berikut:

 echo "{ \ \"AuthMethod\": \"auth-method-skywiz-consul-poc\", \ \"BearerToken\": \"$(cat /run/secrets/kubernetes.io/serviceaccount/token)\" \ }" \ | curl \ --request POST \ --data @- \ consul-ds-client.default.svc.cluster.local/v1/acl/login 

  • Itu berhasil! Setidaknya harus. Sekarang ambil SecretID dan coba akses kunci / nilai yang harus kita akses.

 curl \ consul-ds-client.default.svc.cluster.local/v1/kv/custom-ns/test_key --header “X-Consul-Token: <SecretID_from_prev_response>” 

  • Anda dapat mendekodekan "Nilai" base64 dan melihat bahwa itu cocok dengan nilai di custom-ns / test_key di UI. Jika Anda menggunakan nilai yang sama di atas dalam manual ini, nilai Anda yang dikodekan adalah IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.

Tes Akun Layanan Pengguna:


  • Buat ServiceAccount kustom dengan perintah [ tautan ] berikut.

 kubectl apply -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: custom-sa EOF 

  • Buat file konfigurasi baru untuk perapian. Harap dicatat bahwa saya menyalakan instalasi keriting untuk menghemat tenaga kerja :)

 ###poc-ubuntu-custom-sa.yaml apiVersion: v1 kind: Pod metadata: name: poc-ubuntu-custom-sa namespace: default spec: serviceAccountName: custom-sa containers: - name: poc-ubuntu-custom-sa image: ubuntu command: ["/bin/bash","-ec"] args: ["apt-get update && apt-get install curl -y; sleep infinity"] restartPolicy: Never 

  • Setelah itu, jalankan shell di dalam wadah.

 kubectl exec -it poc-ubuntu-custom-sa /bin/bash 

  • Login!

 echo "{ \ \"AuthMethod\": \"auth-method-skywiz-consul-poc\", \ \"BearerToken\": \"$(cat /run/secrets/kubernetes.io/serviceaccount/token)\" \ }" \ | curl \ --request POST \ --data @- \ consul-ds-client.default.svc.cluster.local/v1/acl/login 

  • Izin ditolak. Oh, kami lupa menambahkan aturan baru yang mengikat dengan izin yang sesuai, mari kita lakukan sekarang.

Ulangi langkah sebelumnya di atas:
a) Buat Kebijakan identik untuk awalan "custom-sa /".
b) Buat Peran, beri nama "custom-sa-role"
c) Lampirkan Kebijakan untuk Berperan.


  • Buat Aturan-Mengikat (hanya mungkin dari cli / api). Perhatikan nilai yang berbeda dari bendera pemilih.

 consul acl binding-rule create \ -method=auth-method-skywiz-consul-poc \ -bind-type=role \ -bind-name='custom-sa-role' \ -selector='serviceaccount.name=="custom-sa"' 

  • Masuk lagi dari wadah poc-ubuntu-custom-sa. Sukses!
  • Periksa akses kami ke jalur kustom-sa / kunci.

 curl \ consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header “X-Consul-Token: <SecretID>” 

  • Anda juga dapat memastikan bahwa token ini tidak menyediakan akses ke kv di "custom-ns /". Cukup ulangi perintah di atas setelah mengganti "custom-sa" dengan awalan "custom-ns".
    Izin ditolak.

Contoh hamparan:


  • Perlu dicatat bahwa semua pemetaan yang mengikat aturan akan ditambahkan ke token dengan hak-hak ini.
  • Wadah poc-ubuntu-custom-sa kami ada di namespace default - jadi mari kita gunakan untuk mengikat aturan lain.
  • Ulangi langkah sebelumnya:
    a) Buat Kebijakan identik untuk awalan kunci "default /".
    b) Buat Peran, beri nama "peran default-ns"
    c) Lampirkan Kebijakan untuk Berperan.
  • Buat Aturan-Mengikat (hanya mungkin dari cli / api)

 consul acl binding-rule create \ -method=auth-method-skywiz-consul-poc \ -bind-type=role \ -bind-name='default-ns-role' \ -selector='serviceaccount.namespace=="default"' 

  • Kembali ke wadah poc-ubuntu-custom-sa kami dan coba akses jalur default / kv.
  • Izin ditolak.
    Anda dapat melihat kredensial yang ditentukan untuk setiap token di UI di bawah ACL> Token. Seperti yang Anda lihat, hanya satu "custom-sa-role" yang dilampirkan ke token kami saat ini. Token yang kami gunakan saat ini dihasilkan saat kami masuk, dan kemudian hanya ada satu aturan yang mengikat, yang kemudian berhubungan. Kita perlu masuk lagi dan menggunakan token baru.
  • Pastikan Anda dapat membaca dari kedua jalur "custom-sa /" dan "default /" kv.
    Sukses!
    Ini karena poc-ubuntu-custom-sa kami cocok dengan binding dari aturan custom-sa dan default-ns.

Kesimpulan


Token mgmt TTL?


Pada saat penulisan ini, tidak ada cara terintegrasi untuk menentukan TTL untuk token yang dihasilkan oleh metode otorisasi ini. Ini akan menjadi kesempatan luar biasa untuk memberikan otomatisasi otorisasi Konsul yang aman.


Dimungkinkan untuk secara manual membuat token dengan TTL:



Saya berharap bahwa dalam waktu dekat kita akan dapat mengontrol bagaimana token dihasilkan (untuk setiap aturan atau metode otorisasi) dan menambahkan TTL.


Sampai saat itu, diusulkan untuk menggunakan dalam logika Anda titik akhir keluar dari sistem.



Baca juga artikel lain di blog kami:


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


All Articles