Showing preview only (615K chars total). Download the full file or copy to clipboard to get everything.
Repository: GoogleCloudPlatform/istio-samples
Branch: master
Commit: 3b73ff8ee2b1
Files: 141
Total size: 572.4 KB
Directory structure:
gitextract_ft7f4bst/
├── .github/
│ └── snippet-bot.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── common/
│ ├── default.yaml
│ └── install_istio.sh
├── internal-load-balancer/
│ ├── README.md
│ └── manifests/
│ ├── install.yaml
│ └── server-ilb.yaml
├── istio-canary-gke/
│ ├── README.md
│ └── canary/
│ ├── destinationrule.yaml
│ ├── productcatalog-v2.yaml
│ ├── rollback.yaml
│ └── vs-split-traffic.yaml
├── istio-stackdriver/
│ └── README.md
├── mesh-expansion-gce/
│ ├── README.md
│ └── scripts/
│ ├── 1-create-cluster.sh
│ ├── 2-create-vm.sh
│ ├── 3-install-istio.sh
│ ├── 4-deploy-hipstershop.sh
│ ├── 5-prep-cluster.sh
│ ├── 6-prep-vm.sh
│ ├── 7-add-to-mesh.sh
│ ├── 8-start-vm-istio.sh
│ ├── install.yaml
│ ├── vm-install-istio.sh
│ └── vm-run-products.sh
├── multicluster-gke/
│ ├── dual-control-plane/
│ │ ├── README.md
│ │ ├── cluster1/
│ │ │ ├── deployments.yaml
│ │ │ ├── istio-defaults.yaml
│ │ │ ├── service-entries.yaml
│ │ │ └── services-local.yaml
│ │ ├── cluster2/
│ │ │ ├── deployments.yaml
│ │ │ ├── istio-defaults.yaml
│ │ │ ├── service-entries.yaml
│ │ │ └── services-local.yaml
│ │ └── scripts/
│ │ ├── 1-create-gke-clusters.sh
│ │ ├── 2-install-istio.sh
│ │ ├── 3-configure-dns.sh
│ │ ├── 4-deploy-online-boutique.sh
│ │ ├── cleanup-delete-clusters.sh
│ │ ├── env.sh
│ │ └── install.yaml
│ ├── single-control-plane/
│ │ ├── README.md
│ │ └── scripts/
│ │ ├── 1-cluster-create.sh
│ │ ├── 2-get-credentials.sh
│ │ ├── 3-firewall.sh
│ │ ├── 4-cluster1-install.sh
│ │ ├── 5-cluster2-install.sh
│ │ ├── 6-connect-clusters.sh
│ │ ├── 7-deploy-hipstershop.sh
│ │ ├── cleanup-delete-clusters.sh
│ │ ├── cluster1.yaml
│ │ ├── cluster2.yaml
│ │ └── env.sh
│ └── vm-migration/
│ ├── README.md
│ ├── cluster1/
│ │ ├── deployments.yaml
│ │ ├── istio-defaults.yaml
│ │ ├── service-entries.yaml
│ │ └── services-local.yaml
│ ├── cluster2/
│ │ ├── deployments.yaml
│ │ ├── istio-defaults.yaml
│ │ ├── service-entries.yaml
│ │ └── services-local.yaml
│ ├── productcatalog-gke/
│ │ ├── deployment.yaml
│ │ ├── service-cluster2.yaml
│ │ ├── serviceentry-cluster1.yaml
│ │ ├── vs-0-cluster1.yaml
│ │ ├── vs-0-cluster2.yaml
│ │ ├── vs-100-cluster1.yaml
│ │ ├── vs-100-cluster2.yaml
│ │ ├── vs-20-cluster1.yaml
│ │ └── vs-20-cluster2.yaml
│ └── scripts/
│ ├── 1-create-infra.sh
│ ├── 10-split-traffic.sh
│ ├── 11-complete-migration.sh
│ ├── 12-cleanup.sh
│ ├── 2-firewall.sh
│ ├── 3-install-istio-gke.sh
│ ├── 4-deploy-onlineboutique-gke.sh
│ ├── 5-prep-cluster1.sh
│ ├── 6-prep-vm.sh
│ ├── 7-add-vm-to-mesh.sh
│ ├── 8-verify-deploy.sh
│ ├── 9-deploy-productcatalog-gke.sh
│ ├── env.sh
│ ├── install.yaml
│ ├── vm-install-istio.sh
│ └── vm-run-products.sh
├── multicluster-ingress/
│ ├── 1-create-clusters.sh
│ ├── 2-install-istio.sh
│ ├── 3-deploy-app.sh
│ ├── 4-verify-app.sh
│ ├── 5-prep-mci.sh
│ ├── 6-mci.sh
│ ├── 7-cleanup.sh
│ ├── README.md
│ ├── common.sh
│ ├── manifests/
│ │ ├── healthcheck.yaml
│ │ ├── ingress.yaml
│ │ └── istio-ingressgateway-patch.json
│ └── zone_printer/
│ ├── deployment.yaml
│ ├── gateway.yaml
│ ├── service.yaml
│ └── virtualservice.yaml
├── sample-apps/
│ ├── grpc-greeter-go/
│ │ ├── README.md
│ │ ├── client/
│ │ │ ├── .dockerignore
│ │ │ ├── .gcloudignore
│ │ │ ├── Dockerfile
│ │ │ ├── client.go
│ │ │ ├── go.mod
│ │ │ └── go.sum
│ │ ├── manifests/
│ │ │ ├── greeter-istio-destinationrule.yaml
│ │ │ ├── greeter-istio-gateway.yaml
│ │ │ ├── greeter-istio-virtualservice.yaml
│ │ │ ├── greeter-k8s.template.yaml
│ │ │ └── istio-operator.yaml
│ │ └── server/
│ │ ├── .dockerignore
│ │ ├── .gcloudignore
│ │ ├── Dockerfile
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── server.go
│ └── helloserver/
│ ├── README.md
│ ├── loadgen/
│ │ ├── Dockerfile
│ │ ├── Dockerfile-base
│ │ ├── loadgen.py
│ │ ├── loadgen.yaml
│ │ └── requirements.txt
│ └── server/
│ ├── Dockerfile
│ ├── server.py
│ └── server.yaml
├── security-intro/
│ ├── README.md
│ └── manifests/
│ ├── authz-frontend.yaml
│ ├── jwt-frontend-authz.yaml
│ ├── jwt-frontend-request.yaml
│ ├── mtls-default-ns.yaml
│ └── mtls-frontend.yaml
└── stackdriver-metrics/
├── README.md
└── istio-stackdriver-metrics.yaml
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/snippet-bot.yml
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
*.env
*.pem
*.tar.gz
cluster-2
istio_master.yaml
istio-1*
istio-2*
istio-master.yaml
istio-remote.yaml
istio.yaml
kubeconfig
kubectx
kubemci*
region-tag-adder
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
## Development Principles (for Googlers)
There are a few principles for developing or refactoring the service
implementations. Read the [Development Principles
Guide](./docs/development-principles.md).
## Contributor License Agreement
Contributions to this project must be accompanied by a Contributor License
Agreement. You (or your employer) retain the copyright to your contribution;
this simply gives us permission to use and redistribute your contributions as
part of the project. Head over to <https://cla.developers.google.com/> to see
your current agreements on file or to sign a new one.
You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.
## Code reviews
All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.
## Community Guidelines
This project follows [Google's Open Source Community
Guidelines](https://opensource.google.com/conduct/).
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# ⛵️ istio-samples
This repository contains Google Cloud Platform demos and sample code for [Istio](https://istio.io/).
**⚠️ Note**: These samples are last updated to the [Istio 1.5 release](https://github.com/istio/istio/releases/), and are no longer under active development. See the [Istio documentation](https://istio.io/) for the most up-to-date examples. For Anthos Service Mesh (ASM) samples, see https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
## Contents
### [Canary Deployments with Istio on GKE](/istio-canary-gke)
Uses the [Hipstershop](https://github.com/GoogleCloudPlatform/microservices-demo) sample app to demonstrate traffic splitting with Istio on GKE, and how to view Istio-generated metrics in Stackdriver.
### [Introduction to Istio Security](/security-intro)
Provides an introduction to Istio service-to-service encryption (mutual TLS), end-user authentication (JSON Web Tokens), and service authorization (role-based access control).
### [Istio and Stackdriver](/istio-stackdriver)
A deep-dive on how to use Stackdriver to monitor Istio services' health, analyze traces, and view logs.
### [Using a GCP Internal Load Balancer with Istio](/internal-load-balancer)
Demonstrates how to connect GCE (VM-based) workloads to Istio services running in GKE, through a private internal load balancer on GCP.
### [Geo-Aware Istio Multicluster Ingress](/multicluster-ingress)
Shows how to attach a global Anycast IP address to multiple Istio IngressGateways running in clusters across regions.
### [Integrating a Google Compute Engine VM with Istio](/mesh-expansion-gce)
Demonstrates how to do Istio Mesh Expansion: the process of incorporating a GCE-based workload into an Istio mesh running in GKE.
### [Multicluster Istio- Single Control Plane](/multicluster-gke/single-control-plane)
Introduces Multicluster Istio by uniting GKE workloads in two different clusters into a single Istio mesh.
### [Multicluster Istio- Dual Control Plane](/multicluster-gke/dual-control-plane)
Shows how to connect two separate GKE clusters, each with their own Istio control planes, into a single Gateway-connected mesh.
### [Virtual Machine Migration with Multicluster Istio](/multicluster-gke/vm-migration/)
Demonstrates how to integrate an Istio-enabled VM into a multicluster mesh, then migrate traffic from the VM to GKE.
================================================
FILE: common/default.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
addonComponents:
grafana:
enabled: true
k8s:
replicaCount: 1
istiocoredns:
enabled: false
kiali:
enabled: true
k8s:
replicaCount: 1
prometheus:
enabled: true
k8s:
replicaCount: 1
tracing:
enabled: true
components:
base:
enabled: true
citadel:
enabled: false
k8s:
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
cni:
enabled: false
egressGateways:
- enabled: false
k8s:
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-ingressgateway
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
name: istio-egressgateway
galley:
enabled: false
k8s:
replicaCount: 1
resources:
requests:
cpu: 100m
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
ingressGateways:
- enabled: true
k8s:
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-ingressgateway
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
name: istio-ingressgateway
nodeAgent:
enabled: false
pilot:
enabled: true
k8s:
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 5
resources:
requests:
cpu: 500m
memory: 2048Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
policy:
enabled: false
k8s:
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-policy
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
sidecarInjector:
enabled: false
k8s:
replicaCount: 1
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
telemetry:
enabled: false
k8s:
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: GOMAXPROCS
value: "6"
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-telemetry
replicaCount: 1
resources:
limits:
cpu: 4800m
memory: 4G
requests:
cpu: 1000m
memory: 1G
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
hub: docker.io/istio
tag: 1.5.1
values:
clusterResources: true
galley:
enableAnalysis: false
image: galley
gateways:
istio-egressgateway:
autoscaleEnabled: true
env:
ISTIO_META_ROUTER_MODE: sni-dnat
ports:
- name: http2
port: 80
- name: https
port: 443
- name: tls
port: 15443
targetPort: 15443
secretVolumes:
- mountPath: /etc/istio/egressgateway-certs
name: egressgateway-certs
secretName: istio-egressgateway-certs
- mountPath: /etc/istio/egressgateway-ca-certs
name: egressgateway-ca-certs
secretName: istio-egressgateway-ca-certs
type: ClusterIP
istio-ingressgateway:
applicationPorts: ""
autoscaleEnabled: true
debug: info
domain: ""
env:
ISTIO_META_ROUTER_MODE: sni-dnat
meshExpansionPorts:
- name: tcp-pilot-grpc-tls
port: 15011
targetPort: 15011
- name: tcp-citadel-grpc-tls
port: 8060
targetPort: 8060
- name: tcp-dns-tls
port: 853
targetPort: 853
ports:
- name: status-port
port: 15020
targetPort: 15020
- name: http2
port: 80
targetPort: 80
- name: https
port: 443
- name: kiali
port: 15029
targetPort: 15029
- name: prometheus
port: 15030
targetPort: 15030
- name: grafana
port: 15031
targetPort: 15031
- name: tracing
port: 15032
targetPort: 15032
- name: tls
port: 15443
targetPort: 15443
sds:
enabled: false
image: node-agent-k8s
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
secretVolumes:
- mountPath: /etc/istio/ingressgateway-certs
name: ingressgateway-certs
secretName: istio-ingressgateway-certs
- mountPath: /etc/istio/ingressgateway-ca-certs
name: ingressgateway-ca-certs
secretName: istio-ingressgateway-ca-certs
type: LoadBalancer
zvpn:
enabled: false
suffix: global
global:
arch:
amd64: 2
ppc64le: 2
s390x: 2
certificates: []
configValidation: true
controlPlaneSecurityEnabled: true
defaultNodeSelector: {}
defaultPodDisruptionBudget:
enabled: true
defaultResources:
requests:
cpu: 10m
disablePolicyChecks: true
enableHelmTest: false
enableTracing: true
imagePullPolicy: IfNotPresent
imagePullSecrets: []
istioNamespace: istio-system
istiod:
enabled: true
jwtPolicy: third-party-jwt
k8sIngress:
enableHttps: false
enabled: false
gatewayName: ingressgateway
localityLbSetting:
enabled: true
logAsJson: false
logging:
level: default:info
meshExpansion:
enabled: false
useILB: false
meshNetworks: {}
mountMtlsCerts: false
mtls:
auto: true
enabled: false
multiCluster:
clusterName: ""
enabled: false
network: ""
omitSidecarInjectorConfigMap: false
oneNamespace: false
operatorManageWebhooks: false
outboundTrafficPolicy:
mode: ALLOW_ANY
pilotCertProvider: istiod
policyCheckFailOpen: false
priorityClassName: ""
proxy:
accessLogEncoding: TEXT
accessLogFile: "/dev/stdout"
accessLogFormat: ""
autoInject: enabled
clusterDomain: cluster.local
componentLogLevel: misc:error
concurrency: 2
dnsRefreshRate: 300s
enableCoreDump: false
envoyAccessLogService:
enabled: false
envoyMetricsService:
enabled: false
tcpKeepalive:
interval: 10s
probes: 3
time: 10s
tlsSettings:
mode: DISABLE
subjectAltNames: []
envoyStatsd:
enabled: false
excludeIPRanges: ""
excludeInboundPorts: ""
excludeOutboundPorts: ""
image: proxyv2
includeIPRanges: '*'
includeInboundPorts: '*'
kubevirtInterfaces: ""
logLevel: warning
privileged: false
protocolDetectionTimeout: 100ms
readinessFailureThreshold: 30
readinessInitialDelaySeconds: 1
readinessPeriodSeconds: 2
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
statusPort: 15020
tracer: zipkin
proxy_init:
image: proxyv2
resources:
limits:
cpu: 100m
memory: 50Mi
requests:
cpu: 10m
memory: 10Mi
sds:
enabled: false
token:
aud: istio-ca
udsPath: ""
sts:
servicePort: 0
tracer:
datadog:
address: $(HOST_IP):8126
lightstep:
accessToken: ""
address: ""
cacertPath: ""
secure: true
stackdriver:
debug: false
maxNumberOfAnnotations: 200
maxNumberOfAttributes: 200
maxNumberOfMessageEvents: 200
zipkin:
address: ""
trustDomain: cluster.local
useMCP: false
grafana:
accessMode: ReadWriteMany
contextPath: /grafana
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- disableDeletion: false
folder: istio
name: istio
options:
path: /var/lib/grafana/dashboards/istio
orgId: 1
type: file
datasources:
datasources.yaml:
apiVersion: 1
env: {}
envSecrets: {}
image:
repository: grafana/grafana
tag: 6.5.2
ingress:
enabled: false
hosts:
- grafana.local
nodeSelector: {}
persist: false
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
security:
enabled: false
passphraseKey: passphrase
secretName: grafana
usernameKey: username
service:
annotations: {}
externalPort: 3000
name: http
type: ClusterIP
storageClassName: ""
tolerations: []
istiocoredns:
coreDNSImage: coredns/coredns
coreDNSPluginImage: istio/coredns-plugin:0.2-istio-1.1
coreDNSTag: 1.6.2
kiali:
contextPath: /kiali
createDemoSecret: true
dashboard:
grafanaInClusterURL: http://grafana:3000
jaegerInClusterURL: http://tracing/jaeger
passphraseKey: passphrase
secretName: kiali
usernameKey: username
viewOnlyMode: false
hub: quay.io/kiali
ingress:
enabled: false
hosts:
- kiali.local
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
security:
cert_file: /kiali-cert/cert-chain.pem
enabled: false
private_key_file: /kiali-cert/key.pem
tag: v1.14
mixer:
adapters:
kubernetesenv:
enabled: true
prometheus:
enabled: true
metricsExpiryDuration: 10m
stackdriver:
auth:
apiKey: ""
appCredentials: false
serviceAccountPath: ""
enabled: false
tracer:
enabled: false
sampleProbability: 1
stdio:
enabled: false
outputAsJson: false
useAdapterCRDs: false
policy:
adapters:
kubernetesenv:
enabled: true
useAdapterCRDs: false
autoscaleEnabled: true
image: mixer
sessionAffinityEnabled: false
telemetry:
autoscaleEnabled: true
env:
GOMAXPROCS: "6"
image: mixer
loadshedding:
latencyThreshold: 100ms
mode: enforce
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
replicaCount: 1
reportBatchMaxEntries: 100
reportBatchMaxTime: 1s
sessionAffinityEnabled: false
tolerations: []
nodeagent:
image: node-agent-k8s
pilot:
appNamespaces: []
autoscaleEnabled: true
autoscaleMax: 5
autoscaleMin: 1
configMap: true
configNamespace: istio-config
cpu:
targetAverageUtilization: 80
enableProtocolSniffingForInbound: false
enableProtocolSniffingForOutbound: true
env: {}
image: pilot
ingress:
ingressClass: istio
ingressControllerMode: STRICT
ingressService: istio-ingressgateway
keepaliveMaxServerConnectionAge: 30m
meshNetworks:
networks: {}
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
policy:
enabled: false
replicaCount: 1
tolerations: []
traceSampling: 1
prometheus:
contextPath: /prometheus
hub: docker.io/prom
ingress:
enabled: false
hosts:
- prometheus.local
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
provisionPrometheusCert: true
retention: 6h
scrapeInterval: 15s
security:
enabled: true
tag: v2.15.1
tolerations: []
security:
dnsCerts:
istio-pilot-service-account.istio-control: istio-pilot.istio-control
enableNamespacesByDefault: true
image: citadel
selfSigned: true
sidecarInjectorWebhook:
enableNamespacesByDefault: false
image: sidecar_injector
injectLabel: istio-injection
objectSelector:
autoInject: true
enabled: false
rewriteAppHTTPProbe: false
selfSigned: false
telemetry:
enabled: true
v1:
enabled: false
v2:
enabled: true
prometheus:
enabled: true
stackdriver:
configOverride: {}
enabled: true
logging: true
monitoring: true
topology: true
tracing:
ingress:
enabled: false
jaeger:
accessMode: ReadWriteMany
hub: docker.io/jaegertracing
memory:
max_traces: 50000
persist: false
spanStorageType: badger
storageClassName: ""
tag: "1.16"
nodeSelector: {}
opencensus:
exporters:
stackdriver:
enable_tracing: true
hub: docker.io/omnition
resources:
limits:
cpu: "1"
memory: 2Gi
requests:
cpu: 200m
memory: 400Mi
tag: 0.1.9
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
provider: jaeger
service:
annotations: {}
externalPort: 9411
name: http-query
type: ClusterIP
zipkin:
hub: docker.io/openzipkin
javaOptsHeap: 700
maxSpans: 500000
node:
cpus: 2
probeStartupDelay: 200
queryPort: 9411
resources:
limits:
cpu: 300m
memory: 900Mi
requests:
cpu: 150m
memory: 900Mi
tag: 2.14.2
version: ""
================================================
FILE: common/install_istio.sh
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#!/bin/bash
# installs standard single-cluster Istio on GKE + the Istio Stackdriver adapter
# Download Istio
WORKDIR="`pwd`"
ISTIO_VERSION="${ISTIO_VERSION:-1.5.2}"
echo "Downloading Istio ${ISTIO_VERSION}..."
curl -L https://git.io/getLatestIstio | ISTIO_VERSION=$ISTIO_VERSION sh -
# Prepare for install
kubectl create namespace istio-system
cd ./istio-${ISTIO_VERSION}/
kubectl create secret generic cacerts -n istio-system \
--from-file=samples/certs/ca-cert.pem \
--from-file=samples/certs/ca-key.pem \
--from-file=samples/certs/root-cert.pem \
--from-file=samples/certs/cert-chain.pem
cd ../
kubectl label namespace default istio-injection=enabled
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)
# install using operator config - https://istio.io/docs/setup/install/istioctl/#customizing-the-configuration
INSTALL_PROFILE=${INSTALL_YAML:-default.yaml}
./istio-${ISTIO_VERSION}/bin/istioctl manifest apply -f ${INSTALL_PROFILE}
================================================
FILE: internal-load-balancer/README.md
================================================
# Demo: Using a GCP Internal Load Balancer with Istio
This demo shows how to use an Internal Load Balancer (ILB) to connect Istio workloads running in Google Kubernetes Engine (GKE) with VM-based workloads in Google Compute Engine (GCE).
**Note**: [ILB for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing) is currently in beta.
## How It Works
An [Internal Load Balancer (ILB)](https://cloud.google.com/load-balancing/docs/internal/) is a Google Cloud Platform (GCP) resource that exposes workloads (in GCE or GKE) to other workloads within the same region, and the same [Virtual Private Cloud](https://cloud.google.com/vpc/) (VPC) network. Using an ILB replaces the need to use a GKE external load balancer with a set of firewall rules.
You can [annotate Kubernetes Services](https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing#overview) directly to provision a GCP ILB, instead of an external network load balancer. However, Istio has its own [ILB Gateway](https://istio.io/docs/reference/config/installation-options/#gateways-options) for exposing Services inside the mesh.
The value of using the Istio ILB Gateway is that it's highly configurable -- you can, for instance, [define granular traffic rules](https://istio.io/docs/tasks/traffic-management/ingress/) to be applied for a specific service exposed via that ILB Gateway. Using an ILB Gateway replaces the need to use an external `Service type=LoadBalancer` with a set of firewall rules.
If Istio's ILB Gateway is enabled on install, it is annotated to provision its own ILB inside your GCP project. Note that a GCP Internal Load Balancer [is not a proxy](https://cloud.google.com/load-balancing/docs/internal/#how_ilb_works), but rather a resource that configures GCE instances directly to talk to "backends" within the same VPC network. In this case, the "backend" of the Istio ILB load balancer will be a GKE Instance Group — or, the set of VMs that comprise the GKE cluster.
In this demo, we will build the following architecture:

## Prerequisites
- A GCP project with billing enabled
- [Helm](https://helm.sh/docs/using_helm/#installing-helm) (CLI) installed on your local machine
## Create a GKE Cluster
1. **Export project ID:**
```
PROJECT_ID=<your-project-id>
```
2. **Create the cluster:**
```
gcloud container clusters create istio-ilb --project $PROJECT_ID --zone us-central1-c \
--machine-type "n1-standard-2" --disk-size "100" \
--num-nodes "4" --network "default" --async
```
3. Wait for the cluster to be `RUNNING`, by executing:
```
gcloud container clusters list --project $PROJECT_ID
```
4. Get credentials:
```
gcloud container clusters get-credentials istio-ilb --zone us-central1-c --project $PROJECT_ID
```
## Install Istio with ILB Gateway Enabled
1. Open the install profile in `manifests/install.yaml`. This is a default install profile with the ILB ingress gateway enabled in addition to the default, publicly-accessible `istio-ingressgateway`. Notice line 104:
```
k8s:
serviceAnnotations:
cloud.google.com/load-balancer-type: "Internal"
```
Here, instead of provisioning this second Istio gateway with a public load balancer, we are telling GKE to instead provision an internal [GCP internal load balancer](https://cloud.google.com/load-balancing/docs/internal). This means that this gateway will only be accessible from inside the GCP virtual private cloud (VPC) - for instance, from a Google Compute Engine instance in the same GCP project.
2. Install Istio on the cluster. Clone this repository and navigate to the root `istio-samples` directory. Then, apply the install profile:
```
cd common/
INSTALL_YAML="../internal-load-balancer/manifests/install.yaml" ./install_istio.sh
```
3. Run `kubectl get pods -n istio-system`. You should see two gateway pods running: `istio-ilbgateway` and `istio-ingressgateway`.
```
NAME READY STATUS RESTARTS
AGE
grafana-556b649566-s2bj2 1/1 Running 0
39s
istio-ilbgateway-7fb4b47dcc-x7zbc 1/1 Running 0
43s
istio-ingressgateway-598796f4d9-gszfx 1/1 Running 0
43s
istio-tracing-7cf5f46848-g47zt 1/1 Running 0
39s
istiod-55fb557b7-ltfxj 1/1 Running 0
58s
kiali-6d54b8ccbc-v26ds 1/1 Running 0
39s
prometheus-5bd4c4679b-dbvsn 2/2 Running 0
38s
```
4. Get the Kubernetes services corresponding to the two Istio Gateways. You should see two gateway services, both with an `EXTERNAL_IP` field. The `istio-ilbgateway` external IP is only "external" to its own VPC. **Note** - it may take several minutes to for the external IP to appear - in the meantime, you will see `<pending>` while the load balancers are provisioned.
```
$ kubectl get service -n istio-system | grep gateway
istio-ilbgateway LoadBalancer 10.0.5.3 10.128.0.9 15011:30940/TCP,15010:32052/TCP,8060:32219/TCP,5353:30527/TCP,80:30694/TCP 19m
istio-ingressgateway LoadBalancer 10.0.2.236 34.70.166.247 15020:30267/TCP,80:32184/TCP,443:30578/TCP,15029:32296/TCP,15030:31735/TCP,15031:32750/TCP,15032:32506/TCP,15443:30743/TCP 19m
```
## Deploy the HelloServer application
HelloServer is a Python HTTP server that serves the `GET / ` endpoint, and prints `HelloWorld`. We'll also deploy a load generator (also Python) that will repeatedly send 10 Requests per Second (RPS) to `helloserver`.
```
cd ../internal-load-balancer/
kubectl apply -f ../sample-apps/helloserver/server/server.yaml
kubectl apply -f ../sample-apps/helloserver/loadgen/loadgen.yaml
```
## Explore the Kiali Dashboard
[Kiali](https://www.kiali.io/) is a web-based Istio dashboard for observing your Istio mesh topology. We installed Kiali already, with the rest of the Istio control plane.
1. Open the Kiali dashboard in a browser.
```
alias istioctl="../common/istio-1.5.2/bin/istioctl"
istioctl dashboard kiali &
```
2. Log in with the demo credentials: `admin/admin`.
3. navigate in the left sidebar to `Graph`, and view the Service Graph for the `default` Kubernetes namespace. This is the namespace into which we've deployed the `helloserver` application.

## Access HelloServer via ILB
Now that we can confirm that in-cluster workloads (like `loadgenerator`) can access `helloserver`, let's access `helloserver` from outside the GKE cluster, via the ILB gateway.
To do this, we'll create a GCE Instance in the same project / VPC. **Note**: we will create this VM in the same region as the GKE cluster. This is a prerequisite for GCP resource communication via ILB. Also notice that `--network=default` means we're creating the GCE VM in the same VPC network as the GKE cluster, which is also using the `default` network.
1. **Create a GCE instance.**
```
gcloud compute --project=$PROJECT_ID instances create gce-ilb --zone=us-central1-c --machine-type=n1-standard-2 --network=default
```
2. **Create a VirtualService and Gateway.**
If we want to send traffic from GCE to GKE, via the Istio ILB Gateway, we will have to expose HelloServer within GCP. This will be the same process as if we were exposing HelloServer to the public internet ([with the IngressGateway](https://istio.io/docs/tasks/traffic-management/ingress/#configuring-ingress-using-an-istio-gateway)). For this, we'll use an Istio `Gateway` resource, along with a `VirtualService`.
```
kubectl apply -f manifests/server-ilb.yaml
```
Because the Istio ILBGateway service is `type=LoadBalancer`, it gets an `EXTERNAL_IP`, but only "external" within our regional VPC network:
3. **Get the EXTERNAL_IP for istio-ilbgateway:**
```
kubectl get svc -n istio-system istio-ilbgateway
```
You should see something like:
```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ilbgateway LoadBalancer 10.67.240.220 10.150.0.7 15011:32390/TCP,15010:32626/TCP,8060:32429/TCP,5353:32066/TCP,80:32624/TCP 39m
```
Copy the `EXTERNAL_IP` to the clipboard.
4. **ssh into the GCE instance:**
```
gcloud compute ssh --project $PROJECT_ID --zone "us-central1-c" gce-ilb
```
5. **Reach helloserver via the ILB gateway IP, at port 80:**
```
export EXTERNAL_IP="<your-external-ip"
curl http://${EXTERNAL_IP}:80
```
You should see:
```
Hello World! /
```
This request just went from your GCE instance, to the Istio ILB Gateway, then to the `hellosvc` Service inside the Istio mesh.
Notice that if you try to execute the same `curl` request on your local machine, you will time out -- this because the ILB Gateway is only exposed from within your GCP project's private VPC network.
Finally, re-open the Kiali service graph in the browser -- now notice how the ilb-gateway is also now serving traffic for `hellosvc`.

🌟 **Well done** - you just exposed a GKE service via Istio's ILB Gateway!
## Cleanup
1. **Delete the GCE VM**:
```
gcloud compute --project=$PROJECT_ID instances delete gce-ilb --zone=us-central1-c --async
```
2. **Delete the GKE Cluster**:
```
gcloud container clusters delete istio-ilb --project $PROJECT_ID --zone us-central1-c --async
```
================================================
FILE: internal-load-balancer/manifests/install.yaml
================================================
# ILB config source - https://github.com/istio/istio/issues/20033
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
addonComponents:
grafana:
enabled: true
k8s:
replicaCount: 1
istiocoredns:
enabled: false
kiali:
enabled: true
k8s:
replicaCount: 1
prometheus:
enabled: true
k8s:
replicaCount: 1
tracing:
enabled: true
components:
base:
enabled: true
citadel:
enabled: false
k8s:
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
cni:
enabled: false
egressGateways:
- enabled: false
k8s:
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-ingressgateway
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
name: istio-egressgateway
galley:
enabled: false
k8s:
replicaCount: 1
resources:
requests:
cpu: 100m
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
ingressGateways:
- name: istio-ingressgateway
enabled: true
k8s:
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-ingressgateway
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
- name: istio-ilbgateway
enabled: true
k8s:
serviceAnnotations:
cloud.google.com/load-balancer-type: "Internal"
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-ilbgateway
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
service:
ports:
- name: grpc-pilot-mtls
port: 15011
- name: grpc-pilot
port: 15010
- name: tcp-citadel-grpc-tls
port: 8060
targetPort: 8060
- name: tcp-dns
port: 5353
- name: http
port: 80
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
overlays:
- kind: HorizontalPodAutoscaler
name: istio-ilbgateway
patches:
- path: metadata.labels.app
value: istio-ilbgateway
- path: metadata.labels.istio
value: ilbgateway
- path: spec.scaleTargetRef.name
value: istio-ilbgateway
- kind: Deployment
name: istio-ilbgateway
patches:
- path: metadata.labels.app
value: istio-ilbgateway
- path: metadata.labels.istio
value: ilbgateway
- path: spec.selector.matchLabels.app
value: istio-ilbgateway
- path: spec.selector.matchLabels.istio
value: ilbgateway
- path: spec.template.metadata.labels.app
value: istio-ilbgateway
- path: spec.template.metadata.labels.istio
value: ilbgateway
- kind: Service
name: istio-ilbgateway
patches:
- path: metadata.labels.app
value: istio-ilbgateway
- path: metadata.labels.istio
value: ilbgateway
- path: spec.selector.app
value: istio-ilbgateway
- path: spec.selector.istio
value: ilbgateway
nodeAgent:
enabled: false
pilot:
enabled: true
k8s:
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 5
resources:
requests:
cpu: 500m
memory: 2048Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
policy:
enabled: false
k8s:
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-policy
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
sidecarInjector:
enabled: false
k8s:
replicaCount: 1
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
telemetry:
enabled: false
k8s:
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: GOMAXPROCS
value: "6"
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-telemetry
replicaCount: 1
resources:
limits:
cpu: 4800m
memory: 4G
requests:
cpu: 1000m
memory: 1G
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
hub: docker.io/istio
tag: 1.5.1
values:
clusterResources: true
galley:
enableAnalysis: false
image: galley
gateways:
istio-egressgateway:
autoscaleEnabled: true
env:
ISTIO_META_ROUTER_MODE: sni-dnat
ports:
- name: http2
port: 80
- name: https
port: 443
- name: tls
port: 15443
targetPort: 15443
secretVolumes:
- mountPath: /etc/istio/egressgateway-certs
name: egressgateway-certs
secretName: istio-egressgateway-certs
- mountPath: /etc/istio/egressgateway-ca-certs
name: egressgateway-ca-certs
secretName: istio-egressgateway-ca-certs
type: ClusterIP
istio-ingressgateway:
applicationPorts: ""
autoscaleEnabled: true
debug: info
domain: ""
env:
ISTIO_META_ROUTER_MODE: sni-dnat
meshExpansionPorts:
- name: tcp-pilot-grpc-tls
port: 15011
targetPort: 15011
- name: tcp-citadel-grpc-tls
port: 8060
targetPort: 8060
- name: tcp-dns-tls
port: 853
targetPort: 853
ports:
- name: status-port
port: 15020
targetPort: 15020
- name: http2
port: 80
targetPort: 80
- name: https
port: 443
- name: kiali
port: 15029
targetPort: 15029
- name: prometheus
port: 15030
targetPort: 15030
- name: grafana
port: 15031
targetPort: 15031
- name: tracing
port: 15032
targetPort: 15032
- name: tls
port: 15443
targetPort: 15443
sds:
enabled: false
image: node-agent-k8s
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
secretVolumes:
- mountPath: /etc/istio/ingressgateway-certs
name: ingressgateway-certs
secretName: istio-ingressgateway-certs
- mountPath: /etc/istio/ingressgateway-ca-certs
name: ingressgateway-ca-certs
secretName: istio-ingressgateway-ca-certs
type: LoadBalancer
zvpn:
enabled: false
suffix: global
global:
arch:
amd64: 2
ppc64le: 2
s390x: 2
certificates: []
configValidation: true
controlPlaneSecurityEnabled: true
defaultNodeSelector: {}
defaultPodDisruptionBudget:
enabled: true
defaultResources:
requests:
cpu: 10m
disablePolicyChecks: true
enableHelmTest: false
enableTracing: true
imagePullPolicy: IfNotPresent
imagePullSecrets: []
istioNamespace: istio-system
istiod:
enabled: true
jwtPolicy: third-party-jwt
k8sIngress:
enableHttps: false
enabled: false
gatewayName: ingressgateway
localityLbSetting:
enabled: true
logAsJson: false
logging:
level: default:info
meshExpansion:
enabled: false
useILB: false
meshNetworks: {}
mountMtlsCerts: false
mtls:
auto: true
enabled: false
multiCluster:
clusterName: ""
enabled: false
network: ""
omitSidecarInjectorConfigMap: false
oneNamespace: false
operatorManageWebhooks: false
outboundTrafficPolicy:
mode: ALLOW_ANY
pilotCertProvider: istiod
policyCheckFailOpen: false
priorityClassName: ""
proxy:
accessLogEncoding: TEXT
accessLogFile: "/dev/stdout"
accessLogFormat: ""
autoInject: enabled
clusterDomain: cluster.local
componentLogLevel: misc:error
concurrency: 2
dnsRefreshRate: 300s
enableCoreDump: false
envoyAccessLogService:
enabled: false
envoyMetricsService:
enabled: false
tcpKeepalive:
interval: 10s
probes: 3
time: 10s
tlsSettings:
mode: DISABLE
subjectAltNames: []
envoyStatsd:
enabled: false
excludeIPRanges: ""
excludeInboundPorts: ""
excludeOutboundPorts: ""
image: proxyv2
includeIPRanges: '*'
includeInboundPorts: '*'
kubevirtInterfaces: ""
logLevel: warning
privileged: false
protocolDetectionTimeout: 100ms
readinessFailureThreshold: 30
readinessInitialDelaySeconds: 1
readinessPeriodSeconds: 2
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
statusPort: 15020
tracer: zipkin
proxy_init:
image: proxyv2
resources:
limits:
cpu: 100m
memory: 50Mi
requests:
cpu: 10m
memory: 10Mi
sds:
enabled: false
token:
aud: istio-ca
udsPath: ""
sts:
servicePort: 0
tracer:
datadog:
address: $(HOST_IP):8126
lightstep:
accessToken: ""
address: ""
cacertPath: ""
secure: true
stackdriver:
debug: false
maxNumberOfAnnotations: 200
maxNumberOfAttributes: 200
maxNumberOfMessageEvents: 200
zipkin:
address: ""
trustDomain: cluster.local
useMCP: false
grafana:
accessMode: ReadWriteMany
contextPath: /grafana
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- disableDeletion: false
folder: istio
name: istio
options:
path: /var/lib/grafana/dashboards/istio
orgId: 1
type: file
datasources:
datasources.yaml:
apiVersion: 1
env: {}
envSecrets: {}
image:
repository: grafana/grafana
tag: 6.5.2
ingress:
enabled: false
hosts:
- grafana.local
nodeSelector: {}
persist: false
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
security:
enabled: false
passphraseKey: passphrase
secretName: grafana
usernameKey: username
service:
annotations: {}
externalPort: 3000
name: http
type: ClusterIP
storageClassName: ""
tolerations: []
istiocoredns:
coreDNSImage: coredns/coredns
coreDNSPluginImage: istio/coredns-plugin:0.2-istio-1.1
coreDNSTag: 1.6.2
kiali:
contextPath: /kiali
createDemoSecret: true
dashboard:
grafanaInClusterURL: http://grafana:3000
jaegerInClusterURL: http://tracing/jaeger
passphraseKey: passphrase
secretName: kiali
usernameKey: username
viewOnlyMode: false
hub: quay.io/kiali
ingress:
enabled: false
hosts:
- kiali.local
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
security:
cert_file: /kiali-cert/cert-chain.pem
enabled: false
private_key_file: /kiali-cert/key.pem
tag: v1.14
mixer:
adapters:
kubernetesenv:
enabled: true
prometheus:
enabled: true
metricsExpiryDuration: 10m
stackdriver:
auth:
apiKey: ""
appCredentials: false
serviceAccountPath: ""
enabled: false
tracer:
enabled: false
sampleProbability: 1
stdio:
enabled: false
outputAsJson: false
useAdapterCRDs: false
policy:
adapters:
kubernetesenv:
enabled: true
useAdapterCRDs: false
autoscaleEnabled: true
image: mixer
sessionAffinityEnabled: false
telemetry:
autoscaleEnabled: true
env:
GOMAXPROCS: "6"
image: mixer
loadshedding:
latencyThreshold: 100ms
mode: enforce
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
replicaCount: 1
reportBatchMaxEntries: 100
reportBatchMaxTime: 1s
sessionAffinityEnabled: false
tolerations: []
nodeagent:
image: node-agent-k8s
pilot:
appNamespaces: []
autoscaleEnabled: true
autoscaleMax: 5
autoscaleMin: 1
configMap: true
configNamespace: istio-config
cpu:
targetAverageUtilization: 80
enableProtocolSniffingForInbound: false
enableProtocolSniffingForOutbound: true
env: {}
image: pilot
ingress:
ingressClass: istio
ingressControllerMode: STRICT
ingressService: istio-ingressgateway
keepaliveMaxServerConnectionAge: 30m
meshNetworks:
networks: {}
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
policy:
enabled: false
replicaCount: 1
tolerations: []
traceSampling: 1
prometheus:
contextPath: /prometheus
hub: docker.io/prom
ingress:
enabled: false
hosts:
- prometheus.local
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
provisionPrometheusCert: true
retention: 6h
scrapeInterval: 15s
security:
enabled: true
tag: v2.15.1
tolerations: []
security:
dnsCerts:
istio-pilot-service-account.istio-control: istio-pilot.istio-control
enableNamespacesByDefault: true
image: citadel
selfSigned: true
sidecarInjectorWebhook:
enableNamespacesByDefault: false
image: sidecar_injector
injectLabel: istio-injection
objectSelector:
autoInject: true
enabled: false
rewriteAppHTTPProbe: false
selfSigned: false
telemetry:
enabled: true
v1:
enabled: false
v2:
enabled: true
prometheus:
enabled: true
stackdriver:
configOverride: {}
enabled: true
logging: true
monitoring: true
topology: true
tracing:
ingress:
enabled: false
jaeger:
accessMode: ReadWriteMany
hub: docker.io/jaegertracing
memory:
max_traces: 50000
persist: false
spanStorageType: badger
storageClassName: ""
tag: "1.16"
nodeSelector: {}
opencensus:
exporters:
stackdriver:
enable_tracing: true
hub: docker.io/omnition
resources:
limits:
cpu: "1"
memory: 2Gi
requests:
cpu: 200m
memory: 400Mi
tag: 0.1.9
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
provider: jaeger
service:
annotations: {}
externalPort: 9411
name: http-query
type: ClusterIP
zipkin:
hub: docker.io/openzipkin
javaOptsHeap: 700
maxSpans: 500000
node:
cpus: 2
probeStartupDelay: 200
queryPort: 9411
resources:
limits:
cpu: 300m
memory: 900Mi
requests:
cpu: 150m
memory: 900Mi
tag: 2.14.2
version: ""
================================================
FILE: internal-load-balancer/manifests/server-ilb.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_internal_load_balancer_manifests_gateway_hello_ilb_gateway]
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: hello-ilb-gateway
spec:
selector:
istio: ilbgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
# [END istio_internal_load_balancer_manifests_gateway_hello_ilb_gateway]
---
# [START istio_internal_load_balancer_manifests_virtualservice_hellosvc_vs]
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: hellosvc-vs
spec:
gateways:
- hello-ilb-gateway
hosts:
- '*'
http:
- route:
- destination:
host: hellosvc
port:
number: 80
# [END istio_internal_load_balancer_manifests_virtualservice_hellosvc_vs]
---
================================================
FILE: istio-canary-gke/README.md
================================================
# ProductCatalog Canary Deployment (GKE / Istio)
This demo accompanies [a GCP Blog Post](https://cloud.google.com/blog/products/networking/advanced-application-deployments-and-traffic-management-with-istio-on-gke) on managing application deployments with Istio and
Stackdriver.
## Introduction
In this example, we will learn how to use [Istio’s](https://istio.io/) [Traffic Splitting](https://istio.io/docs/concepts/traffic-management/#splitting-traffic-between-versions) feature to perform a Canary deployment on [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/).
In this sample, `productcatalogservice-v2` introduces a 3-second
[latency](https://github.com/GoogleCloudPlatform/microservices-demo/tree/master/src/productcatalogservice#latency-injection) into all server requests. We’ll show how to use Stackdriver and Istio together to
view the latency difference between the existing `productcatalog` deployment and the
slower v2 deployment.
- [Setup](#setup)
- [Deploy the Sample App](#deploy-the-sample-app)
- [Deploy ProductCatalog v2](#deploy-productcatalog-v2)
- [Observe Latency with Stackdriver](#observe-latency-with-stackdriver)
- [Rollback](#rollback)
- [Cleanup](#cleanup)
- [Learn More](#learn-more)
## Setup
[Google Cloud Shell](https://cloud.google.com/shell/docs/) is a browser-based terminal that Google provides to interact with your GCP resources. It is backed by a free Compute Engine instance that comes with many useful tools already installed, including everything required to run this demo.
Click the button below to open the demo instructions in your Cloud Shell:
[](https://console.cloud.google.com/cloudshell/open?git_repo=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fistio-samples&page=editor&tutorial=istio-canary-gke/README.md)
## Create a GKE Cluster
1. From Cloud Shell, enable the Kubernetes Engine API.
```
gcloud services enable container.googleapis.com
```
2. Create a GKE cluster:
```
gcloud beta container clusters create istio-canary \
--zone=us-central1-f \
--machine-type=n1-standard-2 \
--num-nodes=4
```
3. Change into the Istio install directory from the root of this repository.
```
cd common/
```
4. Install Istio on the cluster:
```
./install_istio.sh
```
5. Once the cluster is ready, ensure that Istio is running:
```
$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
grafana-556b649566-fw67z 1/1 Running 0 5m24s
istio-ingressgateway-fc6c9d9df-nmndg 1/1 Running 0 5m30s
istio-tracing-7cf5f46848-qksxq 1/1 Running 0 5m24s
istiod-7b5d6db6b6-b457p 1/1 Running 0 5m48s
kiali-b4b5b4fb8-hwm42 1/1 Running 0 5m23s
prometheus-558b665bb7-5v647 2/2 Running 0 5m23s
```
## Deploy the Sample App
1. Deploy the [microservices-demo](https://github.com/GoogleCloudPlatform/microservices-demo) application, and add a `version=v1` label to the `productcatalog` deployment
```
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/kubernetes-manifests.yaml
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/istio-manifests.yaml
kubectl delete serviceentry allow-egress-google-metadata
kubectl delete serviceentry allow-egress-googleapis
kubectl patch deployments/productcatalogservice -p '{"spec":{"template":{"metadata":{"labels":{"version":"v1"}}}}}'
```
2. Using `kubectl get pods`, verify that all pods are `Running` and `Ready`.
At this point, ProductCatalog v1 is deployed to the cluster, along with the rest of the
demo microservices. You can reach the Hipstershop frontend at the `EXTERNAL_IP` address
output for this command:
```
kubectl get svc -n istio-system istio-ingressgateway
```
## Deploy ProductCatalog v2
1. `cd` into the example directory.
```
cd istio-canary-gke/
```
2. Create an Istio [DestinationRule](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#DestinationRule) for `productcatalogservice`.
```
kubectl apply -f canary/destinationrule.yaml
```
3. Deploy `productcatalog` v2.
```
kubectl apply -f canary/productcatalog-v2.yaml
```
4. Using `kubectl get pods`, verify that the `v2` pod is Running.
```
productcatalogservice-v2-79459dfdff-6qdh4 2/2 Running 0 1m
```
5. Create an Istio [VirtualService](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#VirtualService) to split incoming `productcatalog` traffic between v1 (75%) and v2 (25%).
```
kubectl apply -f canary/vs-split-traffic.yaml
```
6. In a web browser, navigate again to the hipstershop frontend.
7. Refresh the homepage a few times. You should notice that periodically, the frontend is
slower to load. Let's explore ProductCatalog's latency with Stackdriver.
## View traffic splitting in Kiali
1. Open the Kiali dashboard.
```
istioctl dashboard kiali &
```
2. Navigate to Service Graph > namespace: `default`
3. Select "Versioned App Graph."
4. In the service graph, zoom in on `productcatalogservice`. You should see that approximately 25% of productcatalog requests are going to `v2`.

## Observe Latency with Stackdriver
1. Navigate to [Stackdriver Monitoring](https://app.google.stackdriver.com).
2. Create a Stackdriver Workspace for your GCP project
([instructions](https://cloud.google.com/monitoring/workspaces/guide#single-project-ws)).
3. From your new Stackdriver Workspace, navigate to **Resources > Metrics Explorer.** in the
left sidebar.

4. From Metrics Explorer, enter the following parameters on the left side of the window:
- **Resource type**: Kubernetes Container
- **Metric**: Server Response Latencies (`istio.io/service/server/response_latencies`)
- **Group by**: `destination_workload_name`
- **Aggregator**: 50th percentile
5. In the menubar of the chart on the right, choose the **Line** type.
6. Once the latency chart renders, you should see `productcatalog-v2` as an outlier, with
mean latencies hovering at 3 seconds. This is the value of `EXTRA_LATENCY` we injected into v2.

You’ll also notice that other services (such as `frontend`) have an irregular latency spike. This is because the [frontend relies on](https://github.com/GoogleCloudPlatform/microservices-demo#service-architecture) ProductCatalog, for which 25% of requests are routing through the slower `v2` deployment.

## Rollback
1. Return 100% of `productcatalog` traffic to `v1`:
```
kubectl apply -f canary/rollback.yaml
```
2. Finally, remove `v2`:
```
kubectl delete -f canary/productcatalog-v2.yaml
```
## Cleanup
To avoid incurring additional billing costs, delete the GKE cluster.
```
gcloud container clusters delete istio-canary --zone us-central1-f
```
## Learn More
- [Incremental Istio Part 1, Traffic
Management](https://istio.io/blog/2018/incremental-traffic-management/) (Istio blog)
- [Canary Deployments using Istio](https://istio.io/blog/2017/0.1-canary/) (Istio blog)
- [Drilling down into Stackdriver Service
Monitoring](https://cloud.google.com/blog/products/gcp/drilling-down-into-stackdriver-service-monitoring)
(GCP blog)
================================================
FILE: istio-canary-gke/canary/destinationrule.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_istio_canary_gke_canary_destinationrule_productcatalogservice]
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productcatalogservice
spec:
host: productcatalogservice
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
# [END istio_istio_canary_gke_canary_destinationrule_productcatalogservice]
---
================================================
FILE: istio-canary-gke/canary/productcatalog-v2.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_istio_canary_gke_canary_deployment_productcatalogservice_v2]
apiVersion: apps/v1
kind: Deployment
metadata:
name: productcatalogservice-v2
spec:
selector:
matchLabels:
app: productcatalogservice
template:
metadata:
labels:
app: productcatalogservice
version: v2
spec:
containers:
- env:
- name: PORT
value: '3550'
- name: EXTRA_LATENCY
value: 3s
image: gcr.io/google-samples/microservices-demo/productcatalogservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:3550
name: server
ports:
- containerPort: 3550
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:3550
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
terminationGracePeriodSeconds: 5
# [END istio_istio_canary_gke_canary_deployment_productcatalogservice_v2]
---
================================================
FILE: istio-canary-gke/canary/rollback.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_istio_canary_gke_canary_virtualservice_productcatalogservice]
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productcatalogservice
spec:
hosts:
- productcatalogservice
http:
- route:
- destination:
host: productcatalogservice
subset: v1
# [END istio_istio_canary_gke_canary_virtualservice_productcatalogservice]
---
================================================
FILE: istio-canary-gke/canary/vs-split-traffic.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_istio_canary_gke_canary_virtualservice_productcatalogservice2]
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productcatalogservice
spec:
hosts:
- productcatalogservice
http:
- route:
- destination:
host: productcatalogservice
subset: v1
weight: 75
- destination:
host: productcatalogservice
subset: v2
weight: 25
# [END istio_istio_canary_gke_canary_virtualservice_productcatalogservice2]
---
================================================
FILE: istio-stackdriver/README.md
================================================
# Istio and Stackdriver
This example demonstrates the ways you can use [Stackdriver](https://cloud.google.com/stackdriver/) to gain insights into and debug microservices deployments running on GKE with [Istio's telemetry support](https://istio.io/docs/concepts/policies-and-telemetry/).
We'll deploy the Hipstershop sample application along with an updated service that introduces a 3-second latency into all requests. Then we'll create Stackdriver Monitoring dashboards to dig into key metrics like cluster and service health. Next, we'll use Stackdriver Trace to identify high latency requests. Finally, we'll dig into service output using Stackdriver Logging.
### Contents
- [Istio and Stackdriver](#istio-and-stackdriver)
- [Contents](#contents)
- [Setup](#setup)
- [Create a GKE cluster](#create-a-gke-cluster)
- [Deploy the sample application](#deploy-the-sample-application)
- [Deploy a high latency service](#deploy-a-high-latency-service)
- [Monitoring](#monitoring)
- [Create a monitoring dashboard](#create-a-monitoring-dashboard)
- [Examine service and cluster health](#examine-service-and-cluster-health)
- [Tracing](#tracing)
- [Review trace output](#review-trace-output)
- [Identify high latency requests](#identify-high-latency-requests)
- [Logging](#logging)
- [Examine service logs](#examine-service-logs)
- [Cleanup](#cleanup)
- [Learn more](#learn-more)
## Setup
1. Clone the repo and change into the demo directory.
```
git clone https://github.com/GoogleCloudPlatform/istio-samples
cd istio-samples/common
```
### Create a GKE cluster
1. From Cloud Shell, **enable the Kubernetes Engine API**.
```
gcloud services enable container.googleapis.com
```
2. **Create a GKE cluster** using [Istio on GKE](https://cloud.google.com/istio/docs/istio-on-gke/overview). This add-on will provision your GKE cluster with Istio.
```
gcloud beta container clusters create istio-stackdriver-demo \
--zone=us-central1-f \
--machine-type=n1-standard-2 \
--num-nodes=4
```
3. **Install Istio** on the cluster.
```
./install_istio.sh
```
4. Wait for all Istio pods to be `Running` or `Completed`.
```
kubectl get pods -n istio-system
```
*Note*: This Istio installation uses the default `PERMISSIVE` [mesh-wide security
option](https://istio.io/docs/reference/config/installation-options/#global-options).
This means that all services in the cluster will send unencrypted traffic by default.
### Deploy the sample application
1. Apply the sample app manifests to the cluster:
```
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/kubernetes-manifests.yaml
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/istio-manifests.yaml
kubectl patch deployments/productcatalogservice -p '{"spec":{"template":{"metadata":{"labels":{"version":"v1"}}}}}'
```
2. Run `kubectl get pods -n default` to ensure that all pods are `Running` and `Ready`.
```
NAME READY STATUS RESTARTS AGE
adservice-76b5c7bd6b-zsqb8 2/2 Running 0 1m
checkoutservice-86f5c7679c-8ghs8 2/2 Running 0 1m
currencyservice-5749fd7c6d-lv6hj 2/2 Running 0 1m
emailservice-6674bf75c5-qtnd8 2/2 Running 0 1m
frontend-56fdfb866c-tvdm6 2/2 Running 0 1m
loadgenerator-b64fcb8bc-m6nd2 2/2 Running 0 1m
paymentservice-67c6696c54-tgnc5 2/2 Running 0 1m
productcatalogservice-76c6454c57-9zj2v 2/2 Running 0 1m
recommendationservice-78c7676bfb-xqtp6 2/2 Running 0 1m
shippingservice-7bc4bc75bb-kzfrb 2/2 Running 0 1m
```
*Note*: Each pod has 2 containers, because each pod now has the injected Istio sidecar proxy.
### Deploy a high latency service
1. Create an Istio [DestinationRule](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#DestinationRule) for `productcatalogservice`.
```
cd ../istio-canary-gke/
kubectl apply -f canary/destinationrule.yaml
```
2. Deploy `productcatalogservice` v2 which introduces a 3-second latency into all server requests.
```
kubectl apply -f canary/productcatalog-v2.yaml
```
3. Using `kubectl get pods`, verify that the `v2` pod is Running.
```
productcatalogservice-v2-79459dfdff-6qdh4 2/2 Running 0 1m
```
4. Create an Istio VirtualService to split incoming `productcatalogservice` traffic between v1 (75%) and v2 (25%).
```
kubectl apply -f canary/vs-split-traffic.yaml
```
## Monitoring
Now that we've deployed Hipstershop, along with an updated service that introduces higher latency to server requests, let's dig into how we can surface that latency via monitoring. Hipstershop includes a built-in load generator that issues requests across a number of services so after a few minutes you should start to see traffic hitting the deplyoment. The following steps will show you how to create a basic dashboard that let's you monitor some metrics for service and cluster health.
### Create a monitoring dashboard
1. Head over to [Stackdriver Monitoring](https://app.google.stackdriver.com/) and [create a Stackdriver Workspace](https://cloud.google.com/monitoring/workspaces/guide#single-project-ws).
2. Navigate to **Dashboards > Create Dashboard** in the left sidebar.
3. In the new Dashboard, click **Add Chart** and the following metric:
* **Metric**: Server Response Latencies (`istio.io/service/server/response_latencies`)
* **Group By**: `destination_workload_name`
* **Aligner**: 50th percentile
* **Reducer**: mean
* **Alignment Period**: 1 minute
* **Type**: Line
4. Click **Save Chart** in the upper right corner and repeat the process by adding new charts for each of the following metrics:
**Client Roundtrip Latencies**
* **Metric**: Client Roundtrip Latencies (`istio.io/service/client/roundtrip_latencies`)
* **Group By**: `destination_workload_name`
* **Aligner**: 50th percentile
* **Reducer**: mean
* **Alignment Period**: 1 minute
* **Type**: Line
**CPU Utilization**
* **Metric**: CPU Utilization (`compute.googleapis.com/instance/cpu/utilization`)
* **Resource Type**: GCE VM Instance
* **Filter**: `goog-gke-node` = ""
* **Aligner**: mean
* **Reducer**: none
* **Alignment Period**: 1 minute
* **Type**: Line
**Memory Usage**
* **Metric**: Memory Usage (`kubernetes.io/node/memory/used_bytes`)
* **Group By**: `node_name`
* **Aligner**: mean
* **Reducer**: mean
* **Alignment Period**: 1 minute
* **Type**: Line
5. After the metrics have been added, you will have a Dashboard that looks similar to the following:

### Examine service and cluster health
1. Now that you have a functioning Dashboard and some load has been generated, take a look at **Server Response Latencies** and **Client Roundtrip Latencies** charts. You will see there are some clear outliers, specifically the `productcatalog` service. You will also see other related services (such as `frontend`) also have latency spikes. This is because the [frontend relies on](https://github.com/GoogleCloudPlatform/microservices-demo#service-architecture) ProductCatalog, for which 25% of requests are routing through the slower `v2` deployment.

Also take a look at the **CPU Utilization** and **Memory Usage** charts and you'll notice that there are no significant outliers there. As expected, the issue isn't with the GKE cluster itself, it's due to the fact that we specifically deployed a service that introduced a 3-second per request latency.
## Tracing
Now that the high latency service (`productcatalogservice`) has been identified, we can use [Stackdriver Trace](https://cloud.google.com/trace/) to dig in and examine the latency impact it's having across the entire deployment.
### Review trace output
1. Open [Stackdriver Trace](https://console.cloud.google.com/traces) and you will see the tracing overview.
The left side of the **Overview** contains
* **Recent traces** captured
* **Most frequent URIs** requested
* **Most frequent RPCs** called
And on the right you'll see automated analysis reports. These reports are generated by the system and correspond to some of the recent and/or high frequency requests/calls.

2. From the left navigation, head over to the **Trace List** and you'll see a chart of all requests plotted against latency along with a table of the most recent 1000 traces.

### Identify high latency requests
1. From the **Trace List** chat, select a high latency outlier and you'll see a **Timeline** and **Summary** appear below.

2. The timeline shows an initial request and the subsequent requests it generated. In the example below, you can see that requesting the URL `/product/L9ECAV7KIM` took about 12.1s, primarily due to the subsequent requests to the `productcatalogservice` (which has an extra 3s of latency added to each request).

3. The **Summary** table to the right aggregates all of the outbound RPC requests and their total duration, along with additional metadata about the initial request itself.

## Logging
At this point, we've been able to
- Identify a high latency service `productcatalogservice` using Stackdriver Monitoring
- Examine the impact that service is having by digging through request traces using Stackdriver Trace
The final step is to look at the logs generated by our services to see if there's any additional debug information we can capture. Using [Stackdriver Logging](https://cloud.google.com/logging/) we can examine individual service logs from our deployment.
### Examine service logs
1. Open [Stackdriver Logging](https://console.cloud.google.com/logs/viewer) and you'll see the logs viewer.

2. Using the **Filter** field and controls, you can select which logs you want to view. In the example below we used the following filter:
- **Resource**: Kubernetes Container
- **Cluster Name**: istio-stackdriver-demo
- **Namespace**: default
- **Container Name**: server

*Note*: In our example, we manually injected the latency into `productcatalogservice-v2` so these example logs won't be of much help.
## Cleanup
Once you're all done, delete the GKE cluster:
```
gcloud container clusters delete istio-stackdriver-demo
```
## Learn more
- [Istio Policies and Telemetry](https://istio.io/docs/concepts/policies-and-telemetry/)
- [Istio In-Depth Telemetry](https://istio.io/docs/examples/telemetry/)
- [Drilling down into Stackdriver Service Monitoring](https://cloud.google.com/blog/products/gcp/drilling-down-into-stackdriver-service-monitoring) (GCP blog)
================================================
FILE: mesh-expansion-gce/README.md
================================================
# Demo: Integrating a Google Compute Engine VM with Istio
This demo shows how to connect a Google Compute Engine virtual machine to an Istio service
mesh running in Google Kubernetes Engine.
This example is relevant if you're running an application outside
of Kubernetes, but still want to enjoy the full benefits of Istio for that service.
We will use the [Hipstershop](https://github.com/GoogleCloudPlatform/microservices-demo) sample app for this demo, with the following topology:

Here, the `productcatalog` service will be our "monolith" running in a VM outside of
Kubernetes. For demonstration purposes, we'll run productcatalog in a raw Docker container
inside the VM, then integrate it with the rest of the in-mesh services running in GKE.
## Prerequisites
- A GCP project with billing enabled
- gcloud
- kubectl
## GCP Setup
For this demo, the GCE VM and the GKE cluster will live in the same GCP project. Set an
environment variable for your project ID.
```
export PROJECT_ID=<your-project-id>
```
## Create a GKE Cluster
Create a 4-node GKE cluster named `mesh-exp-gke`:
```
./scripts/1-create-cluster.sh
```
Wait for the GKE cluster to be `RUNNING` -
```
gcloud container clusters list
```
Connect to the cluster:
```
gcloud container clusters get-credentials mesh-exp-gke --zone us-central1-b --project $PROJECT_ID
```
## Create a GCE Instance
This script will create a Ubuntu GCE instance in your GCP Project. The VM is named `istio-gce`.
```
./scripts/2-create-vm.sh
```
## Install Istio on the cluster
```
./scripts/3-install-istio.sh
```
## Deploy the rest of the sample application to GKE
This step deploys all the services expect `productcatalog` to the GKE cluster, in the Istio-injected `default` namespace.
```
./scripts/4-deploy-hipstershop.sh
```
## Prepare the cluster for the VM.
```
./scripts/5-prep-cluster.sh
```
This step generates a cluster.env file containing the Istio service CIDR (pod IP ranges for your cluster) and the inbound ports - since productcatalog will listen on grpc port `3550` on the VM, we specify port `3550` for the VM proxy to intercept.
This step also creates client certificate files that we'll send to the VM. In the end, your `cluster.env` file should look like this:
```
ISTIO_SERVICE_CIDR=10.87.0.0/20
ISTIO_INBOUND_PORTS=3550,8080
```
## Set up the VM for Istio.
```
./scripts/6-prep-vm.sh
```
This script does the following:
- Sends the certs and `cluster.env` file we just created to the VM, via `scp`
- Logs into the VM via `ssh`
- From the VM, installs the Istio sidecar proxy and updates `/etc/hosts` so that the VM can reach istiod running on the GKE cluster
- Installs Docker
- Runs the `productcatalogservice` on the VM, as a plain Docker container
## Add productcatalog to the mesh
```
./scripts/7-add-to-mesh.sh
```
This step uses the `istioctl add-to-mesh` command to generate a ServiceEntry and headless Service corresponding to the VM `productcatalogservice`. This allows the frontend running as a GKE pod to resolve the `productcatalogservice` DNS to the GCE VM, via Istio.
## Start the Istio proxy on the VM
```
./scripts/8-start-vm-istio.sh
```
## View the service topology
```
alias istioctl="../common/istio-1.5.2/bin/istioctl"
istioctl dashboard kiali &
```
Open Service Graph > click the "default" namespace. You should see traffic moving to the `meshexpansion-productcatalogservice` ServiceEntry, corresponding to the VM.

## Open the frontend in a browser
Get the external IP address of the Istio ingressgateway. Navigate to that IP address in a web browser.
```
kubectl get svc -n istio-system istio-ingressgateway | awk '{print $4}'
```
You should see the sample app frontend with a list of products, fetched from `productcatalog` running on the VM.

## Clean up
To delete the resources used in this sample:
```
gcloud compute firewall-rules delete k8s-to-istio-gce
gcloud compute instances --project $PROJECT_ID delete --zone "us-central1-b" "istio-gce"
gcloud container clusters delete mesh-exp-gke --zone us-central1-b --async
```
## Learn more
Learn about each step of the VM install in the [Istio documentation](https://istio.io/docs/examples/virtual-machines/single-network/#preparing-the-kubernetes-cluster-for-vms).
Learn [how to set up a proxy-injected VM in another network](https://istio.io/docs/examples/virtual-machines/multi-network/).
================================================
FILE: mesh-expansion-gce/scripts/1-create-cluster.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
log() { echo "$1" >&2; }
# set vars
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified}"
ZONE="us-central1-b"
CLUSTER_NAME="mesh-exp-gke"
CTX="gke_${PROJECT_ID}_${ZONE}_${CLUSTER_NAME}"
# Create GKE Cluster
gcloud config set project $PROJECT_ID
gcloud container clusters create $CLUSTER_NAME --zone $ZONE --username "admin" \
--machine-type "n1-standard-2" \
--num-nodes "4" --network "default" --enable-stackdriver-kubernetes --enable-ip-alias --async
================================================
FILE: mesh-expansion-gce/scripts/2-create-vm.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
log() { echo "$1" >&2; }
# set vars
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified}"
gcloud config set project $PROJECT_ID
ZONE="us-central1-b"
CLUSTER_NAME="mesh-exp-gke"
CTX="gke_${PROJECT_ID}_${ZONE}_${CLUSTER_NAME}"
GCE_INSTANCE_NAME="istio-gce"
# allow traffic from K8s cluster to VM service
export K8S_POD_CIDR=$(gcloud container clusters describe ${CLUSTER_NAME?} --zone ${ZONE?} --format=json | jq -r '.clusterIpv4Cidr')
gcloud compute firewall-rules create k8s-to-istio-gce \
--description="Allow k8s pods CIDR to istio-gce instance" \
--source-ranges=$K8S_POD_CIDR \
--target-tags=${GCE_INSTANCE_NAME} \
--action=ALLOW \
--rules=tcp:3550
# Create GCE VM
gcloud config set project $PROJECT_ID
gcloud compute --project=$PROJECT_ID instances create $GCE_INSTANCE_NAME --zone=$ZONE \
--machine-type=n1-standard-2 --subnet=default --network-tier=PREMIUM --maintenance-policy=MIGRATE \
--image=ubuntu-1604-xenial-v20190628 --image-project=ubuntu-os-cloud --boot-disk-size=10GB \
--boot-disk-type=pd-standard --boot-disk-device-name=$GCE_INSTANCE_NAME --tags=${GCE_INSTANCE_NAME}
================================================
FILE: mesh-expansion-gce/scripts/3-install-istio.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
log() { echo "$1" >&2; }
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified}"
ZONE="us-central1-b"
CLUSTER_NAME="mesh-exp-gke"
CTX="gke_${PROJECT_ID}_${ZONE}_${CLUSTER_NAME}"
# configure cluster context
gcloud config set project $PROJECT_ID
gcloud container clusters get-credentials $CLUSTER_NAME --zone $ZONE
kubectl config use-context $CTX
cd ../common/
INSTALL_YAML="../mesh-expansion-gce/scripts/install.yaml" ./install_istio.sh
cd ../mesh-expansion-gce
================================================
FILE: mesh-expansion-gce/scripts/4-deploy-hipstershop.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
log() { echo "$1" >&2; }
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified}"
ZONE="us-central1-b"
CLUSTER_NAME="mesh-exp-gke"
CTX="gke_${PROJECT_ID}_${ZONE}_${CLUSTER_NAME}"
# configure cluster context
gcloud config set project $PROJECT_ID
gcloud container clusters get-credentials $CLUSTER_NAME --zone $ZONE
kubectl config use-context $CTX
# deploy sample app to GKE
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/kubernetes-manifests.yaml
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/istio-manifests.yaml
# remove the cluster-based productcatalog - we'll deploy this on the VM
kubectl delete svc productcatalogservice; kubectl delete deployment productcatalogservice
kubectl delete serviceentry allow-egress-google-metadata
kubectl delete serviceentry allow-egress-googleapis
================================================
FILE: mesh-expansion-gce/scripts/5-prep-cluster.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
log() { echo "$1" >&2; }
# set vars
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified}"
ZONE="us-central1-b"
CLUSTER_NAME="mesh-exp-gke"
CTX="gke_${PROJECT_ID}_${ZONE}_${CLUSTER_NAME}"
GCE_INSTANCE_NAME="istio-gce"
SERVICE_NAMESPACE="default"
# Generate cluster.env
export ISTIOD_IP=$(kubectl get -n istio-system service istiod -o jsonpath='{.spec.clusterIP}')
log "⛵️ istiod IP is $ISTIOD_IP"
ISTIO_SERVICE_CIDR=$(gcloud container clusters describe $CLUSTER_NAME --zone $ZONE --project $PROJECT_ID --format "value(servicesIpv4Cidr)")
echo -e "ISTIO_SERVICE_CIDR=$ISTIO_SERVICE_CIDR\n" > cluster.env
echo "ISTIO_INBOUND_PORTS=3550,8080" >> cluster.env
# client certs
log "Getting client certs..."
go run istio.io/istio/security/tools/generate_cert -client -host spiffee://cluster.local/vm/vmname \
--out-priv key.pem --out-cert cert-chain.pem -mode self-signed
# root cert
log "Getting root cert..."
kubectl -n istio-system get cm istio-ca-root-cert -o jsonpath='{.data.root-cert\.pem}' > root-cert.pem
================================================
FILE: mesh-expansion-gce/scripts/6-prep-vm.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
log() { echo "$1" >&2; }
# set vars
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified}"
ZONE="us-central1-b"
CLUSTER_NAME="mesh-exp-gke"
CTX="gke_${PROJECT_ID}_${ZONE}_${CLUSTER_NAME}"
GCE_NAME="istio-gce"
SERVICE_NAMESPACE="default"
# send certs and cluster.env to VM
gcloud compute scp --project=${PROJECT_ID} --zone=${ZONE} \
{key.pem,cert-chain.pem,cluster.env,root-cert.pem,scripts/vm-install-istio.sh,scripts/vm-run-products.sh} ${GCE_NAME}:
# from the VM, install the Istio sidecar proxy and update /etc/hosts to reach istiod
export ISTIOD_IP=$(kubectl get -n istio-system service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
log "⛵️ GWIP is is $ISTIOD_IP"
gcloud compute --project $PROJECT_ID ssh --zone ${ZONE} ${GCE_NAME} --command="ISTIOD_IP=${ISTIOD_IP} ./vm-install-istio.sh"
# from the VM, install Docker and run productcatalog as a docker container
gcloud compute --project $PROJECT_ID ssh --zone ${ZONE} ${GCE_NAME} --command="./vm-run-products.sh"
================================================
FILE: mesh-expansion-gce/scripts/7-add-to-mesh.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
log() { echo "$1" >&2; }
ZONE="us-central1-b"
GCE_NAME="istio-gce"
export GCE_IP=$(gcloud --format="value(networkInterfaces[0].networkIP)" compute instances describe ${GCE_NAME} --zone ${ZONE})
log "GCE IP is ${GCE_IP}"
../common/istio-1.5.2/bin/istioctl experimental add-to-mesh external-service productcatalogservice ${GCE_IP} grpc:3550 -n default
log "✅ added productcatalog to the mesh."
================================================
FILE: mesh-expansion-gce/scripts/8-start-vm-istio.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
log() { echo "$1" >&2; }
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified}"
ZONE="us-central1-b"
GCE_NAME="istio-gce"
# re-kick Istio on the VM
log "Restarting istio on the VM..."
gcloud compute --project $PROJECT_ID ssh --zone ${ZONE} ${GCE_NAME} --command="sudo systemctl stop istio; sudo systemctl start istio;"
log "Done."
================================================
FILE: mesh-expansion-gce/scripts/install.yaml
================================================
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
addonComponents:
grafana:
enabled: true
k8s:
replicaCount: 1
istiocoredns:
enabled: false
kiali:
enabled: true
k8s:
replicaCount: 1
prometheus:
enabled: true
k8s:
replicaCount: 1
tracing:
enabled: true
components:
base:
enabled: true
citadel:
enabled: false
k8s:
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
cni:
enabled: false
egressGateways:
- enabled: false
k8s:
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-ingressgateway
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
name: istio-egressgateway
galley:
enabled: false
k8s:
replicaCount: 1
resources:
requests:
cpu: 100m
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
ingressGateways:
- enabled: true
k8s:
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-ingressgateway
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
name: istio-ingressgateway
nodeAgent:
enabled: false
pilot:
enabled: true
k8s:
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 5
resources:
requests:
cpu: 500m
memory: 2048Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
policy:
enabled: false
k8s:
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-policy
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
sidecarInjector:
enabled: false
k8s:
replicaCount: 1
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
telemetry:
enabled: false
k8s:
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: GOMAXPROCS
value: "6"
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-telemetry
replicaCount: 1
resources:
limits:
cpu: 4800m
memory: 4G
requests:
cpu: 1000m
memory: 1G
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
hub: docker.io/istio
tag: 1.5.1
values:
clusterResources: true
galley:
enableAnalysis: false
image: galley
gateways:
istio-egressgateway:
autoscaleEnabled: true
env:
ISTIO_META_ROUTER_MODE: sni-dnat
ports:
- name: http2
port: 80
- name: https
port: 443
- name: tls
port: 15443
targetPort: 15443
secretVolumes:
- mountPath: /etc/istio/egressgateway-certs
name: egressgateway-certs
secretName: istio-egressgateway-certs
- mountPath: /etc/istio/egressgateway-ca-certs
name: egressgateway-ca-certs
secretName: istio-egressgateway-ca-certs
type: ClusterIP
istio-ingressgateway:
applicationPorts: ""
autoscaleEnabled: true
debug: info
domain: ""
env:
ISTIO_META_ROUTER_MODE: sni-dnat
meshExpansionPorts:
- name: tcp-pilot-grpc-tls
port: 15011
targetPort: 15011
- name: tcp-citadel-grpc-tls
port: 8060
targetPort: 8060
- name: tcp-dns-tls
port: 853
targetPort: 853
ports:
- name: status-port
port: 15020
targetPort: 15020
- name: http2
port: 80
targetPort: 80
- name: https
port: 443
- name: kiali
port: 15029
targetPort: 15029
- name: prometheus
port: 15030
targetPort: 15030
- name: grafana
port: 15031
targetPort: 15031
- name: tracing
port: 15032
targetPort: 15032
- name: tls
port: 15443
targetPort: 15443
sds:
enabled: false
image: node-agent-k8s
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
secretVolumes:
- mountPath: /etc/istio/ingressgateway-certs
name: ingressgateway-certs
secretName: istio-ingressgateway-certs
- mountPath: /etc/istio/ingressgateway-ca-certs
name: ingressgateway-ca-certs
secretName: istio-ingressgateway-ca-certs
type: LoadBalancer
zvpn:
enabled: false
suffix: global
global:
arch:
amd64: 2
ppc64le: 2
s390x: 2
certificates: []
configValidation: true
controlPlaneSecurityEnabled: true
defaultNodeSelector: {}
defaultPodDisruptionBudget:
enabled: true
defaultResources:
requests:
cpu: 10m
disablePolicyChecks: true
enableHelmTest: false
enableTracing: true
imagePullPolicy: IfNotPresent
imagePullSecrets: []
istioNamespace: istio-system
istiod:
enabled: true
jwtPolicy: third-party-jwt
k8sIngress:
enableHttps: false
enabled: false
gatewayName: ingressgateway
localityLbSetting:
enabled: true
logAsJson: false
logging:
level: default:info
meshExpansion:
enabled: true
useILB: false
meshNetworks: {}
mountMtlsCerts: false
mtls:
auto: true
enabled: false
multiCluster:
clusterName: ""
enabled: false
network: ""
omitSidecarInjectorConfigMap: false
oneNamespace: false
operatorManageWebhooks: false
outboundTrafficPolicy:
mode: ALLOW_ANY
pilotCertProvider: istiod
policyCheckFailOpen: false
priorityClassName: ""
proxy:
accessLogEncoding: TEXT
accessLogFile: "/dev/stdout"
accessLogFormat: ""
autoInject: enabled
clusterDomain: cluster.local
componentLogLevel: misc:error
concurrency: 2
dnsRefreshRate: 300s
enableCoreDump: false
envoyAccessLogService:
enabled: false
envoyMetricsService:
enabled: false
tcpKeepalive:
interval: 10s
probes: 3
time: 10s
tlsSettings:
mode: DISABLE
subjectAltNames: []
envoyStatsd:
enabled: false
excludeIPRanges: ""
excludeInboundPorts: ""
excludeOutboundPorts: ""
image: proxyv2
includeIPRanges: '*'
includeInboundPorts: '*'
kubevirtInterfaces: ""
logLevel: warning
privileged: false
protocolDetectionTimeout: 100ms
readinessFailureThreshold: 30
readinessInitialDelaySeconds: 1
readinessPeriodSeconds: 2
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
statusPort: 15020
tracer: zipkin
proxy_init:
image: proxyv2
resources:
limits:
cpu: 100m
memory: 50Mi
requests:
cpu: 10m
memory: 10Mi
sds:
enabled: false
token:
aud: istio-ca
udsPath: ""
sts:
servicePort: 0
tracer:
datadog:
address: $(HOST_IP):8126
lightstep:
accessToken: ""
address: ""
cacertPath: ""
secure: true
stackdriver:
debug: false
maxNumberOfAnnotations: 200
maxNumberOfAttributes: 200
maxNumberOfMessageEvents: 200
zipkin:
address: ""
trustDomain: cluster.local
useMCP: false
grafana:
accessMode: ReadWriteMany
contextPath: /grafana
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- disableDeletion: false
folder: istio
name: istio
options:
path: /var/lib/grafana/dashboards/istio
orgId: 1
type: file
datasources:
datasources.yaml:
apiVersion: 1
env: {}
envSecrets: {}
image:
repository: grafana/grafana
tag: 6.5.2
ingress:
enabled: false
hosts:
- grafana.local
nodeSelector: {}
persist: false
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
security:
enabled: false
passphraseKey: passphrase
secretName: grafana
usernameKey: username
service:
annotations: {}
externalPort: 3000
name: http
type: ClusterIP
storageClassName: ""
tolerations: []
istiocoredns:
coreDNSImage: coredns/coredns
coreDNSPluginImage: istio/coredns-plugin:0.2-istio-1.1
coreDNSTag: 1.6.2
kiali:
contextPath: /kiali
createDemoSecret: true
dashboard:
grafanaInClusterURL: http://grafana:3000
jaegerInClusterURL: http://tracing/jaeger
passphraseKey: passphrase
secretName: kiali
usernameKey: username
viewOnlyMode: false
hub: quay.io/kiali
ingress:
enabled: false
hosts:
- kiali.local
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
security:
cert_file: /kiali-cert/cert-chain.pem
enabled: false
private_key_file: /kiali-cert/key.pem
tag: v1.14
mixer:
adapters:
kubernetesenv:
enabled: true
prometheus:
enabled: true
metricsExpiryDuration: 10m
stackdriver:
auth:
apiKey: ""
appCredentials: false
serviceAccountPath: ""
enabled: false
tracer:
enabled: false
sampleProbability: 1
stdio:
enabled: false
outputAsJson: false
useAdapterCRDs: false
policy:
adapters:
kubernetesenv:
enabled: true
useAdapterCRDs: false
autoscaleEnabled: true
image: mixer
sessionAffinityEnabled: false
telemetry:
autoscaleEnabled: true
env:
GOMAXPROCS: "6"
image: mixer
loadshedding:
latencyThreshold: 100ms
mode: enforce
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
replicaCount: 1
reportBatchMaxEntries: 100
reportBatchMaxTime: 1s
sessionAffinityEnabled: false
tolerations: []
nodeagent:
image: node-agent-k8s
pilot:
appNamespaces: []
autoscaleEnabled: true
autoscaleMax: 5
autoscaleMin: 1
configMap: true
configNamespace: istio-config
cpu:
targetAverageUtilization: 80
enableProtocolSniffingForInbound: false
enableProtocolSniffingForOutbound: true
env: {}
image: pilot
ingress:
ingressClass: istio
ingressControllerMode: STRICT
ingressService: istio-ingressgateway
keepaliveMaxServerConnectionAge: 30m
meshNetworks:
networks: {}
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
policy:
enabled: false
replicaCount: 1
tolerations: []
traceSampling: 1
prometheus:
contextPath: /prometheus
hub: docker.io/prom
ingress:
enabled: false
hosts:
- prometheus.local
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
provisionPrometheusCert: true
retention: 6h
scrapeInterval: 15s
security:
enabled: true
tag: v2.15.1
tolerations: []
security:
dnsCerts:
istio-pilot-service-account.istio-control: istio-pilot.istio-control
enableNamespacesByDefault: true
image: citadel
selfSigned: true
sidecarInjectorWebhook:
enableNamespacesByDefault: false
image: sidecar_injector
injectLabel: istio-injection
objectSelector:
autoInject: true
enabled: false
rewriteAppHTTPProbe: false
selfSigned: false
telemetry:
enabled: true
v1:
enabled: false
v2:
enabled: true
prometheus:
enabled: true
stackdriver:
configOverride: {}
enabled: true
logging: true
monitoring: true
topology: true
tracing:
ingress:
enabled: false
jaeger:
accessMode: ReadWriteMany
hub: docker.io/jaegertracing
memory:
max_traces: 50000
persist: false
spanStorageType: badger
storageClassName: ""
tag: "1.16"
nodeSelector: {}
opencensus:
exporters:
stackdriver:
enable_tracing: true
hub: docker.io/omnition
resources:
limits:
cpu: "1"
memory: 2Gi
requests:
cpu: 200m
memory: 400Mi
tag: 0.1.9
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
provider: jaeger
service:
annotations: {}
externalPort: 9411
name: http-query
type: ClusterIP
zipkin:
hub: docker.io/openzipkin
javaOptsHeap: 700
maxSpans: 500000
node:
cpus: 2
probeStartupDelay: 200
queryPort: 9411
resources:
limits:
cpu: 300m
memory: 900Mi
requests:
cpu: 150m
memory: 900Mi
tag: 2.14.2
version: ""
================================================
FILE: mesh-expansion-gce/scripts/vm-install-istio.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# install the sidecar proxy
curl -L https://storage.googleapis.com/istio-release/releases/1.5.1/deb/istio-sidecar.deb > istio-sidecar.deb
sudo dpkg -i istio-sidecar.deb
# update /etc/hosts
echo "${ISTIOD_IP} istiod.istio-system.svc" | sudo tee -a /etc/hosts
# install certs
sudo mkdir -p /etc/certs
sudo cp {root-cert.pem,cert-chain.pem,key.pem} /etc/certs
sudo mkdir -p /var/run/secrets/istio/
sudo cp root-cert.pem /var/run/secrets/istio/
# install cluster.env
sudo cp cluster.env /var/lib/istio/envoy
# transfer file ownership to istio proxy
sudo chown -R istio-proxy /etc/certs /var/lib/istio/envoy /var/run/secrets/istio/
# start Istio
sudo systemctl start istio
================================================
FILE: mesh-expansion-gce/scripts/vm-run-products.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# install docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable";
sudo apt-get update;
sudo apt-get install -y docker-ce;
# run productcatalog
sudo docker run -d -p 3550:3550 gcr.io/google-samples/microservices-demo/productcatalogservice:v0.3.4
================================================
FILE: multicluster-gke/dual-control-plane/README.md
================================================
# Demo: Multicluster Istio - Gateway-Connected Clusters
This example shows how to orchestrate an application with [Istio](https://istio.io/) across two different
Google Kubernetes Engine clusters. To do this, we will unite two different Istio service meshes into
one logical, hybrid mesh.

This example is relevant if you run microservices on two different cloud platforms, or are
using a combination of on-prem and cloud Kubernetes. For demonstration purposes here, we'll use two GKE clusters in two different projects, and thus two
different [virtual networks](https://cloud.google.com/kubernetes-engine/docs/concepts/network-overview#inside-cluster).
## How it works
This demo uses Istio 1.4's [Gateway-Connected Clusters](https://preliminary.istio.io/docs/concepts/multicluster-deployments/#multiple-control-plane-topology) feature. This is a specific mode of
multicluster Istio where two separate Kubernetes clusters run their own Istio control
plane, and orchestrate their own mesh. But each Istio control plane also runs a CoreDNS
server, which allows services in both clusters to refer to services in the other cluster,
as if they were part of their own mesh. A service in cluster 1 can call a
cluster 2 service with a DNS name of the format `svc-name.cluster-2-namespace.global`.
The Kubernetes DNS server and Istio's CoreDNS know how to work together to resolve that
`global` DNS suffix.
## Prerequisites
- Two GCP projects with billing and the Kubernetes API enabled
- `gcloud` CLI
- `kubectl`
- `helm` CLI
## Set Project Variables
```
export PROJECT_1=<your-project1>
export PROJECT_2=<your-second-project>
```
## Create Two GKE Clusters
```
./scripts/1-create-gke-clusters.sh
```
Then, run:
```
watch -n 1 gcloud container clusters list
```
And wait for both clusters to be `RUNNING`.
## Install Istio on Both Clusters
```
./scripts/2-install-istio.sh
```
Wait for all Istio pods to be `RUNNING` -
```
NAME READY STATUS RESTARTS
AGE
grafana-556b649566-4fwb9 1/1 Running 0
2m28s
istio-egressgateway-79ffd95b56-zf2vg 1/1 Running 0
8m18s
istio-ingressgateway-6df84b84d4-dp9rw 1/1 Running 0
8m17s
istio-tracing-7cf5f46848-pzmf7 1/1 Running 0
2m28s
istiocoredns-5f7546c6f4-gjl2x 2/2 Running 0
8m17s
istiod-8465c8f9d9-pxb6v 1/1 Running 0
8m38s
kiali-6d54b8ccbc-9qhc9 1/1 Running 0
2m28s
prometheus-75f89f4df8-gd5mn 2/2 Running 0
8m16s
```
## Configure KubeDNS to talk to Istio's CoreDNS
You'll notice `istiocoredns` in the list of pods. This DNS server which will handle DNS resolution across
cluster boundaries.
The next step configures the Kubernetes server (kubedns) to with a
DNS
[stub domain](https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configure-stub-domain-and-upstream-dns-servers)
to talk to this auxiliary Istio CoreDNS server.
A StubDomain is a forwarding rule for DNS addresses with a certain prefix.
Run the script to configure the stub domain on both GKE clusters:
```
./scripts/3-configure-dns.sh
```
## Deploy the Sample App
We will now deploy [Online Boutique, a sample application](https://github.com/GoogleCloudPlatform/microservices-demo), across our two GKE clusters.
For demonstration purposes, we've split the microservices into two halves. One group
will run on Cluster 1 (namespace `hipster1`):
- emailservice
- checkoutservice
- paymentservice
- currencyservice
- shippingservice
- adservice
And another group will run on Cluster 2 (namespace
`hipster2`):
- frontend
- productcatalogservice
- recommendationservice
- cartservice (configured to use a local store, not Redis)
Visually, we will deploy this topology:

The following script creates the following resources on both GKE clusters:
- Kubernetes Deployments for the services assigned to this cluster
- Kubernetes Services for the services that *are* running local to this cluster
- ServiceEntries (type `MESH_INTERNAL`) for all the services *not* running on this cluster. **Note**: for each
of these external ServiceEntries, the script injects the Istio `IngressGateway` IP for the
opposite cluster. This is how CoreDNS will be able to resolve `global` to an actual
external Istio IP.
- ServiceEntries (type `MESH_EXTERNAL`) to access external Google APIs (necessary for
Online Boutique to run)
- Istio VirtualServices / Gateway (for cluster 2 / the frontend only)
Run the script to deploy these resources across both clusters:
```
./scripts/4-deploy-online-boutique.sh
```
## Verify successful deployment
1. Get pods in cluster 1 (namespace `hipster1`) to make sure all are `RUNNING` -
```
NAME READY STATUS RESTARTS AGE
adservice-84449b8756-4nhpm 2/2 Running 0 3m29s
checkoutservice-8dfb487c6-rwh9n 2/2 Running 0 3m30s
currencyservice-b9fcb4c98-98q7x 2/2 Running 0 3m29s
emailservice-57f9ddf9b9-hmpv7 2/2 Running 0 3m30s
paymentservice-84d7bf956-8f9br 2/2 Running 0 3m29s
shippingservice-78dc8784d4-7h4zx 2/2 Running 0 3m29s
```
2. Get pods in cluster 2 (namespace `hipster2`) to make sure all are `RUNNING` -
```
NAME READY STATUS RESTARTS
AGE
cartservice-5b88d44bd-t6s6c 2/2 Running 0
2m31s
frontend-7958cf4f9-r2b9m 2/2 Running 0
2m32s
productcatalogservice-c796f4c6d-qgfp8 2/2 Running 0
2m32s
recommendationservice-6788b77796-z4xq8 2/2 Running 0
2m31s
```
3. Get the Ingress Gateway `EXTERNAL_IP` in `cluster2`, where the web `frontend` is deployed:
```
kubectl config use-context gke_${PROJECT_2}_us-central1-b_dual-cluster2
kubectl get svc -n istio-system istio-ingressgateway
```
Navigate to that address in a browser.

4. View the service graph.
From `cluster2`, open the Kiali service graph dashboard.
```
../../common/istio-1.5.2/bin/istioctl dashboard kiali &
```
Log in as `admin/admin`. Navigate to Graph > Service Graph > namespace: `default`. You should see traffic moving from the `frontend` on cluster2, to services running in both cluster2 (eg. `productcatalogservice`) and in cluster1 (eg. `adservice`). Note that in-cluster traffic within cluster1 is not visible in cluster2's Kiali dashboard.

Congrats! you just deployed Multicluster Istio across
two separate networks, then ran an application that spanned two Kubernetes
environments! All part of a single, two-headed Service Mesh. 🎉
## Clean up
Delete the 2 GKE clusters:
```
./scripts/cleanup-delete-clusters.sh
```
## Further reading
- To learn about Multicluster Istio and its different modes, [see the Istio docs](https://istio.io/docs/concepts/multicluster-deployments/)
- To learn how to configure and install the different modes, see the [Setup](https://istio.io/docs/setup/install/multicluster/) section in the Istio docs.
================================================
FILE: multicluster-gke/dual-control-plane/cluster1/deployments.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_dual_control_plane_cluster1_deployment_emailservice]
apiVersion: apps/v1
kind: Deployment
metadata:
name: emailservice
spec:
selector:
matchLabels:
app: emailservice
template:
metadata:
labels:
app: emailservice
spec:
containers:
- image: gcr.io/google-samples/microservices-demo/emailservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:8080
periodSeconds: 5
name: server
ports:
- containerPort: 8080
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:8080
periodSeconds: 5
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
terminationGracePeriodSeconds: 5
# [END istio_dual_control_plane_cluster1_deployment_emailservice]
---
# [START istio_dual_control_plane_cluster1_deployment_checkoutservice]
apiVersion: apps/v1
kind: Deployment
metadata:
name: checkoutservice
spec:
selector:
matchLabels:
app: checkoutservice
template:
metadata:
labels:
app: checkoutservice
spec:
containers:
- env:
- name: PRODUCT_CATALOG_SERVICE_ADDR
value: productcatalogservice.default.global:3550
- name: SHIPPING_SERVICE_ADDR
value: shippingservice.default.svc.cluster.local:50051
- name: PAYMENT_SERVICE_ADDR
value: paymentservice.default.svc.cluster.local:50051
- name: EMAIL_SERVICE_ADDR
value: emailservice.default.svc.cluster.local:5000
- name: CURRENCY_SERVICE_ADDR
value: currencyservice.default.svc.cluster.local:7000
- name: CART_SERVICE_ADDR
value: cartservice.default.global:7070
image: gcr.io/google-samples/microservices-demo/checkoutservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:5050
name: server
ports:
- containerPort: 5050
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:5050
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
# [END istio_dual_control_plane_cluster1_deployment_checkoutservice]
---
# [START istio_dual_control_plane_cluster1_deployment_paymentservice]
apiVersion: apps/v1
kind: Deployment
metadata:
name: paymentservice
spec:
selector:
matchLabels:
app: paymentservice
template:
metadata:
labels:
app: paymentservice
spec:
containers:
- env:
- name: PORT
value: '50051'
image: gcr.io/google-samples/microservices-demo/paymentservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:50051
name: server
ports:
- containerPort: 50051
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:50051
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
terminationGracePeriodSeconds: 5
# [END istio_dual_control_plane_cluster1_deployment_paymentservice]
---
# [START istio_dual_control_plane_cluster1_deployment_currencyservice]
apiVersion: apps/v1
kind: Deployment
metadata:
name: currencyservice
spec:
selector:
matchLabels:
app: currencyservice
template:
metadata:
labels:
app: currencyservice
spec:
containers:
- env:
- name: PORT
value: '7000'
image: gcr.io/google-samples/microservices-demo/currencyservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:7000
name: server
ports:
- containerPort: 7000
name: grpc
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:7000
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
terminationGracePeriodSeconds: 5
# [END istio_dual_control_plane_cluster1_deployment_currencyservice]
---
# [START istio_dual_control_plane_cluster1_deployment_shippingservice]
apiVersion: apps/v1
kind: Deployment
metadata:
name: shippingservice
spec:
selector:
matchLabels:
app: shippingservice
template:
metadata:
labels:
app: shippingservice
spec:
containers:
- image: gcr.io/google-samples/microservices-demo/shippingservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:50051
name: server
ports:
- containerPort: 50051
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:50051
periodSeconds: 5
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
# [END istio_dual_control_plane_cluster1_deployment_shippingservice]
---
# [START istio_dual_control_plane_cluster1_deployment_adservice]
apiVersion: apps/v1
kind: Deployment
metadata:
name: adservice
spec:
selector:
matchLabels:
app: adservice
template:
metadata:
labels:
app: adservice
spec:
containers:
- env:
- name: PORT
value: '9555'
image: gcr.io/google-samples/microservices-demo/adservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:9555
initialDelaySeconds: 20
periodSeconds: 15
name: server
ports:
- containerPort: 9555
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:9555
initialDelaySeconds: 20
periodSeconds: 15
resources:
limits:
cpu: 300m
memory: 300Mi
requests:
cpu: 200m
memory: 180Mi
terminationGracePeriodSeconds: 5
# [END istio_dual_control_plane_cluster1_deployment_adservice]
---
================================================
FILE: multicluster-gke/dual-control-plane/cluster1/istio-defaults.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_dual_control_plane_cluster1_serviceentry_currency_provider_external]
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: currency-provider-external
spec:
hosts:
- www.ecb.europa.eu
ports:
- name: http
number: 80
protocol: HTTP
- name: https
number: 443
protocol: HTTPS
# [END istio_dual_control_plane_cluster1_serviceentry_currency_provider_external]
================================================
FILE: multicluster-gke/dual-control-plane/cluster1/service-entries.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_dual_control_plane_cluster1_serviceentry_frontendservice_entry]
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: frontendservice-entry
spec:
addresses:
- 240.0.0.5
endpoints:
- address: 35.193.92.27
ports:
http1: 15443
hosts:
- frontend.default.global
location: MESH_INTERNAL
ports:
- name: http1
number: 80
protocol: http
resolution: DNS
# [END istio_dual_control_plane_cluster1_serviceentry_frontendservice_entry]
---
# [START istio_dual_control_plane_cluster1_serviceentry_productcatalogservice_entry]
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: productcatalogservice-entry
spec:
addresses:
- 240.0.0.6
endpoints:
- address: 35.193.92.27
ports:
grpc: 15443
hosts:
- productcatalogservice.default.global
location: MESH_INTERNAL
ports:
- name: grpc
number: 3550
protocol: GRPC
resolution: DNS
# [END istio_dual_control_plane_cluster1_serviceentry_productcatalogservice_entry]
---
# [START istio_dual_control_plane_cluster1_serviceentry_cartservice_entry]
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: cartservice-entry
spec:
addresses:
- 240.0.0.7
endpoints:
- address: 35.193.92.27
ports:
grpc: 15443
hosts:
- cartservice.default.global
location: MESH_INTERNAL
ports:
- name: grpc
number: 7070
protocol: GRPC
resolution: DNS
# [END istio_dual_control_plane_cluster1_serviceentry_cartservice_entry]
---
================================================
FILE: multicluster-gke/dual-control-plane/cluster1/services-local.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_dual_control_plane_cluster1_service_emailservice]
apiVersion: v1
kind: Service
metadata:
name: emailservice
spec:
ports:
- name: grpc
port: 5000
targetPort: 8080
selector:
app: emailservice
type: ClusterIP
# [END istio_dual_control_plane_cluster1_service_emailservice]
---
# [START istio_dual_control_plane_cluster1_service_checkoutservice]
apiVersion: v1
kind: Service
metadata:
name: checkoutservice
spec:
ports:
- name: grpc
port: 5050
targetPort: 5050
selector:
app: checkoutservice
type: ClusterIP
# [END istio_dual_control_plane_cluster1_service_checkoutservice]
---
# [START istio_dual_control_plane_cluster1_service_paymentservice]
apiVersion: v1
kind: Service
metadata:
name: paymentservice
spec:
ports:
- name: grpc
port: 50051
targetPort: 50051
selector:
app: paymentservice
type: ClusterIP
# [END istio_dual_control_plane_cluster1_service_paymentservice]
---
# [START istio_dual_control_plane_cluster1_service_currencyservice]
apiVersion: v1
kind: Service
metadata:
name: currencyservice
spec:
ports:
- name: grpc
port: 7000
targetPort: 7000
selector:
app: currencyservice
type: ClusterIP
# [END istio_dual_control_plane_cluster1_service_currencyservice]
---
# [START istio_dual_control_plane_cluster1_service_shippingservice]
apiVersion: v1
kind: Service
metadata:
name: shippingservice
spec:
ports:
- name: grpc
port: 50051
targetPort: 50051
selector:
app: shippingservice
type: ClusterIP
# [END istio_dual_control_plane_cluster1_service_shippingservice]
---
# [START istio_dual_control_plane_cluster1_service_adservice]
apiVersion: v1
kind: Service
metadata:
name: adservice
spec:
ports:
- name: grpc
port: 9555
targetPort: 9555
selector:
app: adservice
type: ClusterIP
# [END istio_dual_control_plane_cluster1_service_adservice]
---
================================================
FILE: multicluster-gke/dual-control-plane/cluster2/deployments.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: loadgenerator
spec:
selector:
matchLabels:
app: loadgenerator
replicas: 1
template:
metadata:
labels:
app: loadgenerator
annotations:
sidecar.istio.io/rewriteAppHTTPProbers: "true"
spec:
terminationGracePeriodSeconds: 5
restartPolicy: Always
containers:
- name: main
image: gcr.io/google-samples/microservices-demo/loadgenerator:v0.3.4
env:
- name: FRONTEND_ADDR
value: "frontend:80"
- name: USERS
value: "10"
resources:
requests:
cpu: 300m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
---
# [START istio_dual_control_plane_cluster2_deployment_frontend]
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- env:
- name: PRODUCT_CATALOG_SERVICE_ADDR
value: productcatalogservice.default.svc.cluster.local:3550
- name: CURRENCY_SERVICE_ADDR
value: currencyservice.default.global:7000
- name: CART_SERVICE_ADDR
value: cartservice.default.svc.cluster.local:7070
- name: RECOMMENDATION_SERVICE_ADDR
value: recommendationservice.default.svc.cluster.local:8080
- name: SHIPPING_SERVICE_ADDR
value: shippingservice.default.global:50051
- name: CHECKOUT_SERVICE_ADDR
value: checkoutservice.default.global:5050
- name: AD_SERVICE_ADDR
value: adservice.default.global:9555
image: gcr.io/google-samples/microservices-demo/frontend:v0.3.4
livenessProbe:
httpGet:
httpHeaders:
- name: Cookie
value: shop_session-id=x-liveness-probe
path: /_healthz
port: 8080
initialDelaySeconds: 10
name: server
ports:
- containerPort: 8080
readinessProbe:
httpGet:
httpHeaders:
- name: Cookie
value: shop_session-id=x-readiness-probe
path: /_healthz
port: 8080
initialDelaySeconds: 10
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
# [END istio_dual_control_plane_cluster2_deployment_frontend]
---
# [START istio_dual_control_plane_cluster2_deployment_productcatalogservice]
apiVersion: apps/v1
kind: Deployment
metadata:
name: productcatalogservice
spec:
selector:
matchLabels:
app: productcatalogservice
template:
metadata:
labels:
app: productcatalogservice
spec:
containers:
- image: gcr.io/google-samples/microservices-demo/productcatalogservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:3550
name: server
ports:
- containerPort: 3550
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:3550
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
terminationGracePeriodSeconds: 5
# [END istio_dual_control_plane_cluster2_deployment_productcatalogservice]
---
# [START istio_dual_control_plane_cluster2_deployment_cartservice]
apiVersion: apps/v1
kind: Deployment
metadata:
name: cartservice
spec:
selector:
matchLabels:
app: cartservice
template:
metadata:
labels:
app: cartservice
spec:
containers:
- env:
- name: REDIS_ADDR
value: ''
- name: PORT
value: '7070'
- name: LISTEN_ADDR
value: 0.0.0.0
image: gcr.io/google-samples/microservices-demo/cartservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:7070
initialDelaySeconds: 15
periodSeconds: 10
name: server
ports:
- containerPort: 7070
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:7070
initialDelaySeconds: 15
resources:
limits:
cpu: 300m
memory: 128Mi
requests:
cpu: 200m
memory: 64Mi
terminationGracePeriodSeconds: 5
# [END istio_dual_control_plane_cluster2_deployment_cartservice]
---
# [START istio_dual_control_plane_cluster2_deployment_recommendationservice]
apiVersion: apps/v1
kind: Deployment
metadata:
name: recommendationservice
spec:
selector:
matchLabels:
app: recommendationservice
template:
metadata:
labels:
app: recommendationservice
spec:
containers:
- env:
- name: PRODUCT_CATALOG_SERVICE_ADDR
value: productcatalogservice.default.svc.cluster.local:3550
image: gcr.io/google-samples/microservices-demo/recommendationservice:v0.3.4
livenessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:8080
periodSeconds: 5
name: server
ports:
- containerPort: 8080
readinessProbe:
exec:
command:
- /bin/grpc_health_probe
- -addr=:8080
periodSeconds: 5
resources:
limits:
cpu: 200m
memory: 450Mi
requests:
cpu: 100m
memory: 220Mi
terminationGracePeriodSeconds: 5
# [END istio_dual_control_plane_cluster2_deployment_recommendationservice]
---
================================================
FILE: multicluster-gke/dual-control-plane/cluster2/istio-defaults.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_dual_control_plane_cluster2_gateway_frontend_gateway]
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: frontend-gateway
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
# [END istio_dual_control_plane_cluster2_gateway_frontend_gateway]
---
# [START istio_dual_control_plane_cluster2_virtualservice_frontend_ingress]
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: frontend-ingress
spec:
gateways:
- frontend-gateway
hosts:
- '*'
http:
- route:
- destination:
host: frontend
port:
number: 80
# [END istio_dual_control_plane_cluster2_virtualservice_frontend_ingress]
---
# [START istio_dual_control_plane_cluster2_virtualservice_frontend]
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: frontend
spec:
hosts:
- frontend.default.svc.cluster.local
http:
- route:
- destination:
host: frontend
port:
number: 80
# [END istio_dual_control_plane_cluster2_virtualservice_frontend]
================================================
FILE: multicluster-gke/dual-control-plane/cluster2/service-entries.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_dual_control_plane_cluster2_serviceentry_adservice_entry]
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: adservice-entry
spec:
addresses:
- 240.0.0.2
endpoints:
- address: 34.70.9.157
ports:
grpc: 15443
hosts:
- adservice.default.global
location: MESH_INTERNAL
ports:
- name: grpc
number: 9555
protocol: GRPC
resolution: DNS
# [END istio_dual_control_plane_cluster2_serviceentry_adservice_entry]
---
# [START istio_dual_control_plane_cluster2_serviceentry_checkoutservice_entry]
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: checkoutservice-entry
spec:
addresses:
- 240.0.0.3
endpoints:
- address: 34.70.9.157
ports:
grpc: 15443
hosts:
- checkoutservice.default.global
location: MESH_INTERNAL
ports:
- name: grpc
number: 5050
protocol: GRPC
resolution: DNS
# [END istio_dual_control_plane_cluster2_serviceentry_checkoutservice_entry]
---
# [START istio_dual_control_plane_cluster2_serviceentry_currencyservice_entry]
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: currencyservice-entry
spec:
addresses:
- 240.0.0.4
endpoints:
- address: 34.70.9.157
ports:
grpc: 15443
hosts:
- currencyservice.default.global
location: MESH_INTERNAL
ports:
- name: grpc
number: 7000
protocol: GRPC
resolution: DNS
# [END istio_dual_control_plane_cluster2_serviceentry_currencyservice_entry]
---
# [START istio_dual_control_plane_cluster2_serviceentry_shippingservice_entry]
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: shippingservice-entry
spec:
addresses:
- 240.0.0.8
endpoints:
- address: 34.70.9.157
ports:
grpc: 15443
hosts:
- shippingservice.default.global
location: MESH_INTERNAL
ports:
- name: grpc
number: 50051
protocol: GRPC
resolution: DNS
# [END istio_dual_control_plane_cluster2_serviceentry_shippingservice_entry]
---
================================================
FILE: multicluster-gke/dual-control-plane/cluster2/services-local.yaml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START istio_dual_control_plane_cluster2_service_recommendationservice]
apiVersion: v1
kind: Service
metadata:
name: recommendationservice
spec:
ports:
- name: grpc
port: 8080
targetPort: 8080
selector:
app: recommendationservice
type: ClusterIP
# [END istio_dual_control_plane_cluster2_service_recommendationservice]
---
# [START istio_dual_control_plane_cluster2_service_frontend]
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: frontend
type: ClusterIP
# [END istio_dual_control_plane_cluster2_service_frontend]
---
# [START istio_dual_control_plane_cluster2_service_productcatalogservice]
apiVersion: v1
kind: Service
metadata:
name: productcatalogservice
spec:
ports:
- name: grpc
port: 3550
targetPort: 3550
selector:
app: productcatalogservice
type: ClusterIP
# [END istio_dual_control_plane_cluster2_service_productcatalogservice]
---
# [START istio_dual_control_plane_cluster2_service_cartservice]
apiVersion: v1
kind: Service
metadata:
name: cartservice
spec:
ports:
- name: grpc
port: 7070
targetPort: 7070
selector:
app: cartservice
type: ClusterIP
# [END istio_dual_control_plane_cluster2_service_cartservice]
---
================================================
FILE: multicluster-gke/dual-control-plane/scripts/1-create-gke-clusters.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
# Project 1 - Create GKE Cluster 1
gcloud config set project $PROJECT_1
gcloud container clusters create $CLUSTER_1 --zone $ZONE --username "admin" \
--machine-type "n1-standard-2" \
--scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "4" --network "default" --enable-stackdriver-kubernetes --async
# Project 2 - Create GKE Cluster 2
gcloud config set project $PROJECT_2
gcloud container clusters create $CLUSTER_2 --zone $ZONE --username "admin" \
--machine-type "n1-standard-2" \
--num-nodes "4" --network "default" --enable-stackdriver-kubernetes --async
================================================
FILE: multicluster-gke/dual-control-plane/scripts/2-install-istio.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
DUAL_PROFILE="../multicluster-gke/dual-control-plane/scripts/install.yaml"
cd ../../common
# Cluster 1
log "Installing Istio on Cluster 1..."
gcloud config set project $PROJECT_1
gcloud container clusters get-credentials $CLUSTER_1 --zone $ZONE
kubectl config use-context $CTX_1
INSTALL_YAML=${DUAL_PROFILE} ./install_istio.sh
# Cluster 2
log "Installing Istio on Cluster 2..."
gcloud config set project $PROJECT_2
gcloud container clusters get-credentials $CLUSTER_2 --zone $ZONE
kubectl config use-context $CTX_2
INSTALL_YAML=${DUAL_PROFILE} ./install_istio.sh
================================================
FILE: multicluster-gke/dual-control-plane/scripts/3-configure-dns.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
configure_kubedns () {
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
stubDomains: |
{"global": ["$(kubectl get svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP})"]}
EOF
}
# Cluster 1
log "Configuring DNS on Cluster 1..."
gcloud config set project $PROJECT_1
kubectl config use-context $CTX_1
configure_kubedns
log "...done with cluster 1."
# Cluster 2
log "Configuring DNS on Cluster 2..."
gcloud config set project $PROJECT_2
kubectl config use-context $CTX_2
configure_kubedns
log "...done with cluster 2."
================================================
FILE: multicluster-gke/dual-control-plane/scripts/4-deploy-online-boutique.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
# Get the Istio IngressGateway IP for both clusters
kubectl config use-context $CTX_1
GWIP1=$(kubectl get -n istio-system service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
kubectl config use-context $CTX_2
GWIP2=$(kubectl get -n istio-system service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
# Populate YAML / Deploy to Cluster 1
log "Deploying OnlineBoutique on Cluster 1..."
gcloud config set project $PROJECT_1
gcloud container clusters get-credentials $CLUSTER_1 --zone $ZONE
kubectl config use-context $CTX_1
pattern='.*- address:.*'
replace=" - address: "$GWIP2""
gsed -r -i "s|$pattern|$replace|g" cluster1/service-entries.yaml
kubectl apply -f ./cluster1
log "...done with cluster 1."
# Populate YAML / Deploy to Cluster 2
log "Deploying OnlineBoutique on Cluster 2..."
gcloud config set project $PROJECT_2
gcloud container clusters get-credentials $CLUSTER_2 --zone $ZONE
kubectl config use-context $CTX_2
pattern='.*- address:.*'
replace=" - address: "$GWIP1""
gsed -r -i "s|$pattern|$replace|g" cluster2/service-entries.yaml
kubectl apply -f ./cluster2
log "...done with cluster 2."
================================================
FILE: multicluster-gke/dual-control-plane/scripts/cleanup-delete-clusters.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
log "Deleting cluster 1..."
gcloud container clusters delete $CLUSTER_1 --project $PROJECT_1 --zone $ZONE --async
# Project 2 - Create GKE Cluster 2
log "Deleting cluster 2..."
gcloud config set project $PROJECT_2
gcloud container clusters delete $CLUSTER_2 --project $PROJECT_2 --zone $ZONE --async
================================================
FILE: multicluster-gke/dual-control-plane/scripts/env.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
log() { echo "$1" >&2; }
ZONE="us-central1-b"
ISTIO_VERSION=${ISTIO_VERSION:=1.4.2}
PROJECT_1="${PROJECT_1:?PROJECT_1 env variable must be specified}"
CLUSTER_1="dual-cluster1"
CTX_1="gke_${PROJECT_1}_${ZONE}_${CLUSTER_1}"
PROJECT_2="${PROJECT_2:?PROJECT_2 env variable must be specified}"
CLUSTER_2="dual-cluster2"
CTX_2="gke_${PROJECT_2}_${ZONE}_${CLUSTER_2}"
================================================
FILE: multicluster-gke/dual-control-plane/scripts/install.yaml
================================================
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
addonComponents:
grafana:
enabled: true
k8s:
replicaCount: 1
istiocoredns:
enabled: true
kiali:
enabled: true
k8s:
replicaCount: 1
prometheus:
enabled: true
k8s:
replicaCount: 1
tracing:
enabled: true
components:
egressGateways:
- name: istio-egressgateway
enabled: true
values:
kiali:
contextPath: /kiali
createDemoSecret: true
dashboard:
grafanaInClusterURL: http://grafana:3000
jaegerInClusterURL: http://tracing/jaeger
passphraseKey: passphrase
secretName: kiali
usernameKey: username
viewOnlyMode: false
hub: quay.io/kiali
ingress:
enabled: false
hosts:
- kiali.local
nodeSelector: {}
podAntiAffinityLabelSelector: []
podAntiAffinityTermLabelSelector: []
security:
cert_file: /kiali-cert/cert-chain.pem
enabled: false
private_key_file: /kiali-cert/key.pem
tag: v1.14
global:
# Provides dns resolution for global services
podDNSSearchNamespaces:
- global
- "{{ valueOrDefault .DeploymentMeta.Namespace \"default\" }}.global"
multiCluster:
enabled: true
controlPlaneSecurityEnabled: true
# Multicluster with gateways requires a root CA
# Cluster local CAs are bootstrapped with the root CA.
security:
selfSigned: false
gateways:
istio-egressgateway:
env:
# Needed to route traffic via egress gateway if desired.
ISTIO_META_REQUESTED_NETWORK_VIEW: "external"
================================================
FILE: multicluster-gke/single-control-plane/README.md
================================================
# Demo: Multicluster Istio- Single Control Plane
This demo shows how to use Istio to orchestrate [an application](https://github.com/GoogleCloudPlatform/microservices-demo) running across two Google
Kubernetes Engine clusters in the same project, but across two different [zones](https://cloud.google.com/compute/docs/regions-zones/#identifying_a_region_or_zone).

### Prerequisites
1. a GCP project with Billing enabled.
2. gcloud
3. kubectl
4. [helm CLI](https://github.com/helm/helm/releases), installed wherever you're running
these commands (Google Cloud shell, laptop,
etc.) Note that we are only using the `helm template` command in this demo (ie. [Tiller](https://helm.sh/docs/glossary/#tiller)
not required on any of the Kubernetes clusters).
## Create two GKE clusters
Set the project ID to your GCP Project:
```
export PROJECT_ID=<your-GCP-project-ID>
```
Then run the script to create two GKE clusters in your project:
```
./scripts/1-cluster-create.sh
```
Then, run:
```
watch -n 1 gcloud container clusters list
```
Wait for both clusters to be `RUNNING`.
## Connect to clusters
This script creates kubeconfigs for both clusters, to allow future `kubectl` commands to
switch back and forth between them.
```
./scripts/2-get-credentials.sh
```
## Create a GKE Firewall Rule
This step allows pods on both clusters to communicate directly.
```
./scripts/3-firewall.sh
```
## Install the Istio Control Plane on Cluster 1
This step installs the Istio control plane on one of the GKE clusters.
```
./scripts/4-cluster1-install.sh
```
## Install the Istio Remote on Cluster 2
Now we'll install the remote Istio components (Citadel's node-agent, and an Envoy sidecar injector) on Cluster 2.
```
./scripts/5-cluster2-install.sh
```
## Connect Cluster 2 to Cluster 1
This step generates a [Kubeconfig](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#define-clusters-users-and-contexts) file for the remote cluster 2, then adds it as a [Secret](https://kubernetes.io/docs/concepts/configuration/secret/)
to Cluster 1. This step allows the Istio control plane on cluster 1 to configure Istio proxies on cluster 2.
```
./scripts/6-connect-clusters.sh
```
## Deploy [Hipstershop](https://github.com/GoogleCloudPlatform/microservices-demo)
This script deploys the sample application across both cluster 1 and cluster 2. We have
split the microservices in the application so that some run centrally to the Istio control
plane (cluster 1), and the rest run on the remote Istio cluster (cluster 2):

Run the script to deploy:
```
./scripts/7-deploy-hipstershop.sh
```
*Note*: This script uses the default Hipstershop installation, which deploys all services to the cluster, then deletes the deployments that belong on the other cluster. Both clusters need Kubernetes Services for all the Hipstershop workloads, in order for cross-cluster DNS to work.
You can verify that the multicluster deployment was successful using 3 methods:
1. Run `kubectl get pods` on both clusters to ensure all pods are `RUNNING` and `READY`.
2. From cluster-1, run `istioctl proxy-status`. You should see cluster-2 services (eg.
`cartservice`) appear in the list. This means that the Istio control plane can
successfully configure Envoy proxies running on the remote GKE cluster-2.
```
NAME CDS LDS EDS RDS PILOT VERSION
adservice-86674bf94d-gq52w.default SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
checkoutservice-74df4f44c8-b6xlq.default SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
currencyservice-6444b89474-ln4zp.default SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
emailservice-c98d5d48d-5pg65.default SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
frontend-67dcdc8cf8-z64jh.default SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
istio-ingressgateway-5b477bdb4f-l9fw2.istio-system SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
paymentservice-579d78fc44-r65wp.default SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
productcatalogservice-65794cb878-bb6zf.default SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
prometheus-7bc49f57-mjhqx.istio-system SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
shippingservice-794b4d66bb-prc9j.default SYNCED SYNCED SYNCED SYNCED istiod-6c6c489d84-8rgnr 1.5.2
```
3. open Hipstershop in the browser by getting the Istio `IngressGateway`'s `EXTERNAL_IP`:
```
kubectl get svc istio-ingressgateway -n istio-system
```
From the frontend, click on a product. You should see product recommendations, and be able to navigate to your Cart without any errors:

This means that the Hipstershop Frontend service (running in cluster 1) was able to use
its Istio sidecar proxy to resolve DNS to Kubernetes Services running in cluster 2.
🎉 Well done! You just orchestrated an application with Istio across multiple Google
Kubernetes Engine
clusters.
## Cleanup
To delete all the GCP resources used in this demo:
```
./scripts/cleanup-delete-clusters.sh
```
## What's next?
Now that you have Istio installed on two clusters, you can create [traffic rules](https://github.com/GoogleCloudPlatform/istio-samples/tree/master/istio-canary-gke) and [security policies](https://github.com/GoogleCloudPlatform/istio-samples/tree/master/security-intro) that
span both clusters.
Or to deploy the BookInfo app with multicluster Istio, [see the Istio documentation](https://preliminary.istio.io/docs/examples/multicluster/gke/).
================================================
FILE: multicluster-gke/single-control-plane/scripts/1-cluster-create.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Creates two GKE clusters in different regions.
set -euo pipefail
source ./scripts/env.sh
log "Creating cluster1..."
gcloud container clusters create cluster-1 --zone $cluster1zone --username "admin" \
--machine-type "n1-standard-4" \
--scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "2" --network "default" --enable-stackdriver-kubernetes --enable-ip-alias --async
sleep 20
log "Creating cluster2..."
gcloud container clusters create cluster-2 --zone $cluster2zone --username "admin" \
--machine-type "n1-standard-4" \
--scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "2" --network "default" --enable-stackdriver-kubernetes --enable-ip-alias --async
================================================
FILE: multicluster-gke/single-control-plane/scripts/2-get-credentials.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
gcloud container clusters get-credentials cluster-1 --zone $cluster1zone
gcloud container clusters get-credentials cluster-2 --zone $cluster2zone
================================================
FILE: multicluster-gke/single-control-plane/scripts/3-firewall.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
function join_by { local IFS="$1"; shift; echo "$*"; }
ALL_CLUSTER_CIDRS=$(gcloud container clusters list --format='value(clusterIpv4Cidr)' | sort | uniq)
ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
ALL_CLUSTER_NETTAGS=$(gcloud compute instances list --format='value(tags.items.[0])' | sort | uniq)
ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
gcloud compute firewall-rules create istio-multicluster-test-pods \
--allow=tcp,udp,icmp,esp,ah,sctp \
--direction=INGRESS \
--priority=900 \
--source-ranges="${ALL_CLUSTER_CIDRS}" \
--target-tags="${ALL_CLUSTER_NETTAGS}" --quiet
================================================
FILE: multicluster-gke/single-control-plane/scripts/4-cluster1-install.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# cluster 1 is the "main" cluster running the Istio control plane
# src https://istio.io/docs/setup/install/multicluster/shared/
set -euo pipefail
source ./scripts/env.sh
kubectl config use-context $ctx1
log "Installing the Istio ${ISTIO_VERSION} control plane on ${ctx1} ..."
cd ../../common
INSTALL_YAML="../multicluster-gke/single-control-plane/scripts/cluster1.yaml" ./install_istio.sh
================================================
FILE: multicluster-gke/single-control-plane/scripts/5-cluster2-install.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
export ISTIOD_REMOTE_EP=$(kubectl --context=${ctx1} -n istio-system get svc istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
log "ISTIOD_REMOTE_EP is ${ISTIOD_REMOTE_EP}"
kubectl config use-context $ctx2
# configure cluster2 with "remote pilot" to get its config (istiod running in cluster1)
pattern='ISTIOD_REMOTE_EP'
replace="${ISTIOD_REMOTE_EP}"
gsed -r -i "s|$pattern|$replace|g" scripts/cluster2.yaml
# install the istio sidecar injector (istiod), prometheus in cluster2
cd ../../common
INSTALL_YAML="../multicluster-gke/single-control-plane/scripts/cluster2.yaml" ./install_istio.sh
================================================
FILE: multicluster-gke/single-control-plane/scripts/6-connect-clusters.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
# Configure cross cluster service registries
# (let cluster 1 discover services in cluster 2)
cd ../../common/istio-1.5.2/bin
./istioctl x create-remote-secret --context=${ctx2} --name "cluster2" | \
kubectl apply -f - --context=${ctx1}
cd ../../../multicluster-gke/single-control-plane/
================================================
FILE: multicluster-gke/single-control-plane/scripts/7-deploy-hipstershop.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
source ./scripts/env.sh
# Deploy "most of" Hipstershop to cluster 1
kubectl config use-context $ctx1
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/kubernetes-manifests.yaml
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/istio-manifests.yaml
kubectl delete svc frontend-external
# delete cluster2 svcs from cluster1
for i in "${services2[@]}"
do
echo "Deleting ${i} from ${ctx1}"
kubectl delete deployment $i
done
# Deploy the rest of Hipstershop (cartservice, rediscart, recommendations, loadgenerator) to cluster2
kubectl config use-context $ctx2
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/kubernetes-manifests.yaml
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/istio-manifests.yaml
kubectl delete svc frontend-external
# delete cluster1 svcs from cluster2
for i in "${services1[@]}"
do
echo "Deleting ${i} from ${ctx2}"
kubectl delete deployment $i
done
================================================
FILE: multicluster-gke/single-control-plane/scripts/cleanup-delete-clusters.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Creates two GKE clusters in different regions.
set -euo pipefail
source ./scripts/env.sh
log "Deleting cluster1..."
gcloud container clusters delete cluster-1 --zone $cluster1zone --async
log "Deleting cluster2..."
gcloud container clusters delete cluster-2 --zone $cluster2zone --async
================================================
FILE: multicluster-gke/single-control-plane/scripts/cluster1.yaml
================================================
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
security:
selfSigned: false
global:
multiCluster:
clusterName: cluster1
network: ""
meshExpansion:
enabled: true
================================================
FILE: multicluster-gke/single-control-plane/scripts/cluster2.yaml
================================================
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
multiCluster:
clusterName: cluster2
network: ""
remotePilotAddress: ISTIO_REMOTE_EP
================================================
FILE: multicluster-gke/single-control-plane/scripts/env.sh
================================================
#!/usr/bin/env bash
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
log() { echo "$1" >&2; }
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified}"
gcloud config set project $PROJECT_ID
cluster1="cluster1"
cluster2="cluster2"
network1="network1"
cluster1zone="us-east1-b"
cluster2zone="us-central1-b"
ctx1="gke_${PROJECT_ID}_${cluster1zone}_cluster-1"
ctx2="gke_${PROJECT_ID}_${cluster2zone}_cluster-2"
ISTIO_VERSION=${ISTIO_VERSION:=1.5.2}
services1=("emailservice" "paymentservice" "shippingservice" "adservice" "checkoutservice" "currencyservice" "frontend" "productcatalogservice")
services2=("loadgenerator" "cartservice" "recommendationservice" "redis-cart")
================================================
FILE: multicluster-gke/vm-migration/README.md
================================================
# Virtual Machine Migration with Multicluster Istio
- [Introduction](#introduction)
- [Setup](#setup)
- [Deploy the sample application to GKE](#deploy-the-sample-application-to-gke)
- [Install Istio on the VM](#install-istio-on-the-vm)
- [Prepare for VM to GKE Migration](#prepare-for-vm-to-gke-migration)
- [Migrate productcatalog to GKE](#migrate-productcatalog-to-gke)
- [Complete the GKE Migration](#complete-the-gke-migration)
- [Cleanup](#cleanup)
## Introduction
Istio works with services running in Kubernetes containers, but it also works with virtual machines. Because of this, Istio can help you integrate legacy VM workloads into a modern, Kubernetes-based service mesh - and help you migrate the VM services to Kubernetes, when you're ready.
For instance, let's say we want to deploy a multi-service application. This application consists mostly of Kubernetes-ready microservices (running across two cloud datacenters in `us-west` and `us-east`), but one of the older services (`productcatalog`) runs in a virtual machine in `us-central`. We can still get all the benefits of Istio (telemetry, security, traffic policies) for that virtual machine service. Then, when we're ready to migrate `productcatalog` from a VM to a container running in one of our Kubernetes clusters, Istio can progressively - and safely - migrate traffic from the VM to the container version with zero downtime.
In this sample, we will set up multicluster Istio on two GKE clusters, then configure a GCE instance to join the mesh. Then we'll deploy a sample app across the two clusters and the VM. Finally, we'll deploy the VM service a Kubernetes pod alongside the VM instance, and use Istio traffic splitting to migrate from GCE to all GKE. We will work towards this final state, where the VM service is no longer needed -

## Setup
1. Set your project ID.
```
export PROJECT_ID="<your-project-id>"
```
2. Run the first script to create two GKE clusters and one GCE instance in your project.
```
./scripts/1-create-infra.sh
```
3. Wait for the clusters to be `RUNNING`.
```
watch gcloud container clusters list
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE
NODE_VERSION NUM_NODES STATUS
cluster2 us-east1-b 1.14.10-gke.27 35.196.192.71 n1-standard-2
1.14.10-gke.27 4 RUNNING
cluster1 us-west1-b 1.14.10-gke.27 34.83.227.203 n1-standard-2
1.14.10-gke.27 4 RUNNING
```
4. Create firewall rules to allow traffic from the GKE pods in both clusters to your GCE instance. This will allow traffic to move freely between the two GKE clusters and the service running on the VM.
```
./scripts/2-firewall.sh
```
5. Install the Istio control plane on both GKE clusters. This script also connects the two Istio control planes into one logical mesh by updating the KubeDNS stubdomain - this is what will allow cross-cluster GKE mesh traffic to resolve to local Kubernetes services on the opposite cluster. [See the Istio docs](https://istio.io/docs/setup/install/multicluster/gateways/#setup-dns) for more information.
```
./scripts/3-install-istio-gke.sh
```
## Deploy the sample application to GKE
1. Deploy the OnlineBoutique sample application -- minus one backend service, `productcatalog` -- across the two GKE clusters. Note that until we deploy `productcatalog` onto the VM, the app will be in an error state and the loadgenerator pod will not start. This is expected because productcatalog is unreachable for now.
```
./scripts/4-deploy-onlineboutique-gke.sh
```
Note that this script creates Istio `ServiceEntry` resources so that services across clusters can access each other via the `IngressGateway` running in the opposite cluster. For example, in cluster 2, we create a `ServiceEntry` for `adservice` (running in cluster1) to that the frontend (in cluster2) can reach adservice in the opposite cluster via the Kubernetes DNS name `adservice.default.global`:
```YAML
# this service entry lives in cluster 2
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: adservice-entry
spec:
addresses:
# this is a placeholder virtual IP, it's not used for routing
- 240.0.0.2
endpoints:
# this is the istio ingressgateway IP for cluster 1 (the actual routing IP)
- address: 35.230.67.174
ports:
grpc: 15443
hosts:
# this is the address the frontend uses to reach adservice
- adservice.default.global
# mesh internal means we own this service and it has a sidecar proxy
location: MESH_INTERNAL
ports:
- name: grpc
# adservice serves grpc traffic on this port #
number: 9555
protocol: GRPC
resolution: DNS
```
[See the Istio docs](https://istio.io/docs/setup/install/multicluster/gateways/#configure-the-example-services) for more details on how cross-cluster service discovery works.
## Install Istio on the VM
Now we're ready to install the Istio agent (sidecar proxy) on the GCE instance we provisioned earlier. This is the architecture we will set up:

1. Gather information about the Istio mesh running on GKE. This information is needed so that the Istio proxy on the VM can "call home" to a control plane, to receive proxy config, certs for mutual TLS, and know where to send metrics. Because we're running two Istio control planes, **we will configure the VM to "call home" to the Istio control plane running on cluster1.**
```
./scripts/5-prep-cluster1.sh
```
2. Install the Istio proxy on the VM, along with Docker. Then deploy `productcatalog` onto the VM as a raw Docker container. Note that you could use systemd or another deployment method to deploy your Istio-enabled service to the VM.
```
./scripts/6-prep-vm.sh
```
3. Add productcatalog to the logical mesh, via the `istioctl` tool. This command will create a `Service` and `ServiceEntry` for productcatalog running on the VM, to allow pods inside both clusters to reach `productcatalog` with a Kubernetes DNS name (`productcatalog.default.svc.cluster.local`), even though `productcatalog` isn't running in Kubernetes.
```
./scripts/7-add-vm-to-mesh.sh
```
The configuration across clusters now looks like this:

Note that we do this step for both clusters, because services on **both** cluster1 (recommendations, checkout) and cluster2 (frontend) must reach productcatalog on the VM.
4. Verify deployment. This script shows the pods running across both clusters, opens the Kiali service graph (for cluster1) in a browser tab, and outputs the Online frontend
```
./scripts/8-verify-deploy.sh
```
5. In a browser, navigate the IP shown at the end of the script output. You should see the OnlineBoutique frontend with a list of products - this shows that the frontend running on `cluster2` can reach both the services running on `cluster1` (eg. `currencyservice`) **and** the `productcatalog` service running on the VM, using the Kubernetes DNS names made possible by the Istio `ServiceEntry` resources we just created.

6. Open the Kiali service graph for cluster1. Log in with the demo credentials - `admin`/`admin`. You should see traffic going from two backend services -- `checkout` and `recommendations` to the ServiceEntry for `productcatalogservice`:

7. Open the Kiali service graph for cluster2. You should see traffic going from the frontend to `productcatalogservice` on the VM:

## Prepare for VM to GKE Migration
Now let's say we are ready to migrate `productcatalog` from GCE to one of our Istio-enabled GKE clusters. The first step to do this is to deploy `productcatalog` as a GKE pod, alongside the VM. To start, we will continue sending all traffic to the VM.
1. Deploy `productcatalog-gke` to cluster2, but don't send any traffic there yet. This script creates the Kubernetes and Istio resources to set up the VM-to-GKE migration - `Deployment` (cluster2), `Service` (cluster2), `ServiceEntry` (cluster1), and `VirtualService` (both clusters).
```
./scripts/9-deploy-productcatalog-gke.sh
```
Note the way we're "wrapping" a single VirtualService around two Kubernetes hostnames. This is what will let us split traffic across the GKE and VM versions of `productcatalog` in the next step. Here, `productcatalogservice` is the VM `ServiceEntry` already created on both clusters. `productcatalogservice-gke` is a separate Kubernetes service. For cluster2, `productcatalogservice-gke` is a **local** `Service`:
```YAML
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productcatalog-migration
spec:
hosts:
- productcatalogservice
http:
- route:
- destination:
host: productcatalogservice
weight: 0
- destination:
host: productcatalogservice-gke
weight: 100
```
For cluster1, productcatalog's hostname corresponds to an Istio ServiceEntry.
```YAML
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productcatalog-migration
spec:
hosts:
- productcatalogservice
http:
- route:
- destination:
host: productcatalogservice
weight: 0
- destination:
host: productcatalogservice-gke.default.global
weight: 100
```
## Migrate productcatalog to GKE
1. Update the two VirtualServices to send 20% of productcatalog traffic to the GKE pod running in `cluster2`, and send the remaining 80% of traffic to the VM.
```
./scripts/10-split-traffic.sh
```
Our Istio configuration now looks like this:

And the traffic split looks like this:

2. Return to the Kiali service graph to view the traffic splitting in action:

## Complete the GKE Migration
In a real production migration, you would continue updating the traffic percentages to slowly send more traffic to the GKE version of `productcatalog.`. Let's say we've done that and we're ready to send 100% of traffic to the GKE pod.
1. Complete the migration by updating both VirtualServices to send 100% of productcatalog traffic to the GKE pod, and 0% of traffic to the VM.
```
./scripts/11-complete-migration.sh
```
Our Istio config is now:

To create the final traffic state where all traffic is now within GKE:

You should also see in Kiali (cluster1 shown here) that 100% of productcatalog traffic is going to the GKE version:

The VM migration is complete! Now it would be safe to retire the VM, since all the app services are now running across our two GKE clusters.
## Cleanup
To clean up the resources (GKE clusters, VM) used in this tutorial:
```
./scripts/12-cleanup.sh
```
================================================
FILE: multicluster-gke/vm-migra
gitextract_ft7f4bst/
├── .github/
│ └── snippet-bot.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── common/
│ ├── default.yaml
│ └── install_istio.sh
├── internal-load-balancer/
│ ├── README.md
│ └── manifests/
│ ├── install.yaml
│ └── server-ilb.yaml
├── istio-canary-gke/
│ ├── README.md
│ └── canary/
│ ├── destinationrule.yaml
│ ├── productcatalog-v2.yaml
│ ├── rollback.yaml
│ └── vs-split-traffic.yaml
├── istio-stackdriver/
│ └── README.md
├── mesh-expansion-gce/
│ ├── README.md
│ └── scripts/
│ ├── 1-create-cluster.sh
│ ├── 2-create-vm.sh
│ ├── 3-install-istio.sh
│ ├── 4-deploy-hipstershop.sh
│ ├── 5-prep-cluster.sh
│ ├── 6-prep-vm.sh
│ ├── 7-add-to-mesh.sh
│ ├── 8-start-vm-istio.sh
│ ├── install.yaml
│ ├── vm-install-istio.sh
│ └── vm-run-products.sh
├── multicluster-gke/
│ ├── dual-control-plane/
│ │ ├── README.md
│ │ ├── cluster1/
│ │ │ ├── deployments.yaml
│ │ │ ├── istio-defaults.yaml
│ │ │ ├── service-entries.yaml
│ │ │ └── services-local.yaml
│ │ ├── cluster2/
│ │ │ ├── deployments.yaml
│ │ │ ├── istio-defaults.yaml
│ │ │ ├── service-entries.yaml
│ │ │ └── services-local.yaml
│ │ └── scripts/
│ │ ├── 1-create-gke-clusters.sh
│ │ ├── 2-install-istio.sh
│ │ ├── 3-configure-dns.sh
│ │ ├── 4-deploy-online-boutique.sh
│ │ ├── cleanup-delete-clusters.sh
│ │ ├── env.sh
│ │ └── install.yaml
│ ├── single-control-plane/
│ │ ├── README.md
│ │ └── scripts/
│ │ ├── 1-cluster-create.sh
│ │ ├── 2-get-credentials.sh
│ │ ├── 3-firewall.sh
│ │ ├── 4-cluster1-install.sh
│ │ ├── 5-cluster2-install.sh
│ │ ├── 6-connect-clusters.sh
│ │ ├── 7-deploy-hipstershop.sh
│ │ ├── cleanup-delete-clusters.sh
│ │ ├── cluster1.yaml
│ │ ├── cluster2.yaml
│ │ └── env.sh
│ └── vm-migration/
│ ├── README.md
│ ├── cluster1/
│ │ ├── deployments.yaml
│ │ ├── istio-defaults.yaml
│ │ ├── service-entries.yaml
│ │ └── services-local.yaml
│ ├── cluster2/
│ │ ├── deployments.yaml
│ │ ├── istio-defaults.yaml
│ │ ├── service-entries.yaml
│ │ └── services-local.yaml
│ ├── productcatalog-gke/
│ │ ├── deployment.yaml
│ │ ├── service-cluster2.yaml
│ │ ├── serviceentry-cluster1.yaml
│ │ ├── vs-0-cluster1.yaml
│ │ ├── vs-0-cluster2.yaml
│ │ ├── vs-100-cluster1.yaml
│ │ ├── vs-100-cluster2.yaml
│ │ ├── vs-20-cluster1.yaml
│ │ └── vs-20-cluster2.yaml
│ └── scripts/
│ ├── 1-create-infra.sh
│ ├── 10-split-traffic.sh
│ ├── 11-complete-migration.sh
│ ├── 12-cleanup.sh
│ ├── 2-firewall.sh
│ ├── 3-install-istio-gke.sh
│ ├── 4-deploy-onlineboutique-gke.sh
│ ├── 5-prep-cluster1.sh
│ ├── 6-prep-vm.sh
│ ├── 7-add-vm-to-mesh.sh
│ ├── 8-verify-deploy.sh
│ ├── 9-deploy-productcatalog-gke.sh
│ ├── env.sh
│ ├── install.yaml
│ ├── vm-install-istio.sh
│ └── vm-run-products.sh
├── multicluster-ingress/
│ ├── 1-create-clusters.sh
│ ├── 2-install-istio.sh
│ ├── 3-deploy-app.sh
│ ├── 4-verify-app.sh
│ ├── 5-prep-mci.sh
│ ├── 6-mci.sh
│ ├── 7-cleanup.sh
│ ├── README.md
│ ├── common.sh
│ ├── manifests/
│ │ ├── healthcheck.yaml
│ │ ├── ingress.yaml
│ │ └── istio-ingressgateway-patch.json
│ └── zone_printer/
│ ├── deployment.yaml
│ ├── gateway.yaml
│ ├── service.yaml
│ └── virtualservice.yaml
├── sample-apps/
│ ├── grpc-greeter-go/
│ │ ├── README.md
│ │ ├── client/
│ │ │ ├── .dockerignore
│ │ │ ├── .gcloudignore
│ │ │ ├── Dockerfile
│ │ │ ├── client.go
│ │ │ ├── go.mod
│ │ │ └── go.sum
│ │ ├── manifests/
│ │ │ ├── greeter-istio-destinationrule.yaml
│ │ │ ├── greeter-istio-gateway.yaml
│ │ │ ├── greeter-istio-virtualservice.yaml
│ │ │ ├── greeter-k8s.template.yaml
│ │ │ └── istio-operator.yaml
│ │ └── server/
│ │ ├── .dockerignore
│ │ ├── .gcloudignore
│ │ ├── Dockerfile
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── server.go
│ └── helloserver/
│ ├── README.md
│ ├── loadgen/
│ │ ├── Dockerfile
│ │ ├── Dockerfile-base
│ │ ├── loadgen.py
│ │ ├── loadgen.yaml
│ │ └── requirements.txt
│ └── server/
│ ├── Dockerfile
│ ├── server.py
│ └── server.yaml
├── security-intro/
│ ├── README.md
│ └── manifests/
│ ├── authz-frontend.yaml
│ ├── jwt-frontend-authz.yaml
│ ├── jwt-frontend-request.yaml
│ ├── mtls-default-ns.yaml
│ └── mtls-frontend.yaml
└── stackdriver-metrics/
├── README.md
└── istio-stackdriver-metrics.yaml
SYMBOL INDEX (15 symbols across 4 files)
FILE: sample-apps/grpc-greeter-go/client/client.go
constant defaultName (line 43) | defaultName = "world"
constant timeout (line 44) | timeout = 5 * time.Second
function main (line 47) | func main() {
FILE: sample-apps/grpc-greeter-go/server/server.go
type greeterServer (line 46) | type greeterServer struct
method SayHello (line 51) | func (s *greeterServer) SayHello(ctx context.Context, in *pb.HelloRequ...
type healthServer (line 65) | type healthServer struct
method Check (line 68) | func (s *healthServer) Check(ctx context.Context, in *healthpb.HealthC...
method Watch (line 74) | func (s *healthServer) Watch(in *healthpb.HealthCheckRequest, srv heal...
function main (line 78) | func main() {
FILE: sample-apps/helloserver/loadgen/loadgen.py
function exception_handler (line 22) | def exception_handler(request, exception):
function callserver (line 26) | def callserver():
FILE: sample-apps/helloserver/server/server.py
class S (line 20) | class S(BaseHTTPRequestHandler):
method _set_response (line 21) | def _set_response(self):
method do_GET (line 26) | def do_GET(self):
function run (line 32) | def run(server_class=HTTPServer, handler_class=S, port=8080):
Condensed preview — 141 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (614K chars).
[
{
"path": ".github/snippet-bot.yml",
"chars": 1,
"preview": "\n"
},
{
"path": ".gitignore",
"chars": 168,
"preview": ".DS_Store\n*.env\n*.pem\n*.tar.gz\ncluster-2\nistio_master.yaml\nistio-1*\nistio-2*\nistio-master.yaml\nistio-remote.yaml\nistio.y"
},
{
"path": "CONTRIBUTING.md",
"chars": 1173,
"preview": "# Contributing\n\n## Development Principles (for Googlers)\n\nThere are a few principles for developing or refactoring the s"
},
{
"path": "LICENSE",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 2364,
"preview": "# ⛵️ istio-samples\n\nThis repository contains Google Cloud Platform demos and sample code for [Istio](https://istio.io/)."
},
{
"path": "common/default.yaml",
"chars": 16967,
"preview": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "common/install_istio.sh",
"chars": 1625,
"preview": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "internal-load-balancer/README.md",
"chars": 9432,
"preview": "# Demo: Using a GCP Internal Load Balancer with Istio\n\nThis demo shows how to use an Internal Load Balancer (ILB) to con"
},
{
"path": "internal-load-balancer/manifests/install.yaml",
"chars": 18888,
"preview": "# ILB config source - https://github.com/istio/istio/issues/20033\napiVersion: install.istio.io/v1alpha1\nkind: IstioOpera"
},
{
"path": "internal-load-balancer/manifests/server-ilb.yaml",
"chars": 1356,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "istio-canary-gke/README.md",
"chars": 7529,
"preview": "# ProductCatalog Canary Deployment (GKE / Istio)\n\nThis demo accompanies [a GCP Blog Post](https://cloud.google.com/blog/"
},
{
"path": "istio-canary-gke/canary/destinationrule.yaml",
"chars": 971,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "istio-canary-gke/canary/productcatalog-v2.yaml",
"chars": 1699,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "istio-canary-gke/canary/rollback.yaml",
"chars": 969,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "istio-canary-gke/canary/vs-split-traffic.yaml",
"chars": 1079,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "istio-stackdriver/README.md",
"chars": 11114,
"preview": "# Istio and Stackdriver\n\nThis example demonstrates the ways you can use [Stackdriver](https://cloud.google.com/stackdriv"
},
{
"path": "mesh-expansion-gce/README.md",
"chars": 4542,
"preview": "# Demo: Integrating a Google Compute Engine VM with Istio\n\nThis demo shows how to connect a Google Compute Engine virtua"
},
{
"path": "mesh-expansion-gce/scripts/1-create-cluster.sh",
"chars": 1095,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "mesh-expansion-gce/scripts/2-create-vm.sh",
"chars": 1726,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "mesh-expansion-gce/scripts/3-install-istio.sh",
"chars": 1093,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "mesh-expansion-gce/scripts/4-deploy-hipstershop.sh",
"chars": 1532,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "mesh-expansion-gce/scripts/5-prep-cluster.sh",
"chars": 1643,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "mesh-expansion-gce/scripts/6-prep-vm.sh",
"chars": 1632,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "mesh-expansion-gce/scripts/7-add-to-mesh.sh",
"chars": 1007,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "mesh-expansion-gce/scripts/8-start-vm-istio.sh",
"chars": 962,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "mesh-expansion-gce/scripts/install.yaml",
"chars": 16391,
"preview": "apiVersion: install.istio.io/v1alpha1\nkind: IstioOperator\nspec:\n addonComponents:\n grafana:\n enabled: true\n "
},
{
"path": "mesh-expansion-gce/scripts/vm-install-istio.sh",
"chars": 1270,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "mesh-expansion-gce/scripts/vm-run-products.sh",
"chars": 983,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/dual-control-plane/README.md",
"chars": 7189,
"preview": "# Demo: Multicluster Istio - Gateway-Connected Clusters\n\nThis example shows how to orchestrate an application with [Isti"
},
{
"path": "multicluster-gke/dual-control-plane/cluster1/deployments.yaml",
"chars": 7190,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/dual-control-plane/cluster1/istio-defaults.yaml",
"chars": 994,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/dual-control-plane/cluster1/service-entries.yaml",
"chars": 2105,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/dual-control-plane/cluster1/services-local.yaml",
"chars": 2473,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/dual-control-plane/cluster2/deployments.yaml",
"chars": 6468,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/dual-control-plane/cluster2/istio-defaults.yaml",
"chars": 1723,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/dual-control-plane/cluster2/service-entries.yaml",
"chars": 2586,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/dual-control-plane/cluster2/services-local.yaml",
"chars": 1867,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/dual-control-plane/scripts/1-create-gke-clusters.sh",
"chars": 1528,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/dual-control-plane/scripts/2-install-istio.sh",
"chars": 1207,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/dual-control-plane/scripts/3-configure-dns.sh",
"chars": 1244,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/dual-control-plane/scripts/4-deploy-online-boutique.sh",
"chars": 1806,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/dual-control-plane/scripts/cleanup-delete-clusters.sh",
"chars": 941,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/dual-control-plane/scripts/env.sh",
"chars": 962,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/dual-control-plane/scripts/install.yaml",
"chars": 1714,
"preview": "apiVersion: install.istio.io/v1alpha1\nkind: IstioOperator\nspec:\n addonComponents:\n grafana:\n enabled: true\n "
},
{
"path": "multicluster-gke/single-control-plane/README.md",
"chars": 6116,
"preview": "# Demo: Multicluster Istio- Single Control Plane\n\nThis demo shows how to use Istio to orchestrate [an application](https"
},
{
"path": "multicluster-gke/single-control-plane/scripts/1-cluster-create.sh",
"chars": 1920,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/single-control-plane/scripts/2-get-credentials.sh",
"chars": 785,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/single-control-plane/scripts/3-firewall.sh",
"chars": 1265,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/single-control-plane/scripts/4-cluster1-install.sh",
"chars": 990,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/single-control-plane/scripts/5-cluster2-install.sh",
"chars": 1257,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/single-control-plane/scripts/6-connect-clusters.sh",
"chars": 932,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/single-control-plane/scripts/7-deploy-hipstershop.sh",
"chars": 1724,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/single-control-plane/scripts/cleanup-delete-clusters.sh",
"chars": 889,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/single-control-plane/scripts/cluster1.yaml",
"chars": 234,
"preview": "apiVersion: install.istio.io/v1alpha1\nkind: IstioOperator\nspec:\n values:\n security:\n selfSigned: false\n glob"
},
{
"path": "multicluster-gke/single-control-plane/scripts/cluster2.yaml",
"chars": 195,
"preview": "apiVersion: install.istio.io/v1alpha1\nkind: IstioOperator\nspec:\n values:\n global:\n multiCluster:\n cluste"
},
{
"path": "multicluster-gke/single-control-plane/scripts/env.sh",
"chars": 1213,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/README.md",
"chars": 10987,
"preview": "# Virtual Machine Migration with Multicluster Istio\n\n - [Introduction](#introduction)\n - [Setup](#setup)\n - [Deploy t"
},
{
"path": "multicluster-gke/vm-migration/cluster1/deployments.yaml",
"chars": 8325,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/vm-migration/cluster1/istio-defaults.yaml",
"chars": 994,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/vm-migration/cluster1/service-entries.yaml",
"chars": 1574,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/vm-migration/cluster1/services-local.yaml",
"chars": 2818,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/vm-migration/cluster2/deployments.yaml",
"chars": 5089,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/vm-migration/cluster2/istio-defaults.yaml",
"chars": 1723,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/vm-migration/cluster2/service-entries.yaml",
"chars": 2960,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/vm-migration/cluster2/services-local.yaml",
"chars": 1348,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-gke/vm-migration/productcatalog-gke/deployment.yaml",
"chars": 849,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: productcatalogservice-gke\nspec:\n selector:\n matchLabels:\n "
},
{
"path": "multicluster-gke/vm-migration/productcatalog-gke/service-cluster2.yaml",
"chars": 203,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: productcatalogservice-gke\nspec:\n ports:\n - name: grpc\n port: 3550\n "
},
{
"path": "multicluster-gke/vm-migration/productcatalog-gke/serviceentry-cluster1.yaml",
"chars": 363,
"preview": "apiVersion: networking.istio.io/v1alpha3\nkind: ServiceEntry\nmetadata:\n name: productcatalogservice-gke\nspec:\n addresse"
},
{
"path": "multicluster-gke/vm-migration/productcatalog-gke/vs-0-cluster1.yaml",
"chars": 329,
"preview": "apiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n name: productcatalog-migration\nspec:\n hosts:\n"
},
{
"path": "multicluster-gke/vm-migration/productcatalog-gke/vs-0-cluster2.yaml",
"chars": 314,
"preview": "apiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n name: productcatalog-migration\nspec:\n hosts:\n"
},
{
"path": "multicluster-gke/vm-migration/productcatalog-gke/vs-100-cluster1.yaml",
"chars": 329,
"preview": "apiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n name: productcatalog-migration\nspec:\n hosts:\n"
},
{
"path": "multicluster-gke/vm-migration/productcatalog-gke/vs-100-cluster2.yaml",
"chars": 314,
"preview": "apiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n name: productcatalog-migration\nspec:\n hosts:\n"
},
{
"path": "multicluster-gke/vm-migration/productcatalog-gke/vs-20-cluster1.yaml",
"chars": 329,
"preview": "apiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n name: productcatalog-migration\nspec:\n hosts:\n"
},
{
"path": "multicluster-gke/vm-migration/productcatalog-gke/vs-20-cluster2.yaml",
"chars": 314,
"preview": "apiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n name: productcatalog-migration\nspec:\n hosts:\n"
},
{
"path": "multicluster-gke/vm-migration/scripts/1-create-infra.sh",
"chars": 2264,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/10-split-traffic.sh",
"chars": 901,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/11-complete-migration.sh",
"chars": 920,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/12-cleanup.sh",
"chars": 960,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/2-firewall.sh",
"chars": 1550,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/3-install-istio-gke.sh",
"chars": 1792,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/4-deploy-onlineboutique-gke.sh",
"chars": 1803,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/5-prep-cluster1.sh",
"chars": 1646,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/6-prep-vm.sh",
"chars": 1564,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/7-add-vm-to-mesh.sh",
"chars": 1204,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/8-verify-deploy.sh",
"chars": 1075,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/9-deploy-productcatalog-gke.sh",
"chars": 1598,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/env.sh",
"chars": 1140,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/install.yaml",
"chars": 16490,
"preview": "apiVersion: install.istio.io/v1alpha1\nkind: IstioOperator\nspec:\n addonComponents:\n grafana:\n enabled: true\n "
},
{
"path": "multicluster-gke/vm-migration/scripts/vm-install-istio.sh",
"chars": 1270,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-gke/vm-migration/scripts/vm-run-products.sh",
"chars": 983,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-ingress/1-create-clusters.sh",
"chars": 1668,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-ingress/2-install-istio.sh",
"chars": 1037,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-ingress/3-deploy-app.sh",
"chars": 866,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-ingress/4-verify-app.sh",
"chars": 875,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-ingress/5-prep-mci.sh",
"chars": 1084,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-ingress/6-mci.sh",
"chars": 1017,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-ingress/7-cleanup.sh",
"chars": 1122,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-ingress/README.md",
"chars": 11175,
"preview": "# Geo-Aware Istio Multicluster Ingress\n- [Geo-Aware Istio Multicluster Ingress](#geo-aware-istio-multicluster-ingress)\n "
},
{
"path": "multicluster-ingress/common.sh",
"chars": 1011,
"preview": "#!/usr/bin/env bash\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "multicluster-ingress/manifests/healthcheck.yaml",
"chars": 1279,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-ingress/manifests/ingress.yaml",
"chars": 1043,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-ingress/manifests/istio-ingressgateway-patch.json",
"chars": 153,
"preview": "[\n {\n \"op\": \"replace\",\n \"path\": \"/spec/type\",\n \"value\": \"NodePort\"\n },\n {\n \"op\": \"remove\",\n"
},
{
"path": "multicluster-ingress/zone_printer/deployment.yaml",
"chars": 1099,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-ingress/zone_printer/gateway.yaml",
"chars": 969,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-ingress/zone_printer/service.yaml",
"chars": 922,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "multicluster-ingress/zone_printer/virtualservice.yaml",
"chars": 992,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "sample-apps/grpc-greeter-go/README.md",
"chars": 1134,
"preview": "# grpc-greeter-go\n\nThis sample application consists of a gRPC server and client.\n\nIt is a adapted from\n[the gRPC-Go hell"
},
{
"path": "sample-apps/grpc-greeter-go/client/.dockerignore",
"chars": 662,
"preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "sample-apps/grpc-greeter-go/client/.gcloudignore",
"chars": 679,
"preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "sample-apps/grpc-greeter-go/client/Dockerfile",
"chars": 1088,
"preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "sample-apps/grpc-greeter-go/client/client.go",
"chars": 2802,
"preview": "/*\n *\n * Original work Copyright 2015 gRPC authors.\n * Modified work Copyright 2020 Google LLC\n *\n * Licensed under the "
},
{
"path": "sample-apps/grpc-greeter-go/client/go.mod",
"chars": 843,
"preview": "// Copyright 2021 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "sample-apps/grpc-greeter-go/client/go.sum",
"chars": 109912,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
},
{
"path": "sample-apps/grpc-greeter-go/manifests/greeter-istio-destinationrule.yaml",
"chars": 916,
"preview": "\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "sample-apps/grpc-greeter-go/manifests/greeter-istio-gateway.yaml",
"chars": 996,
"preview": "\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "sample-apps/grpc-greeter-go/manifests/greeter-istio-virtualservice.yaml",
"chars": 980,
"preview": "\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "sample-apps/grpc-greeter-go/manifests/greeter-k8s.template.yaml",
"chars": 1576,
"preview": "\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "sample-apps/grpc-greeter-go/manifests/istio-operator.yaml",
"chars": 1270,
"preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "sample-apps/grpc-greeter-go/server/.dockerignore",
"chars": 662,
"preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "sample-apps/grpc-greeter-go/server/.gcloudignore",
"chars": 679,
"preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "sample-apps/grpc-greeter-go/server/Dockerfile",
"chars": 1336,
"preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "sample-apps/grpc-greeter-go/server/go.mod",
"chars": 843,
"preview": "// Copyright 2021 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "sample-apps/grpc-greeter-go/server/go.sum",
"chars": 109912,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
},
{
"path": "sample-apps/grpc-greeter-go/server/server.go",
"chars": 2899,
"preview": "/*\n *\n * Original work Copyright 2015 gRPC authors\n * Modified work Copyright 2021 Google LLC\n *\n * Licensed under the A"
},
{
"path": "sample-apps/helloserver/README.md",
"chars": 595,
"preview": "## Sample App: helloserver \n\nThe `helloserver` application is a small sample application designed to be used for \"hello "
},
{
"path": "sample-apps/helloserver/loadgen/Dockerfile",
"chars": 318,
"preview": "FROM gcr.io/google-samples/istio-samples/helloserver/loadgen-base as final\n\n# Enable unbuffered logging\nENV PYTHONUNBUFF"
},
{
"path": "sample-apps/helloserver/loadgen/Dockerfile-base",
"chars": 232,
"preview": "FROM python:3-slim as builder\n\nRUN apt-get -qq update \\\n && apt-get install -y --no-install-recommends \\\n g++ "
},
{
"path": "sample-apps/helloserver/loadgen/loadgen.py",
"chars": 1427,
"preview": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "sample-apps/helloserver/loadgen/loadgen.yaml",
"chars": 1691,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "sample-apps/helloserver/loadgen/requirements.txt",
"chars": 50,
"preview": "grequests==0.3.0\nrequests==2.31.0\nschedule==0.6.0\n"
},
{
"path": "sample-apps/helloserver/server/Dockerfile",
"chars": 544,
"preview": "FROM python:3.9-slim as base\nFROM base as builder\nRUN apt-get -qq update \\\n && apt-get install -y --no-install-recomm"
},
{
"path": "sample-apps/helloserver/server/server.py",
"chars": 1641,
"preview": "#!/usr/bin/env python3\n\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "sample-apps/helloserver/server/server.yaml",
"chars": 1387,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "security-intro/README.md",
"chars": 15915,
"preview": "# Demo: Introduction to Istio Security\n\nThis example demonstrates how to leverage [Istio's](https://istio.io/docs/concep"
},
{
"path": "security-intro/manifests/authz-frontend.yaml",
"chars": 966,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "security-intro/manifests/jwt-frontend-authz.yaml",
"chars": 1015,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "security-intro/manifests/jwt-frontend-request.yaml",
"chars": 1050,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "security-intro/manifests/mtls-default-ns.yaml",
"chars": 1204,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "security-intro/manifests/mtls-frontend.yaml",
"chars": 1250,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
},
{
"path": "stackdriver-metrics/README.md",
"chars": 4892,
"preview": "# Configuring Stackdriver Monitoring for Open Source Istio\n\n- [Background](#background)\n- [Stackdriver Adapter](#stackdr"
},
{
"path": "stackdriver-metrics/istio-stackdriver-metrics.yaml",
"chars": 30004,
"preview": "\n# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this "
}
]
About this extraction
This page contains the full source code of the GoogleCloudPlatform/istio-samples GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 141 files (572.4 KB), approximately 213.3k tokens, and a symbol index with 15 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.