Tutorial ini menjelaskan cara menggunakan gateway keluar dan masuk Anthos Service Mesh untuk membantu mengamankan lalu lintas antar cluster dengan menggunakan mutual Keamanan Lapisan Transportasi (mTLS). Tutorial ini ditujukan untuk administrator cluster Kubernetes yang bertanggung jawab atas aspek jaringan, keamanan, dan platform. Kontrol yang dijelaskan di sini mungkin berguna khususnya bagi organisasi yang memiliki persyaratan keamanan yang tinggi atau untuk memenuhi prasyarat peraturan. Tutorial ini dilengkapi dengan panduan konsep pelengkap.
Tutorial ini berarti bahwa Anda sudah memahami Kubernetes dan Anthos Service Mesh.
Tujuan
- Menerapkan Terraform untuk memasang infrastruktur:
- Membuat jaringan VPC kustom dengan dua subnet pribadi.
- Membuat dua cluster Kubernetes dengan Anthos Service Mesh yang telah diaktifkan:
- Satu cluster GKE
- Satu cluster Operasi Kubernetes (kOps) yang berjalan di jaringan VPC khusus
- Mendaftarkan cluster pada GKE Hub.
- Menerapkan klien MySQL di cluster GKE.
- Menerpkan server MySQL di cluster kOps.
- Konfigurasikan gateway keluar dan masuk untuk mengekspos server dengan menggunakan mTLS.
- Uji akses ke server MySQL menggunakan klien MySQL yang berjalan di berbagai cluster atau VPC.
Biaya
Dalam dokumen ini, Anda menggunakan komponen Google Cloud yang dapat ditagih berikut:
- Google Kubernetes Engine(GKE)
- Compute Engine
- Container Registry
- Anthos Service Mesh
- Jaringan cloud dan penyeimbangan beban
Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda,
gunakan kalkulator harga.
Setelah menyelesaikan tugas yang dijelaskan dalam dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, lihat Pembersihan.
Sebelum memulai
Untuk tutorial ini, Anda memerlukan proyek Google Cloud. Anda dapat membuat yang baru, atau memilih proyek yang sudah Anda buat
-
Di konsol Google Cloud, buka halaman Pemilih project.
-
Pilih atau buat project Google Cloud.
-
Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.
Di konsol Google Cloud, buka Cloud Shell.
Di bagian bawah Google Cloud Console, sesi Cloud Shell akan terbuka dan menampilkan perintah command line. Cloud Shell adalah lingkungan shell dengan Google Cloud CLI yang sudah terinstal, termasuk Google Cloud CLI Perlu waktu beberapa detik untuk sesi dimulai.
- Di Cloud Shell, pastikan mengerjakan project yang Anda buat atau pilih:
export PROJECT_ID=PROJECT_ID gcloud config set project ${PROJECT_ID}
Ganti
PROJECT_ID
dengan project ID Anda. - Buat variabel lingkungan untuk alamat email yang Anda gunakan untuk Google Cloud:
export GOOGLE_CLOUD_EMAIL_ADDRESS=GOOGLE_CLOUD_EMAIL_ADDRESS
Ganti
GOOGLE_CLOUD_EMAIL_ADDRESS
dengan alamat email yang Anda gunakan pada Google Cloud. - Tetapkan wilayah dan zona untuk sumber daya komputasi Anda:
export REGION=us-central1 export ZONE=us-central1-b gcloud config set compute/region ${REGION} gcloud config set compute/zone ${ZONE}
Tutorial ini menggunakan
us-central1
untuk region danus-central1-b
untuk zona. Anda dapat men-deploy ke region pilihan Anda. - Tetapkan peran Identity and Access Management (IAM) yang diperlukan. Jika Anda adalah Pemilik Project, Anda memiliki semua izin yang diperlukan untuk menyelesaikan pemasangan. Jika tidak, mintalah administrator Anda untuk memberikan Peran Identity and Access Management (IAM) dengan menjalankan perintah berikut di Cloud Shell:
ROLES=( 'roles/container.admin' \ 'roles/gkehub.admin' \ 'roles/iam.serviceAccountAdmin' \ 'roles/iam.serviceAccountKeyAdmin' \ 'roles/resourcemanager.projectIamAdmin' \ 'roles/compute.securityAdmin' \ 'roles/compute.instanceAdmin' \ 'roles/storage.admin' \ 'roles/serviceusage.serviceUsageAdmin' ) for role in "${ROLES[@]}" do gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member "user:${GOOGLE_CLOUD_EMAIL_ADDRESS}" \ --role="$role" done
- Aktifkan API yang diperlukan untuk tutorial:
gcloud services enable \ anthos.googleapis.com \ anthosgke.googleapis.com \ anthosaudit.googleapis.com \ compute.googleapis.com \ container.googleapis.com \ cloudresourcemanager.googleapis.com \ serviceusage.googleapis.com \ stackdriver.googleapis.com \ monitoring.googleapis.com \ logging.googleapis.com \ cloudtrace.googleapis.com \ meshca.googleapis.com \ meshconfig.googleapis.com \ iamcredentials.googleapis.com \ gkeconnect.googleapis.com \ gkehub.googleapis.com
Mempersiapkan lingkungan Andaa
Di Cloud Shell, clone repositori berikut:
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples cd anthos-service-mesh-samples/docs/mtls-egress-ingress
Memperbarui Terraform untuk lingkungan Anda. Secara default, konsol Google Cloud dilengkapi dengan Terraform 0.12. Tutorial ini mengasumsikan bahwa Anda telah menginstal Terraform 0.13.5 atau yang lebih baru. Anda dapat menggunakan Terraform versi lain untuk sementara dengan menjalankan perintah berikut:
mkdir ~/bin curl https://releases.hashicorp.com/terraform/0.13.5/terraform_0.13.5_linux_amd64.zip -o ~/bin/terraform.zip unzip ~/bin/terraform.zip -d ~/bin/
Buka subfolder
terraform
dan lakukan inisialisasi Terraform:cd terraform/ ~/bin/terraform init
Buat file
terraform.tfvars
(berdasarkan variabel lingkungan yang Anda buat sebelumnya):cat << EOF > terraform.tfvars project_id = "${PROJECT_ID}" region = "${REGION}" zones = ["${ZONE}"] EOF
Pada langkah berikutnya, Anda buat infrastruktur awal. Untuk melakukannya, Anda akan membuat dan menerapkan rencana eksekusi Terraform untuk konfigurasi ini. Skrip dan modul dalam rencana ini membuat hal berikut:
- Jaringan VPC khusus dengan dua subnet pribadi
- Dua cluster Kubernetes dengan Anthos Service Mesh diaktifkan
- Satu cluster GKE
- Satu cluster kOps yang berjalan di jaringan VPC khusus
Rencana pelaksanaan ini juga mendaftarkan cluster ke GKE Hub.
Jalankan rencana pelaksanaan:
~/bin/terraform plan -out mtls-terraform-plan ~/bin/terraform apply "mtls-terraform-plan"
Outputnya mirip dengan yang berikut ini:
Apply complete! Resources: 27 added, 0 changed, 0 destroyed. Outputs: server_token = <sensitive>
Bagian
<sensitive>
adalah variabel output Terraform yang tidak ditampilkan di konsol, tetapi dapat dikueri misalnya,~/bin/terraform output server_token
.Dapatkan file
kubeconfig
cluster server dari direktoriterraform
. Kemudian, gabungkan dengan file konfigurasiclient-cluster
:cd .. export KUBECONFIG=client-server-kubeconfig cp ./terraform/server-kubeconfig $KUBECONFIG gcloud container clusters get-credentials client-cluster --zone ${ZONE} --project ${PROJECT_ID}
File
client-server-kubeconfig
kini menyimpan konfigurasi untuk kedua cluster tersebut, yang dapat Anda verifikasi dengan menjalankan perintah berikut:kubectl config view -ojson | jq -r '.clusters[].name'
Outputnya adalah sebagai berikut:
gke_PROJECT_ID_us-central1-c_client-cluster server-cluster.k8s.local
Dapatkan konteks kedua klaster tersebut untuk digunakan nanti:
export CLIENT_CLUSTER=$(kubectl config view -ojson | jq -r '.clusters[].name' | grep client) export SERVER_CLUSTER=$(kubectl config view -ojson | jq -r '.clusters[].name' | grep server) echo -e "${CLIENT_CLUSTER}\n${SERVER_CLUSTER}"
Outputnya (lagi) adalah sebagai berikut:
gke_PROJECT_ID_us-central1-c_client-cluster server-cluster.k8s.local
Kini Anda dapat menggunakan nama cluster ini sebagai konteks untuk perintah
kubectl
lebih lanjut.Referensikan cluster klien:
kubectl --context ${CLIENT_CLUSTER} get pods -n istio-system
Referensikan cluster server:
kubectl --context ${SERVER_CLUSTER} get pods -n istio-system
Mengonfigurasi sisi klien
Seperti disebutkan dalam panduan konsep, sisi klien mengharuskan Anda mengonfigurasi gateway keluar di Anthos Service Mesh.
Di bagian ini, Anda akan mengonfigurasi elemen Anthos Service Mesh untuk mengidentifikasi traffic eksternal berdasarkan asalnya dan menggunakan sertifikat kustom untuk mengenkripsi komunikasi. Selain itu, Anda hanya perlu merutekan traffic tersebut ke tujuannya (DB MySQL dalam sebuah container). Biasanya, Anda melakukannya dengan menggunakan layanan di Kubernetes. Dalam hal ini, Anda perlu menangkap traffic tersebut di dalam komunikasi mesh. Untuk menangkap traffic, gunakan elemen Istio untuk membuat definisi khusus layanan. Anda menentukan elemen berikut:
- Gateway keluar
- Entri layanan
- Layanan Virtuall
- Sertifikat TLS (sebagai rahasia)
- Aturan tujuan
Di Cloud Shell, dapatkan alamat IP gateway masuk di sisi server dengan membuat kueri alamat IP load balancer dari layanan
istio-ingressgateway
menggunakan konteks sisi server ($SERVER_CLUSTER
, yang telah Anda buat sebelumnya):INGRESS_HOST=$(kubectl -n istio-system --context ${SERVER_CLUSTER} get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
Karena
INGRESS_HOST
hanyalah bagian alamat IP dari host, Anda harus membuat nama domain yang sepenuhnya memenuhi syarat (FQDN). Langkah ini diperlukan karena, agar dapat berfungsi dengan benar, sertifikat memerlukan nama domain.Dalam tutorial ini, Anda akan menggunakan layanan DNS karakter pengganti nip.io untuk membuat FQDN bagi alamat IP masuk. Layanan ini memungkinkan Anda membuat FQDN tanpa harus memiliki domain.
Simpan URL layanan FQDN dalam variabel lingkungan:
export SERVICE_URL="${INGRESS_HOST}.nip.io"
Setelah
SERVICE_URL
ditetapkan sebagai FQDN, Anda dapat mulai menentukan bagian Istio dari cluster klien.
Membuat gateway keluarr
Anda memulai dengan membuat gateway keluar untuk memproses traffic yang ditujukan untuk layanan eksternal.
Di Cloud Shell, buat file YAML berikut dan beri nama
client-egress-gateway.yaml
:cat <<EOF > client-egress-gateway.yaml apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-egressgateway-mysql spec: selector: istio: egressgateway servers: - port: number: 15443 name: tls protocol: TLS hosts: - $SERVICE_URL tls: mode: ISTIO_MUTUAL EOF
Terapkan file YAML sebelumnya ke cluster klien:
kubectl --context ${CLIENT_CLUSTER} apply -f client-egress-gateway.yaml
Perhatikan portnya. Anda telah menggunakan port
default
di sini untuk tombol server keluar, yaitu15443
. Jika ingin menggunakan port lain, Anda perlu mengedit objekservice
gateway keluar untuk menambahkan port khusus.Tombol
hosts
menentukan endpoint, tempat traffic harus diarahkan.
Menentukan entri layanan
Langkah berikutnya adalah memberi tahu mesh layanan tentang layanan eksternal. Istio memiliki registry sendiri yang menyimpan endpoint layanan untuk mesh. Jika Istio diinstal di atas Kubernetes, layanan yang ditentukan dalam cluster akan ditambahkan ke registry Istio secara otomatis. Dengan definisi entri layanan, Anda dapat menambahkan endpoint baru ke registry Istio seperti yang ditunjukkan dalam diagram berikut.
Di Cloud Shell, buat file YAML berikut dan beri nama
client-service-entry.yaml
:cat <<EOF > client-service-entry.yaml apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: mysql-external spec: hosts: - $SERVICE_URL location: MESH_EXTERNAL ports: - number: 3306 name: tcp protocol: TCP - number: 13306 name: tls protocol: TLS resolution: DNS endpoints: - address: $SERVICE_URL ports: tls: 13306 EOF
Terapkan file YAML sebelumnya ke cluster klien:
kubectl --context ${CLIENT_CLUSTER} apply -f client-service-entry.yaml
Definisi layanan klien dalam file YAML ini memberi tahu layanan jenis traffic yang diharapkan (MySQL L4 - lapisan jaringan empat, menggunakan port 3306). Anda juga mendefinisikan bahwa komunikasi akan berupa "mesh eksternal". Di bagian endpoint, Anda menentukan bahwa alur harus mengarah ke alamat FQDN
$SERVICE_URL
yang telah Anda tetapkan sebelumnya dan yang dipetakan ke gateway masuk di cluster server (kOps).
Menentukan layanan virtual
Layanan virtual adalah seperangkat aturan perutean traffic yang akan diterapkan saat host ditangani. Setiap aturan perutean menentukan kriteria yang cocok untuk lalu lintas protokol tertentu. Jika traffic cocok, traffic akan dikirim ke layanan tujuan bernama (atau subset atau versinya) yang ditentukan dalam registry. Untuk mengetahui informasi selengkapnya, baca dokumentasi Terraform.
Definisi layanan virtual memberi tahu Istio cara menerapkan perutean untuk traffic yang mencapai layanan eksternal. Dengan definisi berikut, Anda memberi tahu mesh untuk merutekan traffic dari klien ke gateway keluar pada port 15443
. Dari gateway keluar, selanjutnya Anda mengarahkan traffic ke $SERVICE_URL
host di port 13306
(tempat gateway masuk sisi server Anda memproses).
Buat file YAML berikut dan beri nama
client-virtual-service.yaml
:cat <<EOF > client-virtual-service.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: direct-mysql-through-egress-gateway spec: hosts: - $SERVICE_URL gateways: - istio-egressgateway-mysql - mesh tcp: - match: - gateways: - mesh port: 3306 route: - destination: host: istio-egressgateway.istio-system.svc.cluster.local subset: mysql port: number: 15443 weight: 100 - match: - gateways: - istio-egressgateway-mysql port: 15443 route: - destination: host: $SERVICE_URL port: number: 13306 weight: 100 EOF
Terapkan definisi YAML ke cluster klien:
kubectl --context ${CLIENT_CLUSTER} apply -f client-virtual-service.yaml
Anda dapat menentukan gateway mana yang harus diterapkan konfigurasi dengan mengedit tombol
gateways
di file YAML.Bagian penting dalam definisi ini adalah penggunaan kata yang dicadangkan
mesh
, yang menyiratkan semua file bantuan di mesh. Menurut dokumentasi Istio, jika kolom ini dihilangkan, gateway default (mesh) akan digunakan, dengan menerapkan aturan pada semua file bantuan di mesh. Jika Anda memberikan daftar nama gateway, aturan hanya berlaku untuk gateway tersebut. Untuk menerapkan aturan ke gateway dan file bantuan, tetapkanmesh
sebagai salah satu nama gateway.
Di bagian berikutnya, Anda akan menentukan cara menangani traffic yang keluar
dari proxy produksi klien, match.gateways.mesh
. Anda juga menentukan cara
mengalihkan traffic dari traffic keluar ke layanan eksternal menggunakan
tombol match.gateways.istio-egressgateway-mysql
.
Tentukan aturan tujuan (dari klien ke gateway keluar)
Setelah menentukan cara mengarahkan traffic ke layanan eksternal, Anda perlu menentukan kebijakan traffic yang harus diterapkan. Layanan virtual yang baru saja Anda tetapkan menangani dua kasus {i>routing<i} sekaligus. Satu project menangani traffic dari proxy file bantuan ke gateway keluar, dan satunya lagi menangani traffic dari gateway keluar ke layanan eksternal.
Untuk mencocokkan kasus ini dengan aturan tujuan, Anda memerlukan dua aturan yang terpisah. Diagram berikut menunjukkan aturan pertama, yang menangani traffic dari proxy ke gateway keluar. Dalam definisi ini, Anda memberi tahu Anthos Service Mesh agar menggunakan sertifikat defaultnya untuk komunikasi mTLS.
Di Cloud Shell, buat file YAML berikut dan beri nama
client-destination-rule-to-egress-gateway.yaml
:cat <<EOF > client-destination-rule-to-egress-gateway.yaml apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: egressgateway-for-mysql spec: host: istio-egressgateway.istio-system.svc.cluster.local subsets: - name: mysql trafficPolicy: loadBalancer: simple: ROUND_ROBIN portLevelSettings: - port: number: 15443 tls: mode: ISTIO_MUTUAL sni: $SERVICE_URL EOF
Terapkan definisi YAML sebelumnya ke cluster klien:
kubectl --context ${CLIENT_CLUSTER} apply -f client-destination-rule-to-egress-gateway.yaml
Dalam file YAML sebelumnya, Anda menggunakan tombol
hosts
untuk menentukan cara merutekan traffic dari proxy klien ke gateway keluar. Selain itu, Anda telah mengonfigurasi mesh untuk menggunakanISTIO_MUTUAL
pada port15443
, yang merupakan salah satu port yang otomatis terbuka di gateway keluar.
Buat aturan tujuan (dari gateway keluar ke layanan eksternal)
Diagram berikut menunjukkan aturan tujuan kedua, yang memberi tahu mesh cara menangani traffic dari gateway keluar ke layanan eksternal.
Anda harus memberi tahu mesh agar menggunakan sertifikat yang dimasukkan untuk komunikasi TLS dengan layanan eksternal.
Di Cloud Shell, dari direktori
anthos-service-mesh-samples/docs/mtls-egress-ingress
, buat sertifikat:./create-keys.sh
Pastikan untuk memberikan sandi saat skrip memintanya.
Salin file yang dihasilkan ke direktori saat ini:
cp ./certs/2_intermediate/certs/ca-chain.cert.pem ca-chain.cert.pem cp ./certs/4_client/private/$SERVICE_URL.key.pem client-$SERVICE_URL.key.pem cp ./certs/4_client/certs/$SERVICE_URL.cert.pem client-$SERVICE_URL.cert.pem
Buat rahasia Kubernetes yang menyimpan sertifikat agar dapat direferensikan nanti di gateway:
kubectl --context ${CLIENT_CLUSTER} create secret -n istio-system \ generic client-credential \ --from-file=tls.key=client-$SERVICE_URL.key.pem \ --from-file=tls.crt=client-$SERVICE_URL.cert.pem \ --from-file=ca.crt=ca-chain.cert.pem
Perintah sebelumnya menambahkan file sertifikat berikut ke secret:
client-$SERVICE_URL.key.pem client-$SERVICE_URL.cert.pem ca-chain.cert.pem
Praktik terbaik saat ini untuk mendistribusikan sertifikat diikuti di sini dengan menggunakan layanan penemuan rahasia (SDS), bukan pemasangan file. Praktik ini akan menghindari proses mulai ulang pod saat menambahkan sertifikat baru. Mulai dari Istio 1.8/1.9, dengan teknik ini, Anda tidak lagi memerlukan hak akses baca (RBAC) untuk rahasia gateway.
Tambahkan sertifikat ke
DestinationRule
dan beri namaclient-destination-rule-to-external-service.yaml
:cat <<EOF > client-destination-rule-to-external-service.yaml apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: originate-mtls-for-mysql spec: host: $SERVICE_URL trafficPolicy: loadBalancer: simple: ROUND_ROBIN portLevelSettings: - port: number: 13306 tls: mode: MUTUAL credentialName: client-credential sni: $SERVICE_URL EOF
Terapkan definisi YAML sebelumnya ke cluster klien:
kubectl --context ${CLIENT_CLUSTER} apply -f client-destination-rule-to-external-service.yaml
Aturan ini hanya berfungsi jika Anda telah membuat rahasia terlebih dahulu. Rahasia ini memastikan bahwa sertifikat digunakan untuk enkripsi mTLS dari gateway keluar ke endpoint eksternal.
Setelah menyelesaikan langkah-langkah ini, penyiapan sisi klien Anda sudah selesai dan akan terlihat seperti diagram berikut.
Mengonfigurasi sisi server
Seperti yang telah dibahas dalam panduan konsep, untuk sisi server, Anda harus mengonfigurasi gateway ingress di Anthos Service Mesh. Sebelum Anda membuat file yang diperlukan, sebaiknya tinjau komponen mana yang diperlukan untuk mewujudkan bagian server dari solusi.
Pada dasarnya, Anda ingin mengidentifikasi traffic masuk berdasarkan asal dan sertifikatnya. Anda juga ingin secara khusus merutekan traffic tersebut ke tujuannya: DB MySQL Anda dalam sebuah container. Biasanya Anda menggunakan layanan di Kubernetes untuk melakukannya, tetapi dalam contoh ini, Anda mengidentifikasi traffic masuk di dalam komunikasi mesh, sehingga Anda memerlukan definisi khusus layanan yang mencakup hal-hal berikut:
- Sertifikat TLS (sebagai rahasia)
- Gateway masuk
- Layanan Virtuall
Membuat rahasia untuk gateway masuk
Seperti yang Anda lakukan untuk gateway keluar, Anda memerlukan sertifikat yang sama guna mengamankan komunikasi untuk gateway masuk. Untuk melakukannya, simpan sertifikat di rahasia dan tentukan rahasia ini dengan objek gateway masuk Anda.
Di Cloud Shell, salin file yang dihasilkan ke lokasi tempat Anda menjalankan perintah berikutnya:
cp ./certs/3_application/private/$SERVICE_URL.key.pem server-$SERVICE_URL.key.pem cp ./certs/3_application/certs/$SERVICE_URL.cert.pem server-$SERVICE_URL.cert.pem
Buat rahasia server:
kubectl --context ${SERVER_CLUSTER} create secret -n istio-system \ generic mysql-credential \ --from-file=tls.key=server-$SERVICE_URL.key.pem \ --from-file=tls.crt=server-$SERVICE_URL.cert.pem \ --from-file=ca.crt=ca-chain.cert.pem
Anda baru saja menambahkan file sertifikat berikut ke secret:
server-$SERVICE_URL.key.pem server-$SERVICE_URL.cert.pem ca-chain.cert.pem
Menentukan gateway masuk
Untuk menerima traffic dari cluster sisi klien, Anda harus menentukan gateway masuk yang dapat mendekripsi dan memverifikasi komunikasi TLS menggunakan sertifikat.
Diagram ini menunjukkan letak gateway ingress di cluster Anda. Traffic akan melewati dan diperiksa jika memenuhi kriteria keamanan dan penerusan.
Di Cloud Shell, gunakan file YAML berikut dan beri nama
server-ingress-gatway.yaml
:cat <<EOF > server-ingress-gatway.yaml apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: gateway-mysql spec: selector: istio: ingressgateway # Istio default gateway implementation servers: - port: number: 13306 name: tls-mysql protocol: TLS tls: mode: MUTUAL credentialName: mysql-credential hosts: - "$SERVICE_URL" EOF
Terapkan definisi YAML sebelumnya ke cluster klien:
kubectl --context ${SERVER_CLUSTER} apply -f server-ingress-gatway.yaml
Perhatikan bagian
tls:
karena bagian ini sangat penting. Di bagian ini, Anda menentukan bahwa Anda ingin mTLS. Untuk memastikannya berfungsi seperti yang diharapkan, Anda harus memberikan secret yang Anda buat yang berisi sertifikat tersebut.Aktifkan port
13306
dengan mem-patch layanan ingress. Anda mengaktifkan port ini dengan membuat file JSON berikut dan menamakannyagateway-patch.json
:cat <<EOF > gateway-patch.json [{ "op": "add", "path": "/spec/ports/0", "value": { "name": "tls-mysql", "protocol": "TCP", "targetPort": 13306, "port": 13306 } }] EOF
Terapkan patch ke layanan gateway:
kubectl --context ${SERVER_CLUSTER} -n istio-system patch --type=json svc istio-ingressgateway -p "$(cat gateway-patch.json)"
Setelah membuka port di gateway masuk, Anda harus mengambil traffic yang berasal dari gateway ingress baru Anda dan mengarahkannya ke Pod database. Untuk melakukannya, gunakan objek internal mesh: layanan virtual.
Menentukan layanan virtual
Seperti yang dibahas sebelumnya, layanan virtual adalah definisi pola pencocokan traffic yang membentuk traffic dalam mesh Anda. Anda perlu mengidentifikasi dan meneruskan traffic dengan benar dari gateway ingress ke layanan MySQL DB, seperti yang ditunjukkan pada diagram berikut.
Di Cloud Shell, buat file YAML berikut dan beri nama
server-virtual-service.yaml
:cat <<EOF > server-virtual-service.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: mysql-virtual-service spec: hosts: - "$SERVICE_URL" gateways: - gateway-mysql tcp: - route: - destination: port: number: 3306 host: mysql.default.svc.cluster.local EOF
Layanan virtual ini harus merujuk ke gateway masuk tempat traffic berasal. Gateway diberi nama
gateway-mysql
.Karena layanan virtual ini diterapkan di L4, Anda perlu memberikan flag
tcp
untuk mendeskripsikan traffic MySQL. Penanda ini pada dasarnya memberi tahu {i> mesh<i} bahwa L4 digunakan untuk lalu lintas ini.Anda mungkin telah mengetahui bahwa layanan ingress menggunakan port
13306
untuk meneruskan traffic. Layanan virtual mengambilnya dan menerjemahkannya kembali ke3306
.Terakhir, Anda meneruskan traffic ke server MySQL di cluster Kubernetes server. Untuk contoh ini, server memproses port MySQL standar
3306
.Terapkan definisi YAML ke cluster server:
kubectl --context ${SERVER_CLUSTER} apply -f server-virtual-service.yaml
Kedua definisi ini mendekripsi permintaan klien MySQL yang dienkapsulasi mTLS dan meneruskannya ke database MySQL di dalam mesh.
Penting untuk memahami bahwa penerusan internal mesh juga dilakukan menggunakan enkripsi. Namun, dalam hal ini, enkripsi didasarkan pada sertifikat internal mesh. Penghentian mTLS terjadi di gateway.
Sekarang Anda memiliki cara berkomunikasi yang sepenuhnya terenkripsi satu sama lain dengan server MySQL. Bentuk enkripsi ini bersifat transparan untuk klien dan server MySQL, sehingga aplikasi tidak perlu diubah. Dengan begitu, tugas seperti mengubah atau merotasi sertifikat menjadi mudah. Juga, cara komunikasi ini dapat digunakan untuk banyak skenario yang berbeda.
Menguji penyiapan
Setelah memiliki sisi klien dan server, Anda dapat menguji penyiapannya.
Saatnya untuk menghasilkan beberapa lalu lintas dari sisi klien ke sisi server. Anda ingin mengikuti alur traffic dan memastikan bahwa traffic dirutekan, serta dienkripsi dan didekripsi seperti yang Anda inginkan.
Di Cloud Shell, deploy server MySQL ke cluster server:
kubectl --context ${SERVER_CLUSTER} apply -f server/mysql-server/mysql.yaml
Mulai klien MySQL di cluster klien:
kubectl run --context ${CLIENT_CLUSTER} --env=SERVICE_URL=$SERVICE_URL -it --image=mysql:5.6 mysql-client-1 --restart=Never -- /bin/bash
Saat container dimulai, Anda akan melihat shell, yang akan terlihat seperti berikut:
root@mysql-client-1:/#
Hubungkan ke server MySQL Anda:
mysql -pyougottoknowme -h $SERVICE_URL
Gunakan perintah berikut untuk menambahkan DB dan tabel:
CREATE DATABASE test_encrypted_connection; USE test_encrypted_connection; CREATE TABLE message (id INT, content VARCHAR(20)); INSERT INTO message (id,content) VALUES(1,"Crypto Hi");
Setelah menghubungkan dan menambahkan tabel, keluar dari koneksi MySQL dan Pod:
exit exit
Anda harus mengetik exit dua kali—pertama, untuk meninggalkan koneksi DB, dan kedua, untuk keluar dari Pod. Jika Pod berhenti merespons saat keluar, tekan Control+C untuk membatalkan bash shell.
Dengan mengikuti langkah-langkah ini, Anda akan menghasilkan beberapa output logging penting yang sekarang dapat dianalisis lebih lanjut.
Di bagian berikutnya, Anda perlu memeriksa apakah traffic sisi klien meneruskan proxy dan gateway keluar. Anda juga akan menguji apakah traffic yang masuk ke sisi server dapat dilihat melalui gateway masuk.
Menguji gateway keluar dan proxy sisi klien
Di Cloud Shell, pada proxy sisi klien, pastikan Anda dapat melihat log proxy Istio:
kubectl --context ${CLIENT_CLUSTER} logs -l run=mysql-client-1 -c istio-proxy -f
Outputnya terlihat mirip dengan yang berikut ini:
[2021-02-10T21:19:08.292Z] "- - -" 0 - "-" "-" 176 115 10 - "-" "-" "-" "-" "192.168.1.4:15443" outbound|15443|mysql|istio-egressgateway.istio-system.svc.cluster.local 192.168.1.12:58614 34.66.165.46:3306 192.168.1.12:39642 - -
Tekan Control+C untuk keluar dari output log.
Dalam entri log ini, Anda dapat melihat bahwa klien meminta server yang berjalan di alamat IP
34.66.165.46
pada port3306
. Permintaan diteruskan (outbound
) keistio-egressgateway
yang memproses alamat IP port192.168.1.4
15443
. Anda menentukan penerusan ini dalam layanan virtual Anda (client-virtual-service.yaml
).Baca log proxy gateway keluar:
kubectl --context ${CLIENT_CLUSTER} logs -n istio-system -l app=istio-egressgateway -f
Outputnya mirip dengan yang berikut ini:
[2021-02-10T21:19:08.292Z] "- - -" 0 - "-" "-" 176 115 19 - "-" "-" "-" "-" "34.66.165.46:13306" outbound|13306||34.66.165.46.nip.io 192.168.1.4:53542 192.168.1.4:15443 192.168.1.12:58614 34.66.165.46.nip.io -
Tekan Control+C untuk keluar dari output log.
Dalam entri log ini, Anda dapat melihat bahwa permintaan klien yang dirutekan ke
istio-egressgateway
yang memproses port192.168.1.4
alamat IP15443
diteruskan lebih lanjut ke luar mesh layanan ke port eksternal layanan yang memproses alamat IP34.66.165.46
pada port13306.
Anda menentukan penerusan ini di bagian kedua layanan virtual Anda (client-virtual-service.yaml
).
Menguji gateway masuk sisi server
Di Cloud Shell, di sisi server, lihat log proxy gateway masuk:
kubectl --context ${SERVER_CLUSTER} logs -n istio-system -l app=istio-ingressgateway -f
Output dalam log terlihat mirip dengan berikut ini:
[2021-02-10T21:22:27.381Z] "- - -" 0 - "-" "-" 0 78 5 - "-" "-" "-" "-" "100.96.4.8:3306" outbound|3306||mysql.default.svc.cluster.local 100.96.1.3:55730 100.96.1.3:13306 100.96.1.1:42244 34.66.165.46.nip.io -
Tekan Control+C untuk keluar dari output log.
Dalam entri log ini, Anda dapat melihat bahwa permintaan klien eksternal yang dirutekan ke
istio-ingressgateway
yang memproses port34.66.165.46
alamat IP13306
diteruskan lebih lanjut ke layanan MySQL di dalam mesh yang diidentifikasi dengan nama layananmysql.default.svc.cluster.local
pada port3306.
Anda menentukan penerusan ini di gateway masuk (server-ingress-gateway.yaml
).Untuk server MySQL, lihat log proxy Istio:
kubectl --context ${SERVER_CLUSTER} logs -l app=mysql -c istio-proxy -f
Outputnya terlihat mirip dengan yang berikut ini:
[2021-02-10T21:22:27.382Z] "- - -" 0 - "-" "-" 1555 1471 4 - "-" "-" "-" "-" "127.0.0.1:3306" inbound|3306|mysql|mysql.default.svc.cluster.local 127.0.0.1:45894 100.96.4.8:3306 100.96.1.3:55730 outbound_.3306_._.mysql.default.svc.cluster.local -
Tekan Control+C untuk keluar dari output log.
Dalam entri log ini, Anda dapat melihat panggilan masuk ke server database MySQL yang memproses alamat IP
100.96.4.8
port3306
. Panggilan ini berasal dari Pod ingress dengan alamat IP100.96.1.3
.Untuk mengetahui informasi selengkapnya tentang format logging Envoy, lihat Mendapatkan Log Akses Envoy.
Uji database Anda untuk melihat input yang dihasilkan:
MYSQL=$(kubectl --context ${SERVER_CLUSTER} get pods -n default | tail -n 1 | awk '{print $1}') kubectl --context ${SERVER_CLUSTER} exec $MYSQL -ti -- /bin/bash
Verifikasi database yang dibuat:
mysql -pyougottoknowme USE test_encrypted_connection; SELECT * from message;
Outputnya mirip dengan hal berikut ini:
+------+-----------+ | id | content | +------+-----------+ | 1 | Crypto Hi | +------+-----------+ 1 row in set (0.00 sec)
Biarkan database MySQL:
exit exit
Anda perlu mengetik
exit
dua kali—pertama, untuk meninggalkan koneksi DB, dan kedua, untuk keluar dari Pod.
Menguji akses dengan menghapus sertifikat
Setelah menguji dan memverifikasi bahwa akses berfungsi menggunakan sertifikat yang dimasukkan, uji juga hal sebaliknya: apa yang terjadi jika Anda menghilangkan gateway keluar dan injeksi sertifikat. Pengujian ini juga disebut pengujian negatif.
Anda dapat melakukan pengujian ini dengan meluncurkan Pod lain dalam namespace tanpa mengaktifkan injeksi side proxy.
Di Cloud Shell, buat namespace baru:
kubectl --context ${CLIENT_CLUSTER} create ns unencrypted
Buat Pod dan mulai shell interaktif di dalam container:
kubectl --context ${CLIENT_CLUSTER} run -it --image=mysql:5.6 \ mysql-client-2 --env=SERVICE_URL=$SERVICE_URL \ -n unencrypted --restart=Never -- /bin/bash
Coba hubungkan ke database setelah shell interaktif dimulai:
mysql -pyougottoknowme -h $SERVICE_URL
Setelah 30 detik, Anda akan melihat output yang mirip dengan berikut ini:
Warning: Using a password on the command line interface can be insecure. ERROR 2003 (HY000): Can't connect to MySQL server on '104.154.164.12.nip.io' (110)
Peringatan ini sudah diperkirakan karena Pod ini menghilangkan gateway keluar dan mencoba menjangkau gateway masuk (
$SERVICE_URL
) secara langsung melalui internet.Coba tentukan alamat IP layanan:
resolveip $SERVICE_URL
Outputnya mirip dengan yang berikut ini. Alamat IP Anda akan berbeda.
IP address of 104.154.164.12.nip.io is 104.154.164.12
Hal ini membuktikan bahwa FQDN dapat diselesaikan dan bahwa koneksi yang gagal memang karena injeksi sertifikat yang tidak ada.
Keluar dari koneksi MySQL dan Pod server MySQL:
exit exit
Penyelidikan Lebih Jauh
Salah satu topik yang tidak dibahas dalam tutorial ini adalah bahwa konfigurasi egress, biasanya dimiliki oleh organisasi atau peran yang berbeda di perusahaan Anda, karena dihosting di namespace istio-system
. Konfigurasikan izin RBAC Kubernetes sehingga hanya administrator jaringan yang dapat langsung membuat dan mengubah resource yang dibahas dalam tutorial ini.
Setelah mengetahui cara menggunakan mesh layanan untuk membantu memastikan komunikasi yang aman, Anda dapat mencobanya dengan aplikasi yang perlu bertukar data secara aman, dan tempat Anda ingin mengontrol enkripsi hingga ke lapisan sertifikat singkat ini. Untuk memulai, Anda dapat menginstal Anthos Service Mesh.
Coba gunakan dua cluster GKE dan gabungkan dengan menggunakan teknik dalam tutorial ini. Teknik ini juga dapat digunakan di platform GKE Enterprise antara dua cluster Kubernetes asing.
Mesh layanan adalah cara terbaik untuk meningkatkan keamanan di dalam cluster Anda serta dengan layanan eksternal. Salah satu kasus penggunaan terakhir yang harus dicoba adalah memiliki endpoint mTLS yang bukan merupakan cluster Kubernetes kedua, tetapi penyedia pihak ketiga (seperti penyedia pembayaran).
Pembersihan
Agar tidak menimbulkan biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, Anda dapat menghapus project Anda.
Menghapus project
- Di konsol Google Cloud, buka halaman Manage resource.
- Pada daftar project, pilih project yang ingin Anda hapus, lalu klik Delete.
- Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.
Langkah selanjutnya
- Bacapanduan konsep pendamping.
- Untuk praktik terbaik lebih lanjut tentang cara mengonfigurasi gateway keluar Anda, lihat Menggunakan gateway keluar Anthos Service Mesh di cluster GKE: Tutorial.
- Pelajari panduan hardening GKE dan modul Terraform yang menyertainya.
- Pelajari arsitektur referensi, diagram, dan praktik terbaik tentang Google Cloud. Lihat Cloud Architecture Center kami.