mirror of https://github.com/istio/istio.io.git
Add microservices tutorial - first modules (#5111)
* Add intro, fix broken links/titles, set 80 columns * Clarified, expanded wording and made it consistent * Fixed curl case * Removed tutorial node and moved to examples node * Fixed PR comments
This commit is contained in:
parent
31d21ffbb4
commit
8a29b55cf5
|
@ -313,6 +313,7 @@ Kuat
|
|||
Kube
|
||||
Kubecon
|
||||
kubeconfig
|
||||
kubectl
|
||||
Kubelet
|
||||
kubelet
|
||||
Kubernetes
|
||||
|
@ -370,6 +371,7 @@ netmask
|
|||
networking.istio.io
|
||||
nginx
|
||||
NLBs
|
||||
Node.js
|
||||
nodePorts
|
||||
non-sandboxed
|
||||
normalization
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
---
|
||||
{{< warning >}}
|
||||
This is work in progress. We will add its sections in pieces. Your feedback is welcome at [discuss.istio.io](https://discuss.istio.io).
|
||||
{{< /warning >}}
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
title: Learn Microservices using Kubernetes and Istio
|
||||
description: This modular tutorial provides new users with hands-on experience using Istio for common microservices scenarios, one step at a time.
|
||||
weight: 40
|
||||
icon: classroom
|
||||
simple_list: true
|
||||
content_above: true
|
||||
---
|
||||
|
||||
It is intended for self-guided users or instructors who train
|
||||
others. It begins with the steps to set up a cluster to
|
||||
control an example microservice running on a local computer, and culminates into
|
||||
demonstrating several crucial microservice management tasks using Istio.
|
||||
|
||||
For the best experience, follow the modules in the order provided.
|
||||
|
||||
{{< boilerplate work-in-progress >}}
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
title: Prerequisites
|
||||
overview: Check the prerequisites for this tutorial.
|
||||
weight: 2
|
||||
---
|
||||
|
||||
{{< boilerplate work-in-progress >}}
|
||||
|
||||
For this tutorial you need a Kubernetes cluster with a namespace for the
|
||||
tutorial's modules and a local computer to run the commands. If you have your
|
||||
own cluster, ensure your cluster satisfies the prerequisites.
|
||||
|
||||
If you are in a workshop and the instructors provide a cluster, let
|
||||
them handle the cluster prerequisites, while you skip ahead to setup your local
|
||||
computer.
|
||||
|
||||
## Kubernetes cluster
|
||||
|
||||
Ensure the following conditions are met:
|
||||
|
||||
- You have administrator privileges on a Kubernetes cluster.
|
||||
- You can create a namespace in the cluster for each participant.
|
||||
|
||||
## Local computer
|
||||
|
||||
Ensure the following conditions are met:
|
||||
|
||||
- You have write access to the local computer's `/etc/hosts` file.
|
||||
- You have the ability and permission to download, install and run command line tools on the local computer.
|
||||
- You have Internet connectivity for the duration of the tutorial.
|
|
@ -0,0 +1,228 @@
|
|||
---
|
||||
title: Setup a Kubernetes Cluster
|
||||
overview: Set up your Kubernetes cluster for the tutorial.
|
||||
weight: 2
|
||||
---
|
||||
|
||||
{{< boilerplate work-in-progress >}}
|
||||
|
||||
In this module, you set up a Kubernetes cluster that has Istio installed and a
|
||||
namespace to use throughout the tutorial.
|
||||
|
||||
{{< warning >}}
|
||||
If you are in a workshop and the instructors provide a cluster for you,
|
||||
proceed to [setting up your local computer](/docs/examples/microservices-istio/setup-local-computer).
|
||||
{{</ warning >}}
|
||||
|
||||
1. Ensure you have access to a [Kubernetes cluster](https://kubernetes.io/docs/tutorials/kubernetes-basics/).
|
||||
You can use the [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/docs/quickstart) or the
|
||||
[IBM Cloud Kubernetes Service](https://cloud.ibm.com/docs/containers?topic=containers-getting-started).
|
||||
|
||||
1. Connect to your cluster and create an environment variable to store the name
|
||||
of a namespace that you will use when you run the tutorial commands.
|
||||
You can use any name, for example `tutorial`.
|
||||
|
||||
{{< text bash >}}
|
||||
$ export NAMESPACE=tutorial
|
||||
{{< /text >}}
|
||||
|
||||
1. Create the namespace:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl create namespace $NAMESPACE
|
||||
{{< /text >}}
|
||||
|
||||
{{< tip >}}
|
||||
If you are an instructor, you should allocate a separate namespace per each
|
||||
participant. The tutorial supports work in multiple namespaces
|
||||
simultaneously by multiple participants.
|
||||
{{< /tip >}}
|
||||
|
||||
1. Install Istio with strict mutual TLS enabled by selecting the `strict mutual
|
||||
TLS` tab when you follow [the Kubernetes installation steps](/docs/setup/install/kubernetes/#installation-steps).
|
||||
|
||||
1. [Enable Envoy's access logging](/docs/tasks/observability/logs/access-log/#enable-envoy-s-access-logging).
|
||||
|
||||
1. Create a Kubernetes Ingress resource for these common Istio services using
|
||||
the `kubectl` command shown. It is not necessary to be familiar with each of
|
||||
these services at this point in the tutorial.
|
||||
|
||||
- [Grafana](https://grafana.com/docs/guides/getting_started/)
|
||||
- [Jaeger](https://www.jaegertracing.io/docs/1.13/getting-started/)
|
||||
- [Prometheus](https://prometheus.io/docs/prometheus/latest/getting_started/)
|
||||
- [Kiali](https://www.kiali.io/documentation/getting-started/)
|
||||
|
||||
The `kubectl` command can accept an in-line configuration to create the
|
||||
Ingress resources for each service:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: istio-system
|
||||
namespace: istio-system
|
||||
spec:
|
||||
rules:
|
||||
- host: my-istio-dashboard.io
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: grafana
|
||||
servicePort: 3000
|
||||
- host: my-istio-tracing.io
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: tracing
|
||||
servicePort: 80
|
||||
- host: my-istio-logs-database.io
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: prometheus
|
||||
servicePort: 9090
|
||||
- host: my-kiali.io
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: kiali
|
||||
servicePort: 20001
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. Create a role to provide read access to the `istio-system` namespace. This
|
||||
role is required to limit permissions of the participants in the steps
|
||||
below.
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl apply -f - <<EOF
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: istio-system-access
|
||||
namespace: istio-system
|
||||
rules:
|
||||
- apiGroups: ["", "extensions", "apps"]
|
||||
resources: ["*"]
|
||||
verbs: ["get", "list"]
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. Create a service account for each participant:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: ${NAMESPACE}-user
|
||||
namespace: $NAMESPACE
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. Limit each participant's permissions. During the tutorial, participants only
|
||||
need to create resources in their namespace and to read resources from
|
||||
`istio-system` namespace. It is a good practice, even if using your own
|
||||
cluster, to avoid interfering with other namespaces in
|
||||
your cluster.
|
||||
|
||||
Create a role to allow read-write access to each participant's namespace.
|
||||
Bind the participant's service account to this role and to the role for
|
||||
reading resources from `istio-system`:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl apply -f - <<EOF
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: ${NAMESPACE}-access
|
||||
namespace: $NAMESPACE
|
||||
rules:
|
||||
- apiGroups: ["", "extensions", "apps", "networking.k8s.io", "networking.istio.io", "authentication.istio.io",
|
||||
"rbac.istio.io", "config.istio.io"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
---
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: ${NAMESPACE}-access
|
||||
namespace: $NAMESPACE
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: ${NAMESPACE}-user
|
||||
namespace: $NAMESPACE
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: ${NAMESPACE}-access
|
||||
---
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: ${NAMESPACE}-istio-system-access
|
||||
namespace: istio-system
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: ${NAMESPACE}-user
|
||||
namespace: $NAMESPACE
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: istio-system-access
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. Each participant needs to use their own Kubernetes configuration file. This configuration file specifies
|
||||
the cluster details, the service account, the credentials and the namespace of the participant.
|
||||
The `kubectl` command uses the configuration file to operate on the cluster.
|
||||
|
||||
Generate a Kubernetes configuration file for each participant:
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF > ./${NAMESPACE}-user-config.yaml
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
preferences: {}
|
||||
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: $(kubectl get secret $(kubectl get sa ${NAMESPACE}-user -n $NAMESPACE -o jsonpath={.secrets..name}) -n $NAMESPACE -o jsonpath='{.data.ca\.crt}')
|
||||
server: $(kubectl config view -o jsonpath="{.clusters[?(.name==\"$(kubectl config view -o jsonpath="{.contexts[?(.name==\"$(kubectl config current-context)\")].context.cluster}")\")].cluster.server}")
|
||||
name: ${NAMESPACE}-cluster
|
||||
|
||||
users:
|
||||
- name: ${NAMESPACE}-user
|
||||
user:
|
||||
as-user-extra: {}
|
||||
client-key-data: $(kubectl get secret $(kubectl get sa ${NAMESPACE}-user -n $NAMESPACE -o jsonpath={.secrets..name}) -n $NAMESPACE -o jsonpath='{.data.ca\.crt}')
|
||||
token: $(kubectl get secret $(kubectl get sa ${NAMESPACE}-user -n $NAMESPACE -o jsonpath={.secrets..name}) -n $NAMESPACE -o jsonpath={.data.token} | base64 --decode)
|
||||
|
||||
contexts:
|
||||
- context:
|
||||
cluster: ${NAMESPACE}-cluster
|
||||
namespace: ${NAMESPACE}
|
||||
user: ${NAMESPACE}-user
|
||||
name: ${NAMESPACE}
|
||||
|
||||
current-context: ${NAMESPACE}
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. If you are setting up the cluster for yourself, copy the
|
||||
`${NAMESPACE}-user-config.yaml` file mentioned in the previous steps to your
|
||||
local computer, where `${NAMESPACE}` is the name of the namespace you
|
||||
provided in the previous steps. For example, `tutorial-user-config.yaml`.
|
||||
You will need this file later in the tutorial.
|
||||
|
||||
If you are an instructor, send the generated configuration files to each
|
||||
participant who should copy it to their local computer.
|
||||
|
||||
Congratulations, you configured your cluster for the tutorials!
|
||||
|
||||
You are ready to [setup a local computer](/docs/examples/microservices-istio/setup-local-computer).
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
title: Setup a Local Computer
|
||||
overview: Set up your local computer for the tutorial.
|
||||
weight: 3
|
||||
---
|
||||
|
||||
{{< boilerplate work-in-progress >}}
|
||||
|
||||
In this module you prepare your local computer for the tutorial.
|
||||
|
||||
1. On your local computer, locate the `${NAMESPACE}-user-config.yaml` file you
|
||||
created earlier in the tutorial, where `${NAMESPACE}` is the name of your
|
||||
namespace. For example `tutorial-user-config.yaml`.
|
||||
|
||||
1. Install [curl](https://curl.haxx.se/download.html).
|
||||
|
||||
1. Install [Node.js](https://nodejs.org/en/download/).
|
||||
|
||||
1. Install [Docker](https://docs.docker.com/install/).
|
||||
|
||||
1. Install [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/).
|
||||
|
||||
1. Set the `KUBECONFIG` environment variable for the `${NAMESPACE}-user-config.yaml`
|
||||
configuration file:
|
||||
|
||||
{{< text bash >}}
|
||||
$ export KUBECONFIG=./${NAMESPACE}-user-config.yaml
|
||||
{{< /text >}}
|
||||
|
||||
1. Verify that the configuration took effect by printing the current namespace:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl config view -o jsonpath="{.contexts[?(@.name==\"$(kubectl config current-context)\")].context.namespace}"
|
||||
tutorial
|
||||
{{< /text >}}
|
||||
|
||||
You should see the name of your namespace in the output.
|
||||
|
||||
1. Download one of the [Istio release archives](https://github.com/istio/istio/releases) and extract
|
||||
the `istioctl` command line tool from the `bin` directory, and verify that you
|
||||
can run `istioctl` with the following command:
|
||||
|
||||
{{< text bash >}}
|
||||
$ istioctl version
|
||||
version.BuildInfo{Version:"release-1.1-20190214-09-16", GitRevision:"6113e155ac85e2485e30dfea2b80fd97afd3130a", User:"root", Host:"4496ae63-3039-11e9-86e9-0a580a2c0304", GolangVersion:"go1.10.4", DockerHub:"gcr.io/istio-release", BuildStatus:"Clean", GitTag:"1.1.0-snapshot.6-6-g6113e15"}
|
||||
{{< /text >}}
|
||||
|
||||
Congratulations, you configured your local computer!
|
||||
|
||||
You are ready to [run a single service locally](/docs/examples/microservices-istio/single/).
|
|
@ -0,0 +1,129 @@
|
|||
---
|
||||
title: Run a Microservice Locally
|
||||
overview: Learn how to work on a single service on your local machine.
|
||||
weight: 10
|
||||
---
|
||||
|
||||
{{< boilerplate work-in-progress >}}
|
||||
|
||||
Before the advent of microservice architecture, development teams built,
|
||||
deployed and ran the whole application as one large chunk of software. To test a
|
||||
small change in their module not merely by unit testing, the developers had to
|
||||
build the whole application. Therefore the builds took large amount of time.
|
||||
After the build, the developers deployed their version of the application into a
|
||||
test server. The developers ran the server either on a remote machine, or on their
|
||||
local computer. In the latter case, the developers had to install and operate a
|
||||
rather complex environment on their local computer.
|
||||
|
||||
In the era of microservice architecture, the developers write, build, test and
|
||||
run small software services. Builds are fast. With modern frameworks like
|
||||
[Node.js](https://nodejs.org/en/) there is no need to install and operate
|
||||
complex server environments to test a single service, since the service runs as
|
||||
a regular process. You do not have to deploy your service to some environment to
|
||||
merely test it, so you just build your service and run it immediately on your
|
||||
local computer.
|
||||
|
||||
This module covers the different aspects involved in developing a single service
|
||||
on a local machine. You don't need to write code though. Instead, you build,
|
||||
run, and test an existing service: `ratings`.
|
||||
|
||||
The `ratings` service is a small web app written in
|
||||
[Node.js](https://nodejs.org/en/) that can run on its own. It performs similar
|
||||
actions to those of other web apps:
|
||||
|
||||
- Listen to the port it receives as a parameter.
|
||||
- Expect `HTTP GET` requests on the `/ratings/{productID}` path and return the
|
||||
ratings of the product matching the value the client specifies for `productID`.
|
||||
- Expect `HTTP POST` requests on the `/ratings/{productID}` path and update the
|
||||
ratings of the product matching the value you specify for `productID`.
|
||||
|
||||
Follow these steps to download the code of the app, install its dependencies,
|
||||
and run it locally:
|
||||
|
||||
1. Download
|
||||
[the service's code]({{< github_blob >}}/samples/bookinfo/src/ratings/ratings.js)
|
||||
and
|
||||
[the package file]({{< github_blob >}}/samples/bookinfo/src/ratings/package.json)
|
||||
into a separate directory:
|
||||
|
||||
{{< text bash >}}
|
||||
$ mkdir ratings
|
||||
$ cd ratings
|
||||
$ curl -s {{< github_file >}}/samples/bookinfo/src/ratings/ratings.js -o ratings.js
|
||||
$ curl -s {{< github_file >}}/samples/bookinfo/src/ratings/package.json -o package.json
|
||||
{{< /text >}}
|
||||
|
||||
1. Skim the service's code and note the following elements on the code:
|
||||
- The web server's features:
|
||||
- listening to a port
|
||||
- handling requests and responses
|
||||
- The aspects related to HTTP:
|
||||
- headers
|
||||
- path
|
||||
- status code
|
||||
|
||||
{{< tip >}}
|
||||
In Node.js, the web server's functionality is embedded in the code of the application. A Node.js
|
||||
web application runs as a standalone process.
|
||||
{{< /tip >}}
|
||||
|
||||
1. Node.js applications are written in JavaScript, which means that there is no
|
||||
explicit compilation step. Instead, they use [just-in-time compilation](https://en.wikipedia.org/wiki/Just-in-time_compilation). To build a Node.js application, then means to install its dependencies. Install
|
||||
the dependencies of the `ratings` service in the same folder where you
|
||||
stored the service code and the package file:
|
||||
|
||||
{{< text bash >}}
|
||||
$ npm install
|
||||
npm notice created a lockfile as package-lock.json. You should commit this file.
|
||||
npm WARN ratings No description
|
||||
npm WARN ratings No repository field.
|
||||
npm WARN ratings No license field.
|
||||
|
||||
added 24 packages in 2.094s
|
||||
{{< /text >}}
|
||||
|
||||
1. Run the service, passing `9080` as a parameter. The application then listens on port 9080.
|
||||
|
||||
{{< text bash >}}
|
||||
$ npm start 9080
|
||||
> @ start /tmp/ratings
|
||||
> node ratings.js "9080"
|
||||
Server listening on: http://0.0.0.0:9080
|
||||
{{< /text >}}
|
||||
|
||||
{{< tip >}}
|
||||
The `ratings` service is a web app and you can communicate with it as you would
|
||||
with any other web app. You can use a browser or a command line web client like
|
||||
[`curl`](https://curl.haxx.se) or [`Wget`](https://www.gnu.org/software/wget/).
|
||||
Since you run the `ratings` service locally, you can also access it via the
|
||||
`localhost` hostname.
|
||||
{{< /tip >}}
|
||||
|
||||
1. Open [http://localhost:9080/ratings/7](http://localhost:9080/ratings/7) in
|
||||
your browser or access `ratings` using the `curl` command:
|
||||
|
||||
{{< text bash >}}
|
||||
$ curl localhost:9080/ratings/7
|
||||
{"id":7,"ratings":{"Reviewer1":5,"Reviewer2":4}}
|
||||
{{< /text >}}
|
||||
|
||||
1. Use the `POST` method of the `curl` command to set the ratings for the
|
||||
product to `1`:
|
||||
|
||||
{{< text bash >}}
|
||||
$ curl -X POST localhost:9080/ratings/7 -d '{"Reviewer1":1,"Reviewer2":1}'
|
||||
{"id":7,"ratings":{"Reviewer1":1,"Reviewer2":1}}
|
||||
{{< /text >}}
|
||||
|
||||
1. Check the updated ratings:
|
||||
|
||||
{{< text bash >}}
|
||||
$ curl localhost:9080/ratings/7
|
||||
{"id":7,"ratings":{"Reviewer1":1,"Reviewer2":1}}
|
||||
{{< /text >}}
|
||||
|
||||
1. Use `Ctrl-C` in the terminal running the service to stop it.
|
||||
|
||||
Congratulations, you can now build, test, and run a service on your local computer!
|
||||
|
||||
You are ready to learn how to package the service into a container.
|
Loading…
Reference in New Issue