From 2a4985b5f3e664fd5df6bb96ee35007fb48a7bee Mon Sep 17 00:00:00 2001 From: Jason Young Date: Wed, 28 Feb 2018 08:55:09 -0500 Subject: [PATCH 001/191] add example for disabling injection (#1021) --- _docs/setup/kubernetes/sidecar-injection.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index 0ab7dd6eee0f..a9ccdaa41f95 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -375,6 +375,25 @@ value `true` to the pod template spec to enable injection. `enabled` - The sidecar injector will inject the sidecar into pods by default. Add the `sidecar.istio.io/inject` annotation with value `false` to the pod template spec to disable injection. + +The following example uses the `sidecar.istio.io/inject` annotation to disable sidecar injection. + +```yaml +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: ignored +spec: + template: + metadata: + annotations: + sidecar.istio.io/inject: "false" + spec: + containers: + - name: ignored + image: tutum/curl + command: ["/bin/sleep","infinity"] +``` ##### _**template**_ From b75c48b395c0d1728b15a46a5f14a97676ef1da0 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Wed, 28 Feb 2018 10:07:20 -0800 Subject: [PATCH 002/191] Updated reference docs. (#1045) --- _docs/reference/commands/istio_ca.html | 105 ------ _docs/reference/commands/istioctl.html | 180 ---------- _docs/reference/commands/mixs.html | 320 +----------------- _docs/reference/commands/node_agent.html | 35 +- _docs/reference/commands/pilot-agent.html | 47 +-- _docs/reference/commands/pilot-discovery.html | 47 +-- .../reference/commands/sidecar-injector.html | 45 --- _docs/reference/config/adapters/datadog.html | 167 +++++++++ .../reference/config/istio.mesh.v1alpha1.html | 26 +- .../config/istio.mixer.v1.config.client.html | 100 ++++-- _docs/reference/config/template/apikey.html | 2 +- .../config/template/authorization.html | 4 +- .../reference/config/template/kubernetes.html | 18 +- .../reference/config/template/listentry.html | 2 +- _docs/reference/config/template/logentry.html | 8 +- _docs/reference/config/template/metric.html | 8 +- _docs/reference/config/template/quota.html | 4 +- .../config/template/servicecontrolreport.html | 6 +- 18 files changed, 302 insertions(+), 822 deletions(-) create mode 100644 _docs/reference/config/adapters/datadog.html diff --git a/_docs/reference/commands/istio_ca.html b/_docs/reference/commands/istio_ca.html index 0c1277eff8c5..d78718a77356 100644 --- a/_docs/reference/commands/istio_ca.html +++ b/_docs/reference/commands/istio_ca.html @@ -15,11 +15,6 @@ ---alsologtostderr - -log to standard error as well as files - - --cert-chain <string> Path to the certificate chain file (default ``) @@ -65,21 +60,11 @@ Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - --log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`) @@ -115,11 +100,6 @@ The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`) ---logtostderr - -log to standard error instead of files - - --max-workload-cert-ttl <duration> The max TTL of issued workload certificates (default `168h0m0s`) @@ -160,11 +140,6 @@ Path to the CA signing key file (default ``) ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - --upstream-auth <string> Specifies how the Istio CA is authenticated to the upstream CA. (default `mtls`) @@ -180,16 +155,6 @@ Path to the certificate for authenticating upstream CA. (default ``) ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - - --workload-cert-grace-period-ratio <float32> The workload certificate rotation grace period, as a ratio of the workload certificate TTL. (default `0.5`) @@ -218,11 +183,6 @@

istio_ca probe

---alsologtostderr - -log to standard error as well as files - - --interval <duration> Duration used for checking the target file's last modified time. (default `0s`) @@ -233,21 +193,11 @@

istio_ca probe

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - --log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`) @@ -283,30 +233,10 @@

istio_ca probe

The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`) ---logtostderr - -log to standard error instead of files - - --probe-path <string> Path of the file for checking the availability. (default ``) - ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

istio_ca version

@@ -321,31 +251,16 @@

istio_ca version

---alsologtostderr - -log to standard error as well as files - - --log_as_json Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - --log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`) @@ -381,29 +296,9 @@

istio_ca version

The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`) ---logtostderr - -log to standard error instead of files - - --short -s Displays a short form of the version information - ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - diff --git a/_docs/reference/commands/istioctl.html b/_docs/reference/commands/istioctl.html index 4755b2c76219..64fbf7cec95f 100644 --- a/_docs/reference/commands/istioctl.html +++ b/_docs/reference/commands/istioctl.html @@ -36,11 +36,6 @@ Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -90,16 +85,6 @@ -p Istio host platform (default `kube`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

istioctl context-create

@@ -139,11 +124,6 @@

istioctl context-create

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -193,16 +173,6 @@

istioctl context-create

-p Istio host platform (default `kube`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

Examples

@@ -242,11 +212,6 @@

istioctl create

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -296,16 +261,6 @@

istioctl create

-p Istio host platform (default `kube`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

Examples

@@ -343,11 +298,6 @@

istioctl delete

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -397,16 +347,6 @@

istioctl delete

-p Istio host platform (default `kube`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

Examples

@@ -444,11 +384,6 @@

istioctl deregister

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -498,16 +433,6 @@

istioctl deregister

-p Istio host platform (default `kube`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

istioctl gen-deploy

@@ -567,11 +492,6 @@

istioctl gen-deploy

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -627,20 +547,10 @@

istioctl gen-deploy

Istio host platform (default `kube`) ---v <Level> --v -log level for V logs (default `0`) - - --values <string> Path to the Helm values.yaml file used to render YAML deployments locally when --out=yaml. Flag values are ignored in favor of using the file directly. (default ``) - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

Examples

@@ -673,11 +583,6 @@

istioctl get

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -732,16 +637,6 @@

istioctl get

-p Istio host platform (default `kube`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

Examples

@@ -845,11 +740,6 @@

istioctl kube-inject

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -930,20 +820,10 @@

istioctl kube-inject

Docker tag (default `unknown`) ---v <Level> --v -log level for V logs (default `0`) - - --verbosity <int> Runtime verbosity (default `2`) - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

Examples

@@ -993,11 +873,6 @@

istioctl proxy-config

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -1047,16 +922,6 @@

istioctl proxy-config

-p Istio host platform (default `kube`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

Examples

@@ -1100,11 +965,6 @@

istioctl register

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -1159,16 +1019,6 @@

istioctl register

-s Service account to link to the service (default `default`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

istioctl replace

@@ -1203,11 +1053,6 @@

istioctl replace

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -1257,16 +1102,6 @@

istioctl replace

-p Istio host platform (default `kube`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

Examples

@@ -1299,11 +1134,6 @@

istioctl version

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -1358,15 +1188,5 @@

istioctl version

-s Displays a short form of the version information - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - diff --git a/_docs/reference/commands/mixs.html b/_docs/reference/commands/mixs.html index 41e7d6f2e80e..288a8fb7fe08 100644 --- a/_docs/reference/commands/mixs.html +++ b/_docs/reference/commands/mixs.html @@ -13,41 +13,6 @@ Description - ---alsologtostderr - -log to standard error as well as files - - ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - ---logtostderr - -log to standard error instead of files - - ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

mixs crd

@@ -59,41 +24,6 @@

mixs crd

Description - ---alsologtostderr - -log to standard error as well as files - - ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - ---logtostderr - -log to standard error instead of files - - ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

mixs crd adapter

@@ -107,41 +37,6 @@

mixs crd adapter

Description - ---alsologtostderr - -log to standard error as well as files - - ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - ---logtostderr - -log to standard error instead of files - - ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

mixs crd all

@@ -155,41 +50,6 @@

mixs crd all

Description - ---alsologtostderr - -log to standard error as well as files - - ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - ---logtostderr - -log to standard error instead of files - - ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

mixs crd instance

@@ -203,41 +63,6 @@

mixs crd instance

Description - ---alsologtostderr - -log to standard error as well as files - - ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - ---logtostderr - -log to standard error instead of files - - ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

mixs probe

@@ -252,11 +77,6 @@

mixs probe

---alsologtostderr - -log to standard error as well as files - - --interval <duration> Duration used for checking the target file's last modified time. (default `0s`) @@ -267,21 +87,11 @@

mixs probe

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - --log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`) @@ -317,30 +127,10 @@

mixs probe

The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`) ---logtostderr - -log to standard error instead of files - - --probe-path <string> Path of the file for checking the availability. (default ``) - ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

mixs server

@@ -360,11 +150,6 @@

mixs server

Max number of goroutines in the adapter worker pool (default `1024`) ---alsologtostderr - -log to standard error as well as files - - --apiWorkerPoolSize <int> Max number of goroutines in the API worker pool (default `1024`) @@ -400,21 +185,11 @@

mixs server

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - --log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`) @@ -450,11 +225,6 @@

mixs server

The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`) ---logtostderr - -log to standard error instead of files - - --maxConcurrentStreams <uint> Maximum number of outstanding RPCs per connection (default `1024`) @@ -475,6 +245,11 @@

mixs server

TCP port to use for Mixer's gRPC API (default `9091`) +--profile + +Enable profiling via web interface host:port/debug/pprof + + --readinessProbeInterval <duration> Interval of updating file for the readiness probe. (default `0s`) @@ -490,11 +265,6 @@

mixs server

If true, each request to Mixer will be executed in a single go routine (useful for debugging) ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - --trace_jaeger_url <string> URL of Jaeger HTTP collector (example: 'http://jaeger:14268/api/traces?format=jaeger.thrift'). (default ``) @@ -514,16 +284,6 @@

mixs server

Use the new runtime code for processing requests. - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

mixs validator

@@ -538,11 +298,6 @@

mixs validator

---alsologtostderr - -log to standard error as well as files - - --external-admission-webook-name <string> the name of the external admission webhook registration. Needs to be a domain with at least three segments separated by dots. (default `mixer-webhook.istio.io`) @@ -553,21 +308,6 @@

mixs validator

Use a Kubernetes configuration file instead of in-cluster configuration (default ``) ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - ---logtostderr - -log to standard error instead of files - - --namespace <string> the namespace where this webhook is deployed (default `istio-system`) @@ -588,26 +328,11 @@

mixs validator

The name of k8s secret where the certificates are stored (default ``) ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - --target-namespaces <stringArray> the list of namespaces where changes should be validated. Empty means to validate everything. Used for test only. (default `[]`) ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - - --webhook-name <string> the name of the webhook (default `istio-mixer-webhook`) @@ -626,44 +351,9 @@

mixs version

---alsologtostderr - -log to standard error as well as files - - ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - ---log_dir <string> - -If non-empty, write log files in this directory (default ``) - - ---logtostderr - -log to standard error instead of files - - --short -s Displays a short form of the version information - ---stderrthreshold <severity> - -logs at or above this threshold go to stderr (default `2`) - - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - diff --git a/_docs/reference/commands/node_agent.html b/_docs/reference/commands/node_agent.html index 76c6ecd37b77..860b74c9e9d4 100644 --- a/_docs/reference/commands/node_agent.html +++ b/_docs/reference/commands/node_agent.html @@ -15,29 +15,24 @@ ---aws-root-cert <string> - -Root Certificate file in AWS environment (default `/etc/certs/root-cert.pem`) - - --ca-address <string> Istio CA address (default `istio-ca:8060`) ---env <string> +--cert-chain <string> -Node Environment : onprem | gcp | aws (default `onprem`) +Node Agent identity cert file (default `/etc/certs/cert-chain.pem`) ---gcp-ca-address <string> +--env <string> -Istio CA address in GCP environment (default `istio-ca:8060`) +Node Environment : unspecified | onprem | gcp | aws (default `unspecified`) ---gcp-root-cert <string> +--key <string> -Root Certificate file in GCP environment (default `/etc/certs/root-cert.pem`) +Node Agent private key file (default `/etc/certs/key.pem`) --key-size <int> @@ -90,24 +85,14 @@ The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`) ---onprem-cert-chain <string> - -Node Agent identity cert file in on premise environment (default `/etc/certs/cert-chain.pem`) - - ---onprem-key <string> - -Node identity private key file in on premise environment (default `/etc/certs/key.pem`) - - ---onprem-root-cert <string> +--org <string> -Root Certificate file in on premise environment (default `/etc/certs/root-cert.pem`) +Organization for the cert (default ``) ---org <string> +--root-cert <string> -Organization for the cert (default ``) +Root Certificate file (default `/etc/certs/root-cert.pem`) --workload-cert-ttl <duration> diff --git a/_docs/reference/commands/pilot-agent.html b/_docs/reference/commands/pilot-agent.html index 3e04853895fb..b05b31e6fd07 100644 --- a/_docs/reference/commands/pilot-agent.html +++ b/_docs/reference/commands/pilot-agent.html @@ -18,11 +18,6 @@ Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -62,16 +57,6 @@ The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

pilot-agent proxy

@@ -128,7 +113,7 @@

pilot-agent proxy

--discoveryAddress <string> -Address of the discovery service exposing xDS (e.g. istio-pilot:8080) (default `istio-pilot:15003`) +Address of the discovery service exposing xDS (e.g. istio-pilot:8080) (default `istio-pilot:15007`) --discoveryRefreshDelay <duration> @@ -161,11 +146,6 @@

pilot-agent proxy

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -236,16 +216,6 @@

pilot-agent proxy

IP Address and Port of a statsd UDP listener (e.g. 10.75.241.127:9125) (default ``) ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - - --zipkinAddress <string> Address of the Zipkin service (e.g. zipkin:9411) (default ``) @@ -269,11 +239,6 @@

pilot-agent version

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -318,15 +283,5 @@

pilot-agent version

-s Displays a short form of the version information - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - diff --git a/_docs/reference/commands/pilot-discovery.html b/_docs/reference/commands/pilot-discovery.html index 45795848d78e..6ad1a7063225 100644 --- a/_docs/reference/commands/pilot-discovery.html +++ b/_docs/reference/commands/pilot-discovery.html @@ -18,11 +18,6 @@ Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -62,16 +57,6 @@ The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

pilot-discovery discovery

@@ -176,11 +161,6 @@

pilot-discovery discovery

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -256,19 +236,9 @@

pilot-discovery discovery

Controller resync interval (default `1m0s`) ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - - --webhookEndpoint <string> -Webhook API endpoint (supports DNS, IP, and unix domain socket. (default ``) +Webhook API endpoint (supports http://sockethost, and unix:///absolute/path/to/socket (default ``) @@ -289,11 +259,6 @@

pilot-discovery version

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -338,15 +303,5 @@

pilot-discovery version

-s Displays a short form of the version information - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - diff --git a/_docs/reference/commands/sidecar-injector.html b/_docs/reference/commands/sidecar-injector.html index 078ce7a076c5..1d65d5b41b96 100644 --- a/_docs/reference/commands/sidecar-injector.html +++ b/_docs/reference/commands/sidecar-injector.html @@ -35,11 +35,6 @@ Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -99,16 +94,6 @@ File containing the x509 private key matching --tlsCertFile. (default `/etc/istio/certs/key.pem`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

sidecar-injector probe

@@ -148,11 +133,6 @@

sidecar-injector probe

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -217,16 +197,6 @@

sidecar-injector probe

File containing the x509 private key matching --tlsCertFile. (default `/etc/istio/certs/key.pem`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) -

sidecar-injector version

@@ -261,11 +231,6 @@

sidecar-injector version

Whether to format output as JSON or in plain console-friendly format ---log_backtrace_at <traceLocation> - -when logging hits line file:N, emit a stack trace (default `:0`) - - --log_callers Include caller information, useful for debugging @@ -330,15 +295,5 @@

sidecar-injector version

File containing the x509 private key matching --tlsCertFile. (default `/etc/istio/certs/key.pem`) - ---v <Level> --v -log level for V logs (default `0`) - - ---vmodule <moduleSpec> - -comma-separated list of pattern=N settings for file-filtered logging (default ``) - diff --git a/_docs/reference/config/adapters/datadog.html b/_docs/reference/config/adapters/datadog.html new file mode 100644 index 000000000000..4316166baaec --- /dev/null +++ b/_docs/reference/config/adapters/datadog.html @@ -0,0 +1,167 @@ +--- +title: Datadog +overview: Adapter to deliver metrics to a dogstatsd agent for delivery to DataDog +location: https://istio.io/docs/reference/config/adapters/datadog.html +layout: protoc-gen-docs +number_of_entries: 3 +--- +

The dogstatsd adapter is designed to deliver Istio metric instances to a +listening DataDog agent.

+ +

Params

+
+

Configuration parameter for the DataDog adapter. These params control how Mixer telemetry is transformed and sent to a dogstatsd agent.

+ +

The adapter assumes that a dogstatsd agent is running as a sidecar or at some other endpoint that the Mixer can reach. +Any dimension that is a part of the metric is converted to a tag automatically. The configuration of the DataDog agent/daemon is outside the scope of the adapter.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
addressstring +

Address of the dogstatsd server. +Default: localhost:8125

+ +
prefixstring +

Prefix to prepend to all metrics handled by the adapter. Metric “bar” with prefix “foo.” becomes “foo.bar” in DataDog. +Default: “”

+ +
bufferLengthint32 +

Number of individual metrics to buffer before flushing metrics to the network. When buffered, metrics are flushed every 100ms or when the buffer is filled. +When buffer is 0, metrics are not buffered. +Default: 0

+ +
globalTagsmap<string, string> +

Tags to add to every metric. “global”: “tag” becomes “global:tag” in DataDog +Default: []

+ +
sampleRatedouble +

Chance that any particular metric is sampled when emitted; can take the range [0, 1]. +Default: 1

+ +
metricsmap<string, Params.MetricInfo> +

Map of a specific metric instance name -> info. If a metric’s instnace name is not in the map then the metric will not be exported to DataDog.

+ +
+
+

Params.MetricInfo

+
+

Describes how to represent this metric in DataDog

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
namestring +

Name of the metric in DataDog

+ +
typeParams.MetricInfo.Type +

The type of metric

+ +
tagsmap<string, string> +

Tags to add to the metric in addition to the dimensions. “tag”: “val” becomes “tag:val” in DataDog +Default: []

+ +
+
+

Params.MetricInfo.Type

+
+

Describes the type of metric

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
UNKNOWN_TYPE +

Default Unknown Type

+ +
COUNTER +

Increments a DataDog counter

+ +
GAUGE +

Sets the new value of a DataDog gauge

+ +
DISTRIBUTION +

DISTRIBUTION is converted to a Timing Histogram for metrics with a time unit and a Histogram for all other units

+ +
+
diff --git a/_docs/reference/config/istio.mesh.v1alpha1.html b/_docs/reference/config/istio.mesh.v1alpha1.html index 62d75e831368..59a4d50cb0b3 100644 --- a/_docs/reference/config/istio.mesh.v1alpha1.html +++ b/_docs/reference/config/istio.mesh.v1alpha1.html @@ -331,6 +331,14 @@

ProxyConfig

Path to the proxy binary

+ + + +proxyBootstrapTemplatePath +string + +

Path to the proxy bootstrap template file

+ @@ -472,7 +480,23 @@

ProxyConfig

pilot ServerAddress -

Address of the discovery service exposing xDS.

+

Deprecated, use discoverymtlsaddress/discoveryplainaddress instead.

+ + + + +discoveryMtlsAddress +string + +

Address of the discovery service exposing xDS with mTLS connection.

+ + + + +discoveryPlainAddress +string + +

Address of the discovery service exposing xDS with plain text connection.

diff --git a/_docs/reference/config/istio.mixer.v1.config.client.html b/_docs/reference/config/istio.mixer.v1.config.client.html index 5cc3f20e37fc..b2de35928469 100644 --- a/_docs/reference/config/istio.mixer.v1.config.client.html +++ b/_docs/reference/config/istio.mixer.v1.config.client.html @@ -3,7 +3,7 @@ overview: Configuration state for the Mixer client library location: https://istio.io/docs/reference/config/istio.mixer.v1.config.client.html layout: protoc-gen-docs -number_of_entries: 24 +number_of_entries: 25 ---

APIKey

@@ -765,6 +765,59 @@

JWT.Location

For example, query=jwt_token.

+ + + + +
+

NetworkFailPolicy

+
+

Specifies the behavior when the client is unable to connect to Mixer.

+ + + + + + + + + + + + + + + + +
FieldTypeDescription
policyNetworkFailPolicy.FailPolicy +

Specifies the behavior when the client is unable to connect to Mixer.

+ +
+
+

NetworkFailPolicy.FailPolicy

+
+

Describes the policy.

+ + + + + + + + + + + + + + + + @@ -990,6 +1043,16 @@

ServiceConfig

+ + + + + @@ -1144,9 +1207,10 @@

TransportConfig

- + @@ -1187,36 +1251,6 @@

TransportConfig

NOTE: Any value other than the default “mixer_server” will require the Istio Grafana dashboards to be reconfigured to use the new name.

- - - -
NameDescription
FAIL_OPEN +

If network connection fails, request is allowed and delivered to the service.

+ +
FAIL_CLOSE +

If network connection fails, request is rejected.

+

End user authentication policy.

+
networkFailPolicyNetworkFailPolicy +

Specifies the behavior when the client is unable to connect to Mixer. +This is the service-level policy. It overrides +mesh-level policy.

+
networkFailPolicyTransportConfig.NetworkFailPolicyNetworkFailPolicy -

Specifies the policy when failed to connect to Mixer server.

+

Specifies the behavior when the client is unable to connect to Mixer. +This is the mesh level policy. The default value for policy is FAIL_OPEN.

-
-

TransportConfig.NetworkFailPolicy

-
-

NetworkFailPolicy defines behavior when network connection -failure occurs.

- - - - - - - - - - - - - - - - diff --git a/_docs/reference/config/template/apikey.html b/_docs/reference/config/template/apikey.html index d406e1d40599..d24bca8d6aba 100644 --- a/_docs/reference/config/template/apikey.html +++ b/_docs/reference/config/template/apikey.html @@ -69,7 +69,7 @@

Template

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -102,7 +102,7 @@

Template

- + @@ -120,7 +120,7 @@

Template

- + From 879d80b9902d3e69834548a120b4ac3e9de2ecd7 Mon Sep 17 00:00:00 2001 From: Oliver Liu Date: Wed, 28 Feb 2018 13:46:36 -0800 Subject: [PATCH 003/191] Add task for Istio CA health check. (#1038) * Add task for Istio CA health check. * Small fix. * Small fix. --- _docs/tasks/security/health-check.md | 143 ++++++++++++++++++ _docs/tasks/security/per-service-mtls.md | 2 +- _docs/tasks/security/plugin-ca-cert.md | 6 +- .../security/role-based-access-control.md | 2 +- 4 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 _docs/tasks/security/health-check.md diff --git a/_docs/tasks/security/health-check.md b/_docs/tasks/security/health-check.md new file mode 100644 index 000000000000..b2acb7467552 --- /dev/null +++ b/_docs/tasks/security/health-check.md @@ -0,0 +1,143 @@ +--- +title: Enabling Istio CA health check +overview: This task shows how to enable Istio CA health check. + +order: 70 + +layout: docs +type: markdown +--- +{% include home.html %} + +This task shows how to enable Istio CA health check. Note this is an alpha feature since Istio V0.6. + +Since Istio V0.6, Istio CA has a health check feature that can be optionally enabled. +By default, the normal Istio deployment process does not enable this feature. +Currently, the health check feature is able to detect the failures of the CA CSR signing service, +by periodically sending CSRs to the API. More health check features are coming shortly. + +The Istio CA contains a _prober client_ module that periodically checks the CA's status (currently only the health +status of the gRPC server). +If the Istio CA is healthy, the _prober client_ updates the _modificate time_ of the _health status file_ +(the file is always empty). Otherwise, it does nothing. Istio CA relies on a +[K8s liveness and readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) +with command line to check the _modification time_ of the _health status file_ on the pod. +If the file is not updated for a period, the probe will be triggered and Kubelet will restart the CA container. + +Note: because the Istio CA health check currently only monitors the health status of CSR service API, +this feature is not needed if the production setup is not using the +[Istio Mesh Expansion]({{home}}/docs/setup/kubernetes/mesh-expansion.html) (which requires the CSR service API). + +## Before you begin + +* Set up Istio by following the instructions in the + [quick start]({{home}}/docs/setup/kubernetes/quick-start.html). + Note that authentication should be enabled at step 5 in the + [installation steps]({{home}}/docs/setup/kubernetes/quick-start.html#installation-steps). + +## Deploying the Istio CA with health check + +Deploy the Istio CA with health check enabled. + +```bash +kubectl apply -f install/kubernetes/istio-ca-with-health-check.yaml +``` + +Deploy the `istio-ca` service so that the CSR service can be found by the health checker. + +```bash +cat < Date: Thu, 1 Mar 2018 07:09:53 -0800 Subject: [PATCH 004/191] Updates troubleshooting guide to add pilot (#1037) --- _help/troubleshooting.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/_help/troubleshooting.md b/_help/troubleshooting.md index b7964a5ef381..d090e997783a 100644 --- a/_help/troubleshooting.md +++ b/_help/troubleshooting.md @@ -12,6 +12,38 @@ redirect_from: /troubleshooting Oh no! You're having trouble? Below is a list of solutions to common problems. +## Verifying connectivity to Istio Pilot + +Verifying connectivity to Pilot is a useful troubleshooting step. Every proxy container in the service mesh should be able to communicate with Pilot. This can be accomplished in a few simple steps: + +1. Get the name of the Istio Ingress pod: +```bash +INGRESS_POD_NAME=$(kubectl get po -n istio-system | grep ingress | awk '{print$1}') +``` + +1. Exec into the Istio Ingress pod: +```bash +kubectl exec -it $INGRESS_POD_NAME -n istio-system /bin/bash +``` + +1. Unless you installed Istio using the debug proxy image (`istioctl kube-inject --debug=true`), you need to +install curl. +```bash +apt-get update && apt-get install -y curl +``` + +1. Test connectivity to Pilot using cURL. The following example cURL's the v1 registration API using default Pilot configuration parameters and mTLS enabled: +```bash +curl -k --cert /etc/certs/cert-chain.pem --cacert /etc/certs/root-cert.pem --key /etc/certs/key.pem https://istio-pilot:15003/v1/registration +``` + +If mTLS is disabled: +```bash +curl http://istio-pilot:15003/v1/registration +``` + +You should receive a response listing the "service-key" and "hosts" for each service in the mesh. + ## No traces appearing in Zipkin when running Istio locally on Mac Istio is installed and everything seems to be working except there are no traces showing up in Zipkin when there should be. From db6b6d993b44bb104454dc60dd01108928edd581 Mon Sep 17 00:00:00 2001 From: embs Date: Fri, 2 Mar 2018 13:17:20 -0300 Subject: [PATCH 005/191] Fix misnamed link (#1050) --- _docs/concepts/policy-and-control/mixer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/concepts/policy-and-control/mixer.md b/_docs/concepts/policy-and-control/mixer.md index 977a09364b19..c6b20fefd4ea 100644 --- a/_docs/concepts/policy-and-control/mixer.md +++ b/_docs/concepts/policy-and-control/mixer.md @@ -88,7 +88,7 @@ operator is responsible for: - Configuring a set of *handlers* for Mixer-generated data. Handlers are configured adapters (adapters being binary plugins as described - [below](#adapters)). Providing a `statsd` adapter with the IP address for a + [here](#adapters)). Providing a `statsd` adapter with the IP address for a statsd backend is an example of handler configuration. - Configuring a set of *instances* for Mixer to generate based on attributes and From aacdcfc159e13c31babddeac51e72e91dbdb4563 Mon Sep 17 00:00:00 2001 From: Jason Young Date: Fri, 2 Mar 2018 20:29:59 -0500 Subject: [PATCH 006/191] update document generation for istioctl (#1047) --- scripts/grab_reference_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/grab_reference_docs.sh b/scripts/grab_reference_docs.sh index aa03b3965b53..0b213ca36e64 100755 --- a/scripts/grab_reference_docs.sh +++ b/scripts/grab_reference_docs.sh @@ -74,7 +74,7 @@ done # get_command_doc $WORK_DIR/istio/broker/cmd/brks brks get_command_doc $WORK_DIR/istio/mixer/cmd/mixc mixc get_command_doc $WORK_DIR/istio/mixer/cmd/mixs mixs -get_command_doc $WORK_DIR/istio/pilot/cmd/istioctl istioctl +get_command_doc $WORK_DIR/istio/istioctl/cmd/istioctl istioctl get_command_doc $WORK_DIR/istio/pilot/cmd/pilot-agent pilot-agent get_command_doc $WORK_DIR/istio/pilot/cmd/pilot-discovery pilot-discovery get_command_doc $WORK_DIR/istio/pilot/cmd/sidecar-injector sidecar-injector From 5315de7a4b337ba4b3f138879f01c3986597e82a Mon Sep 17 00:00:00 2001 From: mtail Date: Fri, 2 Mar 2018 17:48:27 -0800 Subject: [PATCH 007/191] Hack to get ownership of Google analytics account for the site. --- analytics.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 analytics.txt diff --git a/analytics.txt b/analytics.txt new file mode 100644 index 000000000000..da352da37d84 --- /dev/null +++ b/analytics.txt @@ -0,0 +1 @@ +GooGhywoiu9839t543j0s7543uw1 - pls add mtail@google.com to GA account UA-98480406 with ‘Manage Users and Edit’ permissions - date 03/02/2018 From 9460f5bef21e18760d86b7a17a5f21f39e791950 Mon Sep 17 00:00:00 2001 From: mtail Date: Fri, 2 Mar 2018 19:04:42 -0800 Subject: [PATCH 008/191] Don't need the analytics hack no more... --- analytics.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 analytics.txt diff --git a/analytics.txt b/analytics.txt deleted file mode 100644 index da352da37d84..000000000000 --- a/analytics.txt +++ /dev/null @@ -1 +0,0 @@ -GooGhywoiu9839t543j0s7543uw1 - pls add mtail@google.com to GA account UA-98480406 with ‘Manage Users and Edit’ permissions - date 03/02/2018 From 5e075d4c27914300d1acb2615a1db668a8a725f5 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Sun, 4 Mar 2018 14:04:01 -0800 Subject: [PATCH 009/191] Make the rake test ensure that we use {{home}} consistently. (#1053) We now generate the test site into a subdirectory such that we can ensure all links are correctly using {{home}}, which makes the site work correctly once archived. Fixed a bunch of broken cases. --- .gitignore | 1 + Rakefile | 6 ++++-- _about/notes/0.3.md | 2 ++ _blog/2017/0.1-canary.md | 2 ++ _docs/concepts/policy-and-control/mixer.md | 2 ++ _docs/concepts/security/mutual-tls.md | 2 ++ _docs/concepts/traffic-management/overview.md | 2 ++ _docs/concepts/traffic-management/request-routing.md | 1 + _docs/concepts/what-is-istio/overview.md | 1 + _docs/index.md | 4 ++-- _docs/reference/config/mixer/expression-language.md | 2 ++ _docs/tasks/traffic-management/circuit-breaking.md | 1 + _docs/tasks/traffic-management/ingress.md | 3 ++- _docs/tasks/traffic-management/mirroring.md | 6 ++++-- _rake_config_override.yml | 2 ++ 15 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 _rake_config_override.yml diff --git a/.gitignore b/.gitignore index e2ecac6289f3..ffc759f48fa1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ _site +_rakesite _static_site .bundle config_override.yml diff --git a/Rakefile b/Rakefile index 3582bd8fc57a..3cfb235b8ea9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,7 +1,9 @@ require 'html-proofer' task :test do - sh "bundle exec jekyll build --incremental" + sh "rm -fr _rakesite" + sh "mkdir _rakesite" + sh "bundle exec jekyll build --config _config.yml,_rake_config_override.yml" typhoeus_configuration = { :timeout => 30, # :verbose => true @@ -17,5 +19,5 @@ task :test do :url_ignore => [/localhost|github\.com\/istio\/istio\.github\.io\/edit\/master\//], :typhoeus => typhoeus_configuration, } - HTMLProofer.check_directory("./_site", options).run + HTMLProofer.check_directory("./_rakesite", options).run end diff --git a/_about/notes/0.3.md b/_about/notes/0.3.md index eb4162949b66..adacbbc41314 100644 --- a/_about/notes/0.3.md +++ b/_about/notes/0.3.md @@ -8,6 +8,8 @@ type: markdown redirect_from: /docs/welcome/notes/0.3.html --- +{% include home.html %} + ## General Starting with 0.3, Istio is switching to a monthly release cadence. We hope this will help accelerate our ability diff --git a/_blog/2017/0.1-canary.md b/_blog/2017/0.1-canary.md index bcf45c083a98..8008761559be 100644 --- a/_blog/2017/0.1-canary.md +++ b/_blog/2017/0.1-canary.md @@ -12,6 +12,8 @@ type: markdown redirect_from: "/blog/canary-deployments-using-istio.html" --- +{% include home.html %} + One of the benefits of the [Istio]({{home}}) project is that it provides the control needed to deploy canary services. The idea behind canary deployment (or rollout) is to introduce a new version of a service by first testing it using a small percentage of user traffic, and then if all goes well, increase, possibly gradually in increments, the percentage while simultaneously phasing out the old version. If anything goes wrong along the way, we abort and rollback to the previous version. In its simplest form, the traffic sent to the canary version is a randomly selected percentage of requests, but in more sophisticated schemes it can be based on the region, user, or other properties of the request. Depending on your level of expertise in this area, you may wonder why Istio's support for canary deployment is even needed, given that platforms like Kubernetes already provide a way to do [version rollout](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment) and [canary deployment](https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#canary-deployments). Problem solved, right? Well, not exactly. Although doing a rollout this way works in simple cases, it’s very limited, especially in large scale cloud environments receiving lots of (and especially varying amounts of) traffic, where autoscaling is needed. diff --git a/_docs/concepts/policy-and-control/mixer.md b/_docs/concepts/policy-and-control/mixer.md index c6b20fefd4ea..edbb0f40465c 100644 --- a/_docs/concepts/policy-and-control/mixer.md +++ b/_docs/concepts/policy-and-control/mixer.md @@ -8,6 +8,8 @@ layout: docs type: markdown --- +{% include home.html %} + The page explains Mixer's role and general architecture. ## Background diff --git a/_docs/concepts/security/mutual-tls.md b/_docs/concepts/security/mutual-tls.md index fb02fd45b873..99bd9354dc08 100644 --- a/_docs/concepts/security/mutual-tls.md +++ b/_docs/concepts/security/mutual-tls.md @@ -7,6 +7,8 @@ layout: docs type: markdown --- +{% include home.html %} + ## Overview Istio Auth's aim is to enhance the security of microservices and their communication without requiring service code changes. It is responsible for: diff --git a/_docs/concepts/traffic-management/overview.md b/_docs/concepts/traffic-management/overview.md index e2002fd2b724..a3c48a3dcd42 100644 --- a/_docs/concepts/traffic-management/overview.md +++ b/_docs/concepts/traffic-management/overview.md @@ -8,6 +8,8 @@ layout: docs type: markdown --- +{% include home.html %} + This page provides an overview of how traffic management works in Istio, including the benefits of its traffic management principles. It assumes that you've already read [What Is Istio?]({{home}}/docs/concepts/what-is-istio/overview.html) diff --git a/_docs/concepts/traffic-management/request-routing.md b/_docs/concepts/traffic-management/request-routing.md index 7c318c44a0c9..7c61cb5068a9 100644 --- a/_docs/concepts/traffic-management/request-routing.md +++ b/_docs/concepts/traffic-management/request-routing.md @@ -7,6 +7,7 @@ order: 20 layout: docs type: markdown --- +{% include home.html %} This page describes how requests are routed between services in an Istio service mesh. diff --git a/_docs/concepts/what-is-istio/overview.md b/_docs/concepts/what-is-istio/overview.md index b43a0becb2a3..7919029982b3 100644 --- a/_docs/concepts/what-is-istio/overview.md +++ b/_docs/concepts/what-is-istio/overview.md @@ -7,6 +7,7 @@ order: 15 layout: docs type: markdown --- +{% include home.html %} This document introduces Istio: an open platform to connect, manage, and secure microservices. Istio provides an easy way to create a network of deployed services with load balancing, service-to-service authentication, monitoring, and more, without requiring any changes in service code. You add Istio support to services by deploying a special sidecar proxy throughout your environment that intercepts all network communication between microservices, configured and managed using Istio's control plane functionality. diff --git a/_docs/index.md b/_docs/index.md index ad2cc2950de3..59d648f16ce7 100644 --- a/_docs/index.md +++ b/_docs/index.md @@ -19,8 +19,8 @@ is where you can learn about what Istio does and how it does it. the Istio control plane in various environments, as well as instructions for installing the sidecar in the application deployment. Quick start instructions are available for - [Kubernetes]({{docs}}/docs/setup/kubernetes/quick-start.html) and - [Docker Compose w/ Consul]({{docs}}/docs/setup/consul/quick-start.html). + [Kubernetes]({{home}}/docs/setup/kubernetes/quick-start.html) and + [Docker Compose w/ Consul]({{home}}/docs/setup/consul/quick-start.html). - [Tasks]({{home}}/docs/tasks/). Tasks show you how to do a single directed activity with Istio. diff --git a/_docs/reference/config/mixer/expression-language.md b/_docs/reference/config/mixer/expression-language.md index 616b1760a4c1..22d9ea006c0d 100644 --- a/_docs/reference/config/mixer/expression-language.md +++ b/_docs/reference/config/mixer/expression-language.md @@ -8,6 +8,8 @@ layout: docs type: markdown --- +{% include home.html %} + {% capture mixerConfig %}{{home}}/docs/concepts/policy-and-control/mixer-config.html{% endcapture %} This page describes how to use the Mixer config expression language (CEXL). diff --git a/_docs/tasks/traffic-management/circuit-breaking.md b/_docs/tasks/traffic-management/circuit-breaking.md index 7a8f949b39ab..8f5ccba3a2b8 100644 --- a/_docs/tasks/traffic-management/circuit-breaking.md +++ b/_docs/tasks/traffic-management/circuit-breaking.md @@ -7,6 +7,7 @@ order: 50 layout: docs type: markdown --- +{% include home.html %} This task demonstrates the circuit-breaking capability for resilient applications. Circuit breaking allows developers to write applications that limit the impact of failures, latency spikes, and other undesirable effects of network peculiarities. This task will show how to configure circuit breaking for connections, requests, and outlier detection. diff --git a/_docs/tasks/traffic-management/ingress.md b/_docs/tasks/traffic-management/ingress.md index 761a43224ef2..a967eb36a159 100644 --- a/_docs/tasks/traffic-management/ingress.md +++ b/_docs/tasks/traffic-management/ingress.md @@ -7,13 +7,14 @@ order: 30 layout: docs type: markdown --- +{% include home.html %} This task describes how to configure Istio to expose a service outside of the service mesh cluster. In a Kubernetes environment, the [Kubernetes Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) allows users to specify services that should be exposed outside the cluster. It allows one to define a backend service per virtual host and path. -Once the Istio Ingress specification is defined, the traffic entering the cluster is directed through the `istio-ingress` service. As a result, Istio features, for example, monitoring and route rules, can be applied to the traffic entering the cluster. +Once the Istio Ingress specification is defined, traffic entering the cluster is directed through the `istio-ingress` service. As a result, Istio features, for example, monitoring and route rules, can be applied to the traffic entering the cluster. The Istio Ingress specification is based on the standard [Kubernetes Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) specification, with the following differences: diff --git a/_docs/tasks/traffic-management/mirroring.md b/_docs/tasks/traffic-management/mirroring.md index 2aec571cdb0b..2b9e5756a400 100644 --- a/_docs/tasks/traffic-management/mirroring.md +++ b/_docs/tasks/traffic-management/mirroring.md @@ -1,14 +1,16 @@ --- title: Mirroring -overview: This task demonstrates the traffic shadowing/mirroring capabilities of Istio +overview: Demonstrates Istio's traffic shadowing/mirroring capabilities order: 60 layout: docs type: markdown --- +{% include home.html %} -This task demonstrates the traffic shadowing/mirroring capabilites of Istio. Traffic mirroring is a powerful concept that allows feature teams to bring changes to production with as little risk as possible. Mirroring brings a copy of live traffic to a mirrored service and happens out of band of the critical request path for the primary service. +This task demonstrates Istio's traffic shadowing/mirroring capabilities. Traffic mirroring is a powerful concept that allows feature teams to bring +changes to production with as little risk as possible. Mirroring brings a copy of live traffic to a mirrored service and happens out of band of the critical request path for the primary service. ## Before you begin diff --git a/_rake_config_override.yml b/_rake_config_override.yml new file mode 100644 index 000000000000..ec34e33ff380 --- /dev/null +++ b/_rake_config_override.yml @@ -0,0 +1,2 @@ +destination: _rakesite/test +baseurl: /test From b4d664bf357d78b93c08b30dd2de04e935439867 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Mon, 5 Mar 2018 09:46:41 -0800 Subject: [PATCH 010/191] Reduce the visual weight of code blocks so they don't break up the page so much. (#1054) --- _sass/base/_common.scss | 10 +++------- _sass/themes/_dark.scss | 3 ++- _sass/themes/_light.scss | 1 + 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/_sass/base/_common.scss b/_sass/base/_common.scss index e529f5de2e9d..18680dda2e39 100644 --- a/_sass/base/_common.scss +++ b/_sass/base/_common.scss @@ -146,18 +146,14 @@ thead+tbody tr:first-child td:last-child { pre { margin: 1em; max-height: 31em; - border: 1px solid $boxBorderColor; - border-left: 7px solid $boxBorderColor; + border: 1px solid $codeBlockBorderColor; + border-left: 5px solid $codeBlockBorderColor; border-radius: 4px; - background-image: linear-gradient(transparent 50%, rgba(69,142,209,0.04) 50%); - background-size: 3em 3em; - background-origin: content-box; - background-attachment: local; box-shadow: 3px 3px 8px $codeBlockShadowColor; code { display: block; - padding-left: 1em; + padding: .5em; } } diff --git a/_sass/themes/_dark.scss b/_sass/themes/_dark.scss index 8945a98f43e5..914b7d092807 100644 --- a/_sass/themes/_dark.scss +++ b/_sass/themes/_dark.scss @@ -28,7 +28,8 @@ $glossaryHeaderColor: lighten($gray, 35%); $searchButtonColor: $light-gray; $blockQuoteBackgroundColor: $dark-gray; $deprecatedBackgroundColor: silver; -$codeBlockShadowColor: #a7a7a7; +$codeBlockShadowColor: #777777; +$codeBlockBorderColor: #777777; $boxBorderColor: $textColor; $headerLightShadowColor: rgba(0, 0, 0, .14); diff --git a/_sass/themes/_light.scss b/_sass/themes/_light.scss index a4201a608a9d..a3fa414c49e4 100644 --- a/_sass/themes/_light.scss +++ b/_sass/themes/_light.scss @@ -29,6 +29,7 @@ $searchButtonColor: $light-gray; $blockQuoteBackgroundColor: $light-gray; $deprecatedBackgroundColor: silver; $codeBlockShadowColor: #a7a7a7; +$codeBlockBorderColor: #dddddd; $boxBorderColor: $secondBrandColor; $headerLightShadowColor: rgba(0, 0, 0, .14); From 8d8fd083992fcd36bf3f2bbc479f02290492ad48 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Mon, 5 Mar 2018 11:05:26 -0800 Subject: [PATCH 011/191] Introduce support for building the site in "preliminary" mode. (#1052) --- _data/istio.yml | 3 ++- _docs/setup/kubernetes/quick-start.md | 6 +++--- _faq/general/what-deployment-environment.md | 2 +- _includes/footer.html | 8 +++++++- _includes/header.html | 4 +++- _layouts/base.html | 6 ++++++ _sass/base/_brand_colors_preliminary.scss | 4 ++++ css/dark_theme.scss | 2 ++ css/light_theme.scss | 2 ++ index.html | 2 ++ 10 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 _sass/base/_brand_colors_preliminary.scss diff --git a/_data/istio.yml b/_data/istio.yml index 16433d647fbc..fbefb2b2682a 100644 --- a/_data/istio.yml +++ b/_data/istio.yml @@ -1,4 +1,5 @@ -version: 0.6 (preliminary) +version: 0.6 +preliminary: false archive: false archive_date: DD-MMM-YYYY search_engine_id: "013699703217164175118:veyyqmfmpj4" diff --git a/_docs/setup/kubernetes/quick-start.md b/_docs/setup/kubernetes/quick-start.md index 64e48548b6b8..1e61b7587fe2 100644 --- a/_docs/setup/kubernetes/quick-start.md +++ b/_docs/setup/kubernetes/quick-start.md @@ -91,9 +91,9 @@ curl -L https://git.io/getLatestIstio | sh - * The `istioctl` client binary in the `bin/` directory. `istioctl` is used when manually injecting Envoy as a sidecar proxy and for creating routing rules and policies. * The `istio.VERSION` configuration file -1. Change directory to istio package. For example, if the package is istio-{{ site.data.istio.version }} +1. Change directory to istio package. For example, if the package is istio-{{site.data.istio.version}} ```bash -cd istio-{{ site.data.istio.version }} +cd istio-{{site.data.istio.version}} ``` 1. Add the `istioctl` client to your PATH. @@ -191,7 +191,7 @@ kubectl create -f <(istioctl kube-inject -f .yaml) kubectl delete -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml ``` -* Uninstall Istio core components. For the {{ site.data.istio.version }} release, the uninstall +* Uninstall Istio core components. For the {{site.data.istio.version}} release, the uninstall deletes the RBAC permissions, the `istio-system` namespace, and hierarchically all resources under it. It is safe to ignore errors for non-existent resources because they may have been deleted hierarchically. diff --git a/_faq/general/what-deployment-environment.md b/_faq/general/what-deployment-environment.md index 1ed655e0ce9e..e8b7cadedd05 100644 --- a/_faq/general/what-deployment-environment.md +++ b/_faq/general/what-deployment-environment.md @@ -6,6 +6,6 @@ type: markdown {% include home.html %} Istio is designed and built to be platform-independent. For our -{{ site.data.istio.version }} release, Istio supports environments running +{{site.data.istio.version}} release, Istio supports environments running container orchestration platforms such as Kubernetes (v1.7.4 or greater) and Nomad (with Consul). diff --git a/_includes/footer.html b/_includes/footer.html index 0ceca9a33a07..d98d3327efdd 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -45,7 +45,13 @@
{% if site.data.istio.archive %}

Istio Archive {{site.data.istio.version}}

+ {% elsif site.data.istio.preliminary %} +

Istio Preliminary {{site.data.istio.version}}

{% else %}

Istio

{% endif %} From d613d953cafbe4a10a797b0e4d9162192e960e31 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Mon, 5 Mar 2018 16:06:41 -0800 Subject: [PATCH 012/191] Notes for 0.6 (#1048) --- _about/notes/0.6.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 _about/notes/0.6.md diff --git a/_about/notes/0.6.md b/_about/notes/0.6.md new file mode 100644 index 000000000000..c72ce6043541 --- /dev/null +++ b/_about/notes/0.6.md @@ -0,0 +1,44 @@ +--- +title: Istio 0.6 + +order: 95 + +layout: about +type: markdown +--- +{% include home.html %} + +In addition to the usual pile of bug fixes and perf improvements, this release includes the new or +updated features detailed below. + +## Networking + +- **Custom Envoy Config**. Pilot now supports ferrying custom Envoy config to the +proxy. [Learn more](https://github.com/mandarjog/istioluawebhook) + +## Mixer adapters + +- **SolarWinds**. Mixer can now interface to AppOptics and Papertrail. +[Learn more]({{home}}/docs/reference/config/adapters/solarwinds.html) + +- **Redisquota**. Mixer now supports a Redis-based adapter for rate limit tracking. +[Learn more]({{home}}/docs/reference/config/adapters/redisquota.html) + +- **Datadog**. Mixer now provides an adapter to deliver metric data to a Datadog agent. +[Learn more]({{home}}/docs/reference/config/adapters/datadog.html) + +## Other + +- **Separate Check & Report Clusters**. When configuring Envoy, it's now possible to use different clusters +for Mixer instances that are used for Mixer's Check functionality from those used for Mixer's Report +functionality. This may be useful in large deployments for better scaling of Mixer instances. + +- **Monitoring Dashboards**. There are now preliminary Mixer & Pilot monitoring dashboard in Grafana. + +- **Servicegraph Visualization**. Servicegraph has a new visualization. [Learn more]({{home}}/docs/tasks/telemetry/servicegraph.html). + +- **Liveness and Readiness Probes**. Istio components now provide canonical liveness and readiness +probe support to help ensure mesh infrastructure health. [Learn more]({{home}}/docs/tasks/security/health-check.html) + +- **Egress Policy and Telemetry**. Istio can monitor traffic to external services defined by EgressRule or External Service. Istio can also apply +Mixer policies on this traffic. From ff48219c68d71898af64d9a57edbacaabcafb249 Mon Sep 17 00:00:00 2001 From: mtail Date: Mon, 5 Mar 2018 16:21:39 -0800 Subject: [PATCH 013/191] Refresh version selection menu given 0.6. --- _data/releases.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_data/releases.yml b/_data/releases.yml index 2dd152b30fae..9f1e6db95312 100644 --- a/_data/releases.yml +++ b/_data/releases.yml @@ -1,7 +1,7 @@ -- name: 0.6 (preliminary) - url: https://archive.istio.io/v0.6 -- name: 0.5 +- name: 0.6 url: https://istio.io +- name: 0.5 + url: https://archive.istio.io/v0.5 - name: 0.4 url: https://archive.istio.io/v0.4 - name: 0.3 From 4a725f4f2cecc1553e0b6282e92858fc1ca06085 Mon Sep 17 00:00:00 2001 From: Krishna Pagadala Date: Mon, 5 Mar 2018 18:18:34 -0800 Subject: [PATCH 014/191] update instructions for mesh expansion (#1056) * update instructions for mesh expansion * remove ISTIO_STAGING references --- _docs/setup/kubernetes/mesh-expansion.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/_docs/setup/kubernetes/mesh-expansion.md b/_docs/setup/kubernetes/mesh-expansion.md index a5e978135b02..0d8eb7f6593d 100644 --- a/_docs/setup/kubernetes/mesh-expansion.md +++ b/_docs/setup/kubernetes/mesh-expansion.md @@ -201,13 +201,9 @@ Get the debian packages from [github releases](https://github.com/istio/istio/re # Note: This will be replaced with an 'apt-get' command once the repositories are setup. source istio.VERSION # defines version and URLs env var - curl -L ${PILOT_DEBIAN_URL}/istio-agent.deb > ${ISTIO_STAGING}/istio-agent.deb - curl -L ${AUTH_DEBIAN_URL}/istio-auth-node-agent.deb > ${ISTIO_STAGING}/istio-auth-node-agent.deb - curl -L ${PROXY_DEBIAN_URL}/istio-proxy.deb > ${ISTIO_STAGING}/istio-proxy.deb + curl -L ${PILOT_DEBIAN_URL}/istio-sidecar.deb > istio-sidecar.deb - dpkg -i istio-proxy-envoy.deb - dpkg -i istio-agent.deb - dpkg -i istio-auth-node-agent.deb + dpkg -i istio-sidecar.deb systemctl start istio systemctl start istio-auth-node-agent From 3fbb31b233bd900132bbde22491a0b18cca11042 Mon Sep 17 00:00:00 2001 From: Jianfei Hu Date: Mon, 5 Mar 2018 22:24:57 -0800 Subject: [PATCH 015/191] Specify --debug option to use docker.io/istio/proxy_debug image for (#1057) deployment. --- _docs/guides/bookinfo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/guides/bookinfo.md b/_docs/guides/bookinfo.md index 77c34654f8a8..69521cf0c8e7 100644 --- a/_docs/guides/bookinfo.md +++ b/_docs/guides/bookinfo.md @@ -85,7 +85,7 @@ To start the application, follow the instructions below corresponding to your Is use the following command instead: ```bash - kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo.yaml) + kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) ``` If you are using a cluster with From 02074eb9ceb5260af7dea776c8d249af455a834d Mon Sep 17 00:00:00 2001 From: mtail Date: Wed, 7 Mar 2018 05:51:46 -0800 Subject: [PATCH 016/191] Update reference docs. --- _docs/reference/commands/pilot-discovery.html | 10 ++++++++++ _docs/reference/config/istio.mesh.v1alpha1.html | 16 ++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/_docs/reference/commands/pilot-discovery.html b/_docs/reference/commands/pilot-discovery.html index 6ad1a7063225..30464cc14484 100644 --- a/_docs/reference/commands/pilot-discovery.html +++ b/_docs/reference/commands/pilot-discovery.html @@ -151,6 +151,11 @@

pilot-discovery discovery

+ + + + + @@ -226,6 +231,11 @@

pilot-discovery discovery

+ + + + + diff --git a/_docs/reference/config/istio.mesh.v1alpha1.html b/_docs/reference/config/istio.mesh.v1alpha1.html index 59a4d50cb0b3..8cd534c4706a 100644 --- a/_docs/reference/config/istio.mesh.v1alpha1.html +++ b/_docs/reference/config/istio.mesh.v1alpha1.html @@ -331,14 +331,6 @@

ProxyConfig

- - - - - @@ -498,6 +490,14 @@

ProxyConfig

+ + + + + From daa19368f04a810831776f5ce91cd5d1b661ec50 Mon Sep 17 00:00:00 2001 From: Julien Senon Date: Wed, 7 Mar 2018 18:31:02 +0100 Subject: [PATCH 017/191] Update Quick start Doc (#1059) Fix Typo --- _docs/setup/kubernetes/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/setup/kubernetes/quick-start.md b/_docs/setup/kubernetes/quick-start.md index 1e61b7587fe2..9343ae9b99e6 100644 --- a/_docs/setup/kubernetes/quick-start.md +++ b/_docs/setup/kubernetes/quick-start.md @@ -172,7 +172,7 @@ The Istio-Sidecar-injector will automatically inject Envoy containers into your ```bash kubectl label namespace istio-injection=enabled -kubectl create -n -f .yaml +kubectl create -n -f .yaml ``` If you do not have the Istio-sidecar-injector installed, you must From 273c11cfcbb3d5f212ae957cc19a126efad83b1c Mon Sep 17 00:00:00 2001 From: Limin Wang Date: Wed, 7 Mar 2018 13:16:58 -0800 Subject: [PATCH 018/191] Update Istio RBAC document to relfect sample changes. (#1062) --- _docs/concepts/security/rbac.md | 53 ++++++++++---- .../security/role-based-access-control.md | 71 +++++++------------ 2 files changed, 67 insertions(+), 57 deletions(-) diff --git a/_docs/concepts/security/rbac.md b/_docs/concepts/security/rbac.md index 05ae247fec74..b4d38898cc04 100644 --- a/_docs/concepts/security/rbac.md +++ b/_docs/concepts/security/rbac.md @@ -52,8 +52,8 @@ Below we show an example "requestcontext". namespace: istio-system spec: subject: - user: request.auth.principal | "" - groups: request.auth.principal | "" + user: source.user | "" + groups: "" properties: service: source.service | "" namespace: source.namespace | "" @@ -98,8 +98,7 @@ Here is an example of a simple role "service-admin", which has full access to al methods: ["*"] ``` -Here is another role "products-viewer", which has read ("GET" and "HEAD") access to service "products.default.svc.cluster.local" -in "default" namespace. +Here is another role "products-viewer", which has read ("GET" and "HEAD") access to "products" service in "default" namespace. ```rule apiVersion: "config.istio.io/v1alpha2" @@ -109,7 +108,7 @@ in "default" namespace. namespace: default spec: rules: - - services: ["products.default.svc.cluster.local"] + - services: ["products"] methods: ["GET", "HEAD"] ``` @@ -117,7 +116,7 @@ In addition, we support **prefix match** and **suffix match** for all the fields has the following permissions in "default" namespace: * Full access to all services with prefix "test-" (e.g, "test-bookstore", "test-performance", "test-api.default.svc.cluster.local"). * Read ("GET") access to all paths with "/reviews" suffix (e.g, "/books/reviews", "/events/booksale/reviews", "/reviews") -in service "bookstore.default.svc.cluster.local". +in "bookstore" service. ```rule apiVersion: "config.istio.io/v1alpha2" @@ -129,7 +128,7 @@ in service "bookstore.default.svc.cluster.local". rules: - services: ["test-*"] methods: ["*"] - - services: ["bookstore.default.svc.cluster.local"] + - services: ["bookstore"] paths: ["*/reviews"] methods: ["GET"] ``` @@ -150,7 +149,7 @@ being "v1" or "v2". Note that the "version" property is provided by `"action.pro namespace: default spec: rules: - - services: ["products.default.svc.cluster.local"] + - services: ["products"] methods: ["GET", "HEAD"] constraints: - key: "version" @@ -169,7 +168,7 @@ instance. Here is an example of ServiceRoleBinding object "test-binding-products", which binds two subjects to ServiceRole "product-viewer": * user "alice@yahoo.com". -* "reviews.abc.svc.cluster.local" service in "abc" namespace. +* "reviews" service in "abc" namespace. ```rule apiVersion: "config.istio.io/v1alpha2" @@ -181,23 +180,45 @@ Here is an example of ServiceRoleBinding object "test-binding-products", which b subjects: - user: "alice@yahoo.com" - properties: - service: "reviews.abc.svc.cluster.local" + service: "reviews" namespace: "abc" roleRef: kind: ServiceRole name: "products-viewer" ``` +In the case that you want to make a service(s) publically accessible, you can use set the subject to `user: "*"`. This will assign a ServiceRole +to all users/services. + +```rule + apiVersion: "config.istio.io/v1alpha2" + kind: ServiceRoleBinding + metadata: + name: binding-products-allusers + namespace: default + spec: + subjects: + - user: "*" + roleRef: + kind: ServiceRole + name: "products-viewer" +``` + ## Enabling Istio RBAC Istio RBAC can be enabled by adding the following Mixer adapter rule. The rule has two parts. The first part defines a RBAC handler. -The `"config_store_url"` parameter specifies where RBAC engine fetches RBAC policies. The default value for "config_store_url" is `"k8s://"`, -which means Kubernetes API server. Alternatively, if you are testing RBAC policy locally, you may set it to a local directory such as -`"fs:///tmp/testdata/configroot"`. +It has two parameters, `"config_store_url"` and `"cache_duration"`. +* The `"config_store_url"` parameter specifies where RBAC engine fetches RBAC policies. The default value for `"config_store_url"` is +`"k8s://"`, which means Kubernetes API server. Alternatively, if you are testing RBAC policy locally, you may set it to a local directory +such as `"fs:///tmp/testdata/configroot"`. +* The `"cache_duration"` parameter specifies the duration for which the authorization results may be cached on Mixer client (i.e., Istio proxy). +The default value for `"cache_duration"` is 1 minute. The second part defines a rule, which specifies that the RBAC handler should be invoked with the "requestcontext" instance [defined earlier in the document](#request-context). +In the following example, Istio RBAC is enabled for "default" namespace. And the cache duration is set to 30 seconds. + ```rule apiVersion: "config.istio.io/v1alpha2" kind: rbac @@ -206,6 +227,7 @@ earlier in the document](#request-context). namespace: istio-system spec: config_store_url: "k8s://" + cache_duration: "30s" --- apiVersion: "config.istio.io/v1alpha2" @@ -214,6 +236,7 @@ earlier in the document](#request-context). name: rbaccheck namespace: istio-system spec: + match: destination.namespace == "default" actions: # handler and instance names default to the rule's namespace. - handler: handler.rbac @@ -221,3 +244,7 @@ earlier in the document](#request-context). - requestcontext.authorization --- ``` + +## What's next + +Try out [Istio RBAC with BookInfo Sample]({{home}}/docs/tasks/security/role-based-access-control.html). \ No newline at end of file diff --git a/_docs/tasks/security/role-based-access-control.md b/_docs/tasks/security/role-based-access-control.md index 036ed0263417..a2fb13018807 100644 --- a/_docs/tasks/security/role-based-access-control.md +++ b/_docs/tasks/security/role-based-access-control.md @@ -21,10 +21,10 @@ RBAC from [Istio RBAC concept page]({{home}}/docs/concepts/security/rbac.html). * Deploy the [Bookinfo]({{home}}/docs/guides/bookinfo.html) sample application. - *> Note: Some sample configurations we use below are not in the current Istio release yet. So before you continue, you + *> Note: The current Istio release may not have the up-to-date Istio RBAC samples. So before you continue, you need to copy the following configuration files from https://github.com/istio/istio/tree/master/samples/bookinfo/kube to - "samples/bookinfo/kube" directory under where you installed Istio. The files include `bookinfo-add-serviceaccount.yaml` - (replace the original one), `istio-rbac-enable.yaml`, `istio-rbac-namespace.yaml`, `istio-rbac-productpage.yaml`, + "samples/bookinfo/kube" directory under where you installed Istio, and replace the original ones. The files include + `bookinfo-add-serviceaccount.yaml`, `istio-rbac-enable.yaml`, `istio-rbac-namespace.yaml`, `istio-rbac-productpage.yaml`, `istio-rbac-details-reviews.yaml`, `istio-rbac-ratings.yaml`.* * In this task, we will enable access control based on Service Accounts, which are cryptographically authenticated in the Istio mesh. @@ -59,7 +59,12 @@ Point your browser at the Bookinfo `productpage` (http://$GATEWAY_URL/productpag ## Enabling Istio RBAC -Run the following command to enable Istio RBAC. +Run the following command to enable Istio RBAC for "default" namespace. + + > Note: if you are using a namespace other than `default`, edit the file `samples/bookinfo/kube/istio-rbac-enable.yaml`, + and specify the namespace, say `"your-namespace"`, in the `match` statement in `rule` spec + `"match: destination.namespace == "your-namespace"`. + ```bash kubectl apply -f samples/bookinfo/kube/istio-rbac-enable.yaml @@ -81,9 +86,9 @@ Using Istio RBAC, you can easily setup namespace-level access control by specify in a namespace are accessible by services from another namespace. In our Bookinfo sample, the "productpage", "reviews", "details", "ratings" services are deployed in "default" namespace. -The Istio components like "ingress" service are deployed in "istio-system" namespace. We can define a policy that all -services in "default" namespace are accessible by services in the same namespace (i.e., "default" namespace) and -services in "istio-system" namespace. +The Istio components like "ingress" service are deployed in "istio-system" namespace. We can define a policy that +any service in "default" namespace that has "app" label set to one of the values in ["productpage", "details", "reviews", "ratings"] +is accessible by services in the same namespace (i.e., "default" namespace) and services in "istio-system" namespace. Run the following command to create a namespace-level access control policy. ```bash @@ -91,7 +96,9 @@ kubectl apply -f samples/bookinfo/kube/istio-rbac-namespace.yaml ``` The policy does the following: -* Creates a ServiceRole "service-viewer" which allows read access to any services in "default" namespace. +* Creates a ServiceRole "service-viewer" which allows read access to any service in "default" namespace that has "app" label +set to one of the values in ["productpage", "details", "reviews", "ratings"]. Note that there is a "constraint" specifying that +the services must have one of the listed "app" labels. ```bash apiVersion: "config.istio.io/v1alpha2" @@ -103,6 +110,9 @@ The policy does the following: rules: - services: ["*"] methods: ["GET"] + constraints: + - key: "app" + values: ["productpage", "details", "reviews", "ratings"] ``` * Creates a ServiceRoleBinding that assign the "service-viewer" role to all services in "istio-system" and "default" namespaces. @@ -174,11 +184,11 @@ The policy does the following: namespace: default spec: rules: - - services: ["productpage.default.svc.cluster.local"] + - services: ["productpage"] methods: ["GET"] ``` -* Creates a ServiceRoleBinding "bind-productpager-viewer" which assigns "productpage-viewer" role to services from "istio-system" namespace. +* Creates a ServiceRoleBinding "bind-productpager-viewer" which assigns "productpage-viewer" role to all users/services. ```bash apiVersion: "config.istio.io/v1alpha2" @@ -188,8 +198,7 @@ The policy does the following: namespace: default spec: subjects: - - properties: - namespace: "istio-system" + - user: "*" roleRef: kind: ServiceRole name: "productpage-viewer" @@ -214,10 +223,7 @@ kubectl apply -f samples/bookinfo/kube/istio-rbac-details-reviews.yaml ``` The policy does the following: -* Creates a ServiceRole "details-reviews-viewer" which allows - * Read access to "details" service, and - * Read access to "reviews" services at versions "v2" and "v3". Note that there is a "constraint" specifying that "version" must be - "v2" or "v3". +* Creates a ServiceRole "details-reviews-viewer" which allows read access to "details" and "reviews" services. ```bash apiVersion: "config.istio.io/v1alpha2" @@ -227,13 +233,8 @@ The policy does the following: namespace: default spec: rules: - - services: ["details.default.svc.cluster.local"] - methods: ["GET"] - - services: ["reviews.default.svc.cluster.local"] + - services: ["details", "reviews"] methods: ["GET"] - constraints: - - key: "version" - values: ["v2", "v3"] ``` * Creates a ServiceRoleBinding "bind-details-reviews" which assigns "details-reviews-viewer" role to service @@ -255,30 +256,12 @@ account "cluster.local/ns/default/sa/bookinfo-productpage" (representing the "pr Point your browser at the Bookinfo `productpage` (http://$GATEWAY_URL/productpage). Now you should see "Bookinfo Sample" page with "Book Details" on the lower left part, and "Book Reviews" on the lower right part. However, in "Book Reviews" section, -you see one of the following two errors: -1. `"Error featching product reviews"`. This is because "productpage" service is only allowed to access "reviews" service with versions -"v2" or "v3". The error occurs when "productpage" service is routed to "reviews" service at version "v1". -2. "Book Reviews" section is shown on the lower right part of the page. But there is an error `"Ratings service currently unavailable"`. This -is because "reviews" service does not have permission to access "ratings" service. +there is an error `"Ratings service currently unavailable"`. This is because "reviews" service does not have permission to access +"ratings" service. To fix this issue, you need to grant "reviews" service read access to "ratings" service. +We will show how to do that in the next step. > Note: There may be delay due to caching on browser and Istio proxy. -To fix the first error, you need to remove the "version" constraint, so that the "details-reviews-viewer" role look like the following: -```bash -apiVersion: "config.istio.io/v1alpha2" -kind: ServiceRole -metadata: - name: details-reviews-viewer - namespace: default -spec: - rules: - - services: ["details.default.svc.cluster.local"] - methods: ["GET"] - - services: ["reviews.default.svc.cluster.local"] - methods: ["GET"] -``` - -To fix the second issue, you need to grant "reviews" service read access to "ratings" service. We will show how to do that in the next step. ### Step 3. allowing "reviews" service to access "ratings" service @@ -303,7 +286,7 @@ The policy does the following: namespace: default spec: rules: - - services: ["ratings.default.svc.cluster.local"] + - services: ["ratings"] methods: ["GET"] ``` From e5ed489f1bcd5ef24ccf895c10ee6e29699be440 Mon Sep 17 00:00:00 2001 From: Rich Curran Date: Thu, 8 Mar 2018 13:06:25 -0500 Subject: [PATCH 019/191] Fix typo in Cleanup section (#1061) --- _docs/tasks/security/role-based-access-control.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/tasks/security/role-based-access-control.md b/_docs/tasks/security/role-based-access-control.md index a2fb13018807..0275aa642252 100644 --- a/_docs/tasks/security/role-based-access-control.md +++ b/_docs/tasks/security/role-based-access-control.md @@ -351,7 +351,7 @@ spec: * Disable Istio RBAC: ```bash - kubectl delete -f samples/bookinfo/kube/istio-rbac-enable.ymal + kubectl delete -f samples/bookinfo/kube/istio-rbac-enable.yaml ``` ## What's next From d778c61333e36df82035e54595fa353b61ce3f67 Mon Sep 17 00:00:00 2001 From: Jason Young Date: Thu, 8 Mar 2018 15:00:17 -0500 Subject: [PATCH 020/191] clarify verification of injected proxy with automatic injection (#1024) --- _docs/setup/kubernetes/sidecar-injection.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index a9ccdaa41f95..fa1b14b2c936 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -119,6 +119,8 @@ sleep 1 1 1 1 2h sleep,istio-pro Sidecars can be automatically added to applicable Kubernetes pods using a [mutating webhook admission controller](https://kubernetes.io/docs/admin/admission-controllers/#validatingadmissionwebhook-alpha-in-18-beta-in-19), available in Kubernetes 1.9 and above. Specifically, verify that the kube-apiserver process has the `admission-control` flag set with the `MutatingAdmissionWebhook` and `ValidatingAdmissionWebhook` admission controllers added and listed in the correct order. +Note that unlike manual injection, automatic injection occurs at the pod-level. You won't see any change to the deployment itself. Instead you'll want to check individual pods (via `kubectl describe`) to see the injected proxy. + ### Prerequisites A Kubernetes 1.9 cluster is required, with the `admissionregistration.k8s.io/v1beta1` API enabled. This is enabled by default on most instllations. If you want to check, you can grep: @@ -338,6 +340,12 @@ sleep-776b7bcdcd-7hpnk 1/1 Terminating 0 1m sleep-776b7bcdcd-bhn9m 2/2 Running 0 7s ``` +View detailed state of the injected pod. You should see the injected `istio-proxy` container and corresponding volumes. Be sure to substitute the correct name for the `Running` pod below. + +```bash +kubectl describe pod sleep-776b7bcdcd-bhn9m +``` + Disable injection for the `default` namespace and verify new pods are created without the sidecar. ```bash From 2377302423a289952404ca859c14ec2ef8221399 Mon Sep 17 00:00:00 2001 From: YaweiWu Date: Fri, 9 Mar 2018 05:26:51 +0800 Subject: [PATCH 021/191] Fixe wrong port number (#1041) --- _docs/tasks/traffic-management/ingress.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_docs/tasks/traffic-management/ingress.md b/_docs/tasks/traffic-management/ingress.md index a967eb36a159..5501bfc8c6b1 100644 --- a/_docs/tasks/traffic-management/ingress.md +++ b/_docs/tasks/traffic-management/ingress.md @@ -238,7 +238,7 @@ The following are known limitations of Istio Ingress: 169.47.243.100 ``` - along with the istio-ingress service's nodePort for port 80: + along with the istio-ingress service's nodePort for port 443: ```bash kubectl -n istio-system get svc istio-ingress @@ -250,7 +250,7 @@ The following are known limitations of Istio Ingress: ``` ```bash - export INGRESS_HOST=169.47.243.100:31486 + export INGRESS_HOST=169.47.243.100:32254 ``` 1. Access the httpbin service using _curl_: @@ -274,7 +274,7 @@ The following are known limitations of Istio Ingress: see a HTTP 404 error ```bash - curl -I -k http://$INGRESS_HOST/headers + curl -I -k https://$INGRESS_HOST/headers ``` ``` From 65ac6cace0830b413fed4b21b6ea684a29d7ce51 Mon Sep 17 00:00:00 2001 From: john-a-joyce Date: Thu, 8 Mar 2018 19:07:46 -0500 Subject: [PATCH 022/191] Sidecar proxy help (#1044) --- _help/troubleshooting.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/_help/troubleshooting.md b/_help/troubleshooting.md index d090e997783a..1780f6269268 100644 --- a/_help/troubleshooting.md +++ b/_help/troubleshooting.md @@ -416,3 +416,26 @@ of HTTP 404s (upto 2x the refresh interval) until the Envoy sidecars get all rel NOTE: The 0.5.0 and 0.5.1 releases are missing scripts to provision webhook certificates. Download the missing files from [here](https://raw.githubusercontent.com/istio/istio/master/install/kubernetes/webhook-create-signed-cert.sh) and [here](https://raw.githubusercontent.com/istio/istio/master/install/kubernetes/webhook-patch-ca-bundle.sh). Subsqeuent releases (> 0.5.1) should include these missing files. +## Automatic sidecar injection will fail if the kube-apiserver has proxy settings + +This was tested on 0.5.0 with the additional files required as referenced in the above issue. When the Kube-apiserver included +proxy settings such as: +```yaml +env: + - name: http_proxy + value: http://proxy-wsa.esl.foo.com:80 + - name: https_proxy + value: http://proxy-wsa.esl.foo.com:80 + - name: no_proxy + value: 127.0.0.1,localhost,dockerhub.foo.com,devhub-docker.foo.com,10.84.100.125,10.84.100.126,10.84.100.127 +``` +The sidecar injection would fail. The only related failure logs was in the kube-apiserver log: +```bash +W0227 21:51:03.156818 1 admission.go:257] Failed calling webhook, failing open sidecar-injector.istio.io: failed calling admission webhook "sidecar-injector.istio.io": Post https://istio-sidecar-injector.istio-system.svc:443/inject: Service Unavailable +``` +Make sure both pod and service CIDRs are not proxied according to *_proxy variables. Check the kube-apiserver files and logs to verify the configuration and whether any requests are being proxied. + +A workaround is to remove the proxy settings from the kube-apiserver manifest and restart the server or use a later version of kubernetes. + +An issue was filed in kubernetes related to this and has since been closed. [https://github.com/kubernetes/kubeadm/issues/666](https://github.com/kubernetes/kubeadm/issues/666) +[https://github.com/kubernetes/kubernetes/pull/58698#discussion_r163879443](https://github.com/kubernetes/kubernetes/pull/58698#discussion_r163879443) From cc4af846c7a3716fc5c90ad2b6e8b754f05ed675 Mon Sep 17 00:00:00 2001 From: embs Date: Fri, 9 Mar 2018 11:00:29 -0300 Subject: [PATCH 023/191] Use same instance name in Mixer config example (#1051) --- _docs/concepts/policy-and-control/mixer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/concepts/policy-and-control/mixer.md b/_docs/concepts/policy-and-control/mixer.md index edbb0f40465c..6b631dbc0960 100644 --- a/_docs/concepts/policy-and-control/mixer.md +++ b/_docs/concepts/policy-and-control/mixer.md @@ -95,7 +95,7 @@ operator is responsible for: - Configuring a set of *instances* for Mixer to generate based on attributes and literal values. They represent a chunk of data that adapter code will operate - on. For example, an operator may configure Mixer to generate `request_count` + on. For example, an operator may configure Mixer to generate `requestcount` metric values from attributes such as `destination.service` and `response.code`. From 933b6355539ac50bb8c6b7d5161721518b9a64f1 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Fri, 9 Mar 2018 09:37:11 -0800 Subject: [PATCH 024/191] Add a bunch of redirects for old pages (#1066) The Google Crawl Engine reported a bunch of broken links pointing into istio.io. This adds redirects so that these links work. Add a hack such that the gear menu logic that lets you time travel through versions of the site will insist that if a page existed in a given version, it must also exist in subsequent versions. This will ensure we always create redirects when we move site content, and thus avoid breaking links into the site. If a page is moved or removed, this will lead to rake test errors when checking the content of archive.istio.io. --- _about/notes/index.md | 1 + _blog/2017/mixer-spof-myth.md | 2 +- _docs/concepts/traffic-management/pilot.md | 1 + .../tasks/policy-enforcement/rate-limiting.md | 1 + _docs/tasks/security/index.md | 1 + _docs/tasks/telemetry/distributed-tracing.md | 1 + _docs/tasks/traffic-management/egress.md | 1 + _docs/tasks/traffic-management/ingress.md | 1 + .../traffic-management/request-routing.md | 1 + _includes/header.html | 52 +++++++++++-------- 10 files changed, 38 insertions(+), 24 deletions(-) diff --git a/_about/notes/index.md b/_about/notes/index.md index 3e6416ef60b8..445420c64e8c 100644 --- a/_about/notes/index.md +++ b/_about/notes/index.md @@ -10,6 +10,7 @@ redirect_from: - "/docs/reference/release-notes.html" - "/release-notes" - "/docs/welcome/notes/index.html" + - "/docs/references/notes" toc: false --- diff --git a/_blog/2017/mixer-spof-myth.md b/_blog/2017/mixer-spof-myth.md index 5c2c7cfa5c55..5614c9d934da 100644 --- a/_blog/2017/mixer-spof-myth.md +++ b/_blog/2017/mixer-spof-myth.md @@ -9,7 +9,7 @@ order: 94 layout: blog type: markdown - +redirect_from: /blog/posts/2017/mixer-spof-myth.html --- {% include home.html %} diff --git a/_docs/concepts/traffic-management/pilot.md b/_docs/concepts/traffic-management/pilot.md index a2e236690804..482367aeec8c 100644 --- a/_docs/concepts/traffic-management/pilot.md +++ b/_docs/concepts/traffic-management/pilot.md @@ -7,6 +7,7 @@ order: 10 layout: docs type: markdown toc: false +redirect_from: /docs/concepts/traffic-management/manager.html --- {% include home.html %} diff --git a/_docs/tasks/policy-enforcement/rate-limiting.md b/_docs/tasks/policy-enforcement/rate-limiting.md index dd8266e57d37..c1951ddc492c 100644 --- a/_docs/tasks/policy-enforcement/rate-limiting.md +++ b/_docs/tasks/policy-enforcement/rate-limiting.md @@ -6,6 +6,7 @@ order: 10 layout: docs type: markdown +redirect_from: /docs/tasks/rate-limiting.html --- {% include home.html %} diff --git a/_docs/tasks/security/index.md b/_docs/tasks/security/index.md index 9ab74e597d65..334d751b9c72 100644 --- a/_docs/tasks/security/index.md +++ b/_docs/tasks/security/index.md @@ -7,6 +7,7 @@ order: 40 layout: docs type: markdown toc: false +redirect_from: /docs/tasks/istio-auth.html --- {% include section-index.html docs=site.docs %} diff --git a/_docs/tasks/telemetry/distributed-tracing.md b/_docs/tasks/telemetry/distributed-tracing.md index 3412327ab984..081590ae130c 100644 --- a/_docs/tasks/telemetry/distributed-tracing.md +++ b/_docs/tasks/telemetry/distributed-tracing.md @@ -6,6 +6,7 @@ order: 10 layout: docs type: markdown +redirect_from: /docs/tasks/zipkin-tracing.html --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/egress.md b/_docs/tasks/traffic-management/egress.md index 8e4973abc6e9..5452ae77b9a7 100644 --- a/_docs/tasks/traffic-management/egress.md +++ b/_docs/tasks/traffic-management/egress.md @@ -6,6 +6,7 @@ order: 40 layout: docs type: markdown +redirect_from: /docs/tasks/egress.html --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/ingress.md b/_docs/tasks/traffic-management/ingress.md index 5501bfc8c6b1..150f30fa73de 100644 --- a/_docs/tasks/traffic-management/ingress.md +++ b/_docs/tasks/traffic-management/ingress.md @@ -6,6 +6,7 @@ order: 30 layout: docs type: markdown +redirect_from: /docs/tasks/ingress.html --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/request-routing.md b/_docs/tasks/traffic-management/request-routing.md index 48e2f68293c9..dee2a70efe33 100644 --- a/_docs/tasks/traffic-management/request-routing.md +++ b/_docs/tasks/traffic-management/request-routing.md @@ -6,6 +6,7 @@ order: 10 layout: docs type: markdown +redirect_from: /docs/tasks/request-routing.html --- {% include home.html %} diff --git a/_includes/header.html b/_includes/header.html index cace140f38d2..63c21d037169 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -49,29 +49,34 @@ @@ -108,7 +108,7 @@ matter fields are: |`order` | An integer used to determine the sort order of this page relative to other pages in the same directory. |`layout` | Indicates which of the Jekyll layouts this page uses |`index` | Indicates whether the page should appear in the doc's top nav tabs -|`draft` | When true, prevents the page from shownig up in any navigation area +|`draft` | When true, prevents the page from showing up in any navigation area |`publish_date` | For blog posts, indicates the date of publication of the post |`subtitle` | For blog posts, supplies an optional subtitle to be displayed below the main title |`attribution` | For blog posts, supplies an optional author's name @@ -249,7 +249,7 @@ For example ``` --- -title: Frequantly Asked Questions +title: Frequently Asked Questions overview: Questions Asked Frequently order: 12 @@ -268,7 +268,7 @@ You can also add many redirects like so: ``` --- -title: Frequantly Asked Questions +title: Frequently Asked Questions overview: Questions Asked Frequently order: 12 diff --git a/_docs/guides/bookinfo.md b/_docs/guides/bookinfo.md index 69521cf0c8e7..fb291ead4937 100644 --- a/_docs/guides/bookinfo.md +++ b/_docs/guides/bookinfo.md @@ -43,7 +43,7 @@ The end-to-end architecture of the application is shown below. This application is polyglot, i.e., the microservices are written in different languages. It’s worth noting that these services have no dependencies on Istio, but make an interesting -sevice mesh example, particularly because of the multitude of services, languages and versions +service mesh example, particularly because of the multitude of services, languages and versions for the reviews service. ## Before you begin diff --git a/_docs/setup/kubernetes/helm.md b/_docs/setup/kubernetes/helm.md index 88babbccd679..b9927c2d6049 100644 --- a/_docs/setup/kubernetes/helm.md +++ b/_docs/setup/kubernetes/helm.md @@ -62,7 +62,7 @@ following table: | global.mixer.hub | registry+namespace | release registry/namespace | Specifies the HUB for the mixer image | | global.mixer.tag | image tag | release unique hash | Specifies the TAG for the mixer image | | global.mixer.enabled | true/false | true | Specifies whether mixer is enabled/disabled | -| global.hyperkube.hub | registry+namesapce | quay.io/coreos/hyperkube | Specifies the HUB for the hyperkube image | +| global.hyperkube.hub | registry+namespace | quay.io/coreos/hyperkube | Specifies the HUB for the hyperkube image | | global.hyperkube.tag | image tag | v1.7.6_coreos.0 | Specifies the TAG for the hyperkube image | | global.ingress.use_nodeport | true/false | false | Specifies whether to use nodeport or LB | | global.ingress.nodeport_port | 32000-32767 | 32000 | If nodeport is used, specifies its port | diff --git a/_docs/tasks/security/health-check.md b/_docs/tasks/security/health-check.md index b2acb7467552..6256131e1242 100644 --- a/_docs/tasks/security/health-check.md +++ b/_docs/tasks/security/health-check.md @@ -18,7 +18,7 @@ by periodically sending CSRs to the API. More health check features are coming s The Istio CA contains a _prober client_ module that periodically checks the CA's status (currently only the health status of the gRPC server). -If the Istio CA is healthy, the _prober client_ updates the _modificate time_ of the _health status file_ +If the Istio CA is healthy, the _prober client_ updates the _modification time_ of the _health status file_ (the file is always empty). Otherwise, it does nothing. Istio CA relies on a [K8s liveness and readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) with command line to check the _modification time_ of the _health status file_ on the pod. @@ -119,7 +119,7 @@ the Istio CA as healthy. Prolonging `probe-check-interval` will reduce the health check overhead, but there will be a greater lagging for the prober to get notified on the unhealthy status. -To avoid the prober restarting the Istio CA due to temporary unavailablily, the `interval` on the prober can be +To avoid the prober restarting the Istio CA due to temporary unavailability, the `interval` on the prober can be configured to be more than `N` times of the `liveness-probe-interval`. This will allow the prober to tolerate `N-1` continuously failed health checks. diff --git a/_docs/tasks/telemetry/distributed-tracing.md b/_docs/tasks/telemetry/distributed-tracing.md index 081590ae130c..f10421f7937b 100644 --- a/_docs/tasks/telemetry/distributed-tracing.md +++ b/_docs/tasks/telemetry/distributed-tracing.md @@ -185,13 +185,13 @@ When you make downstream calls in your applications, make sure to include these * Remove the addon tracing configuration: - If you are running with Zipkin, run the followign command to cleanup: + If you are running with Zipkin, run the following command to cleanup: ```bash kubectl delete -f install/kubernetes/addons/zipkin.yaml ``` - If you are running with Jaeger, run the followign command to cleanup: + If you are running with Jaeger, run the following command to cleanup: ```bash kubectl delete -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml diff --git a/_help/troubleshooting.md b/_help/troubleshooting.md index 1780f6269268..a1fccc49afe8 100644 --- a/_help/troubleshooting.md +++ b/_help/troubleshooting.md @@ -414,7 +414,8 @@ of HTTP 404s (upto 2x the refresh interval) until the Envoy sidecars get all rel ## Kubernetes webhook setup script files are missing from 0.5 release package -NOTE: The 0.5.0 and 0.5.1 releases are missing scripts to provision webhook certificates. Download the missing files from [here](https://raw.githubusercontent.com/istio/istio/master/install/kubernetes/webhook-create-signed-cert.sh) and [here](https://raw.githubusercontent.com/istio/istio/master/install/kubernetes/webhook-patch-ca-bundle.sh). Subsqeuent releases (> 0.5.1) should include these missing files. +NOTE: The 0.5.0 and 0.5.1 releases are missing scripts to provision webhook certificates. Download the missing files from +[here](https://raw.githubusercontent.com/istio/istio/master/install/kubernetes/webhook-create-signed-cert.sh) and [here](https://raw.githubusercontent.com/istio/istio/master/install/kubernetes/webhook-patch-ca-bundle.sh). Subsequent releases (> 0.5.1) should include these missing files. ## Automatic sidecar injection will fail if the kube-apiserver has proxy settings From d70750bfe733b04cd38e490f539c9b284a04efed Mon Sep 17 00:00:00 2001 From: mtail Date: Sun, 11 Mar 2018 23:16:08 -0700 Subject: [PATCH 028/191] Update reference docs. --- _docs/reference/commands/istio_ca.html | 44 -------------- _docs/reference/commands/mixc.html | 39 ------------- _docs/reference/commands/mixs.html | 57 ------------------- _docs/reference/commands/node_agent.html | 18 ------ _docs/reference/commands/pilot-agent.html | 41 ------------- _docs/reference/commands/pilot-discovery.html | 10 ---- .../reference/commands/sidecar-injector.html | 36 ------------ 7 files changed, 245 deletions(-) diff --git a/_docs/reference/commands/istio_ca.html b/_docs/reference/commands/istio_ca.html index d78718a77356..eb1cd83fb788 100644 --- a/_docs/reference/commands/istio_ca.html +++ b/_docs/reference/commands/istio_ca.html @@ -10,163 +10,131 @@
NameDescription
FAIL_OPEN -

If network fails, request is passed to the backend.

- -
FAIL_CLOSE -

If network fails, request is rejected.

-
timestampistio.mixer.v1.template.TimeStampistio.mixer.adapter.model.v1beta1.TimeStamp

Timestamp of API call.

diff --git a/_docs/reference/config/template/authorization.html b/_docs/reference/config/template/authorization.html index 32a8110c1cf6..4c5b21f8c657 100644 --- a/_docs/reference/config/template/authorization.html +++ b/_docs/reference/config/template/authorization.html @@ -55,7 +55,7 @@

Action

propertiesmap<string, istio.mixer.v1.template.Value>map<string, istio.mixer.adapter.model.v1beta1.Value>

Additional data about the action for use in policy.

@@ -99,7 +99,7 @@

Subject

propertiesmap<string, istio.mixer.v1.template.Value>map<string, istio.mixer.adapter.model.v1beta1.Value>

Additional attributes about the subject.

diff --git a/_docs/reference/config/template/kubernetes.html b/_docs/reference/config/template/kubernetes.html index 733102c27d9e..f13b6653959e 100644 --- a/_docs/reference/config/template/kubernetes.html +++ b/_docs/reference/config/template/kubernetes.html @@ -24,7 +24,7 @@

OutputTemplate

sourcePodIpistio.mixer.v1.template.IPAddressistio.mixer.adapter.model.v1beta1.IPAddress

Refers to source pod ip address. attributebindings can refer to this field using $out.sourcepod_ip

@@ -72,7 +72,7 @@

OutputTemplate

sourceHostIpistio.mixer.v1.template.IPAddressistio.mixer.adapter.model.v1beta1.IPAddress

Refers to source pod host ip address. attributebindings can refer to this field using $out.sourcehost_ip

@@ -80,7 +80,7 @@

OutputTemplate

destinationPodIpistio.mixer.v1.template.IPAddressistio.mixer.adapter.model.v1beta1.IPAddress

Refers to destination pod ip address. attributebindings can refer to this field using $out.destinationpod_ip

@@ -128,7 +128,7 @@

OutputTemplate

destinationHostIpistio.mixer.v1.template.IPAddressistio.mixer.adapter.model.v1beta1.IPAddress

Refers to destination pod host ip address. attributebindings can refer to this field using $out.destinationhost_ip

@@ -136,7 +136,7 @@

OutputTemplate

originPodIpistio.mixer.v1.template.IPAddressistio.mixer.adapter.model.v1beta1.IPAddress

Refers to origin pod ip address. attributebindings can refer to this field using $out.originpod_ip

@@ -184,7 +184,7 @@

OutputTemplate

originHostIpistio.mixer.v1.template.IPAddressistio.mixer.adapter.model.v1beta1.IPAddress

Refers to origin pod host ip address. attributebindings can refer to this field using $out.originhost_ip

@@ -247,7 +247,7 @@

Template

sourceIpistio.mixer.v1.template.IPAddressistio.mixer.adapter.model.v1beta1.IPAddress

Source pod’s ip.

@@ -263,7 +263,7 @@

Template

destinationIpistio.mixer.v1.template.IPAddressistio.mixer.adapter.model.v1beta1.IPAddress

Destination pod’s ip.

@@ -279,7 +279,7 @@

Template

originIpistio.mixer.v1.template.IPAddressistio.mixer.adapter.model.v1beta1.IPAddress

Origin pod’s ip.

diff --git a/_docs/reference/config/template/listentry.html b/_docs/reference/config/template/listentry.html index 7de909313799..dc315764fa68 100644 --- a/_docs/reference/config/template/listentry.html +++ b/_docs/reference/config/template/listentry.html @@ -14,7 +14,7 @@

Template

within a list.

When writing the configuration, the value for the fields associated with this template can either be a -literal or an expression. Please note that if the datatype of a field is not istio.mixer.v1.template.Value, +literal or an expression. Please note that if the datatype of a field is not istio.mixer.adapter.model.v1beta1.Value, then the expression’s inferred type must match the datatype of the field.

Example config:

diff --git a/_docs/reference/config/template/logentry.html b/_docs/reference/config/template/logentry.html index 9c27d985a6f5..279452151dd7 100644 --- a/_docs/reference/config/template/logentry.html +++ b/_docs/reference/config/template/logentry.html @@ -12,7 +12,7 @@

Template

The logentry template represents an individual entry within a log.

When writing the configuration, the value for the fields associated with this template can either be a -literal or an expression. Please note that if the datatype of a field is not istio.mixer.v1.template.Value, +literal or an expression. Please note that if the datatype of a field is not istio.mixer.adapter.model.v1beta1.Value, then the expression’s inferred type must match the datatype of the field.

Example config:

@@ -50,7 +50,7 @@

Template

variablesmap<string, istio.mixer.v1.template.Value>map<string, istio.mixer.adapter.model.v1beta1.Value>

Variables that are delivered for each log entry.

@@ -58,7 +58,7 @@

Template

timestampistio.mixer.v1.template.TimeStampistio.mixer.adapter.model.v1beta1.TimeStamp

Timestamp is the time value for the log entry

@@ -84,7 +84,7 @@

Template

monitoredResourceDimensionsmap<string, istio.mixer.v1.template.Value>map<string, istio.mixer.adapter.model.v1beta1.Value>

Optional. A set of expressions that will form the dimensions of the monitored resource this log entry is being recorded on. If the logging backend supports monitored resources, these fields are used to populate that resource. diff --git a/_docs/reference/config/template/metric.html b/_docs/reference/config/template/metric.html index ab04ba321777..39c856cb7c4a 100644 --- a/_docs/reference/config/template/metric.html +++ b/_docs/reference/config/template/metric.html @@ -13,7 +13,7 @@

Template

The metric template represents a single piece of data to report.

When writing the configuration, the value for the fields associated with this template can either be a -literal or an expression. Please note that if the datatype of a field is not istio.mixer.v1.template.Value, +literal or an expression. Please note that if the datatype of a field is not istio.mixer.adapter.model.v1beta1.Value, then the expression’s inferred type must match the datatype of the field.

Example config:

@@ -45,7 +45,7 @@

Template

valueistio.mixer.v1.template.Valueistio.mixer.adapter.model.v1beta1.Value

The value being reported.

@@ -53,7 +53,7 @@

Template

dimensionsmap<string, istio.mixer.v1.template.Value>map<string, istio.mixer.adapter.model.v1beta1.Value>

The unique identity of the particular metric to report.

@@ -71,7 +71,7 @@

Template

monitoredResourceDimensionsmap<string, istio.mixer.v1.template.Value>map<string, istio.mixer.adapter.model.v1beta1.Value>

Optional. A set of expressions that will form the dimensions of the monitored resource this metric is being reported on. If the metric backend supports monitored resources, these fields are used to populate that resource. Otherwise diff --git a/_docs/reference/config/template/quota.html b/_docs/reference/config/template/quota.html index 326dfc9e8270..348ff7804ef0 100644 --- a/_docs/reference/config/template/quota.html +++ b/_docs/reference/config/template/quota.html @@ -12,7 +12,7 @@

Template

The quota template represents a piece of data to check Quota for.

When writing the configuration, the value for the fields associated with this template can either be a -literal or an expression. Please note that if the datatype of a field is not istio.mixer.v1.template.Value, +literal or an expression. Please note that if the datatype of a field is not istio.mixer.adapter.model.v1beta1.Value, then the expression’s inferred type must match the datatype of the field.

Example config:

@@ -41,7 +41,7 @@

Template

dimensionsmap<string, istio.mixer.v1.template.Value>map<string, istio.mixer.adapter.model.v1beta1.Value>

The unique identity of the particular quota to manipulate.

diff --git a/_docs/reference/config/template/servicecontrolreport.html b/_docs/reference/config/template/servicecontrolreport.html index 0e345f60c4ca..5ba87c21aea0 100644 --- a/_docs/reference/config/template/servicecontrolreport.html +++ b/_docs/reference/config/template/servicecontrolreport.html @@ -78,7 +78,7 @@

Template

requestTimeistio.mixer.v1.template.TimeStampistio.mixer.adapter.model.v1beta1.TimeStamp
responseTimeistio.mixer.v1.template.TimeStampistio.mixer.adapter.model.v1beta1.TimeStamp
responseLatencyistio.mixer.v1.template.Durationistio.mixer.adapter.model.v1beta1.Duration
URL for the Eureka server (default ``)
--grpcAddr <string>Discovery service grpc address (default `:15010`)
--kubeconfig <string> Use a Kubernetes configuration file instead of in-cluster configuration (default ``) Enable profiling via web interface host:port/debug/pprof
--rdsv2Enable RDS v2
--registries <stringSlice> Comma separated list of platform service registries to read from (choose one or more from {Kubernetes, Consul, Eureka, CloudFoundry, Mock}) (default `[Kubernetes]`)

Path to the proxy binary

-
proxyBootstrapTemplatePathstring -

Path to the proxy bootstrap template file

-

Address of the discovery service exposing xDS with plain text connection.

+
proxyBootstrapTemplatePathstring +

Path to the proxy bootstrap template file

+
Setup A setup page is similar to a task page, except that it is focused on installation - ectivities. + activities.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -178,63 +146,51 @@

istio_ca probe

FlagsShorthand Description
--cert-chain <string> Path to the certificate chain file (default ``)
--grpc-hostname <string> The hostname for GRPC server. (default `localhost`)
--grpc-port <int> The port number for GRPC server. If unspecified, Istio CA will not server GRPC request. (default `0`)
--istio-ca-storage-namespace <string> Namespace where the Istio CA pods is running. Will not be used if explicit file or other storage mechanism is specified. (default `istio-system`)
--kube-config <string> Specifies path to kubeconfig file. This must be specified when not running inside a Kubernetes pod. (default ``)
--listened-namespace <string> Select a namespace for the CA to listen to. If unspecified, Istio CA tries to use the ${NAMESPACE} environment variable. If neither is set, Istio CA listens to all namespaces. (default ``)
--liveness-probe-interval <duration> Interval of updating file for the liveness probe. (default `0s`)
--liveness-probe-path <string> Path to the file for the liveness probe. (default ``)
--log_as_json Whether to format output as JSON or in plain console-friendly format
--log_callers Include caller information, useful for debugging
--log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string> The path for the optional rotating log file (default ``)
--log_rotate_max_age <int> The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int> The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int> The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string> The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray> The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
--max-workload-cert-ttl <duration> The max TTL of issued workload certificates (default `168h0m0s`)
--probe-check-interval <duration> Interval of checking the liveness of the CA. (default `30s`)
--root-cert <string> Path to the root certificate file (default ``)
--self-signed-ca Indicates whether to use auto-generated self-signed CA certificate. When set to true, the '--signing-cert' and '--signing-key' options are ignored.
--self-signed-ca-cert-ttl <duration> The TTL of self-signed CA root certificate (default `8760h0m0s`)
--self-signed-ca-org <string> The issuer organization used in self-signed CA certificate (default to k8s.cluster.local) (default `k8s.cluster.local`)
--signing-cert <string> Path to the CA signing certificate file (default ``)
--signing-key <string> Path to the CA signing key file (default ``)
--upstream-auth <string> Specifies how the Istio CA is authenticated to the upstream CA. (default `mtls`)
--upstream-ca-address <string> The IP:port address of the upstream CA. When set, the CA will rely on the upstream Istio CA to provision its own certificate. (default ``)
--upstream-ca-cert-file <string> Path to the certificate for authenticating upstream CA. (default ``)
--workload-cert-grace-period-ratio <float32> The workload certificate rotation grace period, as a ratio of the workload certificate TTL. (default `0.5`)
--workload-cert-min-grace-period <duration> The minimum workload certificate rotation grace period. (default `10m0s`)
--workload-cert-ttl <duration> The TTL of issued workload certificates (default `19h0m0s`)
- - - - - - - - - - - - diff --git a/_docs/reference/commands/mixc.html b/_docs/reference/commands/mixc.html index 118e1b7c3a18..534f37e3e5ed 100644 --- a/_docs/reference/commands/mixc.html +++ b/_docs/reference/commands/mixc.html @@ -7,30 +7,6 @@

This command lets you interact with a running instance of Mixer. Note that you need a pretty good understanding of Mixer's API in order to use this command.

-
FlagsShorthand Description
--interval <duration> Duration used for checking the target file's last modified time. (default `0s`)
--log_as_json Whether to format output as JSON or in plain console-friendly format
--log_callers Include caller information, useful for debugging
--log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string> The path for the optional rotating log file (default ``)
--log_rotate_max_age <int> The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int> The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int> The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string> The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray> The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
--probe-path <string> Path of the file for checking the availability. (default ``)
- - - - - - - - - - - - - - - - - - - - - - -
FlagsShorthandDescription
--trace_jaeger_url <string>URL of Jaeger HTTP collector (example: 'http://jaeger:14268/api/traces?format=jaeger.thrift'). (default ``)
--trace_log_spansWhether or not to log trace spans.
--trace_zipkin_url <string>URL of Zipkin collector (example: 'http://zipkin:9411/api/v1/spans'). (default ``)

mixc check

The Check method is used to perform precondition checks and quota allocations. Mixer expects a set of attributes as input, which it uses, along with @@ -224,20 +200,5 @@

mixc version

-s Displays a short form of the version information - ---trace_jaeger_url <string> - -URL of Jaeger HTTP collector (example: 'http://jaeger:14268/api/traces?format=jaeger.thrift'). (default ``) - - ---trace_log_spans - -Whether or not to log trace spans. - - ---trace_zipkin_url <string> - -URL of Zipkin collector (example: 'http://zipkin:9411/api/v1/spans'). (default ``) - diff --git a/_docs/reference/commands/mixs.html b/_docs/reference/commands/mixs.html index 288a8fb7fe08..4cfd8032c8b3 100644 --- a/_docs/reference/commands/mixs.html +++ b/_docs/reference/commands/mixs.html @@ -6,65 +6,20 @@ ---

Mixer is Istio's point of integration with infrastructure backends and is the nexus for policy evaluation and telemetry reporting.

- - - - - - - - -
FlagsShorthandDescription

mixs crd

CRDs (CustomResourceDefinition) available in Mixer

- - - - - - - - -
FlagsShorthandDescription

mixs crd adapter

List CRDs for available adapters

mixs crd adapter [flags]
 
- - - - - - - - -
FlagsShorthandDescription

mixs crd all

List all CRDs

mixs crd all [flags]
 
- - - - - - - - -
FlagsShorthandDescription

mixs crd instance

List CRDs for available instance kinds (mesh functions)

mixs crd instance [flags]
 
- - - - - - - - -
FlagsShorthandDescription

mixs probe

Check the liveness or readiness of a locally-running server

mixs probe [flags]
@@ -72,63 +27,51 @@ 

mixs probe

- - - - - - - - - - - - diff --git a/_docs/reference/commands/node_agent.html b/_docs/reference/commands/node_agent.html index 860b74c9e9d4..d62b939f398c 100644 --- a/_docs/reference/commands/node_agent.html +++ b/_docs/reference/commands/node_agent.html @@ -10,93 +10,75 @@
FlagsShorthand Description
--interval <duration> Duration used for checking the target file's last modified time. (default `0s`)
--log_as_json Whether to format output as JSON or in plain console-friendly format
--log_callers Include caller information, useful for debugging
--log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string> The path for the optional rotating log file (default ``)
--log_rotate_max_age <int> The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int> The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int> The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string> The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray> The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
--probe-path <string> Path of the file for checking the availability. (default ``)
- - - - - - - - - - - - - - - - - - diff --git a/_docs/reference/commands/pilot-agent.html b/_docs/reference/commands/pilot-agent.html index b05b31e6fd07..a41b99d1e554 100644 --- a/_docs/reference/commands/pilot-agent.html +++ b/_docs/reference/commands/pilot-agent.html @@ -8,53 +8,43 @@
FlagsShorthand Description
--ca-address <string> Istio CA address (default `istio-ca:8060`)
--cert-chain <string> Node Agent identity cert file (default `/etc/certs/cert-chain.pem`)
--env <string> Node Environment : unspecified | onprem | gcp | aws (default `unspecified`)
--key <string> Node Agent private key file (default `/etc/certs/key.pem`)
--key-size <int> Size of generated private key (default `2048`)
--log_as_json Whether to format output as JSON or in plain console-friendly format
--log_callers Include caller information, useful for debugging
--log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string> The path for the optional rotating log file (default ``)
--log_rotate_max_age <int> The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int> The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int> The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string> The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray> The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
--org <string> Organization for the cert (default ``)
--root-cert <string> Root Certificate file (default `/etc/certs/root-cert.pem`)
--workload-cert-ttl <duration> The requested TTL for the workload (default `19h0m0s`)
- - - - - - - - - - @@ -66,158 +56,127 @@

pilot-agent proxy

FlagsShorthand Description
--log_as_json Whether to format output as JSON or in plain console-friendly format
--log_callers Include caller information, useful for debugging
--log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string> The path for the optional rotating log file (default ``)
--log_rotate_max_age <int> The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int> The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int> The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string> The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray> The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_docs/reference/commands/pilot-discovery.html b/_docs/reference/commands/pilot-discovery.html index 30464cc14484..ff2db988b6b1 100644 --- a/_docs/reference/commands/pilot-discovery.html +++ b/_docs/reference/commands/pilot-discovery.html @@ -8,53 +8,43 @@
FlagsShorthand Description
--availabilityZone <string> Availability zone (default ``)
--binaryPath <string> Path to the proxy binary (default `/usr/local/bin/envoy`)
--bootstrapv2 Use bootstrap v2
--concurrency <int> number of worker threads to run (default `0`)
--configPath <string> Path to the generated configuration file directory (default `/etc/istio/proxy`)
--connectTimeout <duration> Connection timeout used by Envoy for supporting services (default `1s`)
--controlPlaneAuthPolicy <string> Control Plane Authentication Policy (default `NONE`)
--customConfigFile <string> Path to the generated configuration file directory (default ``)
--discoveryAddress <string> Address of the discovery service exposing xDS (e.g. istio-pilot:8080) (default `istio-pilot:15007`)
--discoveryRefreshDelay <duration> Polling interval for service discovery (used by EDS, CDS, LDS, but not RDS) (default `1s`)
--domain <string> DNS domain suffix. If not provided uses ${POD_NAMESPACE}.svc.cluster.local (default ``)
--drainDuration <duration> The time in seconds that Envoy will drain connections during a hot restart (default `2s`)
--id <string> Proxy unique ID. If not provided uses ${POD_NAME}.${POD_NAMESPACE} from environment variables (default ``)
--ip <string> Proxy IP address. If not provided uses ${INSTANCE_IP} environment variable. (default ``)
--log_as_json Whether to format output as JSON or in plain console-friendly format
--log_callers Include caller information, useful for debugging
--log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string> The path for the optional rotating log file (default ``)
--log_rotate_max_age <int> The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int> The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int> The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string> The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray> The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
--parentShutdownDuration <duration> The time in seconds that Envoy will wait before shutting down the parent process during a hot restart (default `3s`)
--proxyAdminPort <int> Port on which Envoy should listen for administrative commands (default `15000`)
--proxyLogLevel <string> The log level used to start the Envoy proxy (choose from {trace, debug, info, warn, err, critical, off}) (default `info`)
--serviceCluster <string> Service cluster (default `istio-proxy`)
--serviceregistry <string> Select the platform for service registry, options are {Kubernetes, Consul, Eureka} (default `Kubernetes`)
--statsdUdpAddress <string> IP Address and Port of a statsd UDP listener (e.g. 10.75.241.127:9125) (default ``)
--zipkinAddress <string> Address of the Zipkin service (e.g. zipkin:9411) (default ``)
- - - - - - - - - - diff --git a/_docs/reference/commands/sidecar-injector.html b/_docs/reference/commands/sidecar-injector.html index 1d65d5b41b96..b11b8a96487f 100644 --- a/_docs/reference/commands/sidecar-injector.html +++ b/_docs/reference/commands/sidecar-injector.html @@ -10,88 +10,71 @@
FlagsShorthand Description
--log_as_json Whether to format output as JSON or in plain console-friendly format
--log_callers Include caller information, useful for debugging
--log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string> The path for the optional rotating log file (default ``)
--log_rotate_max_age <int> The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int> The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int> The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string> The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray> The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
- - - - - - - - - - - - - - - - - @@ -103,98 +86,79 @@

sidecar-injector probe

FlagsShorthand Description
--healthCheckFile <string> File that should be periodically updated if health checking is enabled (default ``)
--healthCheckInterval <duration> Configure how frequently the health check file specified by --healhCheckFile should be updated (default `0s`)
--injectConfig <string> File containing the Istio sidecar injection configuration and template (default `/etc/istio/inject/config`)
--log_as_json Whether to format output as JSON or in plain console-friendly format
--log_callers Include caller information, useful for debugging
--log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string> The path for the optional rotating log file (default ``)
--log_rotate_max_age <int> The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int> The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int> The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string> The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray> The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
--meshConfig <string> File containing the Istio mesh configuration (default `/etc/istio/config/mesh`)
--port <int> Webhook port (default `443`)
--tlsCertFile <string> File containing the x509 Certificate for HTTPS. (default `/etc/istio/certs/cert.pem`)
--tlsKeyFile <string> File containing the x509 private key matching --tlsCertFile. (default `/etc/istio/certs/key.pem`)
- - - - - - - - - - - - - - - - - - - From 50e33d872dc40b146ebccb234bf89fe211ec7e46 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Mon, 12 Mar 2018 09:46:07 -0700 Subject: [PATCH 029/191] Eliminate flickering on page load. (#1068) - Fix another issue with my arch-nemesis, the Copy button. My last fix for Copy button issues resulted in screen flickering upon page loading. This is now fixed. - Pin the size of the gear and magnifying glass icons in the header to avoid flicker as the fonts for those renders a few ms too late and lead to flickering on page load. - Cleaned up the site's JavaScript for clarity, and include minimized versions in the site for improved perf. --- _config.yml | 3 + _includes/header.html | 4 +- _layouts/base.html | 4 +- _sass/base/_common.scss | 25 ++-- _sass/modules/_header.scss | 3 +- js/misc.js | 144 ++++++++++++---------- js/misc.min.js | 5 + js/{styleswitcher.js => styleSwitcher.js} | 0 js/styleSwitcher.min.js | 1 + 9 files changed, 105 insertions(+), 84 deletions(-) create mode 100644 js/misc.min.js rename js/{styleswitcher.js => styleSwitcher.js} (100%) create mode 100644 js/styleSwitcher.min.js diff --git a/_config.yml b/_config.yml index 837eba754191..9ac5b5eab0a9 100644 --- a/_config.yml +++ b/_config.yml @@ -63,6 +63,9 @@ exclude: - repos/*.html - repos/*.md - vendor/ + - js/misc.js + - js/styleSwitcher.js + - firebase.json repository: istio/istio.github.io diff --git a/_includes/header.html b/_includes/header.html index 63c21d037169..3f8417136f57 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -3,7 +3,7 @@ {% assign current = page.url | downcase | split: '/' %}
-
- + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + diff --git a/_docs/reference/commands/node_agent.html b/_docs/reference/commands/node_agent.html index d62b939f398c..aec28137f3a6 100644 --- a/_docs/reference/commands/node_agent.html +++ b/_docs/reference/commands/node_agent.html @@ -74,6 +74,10 @@ + + + + diff --git a/_docs/reference/config/adapters/circonus.html b/_docs/reference/config/adapters/circonus.html index 668e389d2ca0..e3b46092b214 100644 --- a/_docs/reference/config/adapters/circonus.html +++ b/_docs/reference/config/adapters/circonus.html @@ -10,7 +10,7 @@

Params

-

Cnofiguration format for the Circonus adapter.

+

Configuration format for the Circonus adapter.

FlagsShorthand Description
--healthCheckFile <string> File that should be periodically updated if health checking is enabled (default ``)
--healthCheckInterval <duration> Configure how frequently the health check file specified by --healhCheckFile should be updated (default `0s`)
--injectConfig <string> File containing the Istio sidecar injection configuration and template (default `/etc/istio/inject/config`)
--interval <duration> Duration used for checking the target file's last modified time. (default `0s`)
--log_as_json Whether to format output as JSON or in plain console-friendly format
--log_callers Include caller information, useful for debugging
--log_output_level <string> The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string> The path for the optional rotating log file (default ``)
--log_rotate_max_age <int> The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int> The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int> The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string> The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray> The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
--meshConfig <string> File containing the Istio mesh configuration (default `/etc/istio/config/mesh`)
--port <int> Webhook port (default `443`)
--probe-path <string> Path of the file for checking the availability. (default ``)
--tlsCertFile <string> File containing the x509 Certificate for HTTPS. (default `/etc/istio/certs/cert.pem`)
--tlsKeyFile <string> File containing the x509 private key matching --tlsCertFile. (default `/etc/istio/certs/key.pem`)
attributesmap<string,Attributes.AttributeValue>map<string, Attributes.AttributeValue>

A map of attribute name to its value.

@@ -196,7 +196,7 @@

Attributes.StringMap

entriesmap<string,string>map<string, string>

Holds a set of name/value pairs.

@@ -250,7 +250,7 @@

CheckRequest

quotasmap<string,CheckRequest.QuotaParams>map<string, CheckRequest.QuotaParams>

The individual quotas to allocate

@@ -314,7 +314,7 @@

CheckResponse

quotasmap<string,CheckResponse.QuotaResult>map<string, CheckResponse.QuotaResult>

The resulting quota, one entry per requested quota.

@@ -457,7 +457,7 @@

CompressedAttributes

stringsmap<int32,int32>map<int32, int32>

Holds attributes of type STRING, DNSNAME, EMAILADDRESS, URI

@@ -465,7 +465,7 @@

CompressedAttributes

int64smap<int32,int64>map<int32, int64>

Holds attributes of type INT64

@@ -473,7 +473,7 @@

CompressedAttributes

doublesmap<int32,double>map<int32, double>

Holds attributes of type DOUBLE

@@ -481,7 +481,7 @@

CompressedAttributes

boolsmap<int32,bool>map<int32, bool>

Holds attributes of type BOOL

@@ -489,7 +489,7 @@

CompressedAttributes

timestampsmap<int32,google.protobuf.Timestamp>map<int32, google.protobuf.Timestamp>

Holds attributes of type TIMESTAMP

@@ -497,7 +497,7 @@

CompressedAttributes

durationsmap<int32,google.protobuf.Duration>map<int32, google.protobuf.Duration>

Holds attributes of type DURATION

@@ -505,7 +505,7 @@

CompressedAttributes

bytesmap<int32,bytes>map<int32, bytes>

Holds attributes of type BYTES

@@ -513,7 +513,7 @@

CompressedAttributes

stringMapsmap<int32,StringMap>map<int32, StringMap>

Holds attributes of type STRING_MAP

@@ -740,7 +740,7 @@

StringMap

entriesmap<int32,int32>map<int32, int32>

Holds a set of name/value pairs.

diff --git a/_docs/reference/commands/mixs.html b/_docs/reference/commands/mixs.html index 4cfd8032c8b3..dd0444b49e18 100644 --- a/_docs/reference/commands/mixs.html +++ b/_docs/reference/commands/mixs.html @@ -241,6 +241,11 @@

mixs validator

--configStoreURL <string>URL of the config store. Use k8s://path_to_kubeconfig or fs:// for file system. If path_to_kubeconfig is empty, in-cluster kubeconfig is used. (default ``)
--external-admission-webook-name <string> the name of the external admission webhook registration. Needs to be a domain with at least three segments separated by dots. (default `mixer-webhook.istio.io`)Organization for the cert (default ``)
--platform <string>The platform istio runs on: vm | k8s (default `vm`)
--root-cert <string> Root Certificate file (default `/etc/certs/root-cert.pem`)
diff --git a/_docs/reference/config/adapters/datadog.html b/_docs/reference/config/adapters/datadog.html index 4316166baaec..cccc601008a8 100644 --- a/_docs/reference/config/adapters/datadog.html +++ b/_docs/reference/config/adapters/datadog.html @@ -74,7 +74,7 @@

Params

diff --git a/_docs/reference/config/adapters/denier.html b/_docs/reference/config/adapters/denier.html index f2fed94d2798..03f79322841d 100644 --- a/_docs/reference/config/adapters/denier.html +++ b/_docs/reference/config/adapters/denier.html @@ -10,7 +10,7 @@

Params

-

Cnofiguration format for the Denier adapter.

+

Configuration format for the Denier adapter.

metrics map<string, Params.MetricInfo> -

Map of a specific metric instance name -> info. If a metric’s instnace name is not in the map then the metric will not be exported to DataDog.

+

Map of a specific metric instance name -> info. If a metric’s instance name is not in the map then the metric will not be exported to DataDog.

diff --git a/_docs/reference/config/adapters/list.html b/_docs/reference/config/adapters/list.html index 0ed11f451e5b..1370b0d95477 100644 --- a/_docs/reference/config/adapters/list.html +++ b/_docs/reference/config/adapters/list.html @@ -132,7 +132,7 @@

Params.ListEntryType

diff --git a/_docs/reference/config/istio.mesh.v1alpha1.html b/_docs/reference/config/istio.mesh.v1alpha1.html index 8cd534c4706a..68ebb8fe4335 100644 --- a/_docs/reference/config/istio.mesh.v1alpha1.html +++ b/_docs/reference/config/istio.mesh.v1alpha1.html @@ -4,7 +4,7 @@ location: https://istio.io/docs/reference/config/istio.mesh.v1alpha1.html layout: protoc-gen-docs redirect_from: /docs/reference/config/service-mesh.html -number_of_entries: 6 +number_of_entries: 5 ---

AuthenticationPolicy

@@ -64,7 +64,14 @@

MeshConfig

@@ -72,7 +79,8 @@

MeshConfig

@@ -204,29 +212,6 @@

MeshConfig

DEPRECATED. Mixer address. This option will be removed soon. Please use mixercheck and mixerreport.

- - - - - - - - - - - @@ -376,7 +361,7 @@

ProxyConfig

@@ -466,30 +451,6 @@

ProxyConfig

- - - - - - - - - - - - - - - @@ -503,36 +464,3 @@

ProxyConfig

REGEX -

List entries are treated as re2 regexp. See https://github.com/google/re2/wiki/Syntax for syntax.

+

List entries are treated as re2 regexp. See here for the supported syntax.

mixerCheckServer string -

Deprecated, use mixer_check instead.

+

Address of the server that will be used by the proxies for policy +check calls. By using different names for mixerCheckServer and +mixerReportServer, it is possible to have one set of mixer servers handle +policy check calls while another set of mixer servers handle telemetry +calls.

+ +

NOTE: Omitting mixerCheckServer while specifying mixerReportServer is +equivalent to setting disablePolicyChecks to true.

mixerReportServer string -

Deprecated, use mixer_report instead.

+

Address of the server that will be used by the proxies for policy report +calls.

mixerCheckServerAddress -

Address of the server that will be used by the proxies for policy -check calls. By using different names for mixerCheck and mixerReport, it -is possible to have one set of mixer servers handle policy check calls, -while another set of mixer servers handle telemetry calls.

- -

NOTE: Omitting mixerCheck while specifying mixerReport is -equivalent to setting disablePolicyChecks to true.

- -
mixerReportServerAddress -

Address of the server that will be used by the proxies for policy report -calls.

-
discoveryAddress string -

Deprecated, use server_address instead.

+

Address of the discovery service exposing xDS with mTLS connection.

The number of worker threads to run. Default value is number of cores on the machine.

-
pilotServerAddress -

Deprecated, use discoverymtlsaddress/discoveryplainaddress instead.

- -
discoveryMtlsAddressstring -

Address of the discovery service exposing xDS with mTLS connection.

- -
discoveryPlainAddressstring -

Address of the discovery service exposing xDS with plain text connection.

-
-

ServerAddress

-
-

ServerAddress specifies the address of Istio components like mixer, pilot, etc. -At least one of the field needs to be specified.

- - - - - - - - - - - - - - - - - - - - - -
FieldTypeDescription
mutualTlsstring -

The address for mTLS server, e.g., (istio-pilot:15003)

- -
plainTextstring -

The address for plain text server, e.g., (istio-pilot:15005)

- -
-
diff --git a/_docs/reference/config/istio.mixer.v1.config.client.html b/_docs/reference/config/istio.mixer.v1.config.client.html index b2de35928469..f3b045431fd2 100644 --- a/_docs/reference/config/istio.mixer.v1.config.client.html +++ b/_docs/reference/config/istio.mixer.v1.config.client.html @@ -87,7 +87,7 @@

AttributeMatch

clause -map<string,StringMatch> +map<string, StringMatch>

Map of attribute names to StringMatch type. Each map element specifies one condition to match.

@@ -507,7 +507,7 @@

HttpClientConfig

serviceConfigs -map<string,ServiceConfig> +map<string, ServiceConfig>

Map of control configuration indexed by destination.service. This is used to support per-service configuration for cases where a @@ -595,7 +595,7 @@

IstioService

labels -map<string,string> +map<string, string>

Optional one or more labels that uniquely identify the service version.

@@ -1304,7 +1304,7 @@

istio.mixer.v1.Attributes

attributes -map<string,istio.mixer.v1.Attributes.AttributeValue> +map<string, istio.mixer.v1.Attributes.AttributeValue>

A map of attribute name to its value.

diff --git a/_docs/reference/config/istio.mixer.v1.config.html b/_docs/reference/config/istio.mixer.v1.config.html deleted file mode 100644 index 3067dae281d1..000000000000 --- a/_docs/reference/config/istio.mixer.v1.config.html +++ /dev/null @@ -1,381 +0,0 @@ ---- -title: Policy and Telemetry Rules -overview: Describes the rules used to configure Mixer's policy and telemetry features. -location: https://istio.io/docs/reference/config/istio.mixer.v1.config.html -layout: protoc-gen-docs -redirect_from: /docs/reference/config/mixer/policy-and-telemetry-rules.html -number_of_entries: 7 ---- -

Action

-
-

Action describes which Handler to invoke and what data to pass to it for processing.

- -

The following example instructs Mixer to invoke ‘prometheus-handler’ handler and pass it the object -constructed using the instance ‘RequestCountByService’

- -
  handler: prometheus-handler
-  instances:
-  - RequestCountByService
-
- - - - - - - - - - - - - - - - - - - - - -
FieldTypeDescription
handlerstring -

Required. Fully qualified name of the handler to invoke. -Must match the name of a Handler.

- -
instancesstring[] -

Required. Each value must match the fully qualified name of the -Instances. -Referenced instances are evaluated by resolving the attributes/literals for all the fields. -The constructed objects are then passed to the handler referenced within this action.

- -
-
-

AttributeManifest

-
-

AttributeManifest describes a set of Attributes produced by some component -of an Istio deployment.

- - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeDescription
revisionstring -

Optional. The revision of this document. Assigned by server.

- -
namestring -

Required. Name of the component producing these attributes. This can be -the proxy (with the canonical name “istio-proxy”) or the name of an -attributes kind adapter in Mixer.

- -
attributesmap<string,AttributeManifest.AttributeInfo> -

The set of attributes this Istio component will be responsible for producing at runtime. -We map from attribute name to the attribute’s specification. The name of an attribute, -which is how attributes are referred to in aspect configuration, must conform to:

- -
Name = IDENT { SEPARATOR IDENT };
-
- -

Where IDENT must match the regular expression *a-z*+ and SEPARATOR must -match the regular expression [\.-].

- -

Attribute names must be unique within a single Istio deployment. The set of canonical -attributes are described at https://istio.io/docs/reference/attribute-vocabulary.html. -Attributes not in that list should be named with a component-specific suffix such as -request.count-my.component

- -
-
-

AttributeManifest.AttributeInfo

-
-

AttributeInfo describes the schema of an Istio Attribute.

- -

Istio Attributes

- -

Istio uses attributes to describe runtime activities of Istio services. -An Istio attribute carries a specific piece of information about an activity, -such as the error code of an API request, the latency of an API request, or the -original IP address of a TCP connection. The attributes are often generated -and consumed by different services. For example, a frontend service can -generate an authenticated user attribute and pass it to a backend service for -access control purpose.

- -

To simplify the system and improve developer experience, Istio uses -shared attribute definitions across all components. For example, the same -authenticated user attribute will be used for logging, monitoring, analytics, -billing, access control, auditing. Many Istio components provide their -functionality by collecting, generating, and operating on attributes. -For example, the proxy collects the error code attribute, and the logging -stores it into a log.

- -

Design

- -

Each Istio attribute must conform to an AttributeInfo in an -AttributeManifest in the current Istio deployment at runtime. An -AttributeInfo is used to define an attribute’s -metadata: the type of its value and a detailed description that explains -the semantics of the attribute type. Each attribute’s name is globally unique; -in other words an attribute name can only appear once across all manifests.

- -

The runtime presentation of an attribute is intentionally left out of this -specification, because passing attribute using JSON, XML, or Protocol Buffers -does not change the semantics of the attribute. Different implementations -can choose different representations based on their needs.

- -

HTTP Mapping

- -

Because many systems already have REST APIs, it makes sense to define a -standard HTTP mapping for Istio attributes that are compatible with typical -REST APIs. The design is to map one attribute to one HTTP header, the -attribute name and value becomes the HTTP header name and value. The actual -encoding scheme will be decided later.

- - - - - - - - - - - - - - - - - - - - - -
FieldTypeDescription
descriptionstring -

Optional. A human-readable description of the attribute’s purpose.

- -
valueTypeistio.mixer.v1.config.descriptor.ValueType -

Required. The type of data carried by this attribute.

- -
-
-

Handler

-
-

Handler allows the operator to configure a specific adapter implementation. -Each adapter implementation defines its own params proto.

- -

In the following example we define a metrics handler using the Mixer’s prepackaged -prometheus adapter. This handler doesn’t require any parameters.

- -
name: prometheus-handler
-adapter: prometheus
-params:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeDescription
namestring -

Required. Must be unique in the entire mixer configuration. Used by Actions -to refer to this handler.

- -
adapterstring -

Required. The name of a specific adapter implementation. An adapter’s -implementation name is typically a constant in its code.

- -
paramsgoogle.protobuf.Struct -

Optional. Depends on adapter implementation. Struct representation of a -proto defined by the adapter implementation; this varies depending on the value of field adapter.

- -
-
-

Instance

-
-

An Instance tells Mixer how to create instances for particular template.

- -

Instance is defined by the operator. Instance is defined relative to a known -template. Their purpose is to tell Mixer how to use attributes or literals to produce -instances of the specified template at runtime.

- -

The following example instructs Mixer to construct an instance associated with template -‘istio.mixer.adapter.metric.Metric’. It provides a mapping from the template’s fields to expressions. -Instances produced with this instance can be referenced by Actions using name -‘RequestCountByService’.

- -
- name: RequestCountByService
-  template: istio.mixer.adapter.metric.Metric
-  params:
-    value: 1
-    dimensions:
-      source: source.service
-      destination_ip: destination.ip
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeDescription
namestring -

Required. The name of this instance

- -

Must be unique amongst other Instances in scope. Used by Action to refer -to an instance produced by this instance.

- -
templatestring -

Required. The name of the template this instance creates instances for. -The value must match the name of the available template in scope.

- -
paramsgoogle.protobuf.Struct -

Required. Depends on referenced template. Struct representation of a -proto defined by the template; this varies depending on the value of field template.

- -
-
-

Rule

-
-

A Rule is a selector and a set of intentions to be executed when the -selector is true

- -

The following example instructs Mixer to invoke ‘prometheus-handler’ handler for all services and pass it the -instance constructed using the ‘RequestCountByService’ instance.

- -
- match: destination.service == "*"
-  actions:
-  - handler: prometheus-handler
-    instances:
-    - RequestCountByService
-
- - - - - - - - - - - - - - - - - - - - - -
FieldTypeDescription
matchstring -

Required. Match is an attribute based predicate. When Mixer receives a -request it evaluates the match expression and executes all the associated actions -if the match evaluates to true.

- -

A few example match:

- -
    -
  • an empty match evaluates to true
  • -
  • true, a boolean literal; a rule with this match will always be executed
  • -
  • destination.service == ratings* selects any request targeting a service whose -name starts with “ratings”
  • -
  • attr1 == "20" && attr2 == "30" logical AND, OR, and NOT are also available
  • -
- -
actionsAction[] -

Optional. The actions that will be executed when match evaluates to true.

- -
-
-

google.protobuf.Struct

-
-

Struct represents a structured data value, consisting of fields -which map to dynamically typed values. In some languages, Struct -might be supported by a native representation. For example, in -scripting languages like JS a struct is represented as an -object. The details of that representation are described together -with the proto support for the language.

- -

The JSON representation for Struct is JSON object.

- - - - - - - - - - - - - - - - -
FieldTypeDescription
fieldsmap<string,google.protobuf.Value> -

Unordered map of dynamically typed values.

- -
-
diff --git a/_docs/reference/config/istio.rbac.v1alpha1.html b/_docs/reference/config/istio.rbac.v1alpha1.html index 83cfbed8bbae..facf130c5ed3 100644 --- a/_docs/reference/config/istio.rbac.v1alpha1.html +++ b/_docs/reference/config/istio.rbac.v1alpha1.html @@ -319,7 +319,7 @@

Subject

properties -map<string,string> +map<string, string>

Optional. The set of properties that identify the subject. In the above ServiceRoleBinding example, the second subject has two properties: diff --git a/_docs/reference/config/istio.routing.v1alpha1.html b/_docs/reference/config/istio.routing.v1alpha1.html index e1d4f685cbcd..ea6d13a7cad2 100644 --- a/_docs/reference/config/istio.routing.v1alpha1.html +++ b/_docs/reference/config/istio.routing.v1alpha1.html @@ -456,7 +456,7 @@

DestinationWeight

labels -map<string,string> +map<string, string>

Sometimes required. Service version identifier for the destination service. (– N.B. The map is used instead of pstruct due to lack of serialization support @@ -1213,7 +1213,7 @@

IstioService

labels -map<string,string> +map<string, string>

Optional one or more labels that uniquely identify the service version.

@@ -1581,7 +1581,7 @@

MatchRequest

headers -map<string,StringMatch> +map<string, StringMatch>

Set of HTTP match conditions based on HTTP/1.1, HTTP/2, GRPC request metadata, such as uri, scheme, authority. The header keys must be @@ -1780,7 +1780,7 @@

RouteRule

appendHeaders -map<string,string> +map<string, string>

Additional HTTP headers to add before forwarding a request to the destnation service.

diff --git a/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html b/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html index ecd9c9eb80d4..c9cc5b7a96fa 100644 --- a/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html +++ b/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html @@ -1,35 +1,358 @@ --- title: Mixer Adapter Model -overview: Definitions used when creating Mixer templates +overview: Definitions used to create adapters and templates location: https://istio.io/docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html layout: protoc-gen-docs -number_of_entries: 8 +number_of_entries: 22 --- -

This package defines the types that are used when creating Mixer templates. ValueType defined in this pacakge -is also used by adapters to know the underlying datatype of the instance fields.

+

This package defines the service and types used by adapter code to serve requests from Mixer. +This package also defines the types that are used to create Mixer templates.

-

DNSName

+

Services

+

InfrastructureBackend

+
+

InfrastructureBackend is implemented by backends that wants to provide telemetry and policy functionality to Mixer as an +out of process adapter.

+ +

InfrastructureBackend allows Mixer and the backends to have a session based model. In a session based model, Mixer passes +the relevant configuration state to the backend only once and estabilshes a session using a session identifier. +All future communications between Mixer and the backend uses the session identifier which refers to the previously +passed in configuration data.

+ +

For a given InfrastructureBackend, Mixer calls the Validate function, followed by CreateSession. The session_id +returned from CreateSession is used to make subsequent request-time Handle calls and the eventual CloseSession function. +Mixer assumes that, given the session_id, the backend can retrieve the necessary context to serve the +Handle calls that contains the request-time payload (template-specific instance protobuf).

+ +
rpc Validate(ValidateRequest) returns (ValidateResponse)
+
+

Validates the handler configuration along with the template-specific instances that would be routed to that +handler. The CreateSession for a specific handler configuration is invoked only if its associated Validate +call has returned success.

+ +
rpc CreateSession(CreateSessionRequest) returns (CreateSessionResponse)
+
+

Creates a session for a given handler configuration and the template-specific instances that would be routed to +that handler. For every handler configuration, Mixer creates a separate session by invoking CreateSession +on the backend.

+ +

CreateSessionRequest contains the adapter specific handler configuration and the inferred type information about +the instances the handler would receive during request processing.

+ +

CreateSession must return a session_id which Mixer uses to invoke template-specific Handle functions during +request processing. The session_id provides the Handle functions a way to retrieve the necessary configuration +associated with the session. Upon Mixer configuration change, Mixer will re-invoke CreateSession for all +handler configurations whose existing sessions are invalidated or didn’t existed.

+ +

Backend is allowed to return the same session id if given the same configuration block. +This would happen when multiple instances of Mixer in a deployment all create sessions with the same configuration. +Note that given individial instances of Mixer can call CloseSession, reusing session_id by the backend +assumes that the backend is doing reference counting.

+ +

If the backend couldn’t create a session for a specific handler configuration and +returns non S_OK status, Mixer will not make request-time Handle calls associated with that handler configuration.

+ +
rpc CloseSession(CloseSessionRequest) returns (CloseSessionResponse)
+
+

Closes the session associated with the session_id. Mixer closes a session when its associated handler +configuration or the instance configuration changes. Backend is supposed to cleanup all the resources associated +with the session_id referenced by CloseSessionRequest.

+ +
+

Types

+

CheckResult

+
+

Expresses the result of a precondition check.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
statusgoogle.rpc.Status +

A status code of OK indicates preconditions were satisfied. Any other code indicates preconditions were not +satisfied and details describe why.

+ +
validDurationgoogle.protobuf.Duration +

The amount of time for which this result can be considered valid.

+ +
validUseCountint32 +

The number of uses for which this result can be considered valid.

+ +
+
+

CloseSessionRequest

+
+

Request message for CloseSession method.

+ + + + + + + + + + + + + + + + +
FieldTypeDescription
sessionIdstring +

Id of the session to be closed.

+ +
+
+

CloseSessionResponse

+
+

Response message for CloseSession method.

+ + + + + + + + + + + + + + + + +
FieldTypeDescription
statusgoogle.rpc.Status +

The success/failure status of close session call.

+ +
+
+

CreateSessionRequest

+
+

Request message for CreateSession method.

+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
adapterConfiggoogle.protobuf.Any +

Adapter specific configuration.

+ +
inferredTypesmap<string, google.protobuf.Any> +

Map of instance names to their template-specific inferred type.

+ +
+
+

CreateSessionResponse

+
+

Response message for CreateSession method.

+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
sessionIdstring +

Id of the created session.

+ +
statusgoogle.rpc.Status +

The success/failure status of create session call.

+ +
+
+

DNSName

DNSName is used inside templates for fields that are of ValueType “DNS_NAME”

-

Duration

+

Duration

Duration is used inside templates for fields that are of ValueType “DURATION”

-

EmailAddress

+

EmailAddress

EmailAddress is used inside templates for fields that are of ValueType “EMAIL_ADDRESS” DO NOT USE !! Under Development

-

IPAddress

+

IPAddress

IPAddress is used inside templates for fields that are of ValueType “IP_ADDRESS”

-

TemplateVariety

+

QuotaRequest

+
+

Expresses the quota allocation request.

+ + + + + + + + + + + + + + + + +
FieldTypeDescription
quotasmap<string, QuotaRequest.QuotaParams> +

The individual quotas to allocate

+ +
+
+

QuotaRequest.QuotaParams

+
+

parameters for a quota allocation

+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
amountint64 +

Amount of quota to allocate

+ +
bestEffortbool +

When true, supports returning less quota than what was requested.

+ +
+
+

QuotaResult

+
+

Expresses the result of multiple quota allocations.

+ + + + + + + + + + + + + + + + +
FieldTypeDescription
quotasmap<string, QuotaResult> +

The resulting quota, one entry per requested quota.

+ +
+
+

QuotaResult.Result

+
+

Expresses the result of a quota allocation.

+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
validDurationgoogle.protobuf.Duration +

The amount of time for which this result can be considered valid.

+ +
grantedAmountint64 +

The amount of granted quota. When QuotaParams.best_effort is true, this will be >= 0. +If QuotaParams.best_effort is false, this will be either 0 or >= QuotaParams.amount.

+ +
+
+

ReportResult

+
+

Expresses the result of a report call.

+ +
+

TemplateVariety

The available varieties of templates, controlling the semantics of what an adapter does with each instance.

@@ -72,20 +395,174 @@

TemplateVariety

-

TimeStamp

+

TimeStamp

TimeStamp is used inside templates for fields that are of ValueType “TIMESTAMP”

-

Uri

+

Uri

Uri is used inside templates for fields that are of ValueType “URI” DO NOT USE ! Under Development

-

Value

+

ValidateRequest

+
+

Request message for Validate method.

+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
adapterConfiggoogle.protobuf.Any +

Adapter specific configuration.

+ +
inferredTypesmap<string, google.protobuf.Any> +

Map of instance names to their template-specific inferred type.

+ +
+
+

ValidateResponse

+
+

Response message for Validate method.

+ + + + + + + + + + + + + + + + +
FieldTypeDescription
statusgoogle.rpc.Status +

The success/failure status of validation call.

+ +
+
+

Value

Value is used inside templates for fields that have dynamic types. The actual datatype of the field depends on the datatype of the expression used in the operator configuration.

+

google.rpc.Status

+
+

The Status type defines a logical error model that is suitable for different +programming environments, including REST APIs and RPC APIs. It is used by +gRPC. The error model is designed to be:

+ +
    +
  • Simple to use and understand for most users
  • +
  • Flexible enough to meet unexpected needs
  • +
+ +

Overview

+ +

The Status message contains three pieces of data: error code, error message, +and error details. The error code should be an enum value of +google.rpc.Code, but it may accept additional error codes if needed. The +error message should be a developer-facing English message that helps +developers understand and resolve the error. If a localized user-facing +error message is needed, put the localized message in the error details or +localize it in the client. The optional error details may contain arbitrary +information about the error. There is a predefined set of error detail types +in the package google.rpc that can be used for common error conditions.

+ +

Language mapping

+ +

The Status message is the logical representation of the error model, but it +is not necessarily the actual wire format. When the Status message is +exposed in different client libraries and different wire protocols, it can be +mapped differently. For example, it will likely be mapped to some exceptions +in Java, but more likely mapped to some error codes in C.

+ +

Other uses

+ +

The error model and the Status message can be used in a variety of +environments, either with or without APIs, to provide a +consistent developer experience across different environments.

+ +

Example uses of this error model include:

+ +
    +
  • Partial errors. If a service needs to return partial errors to the client, +it may embed the Status in the normal response to indicate the partial +errors.

  • + +
  • Workflow errors. A typical workflow has multiple steps. Each step may +have a Status message for error reporting.

  • + +
  • Batch operations. If a client uses batch request and batch response, the +Status message should be used directly inside batch response, one for +each error sub-response.

  • + +
  • Asynchronous operations. If an API call embeds asynchronous operation +results in its response, the status of those operations should be +represented directly using the Status message.

  • + +
  • Logging. If some API errors are stored in logs, the message Status could +be used directly after any stripping needed for security/privacy reasons.

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
codeint32 +

The status code, which should be an enum value of google.rpc.Code.

+ +
messagestring +

A developer-facing error message, which should be in English. Any +user-facing error message should be localized and sent in the +google.rpc.Status.details field, or localized by the client.

+ +
detailsgoogle.protobuf.Any[] +

A list of messages that carry the error details. There is a common set of +message types for APIs to use.

+ +
+
diff --git a/_docs/reference/config/mixer/istio.mixer.v1.config.descriptor.html b/_docs/reference/config/mixer/istio.mixer.v1.config.descriptor.html deleted file mode 100644 index 3a3f8afb09b0..000000000000 --- a/_docs/reference/config/mixer/istio.mixer.v1.config.descriptor.html +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: Value Type -overview: Value types used with templates -location: https://istio.io/docs/reference/config/mixer/istio.mixer.v1.config.descriptor.html -layout: protoc-gen-docs -number_of_entries: 1 ---- -

ValueType

-
-

ValueType describes the types that values in the Istio system can take. These -are used to describe the type of Attributes at run time, describe the type of -the result of evaluating an expression, and to describe the runtime type of -fields of other descriptors.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameDescription
VALUE_TYPE_UNSPECIFIED -

Invalid, default value.

- -
STRING -

An undiscriminated variable-length string.

- -
INT64 -

An undiscriminated 64-bit signed integer.

- -
DOUBLE -

An undiscriminated 64-bit floating-point value.

- -
BOOL -

An undiscriminated boolean value.

- -
TIMESTAMP -

A point in time.

- -
IP_ADDRESS -

An IP address.

- -
EMAIL_ADDRESS -

An email address.

- -
URI -

A URI.

- -
DNS_NAME -

A DNS name.

- -
DURATION -

A span between two points in time.

- -
STRING_MAP -

A map string -> string, typically used by headers.

- -
-
diff --git a/_docs/reference/config/mixer/istio.mixer.v1.template.html b/_docs/reference/config/mixer/istio.mixer.v1.template.html deleted file mode 100644 index e9ad08d35a28..000000000000 --- a/_docs/reference/config/mixer/istio.mixer.v1.template.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: Template Metadata -overview: Definitions used when creating Mixer templates -location: https://istio.io/docs/reference/config/mixer/istio.mixer.v1.template.html -layout: protoc-gen-docs -number_of_entries: 8 ---- -

This proto describes the types that can be used inside Mixer templates. These message types are used to specify -field datatype to express the equivalent ValueType for the expressions the field can be mapped to.

- -

DNSName

-
-

DNSName is used inside templates for fields that are of ValueType “DNS_NAME”

- -
-

Duration

-
-

Duration is used inside templates for fields that are of ValueType “DURATION”

- -
-

EmailAddress

-
-

EmailAddress is used inside templates for fields that are of ValueType “EMAIL_ADDRESS” -DO NOT USE !! Under Development

- -
-

IPAddress

-
-

IPAddress is used inside templates for fields that are of ValueType “IP_ADDRESS”

- -
-

TemplateVariety

-
-

Specifies the varity of the the Template.

- - - - - - - - - - - - - - - - - - - - - - - - - - -
NameDescription
TEMPLATE_VARIETY_CHECK -
TEMPLATE_VARIETY_REPORT -
TEMPLATE_VARIETY_QUOTA -
TEMPLATE_VARIETY_ATTRIBUTE_GENERATOR -
-
-

TimeStamp

-
-

TimeStamp is used inside templates for fields that are of ValueType “TIMESTAMP”

- -
-

Uri

-
-

Uri is used inside templates for fields that are of ValueType “URI” -DO NOT USE ! Under Development

- -
-

Value

-
-

Value is used inside templates for fields that have dynamic types. The actual datatype -of the field depends on the datatype of the expression used in the operator configuration.

- -
diff --git a/_docs/reference/config/template/apikey.html b/_docs/reference/config/template/apikey.html index d24bca8d6aba..902242dde534 100644 --- a/_docs/reference/config/template/apikey.html +++ b/_docs/reference/config/template/apikey.html @@ -3,7 +3,7 @@ overview: A template that represents a single API key. location: https://istio.io/docs/reference/config/template/apikey.html layout: protoc-gen-docs -number_of_entries: 1 +number_of_entries: 2 ---

The apikey template represents a single API key, which is used for authorization checks.

@@ -69,7 +69,7 @@

Template

timestamp -istio.mixer.adapter.model.v1beta1.TimeStamp +istio.mixer.adapter.model.v1beta1.TimeStamp

Timestamp of API call.

@@ -78,3 +78,8 @@

Template

+

istio.mixer.adapter.model.v1beta1.TimeStamp

+
+

TimeStamp is used inside templates for fields that are of ValueType “TIMESTAMP”

+ +
diff --git a/_docs/reference/config/template/authorization.html b/_docs/reference/config/template/authorization.html index 4c5b21f8c657..d87271e3fc1f 100644 --- a/_docs/reference/config/template/authorization.html +++ b/_docs/reference/config/template/authorization.html @@ -3,7 +3,7 @@ overview: A template used to represent an access control query. location: https://istio.io/docs/reference/config/template/authorization.html layout: protoc-gen-docs -number_of_entries: 3 +number_of_entries: 4 ---

The authorization template defines parameters for performing policy enforcement within Istio. It is primarily concerned with enabling Mixer

@@ -55,7 +55,7 @@

Action

properties -map<string, istio.mixer.adapter.model.v1beta1.Value> +map<string, istio.mixer.adapter.model.v1beta1.Value>

Additional data about the action for use in policy.

@@ -99,7 +99,7 @@

Subject

properties -map<string, istio.mixer.adapter.model.v1beta1.Value> +map<string, istio.mixer.adapter.model.v1beta1.Value>

Additional attributes about the subject.

@@ -132,8 +132,8 @@

Template

properties: iss: request.auth.token["iss"] action: - namespace: target.namespace | "default" - service: target.service | "" + namespace: destination.namespace | "default" + service: destination.service | "" path: request.path | "/" method: request.method | "post" properties: @@ -169,3 +169,9 @@

Template

+

istio.mixer.adapter.model.v1beta1.Value

+
+

Value is used inside templates for fields that have dynamic types. The actual datatype +of the field depends on the datatype of the expression used in the operator configuration.

+ +
diff --git a/_docs/reference/config/template/kubernetes.html b/_docs/reference/config/template/kubernetes.html index f13b6653959e..2ed145a0b776 100644 --- a/_docs/reference/config/template/kubernetes.html +++ b/_docs/reference/config/template/kubernetes.html @@ -3,7 +3,7 @@ overview: A template that is used to control the production of Kubernetes-specific attributes. location: https://istio.io/docs/reference/config/template/kubernetes.html layout: protoc-gen-docs -number_of_entries: 2 +number_of_entries: 3 ---

The kubernetes template holds data that controls the production of Kubernetes-specific attributes.

@@ -24,7 +24,7 @@

OutputTemplate

sourcePodIp -istio.mixer.adapter.model.v1beta1.IPAddress +istio.mixer.adapter.model.v1beta1.IPAddress

Refers to source pod ip address. attributebindings can refer to this field using $out.sourcepod_ip

@@ -72,7 +72,7 @@

OutputTemplate

sourceHostIp -istio.mixer.adapter.model.v1beta1.IPAddress +istio.mixer.adapter.model.v1beta1.IPAddress

Refers to source pod host ip address. attributebindings can refer to this field using $out.sourcehost_ip

@@ -80,7 +80,7 @@

OutputTemplate

destinationPodIp -istio.mixer.adapter.model.v1beta1.IPAddress +istio.mixer.adapter.model.v1beta1.IPAddress

Refers to destination pod ip address. attributebindings can refer to this field using $out.destinationpod_ip

@@ -128,7 +128,7 @@

OutputTemplate

destinationHostIp -istio.mixer.adapter.model.v1beta1.IPAddress +istio.mixer.adapter.model.v1beta1.IPAddress

Refers to destination pod host ip address. attributebindings can refer to this field using $out.destinationhost_ip

@@ -136,7 +136,7 @@

OutputTemplate

originPodIp -istio.mixer.adapter.model.v1beta1.IPAddress +istio.mixer.adapter.model.v1beta1.IPAddress

Refers to origin pod ip address. attributebindings can refer to this field using $out.originpod_ip

@@ -184,7 +184,7 @@

OutputTemplate

originHostIp -istio.mixer.adapter.model.v1beta1.IPAddress +istio.mixer.adapter.model.v1beta1.IPAddress

Refers to origin pod host ip address. attributebindings can refer to this field using $out.originhost_ip

@@ -247,7 +247,7 @@

Template

sourceIp -istio.mixer.adapter.model.v1beta1.IPAddress +istio.mixer.adapter.model.v1beta1.IPAddress

Source pod’s ip.

@@ -263,7 +263,7 @@

Template

destinationIp -istio.mixer.adapter.model.v1beta1.IPAddress +istio.mixer.adapter.model.v1beta1.IPAddress

Destination pod’s ip.

@@ -279,7 +279,7 @@

Template

originIp -istio.mixer.adapter.model.v1beta1.IPAddress +istio.mixer.adapter.model.v1beta1.IPAddress

Origin pod’s ip.

@@ -288,3 +288,8 @@

Template

+

istio.mixer.adapter.model.v1beta1.IPAddress

+
+

IPAddress is used inside templates for fields that are of ValueType “IP_ADDRESS”

+ +
diff --git a/_docs/reference/config/template/logentry.html b/_docs/reference/config/template/logentry.html index 279452151dd7..3f3e9e924d64 100644 --- a/_docs/reference/config/template/logentry.html +++ b/_docs/reference/config/template/logentry.html @@ -3,7 +3,7 @@ overview: A template that represents a single runtime log entry. location: https://istio.io/docs/reference/config/template/logentry.html layout: protoc-gen-docs -number_of_entries: 1 +number_of_entries: 3 ---

The logentry template represents an individual entry within a log.

@@ -50,7 +50,7 @@

Template

variables -map<string, istio.mixer.adapter.model.v1beta1.Value> +map<string, istio.mixer.adapter.model.v1beta1.Value>

Variables that are delivered for each log entry.

@@ -58,7 +58,7 @@

Template

timestamp -istio.mixer.adapter.model.v1beta1.TimeStamp +istio.mixer.adapter.model.v1beta1.TimeStamp

Timestamp is the time value for the log entry

@@ -84,7 +84,7 @@

Template

monitoredResourceDimensions -map<string, istio.mixer.adapter.model.v1beta1.Value> +map<string, istio.mixer.adapter.model.v1beta1.Value>

Optional. A set of expressions that will form the dimensions of the monitored resource this log entry is being recorded on. If the logging backend supports monitored resources, these fields are used to populate that resource. @@ -95,3 +95,14 @@

Template

+

istio.mixer.adapter.model.v1beta1.TimeStamp

+
+

TimeStamp is used inside templates for fields that are of ValueType “TIMESTAMP”

+ +
+

istio.mixer.adapter.model.v1beta1.Value

+
+

Value is used inside templates for fields that have dynamic types. The actual datatype +of the field depends on the datatype of the expression used in the operator configuration.

+ +
diff --git a/_docs/reference/config/template/metric.html b/_docs/reference/config/template/metric.html index 39c856cb7c4a..5caa3ce2b50a 100644 --- a/_docs/reference/config/template/metric.html +++ b/_docs/reference/config/template/metric.html @@ -3,7 +3,7 @@ overview: A template that represents a single runtime metric. location: https://istio.io/docs/reference/config/template/metric.html layout: protoc-gen-docs -number_of_entries: 1 +number_of_entries: 2 ---

The metric template is designed to let you describe runtime metric to dispatch to monitoring backends.

@@ -45,7 +45,7 @@

Template

value -istio.mixer.adapter.model.v1beta1.Value +istio.mixer.adapter.model.v1beta1.Value

The value being reported.

@@ -53,7 +53,7 @@

Template

dimensions -map<string, istio.mixer.adapter.model.v1beta1.Value> +map<string, istio.mixer.adapter.model.v1beta1.Value>

The unique identity of the particular metric to report.

@@ -71,7 +71,7 @@

Template

monitoredResourceDimensions -map<string, istio.mixer.adapter.model.v1beta1.Value> +map<string, istio.mixer.adapter.model.v1beta1.Value>

Optional. A set of expressions that will form the dimensions of the monitored resource this metric is being reported on. If the metric backend supports monitored resources, these fields are used to populate that resource. Otherwise @@ -82,3 +82,9 @@

Template

+

istio.mixer.adapter.model.v1beta1.Value

+
+

Value is used inside templates for fields that have dynamic types. The actual datatype +of the field depends on the datatype of the expression used in the operator configuration.

+ +
diff --git a/_docs/reference/config/template/quota.html b/_docs/reference/config/template/quota.html index 348ff7804ef0..8b22bea7d16c 100644 --- a/_docs/reference/config/template/quota.html +++ b/_docs/reference/config/template/quota.html @@ -3,7 +3,7 @@ overview: A template that represents a quota allocation request location: https://istio.io/docs/reference/config/template/quota.html layout: protoc-gen-docs -number_of_entries: 1 +number_of_entries: 2 ---

The quota template represents an item for which to check quota.

@@ -41,7 +41,7 @@

Template

dimensions -map<string, istio.mixer.adapter.model.v1beta1.Value> +map<string, istio.mixer.adapter.model.v1beta1.Value>

The unique identity of the particular quota to manipulate.

@@ -50,3 +50,9 @@

Template

+

istio.mixer.adapter.model.v1beta1.Value

+
+

Value is used inside templates for fields that have dynamic types. The actual datatype +of the field depends on the datatype of the expression used in the operator configuration.

+ +
diff --git a/_docs/reference/config/template/servicecontrolreport.html b/_docs/reference/config/template/servicecontrolreport.html index 5ba87c21aea0..80e1581783b9 100644 --- a/_docs/reference/config/template/servicecontrolreport.html +++ b/_docs/reference/config/template/servicecontrolreport.html @@ -3,7 +3,7 @@ overview: A template used by the Google Service Control adapter. location: https://istio.io/docs/reference/config/template/servicecontrolreport.html layout: protoc-gen-docs -number_of_entries: 1 +number_of_entries: 3 ---

The servicecontrolreport template is used by the Google Service Control adapter.

@@ -78,7 +78,7 @@

Template

requestTime -istio.mixer.adapter.model.v1beta1.TimeStamp +istio.mixer.adapter.model.v1beta1.TimeStamp @@ -102,7 +102,7 @@

Template

responseTime -istio.mixer.adapter.model.v1beta1.TimeStamp +istio.mixer.adapter.model.v1beta1.TimeStamp @@ -120,10 +120,20 @@

Template

responseLatency -istio.mixer.adapter.model.v1beta1.Duration +istio.mixer.adapter.model.v1beta1.Duration +

istio.mixer.adapter.model.v1beta1.Duration

+
+

Duration is used inside templates for fields that are of ValueType “DURATION”

+ +
+

istio.mixer.adapter.model.v1beta1.TimeStamp

+
+

TimeStamp is used inside templates for fields that are of ValueType “TIMESTAMP”

+ +
diff --git a/scripts/grab_reference_docs.sh b/scripts/grab_reference_docs.sh index 0b213ca36e64..c89ed0fab88a 100755 --- a/scripts/grab_reference_docs.sh +++ b/scripts/grab_reference_docs.sh @@ -21,7 +21,7 @@ git clone https://github.com/istio/api.git git clone https://github.com/istio/istio.git popd -# Given the name of a .pb.html file, exracts the $location marker and then proceeds to +# Given the name of a .pb.html file, extracts the $location marker and then proceeds to # copy the file to that location in the _docs hierarchy. locate_file() { FILENAME=$1 From ab8feed4f9a0368e689cf84d7079eecf1e1a0779 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Wed, 21 Mar 2018 07:09:42 -0700 Subject: [PATCH 043/191] Fix some newly broken links. (#1082) --- _blog/2017/adapter-model.md | 5 ++++- _docs/concepts/policy-and-control/attributes.md | 2 +- _docs/reference/api/istio.mixer.v1.html | 2 +- _docs/reference/config/istio.mixer.v1.config.client.html | 2 +- _docs/reference/config/mixer/expression-language.md | 3 ++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/_blog/2017/adapter-model.md b/_blog/2017/adapter-model.md index c008b22252b5..b87c8f1bb72e 100644 --- a/_blog/2017/adapter-model.md +++ b/_blog/2017/adapter-model.md @@ -67,7 +67,10 @@ by the proxy into individual bundles of data that can be routed to different ada Creating instances generally requires using [attribute expressions]({{home}}/docs/concepts/policy-and-control/mixer-config.html#attribute-expressions). The point of these expressions is to use any attribute or literal value in order to produce a result that can be assigned to an instance’s field. -Every instance field has a type, as defined in the template, every [attribute has a type](https://github.com/istio/api/blob/master/mixer/v1/config/descriptor/value_type.proto), and every attribute expression has a type. You can only assign type-compatible expressions to any given instance fields. For example, you can’t assign an integer expression to a string field. This kind of strong typing is designed to minimize the risk of creating bogus configurations. +Every instance field has a type, as defined in the template, every attribute has a +[type](https://github.com/istio/api/blob/master/policy/v1beta1/value_type.proto), and every attribute expression has a type. +You can only assign type-compatible expressions to any given instance fields. For example, you can’t assign an integer expression +to a string field. This kind of strong typing is designed to minimize the risk of creating bogus configurations. ## Rules: delivering data to adapters diff --git a/_docs/concepts/policy-and-control/attributes.md b/_docs/concepts/policy-and-control/attributes.md index 4b83c94cc4de..b726bd9624ac 100644 --- a/_docs/concepts/policy-and-control/attributes.md +++ b/_docs/concepts/policy-and-control/attributes.md @@ -44,4 +44,4 @@ separator. For example, `request.size` and `source.ip`. ## Attribute types Istio attributes are strongly typed. The supported attribute types are defined by -[ValueType](https://github.com/istio/api/blob/master/mixer/v1/config/descriptor/value_type.proto). +[ValueType](https://github.com/istio/api/blob/master/policy/v1beta1/value_type.proto). diff --git a/_docs/reference/api/istio.mixer.v1.html b/_docs/reference/api/istio.mixer.v1.html index d739951eef45..c347c430fb06 100644 --- a/_docs/reference/api/istio.mixer.v1.html +++ b/_docs/reference/api/istio.mixer.v1.html @@ -71,7 +71,7 @@

Attributes

here.

Attributes are strongly typed. The supported attribute types are defined by -ValueType. +ValueType. Each type of value is encoded into one of the so-called transport types present in this message.

diff --git a/_docs/reference/config/istio.mixer.v1.config.client.html b/_docs/reference/config/istio.mixer.v1.config.client.html index f3b045431fd2..601e336552b8 100644 --- a/_docs/reference/config/istio.mixer.v1.config.client.html +++ b/_docs/reference/config/istio.mixer.v1.config.client.html @@ -1283,7 +1283,7 @@

istio.mixer.v1.Attributes

here.

Attributes are strongly typed. The supported attribute types are defined by -ValueType. +ValueType. Each type of value is encoded into one of the so-called transport types present in this message.

diff --git a/_docs/reference/config/mixer/expression-language.md b/_docs/reference/config/mixer/expression-language.md index 22d9ea006c0d..71fac77c36ec 100644 --- a/_docs/reference/config/mixer/expression-language.md +++ b/_docs/reference/config/mixer/expression-language.md @@ -16,7 +16,8 @@ This page describes how to use the Mixer config expression language (CEXL). ## Background -Mixer configuration uses an expression language (CEXL) to specify match expressions and [mapping expressions]({{mixerConfig}}#attribute-expressions). CEXL expressions map a set of typed [attributes]({{home}}/docs/concepts/policy-and-control/attributes.html) and constants to a typed [value](https://github.com/istio/api/blob/master/mixer/v1/config/descriptor/value_type.proto#L23). +Mixer configuration uses an expression language (CEXL) to specify match expressions and [mapping expressions]({{mixerConfig}}#attribute-expressions). CEXL expressions map a set of typed [attributes]({{home}}/docs/concepts/policy-and-control/attributes.html) and constants to a typed +[value](https://github.com/istio/api/blob/master/policy/v1beta1/value_type.proto). ## Syntax From f4cf4035b3573ba2f1378d7bc5ea76c648d40f71 Mon Sep 17 00:00:00 2001 From: mtail Date: Wed, 21 Mar 2018 09:52:34 -0700 Subject: [PATCH 044/191] Update reference docs. --- .../config/istio.networking.v1alpha3.html | 2767 +++++++++++++++++ .../istio.mixer.adapter.model.v1beta1.html | 2 +- 2 files changed, 2768 insertions(+), 1 deletion(-) create mode 100644 _docs/reference/config/istio.networking.v1alpha3.html diff --git a/_docs/reference/config/istio.networking.v1alpha3.html b/_docs/reference/config/istio.networking.v1alpha3.html new file mode 100644 index 000000000000..4f8491685c6f --- /dev/null +++ b/_docs/reference/config/istio.networking.v1alpha3.html @@ -0,0 +1,2767 @@ +--- +title: Route Rules Alpha 3 +overview: Configuration affecting traffic routing +location: https://istio.io/docs/reference/config/istio.networking.v1alpha3.html +layout: protoc-gen-docs +number_of_entries: 36 +--- +

ConnectionPoolSettings

+
+

Connection pool settings for an upstream host. The settings apply to +each individual host in the upstream service. See Envoy’s circuit +breaker +for more details. Connection pool settings can be applied at the TCP +level as well as at HTTP level.

+ +

For example, the following rule sets a limit of 100 connections to redis +service called myredissrv with a connect timeout of 30ms

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: bookinfo-redis
+spec:
+  name: myredissrv
+  trafficPolicy:
+    connectionPool:
+      tcp:
+        maxConnections: 100
+        connectTimeout: 30ms
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
tcpConnectionPoolSettings.TCPSettings +

Settings common to both HTTP and TCP upstream connections.

+ +
httpConnectionPoolSettings.HTTPSettings +

HTTP connection pool settings.

+ +
+
+

ConnectionPoolSettings.HTTPSettings

+
+

Settings applicable to HTTP1.1/HTTP2/GRPC connections.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
http1MaxPendingRequestsint32 +

Maximum number of pending HTTP requests to a destination. Default 1024.

+ +
http2MaxRequestsint32 +

Maximum number of requests to a backend. Default 1024.

+ +
maxRequestsPerConnectionint32 +

Maximum number of requests per connection to a backend. Setting this +parameter to 1 disables keep alive.

+ +
maxRetriesint32 +

Maximum number of retries that can be outstanding to all hosts in a +cluster at a given time. Defaults to 3.

+ +
+
+

ConnectionPoolSettings.TCPSettings

+
+

Settings common to both HTTP and TCP upstream connections.

+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
maxConnectionsint32 +

Maximum number of HTTP1 /TCP connections to a destination host.

+ +
connectTimeoutgoogle.protobuf.Duration +

TCP connection timeout.

+ +
+
+

CorsPolicy

+
+

Describes the Cross-Origin Resource Sharing (CORS) policy, for a given +service. Refer to +https://developer.mozilla.org/en-US/docs/Web/HTTP/AccesscontrolCORS +for further details about cross origin resource sharing. For example, +the following rule restricts cross origin requests to those originating +from example.com domain using HTTP POST/GET, and sets the +Access-Control-Allow-Credentials header to false. In addition, it only +exposes X-Foo-bar header and sets an expiry period of 1 day.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings-route
+spec:
+  hosts:
+  - ratings
+  http:
+  - route:
+    - destination:
+        name: ratings
+        subset: v1
+    corsPolicy:
+      allowOrigin:
+      - example.com
+      allowMethods:
+      - POST
+      - GET
+      allowCredentials: false
+      allowHeaders:
+      - X-Foo-Bar
+      maxAge: "1d"
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
allowOriginstring[] +

The list of origins that are allowed to perform CORS requests. The +content will be serialized into the Access-Control-Allow-Origin +header. Wildcard * will allow all origins.

+ +
allowMethodsstring[] +

List of HTTP methods allowed to access the resource. The content will +be serialized into the Access-Control-Allow-Methods header.

+ +
allowHeadersstring[] +

List of HTTP headers that can be used when requesting the +resource. Serialized to Access-Control-Allow-Methods header.

+ +
exposeHeadersstring[] +

A white list of HTTP headers that the browsers are allowed to +access. Serialized into Access-Control-Expose-Headers header.

+ +
maxAgegoogle.protobuf.Duration +

Specifies how long the the results of a preflight request can be +cached. Translates to the Access-Control-Max-Age header.

+ +
allowCredentialsgoogle.protobuf.BoolValue +

Indicates whether the caller is allowed to send the actual request +(not the preflight) using credentials. Translates to +Access-Control-Allow-Credentials header.

+ +
+
+

Destination

+
+

Destination indicates the network addressable service to which the +request/connection will be sent after processing a routing rule. The +destination.name should unambiguously refer to a service in the service +registry. It can be a short name or a fully qualified domain name from +the service registry, a resolvable DNS name, an IP address or a service +name from the service registry and a subset name. The order of inference +is as follows:

+ +
    +
  1. Service registry lookup. The entire name is looked up in the service +registry. If the lookup succeeds, the search terminates. The requests +will be routed to any instance of the service in the mesh. When the +service name consists of a single word, the FQDN will be constructed in +a platform specific manner. For example, in Kubernetes, the namespace +associated with the routing rule will be used to identify the service as +.. However, if the service name contains +multiple words separated by a dot (e.g., reviews.prod), the name in its +entirety would be looked up in the service registry.

  2. + +
  3. Runtime DNS lookup by the proxy. If step 1 fails, and the name is not +an IP address, it will be considered as a DNS name that is not in the +service registry (e.g., wikipedia.org). The sidecar/gateway will resolve +the DNS and load balance requests appropriately. See Envoy’s strict_dns +for details.

  4. +
+ +

The following example routes all traffic by default to pods of the +reviews service with label “version: v1” (i.e., subset v1), and some +to subset v2, in a kubernetes environment.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews-route
+spec:
+  hosts:
+  - reviews # namespace is same as the client/caller's namespace
+  http:
+  - match:
+    - uri:
+        prefix: "/wpcatalog"
+    - uri:
+        prefix: "/consumercatalog"
+    rewrite:
+      uri: "/newcatalog"
+    route:
+    - destination:
+        name: reviews
+        subset: v2
+  - route:
+    - destination:
+        name: reviews
+        subset: v1
+
+ +

And the associated DestinationRule

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: reviews-destination
+spec:
+  name: reviews
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+
+ +

The following VirtualService sets a timeout of 5s for all calls to +productpage.prod service. Notice that there are no subsets defined in +this rule. Istio will fetch all instances of productpage.prod service +from the service registry and populate the sidecar’s load balancing +pool.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: my-productpage-rule
+spec:
+  hosts:
+  - productpage.prod # in kubernetes, this applies only to prod namespace
+  http:
+  - timeout: 5s
+    route:
+    - destination:
+        name: productpage.prod
+
+ +

The following sets a timeout of 5s for all calls to the external +service wikipedia.org, as there is no internal service of that name.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: my-wiki-rule
+spec:
+  hosts:
+  - wikipedia.org
+  http:
+  - timeout: 5s
+    route:
+    - destination:
+        name: wikipedia.org
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
namestring +

REQUIRED. The name can be a short name or a fully qualified domain +name from the service registry, a resolvable DNS name, or an IP +address.

+ +

If short names are used, the FQDN of the service will be resolved in a +platform specific manner. For example in Kubernetes, when a route with a +short name “reviews” in the destination in namespace “bookinfo” is applied, +the final destination is resolved to reviews.bookinfo.svc.cluster.local. The +sidecar will route to the IP +addresses of the pods constituting the service. However, if the lookup +fails, “reviews” is treated as an external service, such that the sidecar +will dynamically resolve the DNS of the service name and route the request +to the IP addresses returned by the DNS.

+ +
subsetstring +

The name of a subset within the service. Applicable only to services +within the mesh. The subset must be defined in a corresponding +DestinationRule.

+ +
portPortSelector +

Specifies the port on the destination. Many services only expose a +single port or label ports with the protocols they support, in these +cases it is not required to explicitly select the port. Note that +selection priority is to first match by name and then match by number.

+ +

Names must comply with DNS label syntax (rfc1035) and therefore cannot +collide with numbers. If there are multiple ports on a service with +the same protocol the names should be of the form -.

+ +
+
+

DestinationRule

+
+

DestinationRule defines policies that apply to traffic intended for a +service after routing has occurred. These rules specify configuration +for load balancing, connection pool size from the sidecar, and outlier +detection settings to detect and evict unhealthy hosts from the load +balancing pool. For example, a simple load balancing policy for the +ratings service would look as follows:

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: bookinfo-ratings
+spec:
+  name: ratings
+  trafficPolicy:
+    loadBalancer:
+      simple: LEAST_CONN
+
+ +

Version specific policies can be specified by defining a named +subset and overriding the settings specified at the service level. The +following rule uses a round robin load balancing policy for all traffic +going to a subset named testversion that is composed of endpoints (e.g., +pods) with labels (version:v3).

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: bookinfo-ratings
+spec:
+  name: ratings
+  trafficPolicy:
+    loadBalancer:
+      simple: LEAST_CONN
+  subsets:
+  - name: testversion
+    labels:
+      version: v3
+    trafficPolicy:
+      loadBalancer:
+        simple: ROUND_ROBIN
+
+ +

Note that policies specified for subsets will not take effect until +a route rule explicitly sends traffic to this subset.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
namestring +

REQUIRED. The destination address for traffic captured by this +rule. Could be a DNS name with wildcard prefix or a CIDR +prefix. Depending on the platform, short-names can also be used +instead of a FQDN (i.e. has no dots in the name). In such a scenario, +the FQDN of the host would be derived based on the underlying +platform.

+ +

For example on Kubernetes, when hosts contains a short name, Istio will +interpret the short name based on the namespace of the rule. Thus, when a +client applies a rule in the “default” namespace, containing a name +“reviews”, Istio will setup routes to the +“reviews.default.svc.cluster.local” service. However, if a different name +such as “reviews.sales” is used, it would be treated as a FQDN during +virtual host matching. In Consul, a plain service name would be resolved to +the FQDN “reviews.service.consul”.

+ +

Note that the hosts field applies to both HTTP and TCP +services. Service inside the mesh, i.e. those found in the service +registry, must always be referred to using their alphanumeric +names. IP addresses or CIDR prefixes are allowed only for services +defined via the Gateway.

+ +
trafficPolicyTrafficPolicy +

Traffic policies to apply (load balancing policy, connection pool +sizes, outlier detection).

+ +
subsetsSubset[] +

One or more named sets that represent individual versions of a +service. Traffic policies can be overridden at subset level.

+ +
+
+

DestinationWeight

+
+

Each routing rule is associated with one or more service versions (see +glossary in beginning of document). Weights associated with the version +determine the proportion of traffic it receives. For example, the +following rule will route 25% of traffic for the “reviews” service to +instances with the “v2” tag and the remaining traffic (i.e., 75%) to +“v1”.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews-route
+spec:
+  hosts:
+  - reviews
+  http:
+  - route:
+    - destination:
+        name: reviews
+        subset: v2
+      weight: 25
+    - destination:
+        name: reviews
+        subset: v1
+      weight: 75
+
+ +

And the associated DestinationRule

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: reviews-destination
+spec:
+  name: reviews
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
destinationDestination +

REQUIRED. Destination uniquely identifies the instances of a service +to which the request/connection should be forwarded to.

+ +
weightint32 +

REQUIRED. The proportion of traffic to be forwarded to the service +version. (0-100). Sum of weights across destinations SHOULD BE == 100. +If there is only destination in a rule, the weight value is assumed to +be 100.

+ +
+
+

ExternalService

+
+

External service describes the endpoints, ports and protocols of a +white-listed set of mesh-external domains and IP blocks that services in +the mesh are allowed to access.

+ +

For example, the following external service configuration describes the +set of services at https://example.com to be accessed internally over +plaintext http (i.e. http://example.com:443), with the sidecar originating +TLS.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: ExternalService
+metadata:
+  name: external-svc-example
+spec:
+  hosts:
+  - example.com
+  ports:
+  - number: 443
+    name: example-http
+    protocol: http # not HTTPS.
+  discovery: DNS
+
+ +

and a destination rule to initiate TLS connections to the external service.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: tls-example
+spec:
+  name: example.com
+  trafficPolicy:
+    tls:
+      mode: SIMPLE # initiates HTTPS when talking to example.com
+
+ +

The following specification specifies a static set of backend nodes for +a MongoDB cluster behind a set of virtual IPs, and sets up a destination +rule to initiate mTLS connections upstream.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: ExternalService
+metadata:
+  name: external-svc-mongocluster
+spec:
+  hosts:
+  - 192.192.192.192/24
+  ports:
+  - number: 27018
+    name: mongodb
+    protocol: mongo
+  discovery: STATIC
+  endpoints:
+  - address: 2.2.2.2
+  - address: 3.3.3.3
+
+ +

and the associated destination rule

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: mtls-mongocluster
+spec:
+  name: 192.192.192.192/24
+  trafficPolicy:
+    tls:
+      mode: MUTUAL
+      clientCertificate: /etc/certs/myclientcert.pem
+      privateKey: /etc/certs/client_private_key.pem
+      caCertificates: /etc/certs/rootcacerts.pem
+
+ +

The following example demonstrates the use of wildcards in the hosts. If +the connection has to be routed to the IP address requested by the +application (i.e. application resolves DNS and attempts to connect to a +specific IP), the discovery mode must be set to “none”.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: ExternalService
+metadata:
+  name: external-svc-wildcard-example
+spec:
+  hosts:
+  - "*.bar.com"
+  ports:
+  - number: 80
+    name: http
+    protocol: http
+  discovery: NONE
+
+ +

For HTTP based services, it is possible to create a virtual service +backed by multiple DNS addressible endpoints. In such a scenario, the +application can use the HTTP_PROXY environment variable to transparently +reroute API calls for the virtual service to a chosen backend. For +example, the following configuration creates a non-existent service +called foo.bar.com backed by three domains: us.foo.bar.com:8443, +uk.foo.bar.com:9443, and in.foo.bar.com:7443

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: ExternalService
+metadata:
+  name: external-svc-dns
+spec:
+  hosts:
+  - foo.bar.com
+  ports:
+  - number: 443
+    name: https
+    protocol: http
+  discovery: DNS
+  endpoints:
+  - address: us.foo.bar.com
+    ports:
+      https: 8443
+  - address: uk.foo.bar.com
+    ports:
+      https: 9443
+  - address: in.foo.bar.com
+    ports:
+      https: 7443
+
+ +

and a destination rule to initiate TLS connections to the external service.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: tls-foobar
+spec:
+  name: foo.bar.com
+  trafficPolicy:
+    tls:
+      mode: SIMPLE # initiates HTTPS
+
+ +

With HTTP_PROXY=http://localhost:443, calls from the application to +http://foo.bar.com will be upgraded to HTTPS and load balanced across +the three domains specified above. In other words, a call to +http://foo.bar.com/baz would be translated to +https://uk.foo.bar.com/baz.

+ +

NOTE: In the scenario above, the value of the HTTP Authority/host header +associated with the outbound HTTP requests will be based on the +endpoint’s DNS name, i.e. “:authority: uk.foo.bar.com”. Refer to Envoy’s +autohostrewrite for further details. The automatic rewrite can be +overridden using a host rewrite route rule.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
hostsstring[] +

REQUIRED. The hosts associated with the external service. Could be a +DNS name with wildcard prefix or a CIDR prefix. Note that the hosts +field applies to all protocols. DNS names in hosts will be ignored if +the application accesses the service over non-HTTP protocols such as +mongo/opaque TCP/even HTTPS. In such scenarios, the port on which the +external service is being accessed must not be shared by any other +service in the mesh. In other words, the sidecar will behave as a +simple TCP proxy, forwarding incoming traffic on a specified port to +the specified destination endpoint IP/host.

+ +
portsPort[] +

REQUIRED. The ports associated with the external service.

+ +
discoveryExternalService.Discovery +

Service discovery mode for the hosts. If not set, Istio will attempt +to infer the discovery mode based on the value of hosts and endpoints.

+ +
endpointsExternalService.Endpoint[] +

One or more endpoints associated with the service. Endpoints must be +accessible over the set of outPorts defined at the service level.

+ +
+
+

ExternalService.Discovery

+
+

Different ways of discovering the IP addresses associated with the +service.

+ + + + + + + + + + + + + + + + + + + + + + +
NameDescription
NONE +

If set to “none”, the proxy will assume that incoming connections +have already been resolved (to a specific destination IP +address). Such connections are typically routed via the proxy using +mechanisms such as IP table REDIRECT/ eBPF. After performing any +routing related transformations, the proxy will forward the +connection to the IP address to which the connection was bound.

+ +
STATIC +

If set to “static”, the proxy will use the IP addresses specified in +endpoints (See below) as the backing nodes associated with the +external service.

+ +
DNS +

If set to “dns”, the proxy will attempt to resolve the DNS address +during request processing. If no endpoints are specified, the proxy +will resolve the DNS address specified in the hosts field, if +wildcards are not used. If endpoints are specified, the DNS +addresses specified in the endpoints will be resolved to determine +the destination IP address.

+ +
+
+

ExternalService.Endpoint

+
+

Endpoint defines a network address (IP or hostname) associated with +the external service.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
addressstring +

REQUIRED: Address associated with the network endpoint without the +port ( IP or fully qualified domain name without wildcards).

+ +
portsmap<string, uint32> +

Set of ports associated with the endpoint. The ports must be +associated with a port name that was declared as part of the +service.

+ +
labelsmap<string, string> +

One or more labels associated with the endpoint.

+ +
+
+

Gateway

+
+

Gateway describes a load balancer operating at the edge of the mesh +receiving incoming or outgoing HTTP/TCP connections. The specification +describes a set of ports that should be exposed, the type of protocol to +use, SNI configuration for the load balancer, etc.

+ +

For example, the following gateway spec sets up a proxy to act as a load +balancer exposing port 80 and 9080 (http), 443 (https), and port 2379 +(TCP) for ingress. The gateway will be applied to the proxy running on +a pod with labels “app: my-gateway-controller”. While Istio will configure the +proxy to listen on these ports, it is the responsibility of the user to +ensure that external traffic to these ports are allowed into the mesh.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: my-gateway
+spec:
+  selector:
+    app: my-gatweway-controller
+  servers:
+  - port:
+      number: 80
+      name: http
+    hosts:
+    - uk.bookinfo.com
+    - eu.bookinfo.com
+    tls:
+      httpsRedirect: true # sends 302 redirect for http requests
+  - port:
+      number: 443
+      name: https
+    hosts:
+    - uk.bookinfo.com
+    - eu.bookinfo.com
+    tls:
+      mode: simple #enables HTTPS on this port
+      serverCertificate: /etc/certs/servercert.pem
+      privateKey: /etc/certs/privatekey.pem
+  - port:
+      number: 9080
+      name: http-wildcard
+    # no hosts implies wildcard match
+  - port:
+      number: 2379 #to expose internal service via external port 2379
+      name: Mongo
+      protocol: MONGO
+
+ +

The gateway specification above describes the L4-L6 properties of a load +balancer. A VirtualService can then be bound to a gateway to control +the forwarding of traffic arriving at a particular host or gateway port.

+ +

For example, the following VirtualService splits traffic for +https://uk.bookinfo.com/reviews, https://eu.bookinfo.com/reviews, +http://uk.bookinfo.com:9080/reviews, http://eu.bookinfo.com:9080/reviews +into two versions (prod and qa) of an internal reviews service on port +9080. In addition, requests containing the cookie user: dev-123 will be +sent to special port 7777 in the qa version. The same rule is also +applicable inside the mesh for requests to the reviews.prod +service. This rule is applicable across ports 443, 9080. Note that +http://uk.bookinfo.com gets redirected to https://uk.bookinfo.com +(i.e. 80 redirects to 443).

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: bookinfo-rule
+spec:
+  hosts:
+  - reviews.prod
+  - uk.bookinfo.com
+  - eu.bookinfo.com
+  gateways:
+  - my-gateway
+  - mesh # applies to all the sidecars in the mesh
+  http:
+  - match:
+    - headers:
+        cookie:
+          user: dev-123
+    route:
+    - destination:
+        port:
+          number: 7777
+        name: reviews.qa
+  - match:
+      uri:
+        prefix: /reviews/
+    route:
+    - destination:
+        port:
+          number: 9080 # can be omitted if its the only port for reviews
+        name: reviews.prod
+      weight: 80
+    - destination:
+        name: reviews.qa
+      weight: 20
+
+ +

The following VirtualService forwards traffic arriving at (external) port +2379 from 172.17.16.0/24 subnet to internal Mongo server on port 5555. This +rule is not applicable internally in the mesh as the gateway list omits +the reserved name “mesh”.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: bookinfo-Mongo
+spec:
+  hosts:
+  - Mongosvr #name of Mongo service
+  gateways:
+  - my-gateway
+  tcp:
+  - match:
+    - port:
+        number: 2379
+      sourceSubnet: "172.17.16.0/24"
+    route:
+    - destination:
+        name: mongo.prod
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
serversServer[] +

REQUIRED: A list of server specifications.

+ +
selectormap<string, string> +

One or more labels that indicate a specific set of pods/VMs +on which this gateway configuration should be applied. +If no selectors are provided, the gateway will be implemented by +the default istio-ingress controller.

+ +
+
+

HTTPFaultInjection.Abort

+
+

Abort specification is used to prematurely abort a request with a +pre-specified error code. The following example will return an HTTP +400 error code for 10% of the requests to the “ratings” service “v1”.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings-route
+spec:
+  hosts:
+  - ratings
+  http:
+  - route:
+    - destination:
+        name: ratings
+        subset: v1
+    fault:
+      abort:
+        percent: 10
+        httpStatus: 400
+
+ +

The httpStatus field is used to indicate the HTTP status code to +return to the caller. The optional percent field, a value between 0 +and 100, is used to only abort a certain percentage of requests. If +not specified, all requests are aborted.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
percentint32 +

Percentage of requests to be aborted with the error code provided (0-100).

+ +
httpStatusint32 (oneof) +

REQUIRED. HTTP status code to use to abort the Http request.

+ +
grpcStatusstring (oneof) +

(– NOT IMPLEMENTED –)

+ +
http2Errorstring (oneof) +

(– NOT IMPLEMENTED –)

+ +
+
+

HTTPFaultInjection.Delay

+
+

Delay specification is used to inject latency into the request +forwarding path. The following example will introduce a 5 second delay +in 10% of the requests to the “v1” version of the “reviews” +service from all pods with label env: prod

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews-route
+spec:
+  hosts:
+  - reviews
+  http:
+  - match:
+    - sourceLabels:
+        env: prod
+    route:
+    - destination:
+        name: reviews
+        subset: v1
+    fault:
+      delay:
+        percent: 10
+        fixedDelay: 5s
+
+ +

The fixedDelay field is used to indicate the amount of delay in +seconds. An optional percent field, a value between 0 and 100, can +be used to only delay a certain percentage of requests. If left +unspecified, all request will be delayed.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
percentint32 +

Percentage of requests on which the delay will be injected (0-100).

+ +
fixedDelaygoogle.protobuf.Duration (oneof) +

REQUIRED. Add a fixed delay before forwarding the request. Format: +1h/1m/1s/1ms. MUST be >=1ms.

+ +
exponentialDelaygoogle.protobuf.Duration (oneof) +

(– Add a delay (based on an exponential function) before forwarding +the request. mean delay needed to derive the exponential delay +values –)

+ +
+
+

HTTPMatchRequest

+
+

HttpMatchRequest specifies a set of criterion to be met in order for the +rule to be applied to the HTTP request. For example, the following +restricts the rule to match only requests where the URL path +starts with /ratings/v2/ and the request contains a “cookie” with value +“user=jason”.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings-route
+spec:
+  hosts:
+  - ratings
+  http:
+  - match:
+    - headers:
+        cookie:
+          regex: "^(.*?;)?(user=jason)(;.*)?"
+        uri:
+          prefix: "/ratings/v2/"
+    route: 
+    - destination:
+        name: ratings
+
+ +

HTTPMatchRequest CANNOT be empty.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
uriStringMatch +

URI to match +values are case-sensitive and formatted as follows:

+ +

exact: “value” or just “value” for exact string match

+ +

prefix: “value” for prefix-based match

+ +

regex: “value” for ECMAscript style regex-based match

+ +
schemeStringMatch +

URI Scheme +values are case-sensitive and formatted as follows:

+ +

exact: “value” or just “value” for exact string match

+ +

prefix: “value” for prefix-based match

+ +

regex: “value” for ECMAscript style regex-based match

+ +
methodStringMatch +

HTTP Method +values are case-sensitive and formatted as follows:

+ +

exact: “value” or just “value” for exact string match

+ +

prefix: “value” for prefix-based match

+ +

regex: “value” for ECMAscript style regex-based match

+ +
authorityStringMatch +

HTTP Authority +values are case-sensitive and formatted as follows:

+ +

exact: “value” or just “value” for exact string match

+ +

prefix: “value” for prefix-based match

+ +

regex: “value” for ECMAscript style regex-based match

+ +
headersmap<string, StringMatch> +

The header keys must be lowercase and use hyphen as the separator, +e.g. x-request-id.

+ +

Header values are case-sensitive and formatted as follows:

+ +

exact: “value” or just “value” for exact string match

+ +

prefix: “value” for prefix-based match

+ +

regex: “value” for ECMAscript style regex-based match

+ +

Note: The keys uri, scheme, method, and authority will be ignored.

+ +
portPortSelector +

Specifies the ports on the host that is being addressed. Many services +only expose a single port or label ports with the protocols they support, +in these cases it is not required to explicitly select the port. Note that +selection priority is to first match by name and then match by number.

+ +

Names must comply with DNS label syntax (rfc1035) and therefore cannot +collide with numbers. If there are multiple ports on a service with the +same protocol the names should be of the form -.

+ +
sourceLabelsmap<string, string> +

One or more labels that constrain the applicability of a rule to +workloads with the given labels. If the VirtualService has a list of +gateways specified at the top, it should include the reserved gateway +“mesh” in order for this field to be applicable.

+ +
gatewaysstring[] +

Names of gateways where the rule should be applied to. Gateway names +at the top of the VirtualService (if any) are overridden. The gateway match is +independent of sourceLabels.

+ +
+
+

HTTPRedirect

+
+

HTTPRedirect can be used to send a 302 redirect response to the caller, +where the Authority/Host and the URI in the response can be swapped with +the specified values. For example, the following rule redirects +requests for /v1/getProductRatings API on the ratings service to +/v1/bookRatings provided by the bookratings service.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings-route
+spec:
+  hosts:
+  - ratings
+  http:
+  - match:
+    - uri:
+        exact: /v1/getProductRatings
+  redirect:
+    uri: /v1/bookRatings
+    authority: bookratings.default.svc.cluster.local
+  ...
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
uristring +

On a redirect, overwrite the Path portion of the URL with this +value. Note that the entire path will be replaced, irrespective of the +request URI being matched as an exact path or prefix.

+ +
authoritystring +

On a redirect, overwrite the Authority/Host portion of the URL with +this value.

+ +
+
+

HTTPRetry

+
+

Describes the retry policy to use when a HTTP request fails. For +example, the following rule sets the maximum number of retries to 3 when +calling ratings:v1 service, with a 2s timeout per retry attempt.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings-route
+spec:
+  hosts:
+  - ratings
+  http:
+  - route:
+    - destination:
+        name: ratings
+        subset: v1
+    retries:
+      attempts: 3
+      perTryTimeout: 2s
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
attemptsint32 +

REQUIRED. Number of retries for a given request. The interval +between retries will be determined automatically (25ms+). Actual +number of retries attempted depends on the httpReqTimeout.

+ +
perTryTimeoutgoogle.protobuf.Duration +

Timeout per retry attempt for a given request. format: 1h/1m/1s/1ms. MUST BE >=1ms.

+ +
+
+

HTTPRewrite

+
+

HTTPRewrite can be used to rewrite specific parts of a HTTP request +before forwarding the request to the destination. Rewrite primitive can +be used only with the DestinationWeights. The following example +demonstrates how to rewrite the URL prefix for api call (/ratings) to +ratings service before making the actual API call.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings-route
+spec:
+  hosts:
+  - ratings
+  http:
+  - match:
+    - uri:
+        prefix: /ratings
+    rewrite:
+      uri: /v1/bookRatings
+    route:
+    - destination:
+        name: ratings
+        subset: v1
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
uristring +

rewrite the path (or the prefix) portion of the URI with this +value. If the original URI was matched based on prefix, the value +provided in this field will replace the corresponding matched prefix.

+ +
authoritystring +

rewrite the Authority/Host header with this value.

+ +
+
+

HTTPRoute

+
+

Describes match conditions and actions for routing HTTP/1.1, HTTP2, and +gRPC traffic. See VirtualService for usage examples.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
matchHTTPMatchRequest[] +

Match conditions to be satisfied for the rule to be +activated. All conditions inside a single match block have AND +semantics, while the list of match blocks have OR semantics. The rule +is matched if any one of the match blocks succeed.

+ +
routeDestinationWeight[] +

A http rule can either redirect or forward (default) traffic. The +forwarding target can be one of several versions of a service (see +glossary in beginning of document). Weights associated with the +service version determine the proportion of traffic it receives.

+ +
redirectHTTPRedirect +

A http rule can either redirect or forward (default) traffic. If +traffic passthrough option is specified in the rule, +route/redirect will be ignored. The redirect primitive can be used to +send a HTTP 302 redirect to a different URI or Authority.

+ +
rewriteHTTPRewrite +

Rewrite HTTP URIs and Authority headers. Rewrite cannot be used with +Redirect primitive. Rewrite will be performed before forwarding.

+ +
websocketUpgradebool +

Indicates that a HTTP/1.1 client connection to this particular route +should be allowed (and expected) to upgrade to a WebSocket connection. +The default is false. Istio’s reference sidecar implementation (Envoy) +expects the first request to this route to contain the WebSocket +upgrade headers. Otherwise, the request will be rejected. Note that +Websocket allows secondary protocol negotiation which may then be +subject to further routing rules based on the protocol selected.

+ +
timeoutgoogle.protobuf.Duration +

Timeout for HTTP requests.

+ +
retriesHTTPRetry +

Retry policy for HTTP requests.

+ +
mirrorDestination +

Mirror HTTP traffic to a another destination in addition to forwarding +the requests to the intended destination. Mirrored traffic is on a +best effort basis where the sidecar/gateway will not wait for the +mirrored cluster to respond before returning the response from the +original destination. Statistics will be generated for the mirrored +destination.

+ +
corsPolicyCorsPolicy +

Cross-Origin Resource Sharing policy (CORS). Refer to +https://developer.mozilla.org/en-US/docs/Web/HTTP/AccesscontrolCORS +for further details about cross origin resource sharing.

+ +
appendHeadersmap<string, string> +

Additional HTTP headers to add before forwarding a request to the +destination service.

+ +
+
+

L4MatchAttributes

+
+

L4 connection match attributes. Note that L4 connection matching support +is incomplete.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
destinationSubnetstring +

IPv4 or IPv6 ip address of destination with optional subnet. E.g., +a.b.c.d/xx form or just a.b.c.d. This is only valid when the +destination service has several IPs and the application explicitly +specifies a particular IP.

+ +
portPortSelector +

Specifies the port on the host that is being addressed. Many services +only expose a single port or label ports with the protocols they support, +in these cases it is not required to explicitly select the port. Note that +selection priority is to first match by name and then match by number.

+ +

Names must comply with DNS label syntax (rfc1035) and therefore cannot +collide with numbers. If there are multiple ports on a service with the +same protocol the names should be of the form -.

+ +
sourceSubnetstring +

IPv4 or IPv6 ip address of source with optional subnet. E.g., a.b.c.d/xx +form or just a.b.c.d

+ +
sourceLabelsmap<string, string> +

One or more labels that constrain the applicability of a rule to +workloads with the given labels. If the VirtualService has a list of +gateways specified at the top, it should include the reserved gateway +“mesh” in order for this field to be applicable.

+ +
gatewaysstring[] +

Names of gateways where the rule should be applied to. Gateway names +at the top of the VirtualService (if any) are overridden. The gateway match is +independent of sourceLabels.

+ +
+
+

LoadBalancerSettings

+
+

Load balancing policies to apply for a specific destination. See Envoy’s +load balancing +documentation +for more details.

+ +

For example, the following rule uses a round robin load balancing policy +for all traffic going to the ratings service.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: bookinfo-ratings
+spec:
+  name: ratings
+  trafficPolicy:
+    loadBalancer:
+      simple: ROUND_ROBIN
+
+ +

The following example uses the consistent hashing based load balancer +for the same ratings service using the Cookie header as the hash key.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: bookinfo-ratings
+spec:
+  name: ratings
+  trafficPolicy:
+    loadBalancer:
+      consistentHash:
+        http_header: Cookie
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
simpleLoadBalancerSettings.SimpleLB (oneof) +
consistentHashLoadBalancerSettings.ConsistentHashLB (oneof) +
+
+

LoadBalancerSettings.ConsistentHashLB

+
+

Consistent hashing (ketama hash) based load balancer for even load +distribution/redistribution when the connection pool changes. This +load balancing policy is applicable only for HTTP-based +connections. A user specified HTTP header is used as the key with +xxHash hashing.

+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
httpHeaderstring +

REQUIRED. The name of the HTTP request header that will be used to +obtain the hash key. If the request header is not present, the load +balancer will use a random number as the hash, effectively making +the load balancing policy random.

+ +
minimumRingSizeuint32 +

The minimum number of virtual nodes to use for the hash +ring. Defaults to 1024. Larger ring sizes result in more granular +load distributions. If the number of hosts in the load balancing +pool is larger than the ring size, each host will be assigned a +single virtual node.

+ +
+
+

LoadBalancerSettings.SimpleLB

+
+

Standard load balancing algorithms that require no tuning.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
ROUND_ROBIN +

Round Robin policy. Default

+ +
LEAST_CONN +

The least request load balancer uses an O(1) algorithm which selects +two random healthy hosts and picks the host which has fewer active +requests.

+ +
RANDOM +

The random load balancer selects a random healthy host. The random +load balancer generally performs better than round robin if no health +checking policy is configured.

+ +
PASSTHROUGH +

This option will forward the connection to the original IP address +requested by the caller without doing any form of load +balancing. This option must be used with care. It is meant for +advanced use cases. Refer to Original Destination load balancer in +Envoy for further details.

+ +
+
+

OutlierDetection

+
+

A Circuit breaker implementation that tracks the status of each +individual host in the upstream service. While currently applicable to +only HTTP services, future versions will support opaque TCP services as +well. For HTTP services, hosts that continually return errors for API +calls are ejected from the pool for a pre-defined period of time. See +Envoy’s outlier +detection +for more details.

+ +

The following rule sets a connection pool size of 100 connections and +1000 concurrent HTTP2 requests, with no more than 10 req/connection to +“reviews” service. In addition, it configures upstream hosts to be +scanned every 5 mins, such that any host that fails 7 consecutive times +with 5XX error code will be ejected for 15 minutes.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: reviews-cb-policy
+spec:
+  name: reviews
+  trafficPolicy:
+    connectionPool:
+      tcp:
+        maxConnections: 100
+      http:
+        http2MaxRequests: 1000
+        maxRequestsPerConnection: 10
+    outlierDetection:
+      http:
+        consecutiveErrors: 7
+        interval: 5m
+        baseEjectionTime: 15m
+
+ + + + + + + + + + + + + + + + +
FieldTypeDescription
httpOutlierDetection.HTTPSettings +

Settings for HTTP1.1/HTTP2/GRPC connections.

+ +
+
+

OutlierDetection.HTTPSettings

+
+

Outlier detection settings for HTTP1.1/HTTP2/GRPC connections.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
consecutiveErrorsint32 +

Number of 5XX errors before a host is ejected from the connection +pool. Defaults to 5.

+ +
intervalgoogle.protobuf.Duration +

Time interval between ejection sweep analysis. format: +1h/1m/1s/1ms. MUST BE >=1ms. Default is 10s.

+ +
baseEjectionTimegoogle.protobuf.Duration +

Minimum ejection duration. A host will remain ejected for a period +equal to the product of minimum ejection duration and the number of +times the host has been ejected. This technique allows the system to +automatically increase the ejection period for unhealthy upstream +servers. format: 1h/1m/1s/1ms. MUST BE >=1ms. Default is 30s.

+ +
maxEjectionPercentint32 +

Maximum % of hosts in the load balancing pool for the upstream +service that can be ejected. Defaults to 10%.

+ +
+
+

Port

+
+

Port describes the properties of a specific port of a service.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
numberuint32 +

REQUIRED: A valid non-negative integer port number.

+ +
protocolstring +

The protocol exposed on the port. +MUST BE one of HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP.

+ +
namestring +

Label assigned to the port.

+ +
+
+

PortSelector

+
+

PortSelector specifies the name or number of a port to be used for +matching or selection for final routing.

+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
numberuint32 (oneof) +

Valid port number

+ +
namestring (oneof) +

Port name

+ +
+
+

Server

+
+

Server describes the properties of the proxy on a given load balancer port. +For example,

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: my-ingress
+spec:
+  selector:
+    app: my-ingress-controller
+  servers:
+  - port:
+      number: 80
+      protocol: HTTP2
+
+ +

Another example

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: my-tcp-ingress
+spec:
+  selector:
+    app: my-tcp-ingress-controller
+  servers:
+  - port:
+      number: 27018
+      protocol: MONGO
+
+ +

The following is an example of TLS configuration for port 443

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: my-tls-ingress
+spec:
+  selector:
+    app: my-tls-ingress-controller
+  servers:
+  - port:
+      number: 443
+      protocol: HTTP
+    tls:
+      mode: simple
+      serverCertificate: /etc/certs/server.pem
+      privateKey: /etc/certs/privatekey.pem
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
portPort +

REQUIRED: The Port on which the proxy should listen for incoming +connections

+ +
hostsstring[] +

A list of hosts exposed by this gateway. While +typically applicable to HTTP services, it can also be used for TCP +services using TLS with SNI. Standard DNS wildcard prefix syntax +is permitted.

+ +

A VirtualService that is bound to a gateway must having a matching host +in its default destination. Specifically one of the VirtualService +destination hosts is a strict suffix of a gateway host or +a gateway host is a suffix of one of the VirtualService hosts.

+ +
tlsServer.TLSOptions +

Set of TLS related options that govern the server’s behavior. Use +these options to control if all http requests should be redirected to +https, and the TLS modes to use.

+ +
+
+

Server.TLSOptions

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
httpsRedirectbool +

If set to true, the load balancer will send a 302 redirect for all +http connections, asking the clients to use HTTPS.

+ +
modeServer.TLSOptions.TLSmode +

Optional: Indicates whether connections to this port should be +secured using TLS. The value of this field determines how TLS is +enforced.

+ +
serverCertificatestring +

REQUIRED if mode is “simple” or “mutual”. The path to the file +holding the server-side TLS certificate to use.

+ +
privateKeystring +

REQUIRED if mode is “simple” or “mutual”. The path to the file +holding the server’s private key.

+ +
caCertificatesstring +

REQUIRED if mode is “mutual”. The path to a file containing +certificate authority certificates to use in verifying a presented +client side certificate.

+ +
subjectAltNamesstring[] +

A list of alternate names to verify the subject identity in the +certificate presented by the client.

+ +
+
+

Server.TLSOptions.TLSmode

+
+

TLS modes enforced by the proxy

+ + + + + + + + + + + + + + + + + + + + + + +
NameDescription
PASSTHROUGH +

If set to “passthrough”, the proxy will forward the connection +to the upstream server selected based on the SNI string presented +by the client.

+ +
SIMPLE +

If set to “simple”, the proxy will secure connections with +standard TLS semantics.

+ +
MUTUAL +

If set to “mutual”, the proxy will secure connections to the +upstream using mutual TLS by presenting client certificates for +authentication.

+ +
+
+

StringMatch

+
+

Describes how to match a given string in HTTP headers. Match is +case-sensitive.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
exactstring (oneof) +

exact string match

+ +
prefixstring (oneof) +

prefix-based match

+ +
regexstring (oneof) +

ECMAscript style regex-based match

+ +
+
+

Subset

+
+

A subset of endpoints of a service. Subsets can be used for scenarios +like A/B testing, or routing to a specific version of a service. Refer +to VirtualService documentation for examples of using subsets in these +scenarios. In addition, traffic policies defined at the service-level +can be overridden at a subset-level. The following rule uses a round +robin load balancing policy for all traffic going to a subset named +testversion that is composed of endpoints (e.g., pods) with labels +(version:v3).

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: bookinfo-ratings
+spec:
+  name: ratings
+  trafficPolicy:
+    loadBalancer:
+      simple: LEAST_CONN
+  subsets:
+  - name: testversion
+    labels:
+      version: v3
+    trafficPolicy:
+      loadBalancer:
+        simple: ROUND_ROBIN
+
+ +

Note that policies specified for subsets will not take effect until +a route rule explicitly sends traffic to this subset.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
namestring +

REQUIRED. name of the subset. The service name and the subset name can +be used for traffic splitting in a route rule.

+ +
labelsmap<string, string> +

REQUIRED. Labels apply a filter over the endpoints of a service in the +service registry. See route rules for examples of usage.

+ +
trafficPolicyTrafficPolicy +

Traffic policies that apply to this subset. Subsets inherit the +traffic policies specified at the DestinationRule level. Settings +specified at the subset level will override the corresponding settings +specified at the DestinationRule level.

+ +
+
+

TCPRoute

+
+

Describes match conditions and actions for routing TCP traffic. The +following routing rule forwards traffic arriving at port 2379 named +Mongo from 172.17.16.* subnet to another Mongo server on port 5555.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: bookinfo-Mongo
+spec:
+  hosts:
+  - myMongosrv 
+  tcp:
+  - match:
+    - port:
+        name: Mongo # only applies to ports named Mongo
+      sourceSubnet: "172.17.16.0/24"
+    route:
+    - destination:
+        name: mongo.prod
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
matchL4MatchAttributes[] +

Match conditions to be satisfied for the rule to be +activated. All conditions inside a single match block have AND +semantics, while the list of match blocks have OR semantics. The rule +is matched if any one of the match blocks succeed.

+ +
routeDestinationWeight[] +

The destination to which the connection should be forwarded to. +Currently, only one destination is allowed for TCP services. When TCP +weighted routing support is introduced in Envoy, multiple destinations +with weights can be specified.

+ +
+
+

TLSSettings

+
+

SSL/TLS related settings for upstream connections. See Envoy’s TLS +context +for more details. These settings are common to both HTTP and TCP upstreams.

+ +

For example, the following rule configures a client to use mutual TLS +for connections to upstream database cluster.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: db-mtls
+spec:
+  name: mydbserver
+  trafficPolicy:
+    tls:
+      mode: MUTUAL
+      clientCertificate: /etc/certs/myclientcert.pem
+      privateKey: /etc/certs/client_private_key.pem
+      caCertificates: /etc/certs/rootcacerts.pem
+
+ +

The following rule configures a client to use TLS when talking to a foreign service whose domain matches *.foo.com.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: tls-foo
+spec:
+  name: "*.foo.com"
+  trafficPolicy:
+    tls:
+      mode: SIMPLE
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
modeTLSSettings.TLSmode +

REQUIRED: Indicates whether connections to this port should be secured +using TLS. The value of this field determines how TLS is enforced.

+ +
clientCertificatestring +

REQUIRED if mode is “mutual”. The path to the file holding the +client-side TLS certificate to use.

+ +
privateKeystring +

REQUIRED if mode is “mutual”. The path to the file holding the +client’s private key.

+ +
caCertificatesstring +

OPTIONAL: The path to the file containing certificate authority +certificates to use in verifying a presented server certificate. If +omitted, the proxy will not verify the server’s certificate.

+ +
subjectAltNamesstring[] +

A list of alternate names to verify the subject identity in the +certificate. If specified, the proxy will verify that the server +certificate’s subject alt name matches one of the specified values.

+ +
snistring +

SNI string to present to the server during TLS handshake.

+ +
+
+

TLSSettings.TLSmode

+
+

TLS connection mode

+ + + + + + + + + + + + + + + + + + + + + + +
NameDescription
DISABLE +

If set to “disable”, the proxy will use not setup a TLS connection to the +upstream server.

+ +
SIMPLE +

If set to “simple”, the proxy will originate a TLS connection to the +upstream server.

+ +
MUTUAL +

If set to “mutual”, the proxy will secure connections to the +upstream using mutual TLS by presenting client certificates for +authentication.

+ +
+
+

TrafficPolicy

+
+

Traffic policies to apply for a specific destination. See +DestinationRule for examples.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
loadBalancerLoadBalancerSettings +

Settings controlling the load balancer algorithms.

+ +
connectionPoolConnectionPoolSettings +

Settings controlling the volume of connections to an upstream service

+ +
outlierDetectionOutlierDetection +

Settings controlling eviction of unhealthy hosts from the load balancing pool

+ +
tlsTLSSettings +

TLS related settings for connections to the upstream service.

+ +
+
+

VirtualService

+
+

A VirtualService defines a set of traffic routing rules to apply when a host is +addressed. Each routing rule defines matching criteria for traffic of a specific +protocol. If the traffic is matched, then it is sent to a named destination service +(or subset/version of it) defined in the registry.

+ +

The source of traffic can also be matched in a routing rule. This allows routing +to be customized for specific client contexts.

+ +

The following example routes all HTTP traffic by default to +pods of the reviews service with label “version: v1”. In addition, +HTTP requests containing /wpcatalog/, /consumercatalog/ url prefixes will +be rewritten to /newcatalog and sent to pods with label “version: v2”. The +rules will be applied at the gateway named “bookinfo” as well as at all +the sidecars in the mesh (indicated by the reserved gateway name +“mesh”).

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews-route
+spec:
+  hosts:
+  - reviews
+  gateways: # if omitted, defaults to "mesh"
+  - bookinfo
+  - mesh
+  http:
+  - match:
+    - uri:
+        prefix: "/wpcatalog"
+    - uri:
+        prefix: "/consumercatalog"
+    rewrite:
+      uri: "/newcatalog"
+    route:
+    - destination:
+        name: reviews
+        subset: v2
+  - route:
+    - destination:
+        name: reviews
+        subset: v1
+
+ +

A subset/version of a route destination is identified with a reference +to a named service subset which must be declared in a corresponding +DestinationRule.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: reviews-destination
+spec:
+  name: reviews
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+
+ +

A host name can be defined by only one VirtualService. A single +VirtualService can be used to describe traffic properties for multiple +HTTP and TCP ports.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
hostsstring[] +

REQUIRED. The destination address for traffic captured by this virtual +service. Could be a DNS name with wildcard prefix or a CIDR +prefix. Depending on the platform, short-names can also be used +instead of a FQDN (i.e. has no dots in the name). In such a scenario, +the FQDN of the host would be derived based on the underlying +platform.

+ +

For example on Kubernetes, when hosts contains a short name, Istio will +interpret the short name based on the namespace of the rule. Thus, when a +client namespace applies a rule in the “default” namespace containing a name +“reviews, Istio will setup routes to the “reviews.default.svc.cluster.local” +service. However, if a different name such as “reviews.sales.svc.cluster.local” +is used, it would be treated as a FQDN during virtual host matching. +In Consul, a plain service name would be resolved to the FQDN +“reviews.service.consul”.

+ +

Note that the hosts field applies to both HTTP and TCP +services. Service inside the mesh, i.e., those found in the service +registry, must always be referred to using their alphanumeric +names. IP addresses or CIDR prefixes are allowed only for services +defined via the Gateway.

+ +
gatewaysstring[] +

The names of gateways and sidecars that should apply these routes. A +single VirtualService is used for sidecars inside the mesh as well +as for one or more gateways. The selection condition imposed by this field +can be overridden using the source field in the match conditions of HTTP/TCP +routes. The reserved word “mesh” is used to imply all the sidecars in +the mesh. When this field is omitted, the default gateway (“mesh”) +will be used, which would apply the rule to all sidecars in the +mesh. If a list of gateway names is provided, the rules will apply +only to the gateways. To apply the rules to both gateways and sidecars, +specify “mesh” as one of the gateway names.

+ +
httpHTTPRoute[] +

An ordered list of route rules for HTTP traffic. +The first rule matching an incoming request is used.

+ +
tcpTCPRoute[] +

An ordered list of route rules for TCP traffic. +The first rule matching an incoming request is used.

+ +
+
diff --git a/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html b/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html index c9cc5b7a96fa..895e3751e386 100644 --- a/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html +++ b/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html @@ -305,7 +305,7 @@

QuotaResult

quotas -map<string, QuotaResult> +map<string, QuotaResult.Result>

The resulting quota, one entry per requested quota.

From acd48acfb31c80bc036ecee4bf1bd4865de8693b Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Thu, 22 Mar 2018 07:22:39 -0700 Subject: [PATCH 045/191] Remove empty document. (#1085) --- _docs/guides/upgrading-istio.md | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 _docs/guides/upgrading-istio.md diff --git a/_docs/guides/upgrading-istio.md b/_docs/guides/upgrading-istio.md deleted file mode 100644 index 691100bb26d2..000000000000 --- a/_docs/guides/upgrading-istio.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Upgrading Istio -overview: This guide demonstrates how to upgrade the Istio control plane and data plane independently. - -order: 70 -draft: true -layout: docs -type: markdown ---- -{% include home.html %} - -This guide demonstrates how to upgrade the Istio control plane and data plane independently. - -## Overview - -Placeholder. - -## Application Setup - -1. Steps - -## Tasks - -1. some tasks that will complete the goal of this sample. From 2372d720c1f0be1254cde101b5c99200850e0bc7 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 22 Mar 2018 20:16:37 +0200 Subject: [PATCH 046/191] Update Ansible documentation to reflect change in Jaeger addon (#1049) * Update Ansible documentation to reflect change in Jaeger addon Relates to: https://github.com/istio/istio/pull/3603 * Small polish to Ansible documentation --- _docs/setup/kubernetes/ansible-install.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/_docs/setup/kubernetes/ansible-install.md b/_docs/setup/kubernetes/ansible-install.md index 58d6c9eaf119..bf83b41a9858 100644 --- a/_docs/setup/kubernetes/ansible-install.md +++ b/_docs/setup/kubernetes/ansible-install.md @@ -53,12 +53,11 @@ The full list of configurable parameters is as follows: | `cluster_flavour` | Defines whether the target cluster is a Kubernetes or an Openshift cluster. | Valid values are `k8s` and `ocp` (default) | | `github_api_token` | The API token used for authentication when calling the GitHub API | Any valid GitHub API token or empty (default) | | `cmd_path` | Can be used when the user does not have the `oc` or `kubectl` binary on the PATH | Defaults to expecting the binary is on the path | -| `istio.release_tag_name` | Should be a valid Istio release version. If left empty, the latest Istio release will be installed | `0.2.12`, `0.3.0`, `0.4.0`, `0.5.0`, `0.5.1` | +| `istio.release_tag_name` | Should be a valid Istio release version. If left empty, the latest Istio release will be installed | `0.2.12`, `0.3.0`, `0.4.0`, ... | | `istio.dest` | The directory of the target machine where Istio will be installed | `~/.istio` (default) | | `istio.auth` | Boolean value to install Istio using MUTUAL_TLS | `true` and `false` (default) | | `istio.namespace` | The namespace where Istio will be installed | `istio-system` (default) | -| `istio.addon` | Which Istio addons should be installed as well | This field is an array field, which by default contains `grafana`, `prometheus`, `zipkin` and `servicegraph` | -| `istio.jaeger` | Whether or not Jaeger tracing should also be installed | `true` and `false` (default)| +| `istio.addon` | Which Istio addons should be installed as well | This field is an array field, which by default contains `grafana`, `prometheus`, `zipkin`, `jaeger` (disables Zipkin if selected), and `servicegraph` | | `istio.delete_resources` | Boolean value to delete resources created under the Istio namespace | `true` and `false` (default)| | `istio.samples` | Array containing the names of the samples that should be installed | Valid names are: `bookinfo`, `helloworld`, `httpbin`, `sleep` @@ -101,12 +100,12 @@ ansible-playbook main.yml -e '{"cluster_flavour": "k8s", "cmd_path": "~/kubectl" - User wants to install Istio on Openshift with settings other than the default ```bash -ansible-playbook main.yml -e '{"istio": {"release_tag_name": "0.4.0", "auth": true, "jaeger": true, "delete_resources": true}}' +ansible-playbook main.yml -e '{"istio": {"release_tag_name": "0.6.0", "auth": true, "delete_resources": true}}' ``` - User wants to install Istio on Openshift but with custom add-on settings ```bash -ansible-playbook main.yml -e '{"istio": {"delete_resources": true, "addon": ["grafana", "prometheus"]}}' +ansible-playbook main.yml -e '{"istio": {"delete_resources": true, "addon": ["grafana", "prometheus", "jaeger"]}}' ``` - User wants to install Istio on Openshift and additionally wants to deploy some of the samples @@ -115,7 +114,6 @@ ansible-playbook main.yml -e '{"istio": {"samples": ["helloworld", "bookinfo"]}} ``` The list of available addons can be found at `istio/vars.main.yml` under the name `istio_all_addons`. -Jaeger is not installed using the `addons` property, but can be installed by enabling `"jaeger": true` like in one of the previous examples. It should be noted that when Jaeger is enabled, Zipkin is disabled whether or not it's been selected in the addons section. ## Adding istioctl to PATH From 8d8a44c665b8a13733bd23bce5c7befa1bcdf55f Mon Sep 17 00:00:00 2001 From: Steven Dake Date: Thu, 22 Mar 2018 21:25:29 -0700 Subject: [PATCH 047/191] Remove extra tilde in the docs (#1087) Fixes #1004 --- _docs/setup/kubernetes/sidecar-injection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index 6eccd13701fe..cf5a54c43f22 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -74,7 +74,7 @@ configuration from the `istio` ConfigMap. Additional parameter overrides are available via flags (see `istioctl kube-inject --help`). ```bash -kubectl apply -f <(~istioctl kube-inject -f samples/sleep/sleep.yaml) +kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) ``` `kube-inject` can also be run without access to a running Kubernetes From b12506c88d4e036db96af66642f092a515bf1de3 Mon Sep 17 00:00:00 2001 From: Frank Budinsky Date: Fri, 23 Mar 2018 09:11:07 -0400 Subject: [PATCH 048/191] [WIP] Update traffic routing tasks to use v1alpha3 config (#1067) * use v1alpha3 route rules * circuit breaking task updated to v1alpha3 * convert mirroring task to v1alpha3 * convert egress task to v1alpha3 * Egress task corrections and clarifications * use simpler rule names * move new tasks to separate folder (keep old versions around for now) * update example outputs * egress tcp task * fix broken refs * more broken refs * imporove wording * add missing include home.html * remove ingress task - will create a replacement in followup PR --- .../circuit-breaking.md | 252 +++++++++++++++ .../traffic-management-v1alpha3/egress-tcp.md | 111 +++++++ .../traffic-management-v1alpha3/egress.md | 297 ++++++++++++++++++ .../fault-injection.md | 174 ++++++++++ .../traffic-management-v1alpha3/index.md | 12 + .../traffic-management-v1alpha3/mirroring.md | 268 ++++++++++++++++ .../request-routing.md | 186 +++++++++++ .../request-timeouts.md | 149 +++++++++ .../traffic-shifting.md | 108 +++++++ 9 files changed, 1557 insertions(+) create mode 100644 _docs/tasks/traffic-management-v1alpha3/circuit-breaking.md create mode 100644 _docs/tasks/traffic-management-v1alpha3/egress-tcp.md create mode 100644 _docs/tasks/traffic-management-v1alpha3/egress.md create mode 100644 _docs/tasks/traffic-management-v1alpha3/fault-injection.md create mode 100644 _docs/tasks/traffic-management-v1alpha3/index.md create mode 100644 _docs/tasks/traffic-management-v1alpha3/mirroring.md create mode 100644 _docs/tasks/traffic-management-v1alpha3/request-routing.md create mode 100644 _docs/tasks/traffic-management-v1alpha3/request-timeouts.md create mode 100644 _docs/tasks/traffic-management-v1alpha3/traffic-shifting.md diff --git a/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md b/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md new file mode 100644 index 000000000000..bf5024f3893d --- /dev/null +++ b/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md @@ -0,0 +1,252 @@ +--- +title: Circuit Breaking +overview: This task demonstrates the circuit-breaking capability for resilient applications + +order: 50 + +layout: docs +type: markdown +--- +{% include home.html %} + +This task demonstrates the circuit-breaking capability for resilient applications. Circuit breaking allows developers to write applications that limit the impact of failures, latency spikes, and other undesirable effects of network peculiarities. This task will show how to configure circuit breaking for connections, requests, and outlier detection. + +## Before you begin + +* Setup Istio by following the instructions in the + [Installation guide]({{home}}/docs/setup/). + +* Start the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) sample + which will be used as the backend service for our task + + ```bash + kubectl apply -f <(istioctl kube-inject --debug -f samples/httpbin/httpbin.yaml) + ``` + +## Circuit breaker + +Let's set up a scenario to demonstrate the circuit-breaking capabilities of Istio. We should have the `httpbin` service running from the previous section. + +1. Create a [destination rule]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#DestinationRule) to specify our circuit breaking settings when calling the `httpbin` service: + + ```bash + cat <2 procs, for 5s: http://httpbin:8000/get +Starting at max qps with 2 thread(s) [gomax 2] for exactly 20 calls (10 per thread + 0) +23:51:10 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +Ended after 106.474079ms : 20 calls. qps=187.84 +Aggregated Function Time : count 20 avg 0.010215375 +/- 0.003604 min 0.005172024 max 0.019434859 sum 0.204307492 +# range, mid point, percentile, count +>= 0.00517202 <= 0.006 , 0.00558601 , 5.00, 1 +> 0.006 <= 0.007 , 0.0065 , 20.00, 3 +> 0.007 <= 0.008 , 0.0075 , 30.00, 2 +> 0.008 <= 0.009 , 0.0085 , 40.00, 2 +> 0.009 <= 0.01 , 0.0095 , 60.00, 4 +> 0.01 <= 0.011 , 0.0105 , 70.00, 2 +> 0.011 <= 0.012 , 0.0115 , 75.00, 1 +> 0.012 <= 0.014 , 0.013 , 90.00, 3 +> 0.016 <= 0.018 , 0.017 , 95.00, 1 +> 0.018 <= 0.0194349 , 0.0187174 , 100.00, 1 +# target 50% 0.0095 +# target 75% 0.012 +# target 99% 0.0191479 +# target 99.9% 0.0194062 +Code 200 : 19 (95.0 %) +Code 503 : 1 (5.0 %) +Response Header Sizes : count 20 avg 218.85 +/- 50.21 min 0 max 231 sum 4377 +Response Body/Total Sizes : count 20 avg 652.45 +/- 99.9 min 217 max 676 sum 13049 +All done 20 calls (plus 0 warmup) 10.215 ms avg, 187.8 qps +``` + +We see almost all requests made it through! + +``` +Code 200 : 19 (95.0 %) +Code 503 : 1 (5.0 %) +``` + +The istio-proxy does allow for some leeway. Let's bring the number of concurrent connections up to 3: + +```bash +kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 3 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get +``` +``` +Fortio 0.6.2 running at 0 queries per second, 2->2 procs, for 5s: http://httpbin:8000/get +Starting at max qps with 3 thread(s) [gomax 2] for exactly 30 calls (10 per thread + 0) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) +Ended after 71.05365ms : 30 calls. qps=422.22 +Aggregated Function Time : count 30 avg 0.0053360199 +/- 0.004219 min 0.000487853 max 0.018906468 sum 0.160080597 +# range, mid point, percentile, count +>= 0.000487853 <= 0.001 , 0.000743926 , 10.00, 3 +> 0.001 <= 0.002 , 0.0015 , 30.00, 6 +> 0.002 <= 0.003 , 0.0025 , 33.33, 1 +> 0.003 <= 0.004 , 0.0035 , 40.00, 2 +> 0.004 <= 0.005 , 0.0045 , 46.67, 2 +> 0.005 <= 0.006 , 0.0055 , 60.00, 4 +> 0.006 <= 0.007 , 0.0065 , 73.33, 4 +> 0.007 <= 0.008 , 0.0075 , 80.00, 2 +> 0.008 <= 0.009 , 0.0085 , 86.67, 2 +> 0.009 <= 0.01 , 0.0095 , 93.33, 2 +> 0.014 <= 0.016 , 0.015 , 96.67, 1 +> 0.018 <= 0.0189065 , 0.0184532 , 100.00, 1 +# target 50% 0.00525 +# target 75% 0.00725 +# target 99% 0.0186345 +# target 99.9% 0.0188793 +Code 200 : 19 (63.3 %) +Code 503 : 11 (36.7 %) +Response Header Sizes : count 30 avg 145.73333 +/- 110.9 min 0 max 231 sum 4372 +Response Body/Total Sizes : count 30 avg 507.13333 +/- 220.8 min 217 max 676 sum 15214 +All done 30 calls (plus 0 warmup) 5.336 ms avg, 422.2 qps +``` + +Now we start to see the circuit breaking behavior we expect. + +``` +Code 200 : 19 (63.3 %) +Code 503 : 11 (36.7 %) +``` + +Only 63.3% of the requests made it through and the rest were trapped by circuit breaking. We can query the istio-proxy stats to see more: + +```bash +kubectl exec -it $FORTIO_POD -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep httpbin | grep pending +``` +``` +cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_active: 0 +cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_failure_eject: 0 +cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_overflow: 12 +cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_total: 39 +``` + +We see `12` for the `upstream_rq_pending_overflow` value which means `12` calls so far have been flagged for circuit breaking. + +## Cleaning up + +1. Remove the rules. + + ```bash + istioctl delete destinationrule httpbin + ``` + +1. Shutdown the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) service and client. + + ```bash + kubectl delete deploy httpbin fortio-deploy + kubectl delete svc httpbin + ``` + +## What's next + +Check out the [destination rule]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#DestinationRule) reference section for more circuit breaker settings. diff --git a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md new file mode 100644 index 000000000000..be1855325266 --- /dev/null +++ b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md @@ -0,0 +1,111 @@ +--- +title: Control Egress TCP Traffic +overview: Describes how to configure Istio to route TCP traffic from services in the mesh to external services. + +order: 41 + +layout: docs +type: markdown +--- +{% include home.html %} + +The [Control Egress Traffic]({{home}}/docs/tasks/traffic-management-v1alpha3/egress.html) task demonstrated how external (outside the Kubernetes cluster) HTTP and HTTPS services can be accessed from applications inside the mesh. A quick reminder: by default, Istio-enabled applications are unable to access URLs outside the cluster. To enable such access, an [external service]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#ExternalService) must be defined, or, alternatively, [direct access to external services]({{home}}/docs/tasks/traffic-management-v1alpha3/egress.html#calling-external-services-directly) must be configured. + +This task describes how to configure Istio to expose external TCP services to applications inside the Istio service mesh. + +## Before you begin + +* Setup Istio by following the instructions in the + [Installation guide]({{home}}/docs/setup/). + +* Start the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) sample application which will be used as a test source for external calls. + + ```bash + kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) + ``` + + **Note**: any pod that you can execute `curl` from is good enough. + +## Using Istio external services for external TCP traffic +In this task we access `wikipedia.org` by HTTPS originated by the application. This task demonstrates the use case where an application cannot use HTTP with TLS origination by the sidecar proxy. Using HTTP with TLS origination by the sidecar proxy is described in the [Control Egress Traffic]({{home}}/docs/tasks/traffic-management-v1alpha3/egress.html) task. In that task, `https://google.com` was accessed by issuing HTTP requests to `http://www.google.com:443`. + +The HTTPS traffic originated by the application will be treated by Istio as _opaque_ TCP. To enable such traffic, we define a TCP external service on port 443. In TCP external services, as opposed to HTTP-based external services, the destinations are specified by IPs or by blocks of IPs in [CIDR notation](https://tools.ietf.org/html/rfc2317). + +Let's assume for the sake of this example that we want to access `wikipedia.org` by the domain name. This means that we have to specify all the IPs of `wikipedia.org` in our TCP external service. Fortunately, the IPs of `wikipedia.org` are published [here]( https://www.mediawiki.org/wiki/Wikipedia_Zero/IP_Addresses). It is a list of IP blocks in [CIDR notation](https://tools.ietf.org/html/rfc2317): `91.198.174.192/27`, `103.102.166.224/27`, and more. + +## Creating an external service +Let's create an external service to enable TCP access to `wikipedia.org`: +```bash +cat <5,563,121 articles in English + ``` + + This means there were 5,563,121 articles in Wikipedia in English when this task was written. + +## Cleanup + +1. Remove the external service we created. + + ```bash + istioctl delete externalservice wikipedia-ext + ``` + +1. Shutdown the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) application. + + ```bash + kubectl delete -f samples/sleep/sleep.yaml + ``` + +## What's next + +* The [External Services]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#ExternalService) reference. + +* The [Control Egress Traffic]({{home}}/docs/tasks/traffic-management-v1alpha3/egress.html) task, for HTTP and HTTPS. diff --git a/_docs/tasks/traffic-management-v1alpha3/egress.md b/_docs/tasks/traffic-management-v1alpha3/egress.md new file mode 100644 index 000000000000..0236892ddb44 --- /dev/null +++ b/_docs/tasks/traffic-management-v1alpha3/egress.md @@ -0,0 +1,297 @@ +--- +title: Control Egress Traffic +overview: Describes how to configure Istio to route traffic from services in the mesh to external services. + +order: 40 + +layout: docs +type: markdown +--- +{% include home.html %} + +By default, Istio-enabled services are unable to access URLs outside of the cluster because +iptables is used in the pod to transparently redirect all outbound traffic to the sidecar proxy, +which only handles intra-cluster destinations. + +This task describes how to configure Istio to expose external services to Istio-enabled clients. +You'll learn how to enable access to external services by defining `ExternalService` configurations, +or alternatively, to simply bypass the Istio proxy for a specific range of IPs. + +## Before you begin + +* Setup Istio by following the instructions in the + [Installation guide]({{home}}/docs/setup/). + +* Start the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) sample + which will be used as a test source for external calls. + + ```bash + kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) + ``` + + Note that any pod that you can `exec` and `curl` from would do. + +## Configuring Istio external services + +Using Istio `ExternalService` configurations, you can access any publicly accessible service +from within your Istio cluster. In this task we will use +[httpbin.org](http://httpbin.org) and [www.google.com](http://www.google.com) as examples. + +### Configuring the external services + +1. Create an `ExternalService` to allow access to an external HTTP service: + + ```bash + cat < Notice that we are restricting the failure impact to user "jason" only. If you login + > as any other user, you would not experience any delays. + + **Fixing the bug:** At this point we would normally fix the problem by either increasing the + productpage timeout or decreasing the reviews to ratings service timeout, + terminate and restart the fixed microservice, and then confirm that the `productpage` + returns its response without any errors. + + However, we already have this fix running in v3 of the reviews service, so we can simply + fix the problem by migrating all + traffic to `reviews:v3` as described in the + [traffic shifting]({{home}}/docs/tasks/traffic-management/traffic-shifting.html) task. + + (Left as an exercise for the reader - change the delay rule to + use a 2.8 second delay and then run it against the v3 version of reviews.) + +## Fault injection using HTTP Abort +As another test of resiliency, we will introduce an HTTP abort to the ratings microservices for the user "jason". +We expect the page to load immediately unlike the delay example and display the "product ratings not available" +message. + +1. Create a fault injection rule to send an HTTP abort for user "jason" + + ```bash + istioctl replace -f samples/bookinfo/routing/route-rule-ratings-test-abort.yaml + ``` + + Confirm the rule is created + + ```bash + istioctl get virtualservice ratings -o yaml + ``` + ```yaml + apiVersion: networking.istio.io/v1alpha3 + kind: VirtualService + metadata: + name: ratings + ... + spec: + hosts: + - ratings + http: + - fault: + abort: + httpStatus: 500 + percent: 100 + match: + - headers: + cookie: + regex: ^(.*?;)?(user=jason)(;.*)?$ + - route: + - destination: + name: ratings + subset: v1 + ``` + +1. Observe application behavior + + Login as user "jason". If the rule propagated successfully to all pods, you should see the page load + immediately with the "product ratings not available" message. Logout from user "jason" and you should + see the ratings v2 show up successfully on the productpage web page. + +## Cleanup + +* Remove the application routing rules: + + ```bash + istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml + ``` + +* If you are not planning to explore any follow-on tasks, refer to the + [Bookinfo cleanup]({{home}}/docs/guides/bookinfo.html#cleanup) instructions + to shutdown the application. + +## What's next + +* Learn more about [fault injection]({{home}}/docs/concepts/traffic-management/fault-injection.html). diff --git a/_docs/tasks/traffic-management-v1alpha3/index.md b/_docs/tasks/traffic-management-v1alpha3/index.md new file mode 100644 index 000000000000..4fe841630e81 --- /dev/null +++ b/_docs/tasks/traffic-management-v1alpha3/index.md @@ -0,0 +1,12 @@ +--- +title: Traffic Management (v1alpha3) +overview: WIP - Describes tasks that demonstrate traffic routing features of Istio service mesh. + +order: 15 + +layout: docs +type: markdown +toc: false +--- + +{% include section-index.html docs=site.docs %} diff --git a/_docs/tasks/traffic-management-v1alpha3/mirroring.md b/_docs/tasks/traffic-management-v1alpha3/mirroring.md new file mode 100644 index 000000000000..7472c16b85b4 --- /dev/null +++ b/_docs/tasks/traffic-management-v1alpha3/mirroring.md @@ -0,0 +1,268 @@ +--- +title: Mirroring +overview: This task demonstrates the traffic shadowing/mirroring capabilities of Istio + +order: 60 + +layout: docs +type: markdown +--- +{% include home.html %} + +This task demonstrates the traffic shadowing/mirroring capabilities of Istio. Traffic mirroring is a powerful concept that allows feature teams to bring changes to production with as little risk as possible. Mirroring brings a copy of live traffic to a mirrored service and happens out of band of the critical request path for the primary service. + + +## Before you begin + +* Setup Istio by following the instructions in the + [Installation guide]({{home}}/docs/setup/). + +* Start two versions of the `httpbin` service that have access logging enabled + +httpbin-v1: + +```bash +cat < +``` + +2. Change the route rule to mirror traffic to v2 + +```bash +cat < Note: This task assumes you don't have any routes set yet. If you've already created conflicting route rules for the sample, + you'll need to use `replace` rather than `create` in the following command. + +1. Set the default version for all microservices to v1. + + ```bash + istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml + ``` + + > Note: In a Kubernetes deployment of Istio, you can replace `istioctl` + > with `kubectl` in the above, and for all other CLI commands. + > Note, however, that `kubectl` currently does not provide input validation. + + You can display the routes that are defined with the following command: + + ```bash + istioctl get virtualservices -o yaml + ``` + ```yaml + apiVersion: networking.istio.io/v1alpha3 + kind: VirtualService + metadata: + name: details + ... + spec: + hosts: + - details + http: + - route: + - destination: + name: details + subset: v1 + --- + apiVersion: networking.istio.io/v1alpha3 + kind: VirtualService + metadata: + name: productpage + ... + spec: + gateways: + - bookinfo-gateway + - mesh + hosts: + - productpage + http: + - route: + - destination: + name: productpage + subset: v1 + --- + apiVersion: networking.istio.io/v1alpha3 + kind: VirtualService + metadata: + name: ratings + ... + spec: + hosts: + - ratings + http: + - route: + - destination: + name: ratings + subset: v1 + --- + apiVersion: networking.istio.io/v1alpha3 + kind: VirtualService + metadata: + name: reviews + ... + spec: + hosts: + - reviews + http: + - route: + - destination: + name: reviews + subset: v1 + --- + ``` + + > Note: The corresponding `subset` definitions can be displayed using `istioctl get destinationrules -o yaml`. + + Since rule propagation to the proxies is asynchronous, you should wait a few seconds for the rules + to propagate to all pods before attempting to access the application. + +1. Open the Bookinfo URL (http://$GATEWAY_URL/productpage) in your browser + + You should see the Bookinfo application productpage displayed. + Notice that the `productpage` is displayed with no rating stars since `reviews:v1` does not access the ratings service. + +1. Route a specific user to `reviews:v2` + + Lets enable the ratings service for test user "jason" by routing productpage traffic to + `reviews:v2` instances. + + ```bash + istioctl replace -f samples/bookinfo/routing/route-rule-reviews-test-v2.yaml + ``` + + Confirm the rule is created: + + ```bash + istioctl get virtualservice reviews -o yaml + ``` + ```yaml + apiVersion: networking.istio.io/v1alpha3 + kind: VirtualService + metadata: + name: reviews + ... + spec: + hosts: + - reviews + http: + - match: + - headers: + cookie: + regex: ^(.*?;)?(user=jason)(;.*)?$ + route: + - destination: + name: reviews + subset: v2 + - route: + - destination: + name: reviews + subset: v1 + ``` + +1. Log in as user "jason" at the `productpage` web page. + + You should now see ratings (1-5 stars) next to each review. Notice that if you log in as + any other user, you will continue to see `reviews:v1`. + +## Understanding what happened + +In this task, you used Istio to send 100% of the traffic to the v1 version of each of the Bookinfo +services. You then set a rule to selectively send traffic to version v2 of the reviews service based +on a header (i.e., a user cookie) in a request. + +Once the v2 version has been tested to our satisfaction, we could use Istio to send traffic from +all users to v2, optionally in a gradual fashion. We'll explore this in a separate task. + +## Cleanup + +* Remove the application routing rules. + + ```bash + istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml + ``` + +* If you are not planning to explore any follow-on tasks, refer to the + [Bookinfo cleanup]({{home}}/docs/guides/bookinfo.html#cleanup) instructions + to shutdown the application. + +## What's next + +* Learn more about [request routing]({{home}}/docs/concepts/traffic-management/rules-configuration.html). diff --git a/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md b/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md new file mode 100644 index 000000000000..ba06022560b4 --- /dev/null +++ b/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md @@ -0,0 +1,149 @@ +--- +title: Setting Request Timeouts +overview: This task shows you how to setup request timeouts in Envoy using Istio. + +order: 28 + +layout: docs +type: markdown +--- +{% include home.html %} + +This task shows you how to setup request timeouts in Envoy using Istio. + +## Before you begin + +* Setup Istio by following the instructions in the + [Installation guide]({{home}}/docs/setup/). + +* Deploy the [Bookinfo]({{home}}/docs/guides/bookinfo.html) sample application. + +* Initialize the application version routing by running the following command: + + ```bash + istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml + ``` + +## Request timeouts + +A timeout for http requests can be specified using the *httpReqTimeout* field of a routing rule. +By default, the timeout is 15 seconds, but in this task we'll override the `reviews` service +timeout to 1 second. +To see its effect, however, we'll also introduce an artificial 2 second delay in calls +to the `ratings` service. + +1. Route requests to v2 of the `reviews` service, i.e., a version that calls the `ratings` service + + ```bash + cat < Note: With the current Envoy sidecar implementation, you may need to refresh the `productpage` very many times + > to see the proper distribution. It may require 15 refreshes or more before you see any change. You can modify the rules to route 90% of the traffic to v3 to see red stars more often. + +1. When version v3 of the `reviews` microservice is considered stable, we can route 100% of the traffic to `reviews:v3`: + + ```bash + istioctl replace -f samples/bookinfo/routing/route-rule-reviews-v3.yaml + ``` + + You can now log into the `productpage` as any user and you should always see book reviews + with *red* colored star ratings for each review. + +## Understanding what happened + +In this task we migrated traffic from an old to new version of the `reviews` service using Istio's +weighted routing feature. Note that this is very different than version migration using deployment features +of container orchestration platforms, which use instance scaling to manage the traffic. +With Istio, we can allow the two versions of the `reviews` service to scale up and down independently, +without affecting the traffic distribution between them. +For more about version routing with autoscaling, check out [Canary Deployments using Istio]({{home}}/blog/canary-deployments-using-istio.html). + +## Cleanup + +* Remove the application routing rules. + + ```bash + istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml + ``` + +* If you are not planning to explore any follow-on tasks, refer to the + [Bookinfo cleanup]({{home}}/docs/guides/bookinfo.html#cleanup) instructions + to shutdown the application. + +## What's next + +* Learn more about [request routing]({{home}}/docs/concepts/traffic-management/rules-configuration.html). From bdaadeefd3ccf7f2682cfb7c391aae72f460e75d Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Fri, 23 Mar 2018 07:12:32 -0700 Subject: [PATCH 049/191] Improve sorting algorithm to use document title and not just document URL. (#1089) This makes it so documents in the same directory get sorted by document title instead of by the URL name (unless they have an order: directive, which takes precedence over alpha order) --- _includes/sort-hierarchy.html | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/_includes/sort-hierarchy.html b/_includes/sort-hierarchy.html index 8b93790d4431..c67e8f7a3800 100644 --- a/_includes/sort-hierarchy.html +++ b/_includes/sort-hierarchy.html @@ -63,15 +63,25 @@ {% assign order = order | slice: 0, len | append: "#####" %} {% endif %} - {% assign a = a | append: "^" | append: order | append: "$" | append: doc.url | append: "$" | append: doc.title | append: "$" | append: doc.overview %} + + {% assign hackUrl = "" %} + {% for i in (1..count) %} + {% assign hackUrl = hackUrl | append: "/" | append: components[i] %} + {% endfor %} + {% assign hackUrl = hackUrl | append: "/" | append: doc.title %} + + {% assign a = a | append: "^" | append: order | append: "$" | append: hackUrl | append: "$" | append: doc.url | append: "$" | append: doc.title | + append: "$" | append: doc.overview %} {% endfor %} {% assign sorted = a | split: "^" | sort %} {% for s in sorted %} {% assign parts = s | split: "$" %} - {% assign urls = urls | append: "$" | append: parts[1] %} - {% assign titles = titles | append: "$" | append: parts[2] %} - {% assign overviews = overviews | append: "$" | append: parts[3] %} + {% assign urls = urls | append: "$" | append: parts[2] %} + {% assign titles = titles | append: "$" | append: parts[3] %} + {% assign overviews = overviews | append: "$" | append: parts[4] %} {% endfor %} {% assign urlslen = urls | size | minus: 2 %} From 9bcbc3394c56f2eb8f9530beeb500dd352111da3 Mon Sep 17 00:00:00 2001 From: Limin Wang Date: Fri, 23 Mar 2018 14:55:27 -0700 Subject: [PATCH 050/191] Istio RBAC doc fix. (#1093) --- _docs/concepts/security/rbac.md | 15 +++++----- .../security/role-based-access-control.md | 28 ++++++++++--------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/_docs/concepts/security/rbac.md b/_docs/concepts/security/rbac.md index b4d38898cc04..00b76315a735 100644 --- a/_docs/concepts/security/rbac.md +++ b/_docs/concepts/security/rbac.md @@ -98,7 +98,8 @@ Here is an example of a simple role "service-admin", which has full access to al methods: ["*"] ``` -Here is another role "products-viewer", which has read ("GET" and "HEAD") access to "products" service in "default" namespace. +Here is another role "products-viewer", which has read ("GET" and "HEAD") access to service "products.default.svc.cluster.local" +in "default" namespace. ```rule apiVersion: "config.istio.io/v1alpha2" @@ -108,7 +109,7 @@ Here is another role "products-viewer", which has read ("GET" and "HEAD") access namespace: default spec: rules: - - services: ["products"] + - services: ["products.default.svc.cluster.local"] methods: ["GET", "HEAD"] ``` @@ -116,7 +117,7 @@ In addition, we support **prefix match** and **suffix match** for all the fields has the following permissions in "default" namespace: * Full access to all services with prefix "test-" (e.g, "test-bookstore", "test-performance", "test-api.default.svc.cluster.local"). * Read ("GET") access to all paths with "/reviews" suffix (e.g, "/books/reviews", "/events/booksale/reviews", "/reviews") -in "bookstore" service. +in service "bookstore.default.svc.cluster.local". ```rule apiVersion: "config.istio.io/v1alpha2" @@ -128,7 +129,7 @@ in "bookstore" service. rules: - services: ["test-*"] methods: ["*"] - - services: ["bookstore"] + - services: ["bookstore.default.svc.cluster.local"] paths: ["*/reviews"] methods: ["GET"] ``` @@ -149,7 +150,7 @@ being "v1" or "v2". Note that the "version" property is provided by `"action.pro namespace: default spec: rules: - - services: ["products"] + - services: ["products.default.svc.cluster.local"] methods: ["GET", "HEAD"] constraints: - key: "version" @@ -168,7 +169,7 @@ instance. Here is an example of ServiceRoleBinding object "test-binding-products", which binds two subjects to ServiceRole "product-viewer": * user "alice@yahoo.com". -* "reviews" service in "abc" namespace. +* "reviews.abc.svc.cluster.local" service in "abc" namespace. ```rule apiVersion: "config.istio.io/v1alpha2" @@ -180,7 +181,7 @@ Here is an example of ServiceRoleBinding object "test-binding-products", which b subjects: - user: "alice@yahoo.com" - properties: - service: "reviews" + service: "reviews.abc.svc.cluster.local" namespace: "abc" roleRef: kind: ServiceRole diff --git a/_docs/tasks/security/role-based-access-control.md b/_docs/tasks/security/role-based-access-control.md index 0275aa642252..fad46f8c659e 100644 --- a/_docs/tasks/security/role-based-access-control.md +++ b/_docs/tasks/security/role-based-access-control.md @@ -67,9 +67,11 @@ Run the following command to enable Istio RBAC for "default" namespace. ```bash -kubectl apply -f samples/bookinfo/kube/istio-rbac-enable.yaml +istioctl create -f samples/bookinfo/kube/istio-rbac-enable.yaml ``` + > Note: if you have conflicting rules that you set in previous tasks, use `istioctl replace` instead of `istioctl create`. + It also defines "requestcontext", which is an instance of the [authorization template](https://github.com/istio/istio/blob/master/mixer/template/authorization/template.proto). "requestcontext" defines the input to the RBAC engine at runtime. @@ -92,7 +94,7 @@ is accessible by services in the same namespace (i.e., "default" namespace) and Run the following command to create a namespace-level access control policy. ```bash -kubectl apply -f samples/bookinfo/kube/istio-rbac-namespace.yaml +istioctl create -f samples/bookinfo/kube/istio-rbac-namespace.yaml ``` The policy does the following: @@ -151,7 +153,7 @@ with "Book Details" section in the lower left part and "Book Reviews" section in Remove the following configuration before you proceed to the next task: ```bash -kubectl delete -f samples/bookinfo/kube/istio-rbac-namespace.yaml +istioctl delete -f samples/bookinfo/kube/istio-rbac-namespace.yaml ``` ## Service-level access control @@ -170,7 +172,7 @@ In this step, we will create a policy that allows external requests to view `pro Run the following command: ```bash -kubectl apply -f samples/bookinfo/kube/istio-rbac-productpage.yaml +istioctl create -f samples/bookinfo/kube/istio-rbac-productpage.yaml ``` The policy does the following: @@ -184,7 +186,7 @@ The policy does the following: namespace: default spec: rules: - - services: ["productpage"] + - services: ["productpage.default.svc.cluster.local"] methods: ["GET"] ``` @@ -219,7 +221,7 @@ We will create a policy to allow "productpage" service to read "details" and "re Run the following command: ```bash -kubectl apply -f samples/bookinfo/kube/istio-rbac-details-reviews.yaml +istioctl create -f samples/bookinfo/kube/istio-rbac-details-reviews.yaml ``` The policy does the following: @@ -233,7 +235,7 @@ The policy does the following: namespace: default spec: rules: - - services: ["details", "reviews"] + - services: ["details.default.svc.cluster.local", "reviews.default.svc.cluster.local"] methods: ["GET"] ``` @@ -272,7 +274,7 @@ We will create a policy to allow "reviews" service to read "ratings" service. No Run the following command to create a policy that allows "reviews" service to read "ratings" service. ```bash -kubectl apply -f samples/bookinfo/kube/istio-rbac-ratings.yaml +istioctl create -f samples/bookinfo/kube/istio-rbac-ratings.yaml ``` The policy does the following: @@ -286,7 +288,7 @@ The policy does the following: namespace: default spec: rules: - - services: ["ratings"] + - services: ["ratings.default.svc.cluster.local"] methods: ["GET"] ``` @@ -336,9 +338,9 @@ spec: * Remove Istio RBAC policy configuration: ```bash - kubectl delete -f samples/bookinfo/kube/istio-rbac-ratings.yaml - kubectl delete -f samples/bookinfo/kube/istio-rbac-details-reviews.yaml - kubectl delete -f samples/bookinfo/kube/istio-rbac-productpage.yaml + istioctl delete -f samples/bookinfo/kube/istio-rbac-ratings.yaml + istioctl delete -f samples/bookinfo/kube/istio-rbac-details-reviews.yaml + istioctl delete -f samples/bookinfo/kube/istio-rbac-productpage.yaml ``` Alternatively, you can delete all ServiceRole and ServiceRoleBinding objects by running the following commands: @@ -351,7 +353,7 @@ spec: * Disable Istio RBAC: ```bash - kubectl delete -f samples/bookinfo/kube/istio-rbac-enable.yaml + istioctl delete -f samples/bookinfo/kube/istio-rbac-enable.yaml ``` ## What's next From 5bf91c35548f5d0354206e1399c5f1beb67846e6 Mon Sep 17 00:00:00 2001 From: Julien Senon Date: Sat, 24 Mar 2018 14:34:34 +0100 Subject: [PATCH 051/191] Improve readability --- _docs/tasks/telemetry/distributed-tracing.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/_docs/tasks/telemetry/distributed-tracing.md b/_docs/tasks/telemetry/distributed-tracing.md index 0ed7b5220583..96569d5af518 100644 --- a/_docs/tasks/telemetry/distributed-tracing.md +++ b/_docs/tasks/telemetry/distributed-tracing.md @@ -25,17 +25,19 @@ example application for this task. * Setup Istio by following the instructions in the [Installation guide]({{home}}/docs/setup/). If you didn't start the Zipkin or Jaeger addon during installation, - you can run the following command to start it now: + you can run the following command to start it now. + + For zipkin: ```bash kubectl apply -f install/kubernetes/addons/zipkin.yaml ``` - for Zipkin, or + + For Jaeger: ```bash kubectl apply -n istio-system -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml ``` - for Jaeger. * Deploy the [Bookinfo]({{home}}/docs/guides/bookinfo.html) sample application. From 420be7f865df114f53e651eb2a2a32a01b953c49 Mon Sep 17 00:00:00 2001 From: Tao Li Date: Mon, 26 Mar 2018 13:04:10 -0700 Subject: [PATCH 052/191] Add one more faq for secret encryption (#1096) --- _faq/security/secret-encryption.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 _faq/security/secret-encryption.md diff --git a/_faq/security/secret-encryption.md b/_faq/security/secret-encryption.md new file mode 100644 index 000000000000..2051a536c59c --- /dev/null +++ b/_faq/security/secret-encryption.md @@ -0,0 +1,10 @@ +--- +title: Is the secret encrypted for workload key and cert? +order: 125 +type: markdown +--- +{% include home.html %} + +By default, they are base64 encoded but not encrypted. However, the [secret encryption feature](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) is supported in Kubernetes and you can do it by following the instruction. + +Notice that this feature is not enabled yet in Google Container Enginer (GKE). While the data may not be encrypted inside the etcd running on the master node, the contents of the master node itself are encrypted, see [here](https://cloud.google.com/security/encryption-at-rest/default-encryption/#encryption_of_data_at_rest) for more info. From 7cf2e07e12215f0320965635c568f6183ecdf46f Mon Sep 17 00:00:00 2001 From: Tao Li Date: Mon, 26 Mar 2018 14:55:55 -0700 Subject: [PATCH 053/191] Add note to have debug version of proxy for curl command (#1097) --- _docs/tasks/security/mutual-tls.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/_docs/tasks/security/mutual-tls.md b/_docs/tasks/security/mutual-tls.md index e26ef9943135..0389fcf37ede 100644 --- a/_docs/tasks/security/mutual-tls.md +++ b/_docs/tasks/security/mutual-tls.md @@ -60,10 +60,17 @@ When running Istio with mutual TLS authentication turned on, you can use curl in envoy to send request to other services. For example, after starting the [Bookinfo]({{home}}/docs/guides/bookinfo.html) sample application you can ssh into the envoy container of `productpage` service, -and send request to other services by curl. +and send request to other services by curl. + +Note: by default istio proxy image does not have curl installed. To try this +feature, please add --debug flag when running kube-inject, i.e., + +```bash +kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) +``` There are several steps: - + 1. get the productpage pod name ```bash kubectl get pods -l app=productpage From 3285d62b97ff4338b4fb3484bbf4292a30c23e12 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Mon, 26 Mar 2018 15:38:03 -0700 Subject: [PATCH 054/191] Delete some old stuff we don't need anymore. * Delete some old stuff we don't need anymore. * Fix problem preventing proper section indices in the "About" section of the site. --- .firebaserc | 6 ------ CONTRIBUTING.md | 2 ++ _about/contribute/index.md | 2 +- _about/notes/index.md | 2 +- firebase.json | 5 ----- scripts/build.sh | 36 ------------------------------------ 6 files changed, 4 insertions(+), 49 deletions(-) delete mode 100644 .firebaserc delete mode 100644 firebase.json delete mode 100755 scripts/build.sh diff --git a/.firebaserc b/.firebaserc deleted file mode 100644 index 8b215d77067c..000000000000 --- a/.firebaserc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "projects": { - "default": "istio-io", - "v01": "istiodocs-v01" - } -} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4696c8e6ee19..c9b6a797648a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,3 +3,5 @@ So, you want to hack on the Istio web site? Yay! Please refer to Istio's overall [contribution guidelines](https://github.com/istio/community/blob/master/CONTRIBUTING.md) to find out how you can help. + +For specifics on hacking on our site, check this [info](https://istio.io/about/contribute/) diff --git a/_about/contribute/index.md b/_about/contribute/index.md index 7a81d0c78059..9289e1fa7d99 100644 --- a/_about/contribute/index.md +++ b/_about/contribute/index.md @@ -10,4 +10,4 @@ toc: false redirect_from: /docs/welcome/contribute/index.html --- -{% include section-index.html docs=site.docs %} +{% include section-index.html docs=site.about %} diff --git a/_about/notes/index.md b/_about/notes/index.md index 445420c64e8c..8b437f4b1a2f 100644 --- a/_about/notes/index.md +++ b/_about/notes/index.md @@ -14,7 +14,7 @@ redirect_from: toc: false --- -{% include section-index.html docs=site.docs %} +{% include section-index.html docs=site.about %} - The [latest](https://github.com/istio/istio/releases) Istio monthly release is {{site.data.istio.version}}. It is downloaded when the following is used(*): diff --git a/firebase.json b/firebase.json deleted file mode 100644 index e3905a5e4ffd..000000000000 --- a/firebase.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "hosting": { - "public": "_site" - } -} diff --git a/scripts/build.sh b/scripts/build.sh deleted file mode 100755 index 4fdd814f69ad..000000000000 --- a/scripts/build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# This is deprecated - moved to -# https://github.com/istio/admin-sites/blob/master/archive.istio.io/build.sh - -#example: PROJECT_ID=istiodocs-v01 RELEASE=0.1 FIREBASE_TOKEN=aabbccdd ./scripts/build.sh - -# This script builds and pushes the current branch -# to a firebase project -# The ci token produced by 'firebase login:ci' -# MUST have access to the given projects - -PROJECT_ID=${PROJECT_ID:?"PROJECT_ID required"} -FIREBASE_TOKEN=${FIREBASE_TOKEN:?"FIREBASE_TOKEN required"} -RELEASE=${RELEASE:?"RELEASE is required"} - -if [[ -z ${INDOCKER} ]];then - docker run --rm --label=jekyll --volume=$(pwd):/srv/jekyll \ - -e PROJECT_ID=$PROJECT_ID \ - -e FIREBASE_TOKEN=$FIREBASE_TOKEN \ - -e INDOCKER=true \ - -e RELEASE=${RELEASE} \ - jekyll/jekyll scripts/build.sh -else - set -e - # The directory now is /srv/jekyll inside the container - # TODO bake a new docker image with correct versions from bundler - PUBLIC=_static_site - rm -Rf ${PUBLIC} ; mkdir ${PUBLIC} - echo "baseurl: /v-${RELEASE}" > config_override.yml - jekyll build --config _config.yml,config_override.yml - mv _site "${PUBLIC}/v-${RELEASE}" - npm install -g firebase-tools - firebase use $PROJECT_ID --non-interactive --token $FIREBASE_TOKEN - firebase deploy --public ${PUBLIC} --non-interactive --token $FIREBASE_TOKEN -fi From b7e624733a054e65fa04ff6f65954433400ae015 Mon Sep 17 00:00:00 2001 From: Tao Li Date: Mon, 26 Mar 2018 16:20:34 -0700 Subject: [PATCH 055/191] Revise note to install curl (#1098) * Revise note to install curl * Revise note to install curl * Address comment --- _docs/tasks/security/mutual-tls.md | 53 ++++++++++++++++++------------ 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/_docs/tasks/security/mutual-tls.md b/_docs/tasks/security/mutual-tls.md index 0389fcf37ede..1e471990eb2e 100644 --- a/_docs/tasks/security/mutual-tls.md +++ b/_docs/tasks/security/mutual-tls.md @@ -57,18 +57,11 @@ Istio CA is up if the "AVAILABLE" column is 1. ## Testing the authentication setup When running Istio with mutual TLS authentication turned on, you can use curl in one service's -envoy to send request to other services. +Envoy to send request to other services. For example, after starting the [Bookinfo]({{home}}/docs/guides/bookinfo.html) -sample application you can ssh into the envoy container of `productpage` service, +sample application you can ssh into the Envoy container of `productpage` service, and send request to other services by curl. -Note: by default istio proxy image does not have curl installed. To try this -feature, please add --debug flag when running kube-inject, i.e., - -```bash -kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) -``` - There are several steps: 1. get the productpage pod name @@ -82,21 +75,39 @@ There are several steps: Make sure the pod is "Running". -1. ssh into the envoy container +1. ssh into the Envoy container ```bash kubectl exec -it productpage-v1-4184313719-5mxjc -c istio-proxy /bin/bash ``` 1. make sure the key/cert is in /etc/certs/ directory ```bash - ls /etc/certs/ + ls /etc/certs/ ``` ```bash cert-chain.pem key.pem root-cert.pem - ``` - - Note that cert-chain.pem is envoy's cert that needs to present to the other side. key.pem is envoy's private key paired with cert-chain.pem. root-cert.pem is the root cert to verify the other side's cert. Currently we only have one CA, so all envoys have the same root-cert.pem. - + ``` + + Note that cert-chain.pem is Envoy's cert that needs to present to the other side. key.pem is Envoy's private key paired with cert-chain.pem. root-cert.pem is the root cert to verify the other side's cert. Currently we only have one CA, so all Envoys have the same root-cert.pem. + +1. make sure 'curl' is installed by + ```bash + curl + ``` + If curl is installed, you should see something like + ```bash + curl: try 'curl --help' or 'curl --manual' for more information + ``` + + Note: by default istio proxy image does not have curl installed to make the + image compact. However, the proxy debug image does have curl, please add --debug flag during kube-inject, i.e., + + ```bash + kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) + ``` + + and start over. + 1. send requests to another service, for example, details. ```bash curl https://details:9080/details/0 -v --key /etc/certs/key.pem --cert /etc/certs/cert-chain.pem --cacert /etc/certs/root-cert.pem -k @@ -113,15 +124,15 @@ There are several steps: < x-envoy-upstream-service-time: 2 ... ``` - + The service name and port are defined [here](https://github.com/istio/istio/blob/master/samples/bookinfo/kube/bookinfo.yaml). - -Note that Istio uses [Kubernetes service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) -as service identity, which offers stronger security than service name -(refer [here]({{home}}/docs/concepts/security/mutual-tls.html#identity) for more information). + +Note that Istio uses [Kubernetes service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) +as service identity, which offers stronger security than service name +(refer [here]({{home}}/docs/concepts/security/mutual-tls.html#identity) for more information). Thus the certificates used in Istio do not have service name, which is the information that curl needs to verify server identity. As a result, we use curl option '-k' to prevent the curl client from aborting when failing to -find and verify the server name (i.e., productpage.ns.svc.cluster.local) in the certificate provided by the server. +find and verify the server name (i.e., productpage.ns.svc.cluster.local) in the certificate provided by the server. Please check secure naming [here]({{home}}/docs/concepts/security/mutual-tls.html#workflow) for more information about how the client verifies the server's identity in Istio. From 3e13d4a3bcebf32d8df04ea5d904b2457fdd82a0 Mon Sep 17 00:00:00 2001 From: mtail Date: Mon, 26 Mar 2018 17:12:01 -0700 Subject: [PATCH 056/191] Fix bug with the Copy button and proto documentation. - HTML generated from protos encode preformatted blocks with
, while HTML generated through Jekyll's markdown converter wraps an extra
around the block. The logic to insert the Copy button on preformatted was assuming the presence of this DIV. If the DIV is not present on input, we now explicitly add one which makes things work. --- js/misc.js | 15 ++++++++++++++- js/misc.min.js | 18 +----------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/js/misc.js b/js/misc.js index d720db7547b2..3dc89b6deb19 100644 --- a/js/misc.js +++ b/js/misc.js @@ -70,7 +70,20 @@ function patchDOM() { button.className = "copy copy-hide"; button.innerText = "Copy"; - pre[i].parentElement.appendChild(button); + var parent = pre[i].parentElement; + if (parent.tagName == "DIV") { + // This is the case for HTML produced from markdown through Jekyll + parent.appendChild(button); + } else { + // This is the case for HTML produced by protoc-gen-docs from proto sources + // we hackily create a DIV on the fly to make this case look like what we get + // from Jekyll + var div = document.createElement("DIV") + div.className = "highlight" + parent.insertBefore(div, pre[i]) + div.appendChild(pre[i]) + div.appendChild(button) + } } var copyCode = new Clipboard('button.copy', { diff --git a/js/misc.min.js b/js/misc.min.js index ae7a04e851d8..e7c0e262c8e6 100644 --- a/js/misc.min.js +++ b/js/misc.min.js @@ -1,20 +1,4 @@ --- --- {% include home.html %} - -"use strict" -function doSearch(){var url='{{home}}/search.html?q='+document.getElementsByName('q')[0].value;window.location.assign(url)} -$(function($){$(document).ready(function(){$('.btn-search').on('click',function(e){e.preventDefault();doSearch()});$('[data-toggle="offcanvas"]').on('click',function(){$('.row-offcanvas').toggleClass('active') - $(this).children('i.fa').toggleClass('fa-chevron-right');$(this).children('i.fa').toggleClass('fa-chevron-left')}) - $(document).on('click','.tree-toggle',function(){$(this).children('i.fa').toggleClass('fa-caret-right');$(this).children('i.fa').toggleClass('fa-caret-down');$(this).parent().children('ul.tree').toggle(200)});$(document).on('mouseenter','pre',function(){$(this).next().toggleClass("copy-show",!0) - $(this).next().toggleClass("copy-hide",!1)});$(document).on('mouseleave','pre',function(){$(this).next().toggleClass("copy-show",!1) - $(this).next().toggleClass("copy-hide",!0)});$(document).on('mouseenter','button.copy',function(){$(this).toggleClass("copy-show",!0) - $(this).toggleClass("copy-hide",!1)});$(document).on('mouseleave','button.copy',function(){$(this).toggleClass("copy-show",!1) - $(this).toggleClass("copy-hide",!0)})})}(jQuery));function patchDOM(){function attachCopyButtons(){var pre=document.getElementsByTagName('PRE');for(var i=0;iresponse.text()).then(data=>{elem.firstChild.innerText=data})} - var pre=document.getElementsByTagName('PRE');for(var i=0;i=f;f++)for(var g in document.getElementsByTagName('h'+f))if('undefined'!=typeof g.id&&''!==g.id){var h=document.createElement('i');h.className='fa fa-link';var j=document.createElement('a');j.className='header-link',j.href='#'+g.id,j.appendChild(h),g.appendChild(j)}}(),function(){for(var f in document.getElementsByTagName('a'))f.hostname&&f.hostname!=location.hostname&&f.setAttribute('target','_blank')}(),function(){function f(j,k){fetch(k).then(l=>l.text()).then(l=>{j.firstChild.innerText=l})}for(var g=document.getElementsByTagName('PRE'),h=0;h Date: Mon, 26 Mar 2018 22:00:45 -0700 Subject: [PATCH 057/191] Update reference docs. --- _docs/reference/commands/istio_ca.html | 4 + _docs/reference/commands/istioctl.html | 169 +++++++++++++++++- _docs/reference/commands/mixs.html | 10 -- .../config/istio.mixer.v1.config.client.html | 13 +- .../config/istio.networking.v1alpha3.html | 29 +++ .../istio.mixer.adapter.model.v1beta1.html | 56 +++++- scripts/grab_reference_docs.sh | 3 +- 7 files changed, 266 insertions(+), 18 deletions(-) diff --git a/_docs/reference/commands/istio_ca.html b/_docs/reference/commands/istio_ca.html index eb1cd83fb788..67cac63c91e9 100644 --- a/_docs/reference/commands/istio_ca.html +++ b/_docs/reference/commands/istio_ca.html @@ -14,6 +14,10 @@ +--append-dns-names +Append DNS names to the certificates for webhook services. + + --cert-chain <string> Path to the certificate chain file (default ``) diff --git a/_docs/reference/commands/istioctl.html b/_docs/reference/commands/istioctl.html index 64fbf7cec95f..2d0417c355fb 100644 --- a/_docs/reference/commands/istioctl.html +++ b/_docs/reference/commands/istioctl.html @@ -2,7 +2,7 @@ title: istioctl overview: Istio control interface layout: pkg-collateral-docs -number_of_entries: 14 +number_of_entries: 16 ---

Istio configuration command line utility.

@@ -435,6 +435,173 @@

istioctl deregister

+

istioctl experimental

+

Experimental commands that may be modified or deprecated

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FlagsShorthandDescription
--istioNamespace <string>-iIstio system namespace (default `istio-system`)
--kubeconfig <string>-cKubernetes configuration file (default `$KUBECONFIG else $HOME/.kube/config`)
--log_as_jsonWhether to format output as JSON or in plain console-friendly format
--log_callersInclude caller information, useful for debugging
--log_output_level <string>The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string>The path for the optional rotating log file (default ``)
--log_rotate_max_age <int>The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int>The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int>The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string>The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray>The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
--namespace <string>-nConfig namespace (default ``)
--platform <string>-pIstio host platform (default `kube`)
+

istioctl experimental convert-networking-config

+

Converts sets of v1alpha1 configs to v1alpha3 equivalents on a best effort basis. The output should be considered a starting point for your v1alpha3 configs and probably require some minor modification. Warnings will (hopefully) be generated where configs cannot be converted perfectly, or in certain edge cases. The input must be the set of configs that would be in place in an environment at a given time. This allows the command to attempt to create and merge output configs intelligently.Output configs are given the namespace and domain of the first input config so it is recommended that input configs be part of the same namespace and domain.

+
istioctl experimental convert-networking-config [flags]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FlagsShorthandDescription
--filenames <stringSlice>-fInput filename (default `[]`)
--istioNamespace <string>-iIstio system namespace (default `istio-system`)
--kubeconfig <string>-cKubernetes configuration file (default `$KUBECONFIG else $HOME/.kube/config`)
--log_as_jsonWhether to format output as JSON or in plain console-friendly format
--log_callersInclude caller information, useful for debugging
--log_output_level <string>The minimum logging level of messages to output, can be one of "debug", "info", "warn", "error", or "none" (default `info`)
--log_rotate <string>The path for the optional rotating log file (default ``)
--log_rotate_max_age <int>The maximum age in days of a log file beyond which the file is rotated (0 indicates no limit) (default `30`)
--log_rotate_max_backups <int>The maximum number of log file backups to keep before older files are deleted (0 indicates no limit) (default `1000`)
--log_rotate_max_size <int>The maximum size in megabytes of a log file beyond which the file is rotated (default `104857600`)
--log_stacktrace_level <string>The minimum logging level at which stack traces are captured, can be one of "debug", "info", "warn", "error", or "none" (default `none`)
--log_target <stringArray>The set of paths where to output the log. This can be any path as well as the special values stdout and stderr (default `[stdout]`)
--namespace <string>-nConfig namespace (default ``)
--output <string>-oOutput filename (default `-`)
--platform <string>-pIstio host platform (default `kube`)
+

Examples

+
istioctl experimental convert-networking-config -f v1alpha1/default-route.yaml -f v1alpha1/header-delay.yaml
+

istioctl gen-deploy

istioctl gen-deploy produces deployment files to run the minimum Istio control for the set of features requested by the --feature flag. If no features are provided, we create deployments for the default control plane: Pilot, Mixer, CA, and Ingress Proxies, with mTLS enabled.

istioctl gen-deploy [flags]
diff --git a/_docs/reference/commands/mixs.html b/_docs/reference/commands/mixs.html
index dd0444b49e18..c660f2971f17 100644
--- a/_docs/reference/commands/mixs.html
+++ b/_docs/reference/commands/mixs.html
@@ -108,11 +108,6 @@ 

mixs server

URL of the config store. Use k8s://path_to_kubeconfig or fs:// for file system. If path_to_kubeconfig is empty, in-cluster kubeconfig is used. (default ``) ---expressionEvalCacheSize <int> - -Number of entries in the expression cache (default `1024`) - - --livenessProbeInterval <duration> Interval of updating file for the liveness probe. (default `0s`) @@ -222,11 +217,6 @@

mixs server

URL of Zipkin collector (example: 'http://zipkin:9411/api/v1/spans'). (default ``) - ---useNewRuntime - -Use the new runtime code for processing requests. -

mixs validator

diff --git a/_docs/reference/config/istio.mixer.v1.config.client.html b/_docs/reference/config/istio.mixer.v1.config.client.html index 601e336552b8..1103495f0b7a 100644 --- a/_docs/reference/config/istio.mixer.v1.config.client.html +++ b/_docs/reference/config/istio.mixer.v1.config.client.html @@ -670,12 +670,14 @@

JWT

string

URL of the provider’s public key set to validate signature of the -JWT. See OpenID Discovery.

+JWT. See OpenID +Discovery.

Optional if the key set document can either (a) be retrieved from -OpenID Discovery -of the issuer or (b) inferred from the email domain of the issuer -(e.g. a Google service account).

+OpenID +Discovery of +the issuer or (b) inferred from the email domain of the issuer (e.g. a +Google service account).

Example: https://www.googleapis.com/oauth2/v1/certs

@@ -686,7 +688,8 @@

JWT

bool

If true, forward the entire base64 encoded JWT in the HTTP request. -If false, remove the JWT from the HTTP request and do not forward to the application.

+If false, remove the JWT from the HTTP request and do not forward to the +application.

diff --git a/_docs/reference/config/istio.networking.v1alpha3.html b/_docs/reference/config/istio.networking.v1alpha3.html index 4f8491685c6f..71b55cf6faf5 100644 --- a/_docs/reference/config/istio.networking.v1alpha3.html +++ b/_docs/reference/config/istio.networking.v1alpha3.html @@ -5,6 +5,35 @@ layout: protoc-gen-docs number_of_entries: 36 --- +

Configuration affecting traffic routing. Here are a few terms useful to define +in the context of traffic routing.

+ +

Service a unit of application behavior bound to a unique name in a +service registry. Services consist of multiple network endpoints +implemented by workload instances running on pods, containers, VMs etc.

+ +

Service versions (subsets) - In a continuous deployment scenario, for +a given service, there can be distinct subsets of instances running +different variants of the application binary. These variants are not +necessarily different API versions. They could be iterative changes to +the same service, deployed in different environments (prod, staging, +dev, etc.). Common scenarios where this occurs include A/B testing, +canary rollouts, etc. The choice of a particular version can be decided +based on various criterion (headers, url, etc.) and/or by weights +assigned to each version. Each service has a default version consisting +of all its instances.

+ +

Source - A downstream client calling a service.

+ +

Host - The address used by a client when attempting to connect to a +service.

+ +

Access model - Applications address only the destination service +(Host) without knowledge of individual service versions (subsets). The +actual choice of the version is determined by the proxy/sidecar, enabling the +application code to decouple itself from the evolution of dependent +services.

+

ConnectionPoolSettings

Connection pool settings for an upstream host. The settings apply to diff --git a/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html b/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html index 895e3751e386..43ad1f8fd4f7 100644 --- a/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html +++ b/_docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html @@ -3,7 +3,7 @@ overview: Definitions used to create adapters and templates location: https://istio.io/docs/reference/config/mixer/istio.mixer.adapter.model.v1beta1.html layout: protoc-gen-docs -number_of_entries: 22 +number_of_entries: 23 ---

This package defines the service and types used by adapter code to serve requests from Mixer. This package also defines the types that are used to create Mixer templates.

@@ -233,6 +233,60 @@

IPAddress

IPAddress is used inside templates for fields that are of ValueType “IP_ADDRESS”

+
+

Info

+
+

Info describes an adapter or a backend that wants to provide telemetry and policy functionality to Mixer as an +out of process adapter.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
namestring +

Name of the adapter. It must be an RFC 1035 compatible DNS label +matching the ^[a-z]([-a-z0-9]*[a-z0-9])?$ regular expression. +Name is used in Istio configuration, therefore it should be descriptive but short. +example: denier +Vendor adapters should use a vendor prefix. +example: mycompany-denier

+ +
descriptionstring +

User-friendly description of the adapter.

+ +
templatesstring[] +

Base64 encoded proto descriptor of all the templates the adapter wants to serve.

+ +
configstring +

Base64 encoded proto descriptor of the adapter configuration.

+ +

QuotaRequest

diff --git a/scripts/grab_reference_docs.sh b/scripts/grab_reference_docs.sh index c89ed0fab88a..922c029870fe 100755 --- a/scripts/grab_reference_docs.sh +++ b/scripts/grab_reference_docs.sh @@ -19,6 +19,7 @@ COMMAND_DIR=$ISTIO_BASE/_docs/reference/commands pushd $WORK_DIR git clone https://github.com/istio/api.git git clone https://github.com/istio/istio.git +rm -fr istio/vendor popd # Given the name of a .pb.html file, extracts the $location marker and then proceeds to @@ -36,7 +37,7 @@ locate_file() { FNP=${LOCATION:31} FN=$(echo $FNP | rev | cut -d'/' -f1 | rev) PP=$(echo $FNP | rev | cut -d'/' -f2- | rev) - sed -e 's/href="https:\/\/istio.io/href="{{site.baseurl}}/g' ${FILENAME} >_docs/${PP}/${FN} + sed -e 's/href="https:\/\/istio.io/href="{{site.baseurl}}/g' ${FILENAME} >_docs${PP}/${FN} } # Given the path and name to an Istio command, builds the command and then From e3616beb461475a86dc2c6c8d6d747082ccfca2a Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Tue, 27 Mar 2018 11:01:08 -0700 Subject: [PATCH 058/191] Fix bug that was messing up all the index pages in the site. (#1100) Fix newly broken k8s link along the way... --- _docs/setup/kubernetes/sidecar-injection.md | 7 ++++--- _includes/sort-hierarchy.html | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index cf5a54c43f22..2fad59d319fa 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -11,7 +11,8 @@ type: markdown _NOTE_: The following requires Istio 0.5.0 or greater. See [https://archive.istio.io/v0.4/docs/setup/kubernetes/sidecar-injection](https://archive.istio.io/v0.4/docs/setup/kubernetes/sidecar-injection) for Istio versions 0.4.0 or older. -_NOTE_: In previous releases, the Kubernetes initializer feature was used for automatic proxy injection. This was an Alpha feature, subject to change/removal, and not enabled by default in Kubernetes. Starting in Kubernetes 1.9 it was replaced by a beta feature called [mutating webhooks](https://kubernetes.io/docs/admin/admission-controllers/#mutatingadmissionwebhook-beta-in-19), which is now enabled by default in Kubernetes 1.9 and beyond. Starting in Istio 0.5.0 the automatic proxy injection uses mutating webhooks, and support for injection by initializer has been removed. Users who cannot uprade to Kubernetes 1.9 should use manual injection. +_NOTE_: In previous releases, the Kubernetes initializer feature was used for automatic proxy injection. This was an Alpha feature, subject to change/removal, and not enabled by default in Kubernetes. Starting in Kubernetes 1.9 it was replaced by a beta feature called +[mutating webhooks](https://kubernetes.io/docs/admin/admission-controllers/#mutatingadmissionwebhook-beta-in-19), which is now enabled by default in Kubernetes 1.9 and beyond. Starting in Istio 0.5.0 the automatic proxy injection uses mutating webhooks, and support for injection by initializer has been removed. Users who cannot uprade to Kubernetes 1.9 should use manual injection. # Pod Spec Requirements @@ -279,8 +280,8 @@ sleep-776b7bcdcd-gmvnr 1/1 Running 0 2s #### Understanding what happened -[admissionregistration.k8s.io/v1alpha1#MutatingWebhookConfiguration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#mutatingwebhookconfiguration-v1beta1-admissionregistration) -configures when the webhook is invoked by Kubernetes. The default +[admissionregistration.k8s.io/v1beta1#MutatingWebhookConfiguration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#mutatingwebhookconfiguration-v1beta1-admissionregistration) +configures when the webhook is invoked by Kubernetes. The default supplied with Istio selects pods in namespaces with label `istio-injection=enabled`. This can be changed by modifying the MutatingWebhookConfiguration in `install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml`. diff --git a/_includes/sort-hierarchy.html b/_includes/sort-hierarchy.html index c67e8f7a3800..0d786a816712 100644 --- a/_includes/sort-hierarchy.html +++ b/_includes/sort-hierarchy.html @@ -63,9 +63,10 @@ {% assign order = order | slice: 0, len | append: "#####" %} {% endif %} - + {% comment %} + Take the full doc url and replace the last component of it by the document title, and use that for collation such that + docs in the same directory end up sorted first by 'order', then by title + {% endcomment %} {% assign hackUrl = "" %} {% for i in (1..count) %} {% assign hackUrl = hackUrl | append: "/" | append: components[i] %} From 3b99a79cd1fd9a0575d687501185a67725825e48 Mon Sep 17 00:00:00 2001 From: Tao Li Date: Tue, 27 Mar 2018 11:36:33 -0700 Subject: [PATCH 059/191] Revise curl instruction in master branch (#1107) --- _docs/tasks/security/mutual-tls.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/_docs/tasks/security/mutual-tls.md b/_docs/tasks/security/mutual-tls.md index 1e471990eb2e..2837ff360f4c 100644 --- a/_docs/tasks/security/mutual-tls.md +++ b/_docs/tasks/security/mutual-tls.md @@ -99,14 +99,11 @@ There are several steps: curl: try 'curl --help' or 'curl --manual' for more information ``` - Note: by default istio proxy image does not have curl installed to make the - image compact. However, the proxy debug image does have curl, please add --debug flag during kube-inject, i.e., - + Otherwise run below command to start over ```bash kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) ``` - - and start over. + Note: istio proxy image does not have curl installed while the debug image does. The "--debug" flag in above command redeploys the service with debug image. 1. send requests to another service, for example, details. ```bash From 31a2a6d09580a87db1b8b0146e926451b23f9a23 Mon Sep 17 00:00:00 2001 From: Sakshi Goel Date: Tue, 27 Mar 2018 16:49:07 -0700 Subject: [PATCH 060/191] Update intro.md (#1110) * Update intro.md Updating info per Wencheng's suggestion * Update intro.md --- _about/intro.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_about/intro.md b/_about/intro.md index 5aee62ce880d..997be8c26275 100644 --- a/_about/intro.md +++ b/_about/intro.md @@ -26,8 +26,8 @@ rate limits and quotas. - Automatic metrics, logs, and traces for all traffic within a cluster, including cluster ingress and egress. -- Secure service-to-service authentication with strong identity assertions -between services in a cluster. +- Secure service-to-service communication in a cluster with strong +identity-based authentication and authorization. Istio can be deployed on [Kubernetes](https://kubernetes.io), [Nomad](https://nomadproject.io) with [Consul](https://www.consul.io/). We From 53c4149c403dc3026ed60e06adb3968805eb1a91 Mon Sep 17 00:00:00 2001 From: Frank Budinsky Date: Wed, 28 Mar 2018 09:28:41 -0400 Subject: [PATCH 061/191] WIP - Combined ingress/gateway task for v1alpha3 (#1094) * First pass combined ingress/gateway task * Add verifying gateway section * clarifications * fix broken link * fix build broken * address review comments --- .../traffic-management-v1alpha3/ingress.md | 522 ++++++++++++++++++ 1 file changed, 522 insertions(+) create mode 100644 _docs/tasks/traffic-management-v1alpha3/ingress.md diff --git a/_docs/tasks/traffic-management-v1alpha3/ingress.md b/_docs/tasks/traffic-management-v1alpha3/ingress.md new file mode 100644 index 000000000000..31be9bcfbb54 --- /dev/null +++ b/_docs/tasks/traffic-management-v1alpha3/ingress.md @@ -0,0 +1,522 @@ +--- +title: Control Ingress Traffic +overview: Describes how to configure Istio to expose a service outside of the service mesh. + +order: 30 + +layout: docs +type: markdown +redirect_from: /docs/tasks/ingress.html +--- +{% include home.html %} + +In a Kubernetes environment, the [Kubernetes Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) +allows users to specify services that should be exposed outside the cluster. +For traffic entering an Istio service mesh, however, an Istio-aware [ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-controllers) +is needed to allow Istio features, for example, monitoring and route rules, to be applied to traffic entering the cluster. + +Istio provides an envoy-based ingress controller that implements very limited support for standard Kubernetes `Ingress` resources +as well as full support for an alternative specification, +[Istio Gateway]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#Gateway). +Using a `Gateway` is the recommended approach for configuring ingress traffic for Istio services. +It is significantly more functional, not to mention the only option for non-Kubernetes environments. + +This task describes how to configure Istio to expose a service outside of the service mesh using either specification. + +## Before you begin + +* Setup Istio by following the instructions in the + [Installation guide]({{home}}/docs/setup/). + +* Make sure your current directory is the `istio` directory. + +* Start the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) sample, + which will be used as the destination service to be exposed externally. + + If you installed the [Istio-Initializer]({{home}}/docs/setup/kubernetes/sidecar-injection.html#automatic-sidecar-injection), do + + ```bash + kubectl apply -f samples/httpbin/httpbin.yaml + ``` + + Without the Istio-Initializer: + + ```bash + kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) + ``` + +* Generate a certificate and key that will be used to demonstrate a TLS-secured gateway + + A private key and certificate can be created for testing using [OpenSSL](https://www.openssl.org/). + + ```bash + openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=foo.bar.com" + ``` + +## Configuring ingress using an Istio Gateway resource (recommended) + +> Note: This is still a WIP and not working yet. + +An [Istio Gateway]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#Gateway) is the preferred +model for configuring ingress traffic in Istio. +An ingress `Gateway` describes a load balancer operating at the edge of the mesh receiving incoming +HTTP/TCP connections. +It configures exposed ports, protocols, etc., +but, unlike [Kubernetes Ingress Resources](https://kubernetes.io/docs/concepts/services-networking/ingress/), +does not include any traffic routing configuration. Traffic routing for ingress traffic is instead configured +using Istio routing rules, exactly in the same was as for internal service requests. + +### Configuring a Gateway + +1. Create an Istio `Gateway` + + ```bash + cat < 80:31486/TCP,443:32254/TCP 32m + ``` + + ```bash + export INGRESS_HOST=169.47.243.100:31486 + export SECURE_INGRESS_HOST=169.47.243.100:32254 + ``` + +1. Access the httpbin service with either HTTP or HTTPS using _curl_: + + ```bash + curl -I http://$INGRESS_HOST/status/200 + ``` + + ``` + HTTP/1.1 200 OK + server: envoy + date: Mon, 29 Jan 2018 04:45:49 GMT + content-type: text/html; charset=utf-8 + access-control-allow-origin: * + access-control-allow-credentials: true + content-length: 0 + x-envoy-upstream-service-time: 48 + ``` + + ```bash + curl -I -k https://$SECURE_INGRESS_HOST/status/200 + ``` + + ``` + HTTP/1.1 200 OK + server: envoy + date: Mon, 29 Jan 2018 04:45:49 GMT + content-type: text/html; charset=utf-8 + access-control-allow-origin: * + access-control-allow-credentials: true + content-length: 0 + x-envoy-upstream-service-time: 96 + ``` + +1. Access any other URL that has not been explicitly exposed. You should + see a HTTP 404 error: + + ```bash + curl -I http://$INGRESS_HOST/headers + ``` + + ``` + HTTP/1.1 404 Not Found + date: Mon, 29 Jan 2018 04:45:49 GMT + server: envoy + content-length: 0 + ``` + + ```bash + curl -I https://$SECURE_INGRESS_HOST/headers + ``` + + ``` + HTTP/1.1 404 Not Found + date: Mon, 29 Jan 2018 04:45:49 GMT + server: envoy + content-length: 0 + ``` + +## Configuring ingress using a Kubernetes Ingress resource + +An Istio `Ingress` specification is based on the standard [Kubernetes Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) +specification, with the following differences: + +1. Istio `Ingress` specification contains a `kubernetes.io/ingress.class: istio` annotation. + +2. All other annotations are ignored. + +3. Path syntax is [c++11 regex format](http://en.cppreference.com/w/cpp/regex/ecmascript) + +Note that `Ingress` traffic is not affected by routing rules configured for a backend +(i.e., an Istio `VirtualService` cannot be combined with an `Ingress` specification). +Traffic splitting, fault injection, mirroring, header match, etc., will not work for ingress traffic. +A `DestinationRule` associated with the backend service will, however, work as expected. + +The `servicePort` field in the `Ingress` specification can take a port number +(integer) or a name. The port name must follow the Istio port naming +conventions (e.g., `grpc-*`, `http2-*`, `http-*`, etc.) in order to +function properly. The name used must match the port name in the backend +service declaration. + +### Configuring simple Ingress + +1. Create a basic `Ingress` specification for the httpbin service + + ```bash + cat < 80:31486/TCP,443:32254/TCP 32m + ``` + + ```bash + export INGRESS_HOST=169.47.243.100:31486 + ``` + +1. Access the httpbin service using _curl_: + + ```bash + curl -I http://$INGRESS_HOST/status/200 + ``` + + ``` + HTTP/1.1 200 OK + server: envoy + date: Mon, 29 Jan 2018 04:45:49 GMT + content-type: text/html; charset=utf-8 + access-control-allow-origin: * + access-control-allow-credentials: true + content-length: 0 + x-envoy-upstream-service-time: 48 + ``` + +1. Access any other URL that has not been explicitly exposed. You should + see a HTTP 404 error + + ```bash + curl -I http://$INGRESS_HOST/headers + ``` + + ``` + HTTP/1.1 404 Not Found + date: Mon, 29 Jan 2018 04:45:49 GMT + server: envoy + content-length: 0 + ``` + +### Configuring secure Ingress (HTTPS) + +1. Create a Kubernetes `Secret` to hold the key/cert + + Create the secret `istio-ingress-certs` in namespace `istio-system` using `kubectl`. The Istio ingress controller + will automatically load the secret. + + > Note: the secret MUST be called `istio-ingress-certs` in the `istio-system` namespace, or it will not + be mounted and available to the Istio ingress controller. + + ```bash + kubectl create -n istio-system secret tls istio-ingress-certs --key /tmp/tls.key --cert /tmp/tls.crt + ``` + + Note that by default all service accounts in the `istio-system` namespace can access this ingress key/cert, + which risks leaking the key/cert. You can change the Role-Based Access Control (RBAC) rules to protect them. + See (Link TBD) for details. + +1. Create the `Ingress` specification for the httpbin service + + ```bash + cat < Note: Because SNI is not yet supported, Envoy currently only allows a single TLS secret in the ingress. + > That means the secretName field in ingress resource is not used. + +### Verifying secure Ingress + +1. Determine the ingress URL: + + * If your cluster is running in an environment that supports external load balancers, + use the ingress' external address: + + ```bash + kubectl get ingress secure-ingress -o wide + ``` + + ```bash + NAME HOSTS ADDRESS PORTS AGE + secure-ingress * 130.211.10.121 80 1d + ``` + + ```bash + export SECURE_INGRESS_HOST=130.211.10.121 + ``` + + * If load balancers are not supported, use the ingress controller pod's hostIP: + + ```bash + kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' + ``` + + ```bash + 169.47.243.100 + ``` + + along with the istio-ingress service's nodePort for port 443: + + ```bash + kubectl -n istio-system get svc istio-ingress + ``` + + ```bash + NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE + istio-ingress 10.10.10.155 80:31486/TCP,443:32254/TCP 32m + ``` + + ```bash + export SECURE_INGRESS_HOST=169.47.243.100:32254 + ``` + +1. Access the httpbin service using _curl_: + + ```bash + curl -I -k https://$SECURE_INGRESS_HOST/status/200 + ``` + + ``` + HTTP/1.1 200 OK + server: envoy + date: Mon, 29 Jan 2018 04:45:49 GMT + content-type: text/html; charset=utf-8 + access-control-allow-origin: * + access-control-allow-credentials: true + content-length: 0 + x-envoy-upstream-service-time: 96 + ``` + +1. Access any other URL that has not been explicitly exposed. You should + see a HTTP 404 error + + ```bash + curl -I -k https://$SECURE_INGRESS_HOST/headers + ``` + + ``` + HTTP/1.1 404 Not Found + date: Mon, 29 Jan 2018 04:45:49 GMT + server: envoy + content-length: 0 + ``` + +## Understanding what happened + +`Gateway` or `Ingress` configuration resources allow external traffic to enter the +Istio service mesh and make the traffic management and policy features of Istio +available for edge services. + +In the preceding steps we created a service inside the Istio service mesh +and showed how to expose both HTTP and HTTPS endpoints of the service to +external traffic. Using an Istio `Gateway` provides significantly more functionality +and is recommended. Using a Kubernetes `Ingress`, however, is also supported +and may be especially useful when moving existing Kubernetes applications to Istio. + +## Cleanup + +1. Remove the `Gateway` configuration. + + ```bash + kubectl delete gateway httpbin-gateway + ``` + +1. Remove the `Ingress` configuration. + + ```bash + kubectl delete ingress simple-ingress secure-ingress + ``` + +1. Remove the routing rule and secret. + + ```bash + istioctl delete virtualservice httpbin + kubectl delete -n istio-system secret istio-ingress-certs + ``` + +1. Shutdown the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) service. + + ```bash + kubectl delete -f samples/httpbin/httpbin.yaml + ``` + +## What's next + +* Learn more about [Ingress Control](https://kubernetes.io/docs/concepts/services-networking/ingress/). + +* Learn more about [Traffic Routing]({{home}}/docs/reference/config/istio.networking.v1alpha3.html). From a2b27b62221a1e7142fea2cb153f5c00c31d953b Mon Sep 17 00:00:00 2001 From: jeff martinez Date: Wed, 28 Mar 2018 06:29:43 -0700 Subject: [PATCH 062/191] fix small grammar issue (#1112) --- _docs/concepts/what-is-istio/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/concepts/what-is-istio/overview.md b/_docs/concepts/what-is-istio/overview.md index 7919029982b3..f2d575c087ba 100644 --- a/_docs/concepts/what-is-istio/overview.md +++ b/_docs/concepts/what-is-istio/overview.md @@ -87,7 +87,7 @@ evaluation can be found in [Mixer Configuration]({{home}}/docs/concepts/policy-a [Pilot]({{home}}/docs/concepts/traffic-management/pilot.html) provides service discovery for the Envoy sidecars, traffic management capabilities for intelligent routing (e.g., A/B tests, canary deployments, etc.), -and resiliency (timeouts, retries, circuit breakers, etc.). It converts a +and resiliency (timeouts, retries, circuit breakers, etc.). It converts high level routing rules that control traffic behavior into Envoy-specific configurations, and propagates them to the sidecars at runtime. Pilot abstracts platform-specifc service discovery mechanisms and synthesizes From 33bdfdc942964978959b51bb059dc2c1295e33ef Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Wed, 28 Mar 2018 09:00:14 -0700 Subject: [PATCH 063/191] Fix a few bugs and add a feature. (#1111) - Link injection for document headers has been broken for a while due to my misunderstanding of the "for in" syntax in JavaScript. This now works as expected. - Same problem also prevented the feature that causes every link to outside of istio.io to be opened in a separate window. This now works as intended. - Made the gear dropdown menu be right-aligned such that it doesn't go off-screen on portrait mode tablets. - Stop importing Popper.js since it's only needed for dropdown menus that aren't in the nav bar. Ours is in a nav bar... - Added link injection for
terms, which makes it easy to create links to individual glossary entries. --- _includes/header.html | 2 +- _layouts/base.html | 1 - _sass/base/_common.scss | 3 ++- js/misc.js | 44 ++++++++++++++++++++++++++++++----------- js/misc.min.js | 2 +- 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/_includes/header.html b/_includes/header.html index 27ac7dc91d5e..f84245a60ea4 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -48,7 +48,7 @@ -

DestinationRule

-

# Overview

-

DestinationRule defines policies that apply to traffic intended for a - service after routing has occurred. These rules specify configuration - for load balancing, connection pool size from the sidecar, and outlier - detection settings to detect and evict unhealthy hosts from the load - balancing pool. For example, a simple load balancing policy for the - ratings service would look as follows:

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: DestinationRule
- metadata:
-   name: bookinfo-ratings
- spec:
-   host: ratings.prod.svc.cluster.local
-   trafficPolicy:
-     loadBalancer:
-       simple: LEAST_CONN
+service after routing has occurred. These rules specify configuration
+for load balancing, connection pool size from the sidecar, and outlier
+detection settings to detect and evict unhealthy hosts from the load
+balancing pool. For example, a simple load balancing policy for the
+ratings service would look as follows:

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: bookinfo-ratings
+spec:
+  host: ratings.prod.svc.cluster.local
+  trafficPolicy:
+    loadBalancer:
+      simple: LEAST_CONN
 

Version specific policies can be specified by defining a named - subset and overriding the settings specified at the service level. The - following rule uses a round robin load balancing policy for all traffic - going to a subset named testversion that is composed of endpoints (e.g., - pods) with labels (version:v3).

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: DestinationRule
- metadata:
-   name: bookinfo-ratings
- spec:
-   host: ratings.prod.svc.cluster.local
-   trafficPolicy:
-     loadBalancer:
-       simple: LEAST_CONN
-   subsets:
-   - name: testversion
-     labels:
-       version: v3
-     trafficPolicy:
-       loadBalancer:
-         simple: ROUND_ROBIN
+subset and overriding the settings specified at the service level. The
+following rule uses a round robin load balancing policy for all traffic
+going to a subset named testversion that is composed of endpoints (e.g.,
+pods) with labels (version:v3).

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: bookinfo-ratings
+spec:
+  host: ratings.prod.svc.cluster.local
+  trafficPolicy:
+    loadBalancer:
+      simple: LEAST_CONN
+  subsets:
+  - name: testversion
+    labels:
+      version: v3
+    trafficPolicy:
+      loadBalancer:
+        simple: ROUND_ROBIN
 

Note: Policies specified for subsets will not take effect until - a route rule explicitly sends traffic to this subset.

+a route rule explicitly sends traffic to this subset.

+ +

Traffic policies can be customized to specific ports as well. The +following rule uses the least connection load balancing policy for all +traffic to port 80, while uses a round robin load balancing setting for +traffic to the port 9080.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: bookinfo-ratings-port
+spec:
+  host: ratings.prod.svc.cluster.local
+  trafficPolicy: # Apply to all ports
+    portLevelSettings:
+    - port:
+        number: 80
+      loadBalancer:
+        simple: LEAST_CONN
+    - port:
+        number: 9080
+      loadBalancer:
+        simple: ROUND_ROBIN
+
@@ -519,7 +542,7 @@

DestinationRule

REQUIRED. The name of a service from the service registry. Service names are looked up from the platform’s service registry (e.g., Kubernetes services, Consul services, etc.) and from the hosts -declared by ExternalServices. Rules defined for +declared by ServiceEntries. Rules defined for services that do not exist in the service registry will be ignored.

Note for Kubernetes users: When short names are used (e.g. “reviews” @@ -649,297 +672,6 @@

DestinationWeight

If there is only destination in a rule, the weight value is assumed to be 100.

- - - -
-
-

ExternalService

-
-

# Overview

- -

ExternalService describes the endpoints, ports and protocols of a - white-listed set of mesh-external domains and IP blocks that services in - the mesh are allowed to access.

- -

For example, the following ExternalService configuration describes the - set of services at https://example.com to be accessed internally over - plaintext http (i.e. http://example.com:443), with the sidecar originating - TLS.

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: ExternalService
- metadata:
-   name: external-svc-example
- spec:
-   hosts:
-   - example.com
-   ports:
-   - number: 443
-     name: example-http
-     protocol: HTTP # not HTTPS.
-   discovery: DNS
-
- -

and a DestinationRule to initiate TLS connections to the external service.

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: DestinationRule
- metadata:
-   name: tls-example
- spec:
-   name: example.com
-   trafficPolicy:
-     tls:
-       mode: SIMPLE # initiates HTTPS when talking to example.com
-
- -

The following specification specifies a static set of backend nodes for - a MongoDB cluster behind a set of virtual IPs, and sets up a - DestinationRule to initiate mTLS connections upstream.

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: ExternalService
- metadata:
-   name: external-svc-mongocluster
- spec:
-   hosts:
-   - 192.192.192.192/24
-   ports:
-   - number: 27018
-     name: mongodb
-     protocol: MONGO
-   discovery: STATIC
-   endpoints:
-   - address: 2.2.2.2
-   - address: 3.3.3.3
-
- -

and the associated DestinationRule

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: DestinationRule
- metadata:
-   name: mtls-mongocluster
- spec:
-   name: 192.192.192.192/24
-   trafficPolicy:
-     tls:
-       mode: MUTUAL
-       clientCertificate: /etc/certs/myclientcert.pem
-       privateKey: /etc/certs/client_private_key.pem
-       caCertificates: /etc/certs/rootcacerts.pem
-
- -

The following example demonstrates the use of wildcards in the hosts. If - the connection has to be routed to the IP address requested by the - application (i.e. application resolves DNS and attempts to connect to a - specific IP), the discovery mode must be set to NONE.

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: ExternalService
- metadata:
-   name: external-svc-wildcard-example
- spec:
-   hosts:
-   - "*.bar.com"
-   ports:
-   - number: 80
-     name: http
-     protocol: HTTP
-   discovery: NONE
-
- -

For HTTP based services, it is possible to create a VirtualService - backed by multiple DNS addressible endpoints. In such a scenario, the - application can use the HTTP_PROXY environment variable to transparently - reroute API calls for the VirtualService to a chosen backend. For - example, the following configuration creates a non-existent service - called foo.bar.com backed by three domains: us.foo.bar.com:8443, - uk.foo.bar.com:9443, and in.foo.bar.com:7443

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: ExternalService
- metadata:
-   name: external-svc-dns
- spec:
-   hosts:
-   - foo.bar.com
-   ports:
-   - number: 443
-     name: https
-     protocol: HTTP
-   discovery: DNS
-   endpoints:
-   - address: us.foo.bar.com
-     ports:
-       https: 8443
-   - address: uk.foo.bar.com
-     ports:
-       https: 9443
-   - address: in.foo.bar.com
-     ports:
-       https: 7443
-
- -

and a DestinationRule to initiate TLS connections to the ExternalService.

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: DestinationRule
- metadata:
-   name: tls-foobar
- spec:
-   name: foo.bar.com
-   trafficPolicy:
-     tls:
-       mode: SIMPLE # initiates HTTPS
-
- -

With HTTP_PROXY=http://localhost:443, calls from the application to - http://foo.bar.com will be upgraded to HTTPS and load balanced across - the three domains specified above. In other words, a call to - http://foo.bar.com/baz would be translated to - https://uk.foo.bar.com/baz.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldTypeDescription
hostsstring[] -

REQUIRED. The hosts associated with the ExternalService. Could be a -DNS name with wildcard prefix or a CIDR prefix. Note that the hosts -field applies to all protocols. DNS names in hosts will be ignored if -the application accesses the service over non-HTTP protocols such as -mongo/opaque TCP/even HTTPS. In such scenarios, the port on which the -external service is being accessed must not be shared by any other -service in the mesh. In other words, the sidecar will behave as a -simple TCP proxy, forwarding incoming traffic on a specified port to -the specified destination endpoint IP/host.

- -
portsPort[] -

REQUIRED. The ports associated with the external service.

- -
discoveryExternalService.Discovery -

Service discovery mode for the hosts. If not set, Istio will attempt -to infer the discovery mode based on the value of hosts and endpoints.

- -
endpointsExternalService.Endpoint[] -

One or more endpoints associated with the service.

- -
-
-

ExternalService.Discovery

-
-

Different ways of discovering the IP addresses associated with the -service.

- - - - - - - - - - - - - - - - - - - - - - -
NameDescription
NONE -

Assume that incoming connections have already been resolved (to a -specific destination IP address). Such connections are typically -routed via the proxy using mechanisms such as IP table REDIRECT/ -eBPF. After performing any routing related transformations, the -proxy will forward the connection to the IP address to which the -connection was bound.

- -
STATIC -

Use the IP addresses specified in endpoints (See below) as the -backing nodes associated with the ExternalService.

- -
DNS -

Attempt to resolve the DNS address during request processing. If no -endpoints are specified, the proxy will resolve the DNS address -specified in the hosts field, if wildcards are not used. If -endpoints are specified, the DNS addresses specified in the -endpoints will be resolved to determine the destination IP address.

- -
-
-

ExternalService.Endpoint

-
-

Endpoint defines a network address (IP or hostname) associated with -the external service.

- - - - - - - - - - - - - - - - - - - - - - - - @@ -947,133 +679,131 @@

ExternalService.Endpoint

Gateway

-

# Overview

-

Gateway describes a load balancer operating at the edge of the mesh - receiving incoming or outgoing HTTP/TCP connections. The specification - describes a set of ports that should be exposed, the type of protocol to - use, SNI configuration for the load balancer, etc.

+receiving incoming or outgoing HTTP/TCP connections. The specification +describes a set of ports that should be exposed, the type of protocol to +use, SNI configuration for the load balancer, etc.

For example, the following Gateway configuration sets up a proxy to act - as a load balancer exposing port 80 and 9080 (http), 443 (https), and - port 2379 (TCP) for ingress. The gateway will be applied to the proxy - running on a pod with labels app: my-gateway-controller. While Istio - will configure the proxy to listen on these ports, it is the - responsibility of the user to ensure that external traffic to these - ports are allowed into the mesh.

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: Gateway
- metadata:
-   name: my-gateway
- spec:
-   selector:
-     app: my-gatweway-controller
-   servers:
-   - port:
-       number: 80
-       name: http
-       protocol: HTTP
-     hosts:
-     - uk.bookinfo.com
-     - eu.bookinfo.com
-     tls:
-       httpsRedirect: true # sends 302 redirect for http requests
-   - port:
-       number: 443
-       name: https
-       protocol: HTTPS
-     hosts:
-     - uk.bookinfo.com
-     - eu.bookinfo.com
-     tls:
-       mode: SIMPLE #enables HTTPS on this port
-       serverCertificate: /etc/certs/servercert.pem
-       privateKey: /etc/certs/privatekey.pem
-   - port:
-       number: 9080
-       name: http-wildcard
-       protocol: HTTP
-     # no hosts implies wildcard match
-   - port:
-       number: 2379 #to expose internal service via external port 2379
-       name: mongo
-       protocol: MONGO
+as a load balancer exposing port 80 and 9080 (http), 443 (https), and
+port 2379 (TCP) for ingress.  The gateway will be applied to the proxy
+running on a pod with labels app: my-gateway-controller. While Istio
+will configure the proxy to listen on these ports, it is the
+responsibility of the user to ensure that external traffic to these
+ports are allowed into the mesh.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: my-gateway
+spec:
+  selector:
+    app: my-gatweway-controller
+  servers:
+  - port:
+      number: 80
+      name: http
+      protocol: HTTP
+    hosts:
+    - uk.bookinfo.com
+    - eu.bookinfo.com
+    tls:
+      httpsRedirect: true # sends 302 redirect for http requests
+  - port:
+      number: 443
+      name: https
+      protocol: HTTPS
+    hosts:
+    - uk.bookinfo.com
+    - eu.bookinfo.com
+    tls:
+      mode: SIMPLE #enables HTTPS on this port
+      serverCertificate: /etc/certs/servercert.pem
+      privateKey: /etc/certs/privatekey.pem
+  - port:
+      number: 9080
+      name: http-wildcard
+      protocol: HTTP
+    # no hosts implies wildcard match
+  - port:
+      number: 2379 #to expose internal service via external port 2379
+      name: mongo
+      protocol: MONGO
 

The Gateway specification above describes the L4-L6 properties of a load - balancer. A VirtualService can then be bound to a gateway to control - the forwarding of traffic arriving at a particular host or gateway port.

+balancer. A VirtualService can then be bound to a gateway to control +the forwarding of traffic arriving at a particular host or gateway port.

For example, the following VirtualService splits traffic for - “https://uk.bookinfo.com/reviews”, “https://eu.bookinfo.com/reviews”, - “http://uk.bookinfo.com:9080/reviews”, - “http://eu.bookinfo.com:9080/reviews” into two versions (prod and qa) of - an internal reviews service on port 9080. In addition, requests - containing the cookie “user: dev-123” will be sent to special port 7777 - in the qa version. The same rule is also applicable inside the mesh for - requests to the r”eviews.prod.svc.cluster.local” service. This rule is - applicable across ports 443, 9080. Note that “http://uk.bookinfo.com” - gets redirected to “https://uk.bookinfo.com” (i.e. 80 redirects to 443).

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: VirtualService
- metadata:
-   name: bookinfo-rule
- spec:
-   hosts:
-   - reviews.prod.svc.cluster.local
-   - uk.bookinfo.com
-   - eu.bookinfo.com
-   gateways:
-   - my-gateway
-   - mesh # applies to all the sidecars in the mesh
-   http:
-   - match:
-     - headers:
-         cookie:
-           user: dev-123
-     route:
-     - destination:
-         port:
-           number: 7777
-         name: reviews.qa.svc.cluster.local
-   - match:
-       uri:
-         prefix: /reviews/
-     route:
-     - destination:
-         port:
-           number: 9080 # can be omitted if its the only port for reviews
-         name: reviews.prod.svc.cluster.local
-       weight: 80
-     - destination:
-         name: reviews.qa.svc.cluster.local
-       weight: 20
+“https://uk.bookinfo.com/reviews”, “https://eu.bookinfo.com/reviews”,
+“http://uk.bookinfo.com:9080/reviews”,
+“http://eu.bookinfo.com:9080/reviews” into two versions (prod and qa) of
+an internal reviews service on port 9080. In addition, requests
+containing the cookie “user: dev-123” will be sent to special port 7777
+in the qa version. The same rule is also applicable inside the mesh for
+requests to the r”eviews.prod.svc.cluster.local” service. This rule is
+applicable across ports 443, 9080. Note that “http://uk.bookinfo.com”
+gets redirected to “https://uk.bookinfo.com” (i.e. 80 redirects to 443).

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: bookinfo-rule
+spec:
+  hosts:
+  - reviews.prod.svc.cluster.local
+  - uk.bookinfo.com
+  - eu.bookinfo.com
+  gateways:
+  - my-gateway
+  - mesh # applies to all the sidecars in the mesh
+  http:
+  - match:
+    - headers:
+        cookie:
+          user: dev-123
+    route:
+    - destination:
+        port:
+          number: 7777
+        name: reviews.qa.svc.cluster.local
+  - match:
+      uri:
+        prefix: /reviews/
+    route:
+    - destination:
+        port:
+          number: 9080 # can be omitted if its the only port for reviews
+        name: reviews.prod.svc.cluster.local
+      weight: 80
+    - destination:
+        name: reviews.qa.svc.cluster.local
+      weight: 20
 

The following VirtualService forwards traffic arriving at (external) - port 27017 from “172.17.16.0/24” subnet to internal Mongo server on port - 5555. This rule is not applicable internally in the mesh as the gateway - list omits the reserved name mesh.

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: VirtualService
- metadata:
-   name: bookinfo-Mongo
- spec:
-   hosts:
-   - mongosvr.prod.svc.cluster.local #name of internal Mongo service
-   gateways:
-   - my-gateway
-   tcp:
-   - match:
-     - port:
-         number: 27017
-       sourceSubnet: "172.17.16.0/24"
-     route:
-     - destination:
-         name: mongo.prod.svc.cluster.local
+port 27017 from “172.17.16.0/24” subnet to internal Mongo server on port
+5555. This rule is not applicable internally in the mesh as the gateway
+list omits the reserved name mesh.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: bookinfo-Mongo
+spec:
+  hosts:
+  - mongosvr.prod.svc.cluster.local #name of internal Mongo service
+  gateways:
+  - my-gateway
+  tcp:
+  - match:
+    - port:
+        number: 27017
+      sourceSubnet: "172.17.16.0/24"
+    route:
+    - destination:
+        name: mongo.prod.svc.cluster.local
 
FieldTypeDescription
addressstring -

REQUIRED: Address associated with the network endpoint without the -port ( IP or fully qualified domain name without wildcards).

- -
portsmap<string, uint32> -

Set of ports associated with the endpoint. The ports must be -associated with a port name that was declared as part of the -service.

- -
labelsmap<string, string> -

One or more labels associated with the endpoint.

-
@@ -2368,33 +2098,373 @@

Server.TLSOptions.TLSmode

-

StringMatch

+

ServiceEntry

-

Describes how to match a given string in HTTP headers. Match is -case-sensitive.

+

ServiceEntry enables adding additional entries into Istio’s internal +service registry, so that auto-discovered services in the mesh can +access/route to these manually specified services. A service entry +describes the properties of a service (DNS name, VIPs ,ports, protocols, +endpoints). These services could be external to the mesh (e.g., web +APIs) or mesh-internal services that are not part of the platform’s +service registry (e.g., a set of VMs talking to services in Kubernetes).

+ +

The following configuration adds a set of MongoDB instances running on +unmanaged VMs to Istio’s registry, so that these services can be treated +as any other service in the mesh. The associated DestinationRule is used +to initiate mTLS connections to the database instances.

- - - - - - - - - - - - - - - - - -
FieldTypeDescription
exactstring (oneof) -

exact string match

+
apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: external-svc-mongocluster
+spec:
+  hosts:
+  - mymongodb.somedomain # not used
+  addresses:
+  - 192.192.192.192/24 # VIPs
+  ports:
+  - number: 27018
+    name: mongodb
+    protocol: MONGO
+  location: MESH_INTERNAL
+  resolution: STATIC
+  endpoints:
+  - address: 2.2.2.2
+  - address: 3.3.3.3
+
-
prefixstring (oneof) -

prefix-based match

+

and the associated DestinationRule

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: mtls-mongocluster
+spec:
+  host: mymongodb.somedomain
+  trafficPolicy:
+    tls:
+      mode: MUTUAL
+      clientCertificate: /etc/certs/myclientcert.pem
+      privateKey: /etc/certs/client_private_key.pem
+      caCertificates: /etc/certs/rootcacerts.pem
+
+ +

The following example demonstrates the use of wildcards in the hosts for +external services. If the connection has to be routed to the IP address +requested by the application (i.e. application resolves DNS and attempts +to connect to a specific IP), the discovery mode must be set to NONE.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: external-svc-wildcard-example
+spec:
+  hosts:
+  - "*.bar.com"
+  location: MESH_EXTERNAL
+  ports:
+  - number: 80
+    name: http
+    protocol: HTTP
+  resolution: NONE
+
+ +

For HTTP based services, it is possible to create a VirtualService +backed by multiple DNS addressable endpoints. In such a scenario, the +application can use the HTTP_PROXY environment variable to transparently +reroute API calls for the VirtualService to a chosen backend. For +example, the following configuration creates a non-existent external +service called foo.bar.com backed by three domains: us.foo.bar.com:8443, +uk.foo.bar.com:9443, and in.foo.bar.com:7443

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: external-svc-dns
+spec:
+  hosts:
+  - foo.bar.com
+  location: MESH_EXTERNAL
+  ports:
+  - number: 443
+    name: https
+    protocol: HTTP
+  resolution: DNS
+  endpoints:
+  - address: us.foo.bar.com
+    ports:
+      https: 8443
+  - address: uk.foo.bar.com
+    ports:
+      https: 9443
+  - address: in.foo.bar.com
+    ports:
+      https: 7443
+
+ +

and a DestinationRule to initiate TLS connections to the ServiceEntry.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: tls-foobar
+spec:
+  host: foo.bar.com
+  trafficPolicy:
+    tls:
+      mode: SIMPLE # initiates HTTPS
+
+ +

With HTTP_PROXY=http://localhost:443, calls from the application to +http://foo.bar.com will be upgraded to HTTPS and load balanced across +the three domains specified above. In other words, a call to +http://foo.bar.com/baz would be translated to +https://uk.foo.bar.com/baz.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
hostsstring[] +

REQUIRED. The hosts associated with the ServiceEntry. Could be a DNS +name with wildcard prefix (external services only). DNS names in hosts +will be ignored if the application accesses the service over non-HTTP +protocols such as mongo/opaque TCP/even HTTPS. In such scenarios, the +IP addresses specified in the Addresses field or the port will be used +to uniquely identify the destination.

+ +
addressesstring[] +

The virtual IP addresses associated with the service. Could be CIDR +prefix. For HTTP services, the addresses field will be ignored and +the destination will be identified based on the HTTP Host/Authority +header. For non-HTTP protocols such as mongo/opaque TCP/even HTTPS, +the hosts will be ignored. If one or more IP addresses are specified, +the incoming traffic will be idenfified as belonging to this service +if the destination IP matches the IP/CIDRs specified in the addresses +field. If the Addresses field is empty, traffic will be identified +solely based on the destination port. In such scenarios, the port on +which the service is being accessed must not be shared by any other +service in the mesh. In other words, the sidecar will behave as a +simple TCP proxy, forwarding incoming traffic on a specified port to +the specified destination endpoint IP/host.

+ +
portsPort[] +

REQUIRED. The ports associated with the external service.

+ +
locationServiceEntry.Location +

Specify whether the service should be considered external to the mesh +or part of the mesh.

+ +
resolutionServiceEntry.Resolution +

Service discovery mode for the hosts. If not set, Istio will attempt +to infer the discovery mode based on the value of hosts and endpoints.

+ +
endpointsServiceEntry.Endpoint[] +

One or more endpoints associated with the service.

+ +
+ +

ServiceEntry.Endpoint

+
+

Endpoint defines a network address (IP or hostname) associated with +the mesh service.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
addressstring +

REQUIRED: Address associated with the network endpoint without the +port ( IP or fully qualified domain name without wildcards). Domain +names can be used if and only if the resolution is set to DNS.

+ +
portsmap<string, uint32> +

Set of ports associated with the endpoint. The ports must be +associated with a port name that was declared as part of the +service.

+ +
labelsmap<string, string> +

One or more labels associated with the endpoint.

+ +
+
+

ServiceEntry.Location

+
+

Location specifies whether the service is part of Istio mesh or +outside the mesh. Location determines the behavior of several +features, such as service-to-service mTLS authentication, policy +enforcement, etc. When communicating with services outside the mesh, +Istio’s mTLS authentication is disabled, and policy enforcement is +performed on the client-side as opposed to server-side.

+ + + + + + + + + + + + + + + + + + +
NameDescription
MESH_EXTERNAL +

Signifies that the service is external to the mesh. Typically used +to indicate external services consumed through APIs.

+ +
MESH_INTERNAL +

Signifies that the service is part of the mesh. Typically used to +indicate services added explicitly as part of expanding the service +mesh to include unmanaged infrastructure (e.g., VMs added to a +Kubernetes based service mesh).

+ +
+
+

ServiceEntry.Resolution

+
+

Resolution determines how the proxy will resolve the IP addresses of +the network endpoints associated with the service, so that it can +route to one of them. The resolution mode specified here has no impact +on how the application resolves the IP address associated with the +service. The application may still have to use DNS to resolve the +service to an IP so that the outbound traffic can be captured by the +Proxy. Alternatively, for HTTP services, the application could +directly communicate with the proxy (e.g., by setting HTTP_PROXY) to +talk to these services.

+ + + + + + + + + + + + + + + + + + + + + + +
NameDescription
NONE +

Assume that incoming connections have already been resolved (to a +specific destination IP address). Such connections are typically +routed via the proxy using mechanisms such as IP table REDIRECT/ +eBPF. After performing any routing related transformations, the +proxy will forward the connection to the IP address to which the +connection was bound.

+ +
STATIC +

Use the static IP addresses specified in endpoints (see below) as the +backing instances associated with the service.

+ +
DNS +

Attempt to resolve the IP address by querying the ambient DNS, +during request processing. If no endpoints are specified, the proxy +will resolve the DNS address specified in the hosts field, if +wildcards are not used. If endpoints are specified, the DNS +addresses specified in the endpoints will be resolved to determine +the destination IP address.

+ +
+
+

StringMatch

+
+

Describes how to match a given string in HTTP headers. Match is +case-sensitive.

+ + + + + + + + + + + + + + + + + + + @@ -2684,8 +2754,8 @@

TLSSettings.TLSmode

TrafficPolicy

-

Traffic policies to apply for a specific destination. See -DestinationRule for examples.

+

Traffic policies to apply for a specific destination, across all +destination ports. See DestinationRule for examples.

FieldTypeDescription
exactstring (oneof) +

exact string match

+ +
prefixstring (oneof) +

prefix-based match

@@ -2726,70 +2796,142 @@

TrafficPolicy

+ + + + +

TLS related settings for connections to the upstream service.

+
portLevelSettingsTrafficPolicy.PortTrafficPolicy[] +

Traffic policies specific to individual ports. Note that port level +settings will override the destination-level settings. Traffic +settings specified at the destination-level will not be inherited when +overridden by port-level settings, i.e. default values will be applied +to fields omitted in port-level traffic policies.

+
-

VirtualService

+

TrafficPolicy.PortTrafficPolicy

-

# Overview

+

Traffic policies that apply to specific ports of the service

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
portPortSelector +

Specifies the port name or number of a port on the destination service +on which this policy is being applied.

+ +

Names must comply with DNS label syntax (rfc1035) and therefore cannot +collide with numbers. If there are multiple ports on a service with +the same protocol the names should be of the form -.

+ +
loadBalancerLoadBalancerSettings +

Settings controlling the load balancer algorithms.

+ +
connectionPoolConnectionPoolSettings +

Settings controlling the volume of connections to an upstream service

+
outlierDetectionOutlierDetection +

Settings controlling eviction of unhealthy hosts from the load balancing pool

+ +
tlsTLSSettings +

TLS related settings for connections to the upstream service.

+ +
+
+

VirtualService

+

A VirtualService defines a set of traffic routing rules to apply when a host is - addressed. Each routing rule defines matching criteria for traffic of a specific - protocol. If the traffic is matched, then it is sent to a named destination service - (or subset/version of it) defined in the registry.

+addressed. Each routing rule defines matching criteria for traffic of a specific +protocol. If the traffic is matched, then it is sent to a named destination service +(or subset/version of it) defined in the registry.

The source of traffic can also be matched in a routing rule. This allows routing - to be customized for specific client contexts.

+to be customized for specific client contexts.

The following example on Kubernetes, routes all HTTP traffic by default to - pods of the reviews service with label “version: v1”. In addition, - HTTP requests containing /wpcatalog/, /consumercatalog/ url prefixes will - be rewritten to /newcatalog and sent to pods with label “version: v2”.

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: VirtualService
- metadata:
-   name: reviews-route
- spec:
-   hosts:
-   - reviews.prod.svc.cluster.local
-   http:
-   - match:
-     - uri:
-         prefix: "/wpcatalog"
-     - uri:
-         prefix: "/consumercatalog"
-     rewrite:
-       uri: "/newcatalog"
-     route:
-     - destination:
-         host: reviews.prod.svc.cluster.local
-         subset: v2
-   - route:
-     - destination:
-         host: reviews.prod.svc.cluster.local
-         subset: v1
+pods of the reviews service with label “version: v1”. In addition,
+HTTP requests containing /wpcatalog/, /consumercatalog/ url prefixes will
+be rewritten to /newcatalog and sent to pods with label “version: v2”.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews-route
+spec:
+  hosts:
+  - reviews.prod.svc.cluster.local
+  http:
+  - match:
+    - uri:
+        prefix: "/wpcatalog"
+    - uri:
+        prefix: "/consumercatalog"
+    rewrite:
+      uri: "/newcatalog"
+    route:
+    - destination:
+        host: reviews.prod.svc.cluster.local
+        subset: v2
+  - route:
+    - destination:
+        host: reviews.prod.svc.cluster.local
+        subset: v1
 

A subset/version of a route destination is identified with a reference - to a named service subset which must be declared in a corresponding - DestinationRule.

- -
 apiVersion: networking.istio.io/v1alpha3
- kind: DestinationRule
- metadata:
-   name: reviews-destination
- spec:
-   host: reviews.prod.svc.cluster.local
-   subsets:
-   - name: v1
-     labels:
-       version: v1
-   - name: v2
-     labels:
-       version: v2
+to a named service subset which must be declared in a corresponding
+DestinationRule.

+ +
apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: reviews-destination
+spec:
+  host: reviews.prod.svc.cluster.local
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
 
diff --git a/_docs/reference/config/istio.rbac.v1alpha1.html b/_docs/reference/config/istio.rbac.v1alpha1.html index d25b45bc6966..1c1ad71c5831 100644 --- a/_docs/reference/config/istio.rbac.v1alpha1.html +++ b/_docs/reference/config/istio.rbac.v1alpha1.html @@ -3,7 +3,7 @@ overview: Configuration for Role Based Access Control location: https://istio.io/docs/reference/config/istio.rbac.v1alpha1.html layout: protoc-gen-docs -number_of_entries: 6 +number_of_entries: 9 ---

Istio RBAC (Role Based Access Control) defines ServiceRole and ServiceRoleBinding objects.

@@ -185,6 +185,142 @@

AccessRule.Constraint

“v1alpha2” (exact match), or “v1” (prefix match), or “alpha2” (suffix match).

+ + + +
+
+

RbacConfig

+
+

RbacConfig defines the global config to control Istio RBAC behavior. +This Custom Resource is a singleton where only one Custom Resource should be created globally in +the mesh and the namespace should be the same to other Istio components, which usually is istio-system. +Note: This is enforced in both istioctl and server side, new Custom Resource will be rejected if found any +existing one, the user should either delete the existing one or change the existing one directly.

+ +

Below is an example of RbacConfig object “istio-rbac-config” which enables Istio RBAC for all +services in the default namespace.

+ +
apiVersion: "config.istio.io/v1alpha1"
+kind: RbacConfig
+metadata:
+  name: istio-rbac-config
+  namespace: istio-system
+spec:
+  mode: ON_WITH_INCLUSION
+  inclusion:
+    namespaces: [ "default" ]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldTypeDescription
modeRbacConfig.Mode +

Istio RBAC mode.

+ +
inclusionRbacConfig.Target +

A list of services or namespaces that should be enforced by Istio RBAC policies. Note: This field have +effect only when mode is ONWITHINCLUSION and will be ignored for any other modes.

+ +
exclusionRbacConfig.Target +

A list of services or namespaces that should not be enforced by Istio RBAC policies. Note: This field have +effect only when mode is ONWITHEXCLUSION and will be ignored for any other modes.

+ +
+
+

RbacConfig.Mode

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
OFF +

Disable Istio RBAC completely, any other config in RbacConfig will be ignored and Istio RBAC policies +will not be enforced.

+ +
ON +

Enable Istio RBAC for all services and namespaces.

+ +
ON_WITH_INCLUSION +

Enable Istio RBAC only for services and namespaces specified in the inclusion field. Any other +services and namespaces not in the inclusion field will not be enforced by Istio RBAC policies.

+ +
ON_WITH_EXCLUSION +

Enable Istio RBAC for all services and namespaces except those specified in the exclusion field. Any other +services and namespaces not in the exclusion field will be enforced by Istio RBAC policies.

+ +
+
+

RbacConfig.Target

+
+

Target defines a list of services or namespaces.

+ + + + + + + + + + + + + + + + + + + diff --git a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md index 1cc9c81f3b88..d0f9936987a0 100644 --- a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md +++ b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md @@ -9,7 +9,7 @@ type: markdown --- {% include home.html %} -The [Control Egress Traffic]({{home}}/docs/tasks/traffic-management-v1alpha3/egress.html) task demonstrated how external (outside the Kubernetes cluster) HTTP and HTTPS services can be accessed from applications inside the mesh. A quick reminder: by default, Istio-enabled applications are unable to access URLs outside the cluster. To enable such access, an [external service]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#ExternalService) must be defined, or, alternatively, [direct access to external services]({{home}}/docs/tasks/traffic-management-v1alpha3/egress.html#calling-external-services-directly) must be configured. +The [Control Egress Traffic]({{home}}/docs/tasks/traffic-management-v1alpha3/egress.html) task demonstrated how external (outside the Kubernetes cluster) HTTP and HTTPS services can be accessed from applications inside the mesh. A quick reminder: by default, Istio-enabled applications are unable to access URLs outside the cluster. To enable such access, an [external service]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#ServiceEntry) must be defined, or, alternatively, [direct access to external services]({{home}}/docs/tasks/traffic-management-v1alpha3/egress.html#calling-external-services-directly) must be configured. This task describes how to configure Istio to expose external TCP services to applications inside the Istio service mesh. @@ -41,7 +41,7 @@ Let's create an external service to enable TCP access to `wikipedia.org`: ```bash cat < Date: Mon, 30 Apr 2018 11:40:39 -0700 Subject: [PATCH 151/191] Quiet GitHub warning --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 9571864858d9..6362921f6080 100644 --- a/_config.yml +++ b/_config.yml @@ -10,7 +10,7 @@ kramdown: baseurl: -highlighter: none +highlighter: rouge liquid: error_mode: strict From 04d16b577aa2263966000ae47c9ebfed4b2929e4 Mon Sep 17 00:00:00 2001 From: Frank Budinsky Date: Mon, 30 Apr 2018 15:19:09 -0400 Subject: [PATCH 152/191] v1alpha3 routing blog (#1190) --- .spelling | 20 + _blog/2018/aws-nlb.md | 2 +- _blog/2018/img/gateways.png | Bin 0 -> 36725 bytes _blog/2018/img/gateways.svg | 1 + _blog/2018/img/virtualservices-destrules.png | Bin 0 -> 23875 bytes _blog/2018/img/virtualservices-destrules.svg | 1 + _blog/2018/soft-multitenancy.md | 2 +- _blog/2018/v1alpha3-routing.md | 436 +++++++++++++++++++ 8 files changed, 460 insertions(+), 2 deletions(-) create mode 100644 _blog/2018/img/gateways.png create mode 100644 _blog/2018/img/gateways.svg create mode 100644 _blog/2018/img/virtualservices-destrules.png create mode 100644 _blog/2018/img/virtualservices-destrules.svg create mode 100644 _blog/2018/v1alpha3-routing.md diff --git a/.spelling b/.spelling index abf9097fcaf9..1fdf5c071a49 100644 --- a/.spelling +++ b/.spelling @@ -30,11 +30,13 @@ AppOptics AuthPolicy Autoscalers Bookinfo +Budinsky CAP_NET_ADMIN CAs CDNs CIDRs CIOs +Costin CSRs Chrony Circonus @@ -47,6 +49,7 @@ D3.js DaemonSet Datadog Datawire +DestinationRule EgressRule Elasticsearch ExecAction @@ -81,16 +84,19 @@ JWT JWTs Kibana Kops +Kuat Kube Kubecon Kubelet Kubernetes L3-4 +L4-L6 LabelDescription LoadBalancers LoadBalancing.svg Lyft MacOS +Manolache Memquota Mesos Minikube @@ -107,9 +113,11 @@ OP_QUERY OpenID_Connect OpenSSL OpenShift +Ostrowski PaaS Papertrail PilotAdapters.svg +Rajagopalan RawVM Redis Redis-based @@ -118,12 +126,15 @@ Registrator Reviewer1 Reviewer2 SREs +ServiceEntry ServiceGraph ServiceModel_RequestFlow.svg ServiceModel_Versions.svg ServiceRole Servicegraph Sharding +Shriram +Snell-Feikema SolarWinds StatefulSets TCP-level @@ -135,14 +146,18 @@ USE_ORIGIN USE_ORIGIN USE_PEER Undeploy +VMware VM-based VMs ValueType +VirtualService WeaveWorks WebSocket Webhooks X.509 X.509. +Yessenov +Zack Zipkin _CA_ _OK_ @@ -261,6 +276,7 @@ fluentd fortio frontend gRPC +gateways.svg gbd gcloud gdb @@ -342,6 +358,7 @@ metadata.initializers.pending methodName microservice microservices +middleboxes minikube misconfigured mixer-spof-myth-1 @@ -367,6 +384,7 @@ non-sandboxed ns oc ok +onwards openssl packageName.serviceName parenthesization @@ -489,6 +507,7 @@ ulimit uncomment uncommented unencrypted +unmanaged untrusted uptime url @@ -505,6 +524,7 @@ v2-mysql v3 versioned versioning +virtualservices-destrules vm-1 webhook webhooks diff --git a/_blog/2018/aws-nlb.md b/_blog/2018/aws-nlb.md index 05daa69d8c09..f03772b5312c 100644 --- a/_blog/2018/aws-nlb.md +++ b/_blog/2018/aws-nlb.md @@ -5,7 +5,7 @@ publish_date: April 20, 2018 subtitle: Ingress AWS Network Load Balancer attribution: Julien SENON -order: 90 +order: 89 layout: blog type: markdown diff --git a/_blog/2018/img/gateways.png b/_blog/2018/img/gateways.png new file mode 100644 index 0000000000000000000000000000000000000000..5a66379b264ca0ca3adddc44a9417ebed04ca0f4 GIT binary patch literal 36725 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 zÂ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 literal 0 HcmV?d00001 diff --git a/_blog/2018/img/gateways.svg b/_blog/2018/img/gateways.svg new file mode 100644 index 000000000000..4c0bb6132358 --- /dev/null +++ b/_blog/2018/img/gateways.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_blog/2018/img/virtualservices-destrules.png b/_blog/2018/img/virtualservices-destrules.png new file mode 100644 index 0000000000000000000000000000000000000000..985444a18eb06fa9dd61e28e2c764ae47eb2c3d9 GIT binary patch literal 23875 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 c3>$i-a5ucwO{*11j()%dZUK9J@!GwA1K \ No newline at end of file diff --git a/_blog/2018/soft-multitenancy.md b/_blog/2018/soft-multitenancy.md index 9c2a53c1e880..53c7d047a3c3 100644 --- a/_blog/2018/soft-multitenancy.md +++ b/_blog/2018/soft-multitenancy.md @@ -5,7 +5,7 @@ publish_date: April 19, 2018 subtitle: Using multiple Istio control planes and RBAC to create multi-tenancy attribution: John Joyce and Rich Curran -order: 92 +order: 90 layout: blog type: markdown diff --git a/_blog/2018/v1alpha3-routing.md b/_blog/2018/v1alpha3-routing.md new file mode 100644 index 000000000000..353e326a1532 --- /dev/null +++ b/_blog/2018/v1alpha3-routing.md @@ -0,0 +1,436 @@ +--- +title: "Introducing the Istio v1alpha3 routing API" +overview: Introduction, motivation and design principles for the Istio v1alpha3 routing API. +publish_date: April 25, 2018 +subtitle: +attribution: Frank Budinsky (IBM) and Shriram Rajagopalan (VMware) + +order: 88 + +layout: blog +type: markdown +redirect_from: "/blog/v1alpha3-routing.html" +--- + +{% include home.html %} + +Up until now, Istio has provided a simple API for traffic management using four configuration resources: +`RouteRule`, `DestinationPolicy`, `EgressRule`, and (Kubernetes) `Ingress`. +With this API, users have been able to easily manage the flow of traffic in an Istio service mesh. +The API has allowed users to route requests to specific versions of services, inject delays and failures for resilience +testing, add timeouts and circuit breakers, and more, all without changing the application code itself. + +While this functionality has proven to be a very compelling part of Istio, user feedback has also shown that this API does +have some shortcomings, specifically when using it to manage very large applications containing thousands of services, and +when working with protocols other than HTTP. Furthermore, the use of Kubernetes `Ingress` resources to configure external +traffic has proven to be woefully insufficient for our needs. + +To address these, and other concerns, a new traffic management API, a.k.a. `v1alpha3`, is being introduced, which will +completely replace the previous API going forward. Although the `v1alpha3` model is fundamentally the same, it is not +backward compatible and will require manual conversion from the old API. A +[conversion tool]({{home}}/docs/reference/commands/istioctl.html#istioctl%20experimental%20convert-networking-config) +is included in the next few releases of Istio to help with the transition. + +To justify this disruption, the `v1alpha3` API has gone through a long and painstaking community +review process that has hopefully resulted in a greatly improved API that will stand the test of time. In this article, +we will introduce the new configuration model and attempt to explain some of the motivation and design principles that +influenced it. + +## Design principles + +A few key design principles played a role in the routing model redesign: + +* Explicitly model infrastructure as well as intent. For example, in addition to configuring an ingress gateway, the + component (controller) implementing it can also be specified. +* The authoring model should be "producer oriented" and "host centric" as opposed to compositional. For example, all + rules associated with a particular host are configured together, instead of individually. +* Clear separation of routing from post-routing behaviors. + +## Configuration resources in v1alpha3 + +A typical mesh will have one or more load balancers (we call them gateways) +that terminate TLS from external networks and allow traffic into the mesh. +Traffic then flows through internal services via sidecar gateways. +It is also common for applications to consume external +services (e.g., Google Maps API). These may be called directly or, in certain deployments, all traffic +exiting the mesh may be forced through dedicated egress gateways. The following diagram depicts +this mental model. + +{% include figure.html width='80%' ratio='65.16%' + img='./img/gateways.svg' + alt='Role of gateways in the mesh' + title='Gateways in an Istio service mesh' + caption='Gateways in an Istio service mesh' + %} + +With the above setup in mind, `v1alpha3` introduces the following new +configuration resources to control traffic routing into, within, and out of the mesh. + +1. `Gateway` +1. `VirtualService` +1. `DestinationRule` +1. `ServiceEntry` + +`VirtualService`, `DestinationRule`, and `ServiceEntry` replace `RouteRule`, +`DestinationPolicy`, and `EgressRule` respectively. The `Gateway` is a +platform independent abstraction to model the traffic flowing into +dedicated middleboxes. + +The figure below depicts the flow of control across configuration +resources. + +{% include figure.html width='80%' ratio='65.16%' + img='./img/virtualservices-destrules.svg' + alt='Relationship between different v1alpha3 elements' + title='Relationship between different v1alpha3 elements' + caption='Relationship between different v1alpha3 elements' + %} + +### Gateway + +A [Gateway]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#Gateway) +configures a load balancer for HTTP/TCP traffic, regardless of +where it will be running. Any number of gateways can exist within the mesh +and multiple different gateway implementations can co-exist. In fact, a +gateway configuration can be bound to a particular workload by specifying +the set of workload (pod) labels as part of the configuration, allowing +users to reuse off the shelf network appliances by writing a simple gateway +controller. + +For ingress traffic management, you might ask: _Why not reuse Kubernetes Ingress APIs_? +The Ingress APIs proved to be incapable of expressing Istio's routing needs. +By trying to draw a common denominator across different HTTP proxies, the +Ingress is only able to support the most basic HTTP routing and ends up +pushing every other feature of modern proxies into non-portable +annotations. + +Istio `Gateway` overcomes the `Ingress` shortcomings by separating the +L4-L6 spec from L7. It only configures the L4-L6 functions (e.g., ports to +expose, TLS configuration) that are uniformly implemented by all good L7 +proxies. Users can then use standard Istio rules to control HTTP +requests as well as TCP traffic entering a `Gateway` by binding a +`VirtualService` to it. + +For example, the following simple `Gateway` configures a load balancer +to allow external https traffic for host `bookinfo.com` into the mesh: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: bookinfo-gateway +spec: + servers: + - port: + number: 443 + name: https + protocol: HTTPS + hosts: + - bookinfo.com + tls: + mode: SIMPLE + serverCertificate: /tmp/tls.crt + privateKey: /tmp/tls.key +``` + +To configure the corresponding routes, a `VirtualService` (described in the [following section](#virtualservice)) +must be defined for the same host and bound to the `Gateway` using +the `gateways` field in the configuration: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: bookinfo +spec: + hosts: + - bookinfo.com + gateways: + - bookinfo-gateway # <---- bind to gateway + http: + - match: + - uri: + prefix: /reviews + route: + ... +``` + +The `Gateway` can be used to model an edge-proxy or a purely internal proxy +as shown in the first figure. Irrespective of the location, all gateways +can be configured and controlled in the same way. + +### VirtualService + +Replacing route rules with something called “virtual services” might seem peculiar at first, but in reality it’s +fundamentally a much better name for what is being configured, especially after redesigning the API to address the +scalability issues with the previous model. + +In effect, what has changed is that instead of configuring routing using a set of individual configuration resources +(rules) for a particular destination service, each containing a precedence field to control the order of evaluation, we +now configure the (virtual) destination itself, with all of its rules in an ordered list within a corresponding +[VirtualService]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#VirtualService) resource. +For example, where previously we had two `RouteRule` resources for the +[Bookinfo]({{home}}/docs/guides/bookinfo.html) application’s `reviews` service, like this: + +```yaml +apiVersion: config.istio.io/v1alpha2 +kind: RouteRule +metadata: + name: reviews-default +spec: + destination: + name: reviews + precedence: 1 + route: + - labels: + version: v1 +--- +apiVersion: config.istio.io/v1alpha2 +kind: RouteRule +metadata: + name: reviews-test-v2 +spec: + destination: + name: reviews + precedence: 2 + match: + request: + headers: + cookie: + regex: "^(.*?;)?(user=jason)(;.*)?$" + route: + - labels: + version: v2 +``` + +In `v1alph3`, we provide the same configuration in a single `VirtualService` resource: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - match: + - headers: + cookie: + regex: "^(.*?;)?(user=jason)(;.*)?$" + route: + - destination: + host: reviews + subset: v2 + - route: + - destination: + host: reviews + subset: v1 +``` + +As you can see, both of the rules for the `reviews` service are consolidated in one place, which at first may or may not +seem preferable. However, if you look closer at this new model, you’ll see there are fundamental differences that make +`v1alpha3` vastly more functional. + +First of all, notice that the destination service for the `VirtualService` is specified using a `hosts` field (repeated field, in fact) and is then again specified in a `destination` field of each of the route specifications. This is a +very important difference from the previous model. + +A `VirtualService` describes the mapping between one or more user-addressable destinations to the actual destination workloads inside the mesh. In our example, they are the same, however, the user-addressed hosts can be any DNS +names with optional wildcard prefix or CIDR prefix that will be used to address the service. This can be particularly +useful in facilitating turning monoliths into a composite service built out of distinct microservices without requiring the +consumers of the service to adapt to the transition. + +For example, the following rule allows users to address both the `reviews` and `ratings` services of the Bookinfo application +as if they are parts of a bigger (virtual) service at `http://bookinfo.com/`: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: bookinfo +spec: + hosts: + - bookinfo.com + http: + - match: + - uri: + prefix: /reviews + route: + - destination: + host: reviews + - match: + - uri: + prefix: /ratings + route: + - destination: + host: ratings + ... +``` + +The hosts of a `VirtualService` do not actually have to be part of the service registry, they are simply virtual +destinations. This allows users to model traffic for virtual hosts that do not have routable entries inside the mesh. +These hosts can be exposed outside the mesh by binding the `VirtualService` to a `Gateway` configuration for the same host +(as described in the [previous section](#gateway)). + +In addition to this fundamental restructuring, `VirtualService` includes several other important changes: + +1. Multiple match conditions can be expressed inside the `VirtualService` configuration, reducing the need for redundant + rules. +1. Each service version has a name (called a service subset). The set of pods/VMs belonging to a subset is defined in a + `DestinationRule`, described in the following section. +1. `VirtualService` hosts can be specified using wildcard DNS prefixes to create a single rule for all matching services. + For example, in Kubernetes, to apply the same rewrite rule for all services in the `foo` namespace, the `VirtualService` + would use `*.foo.svc.cluster.local` as the host. + +### DestinationRule + +A [DestinationRule]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#DestinationRule) +configures the set of policies to be applied while forwarding traffic to a service. They are +intended to be authored by service owners, describing the circuit breakers, load balancer settings, TLS settings, etc.. +`DestinationRule` is more or less the same as its predecessor, `DestinationPolicy`, with the following exceptions: + +1. The `host` of a `DestinationRule` can include wildcard prefixes, allowing a single rule to be specified for many actual + services. +1. A `DestinationRule` defines addressable `subsets` (i.e., named versions) of the corresponding destination host. These + subsets are used in `VirtualService` route specifications when sending traffic to specific versions of the service. + Naming versions this way allows us to cleanly refer to them across different virtual services, simplify the stats that + Istio proxies emit, and to encode subsets in SNI headers. + +A `DestinationRule` that configures policies and subsets for the reviews service might look something like this: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: reviews +spec: + host: reviews + trafficPolicy: + loadBalancer: + simple: RANDOM + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + trafficPolicy: + loadBalancer: + simple: ROUND_ROBIN + - name: v3 + labels: + version: v3 +``` + +Notice that, unlike `DestinationPolicy`, multiple policies (e.g., default and v2-specific) are specified in a single +`DestinationRule` configuration. + +### ServiceEntry + +[ServiceEntry]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#ServiceEntry) +is used to add additional entries into the service registry that Istio maintains internally. +It is most commonly used to allow one to model traffic to external dependencies of the mesh +such as APIs consumed from the web or traffic to services in legacy infrastructure. + +Everything you could previously configure using an `EgressRule` can just as easily be done with a `ServiceEntry`. +For example, access to a simple external service from inside the mesh can be enabled using a configuration +something like this: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: ServiceEntry +metadata: + name: foo-ext +spec: + hosts: + - foo.com + ports: + - number: 80 + name: http + protocol: HTTP +``` + +That said, `ServiceEntry` has significantly more functionality than its predecessor. +First of all, `ServiceEntry` is not limited to external service configuration. +It can also be used to explicitly add services as part of expanding the service mesh to include unmanaged infrastructure +(e.g., VMs added to a Kubernetes-based service mesh). Such entries are treated just like all other internal services, +unlike external ones where Istio's mTLS authentication is disabled and policy enforcement is +performed on the client-side as opposed to server-side. + +Because a `ServiceEntry` configuration simply adds a destination to the internal service registry, it can be +used in conjunction with a `VirtualService` and/or `DestinationRule`, just like any other service in the registry. +The following `DestinationRule`, for example, can be used to initiate mTLS connections for an external service: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: foo-ext +spec: + name: foo.com + trafficPolicy: + tls: + mode: MUTUAL + clientCertificate: /etc/certs/myclientcert.pem + privateKey: /etc/certs/client_private_key.pem + caCertificates: /etc/certs/rootcacerts.pem +``` + +In addition to its expanded generality, `ServiceEntry` includes several other improvements over `EgressRule` +including the following: + +1. A single `ServiceEntry` can configure multiple service endpoints, which previously would have required multiple + `EgressRules`. +1. The resolution mode for the endpoints is now configurable (`PASSTHROUGH`, `STATIC`, or `DNS`). +1. Secure HTTP services (automatic TLS upgrade) can now be accessed using standard https (e.g., `https://secureservice.com/` + instead of `http://secureservice.com:443/`. + +## Creating and deleting v1alpha3 route rules + +Because all route rules for a given destination are now stored together as an ordered +list in a single `VirtualService` resource, adding a second and subsequent rules for a particular destination +is no longer done by creating a new (`RouteRule`) resource, but instead by updating the one-and-only `VirtualService` +resource for the destination. + +old routing rules: +```bash +istioctl create -f my-second-rule-for-destination-abc.yaml +``` +`v1alpha3` routing rules: +```bash +istioctl replace -f my-updated-rules-for-destination-abc.yaml +``` + +Deleting route rules other than the last one for a particular destination is also done using `istioctl replace`. + +When adding or removing routes that refer to service versions, the `subsets` will need to be updated in +the service's corresponding `DestinationRule`. +As you might have guessed, this is also done using `istioctl replace`. + +## Summary + +The Istio `v1alpha3` routing API has significantly more functionality than +its predecessor, but unfortunately is not backwards compatible, requiring a +one time manual conversion. The previous configuration resources, +`RouteRule`, `DesintationPolicy`, and `EgressRule`, will not be supported +from Istio 0.9 onwards. Kubernetes users can continue to use `Ingress` to +configure their edge load balancers for basic routing. However, advanced +routing features (e.g., traffic split across two versions) will require use +of `Gateway`, a significantly more functional and highly +recommended `Ingress` replacement. + +## Acknowledgments + +Credit for the routing model redesign and implementation work goes to the +following people (in alphabetical order): + +* Frank Budinsky (IBM) +* Zack Butcher (Google) +* Greg Hanson (IBM) +* Costin Manolache (Google) +* Martin Ostrowski (Google) +* Shriram Rajagopalan (VMware) +* Louis Ryan (Google) +* Isaiah Snell-Feikema (IBM) +* Kuat Yessenov (Google) From d79170cfa3991bc8804e50adbc9005fe99356ab5 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Mon, 30 Apr 2018 13:22:10 -0700 Subject: [PATCH 153/191] Clarify istio.io/preliminary.istio.io stuff (#1221) --- README.md | 23 ++++++++++++-------- _about/contribute/creating-a-pull-request.md | 5 ++++- _about/contribute/editing.md | 3 +++ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7875bce31991..e2eaa0c509e2 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## istio.github.io This repository contains the source code for the [istio.io](https://istio.io), -[preliminary.istio.io](https://preliminary.istio.io) and [archive.istio.io](https://archive.istio.io) websites. +[preliminary.istio.io](https://preliminary.istio.io) and [archive.istio.io](https://archive.istio.io) sites. Please see the main Istio [README](https://github.com/istio/istio/blob/master/README.md) file to learn about the overall Istio project and how to get in touch with us. To learn how you can @@ -12,12 +12,12 @@ see the Istio [contribution guidelines](https://github.com/istio/community/blob/ * [Linting](#linting) * [Versions and releases](#versions-and-releases) * [How versioning works](#how-versioning-works) + * [Publishing content immediately](#publishing-content-immediately) * [Creating a version](#creating-a-version) ## Working with the site -The website uses [Jekyll](https://jekyllrb.com/) templates Please make sure you are -familiar with these before editing. +We use [Jekyll](https://jekyllrb.com/) to generate our sites. To run the site locally with Docker, use the following command from the top level directory for this git repo (e.g. pwd must be `~/github/istio.github.io` if you were in `~/github` when you issued @@ -41,8 +41,6 @@ HTML-Proofer finished successfully. in the output -> In some cases the `--incremental` may not work properly and you might have to remove it. - Alternatively, if you just want to develop locally w/o Docker/Kubernetes/Minikube, you can try installing Jekyll locally. You may need to install other prerequisites manually (which is where using the docker image shines). Here's an example of doing so for Mac OS X: @@ -82,16 +80,16 @@ If you get a spelling error, you have three choices to address it: ## Versions and releases -Istio maintains three variations of its public website: +Istio maintains three variations of its public site: -* istio.io is the main site, showing documentation for the current release of the product. +* [istio.io](https://istio.io) is the main site, showing documentation for the current release of the product. This site is currently hosted on Firebase. -* archive.istio.io contains snapshots of the documentation for previous releases of the product. +* [archive.istio.io](https://archive.istio.io) contains snapshots of the documentation for previous releases of the product. This is useful for customers still using these older releases. This site is currently hosted on Firebase. -* preliminary.istio.io contains the actively updated documentation for the next release of the product. +* [preliminary.istio.io](https://preliminary.istio.io) contains the actively updated documentation for the next release of the product. This site is hosted by GitHub Pages. The user can trivially navigate between the different variations of the site using the gear menu in the top right @@ -113,6 +111,13 @@ are included on archive.istio.io is determined by the `TOBUILD` variable in this to make the change in the master branch of istio.github.io and then merge that change into the release branch. +### Publishing content immediately + +Checking in updates to the master branch will automatically update preliminary.istio.io, and will only be reflected on +istio.io the next time a release is created, which can be several weeks in the future. If you'd like some changes to be +immediately reflected on istio.io, you need to check your changes both to the master branch and to the +current release branch (named release-XXX such as release-0.7). + ### Creating a version Here are the steps necessary to create a new documentation version. Let's assume the current diff --git a/_about/contribute/creating-a-pull-request.md b/_about/contribute/creating-a-pull-request.md index b6b36d995e3c..9eb339f6cecf 100644 --- a/_about/contribute/creating-a-pull-request.md +++ b/_about/contribute/creating-a-pull-request.md @@ -17,7 +17,7 @@ repository. This page shows the steps necessary to create a pull request. 1. Create a [GitHub account](https://github.com). -1. Sign the [Contributor License Agreement](https://github.com/istio/community/blob/master/CONTRIBUTING.md#contributor-license-agreements) +1. Sign the [Contributor License Agreement](https://github.com/istio/community/blob/master/CONTRIBUTING.md#contributor-license-agreements). Documentation will be published under the [Apache 2.0](https://github.com/istio/istio.github.io/blob/master/LICENSE) license. @@ -57,3 +57,6 @@ repository. This opens a page that shows the status of your pull request. 1. During the next few days, check your pull request for reviewer comments. If needed, revise your pull request by committing changes to your new branch in your fork. + +> Once your changes have been committed, they will show up immediately on [preliminary.istio.io](https://preliminary.istio.io), but +will only show up on [istio.io](http://istio.io) the next time we produce a new release, which happens around once a month. diff --git a/_about/contribute/editing.md b/_about/contribute/editing.md index 2c8ea9de71a7..cb509d384a31 100644 --- a/_about/contribute/editing.md +++ b/_about/contribute/editing.md @@ -15,3 +15,6 @@ create a copy of our site in your GitHub account called a _fork_. Make any chang are ready to send those changes to us, go to the index page for your fork and click **New Pull Request** to let us know about it. Browse this site's source code + +> Once your changes have been committed, they will show up immediately on [preliminary.istio.io](https://preliminary.istio.io), but +will only show up on [istio.io](http://istio.io) the next time we produce a new release, which happens around once a month. From 611a65192add4cf02b0b2d4e4d387ea13bf3e41c Mon Sep 17 00:00:00 2001 From: Jason Young Date: Mon, 30 Apr 2018 14:46:01 -0700 Subject: [PATCH 154/191] add galley.enabled option to helm instructions (#1222) --- _docs/setup/kubernetes/helm-install.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_docs/setup/kubernetes/helm-install.md b/_docs/setup/kubernetes/helm-install.md index 69193e0d38a9..9d5ce9d25989 100644 --- a/_docs/setup/kubernetes/helm-install.md +++ b/_docs/setup/kubernetes/helm-install.md @@ -95,6 +95,7 @@ following table: | `global.arch.amd64` | Specifies the scheduling policy for `amd64` architectures | 0 = never, 1 = least preferred, 2 = no preference, 3 = most preferred | `2` | | `global.arch.s390x` | Specifies the scheduling policy for `s390x` architectures | 0 = never, 1 = least preferred, 2 = no preference, 3 = most preferred | `2` | | `global.arch.ppc64le` | Specifies the scheduling policy for `ppc64le` architectures | 0 = never, 1 = least preferred, 2 = no preference, 3 = most preferred | `2` | +| `galley.enabled` | Specifies whether Galley should be installed for server-side config validation. Requires k8s >= 1.9 | true/false | `false` | > The Helm chart also offers significant customization options per individual service. Customize these per-service options at your own risk. From 0e4092f5839154587ce42767eb3ed4c51687338c Mon Sep 17 00:00:00 2001 From: Steven Dake Date: Tue, 1 May 2018 18:57:19 +0200 Subject: [PATCH 155/191] Fix naming collision (#1226) ingressgateway and ingress both match the grep, resulting in incorect ingress name being produced in troubleshooting guide. --- _help/troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_help/troubleshooting.md b/_help/troubleshooting.md index 2bb5e0add0cb..ce7cef450a44 100644 --- a/_help/troubleshooting.md +++ b/_help/troubleshooting.md @@ -19,7 +19,7 @@ Verifying connectivity to Pilot is a useful troubleshooting step. Every proxy co 1. Get the name of the Istio Ingress pod: ```bash -INGRESS_POD_NAME=$(kubectl get po -n istio-system | grep ingress | awk '{print$1}') +INGRESS_POD_NAME=$(kubectl get po -n istio-system | grep ingress\- | awk '{print$1}') ``` 1. Exec into the Istio Ingress pod: From 26888acedcaccae1afe0a351c476a62d1c834a12 Mon Sep 17 00:00:00 2001 From: Lin Sun Date: Tue, 1 May 2018 13:45:56 -0400 Subject: [PATCH 156/191] adding the recommended namespace (#1218) * adding the recommended namespace https://github.com/istio/issues/issues/312 * add the recommended namespace * add creating the namespace * correct typos * only need to create namespace for the template approach --- _docs/setup/kubernetes/helm-install.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_docs/setup/kubernetes/helm-install.md b/_docs/setup/kubernetes/helm-install.md index 9d5ce9d25989..cde84845c924 100644 --- a/_docs/setup/kubernetes/helm-install.md +++ b/_docs/setup/kubernetes/helm-install.md @@ -43,11 +43,12 @@ produced for Istio. 1. Create an `istio.yaml` Kubernetes manifest: ```bash - helm template install/kubernetes/helm/istio --name istio --set prometheus.enabled=true > $HOME/istio.yaml + helm template install/kubernetes/helm/istio --name istio --namespace istio-system --set prometheus.enabled=true > $HOME/istio.yaml ``` 1. Create the Istio control plane from `istio.yaml` manifest: ```bash + kubectl create ns istio-system kubectl create -f $HOME/istio.yaml ``` @@ -68,7 +69,7 @@ Upgrading Istio using Helm is not validated. 1. Create the Helm chart: ```bash - helm install install/kubernetes/helm/istio --name istio + helm install install/kubernetes/helm/istio --name istio --namespace istio-system ``` ## Customization with Helm From cf7591929f4d574958365f15538f3f5db2668262 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Tue, 1 May 2018 11:11:41 -0700 Subject: [PATCH 157/191] Introduce support for new fangled PRE blocks. (#1224) Instead of having to have two PRE blocks, one for commands and one for the output, we can now have a single PRE block and we take care of rendering things to show the command vs. the output. The Copy button on such a thing only copy the command, and not the output. We now also show a $ on command-lines, but the Copy button doesn't copy that and knows to just copy the usable part of the command-line. --- _config.yml | 1 + _docs/setup/kubernetes/sidecar-injection.md | 192 +++++--------------- _sass/base/_common.scss | 23 ++- _sass/themes/_dark.scss | 2 + _sass/themes/_light.scss | 2 + js/misc.js | 77 +++++++- js/misc.min.js | 2 +- mdl_style.rb | 1 + 8 files changed, 148 insertions(+), 152 deletions(-) diff --git a/_config.yml b/_config.yml index 6362921f6080..32442467cf96 100644 --- a/_config.yml +++ b/_config.yml @@ -69,6 +69,7 @@ exclude: - js/styleSwitcher.js - firebase.json - _rakesite + - mdl_style.rb repository: istio/istio.github.io diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index a9f08f0c64c0..f1224c313880 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -70,7 +70,7 @@ Two variants of the injection configuration are provided with the default install: `istio-sidecar-injector-configmap-release.yaml` and `istio-sidecar-injector-configmap-debug.yaml`. The injection configmap includes the default injection policy and sidecar injection template. The debug version -includes debug proxy images and additional logging and core dump functionality using +includes debug proxy images and additional logging and core dump functionality used for debugging the sidecar proxy. ### Manual sidecar injection @@ -79,25 +79,24 @@ Use the built-in defaults template and dynamically fetch the mesh configuration from the `istio` ConfigMap. Additional parameter overrides are available via flags (see `istioctl kube-inject --help`). -```bash -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) ``` `kube-inject` can also be run without access to a running Kubernetes cluster. Create local copies of the injection and mesh configmap. -```bash -kubectl create -f install/kubernetes/istio-sidecar-injector-configmap-release.yaml \ +```command +$ kubectl create -f install/kubernetes/istio-sidecar-injector-configmap-release.yaml \ --dry-run \ -o=jsonpath='{.data.config}' > inject-config.yaml - -kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml +$ kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml ``` Run `kube-inject` over the input file. -```bash -istioctl kube-inject \ +```command +$ istioctl kube-inject \ --injectConfigFile inject-config.yaml \ --meshConfigFile mesh-config.yaml \ --filename samples/sleep/sleep.yaml \ @@ -106,16 +105,14 @@ istioctl kube-inject \ Deploy the injected YAML file. -```bash -kubectl apply -f sleep-injected.yaml +```command +$ kubectl apply -f sleep-injected.yaml ``` Verify that the sidecar has been injected into the deployment. -```bash -kubectl get deployment sleep -o wide -``` -```xxx +```command +$ kubectl get deployment sleep -o wide NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR sleep 1 1 1 1 2h sleep,istio-proxy tutum/curl,unknown/proxy:unknown app=sleep ``` @@ -125,12 +122,10 @@ sleep 1 1 1 1 2h sleep,istio-pro Sidecars can be automatically added to applicable Kubernetes pods using a [mutating webhook admission controller](https://kubernetes.io/docs/admin/admission-controllers/#validatingadmissionwebhook-alpha-in-18-beta-in-19). This feature requires Kubernetes 1.9 or later. Verify that the kube-apiserver process has the `admission-control` flag set with the `MutatingAdmissionWebhook` and `ValidatingAdmissionWebhook` admission controllers added and listed in the correct order and the admissionregistration API is enabled. -```bash -kubectl api-versions | grep admissionregistration -``` - -```xxx +```command +$ kubectl api-versions | grep admissionregistration admissionregistration.k8s.io/v1beta1 +admissionregistration.k8s.io/v2beta2 ``` See the Kubernetes [quick start]({{home}}/docs/setup/kubernetes/quick-start.html) guide for instructions on installing Kubernetes version >= 1.9. @@ -139,134 +134,51 @@ Note that unlike manual injection, automatic injection occurs at the pod-level. #### Installing the webhook -##### For version 0.8.0 and later - To enable the sidecar injection webhook, you can use [Helm]({{home}}/docs/setup/kubernetes/helm-install.html) to install Istio with the option sidecar-injector.enabled set to true. E.g. -```bash -helm install --namespace=istio-system --set sidecar-injector.enabled=true install/kubernetes/helm/istio +```command +$ helm install --namespace=istio-system --set sidecar-injector.enabled=true install/kubernetes/helm/istio ``` Alternatively, you can also use Helm to generate the yaml file and install it manually. E.g. -```bash -helm template --namespace=istio-system --set sidecar-injector.enabled=true install/kubernetes/helm/istio > istio.yaml + +```command +$ helm template --namespace=istio-system --set sidecar-injector.enabled=true install/kubernetes/helm/istio > istio.yaml ``` -```bash -kubectl apply -f istio.yaml +```command +$ kubectl apply -f istio.yaml ``` In addition, there are some other configuration parameters defined for sidecar injector webhook service in `values.yaml`. You can override the default values to customize the installation. -##### For versions before 0.8.0 - -> The [0.5.0](https://github.com/istio/istio/releases/tag/0.5.0) and [0.5.1](https://github.com/istio/istio/releases/tag/0.5.1) releases are missing scripts to -provision webhook certificates. Download the missing files from [here](https://raw.githubusercontent.com/istio/istio/release-0.7/install/kubernetes/webhook-create-signed-cert.sh) and [here](https://raw.githubusercontent.com/istio/istio/release-0.7/install/kubernetes/webhook-patch-ca-bundle.sh). -Subsequent releases (> 0.5.1) should include these missing files. - -Install base Istio. - -```bash -kubectl apply -f install/kubernetes/istio.yaml -``` - -Webhooks requires a signed cert/key pair. Use `install/kubernetes/webhook-create-signed-cert.sh` to generate -a cert/key pair signed by the Kubernetes' CA. The resulting cert/key file is stored as a Kubernetes -secret for the sidecar injector webhook to consume. - -> Kubernetes CA approval requires permissions to create and approve CSR. See -[Managing TLS in a Cluster](https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/) -and [install/kubernetes/webhook-create-signed-cert.sh](https://raw.githubusercontent.com/istio/istio/release-0.7/install/kubernetes/webhook-create-signed-cert.sh) for more information. - -```bash -./install/kubernetes/webhook-create-signed-cert.sh \ - --service istio-sidecar-injector \ - --namespace istio-system \ - --secret sidecar-injector-certs -``` - -Install the sidecar injection configmap. - -```bash -kubectl apply -f install/kubernetes/istio-sidecar-injector-configmap-release.yaml -``` - -Set the `caBundle` in the webhook install YAML that the Kubernetes api-server -uses to invoke the webhook. - -```bash -cat install/kubernetes/istio-sidecar-injector.yaml | \ - ./install/kubernetes/webhook-patch-ca-bundle.sh > \ - install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml -``` - -Install the sidecar injector webhook. - -```bash -kubectl apply -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml -``` - -The sidecar injector webhook should now be running. - -```bash -kubectl -n istio-system get deployment -listio=sidecar-injector -``` -```xxx -NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE -istio-sidecar-injector 1 1 1 1 1d -``` - -NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the -selector (see ). The default webhook configuration -uses `istio-injection=enabled`. - -View namespaces showing `istio-injection` label and verify the `default` namespace is not labeled. - -```bash -kubectl get namespace -L istio-injection -``` -```xxx -NAME STATUS AGE ISTIO-INJECTION -default Active 1h -istio-system Active 1h -kube-public Active 1h -kube-system Active 1h -``` - #### Deploying an app Deploy sleep app. Verify both deployment and pod have a single container. -```bash -kubectl apply -f samples/sleep/sleep.yaml +```command +$ kubectl apply -f samples/sleep/sleep.yaml ``` -```bash -kubectl get deployment -o wide -``` -```xxx +```command +$ kubectl get deployment -o wide NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR sleep 1 1 1 1 12m sleep tutum/curl app=sleep ``` -```bash -kubectl get pod -``` -```xxx + +```command +$ kubectl get pod NAME READY STATUS RESTARTS AGE sleep-776b7bcdcd-7hpnk 1/1 Running 0 4 ``` Label the `default` namespace with `istio-injection=enabled` -```bash -kubectl label namespace default istio-injection=enabled -``` -```bash -kubectl get namespace -L istio-injection -``` -```xxx +```command +$ kubectl label namespace default istio-injection=enabled +$ kubectl get namespace -L istio-injection NAME STATUS AGE ISTIO-INJECTION default Active 1h enabled istio-system Active 1h @@ -276,13 +188,9 @@ kube-system Active 1h Injection occurs at pod creation time. Kill the running pod and verify a new pod is created with the injected sidecar. The original pod has 1/1 READY containers and the pod with injected sidecar has 2/2 READY containers. -```bash -kubectl delete pod sleep-776b7bcdcd-7hpnk -``` -```bash -kubectl get pod -``` -```xxx +```command +$ kubectl delete pod sleep-776b7bcdcd-7hpnk +$ kubectl get pod NAME READY STATUS RESTARTS AGE sleep-776b7bcdcd-7hpnk 1/1 Terminating 0 1m sleep-776b7bcdcd-bhn9m 2/2 Running 0 7s @@ -290,22 +198,16 @@ sleep-776b7bcdcd-bhn9m 2/2 Running 0 7s View detailed state of the injected pod. You should see the injected `istio-proxy` container and corresponding volumes. Be sure to substitute the correct name for the `Running` pod below. -```bash -kubectl describe pod sleep-776b7bcdcd-bhn9m +```command +$ kubectl describe pod sleep-776b7bcdcd-bhn9m ``` Disable injection for the `default` namespace and verify new pods are created without the sidecar. -```bash -kubectl label namespace default istio-injection- -``` -```bash -kubectl delete pod sleep-776b7bcdcd-bhn9m -``` -```bash -kubectl get pod -``` -```xxx +```command +$ kubectl label namespace default istio-injection- +$ kubectl delete pod sleep-776b7bcdcd-bhn9m +$ kubectl get pod NAME READY STATUS RESTARTS AGE sleep-776b7bcdcd-bhn9m 2/2 Terminating 0 2m sleep-776b7bcdcd-gmvnr 1/1 Running 0 2s @@ -424,8 +326,8 @@ when applied over a pod defined by the pod template spec in [samples/sleep/sleep #### Uninstalling the webhook -```bash -kubectl delete -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml +```command +$ kubectl delete -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml ``` The above command will not remove the injected sidecars from @@ -434,8 +336,8 @@ the deployment to create them is required. Optionally, if may be also be desirable to clean-up other resources that were created in this task. This includes the secret holding the cert/key and CSR used to sign them, as well as any namespace that was labeled for injection. -```bash -kubectl -n istio-system delete secret sidecar-injector-certs -kubectl delete csr istio-sidecar-injector.istio-system -kubectl label namespace default istio-injection- +```command +$ kubectl -n istio-system delete secret sidecar-injector-certs +$ kubectl delete csr istio-sidecar-injector.istio-system +$ kubectl label namespace default istio-injection- ``` diff --git a/_sass/base/_common.scss b/_sass/base/_common.scss index 02afe687d8a4..bfaff57afde8 100644 --- a/_sass/base/_common.scss +++ b/_sass/base/_common.scss @@ -164,8 +164,28 @@ pre { code { display: block; - padding: .5em; color: $textColor; + padding: .5em; + } + + code.command-output { + padding: 0; + + .command { + padding: .5em .5em 0 .5em; + } + + .output { + color: $preBlockCommandOutputTextColor; + background-color: $preBlockCommandOutputBackgroundColor; + font-style: italic; + padding: 0 .5em .5em .5em; + } + + // if the output div is empty, we need extra padding + div:only-of-type { + padding: .5em; + } } @media print { @@ -173,6 +193,7 @@ pre { } } +// this is necessary in order for proper positioning of the Copy button div.highlight { position: relative; } diff --git a/_sass/themes/_dark.scss b/_sass/themes/_dark.scss index 09f546aa0a85..0f2eb845bc1f 100644 --- a/_sass/themes/_dark.scss +++ b/_sass/themes/_dark.scss @@ -30,6 +30,8 @@ $deprecatedBackgroundColor: silver; $preBlockShadowColor: #777777; $preBlockBorderColor: #777777; $preBlockBackgroundColor: #2d2d2d; +$preBlockCommandOutputTextColor: $textColor; +$preBlockCommandOutputBackgroundColor: $dark-gray; $boxBorderColor: $textColor; $headerLightShadowColor: rgba(0, 0, 0, .14); diff --git a/_sass/themes/_light.scss b/_sass/themes/_light.scss index 47fdbda05b46..c5674f477385 100644 --- a/_sass/themes/_light.scss +++ b/_sass/themes/_light.scss @@ -30,6 +30,8 @@ $deprecatedBackgroundColor: silver; $preBlockShadowColor: #a7a7a7; $preBlockBorderColor: #dddddd; $preBlockBackgroundColor: $backgroundColor; +$preBlockCommandOutputTextColor: $textColor; +$preBlockCommandOutputBackgroundColor: lighten($gray, 50%); $boxBorderColor: $secondBrandColor; $headerLightShadowColor: rgba(0, 0, 0, .14); diff --git a/js/misc.js b/js/misc.js index a61f3bda81c8..926080353b72 100644 --- a/js/misc.js +++ b/js/misc.js @@ -146,8 +146,27 @@ function handleDOMLoaded() { } var copyCode = new Clipboard('button.copy', { - target: function (trigger) { - return trigger.previousElementSibling; + text: function (trigger) { + var commands = trigger.previousElementSibling.getElementsByClassName("command"); + if ((commands != undefined) && (commands.length > 0)) { + var lines = commands[0].innerText.split("\n"); + var cmd = ""; + for (var i = 0; i < lines.length; i++) { + if (lines[i].startsWith("$ ")) { + lines[i] = lines[i].substring(2); + } + + if (cmd != "") { + cmd = cmd + "\n"; + } + + cmd = cmd + lines[i]; + } + + return cmd; + } + + return trigger.previousElementSibling.innerText; } }); @@ -178,8 +197,57 @@ function handleDOMLoaded() { function applySyntaxColoring() { var pre = document.getElementsByTagName('PRE'); for (var i = 0; i < pre.length; i++) { - if (!pre[i].hasAttribute("data-src")) { - Prism.highlightElement(pre[i].firstChild, false) + var code = pre[i].firstChild; + + if (code.classList.contains("language-command")) { + var text = code.innerText; + var lines = text.split("\n"); + + var bottom = false; + var cmd = ""; + var output = ""; + var escape = false; + for (var j = 0; j < lines.length; j++) { + if (bottom) { + output = output + "\n" + lines[j] + } else { + if (lines[j].startsWith("$ ")) { + // line is definitely a command + } else if (escape) { + // continuation + } else { + bottom = true; + output = lines[j]; + continue; + } + + escape = (lines[j].endsWith("\\")); + + if (cmd != "") { + cmd = cmd + "\n"; + } + cmd = cmd + lines[j] + } + } + + var colored = Prism.highlight(cmd, Prism.languages["bash"], "bash"); + var html = "
" + colored + "
"; + + if (output != "") { + html = html + "
" + output + "
"; + } + + code.innerHTML = html; + code.classList.remove("language-command"); + code.classList.add("command-output"); + } else { + Prism.highlightElement(code, false); + var code = pre[i].firstChild; + var div = document.createElement("DIV"); + div.className = "code-plain"; + parent = code.parentElement; + parent.insertBefore(div, code); + div.appendChild(code); } } } @@ -238,7 +306,6 @@ function handleDOMLoaded() { function fetchFile(elem, url) { fetch(url).then(response => response.text()).then(data => { elem.firstChild.innerText = data; - Prism.highlightElement(elem.firstChild, false) }); } diff --git a/js/misc.min.js b/js/misc.min.js index 4e06e0265edb..efe10da43bfd 100644 --- a/js/misc.min.js +++ b/js/misc.min.js @@ -2,4 +2,4 @@ --- {% include home.html %} -'use strict';$(function(a){function b(){var d=a('#search_form'),e=a('#search_textbox'),f=a('#navbar-links');d.removeClass('active'),f.addClass('active'),e.val(''),e.removeClass('grow')}function c(){var d=a('#search_form'),e=a('#search_textbox'),f=a('#navbar-links');d.addClass('active'),f.removeClass('active'),e.addClass('grow'),e.focus()}a('body').on('keyup',function(d){27==d.which&&b()}),a('#search_show').on('click',function(d){d.preventDefault(),c()}),a('#search_close').on('click',function(d){d.preventDefault(),b()}),a('#search_form').submit(function(d){d.preventDefault();var e=a('#search_textbox'),f='{{home}}/search.html?q='+e.val();b(),window.location.assign(f)}),a(document).ready(function(){a('[data-toggle="offcanvas"]').on('click',function(){a('.row-offcanvas').toggleClass('active'),a(this).children('i.fa').toggleClass('fa-flip-horizontal')}),a(document).on('click','.tree-toggle',function(){a(this).children('i.fa').toggleClass('fa-caret-right'),a(this).children('i.fa').toggleClass('fa-caret-down'),a(this).parent().children('ul.tree').toggle(200)}),a(document).on('mouseenter','pre',function(){a(this).next().toggleClass('copy-show',!0),a(this).next().toggleClass('copy-hide',!1)}),a(document).on('mouseleave','pre',function(){a(this).next().toggleClass('copy-show',!1),a(this).next().toggleClass('copy-hide',!0)}),a(document).on('mouseenter','button.copy',function(){a(this).toggleClass('copy-show',!0),a(this).toggleClass('copy-hide',!1)}),a(document).on('mouseleave','button.copy',function(){a(this).toggleClass('copy-show',!1),a(this).toggleClass('copy-hide',!0)})})}(jQuery));function scrollToTop(){document.body.scrollTop=0,document.documentElement.scrollTop=0}var scrollToTopButton,tocLinks,tocHeadings;function handleDOMLoaded(){(function(){function e(l){var m=document.createElement('i');m.className='fa fa-link';var n=document.createElement('a');n.className='header-link',n.href='#'+l.id,n.setAttribute('aria-hidden','true'),n.appendChild(m),l.appendChild(n)}(function(){for(var n,l=document.getElementsByTagName('PRE'),m=0;m=l;l++){m=document.getElementsByTagName('h'+l);for(var o,n=0;nq.text()).then(q=>{o.firstChild.innerText=q,Prism.highlightElement(o.firstChild,!1)})}for(var m=document.getElementsByTagName('PRE'),n=0;n'+r+'')}}()})(),function(){scrollToTopButton=document.getElementById('scroll-to-top');var c=document.getElementById('toc');if(c!=void 0){tocLinks=c.getElementsByTagName('A'),tocHeadings=Array(tocLinks.length);for(var d=0;dh.top&&h.top>f&&(e=g,f=h.top)),tocLinks[g].classList.remove('current');0<=c?tocLinks[c].classList.add('current'):0<=e&&tocLinks[e].classList.add('current')}}()}document.addEventListener('DOMContentLoaded',handleDOMLoaded),window.addEventListener('scroll',handlePageScroll); +'use strict';$(function(a){function b(){var d=a('#search_form'),e=a('#search_textbox'),f=a('#navbar-links');d.removeClass('active'),f.addClass('active'),e.val(''),e.removeClass('grow')}function c(){var d=a('#search_form'),e=a('#search_textbox'),f=a('#navbar-links');d.addClass('active'),f.removeClass('active'),e.addClass('grow'),e.focus()}a('body').on('keyup',function(d){27==d.which&&b()}),a('#search_show').on('click',function(d){d.preventDefault(),c()}),a('#search_close').on('click',function(d){d.preventDefault(),b()}),a('#search_form').submit(function(d){d.preventDefault();var e=a('#search_textbox'),f='{{home}}/search.html?q='+e.val();b(),window.location.assign(f)}),a(document).ready(function(){a('[data-toggle="offcanvas"]').on('click',function(){a('.row-offcanvas').toggleClass('active'),a(this).children('i.fa').toggleClass('fa-flip-horizontal')}),a(document).on('click','.tree-toggle',function(){a(this).children('i.fa').toggleClass('fa-caret-right'),a(this).children('i.fa').toggleClass('fa-caret-down'),a(this).parent().children('ul.tree').toggle(200)}),a(document).on('mouseenter','pre',function(){a(this).next().toggleClass('copy-show',!0),a(this).next().toggleClass('copy-hide',!1)}),a(document).on('mouseleave','pre',function(){a(this).next().toggleClass('copy-show',!1),a(this).next().toggleClass('copy-hide',!0)}),a(document).on('mouseenter','button.copy',function(){a(this).toggleClass('copy-show',!0),a(this).toggleClass('copy-hide',!1)}),a(document).on('mouseleave','button.copy',function(){a(this).toggleClass('copy-show',!1),a(this).toggleClass('copy-hide',!0)})})}(jQuery));function scrollToTop(){document.body.scrollTop=0,document.documentElement.scrollTop=0}var scrollToTopButton,tocLinks,tocHeadings;function handleDOMLoaded(){(function(){function e(m){var n=document.createElement('i');n.className='fa fa-link';var o=document.createElement('a');o.className='header-link',o.href='#'+m.id,o.setAttribute('aria-hidden','true'),o.appendChild(n),m.appendChild(o)}(function(){for(var o,m=document.getElementsByTagName('PRE'),n=0;n'+w+'';''!=t&&(x=x+'
'+t+'
'),o.innerHTML=x,o.classList.remove('language-command'),o.classList.add('command-output')}else{Prism.highlightElement(o,!1);var o=m[n].firstChild,y=document.createElement('DIV');y.className='code-plain',parent=o.parentElement,parent.insertBefore(y,o),y.appendChild(o)}}(),function(){for(var n,m=1;6>=m;m++){n=document.getElementsByTagName('h'+m);for(var p,o=0;or.text()).then(r=>{p.firstChild.innerText=r})}for(var n=document.getElementsByTagName('PRE'),o=0;o'+s+'')}}()})(),function(){scrollToTopButton=document.getElementById('scroll-to-top');var c=document.getElementById('toc');if(c!=void 0){tocLinks=c.getElementsByTagName('A'),tocHeadings=Array(tocLinks.length);for(var d=0;dh.top&&h.top>f&&(e=g,f=h.top)),tocLinks[g].classList.remove('current');0<=c?tocLinks[c].classList.add('current'):0<=e&&tocLinks[e].classList.add('current')}}()}document.addEventListener('DOMContentLoaded',handleDOMLoaded),window.addEventListener('scroll',handlePageScroll); diff --git a/mdl_style.rb b/mdl_style.rb index 040eac15d67a..0ce4bd1eff67 100644 --- a/mdl_style.rb +++ b/mdl_style.rb @@ -9,3 +9,4 @@ exclude_rule 'MD013' exclude_rule 'MD007' exclude_rule 'MD034' +exclude_rule 'MD014' From 1ed57a3a0c00144e6c8caf51883244e7980f2a5e Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Tue, 1 May 2018 16:18:08 -0700 Subject: [PATCH 158/191] 0.8 release notes. (#1223) --- .spelling | 1 + _about/notes/0.8.md | 55 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/.spelling b/.spelling index 1fdf5c071a49..b294d814301a 100644 --- a/.spelling +++ b/.spelling @@ -40,6 +40,7 @@ Costin CSRs Chrony Circonus +CloudWatch Cmd Config ConfigMap diff --git a/_about/notes/0.8.md b/_about/notes/0.8.md index 6160a60f72d7..ff7b3f73f4cd 100644 --- a/_about/notes/0.8.md +++ b/_about/notes/0.8.md @@ -8,4 +8,57 @@ type: markdown --- {% include home.html %} -FILL IN BEFORE RELEASE +In addition to the usual pile of bug fixes and performance improvements, this release includes the new or +updated features detailed below. + +## Networking + +- **Revamped Traffic Management Model**. We're finally ready to take the wraps off our +new [traffic management configuration model]({{home}}/blog/2018/v1alpha3-routing.html). +The new model adds many new features and addresses usability issues +with the prior model. There is a conversion tool built into `istioctl` to help migrate your config from +the old model. [Learn more about the new traffic management model]({{home}}/docs/tasks/traffic-management-v1alpha3/). + +- **Envoy V2**. Users can choose to inject Envoy V2 as the sidecar. In this mode, Pilot uses Envoy's new API to push configuration to the data plane. This new approach +increases effective scalability and should eliminate spurious 404 errors. [TBD: docs on how to control this?] + +- **Gateway for Ingress/Egress**. We no longer support combining Kubernetes Ingress specs with Istio route rules, as it has led to several +bugs and reliability issues. Istio now +supports a platform independent ingress/egress Gateway that works across Kubernetes and Cloud Foundry and works seamlessly with the routing rules +[TBD: doc link] + +- **Constrained Inbound Ports**. We now restrict the inbound ports in a pod to the ones declared by the apps running inside that pod. + +## Security + +- **Introducing Citadel**. We've finally given a name to our security component. What was +formerly known as Istio-Auth or Istio-CA is now called Citadel. + +- **Multicluster Support**. We support per-cluster Citadel in multicluster deployments such that all Citadels share the same root cert +and workloads can authenticate each other across the mesh. + +- **Authentication Policy**. We've introduced authentication policy that can be used to configure service-to-service +authentication (mutual TLS) and end user authentication. This is the recommended way for enabling mutual TLS +(over the existing config flag and service annotations). [Learn more]({{home}}/docs/tasks/security/authn-policy.html). + +## Telemetry + +- **Self-Reporting**. Mixer and Pilot now produce telemetry that flows through the normal +Istio telemetry pipeline, just like services in the mesh. + +## Setup + +- **A la Carte Istio**. Istio has a rich set of features, however you don't need to install or consume them all together. By using +Helm or `istioctl gen-deploy`, users can install only the features they want. For example, users can install Pilot only and enjoy traffic +management functionality without dealing with Mixer or Citadel. +Learn more about [customization through Helm](https://istio.io/docs/setup/kubernetes/helm-install.html#customization-with-helm) +and about [`istioctl gen-deploy`](https://istio.io/docs/reference/commands/istioctl.html#istioctl%20gen-deploy). + +## Mixer adapters + +- **CloudWatch**. Mixer can now report metrics to AWS CloudWatch. +[Learn more]({{home}}/docs/reference/config/adapters/cloudwatch.html) + +## Known issues with 0.8 + +- A gateway with virtual services pointing to a headless service won't work ([Issue #5005](https://github.com/istio/istio/issues/5005)). From f89299f2a12d10a90891cf2b019aa0c5d50f2c3b Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Wed, 2 May 2018 08:19:37 -0700 Subject: [PATCH 159/191] Fix incorrect behavior of the sidenav when dealing with long non-wrapping page titles. (#1229) - When I was last fiddling with the sidenav on mobile, I messed up the sizing for non-mobile cases. This cause the sidenav to grow beyond its expected size when presented with long non-wrapping page titles. The text is now wrapped instead as it should. - Shrank the font size of the list items in the sidenav to 85% to reduce the amount of wrapping that happens. - Reduce the right margin in the side nav to again try to reduce the amount of wrapping. --- _sass/modules/_sidebar.scss | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/_sass/modules/_sidebar.scss b/_sass/modules/_sidebar.scss index 1146a4395549..63e3f680c66d 100644 --- a/_sass/modules/_sidebar.scss +++ b/_sass/modules/_sidebar.scss @@ -4,11 +4,16 @@ z-index: 42; left: -1500px; width: auto; - max-width: 80%; top: $headerHeight; position: absolute; } + @media (max-width: calc($bp-md - 1)) { + .row-offcanvas .sidebar-offcanvas { + max-width: 80%; + } + } + .row-offcanvas.active .sidebar-offcanvas { left: 2rem; } @@ -24,7 +29,7 @@ order: 0; font-size: 85%; - @media (min-width: $bp-lg) { + @media (min-width: $bp-xl) { font-size: 100%; } @@ -110,11 +115,7 @@ @media (min-width: $bp-lg) { .card-body { padding-left: 1.25rem; - padding-right: 1.25rem; - } - - li { - font-size: 100%; + padding-right: 0.5rem; } ul { From 8e271cc89653a70dab088daee2fc5b8268be34d4 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Wed, 2 May 2018 08:50:13 -0700 Subject: [PATCH 160/191] Update content to help upcoming migration from Jekyll to Hugo (#1232) - In front matter, order: and overview: are now weight: and description: - In front matter, we generally don't need layout: and use config to assign layouts automatically - Remove the useless type: front-matter entries, the type is infered from the file extension. --- 404.md | 5 ++-- _about/contribute/creating-a-pull-request.md | 6 ++-- _about/contribute/editing.md | 6 ++-- _about/contribute/index.md | 6 ++-- _about/contribute/reviewing-doc-issues.md | 6 ++-- _about/contribute/staging-your-changes.md | 6 ++-- _about/contribute/style-guide.md | 6 ++-- _about/contribute/writing-a-new-topic.md | 25 +++++----------- _about/feature-stages.md | 6 ++-- _about/index.md | 6 ++-- _about/intro.md | 6 ++-- _about/notes/0.1.md | 4 +-- _about/notes/0.2.md | 4 +-- _about/notes/0.3.md | 4 +-- _about/notes/0.4.md | 4 +-- _about/notes/0.5.md | 4 +-- _about/notes/0.6.md | 4 +-- _about/notes/0.7.md | 4 +-- _about/notes/0.8.md | 5 +--- _about/notes/index.md | 6 ++-- _blog/2017/0.1-announcement.md | 8 ++--- _blog/2017/0.1-auth.md | 8 ++--- _blog/2017/0.1-canary.md | 8 ++--- _blog/2017/0.1-using-network-policy.md | 8 ++--- _blog/2017/0.2-announcement.md | 8 ++--- _blog/2017/adapter-model.md | 8 ++--- _blog/2017/index.md | 6 ++-- _blog/2017/mixer-spof-myth.md | 8 ++--- _blog/2018/aws-nlb.md | 8 ++--- _blog/2018/egress-https.md | 8 ++--- _blog/2018/egress-tcp.md | 8 ++--- _blog/2018/index.md | 6 ++-- _blog/2018/soft-multitenancy.md | 8 ++--- _blog/2018/traffic-mirroring.md | 8 ++--- _blog/2018/v1alpha3-routing.md | 8 ++--- _blog/index.html | 2 +- _config.yml | 26 ++++++++++++++++ _docs/concepts/index.md | 6 ++-- .../concepts/policy-and-control/attributes.md | 6 ++-- _docs/concepts/policy-and-control/index.md | 6 ++-- .../policy-and-control/mixer-config.md | 6 ++-- _docs/concepts/policy-and-control/mixer.md | 6 ++-- _docs/concepts/security/authn-policy.md | 6 ++-- _docs/concepts/security/index.md | 6 ++-- _docs/concepts/security/mutual-tls.md | 6 ++-- _docs/concepts/security/rbac.md | 6 ++-- .../traffic-management/fault-injection.md | 6 ++-- .../traffic-management/handling-failures.md | 6 ++-- _docs/concepts/traffic-management/index.md | 6 ++-- .../traffic-management/load-balancing.md | 6 ++-- _docs/concepts/traffic-management/overview.md | 6 ++-- _docs/concepts/traffic-management/pilot.md | 6 ++-- .../traffic-management/request-routing.md | 6 ++-- .../traffic-management/rules-configuration.md | 6 ++-- _docs/concepts/what-is-istio/goals.md | 6 ++-- _docs/concepts/what-is-istio/index.md | 6 ++-- _docs/concepts/what-is-istio/overview.md | 6 ++-- _docs/guides/bookinfo.md | 6 ++-- _docs/guides/endpoints.md | 6 ++-- _docs/guides/index.md | 6 ++-- _docs/guides/integrating-vms.md | 6 ++-- _docs/guides/intelligent-routing.md | 6 ++-- _docs/guides/policy-enforcement.md | 6 ++-- _docs/guides/security.md | 6 ++-- _docs/guides/telemetry.md | 6 ++-- _docs/guides/using-external-services.md | 6 ++-- _docs/index.md | 6 ++-- _docs/reference/api/index.md | 6 ++-- _docs/reference/api/istio.mixer.v1.html | 2 +- _docs/reference/commands/index.md | 6 ++-- _docs/reference/commands/istio_ca.html | 2 +- _docs/reference/commands/istioctl.html | 2 +- _docs/reference/commands/mixc.html | 2 +- _docs/reference/commands/mixs.html | 2 +- _docs/reference/commands/node_agent.html | 2 +- _docs/reference/commands/pilot-agent.html | 2 +- _docs/reference/commands/pilot-discovery.html | 2 +- .../reference/commands/sidecar-injector.html | 2 +- _docs/reference/config/adapters/circonus.html | 2 +- .../reference/config/adapters/cloudwatch.html | 2 +- _docs/reference/config/adapters/datadog.html | 2 +- _docs/reference/config/adapters/denier.html | 2 +- _docs/reference/config/adapters/fluentd.html | 2 +- _docs/reference/config/adapters/index.md | 6 ++-- .../config/adapters/kubernetesenv.html | 2 +- _docs/reference/config/adapters/list.html | 2 +- _docs/reference/config/adapters/memquota.html | 2 +- _docs/reference/config/adapters/opa.html | 2 +- .../reference/config/adapters/prometheus.html | 2 +- _docs/reference/config/adapters/rbac.html | 2 +- .../reference/config/adapters/redisquota.html | 2 +- .../config/adapters/servicecontrol.html | 2 +- .../reference/config/adapters/solarwinds.html | 2 +- .../config/adapters/stackdriver.html | 2 +- _docs/reference/config/adapters/statsd.html | 2 +- _docs/reference/config/adapters/stdio.html | 2 +- _docs/reference/config/index.md | 6 ++-- .../reference/config/istio.mesh.v1alpha1.html | 2 +- .../config/istio.networking.v1alpha3.html | 2 +- .../config/istio.policy.v1beta1.html | 2 +- .../reference/config/istio.rbac.v1alpha1.html | 2 +- .../config/istio.routing.v1alpha1.html | 2 +- .../config/mixer/attribute-vocabulary.md | 6 ++-- .../config/mixer/expression-language.md | 6 ++-- _docs/reference/config/mixer/index.md | 6 ++-- _docs/reference/config/template/apikey.html | 2 +- .../config/template/authorization.html | 2 +- .../config/template/checknothing.html | 2 +- _docs/reference/config/template/index.md | 6 ++-- .../reference/config/template/kubernetes.html | 2 +- .../reference/config/template/listentry.html | 2 +- _docs/reference/config/template/logentry.html | 2 +- _docs/reference/config/template/metric.html | 2 +- _docs/reference/config/template/quota.html | 2 +- .../config/template/reportnothing.html | 2 +- .../config/template/servicecontrolreport.html | 2 +- _docs/reference/index.md | 6 ++-- _docs/setup/cloudfoundry/index.md | 6 ++-- _docs/setup/cloudfoundry/install.md | 6 ++-- _docs/setup/consul/index.md | 6 ++-- _docs/setup/consul/install.md | 6 ++-- _docs/setup/consul/quick-start.md | 6 ++-- _docs/setup/eureka/index.md | 6 ++-- _docs/setup/eureka/install.md | 6 ++-- _docs/setup/eureka/quick-start.md | 6 ++-- _docs/setup/index.md | 6 ++-- _docs/setup/kubernetes/advanced-install.md | 6 ++-- _docs/setup/kubernetes/ansible-install.md | 6 ++-- _docs/setup/kubernetes/helm-install.md | 6 ++-- _docs/setup/kubernetes/index.md | 6 ++-- _docs/setup/kubernetes/mesh-expansion.md | 6 ++-- .../setup/kubernetes/multicluster-install.md | 6 ++-- _docs/setup/kubernetes/quick-start-gke-dm.md | 6 ++-- _docs/setup/kubernetes/quick-start.md | 6 ++-- _docs/setup/kubernetes/sidecar-injection.md | 6 ++-- _docs/setup/kubernetes/upgrading-istio.md | 6 ++-- _docs/setup/mesos/index.md | 6 ++-- _docs/setup/mesos/install.md | 6 ++-- _docs/tasks/index.md | 6 ++-- _docs/tasks/policy-enforcement/index.md | 6 ++-- .../tasks/policy-enforcement/rate-limiting.md | 6 ++-- _docs/tasks/security/authn-policy.md | 6 ++-- _docs/tasks/security/basic-access-control.md | 6 ++-- _docs/tasks/security/health-check.md | 6 ++-- _docs/tasks/security/https-overlay.md | 6 ++-- _docs/tasks/security/index.md | 6 ++-- _docs/tasks/security/mutual-tls.md | 6 ++-- _docs/tasks/security/per-service-mtls.md | 6 ++-- _docs/tasks/security/plugin-ca-cert.md | 6 ++-- .../security/role-based-access-control.md | 6 ++-- _docs/tasks/security/secure-access-control.md | 6 ++-- _docs/tasks/telemetry/distributed-tracing.md | 6 ++-- _docs/tasks/telemetry/fluentd.md | 6 ++-- _docs/tasks/telemetry/index.md | 6 ++-- _docs/tasks/telemetry/metrics-logs.md | 6 ++-- _docs/tasks/telemetry/querying-metrics.md | 6 ++-- _docs/tasks/telemetry/servicegraph.md | 6 ++-- _docs/tasks/telemetry/tcp-metrics.md | 6 ++-- .../tasks/telemetry/using-istio-dashboard.md | 6 ++-- .../circuit-breaking.md | 6 ++-- .../traffic-management-v1alpha3/egress-tcp.md | 6 ++-- .../traffic-management-v1alpha3/egress.md | 6 ++-- .../fault-injection.md | 6 ++-- .../traffic-management-v1alpha3/index.md | 6 ++-- .../traffic-management-v1alpha3/ingress.md | 6 ++-- .../traffic-management-v1alpha3/mirroring.md | 6 ++-- .../request-routing.md | 6 ++-- .../request-timeouts.md | 6 ++-- .../traffic-shifting.md | 6 ++-- .../traffic-management/circuit-breaking.md | 6 ++-- _docs/tasks/traffic-management/egress-tcp.md | 6 ++-- _docs/tasks/traffic-management/egress.md | 6 ++-- .../traffic-management/fault-injection.md | 6 ++-- _docs/tasks/traffic-management/index.md | 6 ++-- _docs/tasks/traffic-management/ingress.md | 6 ++-- _docs/tasks/traffic-management/mirroring.md | 6 ++-- .../traffic-management/request-routing.md | 6 ++-- .../traffic-management/request-timeouts.md | 6 ++-- .../traffic-management/traffic-shifting.md | 6 ++-- _faq/general/how-do-i-contribute.md | 3 +- _faq/general/how-do-i-get-started.md | 3 +- _faq/general/how-was-istio-started.md | 3 +- _faq/general/istio-doesnt-work.md | 3 +- _faq/general/istio-partners-and-vendors.md | 3 +- _faq/general/roadmap.md | 3 +- _faq/general/what-deployment-environment.md | 3 +- _faq/general/what-does-istio-mean.md | 3 +- _faq/general/what-is-istio.md | 3 +- _faq/general/what-is-the-license.md | 3 +- _faq/general/where-is-the-documentation.md | 3 +- _faq/general/why-use-istio.md | 3 +- _faq/mixer/attribute-expressions.md | 3 +- _faq/mixer/mixer-self-monitoring.md | 3 +- _faq/mixer/seeing-mixer-config.md | 3 +- _faq/mixer/why-mixer.md | 3 +- _faq/mixer/writing-custom-adapters.md | 3 +- _faq/security/accessing-control-services.md | 3 +- _faq/security/auth-mix-and-match.md | 3 +- _faq/security/cert-lifetime-config.md | 3 +- .../does-istio-support-authorization.md | 3 +- _faq/security/enabling-disabling-mtls.md | 3 +- _faq/security/https-overlay.md | 3 +- _faq/security/istio-to-not-istio.md | 3 +- _faq/security/k8s-api-server.md | 3 +- _faq/security/k8s-health-checks.md | 3 +- _faq/security/secret-encryption.md | 3 +- _faq/security/secure-ingress.md | 3 +- _faq/security/use-k8s-secrets.md | 3 +- _faq/setup/consul-app-not-working.md | 3 +- _faq/setup/consul-unset-context.md | 3 +- _faq/setup/eureka-app-not-working.md | 3 +- _faq/setup/eureka-unset-context.md | 3 +- .../k8s-checking-cluster-alpha-features.md | 3 +- _faq/setup/k8s-migrating.md | 3 +- .../k8s-sidecar-injection-not-working.md | 3 +- .../ingress-with-no-route-rules.md | 3 +- .../unreachable-services.md | 3 +- .../viewing-current-rules.md | 3 +- .../weighted-rules-not-working.md | 3 +- _glossary/adapters.md | 1 - _glossary/attribute.md | 1 - _glossary/destination.md | 1 - _glossary/envoy.md | 1 - _glossary/mixer-handler.md | 1 - _glossary/mixer-instance.md | 1 - _glossary/mixer.md | 1 - _glossary/mutual-tls.md | 1 - _glossary/pilot.md | 1 - _glossary/secure-naming.md | 1 - _glossary/service-consumer.md | 1 - _glossary/service-endpoint.md | 1 - _glossary/service-mesh.md | 1 - _glossary/service-name.md | 1 - _glossary/service-operator.md | 1 - _glossary/service-producer.md | 1 - _glossary/service-version.md | 1 - _glossary/service.md | 1 - _glossary/source.md | 1 - _glossary/workload-id.md | 1 - _glossary/workload-name.md | 1 - _glossary/workload-principal.md | 1 - _glossary/workload.md | 1 - _help/bugs.md | 6 ++-- _help/faq/general.html | 4 +-- _help/faq/index.md | 6 ++-- _help/faq/mixer.html | 4 +-- _help/faq/security.html | 4 +-- _help/faq/setup.html | 4 +-- _help/faq/traffic-management.html | 4 +-- _help/glossary.md | 6 ++-- _help/index.md | 6 ++-- _help/troubleshooting.md | 6 ++-- _includes/collection_nav.html | 8 ++--- _includes/faq.html | 2 +- _includes/latest_blog_post.html | 2 +- _includes/primary.html | 4 +-- _includes/section-index.html | 8 ++--- _includes/sidebar.html | 12 ++++---- _includes/sort-hierarchy.html | 30 +++++++++---------- _layouts/base.html | 4 +-- community.md | 3 +- 261 files changed, 447 insertions(+), 774 deletions(-) diff --git a/404.md b/404.md index fd1a6ec28625..8eb11d0d4eca 100644 --- a/404.md +++ b/404.md @@ -1,11 +1,10 @@ --- title: Page Not Found -overview: Page redirection +description: Page redirection -order: 0 +weight: 1 layout: notfound -type: markdown --- {% include home.html %} diff --git a/_about/contribute/creating-a-pull-request.md b/_about/contribute/creating-a-pull-request.md index 9eb339f6cecf..59b0eebf8697 100644 --- a/_about/contribute/creating-a-pull-request.md +++ b/_about/contribute/creating-a-pull-request.md @@ -1,11 +1,9 @@ --- title: Creating a Pull Request -overview: Shows you how to create a GitHub pull request in order to submit your docs for approval. +description: Shows you how to create a GitHub pull request in order to submit your docs for approval. -order: 20 +weight: 20 -layout: about -type: markdown redirect_from: /docs/welcome/contribute/creating-a-pull-request.html --- diff --git a/_about/contribute/editing.md b/_about/contribute/editing.md index cb509d384a31..28d7b8fbab59 100644 --- a/_about/contribute/editing.md +++ b/_about/contribute/editing.md @@ -1,11 +1,9 @@ --- title: Editing Docs -overview: Lets you start editing this site's documentation. +description: Lets you start editing this site's documentation. -order: 10 +weight: 10 -layout: about -type: markdown redirect_from: /docs/welcome/contribute/editing.html --- diff --git a/_about/contribute/index.md b/_about/contribute/index.md index 9289e1fa7d99..16c808dc5be0 100644 --- a/_about/contribute/index.md +++ b/_about/contribute/index.md @@ -1,11 +1,9 @@ --- title: Contributing to the Docs -overview: Learn how to contribute to improve and expand the Istio documentation. +description: Learn how to contribute to improve and expand the Istio documentation. -order: 100 +weight: 100 -layout: about -type: markdown toc: false redirect_from: /docs/welcome/contribute/index.html --- diff --git a/_about/contribute/reviewing-doc-issues.md b/_about/contribute/reviewing-doc-issues.md index 5c2a2f57ebef..5c2ef7df21bf 100644 --- a/_about/contribute/reviewing-doc-issues.md +++ b/_about/contribute/reviewing-doc-issues.md @@ -1,11 +1,9 @@ --- title: Doc Issues -overview: Explains the process involved in accepting documentation updates. +description: Explains the process involved in accepting documentation updates. -order: 60 +weight: 60 -layout: about -type: markdown redirect_from: /docs/welcome/contribute/reviewing-doc-issues.html --- diff --git a/_about/contribute/staging-your-changes.md b/_about/contribute/staging-your-changes.md index 7e56e0e5dee4..92b95be05d2f 100644 --- a/_about/contribute/staging-your-changes.md +++ b/_about/contribute/staging-your-changes.md @@ -1,11 +1,9 @@ --- title: Staging Your Changes -overview: Explains how to test your changes locally before submitting them. +description: Explains how to test your changes locally before submitting them. -order: 40 +weight: 40 -layout: about -type: markdown redirect_from: /docs/welcome/contribute/staging-your-changes.html --- diff --git a/_about/contribute/style-guide.md b/_about/contribute/style-guide.md index 1d1f4b632631..0af67773fec2 100644 --- a/_about/contribute/style-guide.md +++ b/_about/contribute/style-guide.md @@ -1,11 +1,9 @@ --- title: Style Guide -overview: Explains the dos and donts of writing Istio docs. +description: Explains the dos and donts of writing Istio docs. -order: 70 +weight: 70 -layout: about -type: markdown redirect_from: /docs/welcome/contribute/style-guide.html --- diff --git a/_about/contribute/writing-a-new-topic.md b/_about/contribute/writing-a-new-topic.md index b5dd5c9acdff..84cb438916c5 100644 --- a/_about/contribute/writing-a-new-topic.md +++ b/_about/contribute/writing-a-new-topic.md @@ -1,11 +1,9 @@ --- title: Writing a New Topic -overview: Explains the mechanics of creating new documentation pages. +description: Explains the mechanics of creating new documentation pages. -order: 30 +weight: 30 -layout: about -type: markdown redirect_from: /docs/welcome/contribute/writing-a-new-topic.html --- {% include home.html %} @@ -88,12 +86,9 @@ chunk of front matter you should start with: ```yaml --- title: -overview: <overview> +description: <overview> -order: <order> - -layout: docs -type: markdown +weight: <order> --- ``` @@ -272,12 +267,10 @@ For example ```xxx --- title: Frequently Asked Questions -overview: Questions Asked Frequently +description: Questions Asked Frequently -order: 12 +weight: 12 -layout: docs -type: markdown redirect_from: /faq --- @@ -291,12 +284,10 @@ You can also add many redirects like so: ```xxx --- title: Frequently Asked Questions -overview: Questions Asked Frequently +description: Questions Asked Frequently -order: 12 +weight: 12 -layout: docs -type: markdown redirect_from: - /faq - /faq2 diff --git a/_about/feature-stages.md b/_about/feature-stages.md index ad6430741ce6..cb7b1934dea8 100644 --- a/_about/feature-stages.md +++ b/_about/feature-stages.md @@ -1,11 +1,9 @@ --- title: Feature Status -overview: List of features and their release stages. +description: List of features and their release stages. -order: 10 +weight: 10 -layout: about -type: markdown redirect_from: - "/docs/reference/release-roadmap.html" - "/docs/reference/feature-stages.html" diff --git a/_about/index.md b/_about/index.md index 35f36f830a29..d0410be0c0db 100644 --- a/_about/index.md +++ b/_about/index.md @@ -1,11 +1,9 @@ --- title: About Istio -overview: All about Istio. +description: All about Istio. -order: 15 +weight: 15 -layout: about -type: markdown toc: false --- {% include home.html %} diff --git a/_about/intro.md b/_about/intro.md index 07fbad2336db..0c8197f6cc57 100644 --- a/_about/intro.md +++ b/_about/intro.md @@ -1,11 +1,9 @@ --- title: What is Istio? -overview: Context about what problems Istio is designed to solve. +description: Context about what problems Istio is designed to solve. -order: 0 +weight: 1 -layout: about -type: markdown toc: false --- diff --git a/_about/notes/0.1.md b/_about/notes/0.1.md index 8c21c7494438..fda82fa1c6fb 100644 --- a/_about/notes/0.1.md +++ b/_about/notes/0.1.md @@ -1,10 +1,8 @@ --- title: Istio 0.1 -order: 100 +weight: 100 -layout: about -type: markdown toc: false redirect_from: /docs/welcome/notes/0.1.html --- diff --git a/_about/notes/0.2.md b/_about/notes/0.2.md index d00f38ae6159..5271b83fe6e5 100644 --- a/_about/notes/0.2.md +++ b/_about/notes/0.2.md @@ -1,10 +1,8 @@ --- title: Istio 0.2 -order: 99 +weight: 99 -layout: about -type: markdown redirect_from: /docs/welcome/notes/0.2.html --- diff --git a/_about/notes/0.3.md b/_about/notes/0.3.md index 9da8f33569af..524eb9c287c2 100644 --- a/_about/notes/0.3.md +++ b/_about/notes/0.3.md @@ -1,10 +1,8 @@ --- title: Istio 0.3 -order: 98 +weight: 98 -layout: about -type: markdown redirect_from: /docs/welcome/notes/0.3.html --- diff --git a/_about/notes/0.4.md b/_about/notes/0.4.md index 64354e693570..668ca439c232 100644 --- a/_about/notes/0.4.md +++ b/_about/notes/0.4.md @@ -1,10 +1,8 @@ --- title: Istio 0.4 -order: 97 +weight: 97 -layout: about -type: markdown toc: false redirect_from: /docs/welcome/notes/0.4.html --- diff --git a/_about/notes/0.5.md b/_about/notes/0.5.md index 8d9fd885f6a9..7adb9f5be821 100644 --- a/_about/notes/0.5.md +++ b/_about/notes/0.5.md @@ -1,10 +1,8 @@ --- title: Istio 0.5 -order: 96 +weight: 96 -layout: about -type: markdown --- {% include home.html %} diff --git a/_about/notes/0.6.md b/_about/notes/0.6.md index cc058b05e498..c527fc1d85b7 100644 --- a/_about/notes/0.6.md +++ b/_about/notes/0.6.md @@ -1,10 +1,8 @@ --- title: Istio 0.6 -order: 95 +weight: 95 -layout: about -type: markdown --- {% include home.html %} diff --git a/_about/notes/0.7.md b/_about/notes/0.7.md index 9cd922587f62..b5c061b96c4d 100644 --- a/_about/notes/0.7.md +++ b/_about/notes/0.7.md @@ -1,10 +1,8 @@ --- title: Istio 0.7 -order: 94 +weight: 94 -layout: about -type: markdown --- {% include home.html %} diff --git a/_about/notes/0.8.md b/_about/notes/0.8.md index ff7b3f73f4cd..c1329a6bebd6 100644 --- a/_about/notes/0.8.md +++ b/_about/notes/0.8.md @@ -1,10 +1,7 @@ --- title: Istio 0.8 -order: 93 - -layout: about -type: markdown +weight: 93 --- {% include home.html %} diff --git a/_about/notes/index.md b/_about/notes/index.md index e3d8bad07a6e..72ed6d3faa6c 100644 --- a/_about/notes/index.md +++ b/_about/notes/index.md @@ -1,11 +1,9 @@ --- title: Release Notes -overview: Description of features and improvements for every Istio release. +description: Description of features and improvements for every Istio release. -order: 5 +weight: 5 -layout: about -type: markdown redirect_from: - "/docs/reference/release-notes.html" - "/release-notes" diff --git a/_blog/2017/0.1-announcement.md b/_blog/2017/0.1-announcement.md index dfd11574d9a6..9bb0c4647e3e 100644 --- a/_blog/2017/0.1-announcement.md +++ b/_blog/2017/0.1-announcement.md @@ -1,14 +1,12 @@ --- -title: "Introducing Istio" -overview: Istio 0.1 announcement +title: Introducing Istio +description: Istio 0.1 announcement publish_date: May 24, 2017 subtitle: A robust service mesh for microservices attribution: The Istio Team -order: 100 +weight: 100 -layout: blog -type: markdown redirect_from: - "/blog/istio-service-mesh-for-microservices.html" - "/blog/0.1-announcement.html" diff --git a/_blog/2017/0.1-auth.md b/_blog/2017/0.1-auth.md index 17f7591cb588..10d6699d4cc5 100644 --- a/_blog/2017/0.1-auth.md +++ b/_blog/2017/0.1-auth.md @@ -1,14 +1,12 @@ --- -title: "Using Istio to Improve End-to-End Security" -overview: Istio Auth 0.1 announcement +title: Using Istio to Improve End-to-End Security +description: Istio Auth 0.1 announcement publish_date: May 25, 2017 subtitle: Secure by default service to service communications attribution: The Istio Team -order: 99 +weight: 99 -layout: blog -type: markdown redirect_from: - "/blog/0.1-auth.html" - "/blog/istio-auth-for-microservices.html" diff --git a/_blog/2017/0.1-canary.md b/_blog/2017/0.1-canary.md index d41fa99dab71..ffd8364866f2 100644 --- a/_blog/2017/0.1-canary.md +++ b/_blog/2017/0.1-canary.md @@ -1,14 +1,12 @@ --- -title: "Canary Deployments using Istio" -overview: Using Istio to create autoscaled canary deployments +title: Canary Deployments using Istio +description: Using Istio to create autoscaled canary deployments publish_date: June 14, 2017 subtitle: attribution: Frank Budinsky -order: 98 +weight: 98 -layout: blog -type: markdown redirect_from: "/blog/canary-deployments-using-istio.html" --- diff --git a/_blog/2017/0.1-using-network-policy.md b/_blog/2017/0.1-using-network-policy.md index 8990ded9f69a..691f9271bd5b 100644 --- a/_blog/2017/0.1-using-network-policy.md +++ b/_blog/2017/0.1-using-network-policy.md @@ -1,14 +1,12 @@ --- -title: "Using Network Policy with Istio" -overview: How Kubernetes Network Policy relates to Istio policy +title: Using Network Policy with Istio +description: How Kubernetes Network Policy relates to Istio policy publish_date: August 10, 2017 subtitle: attribution: Spike Curtis -order: 97 +weight: 97 -layout: blog -type: markdown redirect_from: "/blog/using-network-policy-in-concert-with-istio.html" --- {% include home.html %} diff --git a/_blog/2017/0.2-announcement.md b/_blog/2017/0.2-announcement.md index 4cfa71dd9479..6491ff14ad51 100644 --- a/_blog/2017/0.2-announcement.md +++ b/_blog/2017/0.2-announcement.md @@ -1,14 +1,12 @@ --- -title: "Announcing Istio 0.2" -overview: Istio 0.2 announcement +title: Announcing Istio 0.2 +description: Istio 0.2 announcement publish_date: October 10, 2017 subtitle: Improved mesh and support for multiple environments attribution: The Istio Team -order: 96 +weight: 96 -layout: blog -type: markdown toc: false redirect_from: "/blog/istio-0.2-announcement.html" --- diff --git a/_blog/2017/adapter-model.md b/_blog/2017/adapter-model.md index 00b0f42fe56a..c5cd94afecaa 100644 --- a/_blog/2017/adapter-model.md +++ b/_blog/2017/adapter-model.md @@ -1,14 +1,12 @@ --- -title: "Mixer Adapter Model" -overview: Provides an overview of the Mixer plug-in architecture +title: Mixer Adapter Model +description: Provides an overview of the Mixer plug-in architecture publish_date: November 3, 2017 subtitle: Extending Istio to integrate with a world of infrastructure backends attribution: Martin Taillefer -order: 95 +weight: 95 -layout: blog -type: markdown redirect_from: "/blog/mixer-adapter-model.html" --- {% include home.html %} diff --git a/_blog/2017/index.md b/_blog/2017/index.md index f51ac13fa698..bbf92652a356 100644 --- a/_blog/2017/index.md +++ b/_blog/2017/index.md @@ -1,11 +1,9 @@ --- title: 2017 Posts -overview: Blog posts for 2017 +description: Blog posts for 2017 -order: 20 +weight: 20 -layout: blog -type: markdown toc: false --- diff --git a/_blog/2017/mixer-spof-myth.md b/_blog/2017/mixer-spof-myth.md index 98857380da7c..88851bf343dc 100644 --- a/_blog/2017/mixer-spof-myth.md +++ b/_blog/2017/mixer-spof-myth.md @@ -1,14 +1,12 @@ --- -title: "Mixer and the SPOF Myth" -overview: Improving availability and reducing latency +title: Mixer and the SPOF Myth +description: Improving availability and reducing latency publish_date: December 7, 2017 subtitle: Improving availability and reducing latency attribution: Martin Taillefer -order: 94 +weight: 94 -layout: blog -type: markdown redirect_from: /blog/posts/2017/mixer-spof-myth.html --- {% include home.html %} diff --git a/_blog/2018/aws-nlb.md b/_blog/2018/aws-nlb.md index f03772b5312c..dd48fee409ec 100644 --- a/_blog/2018/aws-nlb.md +++ b/_blog/2018/aws-nlb.md @@ -1,14 +1,12 @@ --- -title: "Configuring Istio Ingress with AWS NLB" -overview: Describes how to configure Istio ingress with a network load balancer on AWS +title: Configuring Istio Ingress with AWS NLB +description: Describes how to configure Istio ingress with a network load balancer on AWS publish_date: April 20, 2018 subtitle: Ingress AWS Network Load Balancer attribution: Julien SENON -order: 89 +weight: 89 -layout: blog -type: markdown redirect_from: "/blog/aws-nlb.html" --- {% include home.html %} diff --git a/_blog/2018/egress-https.md b/_blog/2018/egress-https.md index 59e9bf5e09a7..a022c5c927b0 100644 --- a/_blog/2018/egress-https.md +++ b/_blog/2018/egress-https.md @@ -1,14 +1,12 @@ --- -title: "Consuming External Web Services" -overview: Describes a simple scenario based on Istio Bookinfo sample +title: Consuming External Web Services +description: Describes a simple scenario based on Istio Bookinfo sample publish_date: January 31, 2018 subtitle: Egress Rules for HTTPS traffic attribution: Vadim Eisenberg -order: 93 +weight: 93 -layout: blog -type: markdown redirect_from: "/blog/egress-https.html" --- {% include home.html %} diff --git a/_blog/2018/egress-tcp.md b/_blog/2018/egress-tcp.md index f72dd95aa197..c4caac844366 100644 --- a/_blog/2018/egress-tcp.md +++ b/_blog/2018/egress-tcp.md @@ -1,14 +1,12 @@ --- -title: "Consuming External TCP Services" -overview: Describes a simple scenario based on Istio Bookinfo sample +title: Consuming External TCP Services +description: Describes a simple scenario based on Istio Bookinfo sample publish_date: February 6, 2018 subtitle: Egress rules for TCP traffic attribution: Vadim Eisenberg -order: 92 +weight: 92 -layout: blog -type: markdown redirect_from: "/blog/egress-tcp.html" --- {% include home.html %} diff --git a/_blog/2018/index.md b/_blog/2018/index.md index e5fc78630b38..89268583c41e 100644 --- a/_blog/2018/index.md +++ b/_blog/2018/index.md @@ -1,11 +1,9 @@ --- title: 2018 Posts -overview: Blog posts for 2018 +description: Blog posts for 2018 -order: 10 +weight: 10 -layout: blog -type: markdown toc: false --- diff --git a/_blog/2018/soft-multitenancy.md b/_blog/2018/soft-multitenancy.md index 53c7d047a3c3..0c7e8ba0f86b 100644 --- a/_blog/2018/soft-multitenancy.md +++ b/_blog/2018/soft-multitenancy.md @@ -1,14 +1,12 @@ --- -title: "Istio Soft Multi-tenancy Support" -overview: Using Kubernetes namespace and RBAC to create an Istio soft multi-tenancy environment +title: Istio Soft Multi-tenancy Support +description: Using Kubernetes namespace and RBAC to create an Istio soft multi-tenancy environment publish_date: April 19, 2018 subtitle: Using multiple Istio control planes and RBAC to create multi-tenancy attribution: John Joyce and Rich Curran -order: 90 +weight: 90 -layout: blog -type: markdown redirect_from: "/blog/soft-multitenancy.html" --- {% include home.html %} diff --git a/_blog/2018/traffic-mirroring.md b/_blog/2018/traffic-mirroring.md index d28f0721cf4a..e5866f42c149 100644 --- a/_blog/2018/traffic-mirroring.md +++ b/_blog/2018/traffic-mirroring.md @@ -1,14 +1,12 @@ --- -title: "Traffic Mirroring with Istio for Testing in Production" -overview: An introduction to safer, lower-risk deployments and release to production +title: Traffic Mirroring with Istio for Testing in Production +description: An introduction to safer, lower-risk deployments and release to production publish_date: February 8, 2018 subtitle: Routing rules for HTTP traffic attribution: Christian Posta -order: 91 +weight: 91 -layout: blog -type: markdown redirect_from: "/blog/traffic-mirroring.html" --- {% include home.html %} diff --git a/_blog/2018/v1alpha3-routing.md b/_blog/2018/v1alpha3-routing.md index 353e326a1532..69c1da1539f3 100644 --- a/_blog/2018/v1alpha3-routing.md +++ b/_blog/2018/v1alpha3-routing.md @@ -1,14 +1,12 @@ --- -title: "Introducing the Istio v1alpha3 routing API" -overview: Introduction, motivation and design principles for the Istio v1alpha3 routing API. +title: Introducing the Istio v1alpha3 routing API +description: Introduction, motivation and design principles for the Istio v1alpha3 routing API. publish_date: April 25, 2018 subtitle: attribution: Frank Budinsky (IBM) and Shriram Rajagopalan (VMware) -order: 88 +weight: 88 -layout: blog -type: markdown redirect_from: "/blog/v1alpha3-routing.html" --- diff --git a/_blog/index.html b/_blog/index.html index 4bd0c3793523..ff36940b5e0c 100644 --- a/_blog/index.html +++ b/_blog/index.html @@ -1,6 +1,6 @@ --- title: Istio Blog -overview: The Istio blog +description: The Istio blog layout: compress --- {% include latest_blog_post.html %} diff --git a/_config.yml b/_config.yml index 32442467cf96..4757003cb9c1 100644 --- a/_config.yml +++ b/_config.yml @@ -42,6 +42,32 @@ plugins: - jekyll-redirect-from - jekyll-sitemap +defaults: + - + scope: + path: "" + type: "about" + values: + layout: "about" + - + scope: + path: "" + type: "docs" + values: + layout: "docs" + - + scope: + path: "" + type: "help" + values: + layout: "help" + - + scope: + path: "" + type: "blog" + values: + layout: "blog" + exclude: - README.md - LICENSE diff --git a/_docs/concepts/index.md b/_docs/concepts/index.md index 1fc77af69f9e..5134317c9a9e 100644 --- a/_docs/concepts/index.md +++ b/_docs/concepts/index.md @@ -1,11 +1,9 @@ --- title: Concepts -overview: Concepts help you learn about the different parts of the Istio system and the abstractions it uses. +description: Concepts help you learn about the different parts of the Istio system and the abstractions it uses. -order: 10 +weight: 10 -layout: docs -type: markdown toc: false --- diff --git a/_docs/concepts/policy-and-control/attributes.md b/_docs/concepts/policy-and-control/attributes.md index 98c8cfde6043..5ab5a8a07b89 100644 --- a/_docs/concepts/policy-and-control/attributes.md +++ b/_docs/concepts/policy-and-control/attributes.md @@ -1,11 +1,9 @@ --- title: Attributes -overview: Explains the important notion of attributes, which is a central mechanism for how policies and control are applied to services within the mesh. +description: Explains the important notion of attributes, which is a central mechanism for how policies and control are applied to services within the mesh. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/policy-and-control/index.md b/_docs/concepts/policy-and-control/index.md index c85f12f4afda..11ee676ce62c 100644 --- a/_docs/concepts/policy-and-control/index.md +++ b/_docs/concepts/policy-and-control/index.md @@ -1,11 +1,9 @@ --- title: Policies and Control -overview: Introduces the policy control mechanisms. +description: Introduces the policy control mechanisms. -order: 40 +weight: 40 -layout: docs -type: markdown toc: false --- diff --git a/_docs/concepts/policy-and-control/mixer-config.md b/_docs/concepts/policy-and-control/mixer-config.md index 7c5602c7ad9f..2414a1ef209c 100644 --- a/_docs/concepts/policy-and-control/mixer-config.md +++ b/_docs/concepts/policy-and-control/mixer-config.md @@ -1,11 +1,9 @@ --- title: Mixer Configuration -overview: An overview of the key concepts used to configure Mixer. +description: An overview of the key concepts used to configure Mixer. -order: 30 +weight: 30 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/policy-and-control/mixer.md b/_docs/concepts/policy-and-control/mixer.md index 3d94998a9467..9921d9fdf7ef 100644 --- a/_docs/concepts/policy-and-control/mixer.md +++ b/_docs/concepts/policy-and-control/mixer.md @@ -1,11 +1,9 @@ --- title: Mixer -overview: Architectural deep-dive into the design of Mixer, which provides the policy and control mechanisms within the service mesh. +description: Architectural deep-dive into the design of Mixer, which provides the policy and control mechanisms within the service mesh. -order: 20 +weight: 20 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/security/authn-policy.md b/_docs/concepts/security/authn-policy.md index d3d1e4a13800..9ad14c2e51b0 100644 --- a/_docs/concepts/security/authn-policy.md +++ b/_docs/concepts/security/authn-policy.md @@ -1,11 +1,9 @@ --- title: Istio Authentication Policy -overview: Describes Istio authentication policy +description: Describes Istio authentication policy -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/security/index.md b/_docs/concepts/security/index.md index 8b3170f4f361..c1138c61d27c 100644 --- a/_docs/concepts/security/index.md +++ b/_docs/concepts/security/index.md @@ -1,11 +1,9 @@ --- title: Security -overview: Describes Istio's authorization and authentication functionality. +description: Describes Istio's authorization and authentication functionality. -order: 30 +weight: 30 -layout: docs -type: markdown toc: false --- diff --git a/_docs/concepts/security/mutual-tls.md b/_docs/concepts/security/mutual-tls.md index 1a315ee3bc85..1ece86e9eca4 100644 --- a/_docs/concepts/security/mutual-tls.md +++ b/_docs/concepts/security/mutual-tls.md @@ -1,10 +1,8 @@ --- title: Mutual TLS Authentication -overview: Describes Istio's mutual TLS authentication architecture which provides a strong service identity and secure communication channels between services. -order: 10 +description: Describes Istio's mutual TLS authentication architecture which provides a strong service identity and secure communication channels between services. +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/security/rbac.md b/_docs/concepts/security/rbac.md index ebbcc65740b0..3437d7395350 100644 --- a/_docs/concepts/security/rbac.md +++ b/_docs/concepts/security/rbac.md @@ -1,10 +1,8 @@ --- title: Istio Role-Based Access Control (RBAC) -overview: Describes Istio RBAC which provides access control for services in Istio Mesh. -order: 20 +description: Describes Istio RBAC which provides access control for services in Istio Mesh. +weight: 20 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/traffic-management/fault-injection.md b/_docs/concepts/traffic-management/fault-injection.md index b488076f3846..b8b11b5b31e9 100644 --- a/_docs/concepts/traffic-management/fault-injection.md +++ b/_docs/concepts/traffic-management/fault-injection.md @@ -1,11 +1,9 @@ --- title: Fault Injection -overview: Introduces the idea of systematic fault injection that can be used to uncover conflicting failure recovery policies across services. +description: Introduces the idea of systematic fault injection that can be used to uncover conflicting failure recovery policies across services. -order: 40 +weight: 40 -layout: docs -type: markdown toc: false --- diff --git a/_docs/concepts/traffic-management/handling-failures.md b/_docs/concepts/traffic-management/handling-failures.md index 03536c0f77cc..fb619e6b1787 100644 --- a/_docs/concepts/traffic-management/handling-failures.md +++ b/_docs/concepts/traffic-management/handling-failures.md @@ -1,11 +1,9 @@ --- title: Handling Failures -overview: An overview of failure recovery capabilities in Envoy that can be leveraged by unmodified applications to improve robustness and prevent cascading failures. +description: An overview of failure recovery capabilities in Envoy that can be leveraged by unmodified applications to improve robustness and prevent cascading failures. -order: 30 +weight: 30 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/traffic-management/index.md b/_docs/concepts/traffic-management/index.md index 4940f53f0ac2..db6114be6502 100644 --- a/_docs/concepts/traffic-management/index.md +++ b/_docs/concepts/traffic-management/index.md @@ -1,11 +1,9 @@ --- title: Traffic Management -overview: Describes the various Istio features focused on traffic routing and control. +description: Describes the various Istio features focused on traffic routing and control. -order: 20 +weight: 20 -layout: docs -type: markdown toc: false --- diff --git a/_docs/concepts/traffic-management/load-balancing.md b/_docs/concepts/traffic-management/load-balancing.md index 86f4daadd07c..37db243b84d1 100644 --- a/_docs/concepts/traffic-management/load-balancing.md +++ b/_docs/concepts/traffic-management/load-balancing.md @@ -1,11 +1,9 @@ --- title: Discovery & Load Balancing -overview: Describes how traffic is load balanced across instances of a service in the mesh. +description: Describes how traffic is load balanced across instances of a service in the mesh. -order: 25 +weight: 25 -layout: docs -type: markdown toc: false --- diff --git a/_docs/concepts/traffic-management/overview.md b/_docs/concepts/traffic-management/overview.md index eecce3dcbfdf..64f856bdce5d 100644 --- a/_docs/concepts/traffic-management/overview.md +++ b/_docs/concepts/traffic-management/overview.md @@ -1,11 +1,9 @@ --- title: Overview -overview: Provides a conceptual overview of traffic management in Istio and the features it enables. +description: Provides a conceptual overview of traffic management in Istio and the features it enables. -order: 0 +weight: 1 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/traffic-management/pilot.md b/_docs/concepts/traffic-management/pilot.md index d55455bd96ed..40f301717e08 100644 --- a/_docs/concepts/traffic-management/pilot.md +++ b/_docs/concepts/traffic-management/pilot.md @@ -1,11 +1,9 @@ --- title: Pilot -overview: Introduces Pilot, the component responsible for managing a distributed deployment of Envoy proxies in the service mesh. +description: Introduces Pilot, the component responsible for managing a distributed deployment of Envoy proxies in the service mesh. -order: 10 +weight: 10 -layout: docs -type: markdown toc: false redirect_from: /docs/concepts/traffic-management/manager.html --- diff --git a/_docs/concepts/traffic-management/request-routing.md b/_docs/concepts/traffic-management/request-routing.md index 212837bfc762..2de211c43623 100644 --- a/_docs/concepts/traffic-management/request-routing.md +++ b/_docs/concepts/traffic-management/request-routing.md @@ -1,11 +1,9 @@ --- title: Request Routing -overview: Describes how requests are routed between services in an Istio service mesh. +description: Describes how requests are routed between services in an Istio service mesh. -order: 20 +weight: 20 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/traffic-management/rules-configuration.md b/_docs/concepts/traffic-management/rules-configuration.md index bb52a27b6bb9..77f845da02e2 100644 --- a/_docs/concepts/traffic-management/rules-configuration.md +++ b/_docs/concepts/traffic-management/rules-configuration.md @@ -1,11 +1,9 @@ --- title: Rules Configuration -overview: Provides a high-level overview of the domain-specific language used by Istio to configure traffic management rules in the service mesh. +description: Provides a high-level overview of the domain-specific language used by Istio to configure traffic management rules in the service mesh. -order: 50 +weight: 50 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/concepts/what-is-istio/goals.md b/_docs/concepts/what-is-istio/goals.md index 1e64a5157810..8d055ce6f263 100644 --- a/_docs/concepts/what-is-istio/goals.md +++ b/_docs/concepts/what-is-istio/goals.md @@ -1,11 +1,9 @@ --- title: Design Goals -overview: Describes the core principles that Istio's design adheres to. +description: Describes the core principles that Istio's design adheres to. -order: 20 +weight: 20 -layout: docs -type: markdown --- This page outlines the core principles that guide Istio's design. diff --git a/_docs/concepts/what-is-istio/index.md b/_docs/concepts/what-is-istio/index.md index f8b57d686435..300b912a0473 100644 --- a/_docs/concepts/what-is-istio/index.md +++ b/_docs/concepts/what-is-istio/index.md @@ -1,11 +1,9 @@ --- title: What is Istio? -overview: A broad overview of the Istio system. +description: A broad overview of the Istio system. -order: 10 +weight: 10 -layout: docs -type: markdown toc: false --- diff --git a/_docs/concepts/what-is-istio/overview.md b/_docs/concepts/what-is-istio/overview.md index 6a45be858cd8..869f8f01bf9c 100644 --- a/_docs/concepts/what-is-istio/overview.md +++ b/_docs/concepts/what-is-istio/overview.md @@ -1,11 +1,9 @@ --- title: Overview -overview: Provides a conceptual introduction to Istio, including the problems it solves and its high-level architecture. +description: Provides a conceptual introduction to Istio, including the problems it solves and its high-level architecture. -order: 15 +weight: 15 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/guides/bookinfo.md b/_docs/guides/bookinfo.md index cfdb3c00f944..cf105ed64fa4 100644 --- a/_docs/guides/bookinfo.md +++ b/_docs/guides/bookinfo.md @@ -1,11 +1,9 @@ --- 1;95;0ctitle: Bookinfo Sample Application -overview: This guide deploys a sample application composed of four separate microservices which will be used to demonstrate various features of the Istio service mesh. +description: This guide deploys a sample application composed of four separate microservices which will be used to demonstrate various features of the Istio service mesh. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/guides/endpoints.md b/_docs/guides/endpoints.md index c86562c9dec0..84a41a22b7ab 100644 --- a/_docs/guides/endpoints.md +++ b/_docs/guides/endpoints.md @@ -1,10 +1,8 @@ --- title: Install Istio for Google Cloud Endpoints Services -overview: Explains how to manually integrate Google Cloud Endpoints services with Istio. +description: Explains how to manually integrate Google Cloud Endpoints services with Istio. -order: 42 -layout: docs -type: markdown +weight: 42 --- {% include home.html %} diff --git a/_docs/guides/index.md b/_docs/guides/index.md index 65db87e6c028..065d09191bec 100644 --- a/_docs/guides/index.md +++ b/_docs/guides/index.md @@ -1,11 +1,9 @@ --- title: Guides -overview: Guides include a variety of fully working example uses for Istio that you can experiment with. +description: Guides include a variety of fully working example uses for Istio that you can experiment with. -order: 30 +weight: 30 -layout: docs -type: markdown toc: false --- diff --git a/_docs/guides/integrating-vms.md b/_docs/guides/integrating-vms.md index 428759c8624a..d8a812bc19e1 100644 --- a/_docs/guides/integrating-vms.md +++ b/_docs/guides/integrating-vms.md @@ -1,10 +1,8 @@ --- title: Integrating Virtual Machines -overview: This sample deploys the Bookinfo services across Kubernetes and a set of virtual machines, and illustrates how to use the Istio service mesh to control this infrastructure as a single mesh. +description: This sample deploys the Bookinfo services across Kubernetes and a set of virtual machines, and illustrates how to use the Istio service mesh to control this infrastructure as a single mesh. -order: 60 -layout: docs -type: markdown +weight: 60 --- {% include home.html %} diff --git a/_docs/guides/intelligent-routing.md b/_docs/guides/intelligent-routing.md index c917577cb130..5c6f391bc788 100644 --- a/_docs/guides/intelligent-routing.md +++ b/_docs/guides/intelligent-routing.md @@ -1,10 +1,8 @@ --- title: Intelligent Routing -overview: This guide demonstrates how to use various traffic management capabilities of an Istio service mesh. +description: This guide demonstrates how to use various traffic management capabilities of an Istio service mesh. -order: 20 -layout: docs -type: markdown +weight: 20 --- {% include home.html %} diff --git a/_docs/guides/policy-enforcement.md b/_docs/guides/policy-enforcement.md index cd7993679f16..68d30b2e66e3 100644 --- a/_docs/guides/policy-enforcement.md +++ b/_docs/guides/policy-enforcement.md @@ -1,11 +1,9 @@ --- title: Policy Enforcement -overview: This sample uses the Bookinfo application to demonstrate policy enforcement using Istio Mixer. +description: This sample uses the Bookinfo application to demonstrate policy enforcement using Istio Mixer. -order: 40 +weight: 40 draft: true -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/guides/security.md b/_docs/guides/security.md index f2d348a2b740..2af8822707de 100644 --- a/_docs/guides/security.md +++ b/_docs/guides/security.md @@ -1,11 +1,9 @@ --- title: Security -overview: This sample demonstrates how to obtain uniform metrics, logs, traces across different services using Istio Mixer and Istio sidecar. +description: This sample demonstrates how to obtain uniform metrics, logs, traces across different services using Istio Mixer and Istio sidecar. -order: 30 +weight: 30 draft: true -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/guides/telemetry.md b/_docs/guides/telemetry.md index ee753669f2a9..7076c39a32c1 100644 --- a/_docs/guides/telemetry.md +++ b/_docs/guides/telemetry.md @@ -1,10 +1,8 @@ --- title: In-Depth Telemetry -overview: This sample demonstrates how to obtain uniform metrics, logs, traces across different services using Istio Mixer and Istio sidecar. +description: This sample demonstrates how to obtain uniform metrics, logs, traces across different services using Istio Mixer and Istio sidecar. -order: 30 -layout: docs -type: markdown +weight: 30 --- {% include home.html %} diff --git a/_docs/guides/using-external-services.md b/_docs/guides/using-external-services.md index 5a0ae48c2724..cd3f9692d7a6 100644 --- a/_docs/guides/using-external-services.md +++ b/_docs/guides/using-external-services.md @@ -1,11 +1,9 @@ --- title: Integrating with External Services -overview: This sample integrates third party services with Bookinfo and demonstrates how to use Istio service mesh to provide metrics, and routing functions for these services. +description: This sample integrates third party services with Bookinfo and demonstrates how to use Istio service mesh to provide metrics, and routing functions for these services. -order: 50 +weight: 50 draft: true -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/index.md b/_docs/index.md index f8bc3284d05f..f6f469b61155 100644 --- a/_docs/index.md +++ b/_docs/index.md @@ -1,11 +1,9 @@ --- title: Welcome -overview: Istio documentation home page. +description: Istio documentation home page. -order: 0 +weight: 1 -layout: docs -type: markdown toc: false --- {% include home.html %} diff --git a/_docs/reference/api/index.md b/_docs/reference/api/index.md index f20458e4c0b7..b9e5b9b9cce1 100644 --- a/_docs/reference/api/index.md +++ b/_docs/reference/api/index.md @@ -1,11 +1,9 @@ --- title: API -overview: Detailed information on API parameters. +description: Detailed information on API parameters. -order: 10 +weight: 10 -layout: docs -type: markdown toc: false --- diff --git a/_docs/reference/api/istio.mixer.v1.html b/_docs/reference/api/istio.mixer.v1.html index c347c430fb06..a1815b79b30b 100644 --- a/_docs/reference/api/istio.mixer.v1.html +++ b/_docs/reference/api/istio.mixer.v1.html @@ -1,6 +1,6 @@ --- title: Mixer -overview: API definitions to interact with Mixer +description: API definitions to interact with Mixer location: https://istio.io/docs/reference/api/istio.mixer.v1.html layout: protoc-gen-docs redirect_from: /docs/reference/api/mixer/mixer.html diff --git a/_docs/reference/commands/index.md b/_docs/reference/commands/index.md index 0fd20af35c09..291b1d442c64 100644 --- a/_docs/reference/commands/index.md +++ b/_docs/reference/commands/index.md @@ -1,11 +1,9 @@ --- title: Commands -overview: Describes usage and options of the Istio commands and utilities. +description: Describes usage and options of the Istio commands and utilities. -order: 30 +weight: 30 -layout: docs -type: markdown toc: false --- diff --git a/_docs/reference/commands/istio_ca.html b/_docs/reference/commands/istio_ca.html index 97056eb72b48..51b2f9d84596 100644 --- a/_docs/reference/commands/istio_ca.html +++ b/_docs/reference/commands/istio_ca.html @@ -1,6 +1,6 @@ --- title: istio_ca -overview: Istio Certificate Authority (CA) +description: Istio Certificate Authority (CA) layout: pkg-collateral-docs number_of_entries: 4 --- diff --git a/_docs/reference/commands/istioctl.html b/_docs/reference/commands/istioctl.html index 7b515bbaec34..25d0904271c6 100644 --- a/_docs/reference/commands/istioctl.html +++ b/_docs/reference/commands/istioctl.html @@ -1,6 +1,6 @@ --- title: istioctl -overview: Istio control interface +description: Istio control interface layout: pkg-collateral-docs number_of_entries: 19 --- diff --git a/_docs/reference/commands/mixc.html b/_docs/reference/commands/mixc.html index 534f37e3e5ed..428e0c0ecf9d 100644 --- a/_docs/reference/commands/mixc.html +++ b/_docs/reference/commands/mixc.html @@ -1,6 +1,6 @@ --- title: mixc -overview: Utility to trigger direct calls to Mixer's API. +description: Utility to trigger direct calls to Mixer's API. layout: pkg-collateral-docs number_of_entries: 5 --- diff --git a/_docs/reference/commands/mixs.html b/_docs/reference/commands/mixs.html index 2b24f44d0aad..ccbda2dfe358 100644 --- a/_docs/reference/commands/mixs.html +++ b/_docs/reference/commands/mixs.html @@ -1,6 +1,6 @@ --- title: mixs -overview: Mixer is Istio's abstraction on top of infrastructure backends. +description: Mixer is Istio's abstraction on top of infrastructure backends. layout: pkg-collateral-docs number_of_entries: 9 --- diff --git a/_docs/reference/commands/node_agent.html b/_docs/reference/commands/node_agent.html index ca602e853aaa..94e4d0c99715 100644 --- a/_docs/reference/commands/node_agent.html +++ b/_docs/reference/commands/node_agent.html @@ -1,6 +1,6 @@ --- title: node_agent -overview: Istio security per-node agent +description: Istio security per-node agent layout: pkg-collateral-docs number_of_entries: 3 --- diff --git a/_docs/reference/commands/pilot-agent.html b/_docs/reference/commands/pilot-agent.html index 946bf965cc7f..6672af31aaaa 100644 --- a/_docs/reference/commands/pilot-agent.html +++ b/_docs/reference/commands/pilot-agent.html @@ -1,6 +1,6 @@ --- title: pilot-agent -overview: Istio Pilot agent +description: Istio Pilot agent layout: pkg-collateral-docs number_of_entries: 5 --- diff --git a/_docs/reference/commands/pilot-discovery.html b/_docs/reference/commands/pilot-discovery.html index 909818894ee4..597d1f1e96f9 100644 --- a/_docs/reference/commands/pilot-discovery.html +++ b/_docs/reference/commands/pilot-discovery.html @@ -1,6 +1,6 @@ --- title: pilot-discovery -overview: Istio Pilot +description: Istio Pilot layout: pkg-collateral-docs number_of_entries: 5 --- diff --git a/_docs/reference/commands/sidecar-injector.html b/_docs/reference/commands/sidecar-injector.html index 1b58aee941e5..bc1a2c3fee24 100644 --- a/_docs/reference/commands/sidecar-injector.html +++ b/_docs/reference/commands/sidecar-injector.html @@ -1,6 +1,6 @@ --- title: sidecar-injector -overview: Kubernetes webhook for automatic Istio sidecar injection +description: Kubernetes webhook for automatic Istio sidecar injection layout: pkg-collateral-docs number_of_entries: 4 --- diff --git a/_docs/reference/config/adapters/circonus.html b/_docs/reference/config/adapters/circonus.html index e3b46092b214..5b7425ed23fd 100644 --- a/_docs/reference/config/adapters/circonus.html +++ b/_docs/reference/config/adapters/circonus.html @@ -1,6 +1,6 @@ --- title: Circonus -overview: Adapter for circonus.com's monitoring solution. +description: Adapter for circonus.com's monitoring solution. location: https://istio.io/docs/reference/config/adapters/circonus.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/config/adapters/cloudwatch.html b/_docs/reference/config/adapters/cloudwatch.html index 0aa15ebe19e2..ec1ca6082969 100644 --- a/_docs/reference/config/adapters/cloudwatch.html +++ b/_docs/reference/config/adapters/cloudwatch.html @@ -1,6 +1,6 @@ --- title: CloudWatch -overview: Adapter for cloudwatch metrics. +description: Adapter for cloudwatch metrics. location: https://istio.io/docs/reference/config/adapters/cloudwatch.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/config/adapters/datadog.html b/_docs/reference/config/adapters/datadog.html index d6c61a836fd2..ba773ec25600 100644 --- a/_docs/reference/config/adapters/datadog.html +++ b/_docs/reference/config/adapters/datadog.html @@ -1,6 +1,6 @@ --- title: Datadog -overview: Adapter to deliver metrics to a dogstatsd agent for delivery to DataDog +description: Adapter to deliver metrics to a dogstatsd agent for delivery to DataDog location: https://istio.io/docs/reference/config/adapters/datadog.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/config/adapters/denier.html b/_docs/reference/config/adapters/denier.html index 03f79322841d..0ce5cb1d9371 100644 --- a/_docs/reference/config/adapters/denier.html +++ b/_docs/reference/config/adapters/denier.html @@ -1,6 +1,6 @@ --- title: Denier -overview: Adapter that always returns a precondition denial. +description: Adapter that always returns a precondition denial. location: https://istio.io/docs/reference/config/adapters/denier.html layout: protoc-gen-docs number_of_entries: 2 diff --git a/_docs/reference/config/adapters/fluentd.html b/_docs/reference/config/adapters/fluentd.html index a43929170ef2..cbefeeef5104 100644 --- a/_docs/reference/config/adapters/fluentd.html +++ b/_docs/reference/config/adapters/fluentd.html @@ -1,6 +1,6 @@ --- title: Fluentd -overview: Adapter that delivers logs to a fluentd daemon. +description: Adapter that delivers logs to a fluentd daemon. location: https://istio.io/docs/reference/config/adapters/fluentd.html layout: protoc-gen-docs number_of_entries: 1 diff --git a/_docs/reference/config/adapters/index.md b/_docs/reference/config/adapters/index.md index 023ff3fc4657..685b15ecee52 100644 --- a/_docs/reference/config/adapters/index.md +++ b/_docs/reference/config/adapters/index.md @@ -1,11 +1,9 @@ --- title: Adapters -overview: Documentation for Mixer's adapters. +description: Documentation for Mixer's adapters. -order: 40 +weight: 40 -layout: docs -type: markdown toc: false --- diff --git a/_docs/reference/config/adapters/kubernetesenv.html b/_docs/reference/config/adapters/kubernetesenv.html index 9103b413e78e..ebbbfc4088b4 100644 --- a/_docs/reference/config/adapters/kubernetesenv.html +++ b/_docs/reference/config/adapters/kubernetesenv.html @@ -1,6 +1,6 @@ --- title: Kubernetes Env -overview: Adapter that extracts information from a Kubernetes environment. +description: Adapter that extracts information from a Kubernetes environment. location: https://istio.io/docs/reference/config/adapters/kubernetesenv.html layout: protoc-gen-docs number_of_entries: 1 diff --git a/_docs/reference/config/adapters/list.html b/_docs/reference/config/adapters/list.html index 1370b0d95477..74983a295a9a 100644 --- a/_docs/reference/config/adapters/list.html +++ b/_docs/reference/config/adapters/list.html @@ -1,6 +1,6 @@ --- title: List -overview: Adapter that performs whitelist or blacklist checks +description: Adapter that performs whitelist or blacklist checks location: https://istio.io/docs/reference/config/adapters/list.html layout: protoc-gen-docs number_of_entries: 2 diff --git a/_docs/reference/config/adapters/memquota.html b/_docs/reference/config/adapters/memquota.html index e3e4435a2d86..18e9686af311 100644 --- a/_docs/reference/config/adapters/memquota.html +++ b/_docs/reference/config/adapters/memquota.html @@ -1,6 +1,6 @@ --- title: Memory quota -overview: Adapter for a simple in-memory quota management system. +description: Adapter for a simple in-memory quota management system. location: https://istio.io/docs/reference/config/adapters/memquota.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/config/adapters/opa.html b/_docs/reference/config/adapters/opa.html index 851addeb2bba..c7d5c15f8196 100644 --- a/_docs/reference/config/adapters/opa.html +++ b/_docs/reference/config/adapters/opa.html @@ -1,6 +1,6 @@ --- title: OPA -overview: Adapter that implements an Open Policy Agent engine +description: Adapter that implements an Open Policy Agent engine location: https://istio.io/docs/reference/config/adapters/opa.html layout: protoc-gen-docs number_of_entries: 1 diff --git a/_docs/reference/config/adapters/prometheus.html b/_docs/reference/config/adapters/prometheus.html index 168d1b2c7254..b597d4acb10b 100644 --- a/_docs/reference/config/adapters/prometheus.html +++ b/_docs/reference/config/adapters/prometheus.html @@ -1,6 +1,6 @@ --- title: Prometheus -overview: Adapter that exposes Istio metrics for ingestion by a Prometheus harvester. +description: Adapter that exposes Istio metrics for ingestion by a Prometheus harvester. location: https://istio.io/docs/reference/config/adapters/prometheus.html layout: protoc-gen-docs number_of_entries: 7 diff --git a/_docs/reference/config/adapters/rbac.html b/_docs/reference/config/adapters/rbac.html index 0aeffc3d960d..9f5897903f62 100644 --- a/_docs/reference/config/adapters/rbac.html +++ b/_docs/reference/config/adapters/rbac.html @@ -1,6 +1,6 @@ --- title: RBAC -overview: Adapter that exposes Istio's Role-Based Access Control model. +description: Adapter that exposes Istio's Role-Based Access Control model. location: https://istio.io/docs/reference/config/adapters/rbac.html layout: protoc-gen-docs number_of_entries: 1 diff --git a/_docs/reference/config/adapters/redisquota.html b/_docs/reference/config/adapters/redisquota.html index e8b274e935fe..d45ea817863e 100644 --- a/_docs/reference/config/adapters/redisquota.html +++ b/_docs/reference/config/adapters/redisquota.html @@ -1,6 +1,6 @@ --- title: Redis Quota -overview: Adapter for a Redis-based quota management system. +description: Adapter for a Redis-based quota management system. location: https://istio.io/docs/reference/config/adapters/redisquota.html layout: protoc-gen-docs number_of_entries: 4 diff --git a/_docs/reference/config/adapters/servicecontrol.html b/_docs/reference/config/adapters/servicecontrol.html index fe904191eeeb..37d979423c9a 100644 --- a/_docs/reference/config/adapters/servicecontrol.html +++ b/_docs/reference/config/adapters/servicecontrol.html @@ -1,6 +1,6 @@ --- title: Service Control -overview: Adapter that delivers logs and metrics to Google Service Control +description: Adapter that delivers logs and metrics to Google Service Control location: https://istio.io/docs/reference/config/adapters/servicecontrol.html layout: protoc-gen-docs number_of_entries: 4 diff --git a/_docs/reference/config/adapters/solarwinds.html b/_docs/reference/config/adapters/solarwinds.html index 79b74af08528..9c5d2d6f575e 100644 --- a/_docs/reference/config/adapters/solarwinds.html +++ b/_docs/reference/config/adapters/solarwinds.html @@ -1,6 +1,6 @@ --- title: SolarWinds -overview: Adapter to deliver logs and metrics to Papertrail and AppOptics backends +description: Adapter to deliver logs and metrics to Papertrail and AppOptics backends location: https://istio.io/docs/reference/config/adapters/solarwinds.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/config/adapters/stackdriver.html b/_docs/reference/config/adapters/stackdriver.html index b9b768063742..e3abd4b6e0e4 100644 --- a/_docs/reference/config/adapters/stackdriver.html +++ b/_docs/reference/config/adapters/stackdriver.html @@ -1,6 +1,6 @@ --- title: Stackdriver -overview: Adapter to deliver logs and metrics to Stackdriver +description: Adapter to deliver logs and metrics to Stackdriver location: https://istio.io/docs/reference/config/adapters/stackdriver.html layout: protoc-gen-docs number_of_entries: 11 diff --git a/_docs/reference/config/adapters/statsd.html b/_docs/reference/config/adapters/statsd.html index fc1754acc971..530f9807ffb0 100644 --- a/_docs/reference/config/adapters/statsd.html +++ b/_docs/reference/config/adapters/statsd.html @@ -1,6 +1,6 @@ --- title: StatsD -overview: Adapter to deliver metrics to a StatsD backend +description: Adapter to deliver metrics to a StatsD backend location: https://istio.io/docs/reference/config/adapters/statsd.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/config/adapters/stdio.html b/_docs/reference/config/adapters/stdio.html index 9fff59a1040b..100abeb3ef99 100644 --- a/_docs/reference/config/adapters/stdio.html +++ b/_docs/reference/config/adapters/stdio.html @@ -1,6 +1,6 @@ --- title: Stdio -overview: Adapter for outputting logs and metrics locally. +description: Adapter for outputting logs and metrics locally. location: https://istio.io/docs/reference/config/adapters/stdio.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/config/index.md b/_docs/reference/config/index.md index a31ddc4d902c..41e416737fc3 100644 --- a/_docs/reference/config/index.md +++ b/_docs/reference/config/index.md @@ -1,11 +1,9 @@ --- title: Configuration -overview: Detailed information on configuration options. +description: Detailed information on configuration options. -order: 20 +weight: 20 -layout: docs -type: markdown toc: false --- diff --git a/_docs/reference/config/istio.mesh.v1alpha1.html b/_docs/reference/config/istio.mesh.v1alpha1.html index bd750b37854b..f9310906e09f 100644 --- a/_docs/reference/config/istio.mesh.v1alpha1.html +++ b/_docs/reference/config/istio.mesh.v1alpha1.html @@ -1,6 +1,6 @@ --- title: Service Mesh -overview: Configuration affecting the service mesh as a whole +description: Configuration affecting the service mesh as a whole location: https://istio.io/docs/reference/config/istio.mesh.v1alpha1.html layout: protoc-gen-docs redirect_from: /docs/reference/config/service-mesh.html diff --git a/_docs/reference/config/istio.networking.v1alpha3.html b/_docs/reference/config/istio.networking.v1alpha3.html index aba7faa8f028..f0b4aba88f52 100644 --- a/_docs/reference/config/istio.networking.v1alpha3.html +++ b/_docs/reference/config/istio.networking.v1alpha3.html @@ -1,6 +1,6 @@ --- title: Route Rules v1alpha3 -overview: Configuration affecting traffic routing +description: Configuration affecting traffic routing location: https://istio.io/docs/reference/config/istio.networking.v1alpha3.html layout: protoc-gen-docs number_of_entries: 39 diff --git a/_docs/reference/config/istio.policy.v1beta1.html b/_docs/reference/config/istio.policy.v1beta1.html index 79db159c7b21..b90047b7848e 100644 --- a/_docs/reference/config/istio.policy.v1beta1.html +++ b/_docs/reference/config/istio.policy.v1beta1.html @@ -1,6 +1,6 @@ --- title: Policy and Telemetry Rules -overview: Describes the rules used to configure Mixer's policy and telemetry features. +description: Describes the rules used to configure Mixer's policy and telemetry features. location: https://istio.io/docs/reference/config/istio.policy.v1beta1.html layout: protoc-gen-docs number_of_entries: 9 diff --git a/_docs/reference/config/istio.rbac.v1alpha1.html b/_docs/reference/config/istio.rbac.v1alpha1.html index 1c1ad71c5831..c9e431518fd0 100644 --- a/_docs/reference/config/istio.rbac.v1alpha1.html +++ b/_docs/reference/config/istio.rbac.v1alpha1.html @@ -1,6 +1,6 @@ --- title: RBAC -overview: Configuration for Role Based Access Control +description: Configuration for Role Based Access Control location: https://istio.io/docs/reference/config/istio.rbac.v1alpha1.html layout: protoc-gen-docs number_of_entries: 9 diff --git a/_docs/reference/config/istio.routing.v1alpha1.html b/_docs/reference/config/istio.routing.v1alpha1.html index 409638792288..cfb2b0bd1087 100644 --- a/_docs/reference/config/istio.routing.v1alpha1.html +++ b/_docs/reference/config/istio.routing.v1alpha1.html @@ -1,6 +1,6 @@ --- title: Route Rules v1alpha1 -overview: Configuration affecting traffic routing +description: Configuration affecting traffic routing location: https://istio.io/docs/reference/config/istio.routing.v1alpha1.html layout: protoc-gen-docs redirect_from: /docs/reference/config/traffic-rules/routing-rules.html diff --git a/_docs/reference/config/mixer/attribute-vocabulary.md b/_docs/reference/config/mixer/attribute-vocabulary.md index 04fbf09136c5..6fe325890e42 100644 --- a/_docs/reference/config/mixer/attribute-vocabulary.md +++ b/_docs/reference/config/mixer/attribute-vocabulary.md @@ -1,11 +1,9 @@ --- title: Attribute Vocabulary -overview: Describes the base attribute vocabulary used for policy and control. +description: Describes the base attribute vocabulary used for policy and control. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/reference/config/mixer/expression-language.md b/_docs/reference/config/mixer/expression-language.md index a362c26d12bb..d265c642ac39 100644 --- a/_docs/reference/config/mixer/expression-language.md +++ b/_docs/reference/config/mixer/expression-language.md @@ -1,11 +1,9 @@ --- title: Expression Language -overview: Mixer config expression language reference. +description: Mixer config expression language reference. -order: 20 +weight: 20 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/reference/config/mixer/index.md b/_docs/reference/config/mixer/index.md index f51d6d1f3eda..53bb514d6f3e 100644 --- a/_docs/reference/config/mixer/index.md +++ b/_docs/reference/config/mixer/index.md @@ -1,11 +1,9 @@ --- title: Mixer -overview: Detailed information on configuration and API exposed by Mixer. +description: Detailed information on configuration and API exposed by Mixer. -order: 30 +weight: 30 -layout: docs -type: markdown toc: false --- diff --git a/_docs/reference/config/template/apikey.html b/_docs/reference/config/template/apikey.html index 902242dde534..7de4d585ad98 100644 --- a/_docs/reference/config/template/apikey.html +++ b/_docs/reference/config/template/apikey.html @@ -1,6 +1,6 @@ --- title: API Key -overview: A template that represents a single API key. +description: A template that represents a single API key. location: https://istio.io/docs/reference/config/template/apikey.html layout: protoc-gen-docs number_of_entries: 2 diff --git a/_docs/reference/config/template/authorization.html b/_docs/reference/config/template/authorization.html index d87271e3fc1f..656fd18373b9 100644 --- a/_docs/reference/config/template/authorization.html +++ b/_docs/reference/config/template/authorization.html @@ -1,6 +1,6 @@ --- title: Authorization -overview: A template used to represent an access control query. +description: A template used to represent an access control query. location: https://istio.io/docs/reference/config/template/authorization.html layout: protoc-gen-docs number_of_entries: 4 diff --git a/_docs/reference/config/template/checknothing.html b/_docs/reference/config/template/checknothing.html index 6d47092d71bc..86c67016402b 100644 --- a/_docs/reference/config/template/checknothing.html +++ b/_docs/reference/config/template/checknothing.html @@ -1,6 +1,6 @@ --- title: Check Nothing -overview: A template that carries no data, useful for testing. +description: A template that carries no data, useful for testing. location: https://istio.io/docs/reference/config/template/checknothing.html layout: protoc-gen-docs number_of_entries: 1 diff --git a/_docs/reference/config/template/index.md b/_docs/reference/config/template/index.md index 1abe621f4f8b..3d4d326c6475 100644 --- a/_docs/reference/config/template/index.md +++ b/_docs/reference/config/template/index.md @@ -1,11 +1,9 @@ --- title: Templates -overview: Generated documentation for Mixer's Templates. +description: Generated documentation for Mixer's Templates. -order: 50 +weight: 50 -layout: docs -type: markdown toc: false --- diff --git a/_docs/reference/config/template/kubernetes.html b/_docs/reference/config/template/kubernetes.html index 2ed145a0b776..831ab7fd9e02 100644 --- a/_docs/reference/config/template/kubernetes.html +++ b/_docs/reference/config/template/kubernetes.html @@ -1,6 +1,6 @@ --- title: Kubernetes -overview: A template that is used to control the production of Kubernetes-specific attributes. +description: A template that is used to control the production of Kubernetes-specific attributes. location: https://istio.io/docs/reference/config/template/kubernetes.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/config/template/listentry.html b/_docs/reference/config/template/listentry.html index dc315764fa68..b72ddc7b545e 100644 --- a/_docs/reference/config/template/listentry.html +++ b/_docs/reference/config/template/listentry.html @@ -1,6 +1,6 @@ --- title: List Entry -overview: A template designed to let you perform list checking operations. +description: A template designed to let you perform list checking operations. location: https://istio.io/docs/reference/config/template/listentry.html layout: protoc-gen-docs number_of_entries: 1 diff --git a/_docs/reference/config/template/logentry.html b/_docs/reference/config/template/logentry.html index 3f3e9e924d64..4944624e7df4 100644 --- a/_docs/reference/config/template/logentry.html +++ b/_docs/reference/config/template/logentry.html @@ -1,6 +1,6 @@ --- title: Log Entry -overview: A template that represents a single runtime log entry. +description: A template that represents a single runtime log entry. location: https://istio.io/docs/reference/config/template/logentry.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/config/template/metric.html b/_docs/reference/config/template/metric.html index 5caa3ce2b50a..e98bcbf5525b 100644 --- a/_docs/reference/config/template/metric.html +++ b/_docs/reference/config/template/metric.html @@ -1,6 +1,6 @@ --- title: Metric -overview: A template that represents a single runtime metric. +description: A template that represents a single runtime metric. location: https://istio.io/docs/reference/config/template/metric.html layout: protoc-gen-docs number_of_entries: 2 diff --git a/_docs/reference/config/template/quota.html b/_docs/reference/config/template/quota.html index 8b22bea7d16c..a0992056703e 100644 --- a/_docs/reference/config/template/quota.html +++ b/_docs/reference/config/template/quota.html @@ -1,6 +1,6 @@ --- title: Quota -overview: A template that represents a quota allocation request +description: A template that represents a quota allocation request location: https://istio.io/docs/reference/config/template/quota.html layout: protoc-gen-docs number_of_entries: 2 diff --git a/_docs/reference/config/template/reportnothing.html b/_docs/reference/config/template/reportnothing.html index 867758f96e9f..cde494b04ea1 100644 --- a/_docs/reference/config/template/reportnothing.html +++ b/_docs/reference/config/template/reportnothing.html @@ -1,6 +1,6 @@ --- title: Report Nothing -overview: A template that carries no data, useful for testing. +description: A template that carries no data, useful for testing. location: https://istio.io/docs/reference/config/template/reportnothing.html layout: protoc-gen-docs number_of_entries: 1 diff --git a/_docs/reference/config/template/servicecontrolreport.html b/_docs/reference/config/template/servicecontrolreport.html index 80e1581783b9..ccd238154e1a 100644 --- a/_docs/reference/config/template/servicecontrolreport.html +++ b/_docs/reference/config/template/servicecontrolreport.html @@ -1,6 +1,6 @@ --- title: Service Control Report -overview: A template used by the Google Service Control adapter. +description: A template used by the Google Service Control adapter. location: https://istio.io/docs/reference/config/template/servicecontrolreport.html layout: protoc-gen-docs number_of_entries: 3 diff --git a/_docs/reference/index.md b/_docs/reference/index.md index 6001dfc271da..24ffc2e4d7f4 100644 --- a/_docs/reference/index.md +++ b/_docs/reference/index.md @@ -1,12 +1,10 @@ --- title: Reference -overview: The Reference section contains detailed authoritative reference material such as command-line options, configuration options, and API calling parameters. +description: The Reference section contains detailed authoritative reference material such as command-line options, configuration options, and API calling parameters. index: true -order: 60 +weight: 60 -layout: docs -type: markdown toc: false --- diff --git a/_docs/setup/cloudfoundry/index.md b/_docs/setup/cloudfoundry/index.md index 6543c4ae919b..9c8ea47d470f 100644 --- a/_docs/setup/cloudfoundry/index.md +++ b/_docs/setup/cloudfoundry/index.md @@ -1,11 +1,9 @@ --- title: Cloud Foundry -overview: Instructions for installing the Istio control plane in Cloud Foundry. +description: Instructions for installing the Istio control plane in Cloud Foundry. -order: 40 +weight: 40 -layout: docs -type: markdown toc: false --- diff --git a/_docs/setup/cloudfoundry/install.md b/_docs/setup/cloudfoundry/install.md index 86838a54ea4a..740d239c8dc1 100644 --- a/_docs/setup/cloudfoundry/install.md +++ b/_docs/setup/cloudfoundry/install.md @@ -1,11 +1,9 @@ --- title: Installation -overview: Instructions for installing the Istio control plane in Cloud Foundry. +description: Instructions for installing the Istio control plane in Cloud Foundry. -order: 10 +weight: 10 -layout: docs -type: markdown --- We are working with the Cloud Foundry developers to integrate Istio diff --git a/_docs/setup/consul/index.md b/_docs/setup/consul/index.md index 0e8cdd166a5c..b2eef23d2b5a 100644 --- a/_docs/setup/consul/index.md +++ b/_docs/setup/consul/index.md @@ -1,11 +1,9 @@ --- title: Nomad & Consul -overview: Instructions for installing the Istio control plane in a Consul based environment, with or without Nomad. +description: Instructions for installing the Istio control plane in a Consul based environment, with or without Nomad. -order: 20 +weight: 20 -layout: docs -type: markdown toc: false --- diff --git a/_docs/setup/consul/install.md b/_docs/setup/consul/install.md index 79ff8babf6d4..4a9bdf7332c2 100644 --- a/_docs/setup/consul/install.md +++ b/_docs/setup/consul/install.md @@ -1,11 +1,9 @@ --- title: Installation -overview: Instructions for installing the Istio control plane in a Consul based environment, with or without Nomad. +description: Instructions for installing the Istio control plane in a Consul based environment, with or without Nomad. -order: 30 +weight: 30 -layout: docs -type: markdown --- > Setup on Nomad has not been tested. diff --git a/_docs/setup/consul/quick-start.md b/_docs/setup/consul/quick-start.md index 641eb0971e93..43bb04e8c67b 100644 --- a/_docs/setup/consul/quick-start.md +++ b/_docs/setup/consul/quick-start.md @@ -1,11 +1,9 @@ --- title: Quick Start on Docker -overview: Quick Start instructions to setup the Istio service mesh with Docker Compose. +description: Quick Start instructions to setup the Istio service mesh with Docker Compose. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/eureka/index.md b/_docs/setup/eureka/index.md index 14ad5fe21fec..51cacef1ebb0 100644 --- a/_docs/setup/eureka/index.md +++ b/_docs/setup/eureka/index.md @@ -1,11 +1,9 @@ --- title: Eureka -overview: Instructions for installing the Istio control plane in a Eureka based environment. +description: Instructions for installing the Istio control plane in a Eureka based environment. -order: 30 +weight: 30 -layout: docs -type: markdown toc: false --- diff --git a/_docs/setup/eureka/install.md b/_docs/setup/eureka/install.md index 81cfd94db978..1e4d1c21c5b7 100644 --- a/_docs/setup/eureka/install.md +++ b/_docs/setup/eureka/install.md @@ -1,11 +1,9 @@ --- title: Installation -overview: Instructions for installing the Istio control plane in an Eureka based environment. +description: Instructions for installing the Istio control plane in an Eureka based environment. -order: 30 +weight: 30 -layout: docs -type: markdown --- Using Istio in a non-Kubernetes environment involves a few key tasks: diff --git a/_docs/setup/eureka/quick-start.md b/_docs/setup/eureka/quick-start.md index ddaaeb298133..c04214cfeedb 100644 --- a/_docs/setup/eureka/quick-start.md +++ b/_docs/setup/eureka/quick-start.md @@ -1,11 +1,9 @@ --- title: Quick Start on Docker -overview: Quick Start instructions to setup the Istio service mesh with Docker Compose. +description: Quick Start instructions to setup the Istio service mesh with Docker Compose. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/index.md b/_docs/setup/index.md index 2fbb1e459a25..84b81bdfde55 100644 --- a/_docs/setup/index.md +++ b/_docs/setup/index.md @@ -1,11 +1,9 @@ --- title: Setup -overview: Setup contains instructions for installing the Istio control plane in various environments (e.g., Kubernetes, Consul, etc.), as well as instructions for installing the sidecar in the application deployment. +description: Setup contains instructions for installing the Istio control plane in various environments (e.g., Kubernetes, Consul, etc.), as well as instructions for installing the sidecar in the application deployment. -order: 15 +weight: 15 -layout: docs -type: markdown toc: false --- diff --git a/_docs/setup/kubernetes/advanced-install.md b/_docs/setup/kubernetes/advanced-install.md index ea0ba6ef7983..902a89112b29 100644 --- a/_docs/setup/kubernetes/advanced-install.md +++ b/_docs/setup/kubernetes/advanced-install.md @@ -1,11 +1,9 @@ --- title: Advanced Install Options -overview: Instructions for customizing the Istio installation. +description: Instructions for customizing the Istio installation. -order: 20 +weight: 20 draft: true -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/kubernetes/ansible-install.md b/_docs/setup/kubernetes/ansible-install.md index f4c81ae8ecd3..92196dba0b2b 100644 --- a/_docs/setup/kubernetes/ansible-install.md +++ b/_docs/setup/kubernetes/ansible-install.md @@ -1,11 +1,9 @@ --- title: Installation with Ansible -overview: Install Istio with the included Ansible playbook. +description: Install Istio with the included Ansible playbook. -order: 40 +weight: 40 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/kubernetes/helm-install.md b/_docs/setup/kubernetes/helm-install.md index cde84845c924..14df190fe08b 100644 --- a/_docs/setup/kubernetes/helm-install.md +++ b/_docs/setup/kubernetes/helm-install.md @@ -1,13 +1,11 @@ --- title: Installation with Helm -overview: Install Istio with the included Helm chart. +description: Install Istio with the included Helm chart. -order: 30 +weight: 30 redirect_from: /docs/setup/kubernetes/helm.html -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/kubernetes/index.md b/_docs/setup/kubernetes/index.md index 64059bbd11eb..71ca6e948a97 100644 --- a/_docs/setup/kubernetes/index.md +++ b/_docs/setup/kubernetes/index.md @@ -1,11 +1,9 @@ --- title: Kubernetes -overview: Instructions for installing the Istio control plane on Kubernetes and adding VMs into the mesh. +description: Instructions for installing the Istio control plane on Kubernetes and adding VMs into the mesh. -order: 10 +weight: 10 -layout: docs -type: markdown redirect_from: "/docs/tasks/installing-istio.html" toc: false --- diff --git a/_docs/setup/kubernetes/mesh-expansion.md b/_docs/setup/kubernetes/mesh-expansion.md index e47e3b7c111b..30ff4e543049 100644 --- a/_docs/setup/kubernetes/mesh-expansion.md +++ b/_docs/setup/kubernetes/mesh-expansion.md @@ -1,11 +1,9 @@ --- title: Mesh Expansion -overview: Instructions for integrating VMs and bare metal hosts into an Istio mesh deployed on Kubernetes. +description: Instructions for integrating VMs and bare metal hosts into an Istio mesh deployed on Kubernetes. -order: 60 +weight: 60 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/kubernetes/multicluster-install.md b/_docs/setup/kubernetes/multicluster-install.md index fa2446215dbf..69aa612554ed 100644 --- a/_docs/setup/kubernetes/multicluster-install.md +++ b/_docs/setup/kubernetes/multicluster-install.md @@ -1,11 +1,9 @@ --- title: Istio Multicluster -overview: Install Istio with multicluster support. +description: Install Istio with multicluster support. -order: 65 +weight: 65 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/kubernetes/quick-start-gke-dm.md b/_docs/setup/kubernetes/quick-start-gke-dm.md index 1a9b10cfcb6c..f4b323f1dc45 100644 --- a/_docs/setup/kubernetes/quick-start-gke-dm.md +++ b/_docs/setup/kubernetes/quick-start-gke-dm.md @@ -1,11 +1,9 @@ --- title: Quick Start with Google Kubernetes Engine -overview: Quick Start instructions to setup the Istio service using Google Kubernetes Engine (GKE) +description: Quick Start instructions to setup the Istio service using Google Kubernetes Engine (GKE) -order: 11 +weight: 11 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/kubernetes/quick-start.md b/_docs/setup/kubernetes/quick-start.md index e3188ae50d70..64a50ef99099 100644 --- a/_docs/setup/kubernetes/quick-start.md +++ b/_docs/setup/kubernetes/quick-start.md @@ -1,11 +1,9 @@ --- title: Quick Start -overview: Quick start instructions to setup the Istio service mesh in a Kubernetes cluster. +description: Quick start instructions to setup the Istio service mesh in a Kubernetes cluster. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index f1224c313880..874b76d7499d 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -1,11 +1,9 @@ --- title: Installing the Istio Sidecar -overview: Instructions for installing the Istio sidecar in application pods automatically using the sidecar injector webhook or manually using istioctl CLI. +description: Instructions for installing the Istio sidecar in application pods automatically using the sidecar injector webhook or manually using istioctl CLI. -order: 50 +weight: 50 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/kubernetes/upgrading-istio.md b/_docs/setup/kubernetes/upgrading-istio.md index 75dbbf8cd2d6..636519865ba4 100644 --- a/_docs/setup/kubernetes/upgrading-istio.md +++ b/_docs/setup/kubernetes/upgrading-istio.md @@ -1,11 +1,9 @@ --- title: Upgrading Istio -overview: This guide demonstrates how to upgrade the Istio control plane and data plane independently. +description: This guide demonstrates how to upgrade the Istio control plane and data plane independently. -order: 70 +weight: 70 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/setup/mesos/index.md b/_docs/setup/mesos/index.md index ecdf36323e48..e8ebb9ddcc35 100644 --- a/_docs/setup/mesos/index.md +++ b/_docs/setup/mesos/index.md @@ -1,11 +1,9 @@ --- title: Mesos -overview: Instructions for installing the Istio control plane in Apache Mesos. +description: Instructions for installing the Istio control plane in Apache Mesos. -order: 50 +weight: 50 -layout: docs -type: markdown toc: false --- diff --git a/_docs/setup/mesos/install.md b/_docs/setup/mesos/install.md index ea50e3b7538d..2a1e5af34ffa 100644 --- a/_docs/setup/mesos/install.md +++ b/_docs/setup/mesos/install.md @@ -1,11 +1,9 @@ --- title: Installation -overview: Instructions for installing the Istio control plane in Apache Mesos. +description: Instructions for installing the Istio control plane in Apache Mesos. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/index.md b/_docs/tasks/index.md index 332569945914..29b54b3d2f6f 100644 --- a/_docs/tasks/index.md +++ b/_docs/tasks/index.md @@ -1,11 +1,9 @@ --- title: Tasks -overview: Tasks show you how to do a single specific targeted activity with the Istio system. +description: Tasks show you how to do a single specific targeted activity with the Istio system. -order: 20 +weight: 20 -layout: docs -type: markdown toc: false --- diff --git a/_docs/tasks/policy-enforcement/index.md b/_docs/tasks/policy-enforcement/index.md index 1559ef3736b2..74222de2f1af 100644 --- a/_docs/tasks/policy-enforcement/index.md +++ b/_docs/tasks/policy-enforcement/index.md @@ -1,11 +1,9 @@ --- title: Policy Enforcement -overview: Describes tasks that demonstrate policy enforcement features. +description: Describes tasks that demonstrate policy enforcement features. -order: 20 +weight: 20 -layout: docs -type: markdown toc: false --- diff --git a/_docs/tasks/policy-enforcement/rate-limiting.md b/_docs/tasks/policy-enforcement/rate-limiting.md index 67df1834aeb8..a70b8c917a38 100644 --- a/_docs/tasks/policy-enforcement/rate-limiting.md +++ b/_docs/tasks/policy-enforcement/rate-limiting.md @@ -1,11 +1,9 @@ --- title: Enabling Rate Limits -overview: This task shows you how to use Istio to dynamically limit the traffic to a service. +description: This task shows you how to use Istio to dynamically limit the traffic to a service. -order: 10 +weight: 10 -layout: docs -type: markdown redirect_from: /docs/tasks/rate-limiting.html --- {% include home.html %} diff --git a/_docs/tasks/security/authn-policy.md b/_docs/tasks/security/authn-policy.md index 86144f16c027..5249d1492e17 100644 --- a/_docs/tasks/security/authn-policy.md +++ b/_docs/tasks/security/authn-policy.md @@ -1,11 +1,9 @@ --- title: Basic Istio Authentication Policy -overview: Shows you how to use Istio authentication policy to setup mutual TLS and simple end-user authentication. +description: Shows you how to use Istio authentication policy to setup mutual TLS and simple end-user authentication. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/security/basic-access-control.md b/_docs/tasks/security/basic-access-control.md index b75b4f6a39e9..2075ae1e8d25 100644 --- a/_docs/tasks/security/basic-access-control.md +++ b/_docs/tasks/security/basic-access-control.md @@ -1,11 +1,9 @@ --- title: Setting up Basic Access Control -overview: This task shows how to control access to a service using the Kubernetes labels. +description: This task shows how to control access to a service using the Kubernetes labels. -order: 20 +weight: 20 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/security/health-check.md b/_docs/tasks/security/health-check.md index 2e6b2ce9c97f..e36d1c4c5efc 100644 --- a/_docs/tasks/security/health-check.md +++ b/_docs/tasks/security/health-check.md @@ -1,11 +1,9 @@ --- title: Enabling Citadel health checking -overview: This task shows how to enable Citadel health checking. +description: This task shows how to enable Citadel health checking. -order: 70 +weight: 70 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/security/https-overlay.md b/_docs/tasks/security/https-overlay.md index ba20bcbb749d..4241bbd1fa70 100644 --- a/_docs/tasks/security/https-overlay.md +++ b/_docs/tasks/security/https-overlay.md @@ -1,11 +1,9 @@ --- title: Mutual TLS over HTTPS services -overview: This task shows how to enable mTLS on HTTPS services. +description: This task shows how to enable mTLS on HTTPS services. -order: 80 +weight: 80 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/security/index.md b/_docs/tasks/security/index.md index 334d751b9c72..74cdd67fb7ab 100644 --- a/_docs/tasks/security/index.md +++ b/_docs/tasks/security/index.md @@ -1,11 +1,9 @@ --- title: Security -overview: Describes tasks that help securing the service mesh traffic. +description: Describes tasks that help securing the service mesh traffic. -order: 40 +weight: 40 -layout: docs -type: markdown toc: false redirect_from: /docs/tasks/istio-auth.html --- diff --git a/_docs/tasks/security/mutual-tls.md b/_docs/tasks/security/mutual-tls.md index dd7d44f96ecf..3473b87cae1c 100644 --- a/_docs/tasks/security/mutual-tls.md +++ b/_docs/tasks/security/mutual-tls.md @@ -1,11 +1,9 @@ --- title: Testing Istio mutual TLS authentication -overview: This task shows you how to verify and test Istio's automatic mutual TLS authentication. +description: This task shows you how to verify and test Istio's automatic mutual TLS authentication. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/security/per-service-mtls.md b/_docs/tasks/security/per-service-mtls.md index dde8b2976dab..a0573a913569 100644 --- a/_docs/tasks/security/per-service-mtls.md +++ b/_docs/tasks/security/per-service-mtls.md @@ -1,11 +1,9 @@ --- title: Per-service mutual TLS authentication control -overview: This task shows how to change mutual TLS authentication for a single service. +description: This task shows how to change mutual TLS authentication for a single service. -order: 50 +weight: 50 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/security/plugin-ca-cert.md b/_docs/tasks/security/plugin-ca-cert.md index 4b80ec7e1e0c..a5ec549866ab 100644 --- a/_docs/tasks/security/plugin-ca-cert.md +++ b/_docs/tasks/security/plugin-ca-cert.md @@ -1,11 +1,9 @@ --- title: Plugging in root certificate, signing certificate and key -overview: This task shows how operators can configure Citadel with existing root certificate, signing certificate and key. +description: This task shows how operators can configure Citadel with existing root certificate, signing certificate and key. -order: 60 +weight: 60 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/security/role-based-access-control.md b/_docs/tasks/security/role-based-access-control.md index caf2790fbc5d..802d5f129fb8 100644 --- a/_docs/tasks/security/role-based-access-control.md +++ b/_docs/tasks/security/role-based-access-control.md @@ -1,11 +1,9 @@ --- title: Setting up Istio Role-Based Access Control -overview: This task shows how to set up role-based access control for services in Istio mesh. +description: This task shows how to set up role-based access control for services in Istio mesh. -order: 40 +weight: 40 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/security/secure-access-control.md b/_docs/tasks/security/secure-access-control.md index 3b6c65a7b394..61d99d1171af 100644 --- a/_docs/tasks/security/secure-access-control.md +++ b/_docs/tasks/security/secure-access-control.md @@ -1,11 +1,9 @@ --- title: Setting up Secure Access Control -overview: This task shows how to securely control access to a service using service accounts. +description: This task shows how to securely control access to a service using service accounts. -order: 30 +weight: 30 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/telemetry/distributed-tracing.md b/_docs/tasks/telemetry/distributed-tracing.md index 11d98d640d85..bc8fdbebbc5d 100644 --- a/_docs/tasks/telemetry/distributed-tracing.md +++ b/_docs/tasks/telemetry/distributed-tracing.md @@ -1,11 +1,9 @@ --- title: Distributed Tracing -overview: How to configure the proxies to send tracing requests to Zipkin or Jaeger +description: How to configure the proxies to send tracing requests to Zipkin or Jaeger -order: 10 +weight: 10 -layout: docs -type: markdown redirect_from: /docs/tasks/zipkin-tracing.html --- {% include home.html %} diff --git a/_docs/tasks/telemetry/fluentd.md b/_docs/tasks/telemetry/fluentd.md index c2da32657aae..bf0c2b6d826e 100644 --- a/_docs/tasks/telemetry/fluentd.md +++ b/_docs/tasks/telemetry/fluentd.md @@ -1,12 +1,10 @@ --- title: Logging with Fluentd -overview: This task shows you how to configure Istio to log to a Fluentd daemon +description: This task shows you how to configure Istio to log to a Fluentd daemon -order: 60 +weight: 60 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/telemetry/index.md b/_docs/tasks/telemetry/index.md index 93d7938e0079..2e7f3f70c5a9 100644 --- a/_docs/tasks/telemetry/index.md +++ b/_docs/tasks/telemetry/index.md @@ -1,11 +1,9 @@ --- title: Metrics, Logs, and Traces -overview: Describes tasks that demonstrate how to collect telemetry information from the service mesh. +description: Describes tasks that demonstrate how to collect telemetry information from the service mesh. -order: 30 +weight: 30 -layout: docs -type: markdown toc: false --- diff --git a/_docs/tasks/telemetry/metrics-logs.md b/_docs/tasks/telemetry/metrics-logs.md index a466e0b68ba1..35b4d7698e1d 100644 --- a/_docs/tasks/telemetry/metrics-logs.md +++ b/_docs/tasks/telemetry/metrics-logs.md @@ -1,12 +1,10 @@ --- title: Collecting Metrics and Logs -overview: This task shows you how to configure Istio to collect metrics and logs. +description: This task shows you how to configure Istio to collect metrics and logs. -order: 20 +weight: 20 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/telemetry/querying-metrics.md b/_docs/tasks/telemetry/querying-metrics.md index 16728c57cb93..c2ad4a46b078 100644 --- a/_docs/tasks/telemetry/querying-metrics.md +++ b/_docs/tasks/telemetry/querying-metrics.md @@ -1,12 +1,10 @@ --- title: Querying Metrics from Prometheus -overview: This task shows you how to query for Istio Metrics using Prometheus. +description: This task shows you how to query for Istio Metrics using Prometheus. -order: 30 +weight: 30 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/telemetry/servicegraph.md b/_docs/tasks/telemetry/servicegraph.md index 994b1daaf0d4..71fc576b03e8 100644 --- a/_docs/tasks/telemetry/servicegraph.md +++ b/_docs/tasks/telemetry/servicegraph.md @@ -1,12 +1,10 @@ --- title: Generating a Service Graph -overview: This task shows you how to generate a graph of services within an Istio mesh. +description: This task shows you how to generate a graph of services within an Istio mesh. -order: 50 +weight: 50 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/telemetry/tcp-metrics.md b/_docs/tasks/telemetry/tcp-metrics.md index d725dcba43d5..802e3b50d3d5 100644 --- a/_docs/tasks/telemetry/tcp-metrics.md +++ b/_docs/tasks/telemetry/tcp-metrics.md @@ -1,12 +1,10 @@ --- title: Collecting Metrics for TCP services -overview: This task shows you how to configure Istio to collect metrics for TCP services. +description: This task shows you how to configure Istio to collect metrics for TCP services. -order: 25 +weight: 25 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/telemetry/using-istio-dashboard.md b/_docs/tasks/telemetry/using-istio-dashboard.md index 95339da0f079..73f2232ac074 100644 --- a/_docs/tasks/telemetry/using-istio-dashboard.md +++ b/_docs/tasks/telemetry/using-istio-dashboard.md @@ -1,12 +1,10 @@ --- title: Visualizing Metrics with Grafana -overview: This task shows you how to setup and use the Istio Dashboard to monitor mesh traffic. +description: This task shows you how to setup and use the Istio Dashboard to monitor mesh traffic. -order: 40 +weight: 40 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md b/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md index edbc3283d014..0a85a3dadcef 100644 --- a/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md +++ b/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md @@ -1,11 +1,9 @@ --- title: Circuit Breaking -overview: This task demonstrates the circuit-breaking capability for resilient applications +description: This task demonstrates the circuit-breaking capability for resilient applications -order: 50 +weight: 50 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md index d0f9936987a0..8cd80cf42973 100644 --- a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md +++ b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md @@ -1,11 +1,9 @@ --- title: Control Egress TCP Traffic -overview: Describes how to configure Istio to route TCP traffic from services in the mesh to external services. +description: Describes how to configure Istio to route TCP traffic from services in the mesh to external services. -order: 41 +weight: 41 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management-v1alpha3/egress.md b/_docs/tasks/traffic-management-v1alpha3/egress.md index 594d8f869328..0ee2fee512be 100644 --- a/_docs/tasks/traffic-management-v1alpha3/egress.md +++ b/_docs/tasks/traffic-management-v1alpha3/egress.md @@ -1,11 +1,9 @@ --- title: Control Egress Traffic -overview: Describes how to configure Istio to route traffic from services in the mesh to external services. +description: Describes how to configure Istio to route traffic from services in the mesh to external services. -order: 40 +weight: 40 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management-v1alpha3/fault-injection.md b/_docs/tasks/traffic-management-v1alpha3/fault-injection.md index 296004650904..dd0ea9c48fc0 100644 --- a/_docs/tasks/traffic-management-v1alpha3/fault-injection.md +++ b/_docs/tasks/traffic-management-v1alpha3/fault-injection.md @@ -1,11 +1,9 @@ --- title: Fault Injection -overview: This task shows how to inject delays and test the resiliency of your application. +description: This task shows how to inject delays and test the resiliency of your application. -order: 20 +weight: 20 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management-v1alpha3/index.md b/_docs/tasks/traffic-management-v1alpha3/index.md index 4fe841630e81..13b4dec06b8c 100644 --- a/_docs/tasks/traffic-management-v1alpha3/index.md +++ b/_docs/tasks/traffic-management-v1alpha3/index.md @@ -1,11 +1,9 @@ --- title: Traffic Management (v1alpha3) -overview: WIP - Describes tasks that demonstrate traffic routing features of Istio service mesh. +description: WIP - Describes tasks that demonstrate traffic routing features of Istio service mesh. -order: 15 +weight: 15 -layout: docs -type: markdown toc: false --- diff --git a/_docs/tasks/traffic-management-v1alpha3/ingress.md b/_docs/tasks/traffic-management-v1alpha3/ingress.md index c0a5ef834453..35f6fd55a29a 100644 --- a/_docs/tasks/traffic-management-v1alpha3/ingress.md +++ b/_docs/tasks/traffic-management-v1alpha3/ingress.md @@ -1,11 +1,9 @@ --- title: Control Ingress Traffic -overview: Describes how to configure Istio to expose a service outside of the service mesh. +description: Describes how to configure Istio to expose a service outside of the service mesh. -order: 30 +weight: 30 -layout: docs -type: markdown redirect_from: /docs/tasks/ingress.html --- {% include home.html %} diff --git a/_docs/tasks/traffic-management-v1alpha3/mirroring.md b/_docs/tasks/traffic-management-v1alpha3/mirroring.md index a0e645fe8e5c..1df318ab31e8 100644 --- a/_docs/tasks/traffic-management-v1alpha3/mirroring.md +++ b/_docs/tasks/traffic-management-v1alpha3/mirroring.md @@ -1,11 +1,9 @@ --- title: Mirroring -overview: This task demonstrates the traffic shadowing/mirroring capabilities of Istio +description: This task demonstrates the traffic shadowing/mirroring capabilities of Istio -order: 60 +weight: 60 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management-v1alpha3/request-routing.md b/_docs/tasks/traffic-management-v1alpha3/request-routing.md index 2d614a18baad..799753048180 100644 --- a/_docs/tasks/traffic-management-v1alpha3/request-routing.md +++ b/_docs/tasks/traffic-management-v1alpha3/request-routing.md @@ -1,11 +1,9 @@ --- title: Configuring Request Routing -overview: This task shows you how to configure dynamic request routing based on weights and HTTP headers. +description: This task shows you how to configure dynamic request routing based on weights and HTTP headers. -order: 10 +weight: 10 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md b/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md index d299989f344a..053989119dd2 100644 --- a/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md +++ b/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md @@ -1,11 +1,9 @@ --- title: Setting Request Timeouts -overview: This task shows you how to setup request timeouts in Envoy using Istio. +description: This task shows you how to setup request timeouts in Envoy using Istio. -order: 28 +weight: 28 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md b/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md index 3358d61931a0..8f28d002e106 100644 --- a/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md +++ b/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md @@ -1,11 +1,9 @@ --- title: Traffic Shifting -overview: This task shows you how to migrate traffic from an old to new version of a service. +description: This task shows you how to migrate traffic from an old to new version of a service. -order: 25 +weight: 25 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/circuit-breaking.md b/_docs/tasks/traffic-management/circuit-breaking.md index f1a0913856b7..ac7f9634abb1 100644 --- a/_docs/tasks/traffic-management/circuit-breaking.md +++ b/_docs/tasks/traffic-management/circuit-breaking.md @@ -1,11 +1,9 @@ --- title: Circuit Breaking -overview: This task demonstrates the circuit-breaking capability for resilient applications +description: This task demonstrates the circuit-breaking capability for resilient applications -order: 50 +weight: 50 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/egress-tcp.md b/_docs/tasks/traffic-management/egress-tcp.md index 90d15656f8e0..2fc616f58d83 100644 --- a/_docs/tasks/traffic-management/egress-tcp.md +++ b/_docs/tasks/traffic-management/egress-tcp.md @@ -1,11 +1,9 @@ --- title: Control Egress TCP Traffic -overview: Describes how to configure Istio to route TCP traffic from services in the mesh to external services. +description: Describes how to configure Istio to route TCP traffic from services in the mesh to external services. -order: 41 +weight: 41 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/egress.md b/_docs/tasks/traffic-management/egress.md index e86dc10dbf15..d00d4b0b2b97 100644 --- a/_docs/tasks/traffic-management/egress.md +++ b/_docs/tasks/traffic-management/egress.md @@ -1,11 +1,9 @@ --- title: Control Egress Traffic -overview: Describes how to configure Istio to route traffic from services in the mesh to external services. +description: Describes how to configure Istio to route traffic from services in the mesh to external services. -order: 40 +weight: 40 -layout: docs -type: markdown redirect_from: /docs/tasks/egress.html --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/fault-injection.md b/_docs/tasks/traffic-management/fault-injection.md index 5177977e1be3..d2bbf889e4d8 100644 --- a/_docs/tasks/traffic-management/fault-injection.md +++ b/_docs/tasks/traffic-management/fault-injection.md @@ -1,11 +1,9 @@ --- title: Fault Injection -overview: This task shows how to inject delays and test the resiliency of your application. +description: This task shows how to inject delays and test the resiliency of your application. -order: 20 +weight: 20 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/index.md b/_docs/tasks/traffic-management/index.md index f027de1ddfa9..ec908bbf6dcc 100644 --- a/_docs/tasks/traffic-management/index.md +++ b/_docs/tasks/traffic-management/index.md @@ -1,11 +1,9 @@ --- title: Traffic Management -overview: Describes tasks that demonstrate traffic routing features of Istio service mesh. +description: Describes tasks that demonstrate traffic routing features of Istio service mesh. -order: 10 +weight: 10 -layout: docs -type: markdown toc: false --- diff --git a/_docs/tasks/traffic-management/ingress.md b/_docs/tasks/traffic-management/ingress.md index 6497384501f5..1f2ff540b0e0 100644 --- a/_docs/tasks/traffic-management/ingress.md +++ b/_docs/tasks/traffic-management/ingress.md @@ -1,11 +1,9 @@ --- title: Istio Ingress -overview: Describes how to configure Istio Ingress on Kubernetes. +description: Describes how to configure Istio Ingress on Kubernetes. -order: 30 +weight: 30 -layout: docs -type: markdown redirect_from: /docs/tasks/ingress.html --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/mirroring.md b/_docs/tasks/traffic-management/mirroring.md index e0b1caacbcf0..0d8365dd6721 100644 --- a/_docs/tasks/traffic-management/mirroring.md +++ b/_docs/tasks/traffic-management/mirroring.md @@ -1,11 +1,9 @@ --- title: Mirroring -overview: Demonstrates Istio's traffic shadowing/mirroring capabilities +description: Demonstrates Istio's traffic shadowing/mirroring capabilities -order: 60 +weight: 60 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/request-routing.md b/_docs/tasks/traffic-management/request-routing.md index 5eea6fb435db..956ddb16cb6e 100644 --- a/_docs/tasks/traffic-management/request-routing.md +++ b/_docs/tasks/traffic-management/request-routing.md @@ -1,11 +1,9 @@ --- title: Configuring Request Routing -overview: This task shows you how to configure dynamic request routing based on weights and HTTP headers. +description: This task shows you how to configure dynamic request routing based on weights and HTTP headers. -order: 10 +weight: 10 -layout: docs -type: markdown redirect_from: /docs/tasks/request-routing.html --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/request-timeouts.md b/_docs/tasks/traffic-management/request-timeouts.md index a17b1c16e29f..a6ae628396fe 100644 --- a/_docs/tasks/traffic-management/request-timeouts.md +++ b/_docs/tasks/traffic-management/request-timeouts.md @@ -1,11 +1,9 @@ --- title: Setting Request Timeouts -overview: This task shows you how to setup request timeouts in Envoy using Istio. +description: This task shows you how to setup request timeouts in Envoy using Istio. -order: 28 +weight: 28 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_docs/tasks/traffic-management/traffic-shifting.md b/_docs/tasks/traffic-management/traffic-shifting.md index ac4bee61a63e..706c11ad5406 100644 --- a/_docs/tasks/traffic-management/traffic-shifting.md +++ b/_docs/tasks/traffic-management/traffic-shifting.md @@ -1,11 +1,9 @@ --- title: Traffic Shifting -overview: This task shows you how to migrate traffic from an old to new version of a service. +description: This task shows you how to migrate traffic from an old to new version of a service. -order: 25 +weight: 25 -layout: docs -type: markdown --- {% include home.html %} diff --git a/_faq/general/how-do-i-contribute.md b/_faq/general/how-do-i-contribute.md index fd1b4cbd8f87..a8485b5bf97f 100644 --- a/_faq/general/how-do-i-contribute.md +++ b/_faq/general/how-do-i-contribute.md @@ -1,7 +1,6 @@ --- title: How can I contribute? -order: 70 -type: markdown +weight: 70 --- {% include home.html %} diff --git a/_faq/general/how-do-i-get-started.md b/_faq/general/how-do-i-get-started.md index 7172e10a8504..05889f3c9169 100644 --- a/_faq/general/how-do-i-get-started.md +++ b/_faq/general/how-do-i-get-started.md @@ -1,7 +1,6 @@ --- title: How do I get started using Istio? -order: 30 -type: markdown +weight: 30 --- {% include home.html %} diff --git a/_faq/general/how-was-istio-started.md b/_faq/general/how-was-istio-started.md index c087c2f8ae39..1e1bd1efa993 100644 --- a/_faq/general/how-was-istio-started.md +++ b/_faq/general/how-was-istio-started.md @@ -1,7 +1,6 @@ --- title: How was Istio started? -order: 50 -type: markdown +weight: 50 --- {% include home.html %} diff --git a/_faq/general/istio-doesnt-work.md b/_faq/general/istio-doesnt-work.md index b1ee18cc0766..3abcb6bee0bf 100644 --- a/_faq/general/istio-doesnt-work.md +++ b/_faq/general/istio-doesnt-work.md @@ -1,7 +1,6 @@ --- title: Istio doesn't work - what do I do? -order: 90 -type: markdown +weight: 90 --- {% include home.html %} diff --git a/_faq/general/istio-partners-and-vendors.md b/_faq/general/istio-partners-and-vendors.md index 6ed304b5f52a..8c50fd49bf5e 100644 --- a/_faq/general/istio-partners-and-vendors.md +++ b/_faq/general/istio-partners-and-vendors.md @@ -1,7 +1,6 @@ --- title: How can I discover more about Partner and Vendor opportunities? -order: 75 -type: markdown +weight: 75 --- {% include home.html %} diff --git a/_faq/general/roadmap.md b/_faq/general/roadmap.md index bf5f4fe99965..c7f045460ca6 100644 --- a/_faq/general/roadmap.md +++ b/_faq/general/roadmap.md @@ -1,7 +1,6 @@ --- title: What is Istio's roadmap? -order: 140 -type: markdown +weight: 140 --- {% include home.html %} diff --git a/_faq/general/what-deployment-environment.md b/_faq/general/what-deployment-environment.md index e0c2582556f4..1e42ae36361b 100644 --- a/_faq/general/what-deployment-environment.md +++ b/_faq/general/what-deployment-environment.md @@ -1,7 +1,6 @@ --- title: What deployment environments are supported? -order: 60 -type: markdown +weight: 60 --- {% include home.html %} diff --git a/_faq/general/what-does-istio-mean.md b/_faq/general/what-does-istio-mean.md index 1585315cebf9..8f69f7c51954 100644 --- a/_faq/general/what-does-istio-mean.md +++ b/_faq/general/what-does-istio-mean.md @@ -1,7 +1,6 @@ --- title: What does the word 'Istio' mean? -order: 160 -type: markdown +weight: 160 --- {% include home.html %} diff --git a/_faq/general/what-is-istio.md b/_faq/general/what-is-istio.md index f0b795b2933c..7808a159faed 100644 --- a/_faq/general/what-is-istio.md +++ b/_faq/general/what-is-istio.md @@ -1,7 +1,6 @@ --- title: What is Istio? -order: 10 -type: markdown +weight: 10 --- {% include home.html %} diff --git a/_faq/general/what-is-the-license.md b/_faq/general/what-is-the-license.md index 6edf7f9a40c0..b5024f35276c 100644 --- a/_faq/general/what-is-the-license.md +++ b/_faq/general/what-is-the-license.md @@ -1,7 +1,6 @@ --- title: What is the license? -order: 40 -type: markdown +weight: 40 --- {% include home.html %} diff --git a/_faq/general/where-is-the-documentation.md b/_faq/general/where-is-the-documentation.md index 182d1b025428..3d3d3ccdfe1b 100644 --- a/_faq/general/where-is-the-documentation.md +++ b/_faq/general/where-is-the-documentation.md @@ -1,7 +1,6 @@ --- title: Where is the documentation? -order: 80 -type: markdown +weight: 80 --- {% include home.html %} diff --git a/_faq/general/why-use-istio.md b/_faq/general/why-use-istio.md index 851fa23c69de..6f21b6257f64 100644 --- a/_faq/general/why-use-istio.md +++ b/_faq/general/why-use-istio.md @@ -1,7 +1,6 @@ --- title: Why would I want to use Istio? -order: 20 -type: markdown +weight: 20 --- {% include home.html %} diff --git a/_faq/mixer/attribute-expressions.md b/_faq/mixer/attribute-expressions.md index 6efda9280b69..e7a73c20b4a4 100644 --- a/_faq/mixer/attribute-expressions.md +++ b/_faq/mixer/attribute-expressions.md @@ -1,7 +1,6 @@ --- title: What is the full set of attribute expressions Mixer supports? -order: 20 -type: markdown +weight: 20 --- {% include home.html %} diff --git a/_faq/mixer/mixer-self-monitoring.md b/_faq/mixer/mixer-self-monitoring.md index e5539eef51f2..bf8693d4f37c 100644 --- a/_faq/mixer/mixer-self-monitoring.md +++ b/_faq/mixer/mixer-self-monitoring.md @@ -1,7 +1,6 @@ --- title: Does Mixer provide any self-monitoring? -order: 30 -type: markdown +weight: 30 --- {% include home.html %} diff --git a/_faq/mixer/seeing-mixer-config.md b/_faq/mixer/seeing-mixer-config.md index 2545ef1295e1..c279102124a8 100644 --- a/_faq/mixer/seeing-mixer-config.md +++ b/_faq/mixer/seeing-mixer-config.md @@ -1,7 +1,6 @@ --- title: How do I see all Mixer's configuration? -order: 10 -type: markdown +weight: 10 --- {% include home.html %} diff --git a/_faq/mixer/why-mixer.md b/_faq/mixer/why-mixer.md index a9a0ff429abc..c056304b80d1 100644 --- a/_faq/mixer/why-mixer.md +++ b/_faq/mixer/why-mixer.md @@ -1,7 +1,6 @@ --- title: Why does Istio need Mixer? -order: 0 -type: markdown +weight: 1 --- {% include home.html %} diff --git a/_faq/mixer/writing-custom-adapters.md b/_faq/mixer/writing-custom-adapters.md index 8ed8d4bd6f4c..a0a4482cb89a 100644 --- a/_faq/mixer/writing-custom-adapters.md +++ b/_faq/mixer/writing-custom-adapters.md @@ -1,7 +1,6 @@ --- title: How can I write a custom adapter for Mixer? -order: 40 -type: markdown +weight: 40 --- {% include home.html %} diff --git a/_faq/security/accessing-control-services.md b/_faq/security/accessing-control-services.md index 2c15a45616e3..cf3e1ba826da 100644 --- a/_faq/security/accessing-control-services.md +++ b/_faq/security/accessing-control-services.md @@ -1,7 +1,6 @@ --- title: How to disable Auth on clients to access the Kubernetes API Server (or any control services that don't have Istio sidecar)? -order: 60 -type: markdown +weight: 60 --- Starting with release 0.3, edit the `mtlsExcludedServices` list in Istio config diff --git a/_faq/security/auth-mix-and-match.md b/_faq/security/auth-mix-and-match.md index 32f6f20abae6..a565619959d6 100644 --- a/_faq/security/auth-mix-and-match.md +++ b/_faq/security/auth-mix-and-match.md @@ -1,7 +1,6 @@ --- title: Can I enable Istio Auth with some services while disable others in the same cluster? -order: 30 -type: markdown +weight: 30 --- Starting with release 0.3, you can use service-level annotations to disable (or enable) Istio Auth for particular service-port. The annotation key should be `auth.istio.io/{port_number}`, and the value should be `NONE` (to disable), or `MUTUAL_TLS` (to enable). diff --git a/_faq/security/cert-lifetime-config.md b/_faq/security/cert-lifetime-config.md index 292ccad34b2a..88fc51a36d72 100644 --- a/_faq/security/cert-lifetime-config.md +++ b/_faq/security/cert-lifetime-config.md @@ -1,7 +1,6 @@ --- title: How to configure the lifetime for Istio certificates? -order: 70 -type: markdown +weight: 70 --- {% include home.html %} diff --git a/_faq/security/does-istio-support-authorization.md b/_faq/security/does-istio-support-authorization.md index 0be72b64ab1d..67a128ea9868 100644 --- a/_faq/security/does-istio-support-authorization.md +++ b/_faq/security/does-istio-support-authorization.md @@ -1,7 +1,6 @@ --- title: Does Istio Auth support authorization? -order: 110 -type: markdown +weight: 110 --- {% include home.html %} diff --git a/_faq/security/enabling-disabling-mtls.md b/_faq/security/enabling-disabling-mtls.md index 6845aea00ad6..5ddf934e71a1 100644 --- a/_faq/security/enabling-disabling-mtls.md +++ b/_faq/security/enabling-disabling-mtls.md @@ -1,7 +1,6 @@ --- title: How can I enable/disable mTLS encryption after I installed Istio? -order: 10 -type: markdown +weight: 10 --- {% include home.html %} diff --git a/_faq/security/https-overlay.md b/_faq/security/https-overlay.md index b82cede791db..cb3234e23273 100644 --- a/_faq/security/https-overlay.md +++ b/_faq/security/https-overlay.md @@ -1,7 +1,6 @@ --- title: Can I install Istio sidecar for HTTPS services? -order: 170 -type: markdown +weight: 170 --- {% include home.html %} diff --git a/_faq/security/istio-to-not-istio.md b/_faq/security/istio-to-not-istio.md index f2fa0eb69659..d1649695c68c 100644 --- a/_faq/security/istio-to-not-istio.md +++ b/_faq/security/istio-to-not-istio.md @@ -1,6 +1,5 @@ --- title: Can a service with Istio Auth enabled communicate with a service without Istio? -order: 20 -type: markdown +weight: 20 --- This is not supported currently, but will be in the near future. diff --git a/_faq/security/k8s-api-server.md b/_faq/security/k8s-api-server.md index 3e58db79e3f3..e21daa60cb5d 100644 --- a/_faq/security/k8s-api-server.md +++ b/_faq/security/k8s-api-server.md @@ -1,7 +1,6 @@ --- title: Can I access the Kubernetes API Server with Auth enabled? -order: 50 -type: markdown +weight: 50 --- The Kubernetes API server does not support mutual TLS authentication, so strictly speaking: no. However, if you use version 0.3 or later, see next diff --git a/_faq/security/k8s-health-checks.md b/_faq/security/k8s-health-checks.md index c81d5a207d57..1999a40bd868 100644 --- a/_faq/security/k8s-health-checks.md +++ b/_faq/security/k8s-health-checks.md @@ -1,7 +1,6 @@ --- title: How can I use Kubernetes liveness and readiness for service health check with Istio Auth enabled? -order: 40 -type: markdown +weight: 40 --- If Istio Auth is enabled, http and tcp health check from kubelet will not work since they do not have Istio Auth issued certs. A workaround is to diff --git a/_faq/security/secret-encryption.md b/_faq/security/secret-encryption.md index 46524aa16be8..edcd7d63d20a 100644 --- a/_faq/security/secret-encryption.md +++ b/_faq/security/secret-encryption.md @@ -1,7 +1,6 @@ --- title: Is the secret encrypted for workload key and cert? -order: 125 -type: markdown +weight: 125 --- {% include home.html %} diff --git a/_faq/security/secure-ingress.md b/_faq/security/secure-ingress.md index d3953f065418..cdbd9c4a0b91 100644 --- a/_faq/security/secure-ingress.md +++ b/_faq/security/secure-ingress.md @@ -1,7 +1,6 @@ --- title: How to configure Istio Ingress to only accept TLS traffic? -order: 130 -type: markdown +weight: 130 --- {% include home.html %} diff --git a/_faq/security/use-k8s-secrets.md b/_faq/security/use-k8s-secrets.md index c21c13f22add..7bc09b6726b4 100644 --- a/_faq/security/use-k8s-secrets.md +++ b/_faq/security/use-k8s-secrets.md @@ -1,7 +1,6 @@ --- title: Does Istio Auth use Kubernetes secrets? -order: 120 -type: markdown +weight: 120 --- {% include home.html %} diff --git a/_faq/setup/consul-app-not-working.md b/_faq/setup/consul-app-not-working.md index 062af3056a4e..6cc034524351 100644 --- a/_faq/setup/consul-app-not-working.md +++ b/_faq/setup/consul-app-not-working.md @@ -1,7 +1,6 @@ --- title: Consul - My application isn't working, where can I troubleshoot this? -order: 40 -type: markdown +weight: 40 --- {% include home.html %} diff --git a/_faq/setup/consul-unset-context.md b/_faq/setup/consul-unset-context.md index 718601a5a3fb..f651daf9a5f2 100644 --- a/_faq/setup/consul-unset-context.md +++ b/_faq/setup/consul-unset-context.md @@ -1,7 +1,6 @@ --- title: Consul - How do I unset the context changed by istioctl at the end? -order: 50 -type: markdown +weight: 50 --- {% include home.html %} diff --git a/_faq/setup/eureka-app-not-working.md b/_faq/setup/eureka-app-not-working.md index ac0f1b61b53c..445592587e2e 100644 --- a/_faq/setup/eureka-app-not-working.md +++ b/_faq/setup/eureka-app-not-working.md @@ -1,7 +1,6 @@ --- title: Eureka - My application isn't working, where can I troubleshoot this? -order: 60 -type: markdown +weight: 60 --- {% include home.html %} diff --git a/_faq/setup/eureka-unset-context.md b/_faq/setup/eureka-unset-context.md index 25a1b40158ea..9cdd3b1d4cb3 100644 --- a/_faq/setup/eureka-unset-context.md +++ b/_faq/setup/eureka-unset-context.md @@ -1,7 +1,6 @@ --- title: Eureka - How do I unset the context changed by `istioctl` at the end? -order: 70 -type: markdown +weight: 70 --- {% include home.html %} diff --git a/_faq/setup/k8s-checking-cluster-alpha-features.md b/_faq/setup/k8s-checking-cluster-alpha-features.md index 0c3a718585c6..29e7bedb4290 100644 --- a/_faq/setup/k8s-checking-cluster-alpha-features.md +++ b/_faq/setup/k8s-checking-cluster-alpha-features.md @@ -1,7 +1,6 @@ --- title: Kubernetes - How do I check if my cluster has enabled the alpha features required for automatic sidecar injection? -order: 10 -type: markdown +weight: 10 --- {% include home.html %} diff --git a/_faq/setup/k8s-migrating.md b/_faq/setup/k8s-migrating.md index f953875127b7..b22425b3f938 100644 --- a/_faq/setup/k8s-migrating.md +++ b/_faq/setup/k8s-migrating.md @@ -1,7 +1,6 @@ --- title: Kubernetes - Can I migrate an existing installation from Istio 0.1.x to 0.2.x? -order: 30 -type: markdown +weight: 30 --- {% include home.html %} diff --git a/_faq/setup/k8s-sidecar-injection-not-working.md b/_faq/setup/k8s-sidecar-injection-not-working.md index e040ad50a29a..73a23a458109 100644 --- a/_faq/setup/k8s-sidecar-injection-not-working.md +++ b/_faq/setup/k8s-sidecar-injection-not-working.md @@ -1,7 +1,6 @@ --- title: Kubernetes - How can I debug problems with automatic sidecar injection? -order: 20 -type: markdown +weight: 20 --- {% include home.html %} diff --git a/_faq/traffic-management/ingress-with-no-route-rules.md b/_faq/traffic-management/ingress-with-no-route-rules.md index 9814d62225b4..f44190b3f55e 100644 --- a/_faq/traffic-management/ingress-with-no-route-rules.md +++ b/_faq/traffic-management/ingress-with-no-route-rules.md @@ -1,7 +1,6 @@ --- title: Can I use standard Ingress specification without any route rules? -order: 40 -type: markdown +weight: 40 --- {% include home.html %} diff --git a/_faq/traffic-management/unreachable-services.md b/_faq/traffic-management/unreachable-services.md index 4a0c8528f272..a94744057418 100644 --- a/_faq/traffic-management/unreachable-services.md +++ b/_faq/traffic-management/unreachable-services.md @@ -1,7 +1,6 @@ --- title: How come some of my services are unreachable after creating route rules? -order: 30 -type: markdown +weight: 30 --- {% include home.html %} diff --git a/_faq/traffic-management/viewing-current-rules.md b/_faq/traffic-management/viewing-current-rules.md index c19819e12ae8..add215237bad 100644 --- a/_faq/traffic-management/viewing-current-rules.md +++ b/_faq/traffic-management/viewing-current-rules.md @@ -1,7 +1,6 @@ --- title: How can I view the current route rules I have configured with Istio? -order: 10 -type: markdown +weight: 10 --- {% include home.html %} diff --git a/_faq/traffic-management/weighted-rules-not-working.md b/_faq/traffic-management/weighted-rules-not-working.md index efd7080f576a..ebe19fd12c62 100644 --- a/_faq/traffic-management/weighted-rules-not-working.md +++ b/_faq/traffic-management/weighted-rules-not-working.md @@ -1,7 +1,6 @@ --- title: Why is creating a weighted route rule to split traffic between two versions of a service not working as expected? -order: 20 -type: markdown +weight: 20 --- {% include home.html %} diff --git a/_glossary/adapters.md b/_glossary/adapters.md index 394d8d1d8528..eb3b72be1b06 100644 --- a/_glossary/adapters.md +++ b/_glossary/adapters.md @@ -1,6 +1,5 @@ --- title: Adapters -type: markdown --- {% include home.html %} diff --git a/_glossary/attribute.md b/_glossary/attribute.md index 911e1b6af7df..cfebd53d05a0 100644 --- a/_glossary/attribute.md +++ b/_glossary/attribute.md @@ -1,6 +1,5 @@ --- title: Attribute -type: markdown --- {% include home.html %} diff --git a/_glossary/destination.md b/_glossary/destination.md index a9174d8c657f..56142dc9a142 100644 --- a/_glossary/destination.md +++ b/_glossary/destination.md @@ -1,6 +1,5 @@ --- title: Destination -type: markdown --- The remote upstream service [Envoy](#envoy) is talking to on behalf of a [source](#source) [workload](#workload). There can be one or more [service versions](#service-version) for a given [service](#service) and Envoy chooses the version based on diff --git a/_glossary/envoy.md b/_glossary/envoy.md index 8a2ea10f9da2..50ddd26d1055 100644 --- a/_glossary/envoy.md +++ b/_glossary/envoy.md @@ -1,6 +1,5 @@ --- title: Envoy -type: markdown --- The high-performance proxy that Istio uses to mediate inbound and outbound traffic for all [services](#service) in the [service mesh](#service-mesh). [Learn more about Envoy](https://envoyproxy.github.io/envoy/). diff --git a/_glossary/mixer-handler.md b/_glossary/mixer-handler.md index 6863c25a56bb..4d58d0b458a5 100644 --- a/_glossary/mixer-handler.md +++ b/_glossary/mixer-handler.md @@ -1,6 +1,5 @@ --- title: Mixer Handler -type: markdown --- {% include home.html %} diff --git a/_glossary/mixer-instance.md b/_glossary/mixer-instance.md index 96665a814820..5ee21759012c 100644 --- a/_glossary/mixer-instance.md +++ b/_glossary/mixer-instance.md @@ -1,6 +1,5 @@ --- title: Mixer Instance -type: markdown --- {% include home.html %} diff --git a/_glossary/mixer.md b/_glossary/mixer.md index 44eba9f4744a..793d311daa89 100644 --- a/_glossary/mixer.md +++ b/_glossary/mixer.md @@ -1,6 +1,5 @@ --- title: Mixer -type: markdown --- {% include home.html %} diff --git a/_glossary/mutual-tls.md b/_glossary/mutual-tls.md index 3ce556cac277..819252016ec0 100644 --- a/_glossary/mutual-tls.md +++ b/_glossary/mutual-tls.md @@ -1,6 +1,5 @@ --- title: Mutual TLS Authentication -type: markdown --- {% include home.html %} diff --git a/_glossary/pilot.md b/_glossary/pilot.md index 593e35c0229a..061d4592c8d4 100644 --- a/_glossary/pilot.md +++ b/_glossary/pilot.md @@ -1,5 +1,4 @@ --- title: Pilot -type: markdown --- The Istio component that programs the [Envoy](#envoy) proxies, responsible for service discovery, load balancing, and routing. diff --git a/_glossary/secure-naming.md b/_glossary/secure-naming.md index d3031d272f75..bb87837dfb86 100644 --- a/_glossary/secure-naming.md +++ b/_glossary/secure-naming.md @@ -1,6 +1,5 @@ --- title: Secure Naming -type: markdown --- Provides a mapping between a [service name](#service-name) and the [workload principals](#workload-principal) that are authorized to run the [workloads](#workload) implementing a [service](#service). diff --git a/_glossary/service-consumer.md b/_glossary/service-consumer.md index 235eec4f124b..d5a383b18287 100644 --- a/_glossary/service-consumer.md +++ b/_glossary/service-consumer.md @@ -1,5 +1,4 @@ --- title: Service Consumer -type: markdown --- The agent that is using a [service](#service). diff --git a/_glossary/service-endpoint.md b/_glossary/service-endpoint.md index 044f00261d08..76a2dee5075e 100644 --- a/_glossary/service-endpoint.md +++ b/_glossary/service-endpoint.md @@ -1,6 +1,5 @@ --- title: Service Endpoint -type: markdown --- The network-reachable manifestation of a [service](#service). Service endpoints are exposed by [workloads](#workload). Not all services have service endpoints. diff --git a/_glossary/service-mesh.md b/_glossary/service-mesh.md index ff410e744c05..b97452fa8cf2 100644 --- a/_glossary/service-mesh.md +++ b/_glossary/service-mesh.md @@ -1,6 +1,5 @@ --- title: Service Mesh -type: markdown --- A shared set of names and identities that allows for common policy enforcement and telemetry collection. [Service names](#service-name) and [workload principals](#workload-principal) are unique within a service mesh. diff --git a/_glossary/service-name.md b/_glossary/service-name.md index d3e70de519c7..f30fc6c8b525 100644 --- a/_glossary/service-name.md +++ b/_glossary/service-name.md @@ -1,6 +1,5 @@ --- title: Service Name -type: markdown --- A unique name for a [service](#service), identifying it within the [service mesh](#service-mesh). A service may not be renamed and maintain its identity, each service name is unique. diff --git a/_glossary/service-operator.md b/_glossary/service-operator.md index 9f4e6d87a1cb..d1e25b189286 100644 --- a/_glossary/service-operator.md +++ b/_glossary/service-operator.md @@ -1,6 +1,5 @@ --- title: Service Operator -type: markdown --- The agent that manages a [service](#service) within a [service mesh](#service-mesh) by manipulating configuration state and monitoring the service's health via a variety of dashboards. diff --git a/_glossary/service-producer.md b/_glossary/service-producer.md index 10cd4db92d84..e59d092cf489 100644 --- a/_glossary/service-producer.md +++ b/_glossary/service-producer.md @@ -1,5 +1,4 @@ --- title: Service Producer -type: markdown --- The agent that creates a [service](#service). diff --git a/_glossary/service-version.md b/_glossary/service-version.md index c70eda54582e..862488cad927 100644 --- a/_glossary/service-version.md +++ b/_glossary/service-version.md @@ -1,6 +1,5 @@ --- title: Service Version -type: markdown --- Distinct variants of a [service](#service), typically backed by a different versions of a [workload](#workload) binary. Common scenarios where multiple [service versions](#service-version) may be used include A/B testing, canary rollouts, etc. diff --git a/_glossary/service.md b/_glossary/service.md index 650690421222..c3cb7cc3e601 100644 --- a/_glossary/service.md +++ b/_glossary/service.md @@ -1,6 +1,5 @@ --- title: Service -type: markdown --- A delineated group of related behaviors within a [service mesh](#service-mesh). Services are identified using a [service name](#service-name), diff --git a/_glossary/source.md b/_glossary/source.md index d5ea707a80c6..9466770f093c 100644 --- a/_glossary/source.md +++ b/_glossary/source.md @@ -1,6 +1,5 @@ --- title: Source -type: markdown --- The downstream client of the [Envoy](#envoy) proxy. Within the [service mesh](#service-mesh) a source is typically a diff --git a/_glossary/workload-id.md b/_glossary/workload-id.md index 7a19fad143f0..2e6af7eda36c 100644 --- a/_glossary/workload-id.md +++ b/_glossary/workload-id.md @@ -1,6 +1,5 @@ --- title: Workload ID -type: markdown --- A unique identifier for an individual instance of a [workload](#workload). Like [workload name](#workload-name), the workload ID is not a strongly verified property and should not be used diff --git a/_glossary/workload-name.md b/_glossary/workload-name.md index 9258d916f1fc..d4c538769034 100644 --- a/_glossary/workload-name.md +++ b/_glossary/workload-name.md @@ -1,6 +1,5 @@ --- title: Workload Name -type: markdown --- A unique name for a [workload](#workload), identifying it within the [service mesh](#service-mesh). Unlike the [service name](#service-name) and the [workload principal], the workload name is not a diff --git a/_glossary/workload-principal.md b/_glossary/workload-principal.md index ff239c6c0a7e..6a8d2e6ca22e 100644 --- a/_glossary/workload-principal.md +++ b/_glossary/workload-principal.md @@ -1,6 +1,5 @@ --- title: Workload Principal -type: markdown --- Identifies the verifiable authority under which a [workload](#workload) runs. Istio's service-to-service authentication is used to produce the workload principal. diff --git a/_glossary/workload.md b/_glossary/workload.md index bfd267917580..06851d4afe7f 100644 --- a/_glossary/workload.md +++ b/_glossary/workload.md @@ -1,6 +1,5 @@ --- title: Workload -type: markdown --- A process/binary deployed by operators in Istio, typically represented by entities such as containers, pods, or VMs. * A workload can expose zero or more [service endpoints](#service-endpoint). diff --git a/_help/bugs.md b/_help/bugs.md index 410c3869a784..4747f76f0237 100644 --- a/_help/bugs.md +++ b/_help/bugs.md @@ -1,11 +1,9 @@ --- title: Reporting Bugs -overview: What to do about bugs +description: What to do about bugs -order: 35 +weight: 35 -layout: help -type: markdown redirect_from: /bugs toc: false --- diff --git a/_help/faq/general.html b/_help/faq/general.html index 89c5df50d2f2..4616e72aa1f5 100644 --- a/_help/faq/general.html +++ b/_help/faq/general.html @@ -1,8 +1,8 @@ --- title: General -overview: General Q&A +description: General Q&A -order: 10 +weight: 10 layout: help --- diff --git a/_help/faq/index.md b/_help/faq/index.md index cb627745b982..6630e01a97ac 100644 --- a/_help/faq/index.md +++ b/_help/faq/index.md @@ -1,11 +1,9 @@ --- title: FAQ -overview: Frequently Asked Questions about Istio. +description: Frequently Asked Questions about Istio. -order: 20 +weight: 20 -layout: help -type: markdown toc: false redirect_from: diff --git a/_help/faq/mixer.html b/_help/faq/mixer.html index abbc6e6c4278..5f754d07c0dc 100644 --- a/_help/faq/mixer.html +++ b/_help/faq/mixer.html @@ -1,8 +1,8 @@ --- title: Mixer -overview: Mixer Q&A +description: Mixer Q&A -order: 40 +weight: 40 layout: help --- diff --git a/_help/faq/security.html b/_help/faq/security.html index 58771291665c..dab199124ffd 100644 --- a/_help/faq/security.html +++ b/_help/faq/security.html @@ -1,8 +1,8 @@ --- title: Security -overview: Security Q&A +description: Security Q&A -order: 30 +weight: 30 layout: help --- diff --git a/_help/faq/setup.html b/_help/faq/setup.html index 242be527b0e3..4e13965cc0e7 100644 --- a/_help/faq/setup.html +++ b/_help/faq/setup.html @@ -1,8 +1,8 @@ --- title: Setup -overview: Setup Q&A +description: Setup Q&A -order: 20 +weight: 20 layout: help --- diff --git a/_help/faq/traffic-management.html b/_help/faq/traffic-management.html index 11ae8c2f982e..ed5f51599ab1 100644 --- a/_help/faq/traffic-management.html +++ b/_help/faq/traffic-management.html @@ -1,8 +1,8 @@ --- title: Traffic Management -overview: Traffic Management Q&A +description: Traffic Management Q&A -order: 50 +weight: 50 layout: help --- diff --git a/_help/glossary.md b/_help/glossary.md index f9b2f6527e4f..f378632e9090 100644 --- a/_help/glossary.md +++ b/_help/glossary.md @@ -1,11 +1,9 @@ --- title: Glossary -overview: A glossary of common Istio terms. +description: A glossary of common Istio terms. -order: 30 +weight: 30 -layout: help -type: markdown redirect_from: - "/glossary" - "/docs/welcome/glossary.html" diff --git a/_help/index.md b/_help/index.md index 31b41a10ee98..8f261e78586a 100644 --- a/_help/index.md +++ b/_help/index.md @@ -1,11 +1,9 @@ --- title: Help! -overview: A bunch of resources to help you deploy, configure and use Istio. +description: A bunch of resources to help you deploy, configure and use Istio. -order: 10 +weight: 10 -layout: help -type: markdown toc: false --- {% include home.html %} diff --git a/_help/troubleshooting.md b/_help/troubleshooting.md index ce7cef450a44..25aa02f177a6 100644 --- a/_help/troubleshooting.md +++ b/_help/troubleshooting.md @@ -1,11 +1,9 @@ --- title: Troubleshooting Guide -overview: Practical advice on practical problems with Istio +description: Practical advice on practical problems with Istio -order: 40 +weight: 40 -layout: help -type: markdown redirect_from: /troubleshooting force_inline_toc: true --- diff --git a/_includes/collection_nav.html b/_includes/collection_nav.html index 908e32289c05..84ed782b3af8 100644 --- a/_includes/collection_nav.html +++ b/_includes/collection_nav.html @@ -1,6 +1,6 @@ {% comment %} -Assigns the next_page_url, next_page_title, next_page_overview, prev_page_url, prev_page_title, and prev_page_overview variables the -URLs, titles and overviews of the next and previous pages within the current collection, relative to the current page. +Assigns the next_page_url, next_page_title, next_page_description, prev_page_url, prev_page_title, and prev_page_description variables the +URLs, titles and descriptions of the next and previous pages within the current collection, relative to the current page. {% endcomment %} {% comment %} @@ -32,7 +32,7 @@ {% if name != "index.html" %} {% assign next_page_url = urls[next_index] %} {% assign next_page_title = titles[next_index] %} - {% assign next_page_overview = overviews[next_index] %} + {% assign next_page_description = descriptions[next_index] %} {% break %} {% endif %} {% endfor %} @@ -53,7 +53,7 @@ {% if name != "index.html" %} {% assign prev_page_url = urls[prev_index] %} {% assign prev_page_title = titles[prev_index] %} - {% assign prev_page_overview = overviews[prev_index] %} + {% assign prev_page_description = descriptions[prev_index] %} {% break %} {% endif %} {% endfor %} diff --git a/_includes/faq.html b/_includes/faq.html index ad6ef8741574..491d0402932a 100644 --- a/_includes/faq.html +++ b/_includes/faq.html @@ -1,5 +1,5 @@ -{% assign faqs = site.faq | sort: "order" %} +{% assign faqs = site.faq | sort: "weight" %} {% for q in faqs %} {% assign comp = q.path | split: '/' %} {% assign qcat = comp[1] %} diff --git a/_includes/latest_blog_post.html b/_includes/latest_blog_post.html index 342a67d1d2f7..4d8b5863528f 100644 --- a/_includes/latest_blog_post.html +++ b/_includes/latest_blog_post.html @@ -5,7 +5,7 @@ {% include home.html %} {% assign latest_year = "0" %} -{% assign sorted = site.blog | sort: "order" %} +{% assign sorted = site.blog | sort: "weight" %} {% for d in sorted %} {% if d.draft == true %} {% continue %} diff --git a/_includes/primary.html b/_includes/primary.html index f48baf960d07..18ebbb050fcc 100644 --- a/_includes/primary.html +++ b/_includes/primary.html @@ -75,12 +75,12 @@ <h1 id="title">{{page.title}}</h1> <div class="row"> <div class="col-6"> {% if next_page_url %} - <a title="{{next_page_overview}}" href="{{home}}{{next_page_url}}"><i class="fa fa-arrow-left"></i>{{next_page_title}}</a> + <a title="{{next_page_description}}" href="{{home}}{{next_page_url}}"><i class="fa fa-arrow-left"></i> {{next_page_title}}</a> {% endif %} </div> <div class="col-6" style="text-align: right"> {% if prev_page_url %} - <a title="{{prev_page_overview}}" href="{{home}}{{prev_page_url}}">{{prev_page_title}} <i class="fa fa-arrow-right"></i></a> + <a title="{{prev_page_description}}" href="{{home}}{{prev_page_url}}">{{prev_page_title}} <i class="fa fa-arrow-right"></i></a> {% endif %} </div> </div> diff --git a/_includes/section-index.html b/_includes/section-index.html index ae6cee4c9fb4..803f46e195cd 100644 --- a/_includes/section-index.html +++ b/_includes/section-index.html @@ -21,7 +21,7 @@ {% include sort-hierarchy.html docs=include.docs prefix=prefix %} -<p>{{page.overview}}</p> +<p>{{page.description}}</p> {% assign pageComponents = page.url | split: "/" %} @@ -36,7 +36,7 @@ {% endif %} {% assign title = titles[forloop.index0] %} - {% assign overview = overviews[forloop.index0] %} + {% assign description = descriptions[forloop.index0] %} {% assign components = url | split: "/" %} {% assign numComponents = components | size %} @@ -48,7 +48,7 @@ {% endfor %} <li class="directory"> - <span title="{{overview}}">{{title}}</span> + <span title="{{description}}">{{title}}</span> <ul> {% else %} @@ -57,7 +57,7 @@ </ul></li> {% endfor %} <li class="file"> - <a href="{{home}}{{url}}">{{title}}</a>. {{ overview }} + <a href="{{home}}{{url}}">{{title}}</a>. {{ description }} </li> {% endif %} {% assign depth = numComponents %} diff --git a/_includes/sidebar.html b/_includes/sidebar.html index 0dc3e5395f68..b96a0843ba7d 100644 --- a/_includes/sidebar.html +++ b/_includes/sidebar.html @@ -36,7 +36,7 @@ {% endif %} {% assign title = titles[forloop.index0] %} - {% assign overview = overviews[forloop.index0] %} + {% assign description = descriptions[forloop.index0] %} {% assign components = url | split: "/" %} {% assign numComponents = components | size %} @@ -67,11 +67,11 @@ <div class="card"> <div class="card-header" role="tab" id="header{{forloop.index0}}"> {% if include.singlecard %} - <div title="{{overview}}"> + <div title="{{description}}"> {{title}} </div> {% else %} - <a data-toggle="collapse" href="#collapse{{forloop.index0}}" title="{{overview}}" role="button" + <a data-toggle="collapse" href="#collapse{{forloop.index0}}" title="{{description}}" role="button" aria-controls="collapse{{forloop.index0}}"> <div> {{title}} @@ -97,7 +97,7 @@ <i class='fa fa-lg fa-caret-right'></i> {% endif %} {% assign niceurl = url | remove: "/index.html" %} - <a class="{% if url == page.url %}current{% endif %}" title="{{overview}}" href="{{home}}{{niceurl}}">{{title}}</a> + <a class="{% if url == page.url %}current{% endif %}" title="{{description}}" href="{{home}}{{niceurl}}">{{title}}</a> </label> <ul class="tree{% if parent == false %} collapse{% endif %}"> {% endif %} @@ -108,9 +108,9 @@ {% endfor %} <li> {% if url == page.url %} - <span class="current" title="{{overview}}">{{title}}</span> + <span class="current" title="{{description}}">{{title}}</span> {% else %} - <a title="{{overview}}" href="{{home}}{{url}}">{{title}}</a> + <a title="{{description}}" href="{{home}}{{url}}">{{title}}</a> {% endif %} </li> {% endif %} diff --git a/_includes/sort-hierarchy.html b/_includes/sort-hierarchy.html index 0d786a816712..39bed070638a 100644 --- a/_includes/sort-hierarchy.html +++ b/_includes/sort-hierarchy.html @@ -1,6 +1,6 @@ {% comment %} Purpose: - Sorts a document hierarchy by the 'order' front-matter entry of each doc. + Sorts a document hierarchy by the 'weight' front-matter entry of each doc. This is hard since Liquid doesn't have functions, recursion, scoped variables, or data structures. Oh, and Liquid is very slow too. @@ -13,11 +13,11 @@ Results: * urls (string array) - the sorted document urls * titles (string array) - the sorted document titles - * overviews (string array) - the sorted document overviews + * descriptions (string array) - the sorted document descriptions Note: This code uses $ and ^ as magic string markers. If any document's - URL, title, or overview contain these characters, then this code + URL, title, or description contain these characters, then this code will get confused and return gibberish. {% endcomment %} @@ -34,9 +34,9 @@ {% continue %} {% endif %} - {% assign o = "00000" | append: doc.order %} + {% assign o = "00000" | append: doc.weight %} {% assign start = o | size | minus: 5 %} - {% assign order = o | slice: start, 5 %} + {% assign weight = o | slice: start, 5 %} {% assign components = doc.url | split: "/" %} {% assign count = components | size | minus:2 %} @@ -49,9 +49,9 @@ {% for sub in include.docs %} {% if sub.url == p %} - {% assign o = "00000" | append: sub.order %} + {% assign o = "00000" | append: sub.weight %} {% assign start = o | size | minus: 5 %} - {% assign order = o | slice: start, 5 | append:"/" | append: order %} + {% assign weight = o | slice: start, 5 | append:"/" | append: weight %} {% break %} {% endif %} {% endfor %} @@ -59,13 +59,13 @@ {% assign name = components | last %} {% if name == "index.html" %} - {% assign len = order | size | minus: 5 %} - {% assign order = order | slice: 0, len | append: "#####" %} + {% assign len = weight | size | minus: 5 %} + {% assign weight = weight | slice: 0, len | append: "#####" %} {% endif %} {% comment %} Take the full doc url and replace the last component of it by the document title, and use that for collation such that - docs in the same directory end up sorted first by 'order', then by title + docs in the same directory end up sorted first by 'weight', then by title {% endcomment %} {% assign hackUrl = "" %} {% for i in (1..count) %} @@ -73,8 +73,8 @@ {% endfor %} {% assign hackUrl = hackUrl | append: "/" | append: doc.title %} - {% assign a = a | append: "^" | append: order | append: "$" | append: hackUrl | append: "$" | append: doc.url | append: "$" | append: doc.title | - append: "$" | append: doc.overview %} + {% assign a = a | append: "^" | append: weight | append: "$" | append: hackUrl | append: "$" | append: doc.url | append: "$" | append: doc.title | + append: "$" | append: doc.description %} {% endfor %} {% assign sorted = a | split: "^" | sort %} @@ -82,13 +82,13 @@ {% assign parts = s | split: "$" %} {% assign urls = urls | append: "$" | append: parts[2] %} {% assign titles = titles | append: "$" | append: parts[3] %} - {% assign overviews = overviews | append: "$" | append: parts[4] %} + {% assign descriptions = descriptions | append: "$" | append: parts[4] %} {% endfor %} {% assign urlslen = urls | size | minus: 2 %} {% assign titleslen = titles | size | minus: 2 %} -{% assign overviewslen = overviews | size | minus: 2 %} +{% assign descriptionslen = descriptions | size | minus: 2 %} {% assign urls = urls | slice: 2, urlslen | split: "$" %} {% assign titles = titles | slice: 2, titleslen | split: "$" %} -{% assign overviews = overviews | slice: 2, overviewslen | split: "$" %} +{% assign descriptions = descriptions | slice: 2, descriptionslen | split: "$" %} diff --git a/_layouts/base.html b/_layouts/base.html index b904d7b80a97..7098c0a9d33f 100644 --- a/_layouts/base.html +++ b/_layouts/base.html @@ -11,10 +11,10 @@ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="theme-color" content="#466BB0"/> - {% if page.overview == nil %} + {% if page.description == nil %} {% assign description = "An open platform to connect, manage, and secure microservices." %} {% else %} - {% assign description = page.overview %} + {% assign description = page.description %} {% endif %} <meta name="title" content="{{page.title}}"> diff --git a/community.md b/community.md index a572693ece13..3f1af32a7b5a 100644 --- a/community.md +++ b/community.md @@ -1,8 +1,7 @@ --- title: Community -overview: Information on the various ways to participate and interact with the Istio community. +description: Information on the various ways to participate and interact with the Istio community. layout: community -type: markdown --- {% include home.html %} From b9189326bf5c267eda4d9975f49009c554d7a10d Mon Sep 17 00:00:00 2001 From: Steven Dake <stdake@cisco.com> Date: Wed, 2 May 2018 17:57:58 +0200 Subject: [PATCH 161/191] Improves multicluster documentation (#1217) * Improves multicluster documentation Improve documentation based upon fresh eyes running through the documented process. * Address reviewer comments. * More refinement. * Exclude rule MD028 Rule 028 is: https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md028---blank-line-inside-blockquote The rationale below cut and pasted from markdownlint seems valid for the general case, however, our MD parser always produces seprate block-quotes, which is what I am after in this PR. I think other people will prefer our renders of blockquotes (separate blockquotes); Rationale: Some markdown parsers will treat two blockquotes separated by one or more blank lines as the same blockquote, while others will treat them as separate blockquotes. --- .../setup/kubernetes/multicluster-install.md | 78 ++++++++++++++----- mdl_style.rb | 1 + 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/_docs/setup/kubernetes/multicluster-install.md b/_docs/setup/kubernetes/multicluster-install.md index 69aa612554ed..61fe504439eb 100644 --- a/_docs/setup/kubernetes/multicluster-install.md +++ b/_docs/setup/kubernetes/multicluster-install.md @@ -23,8 +23,7 @@ to meet the following requirements: * Individual cluster Pod CIDR ranges and service CIDR ranges must be unique across the multicluster environment and may not overlap. - * All nodes' pod CIDR in every cluster must be routable to every other nodes' -pod CIDR. + * All pod CIDRs in every cluster must be routable to each other. * All Kubernetes control plane API servers must be routable to each other. @@ -38,13 +37,20 @@ has been validated with multicluster. <img src="{{home}}/img/exclamation-mark.svg" alt="Warning" title="Warning" style="width: 32px; display:inline" /> All known caveats and known problems with multicluster for the 0.8 release are [tracked here](https://github.com/istio/istio/issues/4822). +## Overview + +Multicluster functions by enabling Kubernetes control planes running +a remote configuration to connect to **one** Istio control plane. +Once one or more remote Kubernetes clusters are connected to the +Istio control plane, Envoy can then communicate with the **single** +Istio control plane and form a mesh network across multiple Kubernetes +clusters. + ## Deploy all Kubernetes clusters to be used in the mesh -Use your desired technique to deploy all Kubernetes clusters -that are to participate in the mesh with only Kubernetes and -the CNI of choice. Once the remote clusters are deployed, each -one will have a credentials file associated with the admin -context typically located in `$HOME/.kube/config`. +After deployment of remote clusters, each one will have a +credentials file associated with the admin context typically +located in `$HOME/.kube/config`. ## Gather credential files from remote @@ -72,15 +78,28 @@ be unique per remote. ## Instantiate the credentials for each remote cluster -Execute this work on the cluster intended to run the Istio control +> Execute this work on the cluster intended to run the Istio control plane. +> Istio can be installed in a different namespace other than +istio-system. + Create a namespace for instantiating the secrets: ```bash kubectl create ns istio-system ``` +> Ordering currently matters. Secrets must be created prior to +the deployment of the Istio control plane. Creating secrets +after Istio is started will not register the secrets with Istio +properly. + +> The local cluster running the Istio control plane does not need +it's secrets stored and labeled. The local node is always aware of +it's Kubernetes credentials, but the local node is not aware of +the remote nodes' credentials. + Create a secret and label it properly for each remote cluster: ```bash @@ -90,26 +109,42 @@ kubectl label secret ${CLUSTER_NAME} istio/multiCluster=true -n istio-system popd ``` -<img src="{{home}}/img/exclamation-mark.svg" alt="Warning" title="Warning" style="width: 32px; display:inline" />Ordering currently matters. Secrets must be created prior to the deployment of -the Istio control plane. Creating secrets after Istio is started will not register the -secrets with Istio properly. - ## Deploy the local Istio control plane -Install the [Istio control plane]({{home}}/docs/setup/kubernetes/quick-start.html) +Install the [Istio control plane]({{home}}/docs/setup/kubernetes/quick-start.html#installation-steps) on **one** Kubernetes cluster. ## Install the Istio remote on every remote cluster -<img src="{{home}}/img/exclamation-mark.svg" alt="Important" title="Important" style="width: 32px; display:inline" /> -The istio-remote component must be deployed to each remote Kubernetes cluster. +The istio-remote component must be deployed to each remote Kubernetes +cluster. There are two approaches to installing the remote. The remote +can be installed and managed entirely by Helm and Tiller, or via Helm and +kubectl. + +### Set environment variables for Pod IPs from Istio control plane needed by remote + +> Please wait for the Istio control plane to finish initializing +before proceeding to steps in this section. + +> These operations must be run on the Istio control plane cluster +to capture the Pilot, Policy, and Statsd Pod IP endpoints. + +> If Helm is used with Tiller on each remote, copy the environment +variables to each node before using Helm to connect the remote +cluster to the Istio control plane. + +```bash +export PILOT_POD_IP=$(kubectl -n istio-system get pod -l istio=pilot -o jsonpath='{.items[0].status.podIP}') +export POLICY_POD_IP=$(kubectl -n istio-system get pod -l istio=mixer -o jsonpath='{.items[0].status.podIP}') +export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-bridge -o jsonpath='{.items[0].status.podIP}') +``` ### Use kubectl with Helm to connect the remote cluster to the local 1. Use the helm template command on a remote to specify the Istio control plane service endpoints: ```bash - helm template install/kubernetes/helm/istio-remote --name istio-remote --set pilotEndpoint=`pod_ip_of_pilot_local` --set policyEndpoint=`pod_ip_of_policy_local` --set statsdEndpoint=`pod_ip_of_statsd_local` > $HOME/istio-remote.yaml + helm template install/kubernetes/helm/istio-remote --name istio-remote --set global.pilotEndpoint=${PILOT_POD_IP} --set global.policyEndpoint=${POLICY_POD_IP} --set global.statsdEndpoint=${STATSD_POD_IP} > $HOME/istio-remote.yaml ``` 1. Instantiate the remote cluster's connection to the Istio control plane: @@ -136,12 +171,17 @@ install one: 1. Install the Helm chart: ```bash - helm install install/kubernetes/helm/istio-remote --name istio-remote --set pilotEndpoint=`pod_ip_of_pilot_local` --set policyEndpoint=`pod_ip_of_policy_local` --set statsdEndpoint=`pod_ip_of_statsd_local` > $HOME/istio-remote.yaml -n istio-system + helm install install/kubernetes/helm/istio-remote --name istio-remote --set global.pilotEndpoint=${PILOT_POD_IP} --set global.policyEndpoint=${POLICY_POD_IP} --set global.statsdEndpoint=${STATSD_POD_IP} --namespace istio-system ``` ### Helm configuration parameters -The `isito-remote` Helm chart requires the configuration of two specific variables defined in the following table: +> The `pilotEndpoint`, `policyEndpoint`, `statsdEndpoint` need to be resolvable via Kubernetes. +The simplest approach to enabling resolution for these variables is to specify the Pod IP of +the various services. One problem with this is Pod IP's change during the lifetime of the +service. + +The `isito-remote` Helm chart requires the three specific variables to be configured as defined in the following table: | Helm Variable | Accepted Values | Default | Purpose of Value | | --- | --- | --- | --- | @@ -149,8 +189,6 @@ The `isito-remote` Helm chart requires the configuration of two specific variabl | `global.policyEndpoint` | A valid IP address | istio-policy.istio-system | Specifies the Istio control plane's policy Pod IP address | | `global.statsdEndpoint` | A valid IP address | istio-statsd-prom-bridge.istio-system | Specifies the Istio control plane's statsd Pod IP address | -> The `pilotEndpoint`, `policyEndpoint`, `statsdEndpoint` need to be resolvable via Kubernetes. - ## Uninstalling > The uninstall method must match the installation method (`Helm and kubectl` or `Helm and Tiller` based). diff --git a/mdl_style.rb b/mdl_style.rb index 0ce4bd1eff67..e2ac7ccb84bc 100644 --- a/mdl_style.rb +++ b/mdl_style.rb @@ -2,6 +2,7 @@ rule 'MD002', :level => 2 rule 'MD013', :line_length => 160, :code_blocks => false, :tables => false rule 'MD026', :punctuation => ".,;:!" +exclude_rule 'MD028' exclude_rule 'MD032' exclude_rule 'MD041' exclude_rule 'MD031' From 09e3e190ee3c98576a2fe977875d5833566a23af Mon Sep 17 00:00:00 2001 From: Tao Li <taotao12@gmail.com> Date: Wed, 2 May 2018 10:44:20 -0700 Subject: [PATCH 162/191] Improve the doc to apply istio-auth.yaml (#1227) --- _docs/setup/kubernetes/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/setup/kubernetes/quick-start.md b/_docs/setup/kubernetes/quick-start.md index 64a50ef99099..c211b17ecc6a 100644 --- a/_docs/setup/kubernetes/quick-start.md +++ b/_docs/setup/kubernetes/quick-start.md @@ -251,7 +251,7 @@ with the [Helm Chart]({{home}}/docs/setup/kubernetes/helm-install.html): _**OR**_ - b) Install Istio and enable [mutual TLS authentication]({{home}}/docs/concepts/security/mutual-tls.html) between sidecars.: + b) Install Istio and enable [mutual TLS authentication]({{home}}/docs/concepts/security/mutual-tls.html) between sidecars. This option is mostly for new clusters, i.e., all applications have sidecars injected during their deployment. For existing applications, please choose the above option and enable mutual TLS using [authentication policy]({{home}}/docs/tasks/security/authn-policy.html): ```bash kubectl apply -f install/kubernetes/istio-auth.yaml From b098123d6f7df6bc2c0d239fc7d6fcf136ec2ae1 Mon Sep 17 00:00:00 2001 From: Tao Li <taotao12@gmail.com> Date: Wed, 2 May 2018 11:37:17 -0700 Subject: [PATCH 163/191] Fix doc (#1228) --- _docs/tasks/security/per-service-mtls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/tasks/security/per-service-mtls.md b/_docs/tasks/security/per-service-mtls.md index a0573a913569..084ef078363d 100644 --- a/_docs/tasks/security/per-service-mtls.md +++ b/_docs/tasks/security/per-service-mtls.md @@ -7,7 +7,7 @@ weight: 50 --- {% include home.html %} -> If you are using Istio 0.7 or later, please refer to [authentication policy task]({{home}}/docs/tasks/security/authn-policy.html) for alternative (recommended) solution using authentication policy. +> This feature will soon be deprecated. If you are using Istio 0.7 or later, please refer to [authentication policy task]({{home}}/docs/tasks/security/authn-policy.html) for the recommended approach moving forward. In the [Installation guide]({{home}}/docs/setup/kubernetes/quick-start.html#installation-steps), we show how to enable [mutual TLS authentication]({{home}}/docs/concepts/security/mutual-tls.html) between sidecars. The settings will be applied to all sidecars in the mesh. From 40dca03a107ff82950f54d65135bfbed3654eb2e Mon Sep 17 00:00:00 2001 From: Frank Budinsky <frankb@ca.ibm.com> Date: Wed, 2 May 2018 17:49:30 -0400 Subject: [PATCH 164/191] Task/guide updates for v1alpha3 (#1231) * Task/guide updates for v1alpha3 * fix typo * remove trailing spaces * tweaks --- _docs/guides/bookinfo.md | 90 +++++++++---------- .../traffic-management-v1alpha3/egress-tcp.md | 4 +- .../traffic-management-v1alpha3/egress.md | 6 +- .../traffic-management-v1alpha3/ingress.md | 2 - 4 files changed, 48 insertions(+), 54 deletions(-) diff --git a/_docs/guides/bookinfo.md b/_docs/guides/bookinfo.md index cf105ed64fa4..613080a5efbc 100644 --- a/_docs/guides/bookinfo.md +++ b/_docs/guides/bookinfo.md @@ -79,26 +79,25 @@ To start the application, follow the instructions below corresponding to your Is 1. Bring up the application containers: - If you are using [manual sidecar injection]({{home}}/docs/setup/kubernetes/sidecar-injection.html#manual-sidecar-injection), - use the following command instead: + * If you are using [manual sidecar injection]({{home}}/docs/setup/kubernetes/sidecar-injection.html#manual-sidecar-injection), + use the following command - ```bash - kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) - ``` + ```bash + kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) + ``` - If you are using a cluster with - [automatic sidecar injection]({{home}}/docs/setup/kubernetes/sidecar-injection.html#automatic-sidecar-injection) - enabled, simply deploy the services using `kubectl`: + The `istioctl kube-inject` command is used to manually modify the `bookinfo.yaml` + file before creating the deployments as documented [here]({{home}}/docs/reference/commands/istioctl.html#istioctl kube-inject). - ```bash - kubectl apply -f samples/bookinfo/kube/bookinfo.yaml - ``` + * If you are using a cluster with + [automatic sidecar injection]({{home}}/docs/setup/kubernetes/sidecar-injection.html#automatic-sidecar-injection) + enabled, simply deploy the services using `kubectl` - The `istioctl kube-inject` command is used to manually modify the `bookinfo.yaml` - file before creating the deployments as documented [here]({{home}}/docs/reference/commands/istioctl.html#istioctl kube-inject). + ```bash + kubectl apply -f samples/bookinfo/kube/bookinfo.yaml + ``` - Either of the above commands launches all four microservices and creates the gateway - ingress resource as illustrated in the above diagram. + Either of the above commands launches all four microservices as illustrated in the above diagram. All 3 versions of the reviews service, v1, v2, and v3, are started. > In a realistic deployment, new versions of a microservice are deployed @@ -107,7 +106,7 @@ To start the application, follow the instructions below corresponding to your Is 1. Define the ingress gateway for the application: ```bash - kubectl apply -f samples/bookinfo/kube/bookinfo-gateway.yaml + istioctl create -f samples/bookinfo/routing/bookinfo-gateway.yaml ``` 1. Confirm all services and pods are correctly defined and running: @@ -116,7 +115,7 @@ To start the application, follow the instructions below corresponding to your Is kubectl get services ``` - which produces the following output: + which produces the following output ```bash NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE @@ -147,49 +146,46 @@ To start the application, follow the instructions below corresponding to your Is #### Determining the ingress IP and Port -1. If your Kubernetes cluster is running in an environment that supports external load balancers, the IP address of ingress can be obtained by the following command: +Execute the following command to determine if your Kubernetes cluster is running in an environment that supports external load balancers - ```bash - kubectl get ingress -o wide - ``` - - whose output should be similar to +```bash +kubectl get svc istio-ingressgateway -n istio-system +``` - ```bash - NAME HOSTS ADDRESS PORTS AGE - gateway * 130.211.10.121 80 1d - ``` +The output should be similar to - The address of the ingress service would then be +```bash +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +istio-ingressgateway LoadBalancer 172.21.109.129 130.211.10.121 80:31380/TCP,443:31390/TCP,31400:31400/TCP 17h +``` - ```bash - export GATEWAY_URL=130.211.10.121:80 - ``` +If the `EXTERNAL-IP` value is set, your environment has an external load balancer that you can use for the ingress gateway -1. _GKE:_ Sometimes when the service is unable to obtain an external IP, `kubectl get ingress -o wide` may display a list of worker node addresses. In this case, you can use any of the addresses, along with the NodePort, to access the ingress. If the cluster has a firewall, you will also need to create a firewall rule to allow TCP traffic to the NodePort. +```bash +export GATEWAY_URL=130.211.10.121:80 +``` - ```bash - export GATEWAY_URL=<workerNodeAddress>:$(kubectl get svc istio-ingress -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') - gcloud compute firewall-rules create allow-book --allow tcp:$(kubectl get svc istio-ingress -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') - ``` +If the `EXTERNAL-IP` value is `<none>` (or perpetually `<pending>`), your environment does not support external load balancers. +In this case, you can access the gateway using the service `nodePort`. -1. _IBM Cloud Container Service Free Tier:_ External load balancer is not available for kubernetes clusters in the free tier. You can use the public IP of the worker node, along with the NodePort, to access the ingress. The public IP of the worker node can be obtained from the output of the following command: +1. _GKE:_ ```bash - bx cs workers <cluster-name or id> - export GATEWAY_URL=<public IP of the worker node>:$(kubectl get svc istio-ingress -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') + export GATEWAY_URL=<workerNodeAddress>:$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') + gcloud compute firewall-rules create allow-book --allow tcp:$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') ``` -1. _IBM Cloud Private:_ External load balancers are not supported in IBM Cloud Private. You can use the host IP of the ingress service, along with the NodePort, to access the ingress. +1. _IBM Cloud Container Service Free Tier:_ ```bash - export GATEWAY_URL=$(kubectl get po -l istio=ingress -n istio-system -o 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc istio-ingress -n istio-system -o 'jsonpath={.spec.ports[0].nodePort}') + bx cs workers <cluster-name or id> + export GATEWAY_URL=<public IP of the worker node>:$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') ``` -1. _Minikube:_ External load balancers are not supported in Minikube. You can use the host IP of the ingress service, along with the NodePort, to access the ingress. +1. _Other environments (e.g., minikube):_ ```bash - export GATEWAY_URL=$(kubectl get po -l istio=ingress -n istio-system -o 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc istio-ingress -n istio-system -o 'jsonpath={.spec.ports[0].nodePort}') + export GATEWAY_URL=$(kubectl get po -l istio=ingressgateway -n istio-system -o 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc istio-ingressgateway -n istio-system -o 'jsonpath={.spec.ports[0].nodePort}') ``` ### Running on Docker with Consul or Eureka @@ -266,8 +262,8 @@ uninstall and clean it up using the following instructions. 1. Confirm shutdown ```bash - istioctl get routerules #-- there should be no more routing rules - kubectl get pods #-- the Bookinfo pods should be deleted + istioctl get virtualservices #-- there should be no more routing rules + kubectl get pods #-- the Bookinfo pods should be deleted ``` ### Uninstall from Docker environment @@ -289,6 +285,6 @@ uninstall and clean it up using the following instructions. 1. Confirm cleanup ```bash - istioctl get routerules #-- there should be no more routing rules - docker ps -a #-- the Bookinfo containers should be deleted + istioctl get virtualservices #-- there should be no more routing rules + docker ps -a #-- the Bookinfo containers should be deleted ``` diff --git a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md index 8cd80cf42973..a114fb058692 100644 --- a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md +++ b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md @@ -96,7 +96,7 @@ This command instructs the Istio proxy to forward requests on port 443 of any of 1. Remove the external service we created. ```bash - istioctl delete ServiceEntry wikipedia-ext + istioctl delete serviceentry wikipedia-ext ``` 1. Shutdown the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) application. @@ -107,6 +107,6 @@ This command instructs the Istio proxy to forward requests on port 443 of any of ## What's next -* The [External Services]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#ServiceEntry) reference. +* The [ServiceEntry]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#ServiceEntry) reference. * The [Control Egress Traffic]({{home}}/docs/tasks/traffic-management-v1alpha3/egress.html) task, for HTTP and HTTPS. diff --git a/_docs/tasks/traffic-management-v1alpha3/egress.md b/_docs/tasks/traffic-management-v1alpha3/egress.md index 0ee2fee512be..9b21877ff46e 100644 --- a/_docs/tasks/traffic-management-v1alpha3/egress.md +++ b/_docs/tasks/traffic-management-v1alpha3/egress.md @@ -76,7 +76,7 @@ from within your Istio cluster. In this task we will use metadata: name: google-ext spec: - name: www.google.com + host: www.google.com trafficPolicy: tls: mode: SIMPLE # initiates HTTPS when talking to www.google.com @@ -267,7 +267,7 @@ cloud provider specific knowledge and configuration. 1. Remove the rules. ```bash - istioctl delete ServiceEntry httpbin-ext google-ext + istioctl delete serviceentry httpbin-ext google-ext istioctl delete destinationrule google-ext istioctl delete virtualservice httpbin-ext ``` @@ -284,7 +284,7 @@ Note that Istio `ServiceEntry` is **not a security feature**. It enables access ## What's next -* Read more about [external services]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#ServiceEntry). +* Read more about [ServiceEntry]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#ServiceEntry). * Learn how to setup [timeouts]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#HTTPRoute.timeout), diff --git a/_docs/tasks/traffic-management-v1alpha3/ingress.md b/_docs/tasks/traffic-management-v1alpha3/ingress.md index 35f6fd55a29a..7f31a5454b73 100644 --- a/_docs/tasks/traffic-management-v1alpha3/ingress.md +++ b/_docs/tasks/traffic-management-v1alpha3/ingress.md @@ -53,8 +53,6 @@ This task describes how to configure Istio to expose a service outside of the se ## Configuring ingress using an Istio Gateway resource (recommended) -> This is still a work in progress and is not yet functional. - An [Istio Gateway]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#Gateway) is the preferred model for configuring ingress traffic in Istio. An ingress `Gateway` describes a load balancer operating at the edge of the mesh receiving incoming From d675860cd4a0241ef1128c566eddf94166ddf349 Mon Sep 17 00:00:00 2001 From: Frank Budinsky <frankb@ca.ibm.com> Date: Thu, 3 May 2018 10:22:10 -0400 Subject: [PATCH 165/191] Corrections and clarifications (#1238) --- _blog/2018/v1alpha3-routing.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/_blog/2018/v1alpha3-routing.md b/_blog/2018/v1alpha3-routing.md index 69c1da1539f3..98da618df864 100644 --- a/_blog/2018/v1alpha3-routing.md +++ b/_blog/2018/v1alpha3-routing.md @@ -350,11 +350,14 @@ spec: ``` That said, `ServiceEntry` has significantly more functionality than its predecessor. -First of all, `ServiceEntry` is not limited to external service configuration. -It can also be used to explicitly add services as part of expanding the service mesh to include unmanaged infrastructure -(e.g., VMs added to a Kubernetes-based service mesh). Such entries are treated just like all other internal services, -unlike external ones where Istio's mTLS authentication is disabled and policy enforcement is -performed on the client-side as opposed to server-side. +First of all, a `ServiceEntry` is not limited to external service configuration, +it can be of two types: mesh-internal or mesh-external. +Mesh-internal entries are like all other internal services but are used to explicitly add services +to the mesh. They can be used to add services as part of expanding the service mesh to include unmanaged infrastructure +(e.g., VMs added to a Kubernetes-based service mesh). +Mesh-external entries represent services external to the mesh. +For them, mTLS authentication is disabled and policy enforcement is performed on the client-side, +instead of on the usual server-side for internal service requests. Because a `ServiceEntry` configuration simply adds a destination to the internal service registry, it can be used in conjunction with a `VirtualService` and/or `DestinationRule`, just like any other service in the registry. @@ -380,7 +383,7 @@ including the following: 1. A single `ServiceEntry` can configure multiple service endpoints, which previously would have required multiple `EgressRules`. -1. The resolution mode for the endpoints is now configurable (`PASSTHROUGH`, `STATIC`, or `DNS`). +1. The resolution mode for the endpoints is now configurable (`NONE`, `STATIC`, or `DNS`). 1. Secure HTTP services (automatic TLS upgrade) can now be accessed using standard https (e.g., `https://secureservice.com/` instead of `http://secureservice.com:443/`. From 052242192b2cb31e83f43c2c56cbcdf82f2b4168 Mon Sep 17 00:00:00 2001 From: Frank Budinsky <frankb@ca.ibm.com> Date: Thu, 3 May 2018 14:24:08 -0400 Subject: [PATCH 166/191] clarify https external services support (#1239) * clarify https external services support * spelling error --- .spelling | 1 + _blog/2018/v1alpha3-routing.md | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.spelling b/.spelling index b294d814301a..69f937140d25 100644 --- a/.spelling +++ b/.spelling @@ -5,6 +5,7 @@ # where filename is relative to this configuration file 0.1.x 0.2.x +0.8.x 1.x 10s 123456789012.my diff --git a/_blog/2018/v1alpha3-routing.md b/_blog/2018/v1alpha3-routing.md index 98da618df864..7f3adc5ebaba 100644 --- a/_blog/2018/v1alpha3-routing.md +++ b/_blog/2018/v1alpha3-routing.md @@ -378,14 +378,15 @@ spec: caCertificates: /etc/certs/rootcacerts.pem ``` -In addition to its expanded generality, `ServiceEntry` includes several other improvements over `EgressRule` +In addition to its expanded generality, `ServiceEntry` provides several other improvements over `EgressRule` including the following: 1. A single `ServiceEntry` can configure multiple service endpoints, which previously would have required multiple `EgressRules`. 1. The resolution mode for the endpoints is now configurable (`NONE`, `STATIC`, or `DNS`). -1. Secure HTTP services (automatic TLS upgrade) can now be accessed using standard https (e.g., `https://secureservice.com/` - instead of `http://secureservice.com:443/`. +1. Additionally, we are working on addressing another pain point: the need to access secure external services over plain + text ports (e.g., `http://google.com:443`). This should be fixed in the coming weeks, allowing you to directly access + `https://google.com` from your application. Stay tuned for an Istio patch release (0.8.x) that addresses this limitation. ## Creating and deleting v1alpha3 route rules From 1d16d7424abef2a182229d902910453aa18586b5 Mon Sep 17 00:00:00 2001 From: Martin Taillefer <geeknoid@users.noreply.github.com> Date: Thu, 3 May 2018 22:43:54 -0700 Subject: [PATCH 167/191] Hopefully finally really fix the issues with the sidenav on small screens. (#1240) --- _sass/modules/_sidebar.scss | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/_sass/modules/_sidebar.scss b/_sass/modules/_sidebar.scss index 63e3f680c66d..6c664e257c19 100644 --- a/_sass/modules/_sidebar.scss +++ b/_sass/modules/_sidebar.scss @@ -1,28 +1,23 @@ @media screen { .row-offcanvas .sidebar-offcanvas { - transition: all .4s ease; - z-index: 42; - left: -1500px; - width: auto; - top: $headerHeight; - position: absolute; - } + @media (max-width: $bp-md - 1) { + position: absolute; + width: 80%; + transition: all .4s ease; + z-index: 42; + left: -$bp-md; + top: $headerHeight; + } - @media (max-width: calc($bp-md - 1)) { - .row-offcanvas .sidebar-offcanvas { - max-width: 80%; + @media (min-width: $bp-md) { + position: unset; + width: auto; } } .row-offcanvas.active .sidebar-offcanvas { left: 2rem; } - - @media (min-width: $bp-md) { - .row-offcanvas .sidebar-offcanvas { - position: unset; - } - } } .sidebar { From c89bfd333d2a6c90eae8833a070b123f6485c72c Mon Sep 17 00:00:00 2001 From: Jason Young <jasonyoung@google.com> Date: Fri, 4 May 2018 09:58:17 -0700 Subject: [PATCH 168/191] fix manual sidecar injection docs for helm template changes (#1211) Addresses https://github.com/istio/istio.github.io/issues/1210 --- _docs/setup/kubernetes/sidecar-injection.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index 874b76d7499d..da6eb394a987 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -84,11 +84,11 @@ $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) `kube-inject` can also be run without access to a running Kubernetes cluster. Create local copies of the injection and mesh configmap. -```command -$ kubectl create -f install/kubernetes/istio-sidecar-injector-configmap-release.yaml \ - --dry-run \ - -o=jsonpath='{.data.config}' > inject-config.yaml -$ kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml +```bash +istioctl kube-inject --emitTemplate > inject-config.yaml + +kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml + ``` Run `kube-inject` over the input file. From b966e8a0df8b2bcdc97f2ae2efd3a46582c9d40d Mon Sep 17 00:00:00 2001 From: Martin Taillefer <geeknoid@users.noreply.github.com> Date: Mon, 7 May 2018 14:43:23 -0700 Subject: [PATCH 169/191] Switch most uses of ```bash to ```command. (#1242) This takes advantage of the new rendering for command-lines and their outputs. --- _about/contribute/style-guide.md | 12 +- _about/contribute/writing-a-new-topic.md | 64 ++++++- _about/notes/index.md | 8 +- _blog/2017/0.1-canary.md | 16 +- _blog/2018/egress-https.md | 24 +-- _blog/2018/egress-tcp.md | 85 ++++----- _blog/2018/soft-multitenancy.md | 71 ++++--- _blog/2018/v1alpha3-routing.md | 8 +- .../concepts/policy-and-control/attributes.md | 2 +- .../traffic-management/rules-configuration.md | 2 +- _docs/guides/bookinfo.md | 112 +++++------ _docs/guides/endpoints.md | 23 +-- _docs/guides/integrating-vms.md | 55 +++--- _docs/setup/consul/install.md | 2 +- _docs/setup/consul/quick-start.md | 32 ++-- _docs/setup/eureka/quick-start.md | 28 +-- _docs/setup/kubernetes/ansible-install.md | 28 +-- _docs/setup/kubernetes/helm-install.md | 30 +-- _docs/setup/kubernetes/mesh-expansion.md | 136 ++++++------- .../setup/kubernetes/multicluster-install.md | 52 ++--- _docs/setup/kubernetes/quick-start-gke-dm.md | 61 +++--- _docs/setup/kubernetes/quick-start.md | 147 +++++++------- _docs/setup/kubernetes/sidecar-injection.md | 17 +- _docs/setup/kubernetes/upgrading-istio.md | 12 +- .../tasks/policy-enforcement/rate-limiting.md | 30 +-- _docs/tasks/security/authn-policy.md | 96 ++++------ _docs/tasks/security/basic-access-control.md | 47 ++--- _docs/tasks/security/health-check.md | 20 +- _docs/tasks/security/https-overlay.md | 134 +++++-------- _docs/tasks/security/mutual-tls.md | 45 ++--- _docs/tasks/security/per-service-mtls.md | 50 ++--- _docs/tasks/security/plugin-ca-cert.md | 56 +++--- .../security/role-based-access-control.md | 72 ++++--- _docs/tasks/security/secure-access-control.md | 21 +- _docs/tasks/telemetry/distributed-tracing.md | 24 +-- _docs/tasks/telemetry/fluentd.md | 35 ++-- _docs/tasks/telemetry/metrics-logs.md | 32 ++-- _docs/tasks/telemetry/querying-metrics.md | 21 +- _docs/tasks/telemetry/servicegraph.md | 25 +-- _docs/tasks/telemetry/tcp-metrics.md | 62 ++---- .../tasks/telemetry/using-istio-dashboard.md | 29 ++- .../circuit-breaking.md | 54 +++--- .../traffic-management-v1alpha3/egress-tcp.md | 30 ++- .../traffic-management-v1alpha3/egress.md | 86 ++++----- .../fault-injection.md | 32 ++-- .../traffic-management-v1alpha3/ingress.md | 168 ++++++---------- .../traffic-management-v1alpha3/mirroring.md | 52 ++--- .../request-routing.md | 25 +-- .../request-timeouts.md | 8 +- .../traffic-shifting.md | 22 +-- .../traffic-management/circuit-breaking.md | 64 +++---- _docs/tasks/traffic-management/egress-tcp.md | 31 ++- _docs/tasks/traffic-management/egress.md | 88 ++++----- .../traffic-management/fault-injection.md | 40 ++-- _docs/tasks/traffic-management/ingress.md | 180 +++++++----------- _docs/tasks/traffic-management/mirroring.md | 29 ++- .../traffic-management/request-routing.md | 26 ++- .../traffic-management/request-timeouts.md | 8 +- .../traffic-management/traffic-shifting.md | 26 ++- _faq/mixer/mixer-self-monitoring.md | 4 +- _faq/mixer/seeing-mixer-config.md | 51 ++--- _faq/security/accessing-control-services.md | 6 +- _faq/security/cert-lifetime-config.md | 4 +- _faq/security/enabling-disabling-mtls.md | 8 +- .../k8s-checking-cluster-alpha-features.md | 4 +- _help/troubleshooting.md | 114 +++++------ js/misc.js | 26 ++- js/misc.min.js | 2 +- 68 files changed, 1320 insertions(+), 1694 deletions(-) diff --git a/_about/contribute/style-guide.md b/_about/contribute/style-guide.md index 0af67773fec2..b84276974299 100644 --- a/_about/contribute/style-guide.md +++ b/_about/contribute/style-guide.md @@ -47,8 +47,8 @@ represents. 1. Display information about a pod: - ```bash - kubectl describe pod <pod-name> + ```command + $ kubectl describe pod <pod-name> ``` where `<pod-name>` is the name of one of your pods. @@ -122,12 +122,8 @@ except if a word is a proper noun or an acronym. Verify that the pod is running on your chosen node: -```bash -kubectl get pods --output=wide -``` -The output is similar to this: - -```xxx +```command +$ kubectl get pods --output=wide NAME READY STATUS RESTARTS AGE IP NODE nginx 1/1 Running 0 13s 10.200.0.4 worker0 ``` diff --git a/_about/contribute/writing-a-new-topic.md b/_about/contribute/writing-a-new-topic.md index 84cb438916c5..83d781347dc2 100644 --- a/_about/contribute/writing-a-new-topic.md +++ b/_about/contribute/writing-a-new-topic.md @@ -194,7 +194,7 @@ current hierarchy: You can embed blocks of preformatted content using the normal markdown technique: -<pre class="language-markdown"><code>``` +<pre class="language-markdown"><code>```plain func HelloWorld() { fmt.Println("Hello World") } @@ -203,14 +203,14 @@ func HelloWorld() { The above produces this kind of output: -```xxx +```plain func HelloWorld() { fmt.Println("Hello World") } ``` -In general, you should indicate the nature of the content in the preformatted block. You do this -by appending a name after the initial set of tick marks +You must indicate the nature of the content in the preformatted block by appending a name after the initial set of tick +marks: <pre class="language-markdown"><code>```go func HelloWorld() { @@ -228,7 +228,55 @@ func HelloWorld() { ``` You can use `markdown`, `yaml`, `json`, `java`, `javascript`, `c`, `cpp`, `csharp`, `go`, `html`, `protobuf`, -`perl`, `docker`, and `bash`. +`perl`, `docker`, and `bash`, along with `command` and its variants described below. + +### Showing commands and command output + +If you want to show one or more bash command-lines with some output, you use the `command` indicator: + +<pre class="language-markdown"><code>```command +$ echo "Hello" +Hello +``` +</code></pre> + +which produces: + +```command +$ echo "Hello" +Hello +``` + +You can have as many command-lines as you want, but only one chunk of output is recognized. + +<pre class="language-markdown"><code>```command +$ echo "Hello" >file.txt +$ cat file.txt +Hello +``` +</code></pre> + +which yields: + +```command +$ echo "Hello" >file.txt +$ cat file.txt +Hello +``` + +You can also use line continuation in your command-lines: + +```command +$ echo "Hello" \ + >file.txt +$ echo "There" >>file.txt +$ cat file.txt +Hello +There +``` + +If the output is the command is JSON or YAML, you can use `command-output-as-json` and `command-output-as-yaml` +instead of merely `command` in order to apply syntax coloring to the command's output. ## Displaying file content @@ -258,13 +306,13 @@ redirects to the site very easily. In the page that is the target of the redirect (where you'd like users to land), you simply add the following to the front-matter: -```xxx +```plain redirect_from: <url> ``` For example -```xxx +```plain --- title: Frequently Asked Questions description: Questions Asked Frequently @@ -281,7 +329,7 @@ to istio.io/help/faq as normal, as well as istio.io/faq. You can also add many redirects like so: -```xxx +```plain --- title: Frequently Asked Questions description: Questions Asked Frequently diff --git a/_about/notes/index.md b/_about/notes/index.md index 72ed6d3faa6c..9ee2f80c85a2 100644 --- a/_about/notes/index.md +++ b/_about/notes/index.md @@ -16,14 +16,14 @@ toc: false The latest Istio monthly release is {{site.data.istio.version}} ([release notes]({{site.data.istio.version}}.html)). You can [download {{site.data.istio.version}}](https://github.com/istio/istio/releases) with: -```bash -curl -L https://git.io/getLatestIstio | sh - +```command +$ curl -L https://git.io/getLatestIstio | sh - ``` The most recent stable release is 0.2.12. You can [download 0.2.12](https://github.com/istio/istio/releases/tag/0.2.12) with: -```bash -curl -L https://git.io/getIstio | sh - +```command +$ curl -L https://git.io/getIstio | sh - ``` [Archived documentation for the 0.2.12 release](https://archive.istio.io/v0.2/docs/). diff --git a/_blog/2017/0.1-canary.md b/_blog/2017/0.1-canary.md index ffd8364866f2..7b59504bae0e 100644 --- a/_blog/2017/0.1-canary.md +++ b/_blog/2017/0.1-canary.md @@ -88,7 +88,7 @@ rule to control the traffic distribution. For example if we want to send 10% of [istioctl]({{home}}/docs/reference/commands/istioctl.html) command to set a routing rule something like this: ```bash -$ cat <<EOF | istioctl create -f - +cat <<EOF | istioctl create -f - apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: @@ -112,11 +112,15 @@ After setting this rule, Istio will ensure that only one tenth of the requests w Because we don’t need to maintain replica ratios anymore, we can safely add Kubernetes [horizontal pod autoscalers](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) to manage the replicas for both version Deployments: -```bash +```command $ kubectl autoscale deployment helloworld-v1 --cpu-percent=50 --min=1 --max=10 deployment "helloworld-v1" autoscaled +``` +```command $ kubectl autoscale deployment helloworld-v2 --cpu-percent=50 --min=1 --max=10 deployment "helloworld-v2" autoscaled +``` +```command $ kubectl get hpa NAME REFERENCE TARGET CURRENT MINPODS MAXPODS AGE Helloworld-v1 Deployment/helloworld-v1 50% 47% 1 10 17s @@ -125,7 +129,7 @@ Helloworld-v2 Deployment/helloworld-v2 50% 40% 1 10 15s If we now generate some load on the **helloworld** service, we would notice that when scaling begins, the **v1** autoscaler will scale up its replicas significantly higher than the **v2** autoscaler will for its replicas because **v1** pods are handling 90% of the load. -```bash +```command $ kubectl get pods | grep helloworld helloworld-v1-3523621687-3q5wh 0/2 Pending 0 15m helloworld-v1-3523621687-73642 2/2 Running 0 11m @@ -141,7 +145,7 @@ helloworld-v2-4095161145-963wt 2/2 Running 0 50m If we then change the routing rule to send 50% of the traffic to **v2**, we should, after a short delay, notice that the **v1** autoscaler will scale down the replicas of **v1** while the **v2** autoscaler will perform a corresponding scale up. -```bash +```command $ kubectl get pods | grep helloworld helloworld-v1-3523621687-73642 2/2 Running 0 35m helloworld-v1-3523621687-7hs31 2/2 Running 0 43m @@ -159,7 +163,7 @@ helloworld-v2-4095161145-v3v9n 0/2 Pending 0 13m The end result is very similar to the simple Kubernetes Deployment rollout, only now the whole process is not being orchestrated and managed in one place. Instead, we’re seeing several components doing their jobs independently, albeit in a cause and effect manner. What's different, however, is that if we now stop generating load, the replicas of both versions will eventually scale down to their minimum (1), regardless of what routing rule we set. -```bash +```command $ kubectl get pods | grep helloworld helloworld-v1-3523621687-dt7n7 2/2 Running 0 1h helloworld-v2-4095161145-963wt 2/2 Running 0 1h @@ -170,7 +174,7 @@ helloworld-v2-4095161145-963wt 2/2 Running 0 1h As mentioned above, the Istio routing rules can be used to route traffic based on specific criteria, allowing more sophisticated canary deployment scenarios. Say, for example, instead of exposing the canary to an arbitrary percentage of users, we want to try it out on internal users, maybe even just a percentage of them. The following command could be used to send 50% of traffic from users at *some-company-name.com* to the canary version, leaving all other users unaffected: ```bash -$ cat <<EOF | istioctl create -f - +cat <<EOF | istioctl create -f - apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: diff --git a/_blog/2018/egress-https.md b/_blog/2018/egress-https.md index a022c5c927b0..f7b98b11c2c1 100644 --- a/_blog/2018/egress-https.md +++ b/_blog/2018/egress-https.md @@ -40,8 +40,8 @@ Here is a copy of the end-to-end architecture of the application from the origin Let's add a new version of the _details_ microservice, _v2_, that fetches the book details from [Google Books APIs](https://developers.google.com/books/docs/v1/getting_started). -```bash -kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-details-v2.yaml) +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-details-v2.yaml) ``` The updated architecture of the application now looks as follows: @@ -120,29 +120,21 @@ Now accessing the web page of the application displays the book details without Note that our egress rule allows traffic to any domain matching _*.googleapis.com_, on port 443, using the HTTPS protocol. Let's assume for the sake of the example that the applications in our Istio service mesh must access multiple subdomains of _googleapis.com_, for example _www.googleapis.com_ and also _fcm.googleapis.com_. Our rule allows traffic to both _www.googleapis.com_ and _fcm.googleapis.com_, since they both match _*.googleapis.com_. This **wildcard** feature allows us to enable traffic to multiple domains using a single egress rule. We can query our egress rules: -```bash -istioctl get egressrules -``` - -and see our new egress rule in the output: - -```bash +```command +$ istioctl get egressrules NAME KIND NAMESPACE googleapis EgressRule.v1alpha2.config.istio.io default ``` We can delete our egress rule: -```bash -istioctl delete egressrule googleapis -n default -``` - -and see in the output of _istioctl delete_ that the egress rule is deleted: - -```bash +```command +$ istioctl delete egressrule googleapis -n default Deleted config: egressrule googleapis ``` +and see in the output that the egress rule is deleted. + Accessing the web page after deleting the egress rule produces the same error that we experienced before, namely _Error fetching product details_. As we can see, the egress rules are defined **dynamically**, as many other Istio configuration artifacts. The Istio operators can decide dynamically which domains they allow the microservices to access. They can enable and disable traffic to the external domains on the fly, without redeploying the microservices. ## Issues with Istio egress traffic control diff --git a/_blog/2018/egress-tcp.md b/_blog/2018/egress-tcp.md index c4caac844366..b9524585acde 100644 --- a/_blog/2018/egress-tcp.md +++ b/_blog/2018/egress-tcp.md @@ -22,30 +22,30 @@ First, I set up a MySQL database instance to hold book ratings data, outside my For this task I set up an instance of [MySQL](https://www.mysql.com). You can use any MySQL instance; I use [Compose for MySQL](https://www.ibm.com/cloud/compose/mysql). I use `mysqlsh` ([MySQL Shell](https://dev.mysql.com/doc/refman/5.7/en/mysqlsh.html)) as a MySQL client to feed the ratings data. 1. To initialize the database, I run the following command entering the password when prompted. The command is performed with the credentials of the `admin` user, created by default by [Compose for MySQL](https://www.ibm.com/cloud/compose/mysql). - ```bash - curl -s https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/src/mysql/mysqldb-init.sql | + ```command + $ curl -s https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/src/mysql/mysqldb-init.sql | \ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host <the database host> --port <the database port> ``` _**OR**_ When using the `mysql` client and a local MySQL database, I would run: - ```bash - curl -s https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/src/mysql/mysqldb-init.sql | + ```command + $ curl -s https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/src/mysql/mysqldb-init.sql | \ mysql -u root -p ``` 1. I then create a user with the name _bookinfo_ and grant it _SELECT_ privilege on the `test.ratings` table: - ```bash - mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host <the database host> --port <the database port> \ + ```command + $ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host <the database host> --port <the database port> \ -e "CREATE USER 'bookinfo' IDENTIFIED BY '<password you choose>'; GRANT SELECT ON test.ratings to 'bookinfo';" ``` _**OR**_ For `mysql` and the local database, the command would be: - ```bash - mysql -u root -p -e \ + ```command + $ mysql -u root -p -e \ "CREATE USER 'bookinfo' IDENTIFIED BY '<password you choose>'; GRANT SELECT ON test.ratings to 'bookinfo';" ``` Here I apply the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege). This means that I do not use my _admin_ user in the Bookinfo application. Instead, I create a special user for the Bookinfo application , _bookinfo_, with minimal privileges. In this case, the _bookinfo_ user only has the `SELECT` privilege on a single table. @@ -53,11 +53,9 @@ For this task I set up an instance of [MySQL](https://www.mysql.com). You can us After running the command to create the user, I will clean my bash history by checking the number of the last command and running `history -d <the number of the command that created the user>`. I don't want the password of the new user to be stored in the bash history. If I'm using `mysql`, I'll remove the last command from `~/.mysql_history` file as well. Read more about password protection of the newly created user in [MySQL documentation](https://dev.mysql.com/doc/refman/5.5/en/create-user.html). 1. I inspect the created ratings to see that everything worked as expected: - ```bash - mysqlsh --sql --ssl-mode=REQUIRED -u bookinfo -p --host <the database host> --port <the database port> \ + ```command + $ mysqlsh --sql --ssl-mode=REQUIRED -u bookinfo -p --host <the database host> --port <the database port> \ -e "select * from test.ratings;" - ``` - ```bash Enter password: +----------+--------+ | ReviewID | Rating | @@ -70,10 +68,8 @@ For this task I set up an instance of [MySQL](https://www.mysql.com). You can us _**OR**_ For `mysql` and the local database: - ```bash - mysql -u bookinfo -p -e "select * from test.ratings;" - ``` - ```bash + ```command + $ mysql -u bookinfo -p -e "select * from test.ratings;" Enter password: +----------+--------+ | ReviewID | Rating | @@ -84,11 +80,9 @@ For this task I set up an instance of [MySQL](https://www.mysql.com). You can us ``` 1. I set the ratings temporarily to 1 to provide a visual clue when our database is used by the Bookinfo _ratings_ service: - ```bash - mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host <the database host> --port <the database port> \ + ```command + $ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host <the database host> --port <the database port> \ -e "update test.ratings set rating=1; select * from test.ratings;" - ``` - ```bash Enter password: +----------+--------+ | ReviewID | Rating | @@ -101,10 +95,8 @@ For this task I set up an instance of [MySQL](https://www.mysql.com). You can us _**OR**_ For `mysql` and the local database: - ```bash - mysql -u root -p -e "update test.ratings set rating=1; select * from test.ratings;" - ``` - ```bash + ```command + $ mysql -u root -p -e "update test.ratings set rating=1; select * from test.ratings;" Enter password: +----------+--------+ | ReviewID | Rating | @@ -151,20 +143,16 @@ As a reminder, here is the end-to-end architecture of the application from the [ 1. I apply the modified spec to deploy the version of the _ratings_ microservice, _v2-mysql_, that will use my database. - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-ratings-v2-mysql.yaml) - ``` - ```bash + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-ratings-v2-mysql.yaml) deployment "ratings-v2-mysql" created ``` 1. I route all the traffic destined to the _reviews_ service to its _v3_ version. I do this to ensure that the _reviews_ service always calls the _ratings_ service. In addition, I route all the traffic destined to the _ratings_ service to _ratings v2-mysql_ that uses my database. I add routing for both services above by adding two [route rules]({{home}}/docs/reference/config/istio.routing.v1alpha1.html). These rules are specified in `samples/bookinfo/kube/route-rule-ratings-mysql.yaml` of an Istio release archive. - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-ratings-mysql.yaml - ``` - ```bash + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-ratings-mysql.yaml Created config route-rule/default/ratings-test-v2-mysql at revision 1918799 Created config route-rule/default/reviews-test-ratings-v2 at revision 1918800 ``` @@ -217,11 +205,8 @@ spec: Then I run `istioctl` to add the egress rule to the service mesh: -```bash -istioctl create -f egress-rule-mysql.yaml -``` - -```bash +```command +$ istioctl create -f egress-rule-mysql.yaml Created config egress-rule/default/mysql at revision 1954425 ``` Note that for a TCP egress rule, we specify `tcp` as the protocol of a port of the rule. Also note that we use an IP of the external service instead of its domain name. I will talk more about TCP egress rules [below](#egress-rules-for-tcp-traffic). For now, let's verify that the egress rule we added fixed the problem. Let's access the webpage and see if the stars are back. @@ -285,38 +270,32 @@ with Istio. The Istio control plane does not have to be accessible from the mach ## Cleanup 1. Drop the _test_ database and the _bookinfo_ user: - ```bash - mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host <the database host> --port <the database port> \ + ```command + $ mysqlsh --sql --ssl-mode=REQUIRED -u admin -p --host <the database host> --port <the database port> \ -e "drop database test; drop user bookinfo;" ``` _**OR**_ For `mysql` and the local database: - ```bash - mysql -u root -p -e "drop database test; drop user bookinfo;" + ```command + $ mysql -u root -p -e "drop database test; drop user bookinfo;" ``` 1. Remove the route rules: - ```bash - istioctl delete -f samples/bookinfo/kube/route-rule-ratings-mysql.yaml - ``` - ```bash + ```command + $ istioctl delete -f samples/bookinfo/kube/route-rule-ratings-mysql.yaml Deleted config: route-rule/default/ratings-test-v2-mysql Deleted config: route-rule/default/reviews-test-ratings-v2 ``` 1. Undeploy _ratings v2-mysql_: - ```bash - kubectl delete -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-ratings-v2-mysql.yaml) - ``` - ```bash + ```command + $ kubectl delete -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-ratings-v2-mysql.yaml) deployment "ratings-v2-mysql" deleted ``` 1. Delete the egress rule: - ```bash - istioctl delete egressrule mysql -n default - ``` - ```bash + ```command + $ istioctl delete egressrule mysql -n default Deleted config: egressrule mysql ``` diff --git a/_blog/2018/soft-multitenancy.md b/_blog/2018/soft-multitenancy.md index 0c7e8ba0f86b..754ace010292 100644 --- a/_blog/2018/soft-multitenancy.md +++ b/_blog/2018/soft-multitenancy.md @@ -47,24 +47,23 @@ level Istio control planes are required; the first can use the istio.yaml defaul *istio-system* and a second control plane can be created by generating a new yaml file with a different namespace. As an example, the following command creates a yaml file with the Istio namespace of *istio-system1*. -```bash -cat istio.yaml | sed s/istio-system/istio-system1/g > istio-system1.yaml + +```command +$ cat istio.yaml | sed s/istio-system/istio-system1/g > istio-system1.yaml ``` The istio yaml file contains the details of the Istio control plane deployment, including the pods that make up the control plane (mixer, pilot, ingress, CA). Deploying the two Istio control plane yaml files: -```bash -kubectl apply -f install/kubernetes/istio.yaml -``` -```bash -kubectl apply -f install/kubernetes/istio-system1.yaml + +```command +$ kubectl apply -f install/kubernetes/istio.yaml +$ kubectl apply -f install/kubernetes/istio-system1.yaml ``` Results in two Istio control planes running in two namespaces. -```bash -kubectl get pods --all-namespaces -``` -```bash + +```command +$ kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE istio-system istio-ca-ffbb75c6f-98w6x 1/1 Running 0 15d istio-system istio-ingress-68d65fc5c6-dnvfl 1/1 Running 0 15d @@ -104,6 +103,7 @@ administrator would create a manifest containing, at a minimum, a `Role` and `Ro similar to the one below. In this example, a tenant administrator named *sales-admin* is limited to the namespace *istio-system1*. A completed manifest would contain many more `apiGroups` under the `Role` providing resource access to the tenant administrator. + ```yaml kind: Role apiVersion: rbac.authorization.k8s.io/v1 @@ -138,6 +138,7 @@ that Pilot should watch for creation of its xDS cache. This is done by starting component with the additional command line arguments `--appNamespace, ns-1`. Where *ns-1* is the namespace that the tenant’s application will be deployed in. An example snippet from the istio-system1.yaml file is included below. + ```yaml apiVersion: extensions/v1beta1 kind: Deployment @@ -207,20 +208,19 @@ the .yaml file for the resource scopes it properly instead. For example, the following command would be required to add a route rule to the *istio-system1* namespace: -```bash -istioctl –i istio-system1 create -n ns-1 -f route_rule_v2.yaml +```command +$ istioctl –i istio-system1 create -n ns-1 -f route_rule_v2.yaml ``` And can be displayed using the command: -```bash -istioctl -i istio-system1 -n ns-1 get routerule -``` -```bash +```command +$ istioctl -i istio-system1 -n ns-1 get routerule NAME KIND NAMESPACE details-Default RouteRule.v1alpha2.config.istio.io ns-1 productpage-default RouteRule.v1alpha2.config.istio.io ns-1 ratings-default RouteRule.v1alpha2.config.istio.io ns-1 reviews-default RouteRule.v1alpha2.config.istio.io ns-1 ``` + See the [Multiple Istio control planes]({{home}}/blog/2018/soft-multitenancy.html#multiple-istio-control-planes) section of this document for more details on `namespace` requirements in a multi-tenant environment. @@ -231,10 +231,9 @@ via RBAC and namespaces, what a tenant administrator can deploy. After deployment, accessing the Istio control plane pods assigned to a specific tenant administrator is permitted: -```bash -kubectl get pods -n istio-system -``` -```bash + +```command +$ kubectl get pods -n istio-system NAME READY STATUS RESTARTS AGE grafana-78d649479f-8pqk9 1/1 Running 0 1d istio-ca-ffbb75c6f-98w6x 1/1 Running 0 1d @@ -246,17 +245,16 @@ prometheus-cf8456855-hdcq7 1/1 Running 0 1d servicegraph-75ff8f7c95-wcjs7 1/1 Running 0 1d ``` However, accessing all the cluster's pods is not permitted: -```bash -kubectl get pods --all-namespaces -``` -```bash + +```command +$ kubectl get pods --all-namespaces Error from server (Forbidden): pods is forbidden: User "dev-admin" cannot list pods at the cluster scope ``` + And neither is accessing another tenant's namespace: -```bash -kubectl get pods -n istio-system1 -``` -```bash + +```command +$ kubectl get pods -n istio-system1 Error from server (Forbidden): pods is forbidden: User "dev-admin" cannot list pods in the namespace "istio-system1" ``` @@ -264,10 +262,9 @@ The tenant administrator can deploy applications in the application namespace co that tenant. As an example, updating the [Bookinfo]({{home}}/docs/guides/bookinfo.html) manifests and then deploying under the tenant's application namespace of *ns-0*, listing the pods in use by this tenant's namespace is permitted: -```bash -kubectl get pods -n ns-0 -``` -```bash + +```command +$ kubectl get pods -n ns-0 NAME READY STATUS RESTARTS AGE details-v1-64b86cd49-b7rkr 2/2 Running 0 1d productpage-v1-84f77f8747-rf2mt 2/2 Running 0 1d @@ -276,11 +273,11 @@ reviews-v1-ff6bdb95b-pm5lb 2/2 Running 0 1d reviews-v2-5799558d68-b989t 2/2 Running 0 1d reviews-v3-58ff7d665b-lw5j9 2/2 Running 0 1d ``` + But accessing another tenant's application namespace is not: -```bash -kubectl get pods -n ns-1 -``` -```bash + +```command +$ kubectl get pods -n ns-1 Error from server (Forbidden): pods is forbidden: User "dev-admin" cannot list pods in the namespace "ns-1" ``` diff --git a/_blog/2018/v1alpha3-routing.md b/_blog/2018/v1alpha3-routing.md index 7f3adc5ebaba..4699fc1e8906 100644 --- a/_blog/2018/v1alpha3-routing.md +++ b/_blog/2018/v1alpha3-routing.md @@ -396,12 +396,12 @@ is no longer done by creating a new (`RouteRule`) resource, but instead by updat resource for the destination. old routing rules: -```bash -istioctl create -f my-second-rule-for-destination-abc.yaml +```command +$ istioctl create -f my-second-rule-for-destination-abc.yaml ``` `v1alpha3` routing rules: -```bash -istioctl replace -f my-updated-rules-for-destination-abc.yaml +```command +$ istioctl replace -f my-updated-rules-for-destination-abc.yaml ``` Deleting route rules other than the last one for a particular destination is also done using `istioctl replace`. diff --git a/_docs/concepts/policy-and-control/attributes.md b/_docs/concepts/policy-and-control/attributes.md index 5ab5a8a07b89..c66c9e71a412 100644 --- a/_docs/concepts/policy-and-control/attributes.md +++ b/_docs/concepts/policy-and-control/attributes.md @@ -17,7 +17,7 @@ environment this traffic occurs in. An Istio attribute carries a specific piece of information such as the error code of an API request, the latency of an API request, or the original IP address of a TCP connection. For example: -```xxx +```plain request.path: xyz/abc request.size: 234 request.time: 12:34:56.789 04/17/2017 diff --git a/_docs/concepts/traffic-management/rules-configuration.md b/_docs/concepts/traffic-management/rules-configuration.md index 77f845da02e2..4dc57624fd62 100644 --- a/_docs/concepts/traffic-management/rules-configuration.md +++ b/_docs/concepts/traffic-management/rules-configuration.md @@ -74,7 +74,7 @@ domain name (FQDN). It is used by Istio Pilot for matching rules to services. Normally, the FQDN of the service is composed from three components: *name*, *namespace*, and *domain*: -```xxx +```plain FQDN = name + "." + namespace + "." + domain ``` diff --git a/_docs/guides/bookinfo.md b/_docs/guides/bookinfo.md index 613080a5efbc..3de2a3ae44e3 100644 --- a/_docs/guides/bookinfo.md +++ b/_docs/guides/bookinfo.md @@ -82,8 +82,8 @@ To start the application, follow the instructions below corresponding to your Is * If you are using [manual sidecar injection]({{home}}/docs/setup/kubernetes/sidecar-injection.html#manual-sidecar-injection), use the following command - ```bash - kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) + ```command + $ kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) ``` The `istioctl kube-inject` command is used to manually modify the `bookinfo.yaml` @@ -93,8 +93,8 @@ To start the application, follow the instructions below corresponding to your Is [automatic sidecar injection]({{home}}/docs/setup/kubernetes/sidecar-injection.html#automatic-sidecar-injection) enabled, simply deploy the services using `kubectl` - ```bash - kubectl apply -f samples/bookinfo/kube/bookinfo.yaml + ```command + $ kubectl apply -f samples/bookinfo/kube/bookinfo.yaml ``` Either of the above commands launches all four microservices as illustrated in the above diagram. @@ -105,19 +105,14 @@ To start the application, follow the instructions below corresponding to your Is 1. Define the ingress gateway for the application: - ```bash - istioctl create -f samples/bookinfo/routing/bookinfo-gateway.yaml + ```command + $ istioctl create -f samples/bookinfo/routing/bookinfo-gateway.yaml ``` 1. Confirm all services and pods are correctly defined and running: - ```bash - kubectl get services - ``` - - which produces the following output - - ```bash + ```command + $ kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE details 10.0.0.31 <none> 9080/TCP 6m kubernetes 10.0.0.1 <none> 443/TCP 7d @@ -128,13 +123,8 @@ To start the application, follow the instructions below corresponding to your Is and - ```bash - kubectl get pods - ``` - - which produces - - ```bash + ```command + $ kubectl get pods NAME READY STATUS RESTARTS AGE details-v1-1520924117-48z17 2/2 Running 0 6m productpage-v1-560495357-jk1lz 2/2 Running 0 6m @@ -148,21 +138,16 @@ To start the application, follow the instructions below corresponding to your Is Execute the following command to determine if your Kubernetes cluster is running in an environment that supports external load balancers -```bash -kubectl get svc istio-ingressgateway -n istio-system -``` - -The output should be similar to - -```bash +```command +$ kubectl get svc istio-ingressgateway -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 172.21.109.129 130.211.10.121 80:31380/TCP,443:31390/TCP,31400:31400/TCP 17h ``` If the `EXTERNAL-IP` value is set, your environment has an external load balancer that you can use for the ingress gateway -```bash -export GATEWAY_URL=130.211.10.121:80 +```command +$ export GATEWAY_URL=130.211.10.121:80 ``` If the `EXTERNAL-IP` value is `<none>` (or perpetually `<pending>`), your environment does not support external load balancers. @@ -170,22 +155,22 @@ In this case, you can access the gateway using the service `nodePort`. 1. _GKE:_ - ```bash - export GATEWAY_URL=<workerNodeAddress>:$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') - gcloud compute firewall-rules create allow-book --allow tcp:$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') + ```command + $ export GATEWAY_URL=<workerNodeAddress>:$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') + $ gcloud compute firewall-rules create allow-book --allow tcp:$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') ``` 1. _IBM Cloud Container Service Free Tier:_ - ```bash - bx cs workers <cluster-name or id> - export GATEWAY_URL=<public IP of the worker node>:$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') + ```command + $ bx cs workers <cluster-name or id> + $ export GATEWAY_URL=<public IP of the worker node>:$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') ``` 1. _Other environments (e.g., minikube):_ - ```bash - export GATEWAY_URL=$(kubectl get po -l istio=ingressgateway -n istio-system -o 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc istio-ingressgateway -n istio-system -o 'jsonpath={.spec.ports[0].nodePort}') + ```command + $ export GATEWAY_URL=$(kubectl get po -l istio=ingressgateway -n istio-system -o 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc istio-ingressgateway -n istio-system -o 'jsonpath={.spec.ports[0].nodePort}') ``` ### Running on Docker with Consul or Eureka @@ -196,41 +181,38 @@ In this case, you can access the gateway using the service `nodePort`. To test with Consul, run the following commands: - ```bash - docker-compose -f samples/bookinfo/consul/bookinfo.yaml up -d - docker-compose -f samples/bookinfo/consul/bookinfo.sidecars.yaml up -d - ``` + ```command + $ docker-compose -f samples/bookinfo/consul/bookinfo.yaml up -d + $ docker-compose -f samples/bookinfo/consul/bookinfo.sidecars.yaml up -d + ``` To test with Eureka, run the following commands: - ```bash - docker-compose -f samples/bookinfo/eureka/bookinfo.yaml up -d - docker-compose -f samples/bookinfo/eureka/bookinfo.sidecars.yaml up -d + ```command + $ docker-compose -f samples/bookinfo/eureka/bookinfo.yaml up -d + $ docker-compose -f samples/bookinfo/eureka/bookinfo.sidecars.yaml up -d ``` 1. Confirm that all docker containers are running: - ```bash - docker ps -a + ```command + $ docker ps -a ``` > If the Istio Pilot container terminates, re-run the command from the previous step. 1. Set the GATEWAY_URL: - ```bash - export GATEWAY_URL=localhost:9081 + ```command + $ export GATEWAY_URL=localhost:9081 ``` ## What's next To confirm that the Bookinfo application is running, run the following `curl` command: -```bash -curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage -``` - -```xxx +```command +$ curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage 200 ``` @@ -255,15 +237,15 @@ uninstall and clean it up using the following instructions. 1. Delete the routing rules and terminate the application pods - ```bash - samples/bookinfo/kube/cleanup.sh + ```command + $ samples/bookinfo/kube/cleanup.sh ``` 1. Confirm shutdown - ```bash - istioctl get virtualservices #-- there should be no more routing rules - kubectl get pods #-- the Bookinfo pods should be deleted + ```command + $ istioctl get virtualservices #-- there should be no more routing rules + $ kubectl get pods #-- the Bookinfo pods should be deleted ``` ### Uninstall from Docker environment @@ -272,19 +254,19 @@ uninstall and clean it up using the following instructions. In a Consul setup, run the following command: - ```bash - samples/bookinfo/consul/cleanup.sh + ```command + $ samples/bookinfo/consul/cleanup.sh ``` In a Eureka setup, run the following command: - ```bash - samples/bookinfo/eureka/cleanup.sh + ```command + $ samples/bookinfo/eureka/cleanup.sh ``` 1. Confirm cleanup - ```bash - istioctl get virtualservices #-- there should be no more routing rules - docker ps -a #-- the Bookinfo containers should be deleted + ```command + $ istioctl get virtualservices #-- there should be no more routing rules + $ docker ps -a #-- the Bookinfo containers should be deleted ``` diff --git a/_docs/guides/endpoints.md b/_docs/guides/endpoints.md index 84a41a22b7ab..4b5d95dad243 100644 --- a/_docs/guides/endpoints.md +++ b/_docs/guides/endpoints.md @@ -16,8 +16,9 @@ the [instructions](https://cloud.google.com/endpoints/docs/openapi/get-started-k to setup an Endpoints service on GKE. After setup, you should be able to get an API key and store it in `ENDPOINTS_KEY` environment variable and the external IP address `EXTERNAL_IP`. You may test the service using the following command: -```bash -curl --request POST --header "content-type:application/json" --data '{"message":"hello world"}' "http://${EXTERNAL_IP}:80/echo?key=${ENDPOINTS_KEY}" + +```command +$ curl --request POST --header "content-type:application/json" --data '{"message":"hello world"}' "http://${EXTERNAL_IP}:80/echo?key=${ENDPOINTS_KEY}" ``` You need to install Istio with [instructions]({{home}}/docs/setup/kubernetes/quick-start.html#google-kubernetes-engine). @@ -54,8 +55,8 @@ Otherwise, ESP won't be able to access Google cloud service control. 1. Get the Ingress IP through [instructions]({{home}}/docs/tasks/traffic-management/ingress.html#verifying-http-ingress). You can verify accessing the Endpoints service through Ingress: -```bash -curl --request POST --header "content-type:application/json" --data '{"message":"hello world"}' "http://${INGRESS_HOST}:80/echo?key=${ENDPOINTS_KEY}"i +```command +$ curl --request POST --header "content-type:application/json" --data '{"message":"hello world"}' "http://${INGRESS_HOST}:80/echo?key=${ENDPOINTS_KEY}"i ``` ## HTTPS Endpoints service using secured Ingress @@ -73,8 +74,8 @@ Adding `"--http_port=8081"` in the ESP deployment arguments and expose the HTTP Update the mesh service deployment. 1. Turn on mTLS in Istio by using the following command: -```bash -kubectl edit cm istio -n istio-system +```command +$ kubectl edit cm istio -n istio-system ``` And uncomment the line: ```yaml @@ -87,8 +88,8 @@ Accessing through Ingress works because Ingress does HTTP terminations. 1. To secure the access at Ingress, following the [instructions]({{home}}/docs/tasks/traffic-management/ingress.html#configuring-secure-ingress-https). 1. You can verify accessing the Endpoints service through secure Ingress: -```bash -curl --request POST --header "content-type:application/json" --data '{"message":"hello world"}' "https://${INGRESS_HOST}/echo?key=${ENDPOINTS_KEY}" -k +```command +$ curl --request POST --header "content-type:application/json" --data '{"message":"hello world"}' "https://${INGRESS_HOST}/echo?key=${ENDPOINTS_KEY}" -k ``` ## HTTPS Endpoints service using `LoadBalancer EXTERNAL_IP` @@ -106,10 +107,10 @@ Update the mesh service deployment. See further readings on port naming rules [here]({{home}}/docs/setup/kubernetes/sidecar-injection.html#pod-spec-requirements). 1. You can verify access to the Endpoints service through secure Ingress: -```bash -curl --request POST --header "content-type:application/json" --data '{"message":"hello world"}' "https://${EXTERNAL_IP}/echo?key=${ENDPOINTS_KEY}" -k +```command +$ curl --request POST --header "content-type:application/json" --data '{"message":"hello world"}' "https://${EXTERNAL_IP}/echo?key=${ENDPOINTS_KEY}" -k ``` -## What next? +## What's next Learn more about [GCP Endpoints](https://cloud.google.com/endpoints/docs/). diff --git a/_docs/guides/integrating-vms.md b/_docs/guides/integrating-vms.md index d8a812bc19e1..0e2729d3653c 100644 --- a/_docs/guides/integrating-vms.md +++ b/_docs/guides/integrating-vms.md @@ -39,37 +39,42 @@ We will first install MySQL on the VM, and configure it as a backend for the rat On the VM: -```bash -sudo apt-get update && sudo apt-get install -y mariadb-server -sudo mysql +```command +$ sudo apt-get update && sudo apt-get install -y mariadb-server +$ sudo mysql # Grant access to root GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; quit; -sudo systemctl restart mysql +``` + +```command +$ sudo systemctl restart mysql ``` You can find details of configuring MySQL at [Mysql](https://mariadb.com/kb/en/library/download/). On the VM add ratings database to mysql. -```bash -# Add ratings db to the MySQL db -curl -q https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/src/mysql/mysqldb-init.sql | mysql -u root -ppassword +```command +$ curl -q https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/src/mysql/mysqldb-init.sql | mysql -u root -ppassword ``` To make it easy to visually inspect the difference in the output of the Bookinfo application, you can change the ratings that are generated by using the -following commands +following commands to inspect the ratings: -```bash -# To inspect the ratings -mysql -u root -ppassword test -e "select * from ratings;" +```command +$ mysql -u root -ppassword test -e "select * from ratings;" +----------+--------+ | ReviewID | Rating | +----------+--------+ | 1 | 5 | | 2 | 4 | +----------+--------+ -# To change the ratings -mysql -u root -ppassword test -e "update ratings set rating=1 where reviewid=1;select * from ratings;" +``` + +and to change the ratings + +```command +$ mysql -u root -ppassword test -e "update ratings set rating=1 where reviewid=1;select * from ratings;" +----------+--------+ | ReviewID | Rating | +----------+--------+ @@ -81,18 +86,17 @@ mysql -u root -ppassword test -e "update ratings set rating=1 where reviewid=1; ## Find out the IP address of the VM that will be used to add it to the mesh On the VM: -```bash -hostname -I + +```command +$ hostname -I ``` ## Registering the mysql service with the mesh On a host with access to `istioctl` commands, register the VM and mysql db service -```bash -istioctl register -n vm mysqldb <ip-address-of-vm> 3306 -``` -Sample output: -```xxx + +```command +$ istioctl register -n vm mysqldb <ip-address-of-vm> 3306 I1108 20:17:54.256699 40419 register.go:43] Registering for service 'mysqldb' ip '10.150.0.5', ports list [{3306 mysql}] I1108 20:17:54.256815 40419 register.go:48] 0 labels ([]) and 1 annotations ([alpha.istio.io/kubernetes-serviceaccounts=default]) W1108 20:17:54.573068 40419 register.go:123] Got 'services "mysqldb" not found' looking up svc 'mysqldb' in namespace 'vm', attempting to create it @@ -107,12 +111,13 @@ Note that the 'mysqldb' virtual machine does not need and should not have specia The ratings service in bookinfo will use the DB on the machine. To verify that it works, create version 2 of the ratings service that uses the mysql db on the VM. Then specify route rules that force the review service to use the ratings version 2. -```bash -# Create the version of ratings service that will use mysql back end -istioctl kube-inject -n bookinfo -f samples/bookinfo/kube/bookinfo-ratings-v2-mysql-vm.yaml | kubectl apply -n bookinfo -f - +```command +$ istioctl kube-inject -n bookinfo -f samples/bookinfo/kube/bookinfo-ratings-v2-mysql-vm.yaml | kubectl apply -n bookinfo -f - +``` +Create route rules that will force bookinfo to use the ratings back end: -# Create route rules that will force bookinfo to use the ratings back end -istioctl create -n bookinfo -f samples/bookinfo/kube/route-rule-ratings-mysql-vm.yaml +```command +$ istioctl create -n bookinfo -f samples/bookinfo/kube/route-rule-ratings-mysql-vm.yaml ``` You can verify the output of the Bookinfo application is showing 1 star from Reviewer1 and 4 stars from Reviewer2 or change the ratings on your VM and see the diff --git a/_docs/setup/consul/install.md b/_docs/setup/consul/install.md index 4a9bdf7332c2..a7ecc987e19a 100644 --- a/_docs/setup/consul/install.md +++ b/_docs/setup/consul/install.md @@ -28,7 +28,7 @@ server requires an as a persistent store. Detailed instructions for setting up the API server can be found [here](https://kubernetes.io/docs/getting-started-guides/scratch/#apiserver-controller-manager-and-scheduler). -Documentation on set of startup options for the Kubernetes API server can be found [here](https://kubernetes.io/docs/admin/kube-apiserver/) +See the [documentation on the startup options for the Kubernetes API server](https://kubernetes.io/docs/admin/kube-apiserver/). #### Local Install diff --git a/_docs/setup/consul/quick-start.md b/_docs/setup/consul/quick-start.md index 43bb04e8c67b..adfbe2ec70de 100644 --- a/_docs/setup/consul/quick-start.md +++ b/_docs/setup/consul/quick-start.md @@ -21,8 +21,8 @@ Quick Start instructions to install and configure Istio in a Docker Compose setu installation file corresponding to your OS. If you are using a MacOS or Linux system, you can also run the following command to download and extract the latest release automatically: - ```bash - curl -L https://git.io/getLatestIstio | sh - + ```command + $ curl -L https://git.io/getLatestIstio | sh - ``` 1. Extract the installation file and change the directory to the file location. The @@ -35,36 +35,36 @@ installation directory contains: 1. Add the `istioctl` client to your PATH. For example, run the following command on a MacOS or Linux system: - ```bash - export PATH=$PWD/bin:$PATH + ```command + $ export PATH=$PWD/bin:$PATH ``` 1. For Linux users, configure the `DOCKER_GATEWAY` environment variable - ```bash - export DOCKER_GATEWAY=172.28.0.1: + ```command + $ export DOCKER_GATEWAY=172.28.0.1: ``` 1. Change directory to the root of the Istio installation directory. 1. Bring up the Istio control plane containers: - ```bash - docker-compose -f install/consul/istio.yaml up -d + ```command + $ docker-compose -f install/consul/istio.yaml up -d ``` 1. Confirm that all docker containers are running: - ```bash - docker ps -a + ```command + $ docker ps -a ``` > If the Istio Pilot container terminates, ensure that you run the `istioctl context-create` command and re-run the command from the previous step. 1. Configure `istioctl` to use mapped local port for the Istio API server: - ```bash - istioctl context-create --api-server http://localhost:8080 + ```command + $ istioctl context-create --api-server http://localhost:8080 ``` ## Deploy your application @@ -80,16 +80,16 @@ installation like [Bookinfo]({{home}}/docs/guides/bookinfo.html). > > The application must use HTTP/1.1 or HTTP/2.0 protocol for all its HTTP traffic because HTTP/1.0 is not supported. -```bash -docker-compose -f <your-app-spec>.yaml up -d +```command +$ docker-compose -f <your-app-spec>.yaml up -d ``` ## Uninstalling Uninstall Istio core components by removing the docker containers: -```bash -docker-compose -f install/consul/istio.yaml down +```command +$ docker-compose -f install/consul/istio.yaml down ``` ## What's next diff --git a/_docs/setup/eureka/quick-start.md b/_docs/setup/eureka/quick-start.md index c04214cfeedb..1b15ccf7fa4c 100644 --- a/_docs/setup/eureka/quick-start.md +++ b/_docs/setup/eureka/quick-start.md @@ -21,8 +21,8 @@ Quick Start instructions to install and configure Istio in a Docker Compose setu installation file corresponding to your OS. If you are using a MacOS or Linux system, you can also run the following command to download and extract the latest release automatically: - ```bash - curl -L https://git.io/getLatestIstio | sh - + ```command + $ curl -L https://git.io/getLatestIstio | sh - ``` 1. Extract the installation file and change the directory to the file location. The @@ -35,30 +35,30 @@ installation directory contains: 1. Add the `istioctl` client to your PATH. For example, run the following command on a MacOS or Linux system: - ```bash - export PATH=$PWD/bin:$PATH + ```command + $ export PATH=$PWD/bin:$PATH ``` 1. Change directory to the root of the Istio installation directory. 1. Bring up the Istio control plane containers: - ```bash - docker-compose -f install/eureka/istio.yaml up -d + ```command + $ docker-compose -f install/eureka/istio.yaml up -d ``` 1. Confirm that all docker containers are running: - ```bash - docker ps -a + ```command + $ docker ps -a ``` > If the Istio Pilot container terminates, ensure that you run the `istioctl context-create` command and re-run the command from the previous step. 1. Configure `istioctl` to use mapped local port for the Istio API server: - ```bash - istioctl context-create --context istio-local --api-server http://localhost:8080 + ```command + $ istioctl context-create --context istio-local --api-server http://localhost:8080 ``` ## Deploy your application @@ -74,16 +74,16 @@ installation like [Bookinfo]({{home}}/docs/guides/bookinfo.html). > > The application must use HTTP/1.1 or HTTP/2.0 protocol for all its HTTP traffic because HTTP/1.0 is not supported. -```bash -docker-compose -f <your-app-spec>.yaml up -d +```command +$ docker-compose -f <your-app-spec>.yaml up -d ``` ## Uninstalling Uninstall Istio core components by removing the docker containers: -```bash -docker-compose -f install/eureka/istio.yaml down +```command +$ docker-compose -f install/eureka/istio.yaml down ``` ## What's next diff --git a/_docs/setup/kubernetes/ansible-install.md b/_docs/setup/kubernetes/ansible-install.md index 92196dba0b2b..cc6c720c1490 100644 --- a/_docs/setup/kubernetes/ansible-install.md +++ b/_docs/setup/kubernetes/ansible-install.md @@ -28,8 +28,8 @@ The following prerequisites must be met if using OpenShift. This playbook will download and install Istio locally on your machine. To deploy the default settings of Istio on OpenShift, the following command may be used: -```bash -ansible-playbook main.yml +```command +$ ansible-playbook main.yml ``` ## Customization with Ansible @@ -55,8 +55,8 @@ The currently exposed options are: Operator installs Istio using all defaults on OpenShift: -```bash -ansible-playbook main.yml +```command +$ ansible-playbook main.yml ``` ## Operational overrides @@ -67,32 +67,32 @@ The following commands describe how an operator could use overrides with this An Operator installs Istio on Kubernetes: -```bash -ansible-playbook main.yml -e '{"cluster_flavour": "k8s"}' +```command +$ ansible-playbook main.yml -e '{"cluster_flavour": "k8s"}' ``` Operator installs Istio on Kubernetes and the path to `kubectl` is explicitly set: -```bash -ansible-playbook main.yml -e '{"cluster_flavour": "k8s", "cmd_path": "~/kubectl"}' +```command +$ ansible-playbook main.yml -e '{"cluster_flavour": "k8s", "cmd_path": "~/kubectl"}' ``` Operator installs Istio on OpenShift with settings other than the default: -```bash -ansible-playbook main.yml -e '{"istio": {"release_tag_name": "0.6.0", "auth": true, "delete_resources": true}}' +```command +$ ansible-playbook main.yml -e '{"istio": {"release_tag_name": "0.6.0", "auth": true, "delete_resources": true}}' ``` Operator installs Istio on OpenShift with customized addons: -```bash -ansible-playbook main.yml -e '{"istio": {"delete_resources": true, "addon": ["grafana", "prometheus", "jaeger"]}}' +```command +$ ansible-playbook main.yml -e '{"istio": {"delete_resources": true, "addon": ["grafana", "prometheus", "jaeger"]}}' ``` Operator installs Istio on OpenShift and additionally wants to deploy some of the samples: -```bash -ansible-playbook main.yml -e '{"istio": {"samples": ["helloworld", "bookinfo"]}}' +```command +$ ansible-playbook main.yml -e '{"istio": {"samples": ["helloworld", "bookinfo"]}}' ``` > When Jaeger is enabled, Zipkin is disabled even when Zipkin is selected in the addons. diff --git a/_docs/setup/kubernetes/helm-install.md b/_docs/setup/kubernetes/helm-install.md index 14df190fe08b..de8048d3f1c4 100644 --- a/_docs/setup/kubernetes/helm-install.md +++ b/_docs/setup/kubernetes/helm-install.md @@ -40,14 +40,14 @@ continuous integration automated testing and release process, the produced for Istio. 1. Create an `istio.yaml` Kubernetes manifest: - ```bash - helm template install/kubernetes/helm/istio --name istio --namespace istio-system --set prometheus.enabled=true > $HOME/istio.yaml + ```command + $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system --set prometheus.enabled=true > $HOME/istio.yaml ``` 1. Create the Istio control plane from `istio.yaml` manifest: - ```bash - kubectl create ns istio-system - kubectl create -f $HOME/istio.yaml + ```command + $ kubectl create ns istio-system + $ kubectl create -f $HOME/istio.yaml ``` ### Alternatively, use Helm and Tiller to manage the Istio deployment @@ -56,18 +56,18 @@ produced for Istio. Upgrading Istio using Helm is not validated. 1. If a service account has not already been installed for Helm, please install one: - ```bash - kubectl create -f install/kubernetes/helm/helm-service-account.yaml + ```command + $ kubectl create -f install/kubernetes/helm/helm-service-account.yaml ``` 1. Initialize Helm: - ```bash - helm init --service-account tiller + ```command + $ helm init --service-account tiller ``` 1. Create the Helm chart: - ```bash - helm install install/kubernetes/helm/istio --name istio --namespace istio-system + ```command + $ helm install install/kubernetes/helm/istio --name istio --namespace istio-system ``` ## Customization with Helm @@ -104,11 +104,11 @@ The per-service options are exposed via the ## Uninstall Istio * Uninstall using kubectl: -```bash -kubectl delete -f $HOME/istio.yaml +```command +$ kubectl delete -f $HOME/istio.yaml ``` * Uninstall using Helm: -```bash -helm delete --purge istio +```command +$ helm delete --purge istio ``` diff --git a/_docs/setup/kubernetes/mesh-expansion.md b/_docs/setup/kubernetes/mesh-expansion.md index 30ff4e543049..6c6a6729b607 100644 --- a/_docs/setup/kubernetes/mesh-expansion.md +++ b/_docs/setup/kubernetes/mesh-expansion.md @@ -40,43 +40,36 @@ You should customize it based on your provisioning tools and DNS requirements. * Setup Internal Load Balancers (ILBs) for Kube DNS, Pilot, Mixer and Citadel. This step is specific to each cloud provider, so you may need to edit annotations. - ```bash - kubectl apply -f install/kubernetes/mesh-expansion.yaml + ```command + $ kubectl apply -f install/kubernetes/mesh-expansion.yaml ``` * Generate the Istio 'cluster.env' configuration to be deployed in the VMs. This file contains the cluster IP address ranges to intercept. - ```bash - export GCP_OPTS="--zone MY_ZONE --project MY_PROJECT" - ``` - ```bash - install/tools/setupMeshEx.sh generateClusterEnv MY_CLUSTER_NAME + ```command + $ export GCP_OPTS="--zone MY_ZONE --project MY_PROJECT" + $ install/tools/setupMeshEx.sh generateClusterEnv MY_CLUSTER_NAME ``` Here's an example generated file - ```bash - cat cluster.env - ``` - ```xxx + ```command + $ cat cluster.env ISTIO_SERVICE_CIDR=10.63.240.0/20 ``` * Generate DNS configuration file to be used in the VMs. This will allow apps on the VM to resolve cluster service names, which will be intercepted by the sidecar and forwarded. - ```bash - # Make sure your kubectl context is set to your cluster - install/tools/setupMeshEx.sh generateDnsmasq + ```command + $ install/tools/setupMeshEx.sh generateDnsmasq ``` Here's an example generated file - ```bash - cat kubedns - ``` - ```xxx + ```command + $ cat kubedns server=/svc.cluster.local/10.150.0.7 address=/istio-mixer/10.150.0.8 address=/istio-pilot/10.150.0.6 @@ -91,23 +84,21 @@ cluster service names, which will be intercepted by the sidecar and forwarded. As an example, you can use the following "all inclusive" script to copy and install the setup: -```bash -# Check what the script does to see that it meets your needs. -export GCP_OPTS="--zone MY_ZONE --project MY_PROJECT" -# change to the namespace you wish to use for VMs but 'vm' is what the bookinfo guide assumes -export SERVICE_NAMESPACE=vm +```command +$ export GCP_OPTS="--zone MY_ZONE --project MY_PROJECT" +$ export SERVICE_NAMESPACE=vm ``` If you are running on a GCE VM, run -```bash -install/tools/setupMeshEx.sh gceMachineSetup VM_NAME +```command +$ install/tools/setupMeshEx.sh gceMachineSetup VM_NAME ``` Otherwise, run -```bash -install/tools/setupMeshEx.sh machineSetup VM_NAME +```command +$ install/tools/setupMeshEx.sh machineSetup VM_NAME ``` GCE provides better user experience since node agent can always relies on @@ -129,45 +120,44 @@ names and connect to pilot, for example: On the VM/external host: - ```bash - host istio-pilot.istio-system + ```command + $ host istio-pilot.istio-system ``` Example generated message: - ```xxx - # Verify you get the same address as shown as "EXTERNAL-IP" in 'kubectl get svc -n istio-system istio-pilot-ilb' - istio-pilot.istio-system has address 10.150.0.6 + ```plain + $ istio-pilot.istio-system has address 10.150.0.6 ``` Check that you can resolve cluster IPs. The actual address will depend on your deployment. - ```bash - host istio-pilot.istio-system.svc.cluster.local. + ```command + $ host istio-pilot.istio-system.svc.cluster.local. ``` Example generated message: - ```xxx + ```plain istio-pilot.istio-system.svc.cluster.local has address 10.63.247.248 ``` Check istio-ingress similarly: - ```bash - host istio-ingress.istio-system.svc.cluster.local. + ```command + $ host istio-ingress.istio-system.svc.cluster.local. ``` Example generated message: - ```xxx + ```plain istio-ingress.istio-system.svc.cluster.local has address 10.63.243.30 ``` * Verify connectivity by checking whether the VM can connect to Pilot and to an endpoint. - ```bash - curl 'http://istio-pilot.istio-system:8080/v1/registration/istio-pilot.istio-system.svc.cluster.local|http-discovery' + ```command + $ curl 'http://istio-pilot.istio-system:8080/v1/registration/istio-pilot.istio-system.svc.cluster.local|http-discovery' ``` ```json @@ -181,9 +171,10 @@ names and connect to pilot, for example: } ``` - ```bash - # On the VM, use the address above. It will directly connect to the pod running istio-pilot. - curl 'http://10.60.1.4:8080/v1/registration/istio-pilot.istio-system.svc.cluster.local|http-discovery' + On the VM, use the address above. It will directly connect to the pod running istio-pilot. + + ```command + $ curl 'http://10.60.1.4:8080/v1/registration/istio-pilot.istio-system.svc.cluster.local|http-discovery' ``` * Extract the initial Istio authentication secrets and copy them to the machine. The default @@ -194,11 +185,12 @@ is named as `istio.<serviceaccount>`). It is recommended that you perform this step to make it easy to enable mTLS in the future and to upgrade to a future version that will have mTLS enabled by default. - ```bash - # ACCOUNT defaults to 'default', or SERVICE_ACCOUNT environment variable - # NAMESPACE defaults to current namespace, or SERVICE_NAMESPACE environment variable - # (this step is done by machineSetup) - # On a mac either brew install base64 or set BASE64_DECODE="/usr/bin/base64 -D" + `ACCOUNT` defaults to 'default', or `SERVICE_ACCOUNT` environment variable + `NAMESPACE` defaults to current namespace, or `SERVICE_NAMESPACE` environment variable + (this step is done by machineSetup) + On a Mac either `brew install base64` or `set BASE64_DECODE="/usr/bin/base64 -D"` + + ```command install/tools/setupMeshEx.sh machineCerts ACCOUNT NAMESPACE ``` @@ -207,16 +199,12 @@ that will have mTLS enabled by default. * Install Istio Debian files and start 'istio' and 'istio-auth-node-agent' services. Get the debian packages from [GitHub releases](https://github.com/istio/istio/releases) or: - ```bash - # Note: This will be replaced with an 'apt-get' command once the repositories are setup. - - source istio.VERSION # defines version and URLs env var - curl -L ${PILOT_DEBIAN_URL}/istio-sidecar.deb > istio-sidecar.deb - - dpkg -i istio-sidecar.deb - - systemctl start istio - systemctl start istio-auth-node-agent + ```command + $ source istio.VERSION # defines version and URLs env var + $ curl -L ${PILOT_DEBIAN_URL}/istio-sidecar.deb > istio-sidecar.deb + $ dpkg -i istio-sidecar.deb + $ systemctl start istio + $ systemctl start istio-auth-node-agent ``` ------ Manual setup steps end ------ @@ -224,20 +212,17 @@ Get the debian packages from [GitHub releases](https://github.com/istio/istio/re After setup, the machine should be able to access services running in the Kubernetes cluster or other mesh expansion machines. -```bash -# Assuming you install bookinfo in 'bookinfo' namespace -curl productpage.bookinfo.svc.cluster.local:9080 +```command +$ curl productpage.bookinfo.svc.cluster.local:9080 ``` -```xxx +```plain ... html content ... ``` Check that the processes are running: -```bash -ps aux |grep istio -``` -```xxx +```command +$ ps aux |grep istio root 6941 0.0 0.2 75392 16820 ? Ssl 21:32 0:00 /usr/local/istio/bin/node_agent --logtostderr root 6955 0.0 0.0 49344 3048 ? Ss 21:32 0:00 su -s /bin/bash -c INSTANCE_IP=10.150.0.5 POD_NAME=demo-vm-1 POD_NAMESPACE=default exec /usr/local/bin/pilot-agent proxy > /var/log/istio/istio.log istio-proxy istio-p+ 7016 0.0 0.1 215172 12096 ? Ssl 21:32 0:00 /usr/local/bin/pilot-agent proxy @@ -246,10 +231,8 @@ istio-p+ 7094 4.0 0.3 69540 24800 ? Sl 21:32 0:37 /usr/local/bin/ Istio auth node agent is healthy: -```bash -sudo systemctl status istio-auth-node-agent -``` -```xxx +```command +$ sudo systemctl status istio-auth-node-agent ● istio-auth-node-agent.service - istio-auth-node-agent: The Istio auth node agent Loaded: loaded (/lib/systemd/system/istio-auth-node-agent.service; disabled; vendor preset: enabled) Active: active (running) since Fri 2017-10-13 21:32:29 UTC; 9s ago @@ -275,9 +258,9 @@ using the ISTIO_INBOUND_PORTS environment variable. Example (on the VM running the service): - ```bash - echo "ISTIO_INBOUND_PORTS=27017,3306,8080" > /var/lib/istio/envoy/sidecar.env - systemctl restart istio + ```command + $ echo "ISTIO_INBOUND_PORTS=27017,3306,8080" > /var/lib/istio/envoy/sidecar.env + $ systemctl restart istio ``` * Manually configure a selector-less service and endpoints. The 'selector-less' service is used for @@ -285,10 +268,9 @@ services that are not backed by Kubernetes pods. Example, on a machine with permissions to modify Kubernetes services: - ```bash - # istioctl register servicename machine-ip portname:port - istioctl -n onprem register mysql 1.2.3.4 3306 - istioctl -n onprem register svc1 1.2.3.4 http:7000 + ```command + $ istioctl -n onprem register mysql 1.2.3.4 3306 + $ istioctl -n onprem register svc1 1.2.3.4 http:7000 ``` After the setup, Kubernetes pods and other mesh expansions should be able to access the diff --git a/_docs/setup/kubernetes/multicluster-install.md b/_docs/setup/kubernetes/multicluster-install.md index 61fe504439eb..1067fb4dd6e8 100644 --- a/_docs/setup/kubernetes/multicluster-install.md +++ b/_docs/setup/kubernetes/multicluster-install.md @@ -86,8 +86,8 @@ istio-system. Create a namespace for instantiating the secrets: -```bash -kubectl create ns istio-system +```command +$ kubectl create ns istio-system ``` > Ordering currently matters. Secrets must be created prior to @@ -102,11 +102,11 @@ the remote nodes' credentials. Create a secret and label it properly for each remote cluster: -```bash -pushd $HOME/multicluster -kubectl create secret generic ${CLUSTER_NAME} --from-file ${CLUSTER_NAME} -n istio-system -kubectl label secret ${CLUSTER_NAME} istio/multiCluster=true -n istio-system -popd +```command +$ pushd $HOME/multicluster +$ kubectl create secret generic ${CLUSTER_NAME} --from-file ${CLUSTER_NAME} -n istio-system +$ kubectl label secret ${CLUSTER_NAME} istio/multiCluster=true -n istio-system +$ popd ``` ## Deploy the local Istio control plane @@ -133,24 +133,24 @@ to capture the Pilot, Policy, and Statsd Pod IP endpoints. variables to each node before using Helm to connect the remote cluster to the Istio control plane. -```bash -export PILOT_POD_IP=$(kubectl -n istio-system get pod -l istio=pilot -o jsonpath='{.items[0].status.podIP}') -export POLICY_POD_IP=$(kubectl -n istio-system get pod -l istio=mixer -o jsonpath='{.items[0].status.podIP}') -export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-bridge -o jsonpath='{.items[0].status.podIP}') +```command +$ export PILOT_POD_IP=$(kubectl -n istio-system get pod -l istio=pilot -o jsonpath='{.items[0].status.podIP}') +$ export POLICY_POD_IP=$(kubectl -n istio-system get pod -l istio=mixer -o jsonpath='{.items[0].status.podIP}') +$ export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-bridge -o jsonpath='{.items[0].status.podIP}') ``` ### Use kubectl with Helm to connect the remote cluster to the local 1. Use the helm template command on a remote to specify the Istio control plane service endpoints: - ```bash - helm template install/kubernetes/helm/istio-remote --name istio-remote --set global.pilotEndpoint=${PILOT_POD_IP} --set global.policyEndpoint=${POLICY_POD_IP} --set global.statsdEndpoint=${STATSD_POD_IP} > $HOME/istio-remote.yaml - ``` + ```command + $ helm template install/kubernetes/helm/istio-remote --name istio-remote --set global.pilotEndpoint=${PILOT_POD_IP} --set global.policyEndpoint=${POLICY_POD_IP} --set global.statsdEndpoint=${STATSD_POD_IP} > $HOME/istio-remote.yaml + ``` 1. Instantiate the remote cluster's connection to the Istio control plane: - ```bash - kubectl create -f $HOME/istio-remote.yaml + ```command + $ kubectl create -f $HOME/istio-remote.yaml ``` ### Alternatively use Helm and Tiller to connect the remote cluster to the local @@ -158,20 +158,20 @@ export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-brid 1. If a service account has not already been installed for Helm, please install one: - ```bash - kubectl create -f install/kubernetes/helm/helm-service-account.yaml + ```command + $ kubectl create -f install/kubernetes/helm/helm-service-account.yaml ``` 1. Initialize Helm: - ```bash - helm init --service-account tiller + ```command + $ helm init --service-account tiller ``` 1. Install the Helm chart: - ```bash - helm install install/kubernetes/helm/istio-remote --name istio-remote --set global.pilotEndpoint=${PILOT_POD_IP} --set global.policyEndpoint=${POLICY_POD_IP} --set global.statsdEndpoint=${STATSD_POD_IP} --namespace istio-system + ```command + $ helm install install/kubernetes/helm/istio-remote --name istio-remote --set global.pilotEndpoint=${PILOT_POD_IP} --set global.policyEndpoint=${POLICY_POD_IP} --set global.statsdEndpoint=${STATSD_POD_IP} --namespace istio-system ``` ### Helm configuration parameters @@ -195,12 +195,12 @@ The `isito-remote` Helm chart requires the three specific variables to be config ### Use kubectl to uninstall istio-remote -```bash -kubectl delete -f $HOME/istio-remote.yaml +```command +$ kubectl delete -f $HOME/istio-remote.yaml ``` ### Alternatively use Helm and Tiller to uninstall istio-remote -```bash -helm delete --purge istio-remote +```command +$ helm delete --purge istio-remote ``` diff --git a/_docs/setup/kubernetes/quick-start-gke-dm.md b/_docs/setup/kubernetes/quick-start-gke-dm.md index f4b323f1dc45..39fe76437fae 100644 --- a/_docs/setup/kubernetes/quick-start-gke-dm.md +++ b/_docs/setup/kubernetes/quick-start-gke-dm.md @@ -69,11 +69,8 @@ Once deployment is complete, do the following on the workstation where you've in 1. Bootstrap `kubectl` for the cluster you just created and confirm the cluster is running and Istio is enabled - ```bash - gcloud container clusters list - ``` - - ```xxx + ```command + $ gcloud container clusters list NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS istio-cluster us-central1-a v1.9.2-gke.1 130.211.216.64 n1-standard-2 v1.9.2-gke.1 3 RUNNING ``` @@ -82,19 +79,16 @@ running and Istio is enabled 1. Now acquire the credentials for this cluster - ```bash - gcloud container clusters get-credentials istio-cluster --zone=us-central1-a + ```command + $ gcloud container clusters get-credentials istio-cluster --zone=us-central1-a ``` ## Verify installation Verify Istio is installed in its own namespace -```bash -kubectl get deployments,ing -n istio-system -``` - -```xxx +```command +$kubectl get deployments,ing -n istio-system NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deploy/grafana 1 1 1 1 3m deploy/istio-citadel 1 1 1 1 3m @@ -109,11 +103,8 @@ deploy/zipkin 1 1 1 1 3m Now confirm that the Bookinfo sample application is also installed: -```bash -kubectl get deployments,ing -``` - -```xxx +```command +$ kubectl get deployments,ing NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deploy/details-v1 1 1 1 1 3m deploy/productpage-v1 1 1 1 1 3m @@ -141,11 +132,9 @@ You can also view the installation using the ***Kubernetes Engine -> Workloads** 1. Set up an environment variable for Bookinfo's external IP address: - ```bash - kubectl get ingress -o wide - ``` - ```bash - export GATEWAY_URL=35.202.120.89 + ```command + $ kubectl get ingress -o wide + $ export GATEWAY_URL=35.202.120.89 ``` 1. Verify you can access the Bookinfo ```http://${GATEWAY_URL}/productpage```: @@ -158,8 +147,8 @@ You can also view the installation using the ***Kubernetes Engine -> Workloads** %} 1. Now send some traffic to it: - ```bash - for i in {1..100}; do curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage; done + ```command + $ for i in {1..100}; do curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage; done ``` ## Verify installed Istio plugins @@ -172,11 +161,11 @@ If you are using Cloud Shell rather than the installed `gcloud` client, you can Set up a tunnel to Grafana: -```bash -kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000 & +```command +$ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000 & ``` then -```xxx +```plain http://localhost:3000/dashboard/db/istio-dashboard ``` You should see some statistics for the requests you sent earlier. @@ -194,13 +183,13 @@ For more details about using Grafana, see [About the Grafana Add-on]({{home}}/do Prometheus is installed with Grafana. You can view Istio and application metrics using the console as follows: -```bash -kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & +```command +$ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & ``` View the console at: -```xxx +```plain http://localhost:9090/graph ``` @@ -217,13 +206,13 @@ For more details, see [About the Prometheus Add-on]({{home}}/docs/tasks/telemetr Set up a tunnel to ServiceGraph: -```bash -kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=servicegraph -o jsonpath='{.items[0].metadata.name}') 8088:8088 & +```command +$ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=servicegraph -o jsonpath='{.items[0].metadata.name}') 8088:8088 & ``` You should see the Bookinfo service topology at -```xxx +```plain http://localhost:8088/dotviz ``` @@ -240,13 +229,13 @@ For more details, see [About the ServiceGraph Add-on]({{home}}/docs/tasks/teleme Set up a tunnel to Zipkin: -```bash -kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=zipkin -o jsonpath='{.items[0].metadata.name}') 9411:9411 & +```command +$ kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=zipkin -o jsonpath='{.items[0].metadata.name}') 9411:9411 & ``` You should see the trace statistics sent earlier: -```xxx +```plain http://localhost:9411 ``` diff --git a/_docs/setup/kubernetes/quick-start.md b/_docs/setup/kubernetes/quick-start.md index c211b17ecc6a..5997e91f6624 100644 --- a/_docs/setup/kubernetes/quick-start.md +++ b/_docs/setup/kubernetes/quick-start.md @@ -32,8 +32,8 @@ support). To install Istio locally, install the latest version of [Minikube](https://kubernetes.io/docs/getting-started-guides/minikube/) (version 0.25.0 or later). -```bash - minikube start \ +```command +$ minikube start \ --extra-config=controller-manager.ClusterSigningCertFile="/var/lib/localkube/certs/ca.crt" \ --extra-config=controller-manager.ClusterSigningKeyFile="/var/lib/localkube/certs/ca.key" \ --extra-config=apiserver.Admission.PluginNames=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota \ @@ -44,25 +44,25 @@ To install Istio locally, install the latest version of Create a new cluster. -```bash -gcloud container clusters create <cluster-name> \ - --cluster-version=1.9.4-gke.1 - --zone <zone> +```command +$ gcloud container clusters create <cluster-name> \ + --cluster-version=1.9.4-gke.1 \ + --zone <zone> \ --project <project-name> ``` Retrieve your credentials for `kubectl`. -```bash -gcloud container clusters get-credentials <cluster-name> \ +```command +$ gcloud container clusters get-credentials <cluster-name> \ --zone <zone> \ --project <project-name> ``` Grant cluster admin permissions to the current user (admin permissions are required to create the necessary RBAC rules for Istio). -```bash -kubectl create clusterrolebinding cluster-admin-binding \ +```command +$ kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole=cluster-admin \ --user=$(gcloud config get-value core/account) ``` @@ -73,14 +73,14 @@ Kubernetes 1.9 is generally available on IBM Cloud Container Service (IKS). At the time of writing it is not the default version, so to create a new lite cluster: -```bash -bx cs cluster-create --name <cluster-name> --kube-version 1.9.3 +```command +$ bx cs cluster-create --name <cluster-name> --kube-version 1.9.3 ``` Or create a new paid cluster: -```bash -bx cs cluster-create --location location --machine-type u2c.2x4 --name <cluster-name> --kube-version 1.9.3 +```command +$ bx cs cluster-create --location location --machine-type u2c.2x4 --name <cluster-name> --kube-version 1.9.3 ``` Retrieve your credentials for `kubectl` (replace `<cluster-name>` with the name of the cluster you want to use): @@ -98,15 +98,16 @@ Configure `kubectl` CLI based on steps [here](https://www.ibm.com/support/knowle OpenShift by default does not allow containers running with UID 0. Enable containers running with UID 0 for Istio's service accounts for ingress as well the Prometheus and Grafana addons: - ```bash - oc adm policy add-scc-to-user anyuid -z istio-ingress-service-account -n istio-system - oc adm policy add-scc-to-user anyuid -z grafana -n istio-system - oc adm policy add-scc-to-user anyuid -z prometheus -n istio-system - ``` +```command +$ oc adm policy add-scc-to-user anyuid -z istio-ingress-service-account -n istio-system +$ oc adm policy add-scc-to-user anyuid -z grafana -n istio-system +$ oc adm policy add-scc-to-user anyuid -z prometheus -n istio-system +``` + Service account that runs application pods need privileged security context constraints as part of sidecar injection. -```bash -oc adm policy add-scc-to-user privileged -z default -n <target-namespace> +```command +$ oc adm policy add-scc-to-user privileged -z default -n <target-namespace> ``` ### AWS (w/Kops) @@ -115,13 +116,13 @@ When you install a new cluster with Kubernetes version 1.9, prerequisite for `ad Nevertheless the list of admission controllers needs to be updated. -```bash -kops edit cluster $YOURCLUSTER +```command +$ kops edit cluster $YOURCLUSTER ``` Add following in the configuration file just opened: -```xxx +```yaml kubeAPIServer: admissionControl: - NamespaceLifecycle @@ -139,27 +140,27 @@ kubeAPIServer: Perform the update -```bash -kops update cluster -kops update cluster --yes +```command +$ kops update cluster +$ kops update cluster --yes ``` Launch the rolling update -```bash -kops rolling-update cluster -kops rolling-update cluster --yes +```command +$ kops rolling-update cluster +$ kops rolling-update cluster --yes ``` Validate with `kubectl` client on kube-api pod, you should see new admission controller: -```bash -for i in `kubectl get pods -nkube-system | grep api | awk '{print $1}'` ; do kubectl describe pods -nkube-system $i | grep "/usr/local/bin/kube-apiserver" ; done +```command +$ for i in `kubectl get pods -nkube-system | grep api | awk '{print $1}'` ; do kubectl describe pods -nkube-system $i | grep "/usr/local/bin/kube-apiserver" ; done ``` Output should be: -```xxx +```plain [...] --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,NodeRestriction,Priority [...] ``` @@ -167,8 +168,8 @@ Output should be: You need to use `ACS-Engine` to deploy you cluster. After following [these instructions](https://github.com/Azure/acs-engine/blob/master/docs/acsengine.md#install) to get and install the `acs-engine` binary, use the following command to download Istio `api model definition`: -```bash -wget https://raw.githubusercontent.com/Azure/acs-engine/master/examples/service-mesh/istio.json +```command +$ wget https://raw.githubusercontent.com/Azure/acs-engine/master/examples/service-mesh/istio.json ``` Use the following command to deploy your cluster using the `istio.json` template. You can find references to the parameters in the [official docs](https://github.com/Azure/acs-engine/blob/master/docs/kubernetes/deploy.md#step-3-edit-your-cluster-definition). @@ -179,27 +180,30 @@ Use the following command to deploy your cluster using the `istio.json` template | `dns_prefix` | Cluster DNS Prefix | | `location` | Cluster Location | -```bash -acs-engine deploy --subscription-id <subscription_id> --dns-prefix <dns_prefix> --location <location> --auto-suffix --api-model istio.json +```command +$ acs-engine deploy --subscription-id <subscription_id> --dns-prefix <dns_prefix> --location <location> --auto-suffix --api-model istio.json ``` After a few minutes you should find your cluster on your Azure subscription in a resource group called `<dns_prefix>-<id>`. Let's say my `dns-prefix` is `myclustername`, a valid resource group and unique cluster id would be `mycluster-5adfba82`. Using this `<dns_prefix>-<id>` cluster id you can copy your `kubeconfig` file to your machine from the `_output` folder generated by `acs-engine`: -```bash -cp _output/<dns_prefix>-<id>/kubeconfig/kubeconfig.<location>.json ~/.kube/config +```command +$ cp _output/<dns_prefix>-<id>/kubeconfig/kubeconfig.<location>.json ~/.kube/config ``` For example: -```bash -cp _output/mycluster-5adfba82/kubeconfig/kubeconfig.westus2.json ~/.kube/config + +```command +$ cp _output/mycluster-5adfba82/kubeconfig/kubeconfig.westus2.json ~/.kube/config ``` To check if the right Istio flags were deployed, use: -```bash -kubectl describe pod --namespace kube-system $(kubectl get pods --namespace kube-system | grep api | cut -d ' ' -f 1) | grep admission-control +```command +$ kubectl describe pod --namespace kube-system $(kubectl get pods --namespace kube-system | grep api | cut -d ' ' -f 1) | grep admission-control ``` + You should see `MutatingAdmissionWebhook` and `ValidatingAdmissionWebhook` flags: -```bash + +```plain --admission-control=...,MutatingAdmissionWebhook,...,ValidatingAdmissionWebhook,... ``` @@ -212,8 +216,8 @@ namespace, and can manage services from all other namespaces. installation file corresponding to your OS. If you are using a MacOS or Linux system, you can also run the following command to download and extract the latest release automatically: - ```bash - curl -L https://git.io/getLatestIstio | sh - + ```command + $ curl -L https://git.io/getLatestIstio | sh - ``` 1. Extract the installation file and change the directory to the file location. The @@ -225,15 +229,15 @@ installation directory contains: 1. Change directory to istio package. For example, if the package is istio-{{site.data.istio.version}} - ```bash - cd istio-{{site.data.istio.version}} + ```command + $ cd istio-{{site.data.istio.version}} ``` 1. Add the `istioctl` client to your PATH. For example, run the following command on a MacOS or Linux system: - ```bash - export PATH=$PWD/bin:$PATH + ```command + $ export PATH=$PWD/bin:$PATH ``` 1. Install Istio's core components. Choose one of the two _**mutually exclusive**_ options below or alternately install @@ -245,16 +249,16 @@ with the [Helm Chart]({{home}}/docs/setup/kubernetes/helm-install.html): applications that use [liveness and readiness probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/), headless services, or StatefulSets. - ```bash - kubectl apply -f install/kubernetes/istio.yaml + ```command + $ kubectl apply -f install/kubernetes/istio.yaml ``` _**OR**_ b) Install Istio and enable [mutual TLS authentication]({{home}}/docs/concepts/security/mutual-tls.html) between sidecars. This option is mostly for new clusters, i.e., all applications have sidecars injected during their deployment. For existing applications, please choose the above option and enable mutual TLS using [authentication policy]({{home}}/docs/tasks/security/authn-policy.html): - ```bash - kubectl apply -f install/kubernetes/istio-auth.yaml + ```command + $ kubectl apply -f install/kubernetes/istio-auth.yaml ``` Both options create the `istio-system` namespace along with the required RBAC permissions, @@ -268,10 +272,8 @@ install the [sidecar injector webhook]({{home}}/docs/setup/kubernetes/sidecar-in 1. Ensure the following Kubernetes services are deployed: `istio-pilot`, `istio-ingress`, `istio-policy`, `istio-telemetry`, `prometheus`. - ```bash - kubectl get svc -n istio-system - ``` - ```xxx + ```command + $ kubectl get svc -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE citadel-ilb LoadBalancer 10.35.251.104 10.138.0.43 8060:32031/TCP 47m istio-citadel ClusterIP 10.35.253.23 <none> 8060/TCP,9093/TCP 47m @@ -293,11 +295,8 @@ install the [sidecar injector webhook]({{home}}/docs/setup/kubernetes/sidecar-in `istio-pilot-*`, `istio-mixer-*`, `istio-ingress-*`, `istio-citadel-*`, and, optionally, `istio-sidecar-injector-*`. - ```bash - kubectl get pods -n istio-system - ``` - - ```xxx + ```command + $ kubectl get pods -n istio-system istio-citadel-b454d647d-92jrv 1/1 Running 0 46m istio-ingress-768b9fb68b-jdxfk 1/1 Running 0 46m istio-pilot-b87b8c56b-kggmk 2/2 Running 0 46m @@ -318,17 +317,17 @@ as shown above, you can deploy the application directly using `kubectl create`. The Istio-Sidecar-injector will automatically inject Envoy containers into your application pods assuming running in namespaces labeled with `istio-injection=enabled` -```bash -kubectl label namespace <namespace> istio-injection=enabled -kubectl create -n <namespace> -f <your-app-spec>.yaml +```command +$ kubectl label namespace <namespace> istio-injection=enabled +$ kubectl create -n <namespace> -f <your-app-spec>.yaml ``` If you do not have the Istio-sidecar-injector installed, you must use [istioctl kube-inject]({{home}}/docs/reference/commands/istioctl.html#istioctl kube-inject) to manually inject Envoy containers in your application pods before deploying them: -```bash -kubectl create -f <(istioctl kube-inject -f <your-app-spec>.yaml) +```command +$ kubectl create -f <(istioctl kube-inject -f <your-app-spec>.yaml) ``` ## Uninstalling @@ -337,8 +336,8 @@ kubectl create -f <(istioctl kube-inject -f <your-app-spec>.yaml) If you installed Istio with sidecar injector enabled, uninstall it: - ```bash - kubectl delete -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml + ```command + $ kubectl delete -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml ``` * Uninstall Istio core components. For the {{site.data.istio.version}} release, the uninstall @@ -347,16 +346,16 @@ It is safe to ignore errors for non-existent resources because they may have bee a) If you installed Istio with mutual TLS authentication disabled: - ```bash - kubectl delete -f install/kubernetes/istio.yaml + ```command + $ kubectl delete -f install/kubernetes/istio.yaml ``` _**OR**_ b) If you installed Istio with mutual TLS authentication enabled: - ```bash - kubectl delete -f install/kubernetes/istio-auth.yaml + ```command + $ kubectl delete -f install/kubernetes/istio-auth.yaml ``` ## What's next diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index da6eb394a987..0f199b5c1fd8 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -84,11 +84,9 @@ $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) `kube-inject` can also be run without access to a running Kubernetes cluster. Create local copies of the injection and mesh configmap. -```bash -istioctl kube-inject --emitTemplate > inject-config.yaml - -kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml - +```command +$ istioctl kube-inject --emitTemplate > inject-config.yaml +$ kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml ``` Run `kube-inject` over the input file. @@ -143,9 +141,6 @@ Alternatively, you can also use Helm to generate the yaml file and install it ma ```command $ helm template --namespace=istio-system --set sidecar-injector.enabled=true install/kubernetes/helm/istio > istio.yaml -``` - -```command $ kubectl apply -f istio.yaml ``` @@ -159,8 +154,6 @@ Deploy sleep app. Verify both deployment and pod have a single container. ```command $ kubectl apply -f samples/sleep/sleep.yaml -``` -```command $ kubectl get deployment -o wide NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR sleep 1 1 1 1 12m sleep tutum/curl app=sleep @@ -257,7 +250,7 @@ The sidecar injection template uses [https://golang.org/pkg/text/template](https when parsed and executed, is decoded to the following struct containing the list of containers and volumes to inject into the pod. -```golang +```go type SidecarInjectionSpec struct { InitContainers []v1.Container `yaml:"initContainers"` Containers []v1.Container `yaml:"containers"` @@ -267,7 +260,7 @@ type SidecarInjectionSpec struct { The template is applied to the following data structure at runtime. -```golang +```go type SidecarTemplateData struct { ObjectMeta *metav1.ObjectMeta Spec *v1.PodSpec diff --git a/_docs/setup/kubernetes/upgrading-istio.md b/_docs/setup/kubernetes/upgrading-istio.md index 636519865ba4..6cd1ea9ff1a0 100644 --- a/_docs/setup/kubernetes/upgrading-istio.md +++ b/_docs/setup/kubernetes/upgrading-istio.md @@ -31,8 +31,8 @@ Sidecar injector. We can use Kubernetes’ rolling update mechanism to upgrade t control plane components. It can be done by simply applying the new version yaml file directly, e.g. -```bash -kubectl apply -f istio.yaml (or istio-auth.yaml) +```command +$ kubectl apply -f istio.yaml (or istio-auth.yaml) ``` > If you have used [Helm](https://istio.io/docs/setup/kubernetes/helm.html) @@ -53,16 +53,16 @@ of sidecar proxy. There are two cases: Manual injection and Automatic injection. If automatic sidecar injection is not enabled, you can upgrade the sidecar manually by running the following command: - ```bash - kubectl apply -f <(istioctl kube-inject -i $ISTIO_NAMESPACE -f $ORIGINAL_DEPLOYMENT_YAML) + ```command + $ kubectl apply -f <(istioctl kube-inject -i $ISTIO_NAMESPACE -f $ORIGINAL_DEPLOYMENT_YAML) ``` If the sidecar was previously injected with some customized inject config files, you will need to change the version tag in the config files to the new version and reinject the sidecar as follows: - ```bash - kubectl apply -f <(istioctl kube-inject \ + ```command + $ kubectl apply -f <(istioctl kube-inject \ --injectConfigFile inject-config.yaml \ --filename $ORIGINAL_DEPLOYMENT_YAML) ``` diff --git a/_docs/tasks/policy-enforcement/rate-limiting.md b/_docs/tasks/policy-enforcement/rate-limiting.md index a70b8c917a38..bc3c797c967a 100644 --- a/_docs/tasks/policy-enforcement/rate-limiting.md +++ b/_docs/tasks/policy-enforcement/rate-limiting.md @@ -20,9 +20,9 @@ This task shows you how to use Istio to dynamically limit the traffic to a servi * Initialize the application version routing to direct `reviews` service requests from test user "jason" to version v2 and requests from any other user to v3. - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml - istioctl create -f samples/bookinfo/kube/route-rule-reviews-v3.yaml + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml + $ istioctl create -f samples/bookinfo/kube/route-rule-reviews-v3.yaml ``` > If you have conflicting rule that you set in previous tasks, @@ -74,8 +74,8 @@ Using Istio we can ensure that `1qps` is not breached. and then run the following command: - ```bash - istioctl create -f ratelimit-handler.yaml + ```command + $ istioctl create -f ratelimit-handler.yaml ``` This configuration specifies a default 5000 qps rate limit. Traffic reaching the ratings service via @@ -114,14 +114,14 @@ Using Istio we can ensure that `1qps` is not breached. Save the configuration as `ratelimit-rule.yaml` and run the following command: - ```bash - istioctl create -f ratelimit-rule.yaml + ```command + $ istioctl create -f ratelimit-rule.yaml ``` 1. Generate load on the `productpage` with the following command: - ```bash - while true; do curl -s -o /dev/null http://$GATEWAY_URL/productpage; done + ```command + $ while true; do curl -s -o /dev/null http://$GATEWAY_URL/productpage; done ``` 1. Refresh the `productpage` in your browser. @@ -178,16 +178,16 @@ If you would like the above policies enforced for a given namespace instead of t * Remove the rate limit configuration: - ```bash - istioctl delete -f ratelimit-handler.yaml - istioctl delete -f ratelimit-rule.yaml + ```command + $ istioctl delete -f ratelimit-handler.yaml + $ istioctl delete -f ratelimit-rule.yaml ``` * Remove the application routing rules: - ```bash - istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml - istioctl delete -f samples/bookinfo/kube/route-rule-reviews-v3.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml + $ istioctl delete -f samples/bookinfo/kube/route-rule-reviews-v3.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/security/authn-policy.md b/_docs/tasks/security/authn-policy.md index 5249d1492e17..01d442ef7ccc 100644 --- a/_docs/tasks/security/authn-policy.md +++ b/_docs/tasks/security/authn-policy.md @@ -23,35 +23,30 @@ Through this task, you will learn how to: * For demo, create two namespaces `foo` and `bar`, and deploy [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) and [sleep](https://github.com/istio/istio/tree/master/samples/sleep) with sidecar on both of them. Also, run another sleep app without sidecar (to keep it separate, run it in `legacy` namespace) - ```bash - kubectl create ns foo - kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo - kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo - kubectl create ns bar - kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n bar - kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n bar - kubectl create ns legacy - kubectl apply -f samples/sleep/sleep.yaml -n legacy + ```command + $ kubectl create ns foo + $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo + $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo + $ kubectl create ns bar + $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n bar + $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n bar + $ kubectl create ns legacy + $ kubectl apply -f samples/sleep/sleep.yaml -n legacy ``` * Verifying setup by sending an http request (using curl command) from any sleep pod (among those in namespace `foo`, `bar` or `legacy`) to either `httpbin.foo` or `httpbin.bar`. All requests should success with HTTP code 200. For example, here is a command to check `sleep.bar` to `httpbin.foo` reachability: - ```bash - kubectl exec $(kubectl get pod -l app=sleep -n bar -o jsonpath={.items..metadata.name}) -c sleep -n bar -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n" - ``` - ``` + ```command + $ kubectl exec $(kubectl get pod -l app=sleep -n bar -o jsonpath={.items..metadata.name}) -c sleep -n bar -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n" 200 ``` Conveniently, this one-liner command iterates through all combinations: - ```bash - for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done - ``` - - ``` + ```command + $ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done sleep.foo to httpbin.foo: 200 sleep.foo to httpbin.bar: 200 sleep.bar to httpbin.foo: 200 @@ -62,12 +57,9 @@ Through this task, you will learn how to: * Also verify that there are no authentication policy in the system - ```bash - kubectl get policies.authentication.istio.io -n foo - kubectl get policies.authentication.istio.io -n bar - ``` - - ```xxx + ```command + $ kubectl get policies.authentication.istio.io -n foo + $ kubectl get policies.authentication.istio.io -n bar No resources found. ``` @@ -89,22 +81,16 @@ EOF ``` And verify the policy was added: -```bash -kubectl get policies.authentication.istio.io -n foo -``` - -```xxx +```command +$ kubectl get policies.authentication.istio.io -n foo NAME AGE enable-mtls 1m ``` Run the same testing command above. We should see request from `sleep.legacy` to `httpbin.foo` start to fail, as the result of enabling mTLS for `httpbin.foo` but `sleep.legacy` doesn't have sidecar to support it. On the other hand, for clients with sidecar (`sleep.foo` and `sleep.bar`), Istio automatically configures them to using mTLS where talking to `http.foo`, so they continue to work. Also, requests to `httpbin.bar` are not affected as the policy is effective on the `foo` namespace only. -```bash -for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done -``` - -```xxx +```command +$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done sleep.foo to httpbin.foo: 200 sleep.foo to httpbin.bar: 200 sleep.bar to httpbin.foo: 200 @@ -134,7 +120,7 @@ EOF Again, run the probing command. As expected, request from `sleep.legacy` to `httpbin.bar` starts failing with the same reasons. -```xxx +```plain ... sleep.legacy to httpbin.bar: 000 command terminated with exit code 56 @@ -160,11 +146,8 @@ EOF This new policy will apply only to the `httpbin` service on port `1234`. As a result, mTLS is disabled (again) on port `8000` and requests from `sleep.legacy` will resume working. -```bash -kubectl exec $(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name}) -c sleep -n legacy -- curl http://httpbin.bar:8000/ip -s -o /dev/null -w "%{http_code}\n" -``` - -```xxx +```command +$ kubectl exec $(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name}) -c sleep -n legacy -- curl http://httpbin.bar:8000/ip -s -o /dev/null -w "%{http_code}\n" 200 ``` @@ -186,11 +169,8 @@ EOF Re-run the request from `sleep.legacy`, we should see a success return code again (200), confirming service-level policy overrules the namespace-level policy. -```bash -kubectl exec $(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name}) -c sleep -n legacy -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n" -``` - -```xxx +```command +$ kubectl exec $(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name}) -c sleep -n legacy -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n" 200 ``` @@ -198,9 +178,9 @@ kubectl exec $(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metad You will need a valid JWT (corresponding to the JWKS endpoint you want to use for the demo). Please follow the instructions [here](https://github.com/istio/istio/tree/master/security/tools/jwt) to create one. You can also use your own JWT/JWKS endpoint for the demo. Once you have that, export to some environment variables. -```bash -export JWKS=https://www.googleapis.com/service_accounts/v1/jwk/<YOUR-SVC-ACCOUNT> -export TOKEN=<YOUR-TOKEN> +```command +$ export JWKS=https://www.googleapis.com/service_accounts/v1/jwk/<YOUR-SVC-ACCOUNT> +$ export TOKEN=<YOUR-TOKEN> ``` Also, for convenience, expose `httpbin.foo` via ingress (for more details, see [ingress task]({{home}}/docs/tasks/traffic-management/ingress.html)). @@ -226,16 +206,13 @@ EOF ``` Get ingress IP -```bash +```command export INGRESS_HOST=$(kubectl get ing -n foo -o=jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}') ``` And run a test query -```bash -curl $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" -``` - -```json +```command-output-as-json +$ curl $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" { "headers": { "Accept": "*/*", @@ -274,16 +251,15 @@ EOF ``` The same curl command from before will return with 401 error code, as a result of server is expecting JWT but none was provided: -```bash -curl $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" -``` -``` +```command +$ curl $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" 401 ``` Attaching the valid token generated above returns success: -```bash -curl --header "Authorization: Bearer $TOKEN" $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" + +```command +$ curl --header "Authorization: Bearer $TOKEN" $INGRESS_HOST/headers -s -o /dev/null -w "%{http_code}\n" ``` You may want to try to modify token or policy (e.g change issuer, audiences, expiry date etc) to observe other aspects of JWT validation. diff --git a/_docs/tasks/security/basic-access-control.md b/_docs/tasks/security/basic-access-control.md index 2075ae1e8d25..c633c81a61e0 100644 --- a/_docs/tasks/security/basic-access-control.md +++ b/_docs/tasks/security/basic-access-control.md @@ -19,9 +19,9 @@ This task shows how to control access to a service using the Kubernetes labels. * Initialize the application version routing to direct `reviews` service requests from test user "jason" to version v2 and requests from any other user to v3. - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml - istioctl create -f samples/bookinfo/kube/route-rule-reviews-v3.yaml + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml + $ istioctl create -f samples/bookinfo/kube/route-rule-reviews-v3.yaml ``` > If you have conflicting rules that you set in previous tasks, @@ -50,13 +50,8 @@ of the `reviews` service. We would like to cut off access to version `v3` of the Run the following command to set up the deny rule along with a handler and an instance. - ```bash - istioctl create -f samples/bookinfo/kube/mixer-rule-deny-label.yaml - ``` - - You can expect to see the output similar to the following: - - ```bash + ```command + $ istioctl create -f samples/bookinfo/kube/mixer-rule-deny-label.yaml Created config denier/default/denyreviewsv3handler at revision 2882105 Created config checknothing/default/denyreviewsv3request at revision 2882106 Created config rule/default/denyreviewsv3 at revision 2882107 @@ -64,7 +59,7 @@ of the `reviews` service. We would like to cut off access to version `v3` of the Notice the following in the `denyreviewsv3` rule: - ```xxx + ```plain match: destination.labels["app"] == "ratings" && source.labels["app"]=="reviews" && source.labels["version"] == "v3" ``` @@ -89,8 +84,8 @@ Istio also supports attribute-based whitelists and blacklists. The following whi 1. Remove the denier configuration that you added in the previous section. - ```bash - istioctl delete -f samples/bookinfo/kube/mixer-rule-deny-label.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/mixer-rule-deny-label.yaml ``` 1. Verify that when you access the Bookinfo `productpage` (http://$GATEWAY_URL/productpage) without logging in, you see red stars. @@ -114,8 +109,8 @@ Istio also supports attribute-based whitelists and blacklists. The following whi and then run the following command: - ```bash - istioctl create -f whitelist-handler.yaml + ```command + $ istioctl create -f whitelist-handler.yaml ``` 1. Extract the version label by creating an instance of the [`listentry`]({{home}}/docs/reference/config/template/listentry.html) template. @@ -132,8 +127,8 @@ Save the following YAML snippet as `appversion-instance.yaml`: and then run the following command: - ```bash - istioctl create -f appversion-instance.yaml + ```command + $ istioctl create -f appversion-instance.yaml ``` 1. Enable `whitelist` checking for the ratings service. @@ -154,8 +149,8 @@ Save the following YAML snippet as `checkversion-rule.yaml`: and then run the following command: - ```bash - istioctl create -f checkversion-rule.yaml + ```command + $ istioctl create -f checkversion-rule.yaml ``` 1. Verify that when you access the Bookinfo `productpage` (http://$GATEWAY_URL/productpage) without logging in, you see **no** stars. @@ -165,17 +160,17 @@ Verify that after logging in as "jason" you see black stars. * Remove the mixer configuration: - ```bash - istioctl delete -f checkversion-rule.yaml - istioctl delete -f appversion-instance.yaml - istioctl delete -f whitelist-handler.yaml + ```command + $ istioctl delete -f checkversion-rule.yaml + $ istioctl delete -f appversion-instance.yaml + $ istioctl delete -f whitelist-handler.yaml ``` * Remove the application routing rules: - ```bash - istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml - istioctl delete -f samples/bookinfo/kube/route-rule-reviews-v3.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml + $ istioctl delete -f samples/bookinfo/kube/route-rule-reviews-v3.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/security/health-check.md b/_docs/tasks/security/health-check.md index e36d1c4c5efc..0d71b86bcc31 100644 --- a/_docs/tasks/security/health-check.md +++ b/_docs/tasks/security/health-check.md @@ -37,8 +37,8 @@ this feature is not needed if the production setup is not using the Deploy Citadel with health checking enabled. -```bash -kubectl apply -f install/kubernetes/istio-citadel-with-health-check.yaml +```command +$ kubectl apply -f install/kubernetes/istio-citadel-with-health-check.yaml ``` Deploy the `istio-citadel` service so that the CSR service can be found by the health checker. @@ -64,12 +64,12 @@ EOF Citadel will log the health checking results. Run the following in command line: -```bash -kubectl logs `kubectl get po -n istio-system | grep istio-citadel | awk '{print $1}'` -n istio-system +```command +$ kubectl logs `kubectl get po -n istio-system | grep istio-citadel | awk '{print $1}'` -n istio-system ``` You will see the output similar to: -```bash +```plain ... 2018-02-27T04:29:56.128081Z info CSR successfully signed. ... @@ -87,7 +87,7 @@ Observe that the health checking interval is about 15 seconds, which is the defa Optionally, adjust the health checking configuration to meet your own needs. Open the file `install/kubernetes/istio-citadel-with-health-check.yaml`, and locate the following lines. -```bash +```plain ... - --liveness-probe-path=/tmp/ca.liveness # path to the liveness health checking status file - --liveness-probe-interval=60s # interval for health checking file update @@ -124,16 +124,16 @@ continuously failed health checks. ## Cleanup * To disable health checking on Citadel: - ```bash + ```command kubectl apply -f install/kubernetes/istio-auth.yaml kubectl delete svc istio-citadel -n istio-system ``` * To remove Citadel: - ```bash - kubectl delete -f install/kubernetes/istio-citadel-with-health-check.yaml - kubectl delete svc istio-citadel -n istio-system + ```command + $ kubectl delete -f install/kubernetes/istio-citadel-with-health-check.yaml + $ kubectl delete svc istio-citadel -n istio-system ``` ## What's next diff --git a/_docs/tasks/security/https-overlay.md b/_docs/tasks/security/https-overlay.md index 4241bbd1fa70..e03446f06979 100644 --- a/_docs/tasks/security/https-overlay.md +++ b/_docs/tasks/security/https-overlay.md @@ -27,48 +27,42 @@ Note that authentication should be **disabled** at step 5 in the You need to have openssl installed to run this command -```bash -openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/nginx.key -out /tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx" +```command +$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/nginx.key -out /tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx" ``` -```bash -kubectl create secret tls nginxsecret --key /tmp/nginx.key --cert /tmp/nginx.crt -secret "nginxsecret" created +```command +$ kubectl create secret tls nginxsecret --key /tmp/nginx.key --cert /tmp/nginx.crt +$ secret "nginxsecret" created ``` Create a configmap used for the HTTPS service -```bash -kubectl create configmap nginxconfigmap --from-file=samples/https/default.conf -configmap "nginxconfigmap" created +```command +$ kubectl create configmap nginxconfigmap --from-file=samples/https/default.conf +$ configmap "nginxconfigmap" created ``` ## Deploy an HTTPS service without Istio sidecar This section creates a NGINX-based HTTPS service. -```bash -kubectl apply -f samples/https/nginx-app.yaml -``` - -```xxx +```command +$ kubectl apply -f samples/https/nginx-app.yaml service "my-nginx" created replicationcontroller "my-nginx" created ``` Then, create another pod to call this service. -```bash -kubectl apply -f <(bin/istioctl kube-inject --debug -f samples/sleep/sleep.yaml) +```command +$ kubectl apply -f <(bin/istioctl kube-inject --debug -f samples/sleep/sleep.yaml) ``` Get the pods -```bash -kubectl get pod -``` - -```xxx +```command +$ kubectl get pod NAME READY STATUS RESTARTS AGE my-nginx-jwwck 2/2 Running 0 1h sleep-847544bbfc-d27jg 2/2 Running 0 18h @@ -76,17 +70,14 @@ sleep-847544bbfc-d27jg 2/2 Running 0 18h Ssh into the istio-proxy container of sleep pod. -```bash -kubectl exec -it sleep-847544bbfc-d27jg -c istio-proxy /bin/bash +```command +$ kubectl exec -it sleep-847544bbfc-d27jg -c istio-proxy /bin/bash ``` Call my-nginx -```bash -curl https://my-nginx -k -``` - -```xxx +```command +$ curl https://my-nginx -k ... <h1>Welcome to nginx!</h1> ... @@ -94,11 +85,8 @@ curl https://my-nginx -k You can actually combine the above three command into one: -```bash -kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl https://my-nginx -k -``` - -```xxx +```command +$ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl https://my-nginx -k ... <h1>Welcome to nginx!</h1> ... @@ -111,23 +99,20 @@ disabled. So you only need to redeploy the NGINX HTTPS service with sidecar. Delete the HTTPS service. -```bash -kubectl delete -f nginx-app.yaml +```command +$ kubectl delete -f nginx-app.yaml ``` Deploy it with a sidecar -```bash -kubectl apply -f <(bin/istioctl kube-inject --debug -f samples/https/nginx-app.yaml) +```command +$ kubectl apply -f <(bin/istioctl kube-inject --debug -f samples/https/nginx-app.yaml) ``` Make sure the pod is up and running -```bash -kubectl get pod -``` - -```xxx +```command +$ kubectl get pod NAME READY STATUS RESTARTS AGE my-nginx-6svcc 2/2 Running 0 1h sleep-847544bbfc-d27jg 2/2 Running 0 18h @@ -135,11 +120,8 @@ sleep-847544bbfc-d27jg 2/2 Running 0 18h And run -```bash -kubectl exec sleep-847544bbfc-d27jg -c sleep -- curl https://my-nginx -k -``` - -```xxx +```command +$ kubectl exec sleep-847544bbfc-d27jg -c sleep -- curl https://my-nginx -k ... <h1>Welcome to nginx!</h1> ... @@ -147,11 +129,8 @@ kubectl exec sleep-847544bbfc-d27jg -c sleep -- curl https://my-nginx -k If you run from istio-proxy container, it should work as well -```bash -kubectl exec sleep-847544bbfc-d27jg -c istio-proxy -- curl https://my-nginx -k -``` - -```xxx +```command +$ kubectl exec sleep-847544bbfc-d27jg -c istio-proxy -- curl https://my-nginx -k ... <h1>Welcome to nginx!</h1> ... @@ -164,33 +143,27 @@ kubectl exec sleep-847544bbfc-d27jg -c istio-proxy -- curl https://my-nginx -k You need to deploy Istio control plane with mTLS enabled. If you have istio control plane with mTLS disabled installed, please delete it: -```bash -kubectl delete -f install/kubernetes/istio.yaml +```command +$ kubectl delete -f install/kubernetes/istio.yaml ``` And wait for everything is down, i.e., there is no pod in control plane namespace (istio-system). -```bash -kubectl get pod -n istio-system -``` - -```xxx +```command +$ kubectl get pod -n istio-system No resources found. ``` Then deploy the Istio control plane with mTLS enabled: -```bash -kubectl apply -f install/kubernetes/istio-auth.yaml +```command +$ kubectl apply -f install/kubernetes/istio-auth.yaml ``` Make sure everything is up and running: -```bash -kubectl get po -n istio-system -``` - -```xxx +```command +$ kubectl get po -n istio-system NAME READY STATUS RESTARTS AGE istio-citadel-58c5856966-k6nm4 1/1 Running 0 2m istio-ingress-5789d889bc-xzdg2 1/1 Running 0 2m @@ -200,20 +173,17 @@ istio-pilot-6954dcd96d-phh5z 2/2 Running 0 2m Then redeploy the HTTPS service and sleep service -```bash -kubectl delete -f <(bin/istioctl kube-inject --debug -f samples/sleep/sleep.yaml) -kubectl apply -f <(bin/istioctl kube-inject --debug -f samples/sleep/sleep.yaml) -kubectl delete -f <(bin/istioctl kube-inject --debug -f samples/https/nginx-app.yaml) -kubectl apply -f <(bin/istioctl kube-inject --debug -f samples/https/nginx-app.yaml) +```command +$ kubectl delete -f <(bin/istioctl kube-inject --debug -f samples/sleep/sleep.yaml) +$ kubectl apply -f <(bin/istioctl kube-inject --debug -f samples/sleep/sleep.yaml) +$ kubectl delete -f <(bin/istioctl kube-inject --debug -f samples/https/nginx-app.yaml) +$ kubectl apply -f <(bin/istioctl kube-inject --debug -f samples/https/nginx-app.yaml) ``` Make sure the pod is up and running -```bash -kubectl get pod -``` - -```xxx +```command +$ kubectl get pod NAME READY STATUS RESTARTS AGE my-nginx-9dvet 2/2 Running 0 1h sleep-77f457bfdd-hdknx 2/2 Running 0 18h @@ -221,11 +191,8 @@ sleep-77f457bfdd-hdknx 2/2 Running 0 18h And run -```bash -kubectl exec sleep-77f457bfdd-hdknx -c sleep -- curl https://my-nginx -k -``` - -```xxx +```command +$ kubectl exec sleep-77f457bfdd-hdknx -c sleep -- curl https://my-nginx -k ... <h1>Welcome to nginx!</h1> ... @@ -237,11 +204,8 @@ and nginx-proxy. In this case, everything works fine. However, if you run this command from istio-proxy container, it will not work. -```bash -kubectl exec sleep-77f457bfdd-hdknx -c istio-proxy -- curl https://my-nginx -k -``` - -```xxx +```command +$ kubectl exec sleep-77f457bfdd-hdknx -c istio-proxy -- curl https://my-nginx -k curl: (35) gnutls_handshake() failed: Handshake failed command terminated with exit code 35 ``` diff --git a/_docs/tasks/security/mutual-tls.md b/_docs/tasks/security/mutual-tls.md index 3473b87cae1c..69ba30c2d036 100644 --- a/_docs/tasks/security/mutual-tls.md +++ b/_docs/tasks/security/mutual-tls.md @@ -33,11 +33,8 @@ Use the parameter *-n yournamespace* to specify a namespace other than the defau Verify the cluster-level Citadel is running: -```bash -kubectl get deploy -l istio=istio-citadel -n istio-system -``` - -```bash +```command +$ kubectl get deploy -l istio=istio-citadel -n istio-system NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE istio-citadel 1 1 1 1 1m ``` @@ -48,8 +45,8 @@ Citadel is up if the "AVAILABLE" column is 1. 1. Verify AuthPolicy setting in ConfigMap. - ```bash - kubectl get configmap istio -o yaml -n istio-system | grep authPolicy | head -1 + ```command + $ kubectl get configmap istio -o yaml -n istio-system | grep authPolicy | head -1 ``` Istio mutual TLS authentication is enabled if the line `authPolicy: MUTUAL_TLS` is uncommented (doesn't have a `#`). @@ -65,10 +62,8 @@ and send request to other services by curl. There are several steps: 1. get the productpage pod name - ```bash - kubectl get pods -l app=productpage - ``` - ```bash + ```command + $ kubectl get pods -l app=productpage NAME READY STATUS RESTARTS AGE productpage-v1-4184313719-5mxjc 2/2 Running 0 23h ``` @@ -76,15 +71,13 @@ There are several steps: Make sure the pod is "Running". 1. ssh into the Envoy container - ```bash - kubectl exec -it productpage-v1-4184313719-5mxjc -c istio-proxy /bin/bash + ```command + $ kubectl exec -it productpage-v1-4184313719-5mxjc -c istio-proxy /bin/bash ``` 1. make sure the key/cert is in /etc/certs/ directory - ```bash - ls /etc/certs/ - ``` - ```bash + ```command + $ ls /etc/certs/ cert-chain.pem key.pem root-cert.pem ``` @@ -93,26 +86,24 @@ There are several steps: In this example, we only have one Citadel in a cluster, so all Envoys have the same `root-cert.pem`. 1. make sure 'curl' is installed by - ```bash - curl + ```command + $ curl ``` If curl is installed, you should see something like - ```bash + ```plain curl: try 'curl --help' or 'curl --manual' for more information ``` - Otherwise run below command to start over - ```bash - kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) + Otherwise run the command below to start over + ```command + $ kubectl apply -f <(istioctl kube-inject --debug -f samples/bookinfo/kube/bookinfo.yaml) ``` > Istio proxy image does not have curl installed while the debug image does. The "--debug" flag in above command redeploys the service with debug image. 1. send requests to another service, for example, details. - ```bash - curl https://details:9080/details/0 -v --key /etc/certs/key.pem --cert /etc/certs/cert-chain.pem --cacert /etc/certs/root-cert.pem -k - ``` - ```bash + ```command + $ curl https://details:9080/details/0 -v --key /etc/certs/key.pem --cert /etc/certs/cert-chain.pem --cacert /etc/certs/root-cert.pem -k ... error fetching CN from cert:The requested data were not available. ... diff --git a/_docs/tasks/security/per-service-mtls.md b/_docs/tasks/security/per-service-mtls.md index 084ef078363d..50ce7a288c39 100644 --- a/_docs/tasks/security/per-service-mtls.md +++ b/_docs/tasks/security/per-service-mtls.md @@ -26,30 +26,23 @@ In this task, you will learn: * Start [httpbin demo](https://github.com/istio/istio/tree/master/samples/httpbin) with Istio sidecar. Also, for testing purpose, run two instances of [sleep](https://github.com/istio/istio/tree/master/samples/sleep), one with sidecar and one without (in different namespace). Below are commands to help you start these services. -```bash -kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) - -kubectl create ns legacy && kubectl apply -f samples/sleep/sleep.yaml -n legacy +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) +$ kubectl create ns legacy && kubectl apply -f samples/sleep/sleep.yaml -n legacy ``` In this initial setup, we expect the sleep instance in default namespace can talk to httpbin service, but the one in legacy namespace cannot, as it doesn't have sidecar to facilitate mTLS. -```bash -kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://httpbin.default:8000/ip -s -``` - -```json +```command-output-as-json +$ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://httpbin.default:8000/ip -s { "origin": "127.0.0.1" } ``` -```bash -kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name} -n legacy) -n legacy -- curl http://httpbin.default:8000/ip -s -``` - -```xxx +```command +$ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name} -n legacy) -n legacy -- curl http://httpbin.default:8000/ip -s command terminated with exit code 56 ``` @@ -58,7 +51,7 @@ command terminated with exit code 56 If we want to disable mTLS only for httpbin (on port 8000), without changing the mesh authentication settings, we can do that by adding this annotations to the httpbin service definition. -```xxx +```plain annotations: auth.istio.io/8000: NONE ``` @@ -80,21 +73,15 @@ In the part of the demo, we will show the impact of this field. By default (0.3 or later), this list contains `kubernetes.default.svc.cluster.local` (which is the name of the API server service in common setup). You can verify it by running this command: -```bash -kubectl get configmap -n istio-system istio -o yaml | grep mtlsExcludedServices -``` - -```bash +```command +$ kubectl get configmap -n istio-system istio -o yaml | grep mtlsExcludedServices mtlsExcludedServices: ["kubernetes.default.svc.cluster.local"] ``` It's then expected that request to kubernetes.default service should be possible: -```bash -kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl https://kubernetes.default:443/api/ -k -s -``` - -```json +```command-output-as-json +$ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl https://kubernetes.default:443/api/ -k -s { "kind": "APIVersions", "versions": [ @@ -111,16 +98,13 @@ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) Now, run `kubectl edit configmap istio -n istio-system` and clear `mtlsExcludedServices` and restart Pilot after done: -```bash -kubectl get pod $(kubectl get pod -l istio=pilot -n istio-system -o jsonpath={.items..metadata.name}) -n istio-system -o yaml | kubectl replace --force -f - +```command +$ kubectl get pod $(kubectl get pod -l istio=pilot -n istio-system -o jsonpath={.items..metadata.name}) -n istio-system -o yaml | kubectl replace --force -f - ``` The same test request above now fail with code 35, as sleep's sidecar starts using mTLS again: -```bash -kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl https://kubernetes.default:443/api/ -k -s -``` - -```xxx +```command +$ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl https://kubernetes.default:443/api/ -k -s command terminated with exit code 35 ``` diff --git a/_docs/tasks/security/plugin-ca-cert.md b/_docs/tasks/security/plugin-ca-cert.md index a5ec549866ab..a1670d00fdf5 100644 --- a/_docs/tasks/security/plugin-ca-cert.md +++ b/_docs/tasks/security/plugin-ca-cert.md @@ -38,15 +38,15 @@ These files are ready to use in the `samples/certs/` directory. The following steps enable plugging in the certificates and key into Citadel: 1. Create a secret `cacert` including all the input files `ca-cert.pem`, `ca-key.pem`, `root-cert.pem` and `cert-chain.pem`: - ```bash - 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 + ```command + $ 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 ``` 1. Redeploy Citadel, which reads the certificates and key from the secret-mount files: - ```bash - kubectl apply -f install/kubernetes/istio-citadel-plugin-certs.yaml + ```command + $ kubectl apply -f install/kubernetes/istio-citadel-plugin-certs.yaml ``` > Note: if you are using different certificate/key file or secret names, you need to change corresponding volume mounts and arguments in `istio-citadel-plugin-certs.yaml`. @@ -54,8 +54,8 @@ The following steps enable plugging in the certificates and key into Citadel: 1. To make sure the workloads obtain the new certificates promptly, delete the secrets generated by Citadel (named as istio.\*). In this example, `istio.default`. Citadel will issue new certificates for the workloads. - ```bash - kubectl delete secret istio.default + ```command + $ kubectl delete secret istio.default ``` ## Verifying the new certificates @@ -69,24 +69,24 @@ This requires you have `openssl` installed on your machine. In the following, we take the ratings pod as an example, and verify the certificates mounted on the pod. Set the pod name to `RATINGSPOD`: - ```bash - RATINGSPOD=`kubectl get pods -l app=ratings -o jsonpath='{.items[0].metadata.name}'` + ```command + $ RATINGSPOD=`kubectl get pods -l app=ratings -o jsonpath='{.items[0].metadata.name}'` ``` Run the following commands to retrieve the certificates mounted on the proxy: - ```bash - kubectl exec -it $RATINGSPOD -c istio-proxy -- /bin/cat /etc/certs/root-cert.pem > /tmp/pod-root-cert.pem + ```command + $ kubectl exec -it $RATINGSPOD -c istio-proxy -- /bin/cat /etc/certs/root-cert.pem > /tmp/pod-root-cert.pem ``` The file `/tmp/pod-root-cert.pem` contains the root certificate propagated to the pod. - ```bash - kubectl exec -it $RATINGSPOD -c istio-proxy -- /bin/cat /etc/certs/cert-chain.pem > /tmp/pod-cert-chain.pem + ```command + $ kubectl exec -it $RATINGSPOD -c istio-proxy -- /bin/cat /etc/certs/cert-chain.pem > /tmp/pod-cert-chain.pem ``` The file `/tmp/pod-cert-chain.pem` contains the workload certificate and the CA certificate propagated to the pod. 1. Verify the root certificate is the same as the one specified by operator: - ```bash + ```command openssl x509 -in samples/certs/root-cert.pem -text -noout > /tmp/root-cert.crt.txt openssl x509 -in /tmp/pod-root-cert.pem -text -noout > /tmp/pod-root-cert.crt.txt diff /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt @@ -94,21 +94,21 @@ This requires you have `openssl` installed on your machine. Expect the output to be empty. 1. Verify the CA certificate is the same as the one specified by operator: - ```bash - tail -n 22 /tmp/pod-cert-chain.pem > /tmp/pod-cert-chain-ca.pem - openssl x509 -in samples/certs/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt - openssl x509 -in /tmp/pod-cert-chain-ca.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt - diff /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt + ```command + $ tail -n 22 /tmp/pod-cert-chain.pem > /tmp/pod-cert-chain-ca.pem + $ openssl x509 -in samples/certs/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt + $ openssl x509 -in /tmp/pod-cert-chain-ca.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt + $ diff /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt ``` Expect the output to be empty. 1. Verify the certificate chain from the root certificate to the workload certificate: - ```bash - head -n 21 /tmp/pod-cert-chain.pem > /tmp/pod-cert-chain-workload.pem - openssl verify -CAfile <(cat samples/certs/ca-cert.pem samples/certs/root-cert.pem) /tmp/pod-cert-chain-workload.pem + ```command + $ head -n 21 /tmp/pod-cert-chain.pem > /tmp/pod-cert-chain-workload.pem + $ openssl verify -CAfile <(cat samples/certs/ca-cert.pem samples/certs/root-cert.pem) /tmp/pod-cert-chain-workload.pem ``` Expect the following output: - ```bash + ```command /tmp/pod-cert-chain-workload.pem: OK ``` @@ -116,13 +116,13 @@ This requires you have `openssl` installed on your machine. * To remove the secret `cacerts`: - ```bash - kubectl delete secret cacerts -n istio-system + ```command + $ kubectl delete secret cacerts -n istio-system ``` * To remove the Istio components: - ```bash - kubectl delete -f install/kubernetes/istio-auth.yaml + ```command + $ kubectl delete -f install/kubernetes/istio-auth.yaml ``` ## What's next diff --git a/_docs/tasks/security/role-based-access-control.md b/_docs/tasks/security/role-based-access-control.md index 802d5f129fb8..26e64ff4f897 100644 --- a/_docs/tasks/security/role-based-access-control.md +++ b/_docs/tasks/security/role-based-access-control.md @@ -34,12 +34,8 @@ microservices running under them. * Create service account `bookinfo-reviews`, and redeploy the services `reviews` (deployments `reviews-v2` and `reviews-v3`) with the service account. - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-add-serviceaccount.yaml) - ``` - - You can expect to see the output similar to the following: - ```bash + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-add-serviceaccount.yaml) serviceaccount "bookinfo-productpage" created deployment "productpage-v1" configured serviceaccount "bookinfo-reviews" created @@ -61,8 +57,8 @@ Run the following command to enable Istio RBAC for "default" namespace. and specify the namespace, say `"your-namespace"`, in the `match` statement in `rule` spec `"match: destination.namespace == "your-namespace"`. -```bash -istioctl create -f samples/bookinfo/kube/istio-rbac-enable.yaml +```command +$ istioctl create -f samples/bookinfo/kube/istio-rbac-enable.yaml ``` > If you have conflicting rules that you set in previous tasks, use `istioctl replace` instead of `istioctl create`. @@ -88,8 +84,8 @@ any service in "default" namespace that has "app" label set to one of the values is accessible by services in the same namespace (i.e., "default" namespace) and services in "istio-system" namespace. Run the following command to create a namespace-level access control policy. -```bash -istioctl create -f samples/bookinfo/kube/istio-rbac-namespace.yaml +```command +$ istioctl create -f samples/bookinfo/kube/istio-rbac-namespace.yaml ``` The policy does the following: @@ -97,7 +93,7 @@ The policy does the following: set to one of the values in ["productpage", "details", "reviews", "ratings"]. Note that there is a "constraint" specifying that the services must have one of the listed "app" labels. - ```bash + ```yaml apiVersion: "config.istio.io/v1alpha2" kind: ServiceRole metadata: @@ -114,7 +110,7 @@ the services must have one of the listed "app" labels. * Creates a `ServiceRoleBinding` that assign the "service-viewer" role to all services in "istio-system" and "default" namespaces. - ```bash + ```yaml apiVersion: "config.istio.io/v1alpha2" kind: ServiceRoleBinding metadata: @@ -131,9 +127,9 @@ the services must have one of the listed "app" labels. name: "service-viewer" ``` -You can expect to see the output similar to the following: +You can expect to see output similar to the following: -```bash +```plain servicerole "service-viewer" created servicerolebinding "bind-service-viewer" created ``` @@ -147,8 +143,8 @@ with "Book Details" section in the lower left part and "Book Reviews" section in Remove the following configuration before you proceed to the next task: -```bash -istioctl delete -f samples/bookinfo/kube/istio-rbac-namespace.yaml +```command +$ istioctl delete -f samples/bookinfo/kube/istio-rbac-namespace.yaml ``` ## Service-level access control @@ -166,14 +162,14 @@ access to the services in Bookinfo sample. In this step, we will create a policy that allows external requests to view `productpage` service via Ingress. Run the following command: -```bash -istioctl create -f samples/bookinfo/kube/istio-rbac-productpage.yaml +```command +$ istioctl create -f samples/bookinfo/kube/istio-rbac-productpage.yaml ``` The policy does the following: * Creates a `ServiceRole` "productpage-viewer" which allows read access to "productpage" service. - ```bash + ```yaml apiVersion: "config.istio.io/v1alpha2" kind: ServiceRole metadata: @@ -187,7 +183,7 @@ The policy does the following: * Creates a `ServiceRoleBinding` "bind-productpager-viewer" which assigns "productpage-viewer" role to all users/services. - ```bash + ```yaml apiVersion: "config.istio.io/v1alpha2" kind: ServiceRoleBinding metadata: @@ -215,14 +211,14 @@ We will create a policy to allow "productpage" service to read "details" and "re "bookinfo-productpage" service account is the authenticated identify for "productpage" service. Run the following command: -```bash -istioctl create -f samples/bookinfo/kube/istio-rbac-details-reviews.yaml +```command +$ istioctl create -f samples/bookinfo/kube/istio-rbac-details-reviews.yaml ``` The policy does the following: * Creates a `ServiceRole` "details-reviews-viewer" which allows read access to "details" and "reviews" services. - ```bash + ```yaml apiVersion: "config.istio.io/v1alpha2" kind: ServiceRole metadata: @@ -237,7 +233,7 @@ The policy does the following: * Creates a `ServiceRoleBinding` "bind-details-reviews" which assigns "details-reviews-viewer" role to service account "cluster.local/ns/default/sa/bookinfo-productpage" (representing the "productpage" service). - ```bash + ```yaml apiVersion: "config.istio.io/v1alpha2" kind: ServiceRoleBinding metadata: @@ -267,15 +263,15 @@ We will create a policy to allow "reviews" service to read "ratings" service. No Run the following command to create a policy that allows "reviews" service to read "ratings" service. -```bash -istioctl create -f samples/bookinfo/kube/istio-rbac-ratings.yaml +```command +$ istioctl create -f samples/bookinfo/kube/istio-rbac-ratings.yaml ``` The policy does the following: * Creates a `ServiceRole` "ratings-viewer" which allows read access to "ratings" service. - ```bash + ```yaml apiVersion: "config.istio.io/v1alpha2" kind: ServiceRole metadata: @@ -290,7 +286,7 @@ The policy does the following: * Creates a `ServiceRoleBinding` "bind-ratings" which assigns "ratings-viewer" role to service account "cluster.local/ns/default/sa/bookinfo-reviews", which represents the "reviews" services. - ```bash + ```yaml apiVersion: "config.istio.io/v1alpha2" kind: ServiceRoleBinding metadata: @@ -312,7 +308,7 @@ the "black" and "red" ratings in "Book Reviews" section. If you would like to only see "red" ratings in "Book Reviews" section, you can do that by specifying that only "reviews" service at version "v3" can access "ratings" service. -```bash +```yaml apiVersion: "config.istio.io/v1alpha2" kind: ServiceRoleBinding metadata: @@ -332,23 +328,23 @@ spec: * Remove Istio RBAC policy configuration: - ```bash - istioctl delete -f samples/bookinfo/kube/istio-rbac-ratings.yaml - istioctl delete -f samples/bookinfo/kube/istio-rbac-details-reviews.yaml - istioctl delete -f samples/bookinfo/kube/istio-rbac-productpage.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/istio-rbac-ratings.yaml + $ istioctl delete -f samples/bookinfo/kube/istio-rbac-details-reviews.yaml + $ istioctl delete -f samples/bookinfo/kube/istio-rbac-productpage.yaml ``` Alternatively, you can delete all `ServiceRole` and `ServiceRoleBinding` resources by running the following commands: - ```bash - kubectl delete servicerole --all - kubectl delete servicerolebinding --all + ```command + $ kubectl delete servicerole --all + $ kubectl delete servicerolebinding --all ``` * Disable Istio RBAC: - ```bash - istioctl delete -f samples/bookinfo/kube/istio-rbac-enable.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/istio-rbac-enable.yaml ``` ## What's next diff --git a/_docs/tasks/security/secure-access-control.md b/_docs/tasks/security/secure-access-control.md index 61d99d1171af..df6363c282c5 100644 --- a/_docs/tasks/security/secure-access-control.md +++ b/_docs/tasks/security/secure-access-control.md @@ -27,12 +27,8 @@ For the format of the service account in Istio, please refer to the * Run the following command to create service account `bookinfo-productpage`, and redeploy the service `productpage` with the service account. - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-add-serviceaccount.yaml) - ``` - - You can expect to see the output similar to the following: - ```bash + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-add-serviceaccount.yaml) serviceaccount "bookinfo-productpage" created deployment "productpage-v1" configured ``` @@ -53,17 +49,14 @@ the `productpage` service. 1. Explicitly deny the requests from `productpage` to `details`. Run the following command to set up the deny rule along with a handler and an instance. - ```bash - istioctl create -f samples/bookinfo/kube/mixer-rule-deny-serviceaccount.yaml - ``` - You can expect to see the output similar to the following: - ```bash + ```command + $ istioctl create -f samples/bookinfo/kube/mixer-rule-deny-serviceaccount.yaml Created config denier/default/denyproductpagehandler at revision 2877836 Created config checknothing/default/denyproductpagerequest at revision 2877837 Created config rule/default/denyproductpage at revision 2877838 ``` Notice the following in the `denyproductpage` rule: - ``` + ```plain match: destination.labels["app"] == "details" && source.user == "cluster.local/ns/default/sa/bookinfo-productpage" ``` It matches requests coming from the service account @@ -88,8 +81,8 @@ the `productpage` service. * Remove the mixer configuration: - ```bash - istioctl delete -f samples/bookinfo/kube/mixer-rule-deny-serviceaccount.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/mixer-rule-deny-serviceaccount.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/telemetry/distributed-tracing.md b/_docs/tasks/telemetry/distributed-tracing.md index bc8fdbebbc5d..7ed0835814fb 100644 --- a/_docs/tasks/telemetry/distributed-tracing.md +++ b/_docs/tasks/telemetry/distributed-tracing.md @@ -26,14 +26,14 @@ example application for this task. For Zipkin: - ```bash - kubectl apply -f install/kubernetes/addons/zipkin.yaml + ```command + $ kubectl apply -f install/kubernetes/addons/zipkin.yaml ``` For Jaeger: - ```bash - kubectl apply -n istio-system -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml + ```command + $ kubectl apply -n istio-system -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml ``` * Deploy the [Bookinfo]({{home}}/docs/guides/bookinfo.html) sample application. @@ -44,8 +44,8 @@ example application for this task. Setup access to the Zipkin dashboard URL using port-forwarding: -```bash -kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=zipkin -o jsonpath='{.items[0].metadata.name}') 9411:9411 & +```command +$ kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=zipkin -o jsonpath='{.items[0].metadata.name}') 9411:9411 & ``` Then open your browser at [http://localhost:9411](http://localhost:9411) @@ -54,8 +54,8 @@ Then open your browser at [http://localhost:9411](http://localhost:9411) Setup access to the Jaeger dashboard URL using port-forwarding: -```bash -kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=jaeger -o jsonpath='{.items[0].metadata.name}') 16686:16686 & +```command +$ kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=jaeger -o jsonpath='{.items[0].metadata.name}') 16686:16686 & ``` Then open your browser at [http://localhost:16686](http://localhost:16686) @@ -183,14 +183,14 @@ When you make downstream calls in your applications, make sure to include these If you are running with Zipkin, run the following command to cleanup: - ```bash - kubectl delete -f install/kubernetes/addons/zipkin.yaml + ```command + $ kubectl delete -f install/kubernetes/addons/zipkin.yaml ``` If you are running with Jaeger, run the following command to cleanup: - ```bash - kubectl delete -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml + ```command + $ kubectl delete -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/telemetry/fluentd.md b/_docs/tasks/telemetry/fluentd.md index bf0c2b6d826e..62d3c82fd1af 100644 --- a/_docs/tasks/telemetry/fluentd.md +++ b/_docs/tasks/telemetry/fluentd.md @@ -278,13 +278,8 @@ spec: Create the resources: -```bash -kubectl apply -f logging-stack.yaml -``` - -You should see the following: - -```xxx +```command +$ kubectl apply -f logging-stack.yaml namespace "logging" created service "elasticsearch" created deployment "elasticsearch" created @@ -349,12 +344,8 @@ spec: Create the resources: -```bash -istioctl create -f fluentd-istio.yaml -``` - -The expected output is similar to: -``` +```command +$ istioctl create -f fluentd-istio.yaml Created config logentry/istio-system/newlog at revision 22374 Created config fluentd/istio-system/handler at revision 22375 Created config rule/istio-system/newlogtofluentd at revision 22376 @@ -373,18 +364,18 @@ example stack. sample, visit `http://$GATEWAY_URL/productpage` in your web browser or issue the following command: - ```bash - curl http://$GATEWAY_URL/productpage + ```command + $ curl http://$GATEWAY_URL/productpage ``` 1. In a Kubernetes environment, setup port-forwarding for Kibana by executing the following command: - ```bash - kubectl -n logging port-forward $(kubectl -n logging get pod -l app=kibana -o jsonpath='{.items[0].metadata.name}') 5601:5601 + ```command + $ kubectl -n logging port-forward $(kubectl -n logging get pod -l app=kibana -o jsonpath='{.items[0].metadata.name}') 5601:5601 ``` - Leave the command running. Press Ctrl-C to exit when done accessing the Kibana UI. + Leave the command running. Press Ctrl-C to exit when done accessing the Kibana UI. 1. Navigate to the [Kibana UI](http://localhost:5601/) and click the "Set up index patterns" in the top right. @@ -398,14 +389,14 @@ example stack. * Remove the new telemetry configuration: - ```bash - istioctl delete -f fluentd-istio.yaml + ```command + $ istioctl delete -f fluentd-istio.yaml ``` * Remove the example Fluentd, Elasticsearch, Kibana stack: - ```bash - kubectl delete -f logging-stack.yaml + ```command + $ kubectl delete -f logging-stack.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/telemetry/metrics-logs.md b/_docs/tasks/telemetry/metrics-logs.md index 35b4d7698e1d..0663422128ef 100644 --- a/_docs/tasks/telemetry/metrics-logs.md +++ b/_docs/tasks/telemetry/metrics-logs.md @@ -118,13 +118,8 @@ as the example application throughout this task. 1. Push the new configuration. - ```bash - istioctl create -f new_telemetry.yaml - ``` - - The expected output is similar to: - - ```xxx + ```command + $ istioctl create -f new_telemetry.yaml Created config metric/istio-system/doublerequestcount at revision 1973035 Created config prometheus/istio-system/doublehandler at revision 1973036 Created config rule/istio-system/doubleprom at revision 1973037 @@ -138,8 +133,8 @@ as the example application throughout this task. For the Bookinfo sample, visit `http://$GATEWAY_URL/productpage` in your web browser or issue the following command: - ```bash - curl http://$GATEWAY_URL/productpage + ```command + $ curl http://$GATEWAY_URL/productpage ``` 1. Verify that the new metric values are being generated and collected. @@ -147,8 +142,8 @@ as the example application throughout this task. In a Kubernetes environment, setup port-forwarding for Prometheus by executing the following command: - ```bash - kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & + ```command + $ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & ``` View values for the new metric via the [Prometheus UI](http://localhost:9090/graph#%5B%7B%22range_input%22%3A%221h%22%2C%22expr%22%3A%22istio_double_request_count%22%2C%22tab%22%3A1%7D%5D). @@ -157,7 +152,7 @@ as the example application throughout this task. the `istio_double_request_count` metric. The table displayed in the **Console** tab includes entries similar to: - ```xxx + ```plain istio_double_request_count{destination="details.default.svc.cluster.local",instance="istio-mixer.istio-system:42422",job="istio-mesh",message="twice the fun!",source="productpage.default.svc.cluster.local"} 2 istio_double_request_count{destination="ingress.istio-system.svc.cluster.local",instance="istio-mixer.istio-system:42422",job="istio-mesh",message="twice the fun!",source="unknown"} 2 istio_double_request_count{destination="productpage.default.svc.cluster.local",instance="istio-mixer.istio-system:42422",job="istio-mesh",message="twice the fun!",source="ingress.istio-system.svc.cluster.local"} 2 @@ -173,13 +168,8 @@ as the example application throughout this task. In a Kubernetes environment, search through the logs for the Mixer pod as follows: - ```bash - kubectl -n istio-system logs $(kubectl -n istio-system get pods -l istio=mixer -o jsonpath='{.items[0].metadata.name}') mixer | grep \"instance\":\"newlog.logentry.istio-system\" - ``` - - The expected output is similar to: - - ```json + ```command-output-as-json + $ kubectl -n istio-system logs $(kubectl -n istio-system get pods -l istio=mixer -o jsonpath='{.items[0].metadata.name}') mixer | grep \"instance\":\"newlog.logentry.istio-system\" {"level":"warn","ts":"2017-09-21T04:33:31.249Z","instance":"newlog.logentry.istio-system","destination":"details","latency":"6.848ms","responseCode":200,"responseSize":178,"source":"productpage","user":"unknown"} {"level":"warn","ts":"2017-09-21T04:33:31.291Z","instance":"newlog.logentry.istio-system","destination":"ratings","latency":"6.753ms","responseCode":200,"responseSize":48,"source":"reviews","user":"unknown"} {"level":"warn","ts":"2017-09-21T04:33:31.263Z","instance":"newlog.logentry.istio-system","destination":"reviews","latency":"39.848ms","responseCode":200,"responseSize":379,"source":"productpage","user":"unknown"} @@ -300,8 +290,8 @@ here to illustrate how to use `match` expressions to control rule execution. * Remove the new telemetry configuration: - ```bash - istioctl delete -f new_telemetry.yaml + ```command + $ istioctl delete -f new_telemetry.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/telemetry/querying-metrics.md b/_docs/tasks/telemetry/querying-metrics.md index c2ad4a46b078..7b91d0b96fe1 100644 --- a/_docs/tasks/telemetry/querying-metrics.md +++ b/_docs/tasks/telemetry/querying-metrics.md @@ -26,13 +26,8 @@ application. In Kubernetes environments, execute the following command: - ```bash - kubectl -n istio-system get svc prometheus - ``` - - The output will be similar to: - - ```xxx + ```command + $ kubectl -n istio-system get svc prometheus NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE prometheus 10.59.241.54 <none> 9090/TCP 2m ``` @@ -42,8 +37,8 @@ application. For the Bookinfo sample, visit `http://$GATEWAY_URL/productpage` in your web browser or issue the following command: - ```bash - curl http://$GATEWAY_URL/productpage + ```command + $ curl http://$GATEWAY_URL/productpage ``` > `$GATEWAY_URL` is the value set in the [Bookinfo]({{home}}/docs/guides/bookinfo.html) guide. @@ -52,8 +47,8 @@ application. In Kubernetes environments, execute the following command: - ```bash - kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & + ```command + $ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & ``` Visit [http://localhost:9090/graph](http://localhost:9090/graph) in your web browser. @@ -117,8 +112,8 @@ docs](https://prometheus.io/docs/querying/basics/). * Remove any `kubectl port-forward` processes that may still be running: - ```bash - killall kubectl + ```command + $ killall kubectl ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/telemetry/servicegraph.md b/_docs/tasks/telemetry/servicegraph.md index 71fc576b03e8..0d913b8e6a8a 100644 --- a/_docs/tasks/telemetry/servicegraph.md +++ b/_docs/tasks/telemetry/servicegraph.md @@ -27,21 +27,16 @@ the example application throughout this task. In Kubernetes environments, execute the following command: - ```bash - kubectl apply -f install/kubernetes/addons/servicegraph.yaml + ```command + $ kubectl apply -f install/kubernetes/addons/servicegraph.yaml ``` 1. Verify that the service is running in your cluster. In Kubernetes environments, execute the following command: - ```bash - kubectl -n istio-system get svc servicegraph - ``` - - The output will be similar to: - - ```xxx + ```command + $ kubectl -n istio-system get svc servicegraph NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE servicegraph 10.59.253.165 <none> 8088/TCP 30s ``` @@ -51,8 +46,8 @@ the example application throughout this task. For the Bookinfo sample, visit `http://$GATEWAY_URL/productpage` in your web browser or issue the following command: - ```bash - curl http://$GATEWAY_URL/productpage + ```command + $ curl http://$GATEWAY_URL/productpage ``` Refresh the page a few times (or send the command a few times) to generate a @@ -64,8 +59,8 @@ the example application throughout this task. In Kubernetes environments, execute the following command: - ```bash - kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=servicegraph -o jsonpath='{.items[0].metadata.name}') 8088:8088 & + ```command + $ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=servicegraph -o jsonpath='{.items[0].metadata.name}') 8088:8088 & ``` Visit [http://localhost:8088/force/forcegraph.html](http://localhost:8088/force/forcegraph.html) @@ -127,8 +122,8 @@ depends on the standard Istio metric configuration. * In Kubernetes environments, execute the following command to remove the Servicegraph add-on: - ```bash - kubectl delete -f install/kubernetes/addons/servicegraph.yaml + ```command + $ kubectl delete -f install/kubernetes/addons/servicegraph.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/telemetry/tcp-metrics.md b/_docs/tasks/telemetry/tcp-metrics.md index 802e3b50d3d5..4e6bd82419f9 100644 --- a/_docs/tasks/telemetry/tcp-metrics.md +++ b/_docs/tasks/telemetry/tcp-metrics.md @@ -104,13 +104,8 @@ will generate and collect automatically. 1. Push the new configuration. - ```bash - istioctl create -f tcp_telemetry.yaml - ``` - - The expected output is similar to: - - ```xxx + ```command + $ istioctl create -f tcp_telemetry.yaml Created config metric/default/mongosentbytes at revision 3852843 Created config metric/default/mongoreceivedbytes at revision 3852844 Created config prometheus/default/mongohandler at revision 3852845 @@ -124,19 +119,14 @@ will generate and collect automatically. If you are using a cluster with automatic sidecar injection enabled, simply deploy the services using `kubectl`: - ```bash - kubectl apply -f samples/bookinfo/kube/bookinfo-ratings-v2.yaml + ```command + $ kubectl apply -f samples/bookinfo/kube/bookinfo-ratings-v2.yaml ``` If you are using manual sidecar injection, use the following command instead: - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-ratings-v2.yaml) - ``` - - Expected output: - - ```xxx + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-ratings-v2.yaml) deployment "ratings-v2" configured ``` @@ -145,32 +135,22 @@ will generate and collect automatically. If you are using a cluster with automatic sidecar injection enabled, simply deploy the services using `kubectl`: - ```bash - kubectl apply -f samples/bookinfo/kube/bookinfo-db.yaml + ```command + $ kubectl apply -f samples/bookinfo/kube/bookinfo-db.yaml ``` If you are using manual sidecar injection, use the following command instead: - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-db.yaml) - ``` - - Expected output: - - ```xxx + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-db.yaml) service "mongodb" configured deployment "mongodb-v1" configured ``` 1. Add routing rules to send traffic to `v2` of the `ratings` service: - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-ratings-db.yaml - ``` - - Expected output: - - ```xxxx + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-ratings-db.yaml Created config route-rule//ratings-test-v2 at revision 7216403 Created config route-rule//reviews-test-ratings-v2 at revision 7216404 ``` @@ -180,8 +160,8 @@ will generate and collect automatically. For the Bookinfo sample, visit `http://$GATEWAY_URL/productpage` in your web browser or issue the following command: - ```bash - curl http://$GATEWAY_URL/productpage + ```command + $ curl http://$GATEWAY_URL/productpage ``` 1. Verify that the new metric values are being generated and collected. @@ -189,8 +169,8 @@ will generate and collect automatically. In a Kubernetes environment, setup port-forwarding for Prometheus by executing the following command: - ```bash - kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & + ```command + $ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & ``` View values for the new metric via the [Prometheus UI](http://localhost:9090/graph#%5B%7B%22range_input%22%3A%221h%22%2C%22expr%22%3A%22istio_mongo_received_bytes%22%2C%22tab%22%3A1%7D%5D). @@ -199,7 +179,7 @@ will generate and collect automatically. the `istio_mongo_received_bytes` metric. The table displayed in the **Console** tab includes entries similar to: - ```xxx + ```plain istio_mongo_received_bytes{destination_version="v1",instance="istio-mixer.istio-system:42422",job="istio-mesh",source_service="ratings.default.svc.cluster.local",source_version="v2"} 2317 ``` @@ -241,14 +221,14 @@ protocols within policies. * Remove the new telemetry configuration: - ```bash - istioctl delete -f tcp_telemetry.yaml + ```command + $ istioctl delete -f tcp_telemetry.yaml ``` * Remove the `port-forward` process: - ```bash - killall kubectl + ```command + $ killall kubectl ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/telemetry/using-istio-dashboard.md b/_docs/tasks/telemetry/using-istio-dashboard.md index 73f2232ac074..2a94b75ccecf 100644 --- a/_docs/tasks/telemetry/using-istio-dashboard.md +++ b/_docs/tasks/telemetry/using-istio-dashboard.md @@ -26,21 +26,16 @@ the example application throughout this task. In Kubernetes environments, execute the following command: - ```bash - kubectl apply -f install/kubernetes/addons/grafana.yaml + ```command + $ kubectl apply -f install/kubernetes/addons/grafana.yaml ``` 1. Verify that the service is running in your cluster. In Kubernetes environments, execute the following command: - ```bash - kubectl -n istio-system get svc grafana - ``` - - The output will be similar to: - - ```xxx + ```command + $ kubectl -n istio-system get svc grafana NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana 10.59.247.103 <none> 3000/TCP 2m ``` @@ -49,8 +44,8 @@ the example application throughout this task. In Kubernetes environments, execute the following command: - ```bash - kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000 & + ```command + $ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000 & ``` Visit [http://localhost:3000/dashboard/db/istio-dashboard](http://localhost:3000/dashboard/db/istio-dashboard) in your web browser. @@ -69,8 +64,8 @@ the example application throughout this task. For the Bookinfo sample, visit `http://$GATEWAY_URL/productpage` in your web browser or issue the following command: - ```bash - curl http://$GATEWAY_URL/productpage + ```command + $ curl http://$GATEWAY_URL/productpage ``` Refresh the page a few times (or send the command a few times) to generate a @@ -114,14 +109,14 @@ For more on how to create, configure, and edit dashboards, please see the * In Kubernetes environments, execute the following command to remove the Grafana add-on: - ```bash - kubectl delete -f install/kubernetes/addons/grafana.yaml + ```command + $ kubectl delete -f install/kubernetes/addons/grafana.yaml ``` * Remove any `kubectl port-forward` processes that may be running: - ```bash - killall kubectl + ```command + $ killall kubectl ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md b/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md index 0a85a3dadcef..04a9a80ecddb 100644 --- a/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md +++ b/_docs/tasks/traffic-management-v1alpha3/circuit-breaking.md @@ -17,8 +17,8 @@ This task demonstrates the circuit-breaking capability for resilient application * Start the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) sample which will be used as the backend service for our task - ```bash - kubectl apply -f <(istioctl kube-inject --debug -f samples/httpbin/httpbin.yaml) + ```command + $ kubectl apply -f <(istioctl kube-inject --debug -f samples/httpbin/httpbin.yaml) ``` ## Circuit breaker @@ -53,10 +53,8 @@ Let's set up a scenario to demonstrate the circuit-breaking capabilities of Isti 1. Verify our destination rule was created correctly: - ```bash - istioctl get destinationrule httpbin -o yaml - ``` - ```xxx + ```command-output-as-yaml + $ istioctl get destinationrule httpbin -o yaml apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: @@ -83,17 +81,15 @@ Let's set up a scenario to demonstrate the circuit-breaking capabilities of Isti Now that we've set up rules for calling the `httpbin` service, let's create a client we can use to send traffic to our service and see whether we can trip the circuit breaking policies. We're going to use a simple load-testing client called [fortio](https://github.com/istio/fortio). With this client we can control the number of connections, concurrency, and delays of outgoing HTTP calls. In this step, we'll set up a client that is injected with the istio sidecar proxy so our network interactions are governed by Istio: -```bash -kubectl apply -f <(istioctl kube-inject --debug -f samples/httpbin/sample-client/fortio-deploy.yaml) +```command +$ kubectl apply -f <(istioctl kube-inject --debug -f samples/httpbin/sample-client/fortio-deploy.yaml) ``` Now we should be able to log into that client pod and use the simple fortio tool to call `httpbin`. We'll pass in `-curl` to indicate we just want to make one call: -```bash -FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }') -kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -curl http://httpbin:8000/get -``` -```xxx +```command +$ FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }') +$ kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -curl http://httpbin:8000/get HTTP/1.1 200 OK server: envoy date: Tue, 16 Jan 2018 23:47:00 GMT @@ -126,10 +122,8 @@ You can see the request succeeded! Now, let's break something. In the circuit-breaking settings, we specified `maxConnections: 1` and `http1MaxPendingRequests: 1`. This should mean that if we exceed more than one connection and request concurrently, we should see the istio-proxy open the circuit for further requests/connections. Let's try with two concurrent connections (`-c 2`) and send 20 requests (`-n 20`) -```bash -kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get -``` -```xxx +```command +$ kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get Fortio 0.6.2 running at 0 queries per second, 2->2 procs, for 5s: http://httpbin:8000/get Starting at max qps with 2 thread(s) [gomax 2] for exactly 20 calls (10 per thread + 0) 23:51:10 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) @@ -159,17 +153,15 @@ All done 20 calls (plus 0 warmup) 10.215 ms avg, 187.8 qps We see almost all requests made it through! -```xxx +```plain Code 200 : 19 (95.0 %) Code 503 : 1 (5.0 %) ``` The istio-proxy does allow for some leeway. Let's bring the number of concurrent connections up to 3: -```bash -kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 3 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get -``` -```xxx +```command +$ kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 3 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get Fortio 0.6.2 running at 0 queries per second, 2->2 procs, for 5s: http://httpbin:8000/get Starting at max qps with 3 thread(s) [gomax 2] for exactly 30 calls (10 per thread + 0) 23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) @@ -211,17 +203,15 @@ All done 30 calls (plus 0 warmup) 5.336 ms avg, 422.2 qps Now we start to see the circuit breaking behavior we expect. -```xxx +```plain Code 200 : 19 (63.3 %) Code 503 : 11 (36.7 %) ``` Only 63.3% of the requests made it through and the rest were trapped by circuit breaking. We can query the istio-proxy stats to see more: -```bash -kubectl exec -it $FORTIO_POD -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep httpbin | grep pending -``` -```xxx +```command +$ kubectl exec -it $FORTIO_POD -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep httpbin | grep pending cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_active: 0 cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_failure_eject: 0 cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_overflow: 12 @@ -234,15 +224,15 @@ We see `12` for the `upstream_rq_pending_overflow` value which means `12` calls 1. Remove the rules. - ```bash - istioctl delete destinationrule httpbin + ```command + $ istioctl delete destinationrule httpbin ``` 1. Shutdown the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) service and client. - ```bash - kubectl delete deploy httpbin fortio-deploy - kubectl delete svc httpbin + ```command + $ kubectl delete deploy httpbin fortio-deploy + $ kubectl delete svc httpbin ``` ## What's next diff --git a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md index a114fb058692..4958fa60713e 100644 --- a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md +++ b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md @@ -18,8 +18,8 @@ This task describes how to configure Istio to expose external TCP services to ap * Start the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) sample application which will be used as a test source for external calls. - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) ``` **Note**: any pod that you can execute `curl` from is good enough. @@ -63,29 +63,23 @@ This command instructs the Istio proxy to forward requests on port 443 of any of 1. `kubectl exec` into the pod to be used as the test source. If you are using the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) application, run the following command: - ```bash - kubectl exec -it $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep bash + ```command + $ kubectl exec -it $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep bash ``` 1. Make a request and verify that we can access https://www.wikipedia.org successfully: - ```bash - curl -o /dev/null -s -w "%{http_code}\n" https://www.wikipedia.org - ``` - ```xxx + ```command + $ curl -o /dev/null -s -w "%{http_code}\n" https://www.wikipedia.org 200 ``` We should see `200` printed as the output, which is the HTTP code _OK_. 1. Now let's fetch the current number of the articles available on Wikipedia in the English language: - ```bash - curl -s https://en.wikipedia.org/wiki/Main_Page | grep articlecount | grep 'Special:Statistics' - ``` - - The output should be similar to: - ```xxx + ```command + $ curl -s https://en.wikipedia.org/wiki/Main_Page | grep articlecount | grep 'Special:Statistics' <div id="articlecount" style="font-size:85%;"><a href="/wiki/Special:Statistics" title="Special:Statistics">5,563,121</a> articles in <a href="/wiki/English_language" title="English language">English</a></div> ``` @@ -95,14 +89,14 @@ This command instructs the Istio proxy to forward requests on port 443 of any of 1. Remove the external service we created. - ```bash - istioctl delete serviceentry wikipedia-ext + ```command + $ istioctl delete serviceentry wikipedia-ext ``` 1. Shutdown the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) application. - ```bash - kubectl delete -f samples/sleep/sleep.yaml + ```command + $ kubectl delete -f samples/sleep/sleep.yaml ``` ## What's next diff --git a/_docs/tasks/traffic-management-v1alpha3/egress.md b/_docs/tasks/traffic-management-v1alpha3/egress.md index 9b21877ff46e..49f800627c41 100644 --- a/_docs/tasks/traffic-management-v1alpha3/egress.md +++ b/_docs/tasks/traffic-management-v1alpha3/egress.md @@ -23,8 +23,8 @@ or alternatively, to simply bypass the Istio proxy for a specific range of IPs. * Start the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) sample which will be used as a test source for external calls. - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) ``` Note that any pod that you can `exec` and `curl` from would do. @@ -93,22 +93,22 @@ the connection to HTTPS. 1. Exec into the pod being used as the test source. For example, if you are using the sleep service, run the following commands: - ```bash - export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) - kubectl exec -it $SOURCE_POD -c sleep bash + ```command + $ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) + $ kubectl exec -it $SOURCE_POD -c sleep bash ``` 1. Make a request to the external HTTP service: - ```bash - curl http://httpbin.org/headers + ```command + $ curl http://httpbin.org/headers ``` 1. Make a request to the external HTTPS service. External services of type HTTPS must be accessed over HTTP with the port specified in the request: - ```bash - curl http://www.google.com:443 + ```command + $ curl http://www.google.com:443 ``` ### Setting route rules on an external service @@ -121,12 +121,9 @@ to set a timeout rule on calls to the httpbin.org service. 1. From inside the pod being used as the test source, invoke the `/delay` endpoint of the httpbin.org external service: - ```bash - kubectl exec -it $SOURCE_POD -c sleep bash - time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5 - ``` - - ```bash + ```command + $ kubectl exec -it $SOURCE_POD -c sleep bash + $ time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5 200 real 0m5.024s @@ -154,12 +151,9 @@ to set a timeout rule on calls to the httpbin.org service. 1. Wait a few seconds, then issue the _curl_ request again: - ```bash - kubectl exec -it $SOURCE_POD -c sleep bash - time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5 - ``` - - ```bash + ```command + $ kubectl exec -it $SOURCE_POD -c sleep bash + $ time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5 504 real 0m3.149s @@ -187,63 +181,61 @@ to the sidecar proxy. The values used for internal IP range(s), however, depends on where your cluster is running. For example, with Minikube the range is 10.0.0.1/24, so you would start the sleep service like this: -```bash -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.0.0.1/24) +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.0.0.1/24) ``` On IBM Cloud Private, use: 1. Get your `service_cluster_ip_range` from IBM Cloud Private configuration file under `cluster/config.yaml`. - ```bash - cat cluster/config.yaml | grep service_cluster_ip_range + ```command + $ cat cluster/config.yaml | grep service_cluster_ip_range ``` A sample output is as following: - ```xxx + ```plain service_cluster_ip_range: 10.0.0.1/24 ``` 1. Inject the `service_cluster_ip_range` to your application profile via `--includeIPRanges` to limit Istio's traffic interception to the service cluster IP range. - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.0.0.1/24) + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.0.0.1/24) ``` On IBM Cloud Container Service, use: -```bash -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=172.30.0.0/16,172.20.0.0/16,10.10.10.0/24) +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=172.30.0.0/16,172.20.0.0/16,10.10.10.0/24) ``` On Google Container Engine (GKE) the ranges are not fixed, so you will need to run the `gcloud container clusters describe` command to determine the ranges to use. For example: -```bash -gcloud container clusters describe XXXXXXX --zone=XXXXXX | grep -e clusterIpv4Cidr -e servicesIpv4Cidr -``` -```xxx +```command +$ gcloud container clusters describe XXXXXXX --zone=XXXXXX | grep -e clusterIpv4Cidr -e servicesIpv4Cidr clusterIpv4Cidr: 10.4.0.0/14 servicesIpv4Cidr: 10.7.240.0/20 ``` -```bash -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.4.0.0/14,10.7.240.0/20) +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.4.0.0/14,10.7.240.0/20) ``` On Azure Container Service(ACS), use: -```bash -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.244.0.0/16,10.240.0.0/16) +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.244.0.0/16,10.240.0.0/16) ``` After starting your service this way, the Istio sidecar will only intercept and manage internal requests within the cluster. Any external request will simply bypass the sidecar and go straight to its intended destination. -```bash -export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -kubectl exec -it $SOURCE_POD -c sleep curl http://httpbin.org/headers +```command +$ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) +$ kubectl exec -it $SOURCE_POD -c sleep curl http://httpbin.org/headers ``` ## Understanding what happened @@ -266,16 +258,16 @@ cloud provider specific knowledge and configuration. 1. Remove the rules. - ```bash - istioctl delete serviceentry httpbin-ext google-ext - istioctl delete destinationrule google-ext - istioctl delete virtualservice httpbin-ext + ```command + $ istioctl delete serviceentry httpbin-ext google-ext + $ istioctl delete destinationrule google-ext + $ istioctl delete virtualservice httpbin-ext ``` 1. Shutdown the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) service. - ```bash - kubectl delete -f samples/sleep/sleep.yaml + ```command + $ kubectl delete -f samples/sleep/sleep.yaml ``` ## `ServiceEntry` and Access Control diff --git a/_docs/tasks/traffic-management-v1alpha3/fault-injection.md b/_docs/tasks/traffic-management-v1alpha3/fault-injection.md index dd0ea9c48fc0..8e79b965e040 100644 --- a/_docs/tasks/traffic-management-v1alpha3/fault-injection.md +++ b/_docs/tasks/traffic-management-v1alpha3/fault-injection.md @@ -20,9 +20,9 @@ This task shows how to inject delays and test the resiliency of your application [request routing](./request-routing.html) task or by running following commands: - ```bash - istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml - istioctl replace -f samples/bookinfo/routing/route-rule-reviews-test-v2.yaml + ```command + $ istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml + $ istioctl replace -f samples/bookinfo/routing/route-rule-reviews-test-v2.yaml ``` # Fault injection @@ -36,17 +36,14 @@ continue without any errors. 1. Create a fault injection rule to delay traffic coming from user "jason" (our test user) - ```bash - istioctl replace -f samples/bookinfo/routing/route-rule-ratings-test-delay.yaml + ```command + $ istioctl replace -f samples/bookinfo/routing/route-rule-ratings-test-delay.yaml ``` Confirm the rule is created: - ```bash - istioctl get virtualservice ratings -o yaml - ``` - - ```yaml + ```command-output-as-yaml + $ istioctl get virtualservice ratings -o yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: @@ -119,17 +116,14 @@ message. 1. Create a fault injection rule to send an HTTP abort for user "jason" - ```bash - istioctl replace -f samples/bookinfo/routing/route-rule-ratings-test-abort.yaml + ```command + $ istioctl replace -f samples/bookinfo/routing/route-rule-ratings-test-abort.yaml ``` Confirm the rule is created - ```bash - istioctl get virtualservice ratings -o yaml - ``` - - ```yaml + ```command-output-as-yaml + $ istioctl get virtualservice ratings -o yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: @@ -163,8 +157,8 @@ message. * Remove the application routing rules: - ```bash - istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml + ```command + $ istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/traffic-management-v1alpha3/ingress.md b/_docs/tasks/traffic-management-v1alpha3/ingress.md index 7f31a5454b73..5fa1c3e3133b 100644 --- a/_docs/tasks/traffic-management-v1alpha3/ingress.md +++ b/_docs/tasks/traffic-management-v1alpha3/ingress.md @@ -33,22 +33,22 @@ This task describes how to configure Istio to expose a service outside of the se If you installed the [Istio-Initializer]({{home}}/docs/setup/kubernetes/sidecar-injection.html#automatic-sidecar-injection), do - ```bash - kubectl apply -f samples/httpbin/httpbin.yaml + ```command + $ kubectl apply -f samples/httpbin/httpbin.yaml ``` Without the Istio-Initializer: - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) ``` * Generate a certificate and key that will be used to demonstrate a TLS-secured gateway A private key and certificate can be created for testing using [OpenSSL](https://www.openssl.org/). - ```bash - openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=foo.bar.com" + ```command + $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=foo.bar.com" ``` ## Configuring ingress using an Istio Gateway resource (recommended) @@ -142,37 +142,28 @@ Therefore, to test our `Gateway` we will send requests to the `istio-ingress` se 1. Get the ingress controller pod's hostIP: - ```bash - kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' - ``` - - ```bash + ```command + $ kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' 169.47.243.100 ``` 1. Get the istio-ingress service's nodePorts for port 80 and 443: - ```bash - kubectl -n istio-system get svc istio-ingress - ``` - - ```bash + ```command + $ kubectl -n istio-system get svc istio-ingress NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingress 10.10.10.155 <pending> 80:31486/TCP,443:32254/TCP 32m ``` - ```bash - export INGRESS_HOST=169.47.243.100:31486 - export SECURE_INGRESS_HOST=169.47.243.100:32254 + ```command + $ export INGRESS_HOST=169.47.243.100:31486 + $ export SECURE_INGRESS_HOST=169.47.243.100:32254 ``` 1. Access the httpbin service with either HTTP or HTTPS using _curl_: - ```bash - curl -I http://$INGRESS_HOST/status/200 - ``` - - ```xxx + ```command + $ curl -I http://$INGRESS_HOST/status/200 HTTP/1.1 200 OK server: envoy date: Mon, 29 Jan 2018 04:45:49 GMT @@ -183,11 +174,8 @@ Therefore, to test our `Gateway` we will send requests to the `istio-ingress` se x-envoy-upstream-service-time: 48 ``` - ```bash - curl -I -k https://$SECURE_INGRESS_HOST/status/200 - ``` - - ```xxx + ```command + $ curl -I -k https://$SECURE_INGRESS_HOST/status/200 HTTP/1.1 200 OK server: envoy date: Mon, 29 Jan 2018 04:45:49 GMT @@ -201,22 +189,16 @@ Therefore, to test our `Gateway` we will send requests to the `istio-ingress` se 1. Access any other URL that has not been explicitly exposed. You should see a HTTP 404 error: - ```bash - curl -I http://$INGRESS_HOST/headers - ``` - - ```xxx + ```command + $ curl -I http://$INGRESS_HOST/headers HTTP/1.1 404 Not Found date: Mon, 29 Jan 2018 04:45:49 GMT server: envoy content-length: 0 ``` - ```bash - curl -I https://$SECURE_INGRESS_HOST/headers - ``` - - ```xxx + ```command + $ curl -I https://$SECURE_INGRESS_HOST/headers HTTP/1.1 404 Not Found date: Mon, 29 Jan 2018 04:45:49 GMT server: envoy @@ -278,51 +260,39 @@ service declaration. * If your cluster is running in an environment that supports external load balancers, use the ingress' external address: - ```bash - kubectl get ingress simple-ingress -o wide - ``` - - ```xxx + ```command + $ kubectl get ingress simple-ingress -o wide NAME HOSTS ADDRESS PORTS AGE simple-ingress * 130.211.10.121 80 1d ``` - ```bash - export INGRESS_HOST=130.211.10.121 + ```command + $ export INGRESS_HOST=130.211.10.121 ``` * If load balancers are not supported, use the ingress controller pod's hostIP: - ```bash - kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' - ``` - - ```xxx + ```command + $ kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' 169.47.243.100 ``` along with the istio-ingress service's nodePort for port 80: - ```bash - kubectl -n istio-system get svc istio-ingress - ``` - - ```xxx + ```command + $ kubectl -n istio-system get svc istio-ingress NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingress 10.10.10.155 <pending> 80:31486/TCP,443:32254/TCP 32m ``` - ```bash - export INGRESS_HOST=169.47.243.100:31486 + ```command + $ export INGRESS_HOST=169.47.243.100:31486 ``` 1. Access the httpbin service using _curl_: - ```bash - curl -I http://$INGRESS_HOST/status/200 - ``` - - ```xxx + ```command + $ curl -I http://$INGRESS_HOST/status/200 HTTP/1.1 200 OK server: envoy date: Mon, 29 Jan 2018 04:45:49 GMT @@ -336,11 +306,8 @@ service declaration. 1. Access any other URL that has not been explicitly exposed. You should see a HTTP 404 error - ```bash - curl -I http://$INGRESS_HOST/headers - ``` - - ```xxx + ```command + $ curl -I http://$INGRESS_HOST/headers HTTP/1.1 404 Not Found date: Mon, 29 Jan 2018 04:45:49 GMT server: envoy @@ -357,8 +324,8 @@ service declaration. > The secret MUST be called `istio-ingress-certs` in the `istio-system` namespace, or it will not be mounted and available to the Istio ingress controller. - ```bash - kubectl create -n istio-system secret tls istio-ingress-certs --key /tmp/tls.key --cert /tmp/tls.crt + ```command + $ kubectl create -n istio-system secret tls istio-ingress-certs --key /tmp/tls.key --cert /tmp/tls.crt ``` Note that by default all service accounts in the `istio-system` namespace can access this ingress key/cert, @@ -402,51 +369,39 @@ service declaration. * If your cluster is running in an environment that supports external load balancers, use the ingress' external address: - ```bash - kubectl get ingress secure-ingress -o wide - ``` - - ```xxx + ```command + $ kubectl get ingress secure-ingress -o wide NAME HOSTS ADDRESS PORTS AGE secure-ingress * 130.211.10.121 80 1d ``` - ```bash - export SECURE_INGRESS_HOST=130.211.10.121 + ```command + $ export SECURE_INGRESS_HOST=130.211.10.121 ``` * If load balancers are not supported, use the ingress controller pod's hostIP: - ```bash - kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' - ``` - - ```xxx + ```command + $ kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' 169.47.243.100 ``` along with the istio-ingress service's nodePort for port 443: - ```bash - kubectl -n istio-system get svc istio-ingress - ``` - - ```xxx + ```command + $ kubectl -n istio-system get svc istio-ingress NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingress 10.10.10.155 <pending> 80:31486/TCP,443:32254/TCP 32m ``` - ```bash - export SECURE_INGRESS_HOST=169.47.243.100:32254 + ```command + $ export SECURE_INGRESS_HOST=169.47.243.100:32254 ``` 1. Access the httpbin service using _curl_: - ```bash - curl -I -k https://$SECURE_INGRESS_HOST/status/200 - ``` - - ```xxx + ```command + $ curl -I -k https://$SECURE_INGRESS_HOST/status/200 HTTP/1.1 200 OK server: envoy date: Mon, 29 Jan 2018 04:45:49 GMT @@ -460,11 +415,8 @@ service declaration. 1. Access any other URL that has not been explicitly exposed. You should see a HTTP 404 error - ```bash - curl -I -k https://$SECURE_INGRESS_HOST/headers - ``` - - ```xxx + ```command + $ curl -I -k https://$SECURE_INGRESS_HOST/headers HTTP/1.1 404 Not Found date: Mon, 29 Jan 2018 04:45:49 GMT server: envoy @@ -487,27 +439,27 @@ and may be especially useful when moving existing Kubernetes applications to Ist 1. Remove the `Gateway` configuration. - ```bash - kubectl delete gateway httpbin-gateway + ```command + $ kubectl delete gateway httpbin-gateway ``` 1. Remove the `Ingress` configuration. - ```bash - kubectl delete ingress simple-ingress secure-ingress + ```command + $ kubectl delete ingress simple-ingress secure-ingress ``` 1. Remove the routing rule and secret. - ```bash - istioctl delete virtualservice httpbin - kubectl delete -n istio-system secret istio-ingress-certs + ```command + $ istioctl delete virtualservice httpbin + $ kubectl delete -n istio-system secret istio-ingress-certs ``` 1. Shutdown the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) service. - ```bash - kubectl delete -f samples/httpbin/httpbin.yaml + ```command + $ kubectl delete -f samples/httpbin/httpbin.yaml ``` ## What's next diff --git a/_docs/tasks/traffic-management-v1alpha3/mirroring.md b/_docs/tasks/traffic-management-v1alpha3/mirroring.md index 1df318ab31e8..a134e324f0f0 100644 --- a/_docs/tasks/traffic-management-v1alpha3/mirroring.md +++ b/_docs/tasks/traffic-management-v1alpha3/mirroring.md @@ -153,11 +153,9 @@ EOF Now all traffic should go to `httpbin v1` service. Let's try sending in some traffic: -```bash -export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' -``` -```xxx +```command-output-as-json +$ export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) +$ kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' { "headers": { "Accept": "*/*", @@ -174,19 +172,15 @@ kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers If we check the logs for `v1` and `v2` of our `httpbin` pods, we should see access log entries for only `v1`: -```bash -export V1_POD=$(kubectl get pod -l app=httpbin,version=v1 -o jsonpath={.items..metadata.name}) -kubectl logs -f $V1_POD -c httpbin -``` -```xxx +```command +$ export V1_POD=$(kubectl get pod -l app=httpbin,version=v1 -o jsonpath={.items..metadata.name}) +$ kubectl logs -f $V1_POD -c httpbin 127.0.0.1 - - [07/Mar/2018:19:02:43 +0000] "GET /headers HTTP/1.1" 200 321 "-" "curl/7.35.0" ``` -```bash -export V2_POD=$(kubectl get pod -l app=httpbin,version=v2 -o jsonpath={.items..metadata.name}) -kubectl logs -f $V2_POD -c httpbin -``` -```xxx +```command +$ export V2_POD=$(kubectl get pod -l app=httpbin,version=v2 -o jsonpath={.items..metadata.name}) +$ kubectl logs -f $V2_POD -c httpbin <none> ``` @@ -217,24 +211,20 @@ This route rule specifies we route 100% of the traffic to v1. The last stanza sp Now if we send in traffic: -```bash -kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' +```command +$ kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' ``` We should see access logging for both `v1` and `v2`. The access logs created in `v2` is the mirrored requests that are actually going to `v1`. -```bash -kubectl logs -f $V1_POD -c httpbin -``` -```xxx +```command +$ kubectl logs -f $V1_POD -c httpbin 127.0.0.1 - - [07/Mar/2018:19:02:43 +0000] "GET /headers HTTP/1.1" 200 321 "-" "curl/7.35.0" 127.0.0.1 - - [07/Mar/2018:19:26:44 +0000] "GET /headers HTTP/1.1" 200 321 "-" "curl/7.35.0" ``` -```bash -kubectl logs -f $V2_POD -c httpbin -``` -```xxx +```command +$ kubectl logs -f $V2_POD -c httpbin 127.0.0.1 - - [07/Mar/2018:19:26:44 +0000] "GET /headers HTTP/1.1" 200 361 "-" "curl/7.35.0" ``` @@ -242,16 +232,16 @@ kubectl logs -f $V2_POD -c httpbin 1. Remove the rules. - ```bash - istioctl delete virtualservice httpbin - istioctl delete destinationrule httpbin + ```command + $ istioctl delete virtualservice httpbin + $ istioctl delete destinationrule httpbin ``` 1. Shutdown the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) service and client. - ```bash - kubectl delete deploy httpbin-v1 httpbin-v2 sleep - kubectl delete svc httpbin + ```command + $ kubectl delete deploy httpbin-v1 httpbin-v2 sleep + $ kubectl delete svc httpbin ``` ## What's next diff --git a/_docs/tasks/traffic-management-v1alpha3/request-routing.md b/_docs/tasks/traffic-management-v1alpha3/request-routing.md index 799753048180..59efcda260c0 100644 --- a/_docs/tasks/traffic-management-v1alpha3/request-routing.md +++ b/_docs/tasks/traffic-management-v1alpha3/request-routing.md @@ -30,8 +30,8 @@ you'll need to use `replace` rather than `create` in the following command. 1. Set the default version for all microservices to v1. - ```bash - istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml + ```command + $ istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml ``` > In a Kubernetes deployment of Istio, you can replace `istioctl` @@ -40,11 +40,8 @@ you'll need to use `replace` rather than `create` in the following command. You can display the routes that are defined with the following command: - ```bash - istioctl get virtualservices -o yaml - ``` - - ```yaml + ```command-output-as-yaml + $ istioctl get virtualservices -o yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: @@ -121,16 +118,14 @@ you'll need to use `replace` rather than `create` in the following command. Lets enable the ratings service for test user "jason" by routing productpage traffic to `reviews:v2` instances. - ```bash - istioctl replace -f samples/bookinfo/routing/route-rule-reviews-test-v2.yaml + ```command + $ istioctl replace -f samples/bookinfo/routing/route-rule-reviews-test-v2.yaml ``` Confirm the rule is created: - ```bash - istioctl get virtualservice reviews -o yaml - ``` - ```yaml + ```command-output-as-yaml + $ istioctl get virtualservice reviews -o yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: @@ -172,8 +167,8 @@ all users to v2, optionally in a gradual fashion. We'll explore this in a separa * Remove the application routing rules. - ```bash - istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml + ```command + $ istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md b/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md index 053989119dd2..b5c38dacca21 100644 --- a/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md +++ b/_docs/tasks/traffic-management-v1alpha3/request-timeouts.md @@ -18,8 +18,8 @@ This task shows you how to setup request timeouts in Envoy using Istio. * Initialize the application version routing by running the following command: - ```bash - istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml + ```command + $ istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml ``` ## Request timeouts @@ -131,8 +131,8 @@ the timeout is specified in millisecond (instead of second) units. * Remove the application routing rules. - ```bash - istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml + ```command + $ istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md b/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md index 8f28d002e106..c6510458189c 100644 --- a/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md +++ b/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md @@ -24,8 +24,8 @@ two steps: 50%, 100%. 1. Set the default version for all microservices to v1. - ```bash - istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml + ```command + $ istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml ``` 1. Confirm v1 is the active version of the `reviews` service by opening http://$GATEWAY_URL/productpage in your browser. @@ -35,16 +35,14 @@ two steps: 50%, 100%. 1. First, transfer 50% of the traffic from `reviews:v1` to `reviews:v3` with the following command: - ```bash - istioctl replace -f samples/bookinfo/routing/route-rule-reviews-50-v3.yaml + ```command + $ istioctl replace -f samples/bookinfo/routing/route-rule-reviews-50-v3.yaml ``` Confirm the rule was replaced: - ```bash - istioctl get virtualservice reviews -o yaml - ``` - ```yaml + ```command-output-as-yaml + $ istioctl get virtualservice reviews -o yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: @@ -73,8 +71,8 @@ two steps: 50%, 100%. 1. When version v3 of the `reviews` microservice is considered stable, we can route 100% of the traffic to `reviews:v3`: - ```bash - istioctl replace -f samples/bookinfo/routing/route-rule-reviews-v3.yaml + ```command + $ istioctl replace -f samples/bookinfo/routing/route-rule-reviews-v3.yaml ``` You can now log into the `productpage` as any user and you should always see book reviews @@ -93,8 +91,8 @@ For more about version routing with autoscaling, check out [Canary Deployments u * Remove the application routing rules. - ```bash - istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml + ```command + $ istioctl delete -f samples/bookinfo/routing/route-rule-all-v1.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/traffic-management/circuit-breaking.md b/_docs/tasks/traffic-management/circuit-breaking.md index ac7f9634abb1..1da7e6a7a4dd 100644 --- a/_docs/tasks/traffic-management/circuit-breaking.md +++ b/_docs/tasks/traffic-management/circuit-breaking.md @@ -17,8 +17,8 @@ This task demonstrates the circuit-breaking capability for resilient application * Start the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) sample which will be used as the backend service for our task - ```bash - kubectl apply -f <(istioctl kube-inject --debug -f samples/httpbin/httpbin.yaml) + ```command + $ kubectl apply -f <(istioctl kube-inject --debug -f samples/httpbin/httpbin.yaml) ``` ## Circuit breaker @@ -30,23 +30,21 @@ Let's set up a scenario to demonstrate the circuit-breaking capabilities of Isti 1. Create a default route rule to route all traffic to `v1` of our `httpbin` service: - ```bash - istioctl create -f samples/httpbin/routerules/httpbin-v1.yaml + ```command + $ istioctl create -f samples/httpbin/routerules/httpbin-v1.yaml ``` 1. Create a [destination policy]({{home}}/docs/reference/config/istio.routing.v1alpha1.html#CircuitBreaker) to specify our circuit breaking settings when calling `httpbin` service: - ```bash - istioctl create -f samples/httpbin/destinationpolicies/httpbin-circuit-breaker.yaml + ```command + $ istioctl create -f samples/httpbin/destinationpolicies/httpbin-circuit-breaker.yaml ``` 1. Verify our destination policy was created correctly: - ```bash - istioctl get destinationpolicy - ``` - ```xxx + ```command + $ istioctl get destinationpolicy NAME KIND NAMESPACE httpbin-circuit-breaker DestinationPolicy.v1alpha2.config.istio.io istio-samples ``` @@ -55,17 +53,15 @@ calling `httpbin` service: Now that we've set up rules for calling the `httpbin` service, let's create a client we can use to send traffic to our service and see whether we can trip the circuit breaking policies. We're going to use a simple load-testing client called [fortio](https://github.com/istio/fortio). With this client we can control the number of connections, concurrency, and delays of outgoing HTTP calls. In this step, we'll set up a client that is injected with the istio sidecar proxy so our network interactions are governed by Istio: -```bash -kubectl apply -f <(istioctl kube-inject --debug -f samples/httpbin/sample-client/fortio-deploy.yaml) +```command +$ kubectl apply -f <(istioctl kube-inject --debug -f samples/httpbin/sample-client/fortio-deploy.yaml) ``` Now we should be able to log into that client pod and use the simple fortio tool to call `httpbin`. We'll pass in `-curl` to indicate we just want to make one call: -```bash -FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }') -kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -curl http://httpbin:8000/get -``` -```xxx +```command +$ FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }') +$ kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -curl http://httpbin:8000/get HTTP/1.1 200 OK server: envoy date: Tue, 16 Jan 2018 23:47:00 GMT @@ -98,10 +94,8 @@ You can see the request succeeded! Now, let's break something. In the circuit-breaking settings, we specified `maxConnections: 1` and `httpMaxPendingRequests: 1`. This should mean that if we exceed more than one connection and request concurrently, we should see the istio-proxy open the circuit for further requests/connections. Let's try with two concurrent connections (`-c 2`) and send 20 requests (`-n 20`) -```bash -kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get -``` -```xxx +```command +$ kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get Fortio 0.6.2 running at 0 queries per second, 2->2 procs, for 5s: http://httpbin:8000/get Starting at max qps with 2 thread(s) [gomax 2] for exactly 20 calls (10 per thread + 0) 23:51:10 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) @@ -131,17 +125,15 @@ All done 20 calls (plus 0 warmup) 10.215 ms avg, 187.8 qps We see almost all requests made it through! -```xxx +```plain Code 200 : 19 (95.0 %) Code 503 : 1 (5.0 %) ``` The istio-proxy does allow for some leeway. Let's bring the number of concurrent connections up to 3: -```bash -kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 3 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get -``` -```xxx +```command +$ kubectl exec -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 3 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get Fortio 0.6.2 running at 0 queries per second, 2->2 procs, for 5s: http://httpbin:8000/get Starting at max qps with 3 thread(s) [gomax 2] for exactly 30 calls (10 per thread + 0) 23:51:51 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) @@ -183,17 +175,15 @@ All done 30 calls (plus 0 warmup) 5.336 ms avg, 422.2 qps Now we start to see the circuit breaking behavior we expect. -```xxx +```plain Code 200 : 19 (63.3 %) Code 503 : 11 (36.7 %) ``` Only 63.3% of the requests made it through and the rest were trapped by circuit breaking. We can query the istio-proxy stats to see more: -```bash -kubectl exec -it $FORTIO_POD -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep httpbin | grep pending -``` -```xxx +```command +$ kubectl exec -it $FORTIO_POD -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep httpbin | grep pending cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_active: 0 cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_failure_eject: 0 cluster.out.httpbin.springistio.svc.cluster.local|http|version=v1.upstream_rq_pending_overflow: 12 @@ -206,16 +196,16 @@ We see `12` for the `upstream_rq_pending_overflow` value which means `12` calls 1. Remove the rules. - ```bash - istioctl delete routerule httpbin-default-v1 - istioctl delete destinationpolicy httpbin-circuit-breaker + ```command + $ istioctl delete routerule httpbin-default-v1 + $ istioctl delete destinationpolicy httpbin-circuit-breaker ``` 1. Shutdown the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) service and client. - ```bash - kubectl delete deploy httpbin fortio-deploy - kubectl delete svc httpbin + ```command + $ kubectl delete deploy httpbin fortio-deploy + $ kubectl delete svc httpbin ``` ## What's next diff --git a/_docs/tasks/traffic-management/egress-tcp.md b/_docs/tasks/traffic-management/egress-tcp.md index 2fc616f58d83..dbf38b09d059 100644 --- a/_docs/tasks/traffic-management/egress-tcp.md +++ b/_docs/tasks/traffic-management/egress-tcp.md @@ -18,8 +18,8 @@ This task describes how to configure Istio to expose external TCP services to ap * Start the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) sample application which will be used as a test source for external calls. - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) ``` > any pod that you can execute `curl` from is good enough. @@ -102,29 +102,22 @@ a single `istioctl` command. 1. `kubectl exec` into the pod to be used as the test source. If you are using the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) application, run the following command: - ```bash - kubectl exec -it $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep bash + ```command + $ kubectl exec -it $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep bash ``` 1. Make a request and verify that we can access https://www.wikipedia.org successfully: - ```bash - curl -o /dev/null -s -w "%{http_code}\n" https://www.wikipedia.org - ``` - ```bash + ```command + $ curl -o /dev/null -s -w "%{http_code}\n" https://www.wikipedia.org 200 ``` We should see `200` printed as the output, which is the HTTP code _OK_. 1. Now let's fetch the current number of the articles available on Wikipedia in the English language: - ```bash - curl -s https://en.wikipedia.org/wiki/Main_Page | grep articlecount | grep 'Special:Statistics' - ``` - - The output should be similar to: - - ```bash + ```command + $ curl -s https://en.wikipedia.org/wiki/Main_Page | grep articlecount | grep 'Special:Statistics' <div id="articlecount" style="font-size:85%;"><a href="/wiki/Special:Statistics" title="Special:Statistics">5,563,121</a> articles in <a href="/wiki/English_language" title="English language">English</a></div> ``` @@ -134,14 +127,14 @@ a single `istioctl` command. 1. Remove the egress rules we created. - ```bash - istioctl delete egressrule wikipedia-range1 wikipedia-range2 wikipedia-range3 wikipedia-range4 wikipedia-range5 -n default + ```command + $ istioctl delete egressrule wikipedia-range1 wikipedia-range2 wikipedia-range3 wikipedia-range4 wikipedia-range5 -n default ``` 1. Shutdown the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) application. - ```bash - kubectl delete -f samples/sleep/sleep.yaml + ```command + $ kubectl delete -f samples/sleep/sleep.yaml ``` ## What's next diff --git a/_docs/tasks/traffic-management/egress.md b/_docs/tasks/traffic-management/egress.md index d00d4b0b2b97..22bae2f86b71 100644 --- a/_docs/tasks/traffic-management/egress.md +++ b/_docs/tasks/traffic-management/egress.md @@ -24,8 +24,8 @@ or alternatively, to simply bypass the Istio proxy for a specific range of IPs. * Start the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) sample which will be used as a test source for external calls. - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) ``` Note that any pod that you can `exec` and `curl` from would do. @@ -77,22 +77,22 @@ from within your Istio cluster. In this task we will use 1. Exec into the pod being used as the test source. For example, if you are using the sleep service, run the following commands: - ```bash - export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) - kubectl exec -it $SOURCE_POD -c sleep bash + ```command + $ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) + $ kubectl exec -it $SOURCE_POD -c sleep bash ``` 1. Make a request to the external HTTP service: - ```bash - curl http://httpbin.org/headers + ```command + $ curl http://httpbin.org/headers ``` 1. Make a request to the external HTTPS service. External services of type HTTPS must be accessed over HTTP with the port specified in the request: - ```bash - curl http://www.google.com:443 + ```command + $ curl http://www.google.com:443 ``` ### Setting route rules on an external service @@ -105,12 +105,9 @@ to set a timeout rule on calls to the httpbin.org service. 1. From inside the pod being used as the test source, invoke the `/delay` endpoint of the httpbin.org external service: - ```bash - kubectl exec -it $SOURCE_POD -c sleep bash - time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5 - ``` - - ```bash + ```command + $ kubectl exec -it $SOURCE_POD -c sleep bash + $ time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5 200 real 0m5.024s @@ -139,12 +136,9 @@ to set a timeout rule on calls to the httpbin.org service. 1. Wait a few seconds, then issue the _curl_ request again: - ```bash - kubectl exec -it $SOURCE_POD -c sleep bash - time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5 - ``` - - ```bash + ```command + $ kubectl exec -it $SOURCE_POD -c sleep bash + $ time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5 504 real 0m3.149s @@ -172,63 +166,57 @@ to the sidecar proxy. The values used for internal IP range(s), however, depends on where your cluster is running. For example, with Minikube the range is 10.0.0.1/24, so you would start the sleep service like this: -```bash -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.0.0.1/24) +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.0.0.1/24) ``` On IBM Cloud Private, use: 1. Get your `service_cluster_ip_range` from IBM Cloud Private configuration file under `cluster/config.yaml`. - ```bash - cat cluster/config.yaml | grep service_cluster_ip_range - ``` - - A sample output is as following: - - ```xxx + ```command + $ cat cluster/config.yaml | grep service_cluster_ip_range service_cluster_ip_range: 10.0.0.1/24 ``` 1. Inject the `service_cluster_ip_range` to your application profile via `--includeIPRanges` to limit Istio's traffic interception to the service cluster IP range. - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.0.0.1/24) + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.0.0.1/24) ``` On IBM Cloud Container Service, use: -```bash -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=172.30.0.0/16,172.20.0.0/16,10.10.10.0/24) +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=172.30.0.0/16,172.20.0.0/16,10.10.10.0/24) ``` On Google Container Engine (GKE) the ranges are not fixed, so you will need to run the `gcloud container clusters describe` command to determine the ranges to use. For example: -```bash -gcloud container clusters describe <cluster_name> --zone <zone> | grep -e clusterIpv4Cidr -e servicesIpv4Cidr -``` -```xxx +```command +$ gcloud container clusters describe <cluster_name> --zone <zone> | grep -e clusterIpv4Cidr -e servicesIpv4Cidr clusterIpv4Cidr: 10.4.0.0/14 servicesIpv4Cidr: 10.7.240.0/20 ``` -```bash -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.4.0.0/14,10.7.240.0/20) + +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.4.0.0/14,10.7.240.0/20) ``` On Azure Container Service(ACS), use: -```bash -kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.244.0.0/16,10.240.0.0/16) +```command +$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.244.0.0/16,10.240.0.0/16) ``` After starting your service this way, the Istio sidecar will only intercept and manage internal requests within the cluster. Any external request will simply bypass the sidecar and go straight to its intended destination. -```bash -export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -kubectl exec -it $SOURCE_POD -c sleep curl http://httpbin.org/headers +```command +$ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) +$ kubectl exec -it $SOURCE_POD -c sleep curl http://httpbin.org/headers ``` ## Understanding what happened @@ -251,15 +239,15 @@ cloud provider specific knowledge and configuration. 1. Remove the rules. - ```bash - istioctl delete egressrule httpbin-egress-rule google-egress-rule - istioctl delete routerule httpbin-timeout-rule + ```command + $ istioctl delete egressrule httpbin-egress-rule google-egress-rule + $ istioctl delete routerule httpbin-timeout-rule ``` 1. Shutdown the [sleep](https://github.com/istio/istio/tree/master/samples/sleep) service. - ```bash - kubectl delete -f samples/sleep/sleep.yaml + ```command + $ kubectl delete -f samples/sleep/sleep.yaml ``` ## Egress Rules and Access Control diff --git a/_docs/tasks/traffic-management/fault-injection.md b/_docs/tasks/traffic-management/fault-injection.md index d2bbf889e4d8..545449f972d1 100644 --- a/_docs/tasks/traffic-management/fault-injection.md +++ b/_docs/tasks/traffic-management/fault-injection.md @@ -22,9 +22,9 @@ This task shows how to inject delays and test the resiliency of your application > This assumes you don't have any routes set yet. If you've already created conflicting route rules for the sample, you'll need to use `replace` rather than `create` in one or both of the following commands. - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml - istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml + $ istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml ``` > This task assumes you are deploying the application on Kubernetes. @@ -45,16 +45,14 @@ continue without any errors. 1. Create a fault injection rule to delay traffic coming from user "jason" (our test user) - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-ratings-test-delay.yaml + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-ratings-test-delay.yaml ``` Confirm the rule is created: - ```bash - istioctl get routerule ratings-test-delay -o yaml - ``` - ```yaml + ```command-output-as-yaml + $ istioctl get routerule ratings-test-delay -o yaml apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: @@ -124,22 +122,20 @@ message. 1. Remove the fault delay injection rule before attempting the fault abort rule - ```bash - istioctl delete -f samples/bookinfo/kube/route-rule-ratings-test-delay.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/route-rule-ratings-test-delay.yaml ``` 1. Create the fault injection rule to send an HTTP abort for user "jason" - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-ratings-test-abort.yaml + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-ratings-test-abort.yaml ``` Confirm the rule is created - ```bash - istioctl get routerules ratings-test-abort -o yaml - ``` - ```yaml + ```command-output-as-yaml + $ istioctl get routerules ratings-test-abort -o yaml apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: @@ -174,11 +170,11 @@ message. * Remove the application routing rules: - ```bash - istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml - istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml - istioctl delete -f samples/bookinfo/kube/route-rule-ratings-test-delay.yaml - istioctl delete -f samples/bookinfo/kube/route-rule-ratings-test-abort.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml + $ istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml + $ istioctl delete -f samples/bookinfo/kube/route-rule-ratings-test-delay.yaml + $ istioctl delete -f samples/bookinfo/kube/route-rule-ratings-test-abort.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/traffic-management/ingress.md b/_docs/tasks/traffic-management/ingress.md index 1f2ff540b0e0..f96da3332235 100644 --- a/_docs/tasks/traffic-management/ingress.md +++ b/_docs/tasks/traffic-management/ingress.md @@ -38,14 +38,14 @@ The following are known limitations of Istio Ingress: If you installed the [Istio-Initializer]({{home}}/docs/setup/kubernetes/sidecar-injection.html#automatic-sidecar-injection), do - ```bash - kubectl apply -f samples/httpbin/httpbin.yaml + ```command + $ kubectl apply -f samples/httpbin/httpbin.yaml ``` Without the Istio-Initializer: - ```bash - kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) + ```command + $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) ``` ## Configuring ingress (HTTP) @@ -86,51 +86,39 @@ The following are known limitations of Istio Ingress: * If your cluster is running in an environment that supports external load balancers, use the ingress' external address: - ```bash - kubectl get ingress simple-ingress -o wide - ``` - - ```xxx + ```command + $ kubectl get ingress simple-ingress -o wide NAME HOSTS ADDRESS PORTS AGE simple-ingress * 130.211.10.121 80 1d ``` - ```bash - export INGRESS_HOST=130.211.10.121 + ```command + $ export INGRESS_HOST=130.211.10.121 ``` * If load balancers are not supported, use the ingress controller pod's hostIP: - ```bash - kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' - ``` - - ```xxx + ```command + $ kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' 169.47.243.100 ``` along with the istio-ingress service's nodePort for port 80: - ```bash - kubectl -n istio-system get svc istio-ingress - ``` - - ```xxx + ```command + $ kubectl -n istio-system get svc istio-ingress NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingress 10.10.10.155 <pending> 80:31486/TCP,443:32254/TCP 32m ``` - ```bash - export INGRESS_HOST=169.47.243.100:31486 + ```command + $ export INGRESS_HOST=169.47.243.100:31486 ``` 1. Access the httpbin service using _curl_: - ```bash - curl -I http://$INGRESS_HOST/status/200 - ``` - - ```xxx + ```command + $ curl -I http://$INGRESS_HOST/status/200 HTTP/1.1 200 OK server: envoy date: Mon, 29 Jan 2018 04:45:49 GMT @@ -144,11 +132,8 @@ The following are known limitations of Istio Ingress: 1. Access any other URL that has not been explicitly exposed. You should see a HTTP 404 error - ```bash - curl -I http://$INGRESS_HOST/headers - ``` - - ```xxx + ```command + $ curl -I http://$INGRESS_HOST/headers HTTP/1.1 404 Not Found date: Mon, 29 Jan 2018 04:45:49 GMT server: envoy @@ -161,8 +146,8 @@ The following are known limitations of Istio Ingress: A private key and certificate can be created for testing using [OpenSSL](https://www.openssl.org/). - ```bash - openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=foo.bar.com" + ```command + $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=foo.bar.com" ``` 1. Create the secret @@ -172,8 +157,8 @@ The following are known limitations of Istio Ingress: > The secret must be called `istio-ingress-certs` in `istio-system` namespace, for it to be mounted on Istio Ingress. - ```bash - kubectl create -n istio-system secret tls istio-ingress-certs --key /tmp/tls.key --cert /tmp/tls.crt + ```command + $ kubectl create -n istio-system secret tls istio-ingress-certs --key /tmp/tls.key --cert /tmp/tls.crt ``` 1. Create the Ingress specification for the httpbin service @@ -213,51 +198,39 @@ The following are known limitations of Istio Ingress: * If your cluster is running in an environment that supports external load balancers, use the ingress' external address: - ```bash - kubectl get ingress secure-ingress -o wide - ``` - - ```xxx + ```command + $ kubectl get ingress secure-ingress -o wide NAME HOSTS ADDRESS PORTS AGE secure-ingress * 130.211.10.121 80 1d ``` - ```bash - export INGRESS_HOST=130.211.10.121 + ```command + $ export INGRESS_HOST=130.211.10.121 ``` * If load balancers are not supported, use the ingress controller pod's hostIP: - ```bash - kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' - ``` - - ```xxx + ```command + $ kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' 169.47.243.100 ``` along with the istio-ingress service's nodePort for port 443: - ```bash - kubectl -n istio-system get svc istio-ingress - ``` - - ```xxx + ```command + $ kubectl -n istio-system get svc istio-ingress NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingress 10.10.10.155 <pending> 80:31486/TCP,443:32254/TCP 32m ``` - ```bash - export INGRESS_HOST=169.47.243.100:32254 + ```command + $ export INGRESS_HOST=169.47.243.100:32254 ``` 1. Access the httpbin service using _curl_: - ```bash - curl -I -k https://$INGRESS_HOST/status/200 - ``` - - ```xxx + ```command + $ curl -I -k https://$INGRESS_HOST/status/200 HTTP/1.1 200 OK server: envoy date: Mon, 29 Jan 2018 04:45:49 GMT @@ -271,11 +244,8 @@ The following are known limitations of Istio Ingress: 1. Access any other URL that has not been explicitly exposed. You should see a HTTP 404 error - ```bash - curl -I -k https://$INGRESS_HOST/headers - ``` - - ```xxx + ```command + $ curl -I -k https://$INGRESS_HOST/headers HTTP/1.1 404 Not Found date: Mon, 29 Jan 2018 04:45:49 GMT server: envoy @@ -291,11 +261,8 @@ The following are known limitations of Istio Ingress: these RBAC set up to only allow istio-ingress-service-account to access ingress key/cert. We can use `kubectl` to list all secrets in namespace istio-system that we need to protect using RBAC. - ```bash - kubectl get secrets -n istio-system - ``` - This produces the following output: - ```xxx + ```command + $ kubectl get secrets -n istio-system NAME TYPE DATA AGE istio-ingress-certs kubernetes.io/tls 2 7d istio.istio-ingress-service-account istio.io/key-and-cert 3 7d @@ -306,16 +273,16 @@ The following are known limitations of Istio Ingress: Record `ClusterRole` istio-mixer-istio-system and istio-pilot-istio-system. We will refer to these copies when we redefine them to avoid breaking access permissions to other resources. - ```bash - kubectl describe ClusterRole istio-mixer-istio-system - kubectl describe ClusterRole istio-pilot-istio-system + ```command + $ kubectl describe ClusterRole istio-mixer-istio-system + $ kubectl describe ClusterRole istio-pilot-istio-system ``` Delete existing `ClusterRoleBindings` and `ClusterRole`. - ```bash - kubectl delete ClusterRoleBinding istio-pilot-admin-role-binding-istio-system - kubectl delete ClusterRoleBinding istio-mixer-admin-role-binding-istio-system - kubectl delete ClusterRole istio-mixer-istio-system + ```command + $ kubectl delete ClusterRoleBinding istio-pilot-admin-role-binding-istio-system + $ kubectl delete ClusterRoleBinding istio-mixer-admin-role-binding-istio-system + $ kubectl delete ClusterRole istio-mixer-istio-system ``` As istio-pilot-istio-system is also bound to istio-ingress-service-account, we will delete istio-pilot-istio-system in next step. @@ -354,17 +321,17 @@ The following are known limitations of Istio Ingress: apiGroup: rbac.authorization.k8s.io ``` - ```bash - kubectl apply -f istio-mixer-istio-system.yaml + ```command + $ kubectl apply -f istio-mixer-istio-system.yaml ``` 1. Update RBAC set up for istio-pilot-service-account and istio-ingress-service-account Delete existing `ClusterRoleBinding` and `ClusterRole`. - ```bash - kubectl delete clusterrolebinding istio-ingress-admin-role-binding-istio-system - kubectl delete ClusterRole istio-pilot-istio-system + ```command + $ kubectl delete clusterrolebinding istio-ingress-admin-role-binding-istio-system + $ kubectl delete ClusterRole istio-pilot-istio-system ``` Create istio-pilot-istio-system.yaml, which allows istio-pilot-service-account to read @@ -401,8 +368,8 @@ The following are known limitations of Istio Ingress: apiGroup: rbac.authorization.k8s.io ``` - ```bash - kubectl apply -f istio-pilot-istio-system.yaml + ```command + $ kubectl apply -f istio-pilot-istio-system.yaml ``` Create istio-ingress-istio-system.yaml which allows istio-ingress-service-account to read @@ -443,15 +410,15 @@ The following are known limitations of Istio Ingress: apiGroup: rbac.authorization.k8s.io ``` - ```bash - kubectl apply -f istio-ingress-istio-system.yaml + ```command + $ kubectl apply -f istio-ingress-istio-system.yaml ``` 1. Update RBAC set up for istio-citadel-service-account Record `ClusterRole` istio-citadel-istio-system. - ```bash - kubectl describe ClusterRole istio-citadel-istio-system + ```command + $ kubectl describe ClusterRole istio-citadel-istio-system ``` Create istio-citadel-istio-system.yaml, which updates existing `ClusterRole` istio-citadel-istio-system @@ -486,26 +453,20 @@ The following are known limitations of Istio Ingress: name: istio-citadel-istio-system apiGroup: rbac.authorization.k8s.io ``` - ```bash - kubectl apply -f istio-citadel-istio-system.yaml + ```command + $ kubectl apply -f istio-citadel-istio-system.yaml ``` 1. Verify that the new `ClusterRoles` work as expected - ```bash - kubectl auth can-i get secret/istio-ingress-certs --as system:serviceaccount:istio-system:istio-ingress-service-account -n istio-system - ``` - whose output should be - ```xxx + ```command + $ kubectl auth can-i get secret/istio-ingress-certs --as system:serviceaccount:istio-system:istio-ingress-service-account -n istio-system yes ``` In this command, we can replace verb "get" with "list" or "watch", and the output should always be "yes". Now let us test with other service accounts. - ```bash - kubectl auth can-i get secret/istio-ingress-certs --as system:serviceaccount:istio-system:istio-pilot-service-account -n istio-system - ``` - whose output should be - ```xxx + ```command + $ kubectl auth can-i get secret/istio-ingress-certs --as system:serviceaccount:istio-system:istio-pilot-service-account -n istio-system no - Unknown user "system:serviceaccount:istio-system:istio-pilot-service-account" ``` In this command, we can replace service account with istio-mixer-service-account, or @@ -515,11 +476,8 @@ The following are known limitations of Istio Ingress: Accessibility to secret resources except istio-ingress-certs should remain the same for istio-citadel-service-account, istio-ingress-service-account, istio-pilot-service-account and istio-mixer-service-account. - ```bash - kubectl auth can-i get secret/istio-citadel-service-account-token-r14xm --as system:serviceaccount:istio-system:istio-citadel-service-account -n istio-system - ``` - whose output should be - ```xxx + ```command + $ kubectl auth can-i get secret/istio-citadel-service-account-token-r14xm --as system:serviceaccount:istio-system:istio-citadel-service-account -n istio-system yes ``` @@ -600,15 +558,15 @@ an Istio route rule. 1. Remove the secret and Ingress Resource definitions. - ```bash - kubectl delete ingress simple-ingress secure-ingress - kubectl delete -n istio-system secret istio-ingress-certs + ```command + $ kubectl delete ingress simple-ingress secure-ingress + $ kubectl delete -n istio-system secret istio-ingress-certs ``` 1. Shutdown the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) service. - ```bash - kubectl delete -f samples/httpbin/httpbin.yaml + ```command + $ kubectl delete -f samples/httpbin/httpbin.yaml ``` ## What's next diff --git a/_docs/tasks/traffic-management/mirroring.md b/_docs/tasks/traffic-management/mirroring.md index 0d8365dd6721..265ef8c0df19 100644 --- a/_docs/tasks/traffic-management/mirroring.md +++ b/_docs/tasks/traffic-management/mirroring.md @@ -137,10 +137,9 @@ EOF Now all traffic should go to `httpbin v1` service. Let's try sending in some traffic: -```bash -export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' - +```command-output-as-json +$ export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) +$ kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' { "headers": { "Accept": "*/*", @@ -157,10 +156,8 @@ kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers If we check the logs for `v1` and `v2` of our `httpbin` pods, we should see access log entries for only `v1`: -```bash -kubectl logs -f httpbin-v1-2113278084-98whj -c httpbin -``` -```xxx +```command +$ kubectl logs -f httpbin-v1-2113278084-98whj -c httpbin 127.0.0.1 - - [07/Feb/2018:00:07:39 +0000] "GET /headers HTTP/1.1" 200 349 "-" "curl/7.35.0" ``` @@ -197,8 +194,8 @@ The last stanza specifies we want to mirror to the `httpbin v2` service. When tr Now if we send in traffic: -```bash -kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' +```command +$ kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' ``` We should see access logging for both `v1` and `v2`. The access logs created in `v2` is the mirrored requests that are actually going to `v1`. @@ -207,16 +204,16 @@ We should see access logging for both `v1` and `v2`. The access logs created in 1. Remove the rules. - ```bash - istioctl delete routerule mirror-traffic-to-httbin-v2 - istioctl delete routerule httpbin-default-v1 + ```command + $ istioctl delete routerule mirror-traffic-to-httbin-v2 + $ istioctl delete routerule httpbin-default-v1 ``` 1. Shutdown the [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) service and client. - ```bash - kubectl delete deploy httpbin-v1 httpbin-v2 sleep - kubectl delete svc httpbin + ```command + $ kubectl delete deploy httpbin-v1 httpbin-v2 sleep + $ kubectl delete svc httpbin ``` ## What's next diff --git a/_docs/tasks/traffic-management/request-routing.md b/_docs/tasks/traffic-management/request-routing.md index 956ddb16cb6e..34a37bf35941 100644 --- a/_docs/tasks/traffic-management/request-routing.md +++ b/_docs/tasks/traffic-management/request-routing.md @@ -38,8 +38,8 @@ you'll need to use `replace` rather than `create` in one or both of the followin 1. Set the default version for all microservices to v1. - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml ``` > In a Kubernetes deployment of Istio, you can replace `istioctl` @@ -48,10 +48,8 @@ you'll need to use `replace` rather than `create` in one or both of the followin You can display the routes that are defined with the following command: - ```bash - istioctl get routerules -o yaml - ``` - ```yaml + ```command-output-as-yaml + $ istioctl get routerules -o yaml apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: @@ -123,16 +121,14 @@ you'll need to use `replace` rather than `create` in one or both of the followin Lets enable the ratings service for test user "jason" by routing productpage traffic to `reviews:v2` instances. - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml ``` Confirm the rule is created: - ```bash - istioctl get routerule reviews-test-v2 -o yaml - ``` - ```yaml + ```command-output-as-yaml + $ istioctl get routerule reviews-test-v2 -o yaml apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: @@ -171,9 +167,9 @@ all users to v2, optionally in a gradual fashion. We'll explore this in a separa * Remove the application routing rules. - ```bash - istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml - istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml + $ istioctl delete -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/traffic-management/request-timeouts.md b/_docs/tasks/traffic-management/request-timeouts.md index a6ae628396fe..fca08844b098 100644 --- a/_docs/tasks/traffic-management/request-timeouts.md +++ b/_docs/tasks/traffic-management/request-timeouts.md @@ -18,8 +18,8 @@ This task shows you how to setup request timeouts in Envoy using Istio. * Initialize the application version routing by running the following command: - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml ``` > This task assumes you are deploying the application on Kubernetes. @@ -134,8 +134,8 @@ the timeout is specified in millisecond (instead of second) units. * Remove the application routing rules. - ```bash - istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_docs/tasks/traffic-management/traffic-shifting.md b/_docs/tasks/traffic-management/traffic-shifting.md index 706c11ad5406..eb33cf3ab60d 100644 --- a/_docs/tasks/traffic-management/traffic-shifting.md +++ b/_docs/tasks/traffic-management/traffic-shifting.md @@ -31,8 +31,8 @@ the Consul-based runtime). 1. Set the default version for all microservices to v1. - ```bash - istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml + ```command + $ istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml ``` 1. Confirm v1 is the active version of the `reviews` service by opening http://$GATEWAY_URL/productpage in your browser. @@ -43,24 +43,22 @@ the Consul-based runtime). > If you previously ran the [request routing](./request-routing.html) task, you may need to either log out as test user "jason" or delete the test rules that were created exclusively for him: - ```bash - istioctl delete routerule reviews-test-v2 + ```command + $ istioctl delete routerule reviews-test-v2 ``` 1. First, transfer 50% of the traffic from `reviews:v1` to `reviews:v3` with the following command: - ```bash - istioctl replace -f samples/bookinfo/kube/route-rule-reviews-50-v3.yaml + ```command + $ istioctl replace -f samples/bookinfo/kube/route-rule-reviews-50-v3.yaml ``` Notice that we are using `istioctl replace` instead of `create`. Confirm the rule was replaced: - ```bash - istioctl get routerule reviews-default -o yaml - ``` - ```yaml + ```command-output-as-yaml + $ istioctl get routerule reviews-default -o yaml apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: @@ -86,8 +84,8 @@ the Consul-based runtime). 1. When version v3 of the `reviews` microservice is considered stable, we can route 100% of the traffic to `reviews:v3`: - ```bash - istioctl replace -f samples/bookinfo/kube/route-rule-reviews-v3.yaml + ```command + $ istioctl replace -f samples/bookinfo/kube/route-rule-reviews-v3.yaml ``` You can now log into the `productpage` as any user and you should always see book reviews @@ -106,8 +104,8 @@ For more about version routing with autoscaling, check out [Canary Deployments u * Remove the application routing rules. - ```bash - istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml + ```command + $ istioctl delete -f samples/bookinfo/kube/route-rule-all-v1.yaml ``` * If you are not planning to explore any follow-on tasks, refer to the diff --git a/_faq/mixer/mixer-self-monitoring.md b/_faq/mixer/mixer-self-monitoring.md index bf8693d4f37c..d771d3a0db6a 100644 --- a/_faq/mixer/mixer-self-monitoring.md +++ b/_faq/mixer/mixer-self-monitoring.md @@ -16,8 +16,8 @@ function: Mixer logs can be accessed via a `kubectl logs` command, as follows: -```bash -kubectl -n istio-system logs $(kubectl -n istio-system get pods -listio=mixer -o jsonpath='{.items[0].metadata.name}') mixer +```command +$ kubectl -n istio-system logs $(kubectl -n istio-system get pods -listio=mixer -o jsonpath='{.items[0].metadata.name}') mixer ``` Mixer trace generation is controlled by the command-line flag `traceOutput`. If the flag value is set to `STDOUT` or `STDERR` trace data will be written diff --git a/_faq/mixer/seeing-mixer-config.md b/_faq/mixer/seeing-mixer-config.md index c279102124a8..3297f36155ef 100644 --- a/_faq/mixer/seeing-mixer-config.md +++ b/_faq/mixer/seeing-mixer-config.md @@ -13,13 +13,8 @@ server](https://kubernetes.io/docs/admin/kube-apiserver/) for the resources. To see the list of all rules, execute the following: -```bash -kubectl get rules --all-namespaces -``` - -Output will be similar to: - -```xxx +```command +$ kubectl get rules --all-namespaces NAMESPACE NAME KIND default mongoprom rule.v1alpha2.config.istio.io istio-system promhttp rule.v1alpha2.config.istio.io @@ -29,8 +24,8 @@ istio-system stdio rule.v1alpha2.config.istio.io To see an individual rule configuration, execute the following: -```bash -kubectl -n <namespace> get rules <name> -o yaml +```command +$ kubectl -n <namespace> get rules <name> -o yaml ``` ## Handlers @@ -41,13 +36,8 @@ for adapters. First, identify the list of adapter kinds: -```bash -kubectl get crd -listio=mixer-adapter -``` - -The output will be similar to: - -```xxx +```command +$ kubectl get crd -listio=mixer-adapter NAME KIND deniers.config.istio.io CustomResourceDefinition.v1beta1.apiextensions.k8s.io listcheckers.config.istio.io CustomResourceDefinition.v1beta1.apiextensions.k8s.io @@ -62,21 +52,21 @@ svcctrls.config.istio.io CustomResourceDefinition.v1beta1.apiextensions.k8 Then, for each adapter kind in that list, issue the following command: -```bash -kubectl get <adapter kind name> --all-namespaces +```command +$ kubectl get <adapter kind name> --all-namespaces ``` Output for `stdios` will be similar to: -```xxx +```plain NAMESPACE NAME KIND istio-system handler stdio.v1alpha2.config.istio.io ``` To see an individual handler configuration, execute the following: -```bash -kubectl -n <namespace> get <adapter kind name> <name> -o yaml +```command +$ kubectl -n <namespace> get <adapter kind name> <name> -o yaml ``` ## Instances @@ -87,13 +77,8 @@ for instances. First, identify the list of instance kinds: -```bash -kubectl get crd -listio=mixer-instance -``` - -The output will be similar to: - -```xxx +```command +$ kubectl get crd -listio=mixer-instance NAME KIND checknothings.config.istio.io CustomResourceDefinition.v1beta1.apiextensions.k8s.io listentries.config.istio.io CustomResourceDefinition.v1beta1.apiextensions.k8s.io @@ -105,13 +90,13 @@ reportnothings.config.istio.io CustomResourceDefinition.v1beta1.apiextensions. Then, for each instance kind in that list, issue the following command: -```bash -kubectl get <instance kind name> --all-namespaces +```command +$ kubectl get <instance kind name> --all-namespaces ``` Output for `metrics` will be similar to: -```xxx +```plain NAMESPACE NAME KIND default mongoreceivedbytes metric.v1alpha2.config.istio.io default mongosentbytes metric.v1alpha2.config.istio.io @@ -125,6 +110,6 @@ istio-system tcpbytesent metric.v1alpha2.config.istio.io To see an individual instance configuration, execute the following: -```bash -kubectl -n <namespace> get <instance kind name> <name> -o yaml +```command +$ kubectl -n <namespace> get <instance kind name> <name> -o yaml ``` diff --git a/_faq/security/accessing-control-services.md b/_faq/security/accessing-control-services.md index cf3e1ba826da..0144fe1553ef 100644 --- a/_faq/security/accessing-control-services.md +++ b/_faq/security/accessing-control-services.md @@ -10,9 +10,9 @@ already contains `kubernetes.default.svc.cluster.local`, which is the default service name of the Kubernetes API server. For a quick reference, here are commands to edit Istio configmap and to restart pilot. -```bash -kubectl edit configmap -n istio-system istio -kubectl delete pods -n istio-system -l istio=pilot +```command +$ kubectl edit configmap -n istio-system istio +$ kubectl delete pods -n istio-system -l istio=pilot ``` > Do not use this approach to disable mTLS for services that are managed diff --git a/_faq/security/cert-lifetime-config.md b/_faq/security/cert-lifetime-config.md index 88fc51a36d72..98152ef4bbd0 100644 --- a/_faq/security/cert-lifetime-config.md +++ b/_faq/security/cert-lifetime-config.md @@ -16,7 +16,7 @@ Modify the `istio-auth.yaml` file to customize the Citadel configuration. The following modification specifies that the Istio certificates for workloads running in Kubernetes has 1 hours lifetime. Besides that, the maximum allowed Istio certificate lifetime is 48 hours. -```bash +```plain ... kind: Deployment ... @@ -45,7 +45,7 @@ To customize this configuration, the argument for the node agent service should After [setting up the machines]({{home}}/docs/setup/kubernetes/mesh-expansion.html#setting-up-the-machines) for Istio mesh expansion, modify the file `/lib/systemd/system/istio-auth-node-agent.service` on the VMs or bare metal hosts: -```bash +```plain ... [Service] ExecStart=/usr/local/bin/node_agent --workload-cert-ttl=24h # Specify certificate lifetime for workloads on this machine. diff --git a/_faq/security/enabling-disabling-mtls.md b/_faq/security/enabling-disabling-mtls.md index 5ddf934e71a1..0c5718b5306c 100644 --- a/_faq/security/enabling-disabling-mtls.md +++ b/_faq/security/enabling-disabling-mtls.md @@ -9,14 +9,14 @@ uninstalling and re-installing Istio. If you are an advanced user and understand the risks you can also do the following: -```bash -kubectl edit configmap -n istio-system istio +```command +$ kubectl edit configmap -n istio-system istio ``` comment out or uncomment `authPolicy: MUTUAL_TLS` to toggle mTLS and then -```bash -kubectl delete pods -n istio-system -l istio=pilot +```command +$ kubectl delete pods -n istio-system -l istio=pilot ``` to restart Pilot, after a few seconds (depending on your `*RefreshDelay`) your diff --git a/_faq/setup/k8s-checking-cluster-alpha-features.md b/_faq/setup/k8s-checking-cluster-alpha-features.md index 29e7bedb4290..68adbafacea8 100644 --- a/_faq/setup/k8s-checking-cluster-alpha-features.md +++ b/_faq/setup/k8s-checking-cluster-alpha-features.md @@ -9,8 +9,8 @@ Automatic sidecar injection requires the Run the following command to check if the initializer has been enabled (empty output indicates that initializers are not enabled): -```bash -kubectl api-versions | grep admissionregistration +```command +$ kubectl api-versions | grep admissionregistration ``` In addition, the Kubernetes API server must be started with the Initializer plugin [enabled](https://kubernetes.io/docs/admin/extensible-admission-controllers/#enable-initializers-alpha-feature). Failure to enable the `Initializer` plugin will result in the following error when trying to create the initializer deployment. diff --git a/_help/troubleshooting.md b/_help/troubleshooting.md index 25aa02f177a6..97b7a5becd27 100644 --- a/_help/troubleshooting.md +++ b/_help/troubleshooting.md @@ -16,29 +16,34 @@ Oh no! You're having trouble? Below is a list of solutions to common problems. Verifying connectivity to Pilot is a useful troubleshooting step. Every proxy container in the service mesh should be able to communicate with Pilot. This can be accomplished in a few simple steps: 1. Get the name of the Istio Ingress pod: -```bash -INGRESS_POD_NAME=$(kubectl get po -n istio-system | grep ingress\- | awk '{print$1}') + +```command +$ INGRESS_POD_NAME=$(kubectl get po -n istio-system | grep ingress\- | awk '{print$1}') ``` 1. Exec into the Istio Ingress pod: -```bash -kubectl exec -it $INGRESS_POD_NAME -n istio-system /bin/bash + +```command +$ kubectl exec -it $INGRESS_POD_NAME -n istio-system /bin/bash ``` 1. Unless you installed Istio using the debug proxy image (`istioctl kube-inject --debug=true`), you need to install curl. -```bash -apt-get update && apt-get install -y curl + +```command +$ apt-get update && apt-get install -y curl ``` 1. Test connectivity to Pilot using cURL. The following example cURL's the v1 registration API using default Pilot configuration parameters and mTLS enabled: -```bash -curl -k --cert /etc/certs/cert-chain.pem --cacert /etc/certs/root-cert.pem --key /etc/certs/key.pem https://istio-pilot:15003/v1/registration + +```command +$ curl -k --cert /etc/certs/cert-chain.pem --cacert /etc/certs/root-cert.pem --key /etc/certs/key.pem https://istio-pilot:15003/v1/registration ``` If mTLS is disabled: -```bash -curl http://istio-pilot:15003/v1/registration + +```command +$ curl http://istio-pilot:15003/v1/registration ``` You should receive a response listing the "service-key" and "hosts" for each service in the mesh. @@ -54,10 +59,13 @@ when you select a very long date range in Zipkin you will see the traces appeari You can also confirm this problem by comparing the date inside a docker container to outside: -```bash -docker run --entrypoint date gcr.io/istio-testing/ubuntu-16-04-slave:latest +```command +$ docker run --entrypoint date gcr.io/istio-testing/ubuntu-16-04-slave:latest Sun Jun 11 11:44:18 UTC 2017 -date -u +``` + +```command +$ date -u Thu Jun 15 02:25:42 UTC 2017 ``` @@ -70,7 +78,7 @@ will need to set the [proxy_http_version](https://nginx.org/en/docs/http/ngx_htt Example config: -```xxxx +```plain upstream http_backend { server 127.0.0.1:8080; @@ -131,8 +139,8 @@ Check these metrics. In Kubernetes environments, execute the following command: - ```bash - kubectl -n istio-system port-forward <mixer pod> 9093 & + ```command + $ kubectl -n istio-system port-forward <mixer pod> 9093 & ``` 1. Verify successful report calls. @@ -142,7 +150,7 @@ Check these metrics. You should see something like: - ```xxxx + ```plain grpc_server_handled_total{grpc_code="OK",grpc_method="Report",grpc_service="istio.mixer.v1.Mixer",grpc_type="unary"} 68 ``` @@ -159,13 +167,8 @@ or [manual]({{home}}/docs/setup/kubernetes/sidecar-injection.html#manual-sidecar In Kubernetes environments, issue the following command: - ```bash - kubectl get rules --all-namespaces - ``` - - With the default configuration, you should see something like: - - ```bash + ```command + $ kubectl get rules --all-namespaces NAMESPACE NAME KIND istio-system promhttp rule.v1alpha2.config.istio.io istio-system promtcp rule.v1alpha2.config.istio.io @@ -182,13 +185,8 @@ or [manual]({{home}}/docs/setup/kubernetes/sidecar-injection.html#manual-sidecar In Kubernetes environments, issue the following command: - ```bash - kubectl get prometheuses.config.istio.io --all-namespaces - ``` - - The expected output is: - - ```bash + ```command + $ kubectl get prometheuses.config.istio.io --all-namespaces NAMESPACE NAME KIND istio-system handler prometheus.v1alpha2.config.istio.io ``` @@ -201,13 +199,8 @@ or [manual]({{home}}/docs/setup/kubernetes/sidecar-injection.html#manual-sidecar In Kubernetes environments, issue the following command: - ```bash - kubectl get metrics.config.istio.io --all-namespaces - ``` - - The expected output is: - - ```bash + ```command + $ kubectl get metrics.config.istio.io --all-namespaces NAMESPACE NAME KIND istio-system requestcount metric.v1alpha2.config.istio.io istio-system requestduration metric.v1alpha2.config.istio.io @@ -237,7 +230,7 @@ or [manual]({{home}}/docs/setup/kubernetes/sidecar-injection.html#manual-sidecar You should find something like: - ```bash + ```plain mixer_config_resolve_count{error="false",target="details.default.svc.cluster.local"} 56 mixer_config_resolve_count{error="false",target="ingress.istio-system.svc.cluster.local"} 67 mixer_config_resolve_count{error="false",target="mongodb.default.svc.cluster.local"} 18 @@ -255,8 +248,8 @@ or [manual]({{home}}/docs/setup/kubernetes/sidecar-injection.html#manual-sidecar In Kubernetes environments, retrieve the Mixer logs via: - ```bash - kubectl -n istio-system logs <mixer pod> mixer + ```command + $ kubectl -n istio-system logs <mixer pod> mixer ``` Look for errors related to your configuration or your service in the @@ -276,7 +269,7 @@ More on viewing Mixer configuration can be found [here]({{home}}/help/faq/mixer. You should find something like: - ```xxxx + ```plain mixer_adapter_dispatch_count{adapter="prometheus",error="false",handler="handler.prometheus.istio-system",meshFunction="metric",response_code="OK"} 114 mixer_adapter_dispatch_count{adapter="prometheus",error="true",handler="handler.prometheus.default",meshFunction="metric",response_code="INTERNAL"} 4 mixer_adapter_dispatch_count{adapter="stdio",error="false",handler="handler.stdio.istio-system",meshFunction="logentry",response_code="OK"} 104 @@ -295,8 +288,8 @@ More on viewing Mixer configuration can be found [here]({{home}}/help/faq/mixer. In Kubernetes environment, check the Mixer logs via: - ```bash - kubectl -n istio-system logs <mixer pod> mixer + ```command + $ kubectl -n istio-system logs <mixer pod> mixer ``` Filter for lines including something like `Report 0 returned with: INTERNAL @@ -310,8 +303,8 @@ More on viewing Mixer configuration can be found [here]({{home}}/help/faq/mixer. In Kubernetes environments, setup port-forwarding as follows: - ```bash - kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & + ```command + $ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090 & ``` 1. Visit [http://localhost:9090/config](http://localhost:9090/config). @@ -356,7 +349,7 @@ Communication between Envoy and the app happens on 127.0.0.1, and is not encrypt Check your `ulimit -a`. Many systems have a 1024 open file descriptor limit by default which will cause Envoy to assert and crash with: -```bash +```plain [2017-05-17 03:00:52.735][14236][critical][assert] assert failure: fd_ != -1: external/envoy/source/common/network/connection_impl.cc:58 ``` @@ -373,18 +366,15 @@ happening, you will need to disable mTLS and the `istio-citadel` deployment. First, edit your istio config to disable mTLS -```bash -# comment out or uncomment authPolicy: MUTUAL_TLS to toggle mTLS and then -kubectl edit configmap -n istio-system istio - -# restart pilot and wait a few minutes -kubectl delete pods -n istio-system -l istio=pilot +```command +$ kubectl edit configmap -n istio-system istio +$ kubectl delete pods -n istio-system -l istio=pilot ``` Next, scale down the `istio-citadel` deployment to disable Envoy restarts. -```bash -kubectl scale --replicas=0 deploy/istio-citadel -n istio-system +```command +$ kubectl scale --replicas=0 deploy/istio-citadel -n istio-system ``` This should stop Istio from restarting Envoy and disconnecting TCP connections. @@ -397,13 +387,9 @@ CPU usage, even when Envoy isn't doing anything. In order to bring the CPU usage down for larger deployments, increase the refresh interval for Envoy to something higher, like 30 seconds. -```bash -# increase the field rdsRefreshDelay in the mesh and defaultConfig section -# set the refresh interval to 30s -kubectl edit configmap -n istio-system istio - -# restart pilot and wait a few minutes -kubectl delete pods -n istio-system -l istio=pilot +```command +$ kubectl edit configmap -n istio-system istio +$ kubectl delete pods -n istio-system -l istio=pilot ``` Also make sure to reinject the sidecar into all of your pods, as @@ -435,9 +421,9 @@ env: - name: no_proxy value: 127.0.0.1,localhost,dockerhub.foo.com,devhub-docker.foo.com,10.84.100.125,10.84.100.126,10.84.100.127 ``` -The sidecar injection would fail. The only related failure logs was in the kube-apiserver log: +The sidecar injection would fail. The only related failure logs was in the kube-apiserver log: -```bash +```plain W0227 21:51:03.156818 1 admission.go:257] Failed calling webhook, failing open sidecar-injector.istio.io: failed calling admission webhook "sidecar-injector.istio.io": Post https://istio-sidecar-injector.istio-system.svc:443/inject: Service Unavailable ``` diff --git a/js/misc.js b/js/misc.js index 926080353b72..6ecae7cc3de5 100644 --- a/js/misc.js +++ b/js/misc.js @@ -199,7 +199,15 @@ function handleDOMLoaded() { for (var i = 0; i < pre.length; i++) { var code = pre[i].firstChild; - if (code.classList.contains("language-command")) { + var cl = ""; + for (var j = 0; j < code.classList.length; j++) { + if (code.classList.item(j).startsWith("language-command")) { + cl = code.classList.item(j); + break; + } + } + + if (cl != "") { var text = code.innerText; var lines = text.split("\n"); @@ -230,15 +238,29 @@ function handleDOMLoaded() { } } + // in case someone forgot the $, treat everything as a command instead of as output + if (cmd == "") { + cmd = output; + output = ""; + } + var colored = Prism.highlight(cmd, Prism.languages["bash"], "bash"); var html = "<div class='command'>" + colored + "</div>"; if (output != "") { + + // apply formatting to the output? + var prefix = "language-command-output-as-"; + if (cl.length > prefix.length) { + var lang = cl.substr(prefix.length); + output = Prism.highlight(output, Prism.languages[lang], lang); + } + html = html + "<div class='output'>" + output + "</div>"; } code.innerHTML = html; - code.classList.remove("language-command"); + code.classList.remove(cl); code.classList.add("command-output"); } else { Prism.highlightElement(code, false); diff --git a/js/misc.min.js b/js/misc.min.js index efe10da43bfd..3159f0eb1707 100644 --- a/js/misc.min.js +++ b/js/misc.min.js @@ -2,4 +2,4 @@ --- {% include home.html %} -'use strict';$(function(a){function b(){var d=a('#search_form'),e=a('#search_textbox'),f=a('#navbar-links');d.removeClass('active'),f.addClass('active'),e.val(''),e.removeClass('grow')}function c(){var d=a('#search_form'),e=a('#search_textbox'),f=a('#navbar-links');d.addClass('active'),f.removeClass('active'),e.addClass('grow'),e.focus()}a('body').on('keyup',function(d){27==d.which&&b()}),a('#search_show').on('click',function(d){d.preventDefault(),c()}),a('#search_close').on('click',function(d){d.preventDefault(),b()}),a('#search_form').submit(function(d){d.preventDefault();var e=a('#search_textbox'),f='{{home}}/search.html?q='+e.val();b(),window.location.assign(f)}),a(document).ready(function(){a('[data-toggle="offcanvas"]').on('click',function(){a('.row-offcanvas').toggleClass('active'),a(this).children('i.fa').toggleClass('fa-flip-horizontal')}),a(document).on('click','.tree-toggle',function(){a(this).children('i.fa').toggleClass('fa-caret-right'),a(this).children('i.fa').toggleClass('fa-caret-down'),a(this).parent().children('ul.tree').toggle(200)}),a(document).on('mouseenter','pre',function(){a(this).next().toggleClass('copy-show',!0),a(this).next().toggleClass('copy-hide',!1)}),a(document).on('mouseleave','pre',function(){a(this).next().toggleClass('copy-show',!1),a(this).next().toggleClass('copy-hide',!0)}),a(document).on('mouseenter','button.copy',function(){a(this).toggleClass('copy-show',!0),a(this).toggleClass('copy-hide',!1)}),a(document).on('mouseleave','button.copy',function(){a(this).toggleClass('copy-show',!1),a(this).toggleClass('copy-hide',!0)})})}(jQuery));function scrollToTop(){document.body.scrollTop=0,document.documentElement.scrollTop=0}var scrollToTopButton,tocLinks,tocHeadings;function handleDOMLoaded(){(function(){function e(m){var n=document.createElement('i');n.className='fa fa-link';var o=document.createElement('a');o.className='header-link',o.href='#'+m.id,o.setAttribute('aria-hidden','true'),o.appendChild(n),m.appendChild(o)}(function(){for(var o,m=document.getElementsByTagName('PRE'),n=0;n<m.length;n++){o=document.createElement('BUTTON'),o.title='Copy to clipboard',o.className='copy copy-hide',o.innerText='Copy',o.setAttribute('aria-label','Copy to clipboard');var p=m[n].parentElement;if('DIV'==p.tagName)p.appendChild(o);else{var q=document.createElement('DIV');q.className='highlight',p.insertBefore(q,m[n]),q.appendChild(m[n]),q.appendChild(o)}Prism.highlightElement(m[n].firstChild,!1)}var r=new Clipboard('button.copy',{text:function(s){var t=s.previousElementSibling.getElementsByClassName('command');if(t!=void 0&&0<t.length){for(var u=t[0].innerText.split('\n'),v='',w=0;w<u.length;w++)u[w].startsWith('$ ')&&(u[w]=u[w].substring(2)),''!=v&&(v+='\n'),v+=u[w];return v}return s.previousElementSibling.innerText}});r.on('success',function(s){s.clearSelection(),s.trigger.textContent='Done',window.setTimeout(function(){s.trigger.textContent='Copy'},2e3)}),r.on('error',function(s){s.trigger.textContent='Not supported',window.setTimeout(function(){s.trigger.textContent='Copy'},5e3)})})(),function(){for(var o,m=document.getElementsByTagName('PRE'),n=0;n<m.length;n++)if(o=m[n].firstChild,o.classList.contains('language-command')){for(var p=o.innerText,q=p.split('\n'),r=!1,s='',t='',u=!1,v=0;v<q.length;v++)if(r)t=t+'\n'+q[v];else{if(q[v].startsWith('$ '));else if(u);else{r=!0,t=q[v];continue}u=q[v].endsWith('\\'),''!=s&&(s+='\n'),s+=q[v]}var w=Prism.highlight(s,Prism.languages.bash,'bash'),x='<div class=\'command\'>'+w+'</div>';''!=t&&(x=x+'<div class=\'output\'>'+t+'</div>'),o.innerHTML=x,o.classList.remove('language-command'),o.classList.add('command-output')}else{Prism.highlightElement(o,!1);var o=m[n].firstChild,y=document.createElement('DIV');y.className='code-plain',parent=o.parentElement,parent.insertBefore(y,o),y.appendChild(o)}}(),function(){for(var n,m=1;6>=m;m++){n=document.getElementsByTagName('h'+m);for(var p,o=0;o<n.length;o++)p=n[o],''!==p.id&&e(p)}}(),function(){for(var o,m=document.getElementsByTagName('dt'),n=0;n<m.length;n++)o=m[n],''!==o.id&&e(o)}(),function(){for(var o,m=document.getElementsByTagName('a'),n=0;n<m.length;n++)o=m[n],o.hostname&&o.hostname!=location.hostname&&o.setAttribute('target','_blank')}(),function(){function m(p,q){fetch(q).then(r=>r.text()).then(r=>{p.firstChild.innerText=r})}for(var n=document.getElementsByTagName('PRE'),o=0;o<n.length;o++)n[o].hasAttribute('data-src')&&m(n[o],n[o].getAttribute('data-src'))}(),function(){var m=document.getElementById('endnotes');if(void 0!=m)for(var r,n=document.getElementsByTagName('main')[0],o=n.getElementsByTagName('a'),p=new Map(null),q=0;q<o.length;q++)if((r=o[q],r.pathname!=location.pathname)&&!(r.pathname.endsWith('/')&&''!=r.hash)&&!r.classList.contains('not-for-endnotes')){var s=p.get(r.href);if(void 0==s){s=p.size+1,p.set(r.href,s);var t=document.createElement('li');t.innerText=r.href,m.appendChild(t)}r.insertAdjacentHTML('afterend','<sup class=\'endnote-ref\'>'+s+'</sup>')}}()})(),function(){scrollToTopButton=document.getElementById('scroll-to-top');var c=document.getElementById('toc');if(c!=void 0){tocLinks=c.getElementsByTagName('A'),tocHeadings=Array(tocLinks.length);for(var d=0;d<tocLinks.length;d++)tocHeadings[d]=document.getElementById(tocLinks[d].hash.substring(1))}}(),handlePageScroll()}function handlePageScroll(){(function(){scrollToTopButton&&(300<document.body.scrollTop||300<document.documentElement.scrollTop?scrollToTopButton.style.display='block':scrollToTopButton.style.display='none')})(),function(){if(tocLinks){for(var h,c=-1,d=1e6,e=-1,f=-1e6,g=0;g<tocLinks.length;g++)h=tocHeadings[g].getBoundingClientRect(),(h.width||h.height)&&(0<=h.top&&h.top<window.innerHeight?h.top<d&&(c=g,d=h.top):0>h.top&&h.top>f&&(e=g,f=h.top)),tocLinks[g].classList.remove('current');0<=c?tocLinks[c].classList.add('current'):0<=e&&tocLinks[e].classList.add('current')}}()}document.addEventListener('DOMContentLoaded',handleDOMLoaded),window.addEventListener('scroll',handlePageScroll); +'use strict';$(function(a){function b(){var d=a('#search_form'),e=a('#search_textbox'),f=a('#navbar-links');d.removeClass('active'),f.addClass('active'),e.val(''),e.removeClass('grow')}function c(){var d=a('#search_form'),e=a('#search_textbox'),f=a('#navbar-links');d.addClass('active'),f.removeClass('active'),e.addClass('grow'),e.focus()}a('body').on('keyup',function(d){27==d.which&&b()}),a('#search_show').on('click',function(d){d.preventDefault(),c()}),a('#search_close').on('click',function(d){d.preventDefault(),b()}),a('#search_form').submit(function(d){d.preventDefault();var e=a('#search_textbox'),f='{{home}}/search.html?q='+e.val();b(),window.location.assign(f)}),a(document).ready(function(){a('[data-toggle="offcanvas"]').on('click',function(){a('.row-offcanvas').toggleClass('active'),a(this).children('i.fa').toggleClass('fa-flip-horizontal')}),a(document).on('click','.tree-toggle',function(){a(this).children('i.fa').toggleClass('fa-caret-right'),a(this).children('i.fa').toggleClass('fa-caret-down'),a(this).parent().children('ul.tree').toggle(200)}),a(document).on('mouseenter','pre',function(){a(this).next().toggleClass('copy-show',!0),a(this).next().toggleClass('copy-hide',!1)}),a(document).on('mouseleave','pre',function(){a(this).next().toggleClass('copy-show',!1),a(this).next().toggleClass('copy-hide',!0)}),a(document).on('mouseenter','button.copy',function(){a(this).toggleClass('copy-show',!0),a(this).toggleClass('copy-hide',!1)}),a(document).on('mouseleave','button.copy',function(){a(this).toggleClass('copy-show',!1),a(this).toggleClass('copy-hide',!0)})})}(jQuery));function scrollToTop(){document.body.scrollTop=0,document.documentElement.scrollTop=0}var scrollToTopButton,tocLinks,tocHeadings;function handleDOMLoaded(){(function(){function e(m){var n=document.createElement('i');n.className='fa fa-link';var o=document.createElement('a');o.className='header-link',o.href='#'+m.id,o.setAttribute('aria-hidden','true'),o.appendChild(n),m.appendChild(o)}(function(){for(var o,m=document.getElementsByTagName('PRE'),n=0;n<m.length;n++){o=document.createElement('BUTTON'),o.title='Copy to clipboard',o.className='copy copy-hide',o.innerText='Copy',o.setAttribute('aria-label','Copy to clipboard');var p=m[n].parentElement;if('DIV'==p.tagName)p.appendChild(o);else{var q=document.createElement('DIV');q.className='highlight',p.insertBefore(q,m[n]),q.appendChild(m[n]),q.appendChild(o)}Prism.highlightElement(m[n].firstChild,!1)}var r=new Clipboard('button.copy',{text:function(s){var t=s.previousElementSibling.getElementsByClassName('command');if(t!=void 0&&0<t.length){for(var u=t[0].innerText.split('\n'),v='',w=0;w<u.length;w++)u[w].startsWith('$ ')&&(u[w]=u[w].substring(2)),''!=v&&(v+='\n'),v+=u[w];return v}return s.previousElementSibling.innerText}});r.on('success',function(s){s.clearSelection(),s.trigger.textContent='Done',window.setTimeout(function(){s.trigger.textContent='Copy'},2e3)}),r.on('error',function(s){s.trigger.textContent='Not supported',window.setTimeout(function(){s.trigger.textContent='Copy'},5e3)})})(),function(){for(var m=document.getElementsByTagName('PRE'),n=0;n<m.length;n++){for(var o=m[n].firstChild,p='',q=0;q<o.classList.length;q++)if(o.classList.item(q).startsWith('language-command')){p=o.classList.item(q);break}if(''!=p){for(var r=o.innerText,s=r.split('\n'),t=!1,u='',v='',w=!1,q=0;q<s.length;q++)if(t)v=v+'\n'+s[q];else{if(s[q].startsWith('$ '));else if(w);else{t=!0,v=s[q];continue}w=s[q].endsWith('\\'),''!=u&&(u+='\n'),u+=s[q]}''==u&&(u=v,v='');var x=Prism.highlight(u,Prism.languages.bash,'bash'),y='<div class=\'command\'>'+x+'</div>';if(''!=v){var z='language-command-output-as-';if(p.length>z.length){var A=p.substr(z.length);v=Prism.highlight(v,Prism.languages[A],A)}y=y+'<div class=\'output\'>'+v+'</div>'}o.innerHTML=y,o.classList.remove(p),o.classList.add('command-output')}else{Prism.highlightElement(o,!1);var o=m[n].firstChild,B=document.createElement('DIV');B.className='code-plain',parent=o.parentElement,parent.insertBefore(B,o),B.appendChild(o)}}}(),function(){for(var n,m=1;6>=m;m++){n=document.getElementsByTagName('h'+m);for(var p,o=0;o<n.length;o++)p=n[o],''!==p.id&&e(p)}}(),function(){for(var o,m=document.getElementsByTagName('dt'),n=0;n<m.length;n++)o=m[n],''!==o.id&&e(o)}(),function(){for(var o,m=document.getElementsByTagName('a'),n=0;n<m.length;n++)o=m[n],o.hostname&&o.hostname!=location.hostname&&o.setAttribute('target','_blank')}(),function(){function m(p,q){fetch(q).then(r=>r.text()).then(r=>{p.firstChild.innerText=r})}for(var n=document.getElementsByTagName('PRE'),o=0;o<n.length;o++)n[o].hasAttribute('data-src')&&m(n[o],n[o].getAttribute('data-src'))}(),function(){var m=document.getElementById('endnotes');if(void 0!=m)for(var r,n=document.getElementsByTagName('main')[0],o=n.getElementsByTagName('a'),p=new Map(null),q=0;q<o.length;q++)if((r=o[q],r.pathname!=location.pathname)&&!(r.pathname.endsWith('/')&&''!=r.hash)&&!r.classList.contains('not-for-endnotes')){var s=p.get(r.href);if(void 0==s){s=p.size+1,p.set(r.href,s);var t=document.createElement('li');t.innerText=r.href,m.appendChild(t)}r.insertAdjacentHTML('afterend','<sup class=\'endnote-ref\'>'+s+'</sup>')}}()})(),function(){scrollToTopButton=document.getElementById('scroll-to-top');var c=document.getElementById('toc');if(c!=void 0){tocLinks=c.getElementsByTagName('A'),tocHeadings=Array(tocLinks.length);for(var d=0;d<tocLinks.length;d++)tocHeadings[d]=document.getElementById(tocLinks[d].hash.substring(1))}}(),handlePageScroll()}function handlePageScroll(){(function(){scrollToTopButton&&(300<document.body.scrollTop||300<document.documentElement.scrollTop?scrollToTopButton.style.display='block':scrollToTopButton.style.display='none')})(),function(){if(tocLinks){for(var h,c=-1,d=1e6,e=-1,f=-1e6,g=0;g<tocLinks.length;g++)h=tocHeadings[g].getBoundingClientRect(),(h.width||h.height)&&(0<=h.top&&h.top<window.innerHeight?h.top<d&&(c=g,d=h.top):0>h.top&&h.top>f&&(e=g,f=h.top)),tocLinks[g].classList.remove('current');0<=c?tocLinks[c].classList.add('current'):0<=e&&tocLinks[e].classList.add('current')}}()}document.addEventListener('DOMContentLoaded',handleDOMLoaded),window.addEventListener('scroll',handlePageScroll); From e6ff3d8b81a86910db9fc3f149f1ba8b718cf66f Mon Sep 17 00:00:00 2001 From: Yossi Mesika <mesika@il.ibm.com> Date: Tue, 8 May 2018 15:30:24 +0300 Subject: [PATCH 170/191] Fixes to the doc after testing/reviewing it with release-0.8 istio branch (#1244) --- README.md | 2 +- _docs/setup/kubernetes/sidecar-injection.md | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e2eaa0c509e2..688321aebfa5 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ The `rake test` part is to make sure you are not introducing HTML errors or bad HTML-Proofer finished successfully. ``` -in the output +in the output. Alternatively, if you just want to develop locally w/o Docker/Kubernetes/Minikube, you can try installing Jekyll locally. You may need to install other prerequisites manually (which is where using the docker image shines). Here's an example of doing diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index 0f199b5c1fd8..cd367c05e116 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -60,17 +60,10 @@ unmodified. Sidecars can be updated selectively by manually deleting a pods or systematically with a deployment rolling update. Manual and automatic injection use the same templated configuration. Automatic -injection loads the configuration from the `istio-inject` ConfigMap in the +injection loads the configuration from the `istio-sidecar-injector` ConfigMap in the `istio-system` namespace. Manual injection can load from a local file or from the ConfigMap. -Two variants of the injection configuration are provided with the default -install: `istio-sidecar-injector-configmap-release.yaml` -and `istio-sidecar-injector-configmap-debug.yaml`. The injection configmap includes -the default injection policy and sidecar injection template. The debug version -includes debug proxy images and additional logging and core dump functionality used -for debugging the sidecar proxy. - ### Manual sidecar injection Use the built-in defaults template and dynamically fetch the mesh @@ -212,7 +205,7 @@ supplied with Istio selects pods in namespaces with label `istio-injection=enabl This can be changed by modifying the MutatingWebhookConfiguration in `install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml`. -The `istio-inject` ConfigMap in the `istio-system` namespace the default +The `istio-sidecar-injector` ConfigMap in the `istio-system` namespace has the default injection policy and sidecar injection template. ##### _**policy**_ From e34de16c5e4e071227c1b2b380b305ed2d8798cc Mon Sep 17 00:00:00 2001 From: Vadim Eisenberg <vadime@il.ibm.com> Date: Tue, 8 May 2018 15:33:29 +0300 Subject: [PATCH 171/191] update format of a tcp ServiceEntry (#1237) --- _docs/tasks/traffic-management-v1alpha3/egress-tcp.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md index 4958fa60713e..ae27c6c09058 100644 --- a/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md +++ b/_docs/tasks/traffic-management-v1alpha3/egress-tcp.md @@ -44,6 +44,8 @@ metadata: name: wikipedia-ext spec: hosts: + - wikipedia.org + addresses: - 91.198.174.192/27 - 103.102.166.224/27 - 198.35.26.96/27 @@ -51,9 +53,9 @@ spec: - 208.80.154.224/27 ports: - number: 443 - name: tcp protocol: TCP - discovery: NONE + name: tcp-port + resolution: NONE EOF ``` From 3af9ba2a17e0a1a4d1f689e608b2066d5b804c4b Mon Sep 17 00:00:00 2001 From: Martin Taillefer <geeknoid@users.noreply.github.com> Date: Tue, 8 May 2018 05:55:40 -0700 Subject: [PATCH 172/191] Remove broken link. (#1250) --- _docs/setup/consul/install.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/_docs/setup/consul/install.md b/_docs/setup/consul/install.md index a7ecc987e19a..b848de243e15 100644 --- a/_docs/setup/consul/install.md +++ b/_docs/setup/consul/install.md @@ -25,10 +25,8 @@ Istio's API server (based on Kubernetes' API server) provides key functions such as configuration management and Role-Based Access Control. The API server requires an [etcd cluster](https://kubernetes.io/docs/getting-started-guides/scratch/#etcd) -as a persistent store. Detailed instructions for setting up the API server can -be found -[here](https://kubernetes.io/docs/getting-started-guides/scratch/#apiserver-controller-manager-and-scheduler). -See the [documentation on the startup options for the Kubernetes API server](https://kubernetes.io/docs/admin/kube-apiserver/). +as a persistent store. See the +[instructions for setting up the API server](https://kubernetes.io/docs/getting-started-guides/scratch/#apiserver-controller-manager-and-scheduler). #### Local Install From 537c3aa5a607775f7b840a4498481da6bbe70fca Mon Sep 17 00:00:00 2001 From: Frank Budinsky <frankb@ca.ibm.com> Date: Tue, 8 May 2018 11:19:41 -0400 Subject: [PATCH 173/191] WIP PR for v1alpha3 task corrections (#1247) * ingress task corrections * fault injection task version wrong --- .../fault-injection.md | 11 +++-- .../traffic-management-v1alpha3/ingress.md | 41 ++++++++++--------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/_docs/tasks/traffic-management-v1alpha3/fault-injection.md b/_docs/tasks/traffic-management-v1alpha3/fault-injection.md index 8e79b965e040..268021c09208 100644 --- a/_docs/tasks/traffic-management-v1alpha3/fault-injection.md +++ b/_docs/tasks/traffic-management-v1alpha3/fault-injection.md @@ -22,7 +22,6 @@ This task shows how to inject delays and test the resiliency of your application ```command $ istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml - $ istioctl replace -f samples/bookinfo/routing/route-rule-reviews-test-v2.yaml ``` # Fault injection @@ -64,11 +63,11 @@ continue without any errors. route: - destination: name: ratings - subset: v1 + subset: v2 - route: - destination: name: ratings - subset: v1 + subset: v2 ``` Allow several seconds to account for rule propagation delay to all pods. @@ -141,10 +140,14 @@ message. - headers: cookie: regex: ^(.*?;)?(user=jason)(;.*)?$ + route: + - destination: + name: ratings + subset: v2 - route: - destination: name: ratings - subset: v1 + subset: v2 ``` 1. Observe application behavior diff --git a/_docs/tasks/traffic-management-v1alpha3/ingress.md b/_docs/tasks/traffic-management-v1alpha3/ingress.md index 5fa1c3e3133b..ea445fcd894b 100644 --- a/_docs/tasks/traffic-management-v1alpha3/ingress.md +++ b/_docs/tasks/traffic-management-v1alpha3/ingress.md @@ -67,23 +67,31 @@ using Istio routing rules, exactly in the same was as for internal service reque 1. Create an Istio `Gateway` ```bash - cat <<EOF | kubectl create -f - + cat <<EOF | istioctl create -f - apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: httpbin-gateway spec: + selector: + istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http + protocol: HTTP + hosts: + - "*" - port: number: 443 name: https + protocol: HTTPS tls: mode: SIMPLE serverCertificate: /tmp/tls.crt privateKey: /tmp/tls.key + hosts: + - "*" EOF ``` @@ -93,33 +101,27 @@ using Istio routing rules, exactly in the same was as for internal service reque 1. Configure routes for traffic entering via the `Gateway` ```bash - cat <<EOF | kubectl create -f - + cat <<EOF | istioctl create -f - apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts: - - httpbin + - "*" gateways: - httpbin-gateway http: - match: - uri: + - uri: prefix: /status - route: - - destination: - port: - number: 8000 - name: httpbin - - match: - uri: + - uri: prefix: /delay route: - destination: port: number: 8000 - name: httpbin + host: httpbin EOF ``` @@ -137,22 +139,23 @@ using Istio routing rules, exactly in the same was as for internal service reque The proxy instances implementing a particular `Gateway` configuration can be specified using a [selector]({{home}}/docs/reference/config/istio.networking.v1alpha3.html#Gateway.selector) field. -If not specified, as in our case, the `Gateway` will be implemented by the default `istio-ingress` controller. -Therefore, to test our `Gateway` we will send requests to the `istio-ingress` service. +In our case, we have set the selector value to `istio: ingressgateway` to use the default +`istio-ingressgateway` controller. Therefore, to test our `Gateway` we will send requests to +the `istio-ingressgateway` service. -1. Get the ingress controller pod's hostIP: +1. Get the ingressgateway controller pod's hostIP: ```command - $ kubectl -n istio-system get po -l istio=ingress -o jsonpath='{.items[0].status.hostIP}' + $ kubectl -n istio-system get po -l istio=ingressgateway -o jsonpath='{.items[0].status.hostIP}' 169.47.243.100 ``` 1. Get the istio-ingress service's nodePorts for port 80 and 443: ```command - $ kubectl -n istio-system get svc istio-ingress - NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE - istio-ingress 10.10.10.155 <pending> 80:31486/TCP,443:32254/TCP 32m + $ kubectl -n istio-system get svc istio-ingressgateway + NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE + istio-ingressgateway 10.10.10.155 <pending> 80:31486/TCP,443:32254/TCP 32m ``` ```command From 001c906e259488a319d54b6c77dbae0057c540b9 Mon Sep 17 00:00:00 2001 From: Frank Budinsky <frankb@ca.ibm.com> Date: Tue, 8 May 2018 13:21:48 -0400 Subject: [PATCH 174/191] Fault task corrections (#1253) --- .../traffic-management-v1alpha3/fault-injection.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/_docs/tasks/traffic-management-v1alpha3/fault-injection.md b/_docs/tasks/traffic-management-v1alpha3/fault-injection.md index 268021c09208..4069f2f2a533 100644 --- a/_docs/tasks/traffic-management-v1alpha3/fault-injection.md +++ b/_docs/tasks/traffic-management-v1alpha3/fault-injection.md @@ -22,6 +22,7 @@ This task shows how to inject delays and test the resiliency of your application ```command $ istioctl create -f samples/bookinfo/routing/route-rule-all-v1.yaml + $ istioctl replace -f samples/bookinfo/routing/route-rule-reviews-test-v2.yaml ``` # Fault injection @@ -63,11 +64,11 @@ continue without any errors. route: - destination: name: ratings - subset: v2 + subset: v1 - route: - destination: name: ratings - subset: v2 + subset: v1 ``` Allow several seconds to account for rule propagation delay to all pods. @@ -143,18 +144,18 @@ message. route: - destination: name: ratings - subset: v2 + subset: v1 - route: - destination: name: ratings - subset: v2 + subset: v1 ``` 1. Observe application behavior Login as user "jason". If the rule propagated successfully to all pods, you should see the page load immediately with the "product ratings not available" message. Logout from user "jason" and you should - see the ratings v2 show up successfully on the productpage web page. + see reviews with rating stars show up successfully on the productpage web page. ## Cleanup From 7cf70bc3b2ffe2b6e9f842cd01d832283095702c Mon Sep 17 00:00:00 2001 From: Quanjie Lin <32855694+quanjielin@users.noreply.github.com> Date: Tue, 8 May 2018 15:29:37 -0700 Subject: [PATCH 175/191] update samples to align with latest proto definition (#1254) --- _docs/tasks/traffic-management-v1alpha3/mirroring.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_docs/tasks/traffic-management-v1alpha3/mirroring.md b/_docs/tasks/traffic-management-v1alpha3/mirroring.md index a134e324f0f0..1b662f5b969e 100644 --- a/_docs/tasks/traffic-management-v1alpha3/mirroring.md +++ b/_docs/tasks/traffic-management-v1alpha3/mirroring.md @@ -131,7 +131,7 @@ spec: http: - route: - destination: - name: httpbin + host: httpbin subset: v1 weight: 100 --- @@ -140,7 +140,7 @@ kind: DestinationRule metadata: name: httpbin spec: - name: httpbin + host: httpbin subsets: - name: v1 labels: @@ -198,11 +198,11 @@ spec: http: - route: - destination: - name: httpbin + host: httpbin subset: v1 weight: 100 mirror: - name: httpbin + host: httpbin subset: v2 EOF ``` From 26327821b98eb2d41e0a87ab69e56dca9f9a28d9 Mon Sep 17 00:00:00 2001 From: Yossi Mesika <mesika@il.ibm.com> Date: Wed, 9 May 2018 18:30:11 +0300 Subject: [PATCH 176/191] Traffic Shifting Review - Fixed wrong links (#1259) --- _docs/tasks/traffic-management-v1alpha3/traffic-shifting.md | 2 +- _docs/tasks/traffic-management/traffic-shifting.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md b/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md index c6510458189c..47f2b813aa83 100644 --- a/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md +++ b/_docs/tasks/traffic-management-v1alpha3/traffic-shifting.md @@ -101,4 +101,4 @@ For more about version routing with autoscaling, check out [Canary Deployments u ## What's next -* Learn more about [request routing]({{home}}/docs/concepts/traffic-management/rules-configuration.html). +* Learn more about [request routing]({{home}}/docs/concepts/traffic-management/request-routing.html). diff --git a/_docs/tasks/traffic-management/traffic-shifting.md b/_docs/tasks/traffic-management/traffic-shifting.md index eb33cf3ab60d..cf481b640a9a 100644 --- a/_docs/tasks/traffic-management/traffic-shifting.md +++ b/_docs/tasks/traffic-management/traffic-shifting.md @@ -114,4 +114,4 @@ For more about version routing with autoscaling, check out [Canary Deployments u ## What's next -* Learn more about [request routing]({{home}}/docs/concepts/traffic-management/rules-configuration.html). +* Learn more about [request routing]({{home}}/docs/concepts/traffic-management/request-routing.html). From 9f999fedc117df764b6de3f52faac49c2e7640ad Mon Sep 17 00:00:00 2001 From: Ahmet Alp Balkan <ahmetalpbalkan@gmail.com> Date: Wed, 9 May 2018 08:31:52 -0700 Subject: [PATCH 177/191] rbac.md: unindent yaml files (#1257) also fixed a typo Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com> --- _docs/concepts/security/rbac.md | 216 ++++++++++++++++---------------- 1 file changed, 107 insertions(+), 109 deletions(-) diff --git a/_docs/concepts/security/rbac.md b/_docs/concepts/security/rbac.md index 3437d7395350..8d322cca1b45 100644 --- a/_docs/concepts/security/rbac.md +++ b/_docs/concepts/security/rbac.md @@ -48,25 +48,25 @@ and any additional properties about the action. Below we show an example "requestcontext". ```yaml - apiVersion: "config.istio.io/v1alpha2" - kind: authorization - metadata: - name: requestcontext - namespace: istio-system - spec: - subject: - user: source.user | "" - groups: "" - properties: - service: source.service | "" - namespace: source.namespace | "" - action: - namespace: destination.namespace | "" - service: destination.service | "" - method: request.method | "" - path: request.path | "" - properties: - version: request.headers["version"] | "" +apiVersion: "config.istio.io/v1alpha2" +kind: authorization +metadata: + name: requestcontext + namespace: istio-system +spec: + subject: + user: source.user | "" + groups: "" + properties: + service: source.service | "" + namespace: source.namespace | "" + action: + namespace: destination.namespace | "" + service: destination.service | "" + method: request.method | "" + path: request.path | "" + properties: + version: request.headers["version"] | "" ``` ## Istio RBAC policy @@ -90,30 +90,30 @@ fields in a rule. "paths" is optional. If not specified or set to "*", it applie Here is an example of a simple role "service-admin", which has full access to all services in "default" namespace. ```yaml - apiVersion: "config.istio.io/v1alpha2" - kind: ServiceRole - metadata: - name: service-admin - namespace: default - spec: - rules: - - services: ["*"] - methods: ["*"] +apiVersion: "config.istio.io/v1alpha2" +kind: ServiceRole +metadata: + name: service-admin + namespace: default +spec: + rules: + - services: ["*"] + methods: ["*"] ``` Here is another role "products-viewer", which has read ("GET" and "HEAD") access to service "products.default.svc.cluster.local" in "default" namespace. ```yaml - apiVersion: "config.istio.io/v1alpha2" - kind: ServiceRole - metadata: - name: products-viewer - namespace: default - spec: - rules: - - services: ["products.default.svc.cluster.local"] - methods: ["GET", "HEAD"] +apiVersion: "config.istio.io/v1alpha2" +kind: ServiceRole +metadata: + name: products-viewer + namespace: default +spec: + rules: + - services: ["products.default.svc.cluster.local"] + methods: ["GET", "HEAD"] ``` In addition, we support **prefix matching** and **suffix matching** for all the fields in a rule. For example, you can define a "tester" role that @@ -123,18 +123,18 @@ has the following permissions in "default" namespace: in service "bookstore.default.svc.cluster.local". ```yaml - apiVersion: "config.istio.io/v1alpha2" - kind: ServiceRole - metadata: - name: tester - namespace: default - spec: - rules: - - services: ["test-*"] - methods: ["*"] - - services: ["bookstore.default.svc.cluster.local"] - paths: ["*/reviews"] - methods: ["GET"] +apiVersion: "config.istio.io/v1alpha2" +kind: ServiceRole +metadata: + name: tester + namespace: default +spec: + rules: + - services: ["test-*"] + methods: ["*"] + - services: ["bookstore.default.svc.cluster.local"] + paths: ["*/reviews"] + methods: ["GET"] ``` In `ServiceRole`, the combination of "namespace"+"services"+"paths"+"methods" defines "how a service (services) is allowed to be accessed". @@ -146,18 +146,18 @@ For example, the following `ServiceRole` definition extends the previous "produc being "v1" or "v2". Note that the "version" property is provided by `"action.properties.version"` in "requestcontext". ```yaml - apiVersion: "config.istio.io/v1alpha2" - kind: ServiceRole - metadata: - name: products-viewer-version - namespace: default - spec: - rules: - - services: ["products.default.svc.cluster.local"] - methods: ["GET", "HEAD"] - constraints: - - key: "version" - values: ["v1", "v2"] +apiVersion: "config.istio.io/v1alpha2" +kind: ServiceRole +metadata: + name: products-viewer-version + namespace: default +spec: + rules: + - services: ["products.default.svc.cluster.local"] + methods: ["GET", "HEAD"] + constraints: + - key: "version" + values: ["v1", "v2"] ``` ### `ServiceRoleBinding` @@ -175,37 +175,37 @@ Here is an example of `ServiceRoleBinding` resource "test-binding-products", whi * "reviews.abc.svc.cluster.local" service in "abc" namespace. ```yaml - apiVersion: "config.istio.io/v1alpha2" - kind: ServiceRoleBinding - metadata: - name: test-binding-products - namespace: default - spec: - subjects: - - user: "alice@yahoo.com" - - properties: - service: "reviews.abc.svc.cluster.local" - namespace: "abc" - roleRef: - kind: ServiceRole - name: "products-vieweqr" +apiVersion: "config.istio.io/v1alpha2" +kind: ServiceRoleBinding +metadata: + name: test-binding-products + namespace: default +spec: + subjects: + - user: "alice@yahoo.com" + - properties: + service: "reviews.abc.svc.cluster.local" + namespace: "abc" + roleRef: + kind: ServiceRole + name: "products-viewer" ``` In the case that you want to make a service(s) publicly accessible, you can use set the subject to `user: "*"`. This will assign a `ServiceRole` to all users/services. ```yaml - apiVersion: "config.istio.io/v1alpha2" - kind: ServiceRoleBinding - metadata: - name: binding-products-allusers - namespace: default - spec: - subjects: - - user: "*" - roleRef: - kind: ServiceRole - name: "products-viewer" +apiVersion: "config.istio.io/v1alpha2" +kind: ServiceRoleBinding +metadata: + name: binding-products-allusers + namespace: default +spec: + subjects: + - user: "*" + roleRef: + kind: ServiceRole + name: "products-viewer" ``` ## Enabling Istio RBAC @@ -224,29 +224,27 @@ earlier in the document](#request-context). In the following example, Istio RBAC is enabled for "default" namespace. And the cache duration is set to 30 seconds. ```yaml - apiVersion: "config.istio.io/v1alpha2" - kind: rbac - metadata: - name: handler - namespace: istio-system - spec: - config_store_url: "k8s://" - cache_duration: "30s" - - --- - apiVersion: "config.istio.io/v1alpha2" - kind: rule - metadata: - name: rbaccheck - namespace: istio-system - spec: - match: destination.namespace == "default" - actions: - # handler and instance names default to the rule's namespace. - - handler: handler.rbac - instances: - - requestcontext.authorization - --- +apiVersion: "config.istio.io/v1alpha2" +kind: rbac +metadata: + name: handler + namespace: istio-system +spec: + config_store_url: "k8s://" + cache_duration: "30s" +--- +apiVersion: "config.istio.io/v1alpha2" +kind: rule +metadata: + name: rbaccheck + namespace: istio-system +spec: + match: destination.namespace == "default" + actions: + # handler and instance names default to the rule's namespace. + - handler: handler.rbac + instances: + - requestcontext.authorization ``` ## What's next From 3295dbc15f47dc8b6a4a3dc30bce889b4d604556 Mon Sep 17 00:00:00 2001 From: Guang Ya Liu <gyliu513@gmail.com> Date: Wed, 9 May 2018 23:58:36 +0800 Subject: [PATCH 178/191] Create istio namespace before install remote cluster. (#1243) --- _docs/setup/kubernetes/multicluster-install.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_docs/setup/kubernetes/multicluster-install.md b/_docs/setup/kubernetes/multicluster-install.md index 1067fb4dd6e8..ecb0f9635568 100644 --- a/_docs/setup/kubernetes/multicluster-install.md +++ b/_docs/setup/kubernetes/multicluster-install.md @@ -147,6 +147,10 @@ $ export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-br $ helm template install/kubernetes/helm/istio-remote --name istio-remote --set global.pilotEndpoint=${PILOT_POD_IP} --set global.policyEndpoint=${POLICY_POD_IP} --set global.statsdEndpoint=${STATSD_POD_IP} > $HOME/istio-remote.yaml ``` +1. Create a namespace for remote Istio. + ```command + $ kubectl create ns istio-system + ``` 1. Instantiate the remote cluster's connection to the Istio control plane: ```command From 6391c6187db84aa4972047b1d4043706e7ac594e Mon Sep 17 00:00:00 2001 From: salrashid123 <salrashid123@gmail.com> Date: Wed, 9 May 2018 19:27:42 -0700 Subject: [PATCH 179/191] update instructions for gke-iam (#1260) --- _docs/setup/kubernetes/img/dm_gcp_iam.png | Bin 54874 -> 36075 bytes .../setup/kubernetes/img/dm_gcp_iam_role.png | Bin 0 -> 39465 bytes _docs/setup/kubernetes/quick-start-gke-dm.md | 15 ++++++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 _docs/setup/kubernetes/img/dm_gcp_iam_role.png diff --git a/_docs/setup/kubernetes/img/dm_gcp_iam.png b/_docs/setup/kubernetes/img/dm_gcp_iam.png index 394520e4fcdbc32d3a08c3d90083441d4964b92c..e770ed68d71af8e269c32a1292b6f6fe6959915d 100644 GIT binary patch literal 36075 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 literal 54874 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 diff --git a/_docs/setup/kubernetes/img/dm_gcp_iam_role.png b/_docs/setup/kubernetes/img/dm_gcp_iam_role.png new file mode 100644 index 0000000000000000000000000000000000000000..121df4ca87ac9843c41e9ac5428f0857b3a8db83 GIT binary patch literal 39465 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 Los@Rr*2Dh~boO=% literal 0 HcmV?d00001 diff --git a/_docs/setup/kubernetes/quick-start-gke-dm.md b/_docs/setup/kubernetes/quick-start-gke-dm.md index 39fe76437fae..450be1dc625c 100644 --- a/_docs/setup/kubernetes/quick-start-gke-dm.md +++ b/_docs/setup/kubernetes/quick-start-gke-dm.md @@ -29,9 +29,18 @@ application. It uses Deployment Manager to automate the steps detailed in the [ {% include figure.html width="100%" ratio="30%" img='./img/dm_gcp_iam.png' - alt='GCP-IAM Permissions' - title='GCP-IAM Permissions' - caption='GKE-IAM Permissions' + alt='GCP-IAM Service' + title='GCP-IAM Service' + caption='GKE-IAM Service' + %} + +Then add the ```Kubernetes Engine Admin``` Role + + {% include figure.html width="100%" ratio="37%" + img='./img/dm_gcp_iam_role.png' + alt='GCP-IAM Role' + title='GCP-IAM Role' + caption='GKE-IAM Role' %} ## Setup From 61e25a2f9a8ad1538c152466f9c4008995ce1af2 Mon Sep 17 00:00:00 2001 From: Martin Taillefer <geeknoid@users.noreply.github.com> Date: Wed, 9 May 2018 19:28:26 -0700 Subject: [PATCH 180/191] Remove a broken link. (#1263) --- _faq/mixer/seeing-mixer-config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_faq/mixer/seeing-mixer-config.md b/_faq/mixer/seeing-mixer-config.md index 3297f36155ef..6a197d75ec09 100644 --- a/_faq/mixer/seeing-mixer-config.md +++ b/_faq/mixer/seeing-mixer-config.md @@ -6,8 +6,8 @@ weight: 10 Configuration for *instances*, *handlers*, and *rules* is stored as Kubernetes [Custom Resources](https://kubernetes.io/docs/concepts/api-extension/custom-resources/). -Configuration may be accessed by using `kubectl` to query the Kubernetes [API -server](https://kubernetes.io/docs/admin/kube-apiserver/) for the resources. +Configuration may be accessed by using `kubectl` to query the Kubernetes +API server for the resources. ## Rules From 8f0353bd31986e3e8806689a5667c2ded668dc6b Mon Sep 17 00:00:00 2001 From: Martin Taillefer <geeknoid@users.noreply.github.com> Date: Wed, 9 May 2018 19:49:49 -0700 Subject: [PATCH 181/191] Fix another broken link. (#1265) --- .spelling | 3 +++ _docs/setup/eureka/install.md | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.spelling b/.spelling index 69f937140d25..cff75e38f60d 100644 --- a/.spelling +++ b/.spelling @@ -246,6 +246,7 @@ destination.user dev dm_bookinfo.png dm_gcp_iam.png +dm_gcp_iam_role.png dm_grafana.png dm_kubernetes.png dm_kubernetes_workloads.png @@ -307,6 +308,7 @@ https_from_the_app.svg hyperkube i.e. img +ingressgateway initializer initializers int64 @@ -352,6 +354,7 @@ listchecker liveness mTLS machine.svg +machineSetup memcached memquota mesos-dns diff --git a/_docs/setup/eureka/install.md b/_docs/setup/eureka/install.md index 1e4d1c21c5b7..6c56dadf813e 100644 --- a/_docs/setup/eureka/install.md +++ b/_docs/setup/eureka/install.md @@ -26,8 +26,6 @@ server requires an as a persistent store. Detailed instructions for setting up the API server can be found [here](https://kubernetes.io/docs/getting-started-guides/scratch/#apiserver-controller-manager-and-scheduler). -Documentation on set of startup options for the Kubernetes API server can be found -[here](https://kubernetes.io/docs/admin/kube-apiserver/) #### Local install From bd35e855721265aa1b9d651b6c8ff318d21d4367 Mon Sep 17 00:00:00 2001 From: "imgbot[bot]" <imgbot[bot]@users.noreply.github.com> Date: Wed, 9 May 2018 19:50:51 -0700 Subject: [PATCH 182/191] [ImgBot] optimizes images (#1264) *Total -- 73.77kb -> 65.13kb (11.72%) /_docs/setup/kubernetes/img/dm_gcp_iam_role.png -- 38.54kb -> 33.47kb (13.15%) /_docs/setup/kubernetes/img/dm_gcp_iam.png -- 35.23kb -> 31.65kb (10.15%) --- _docs/setup/kubernetes/img/dm_gcp_iam.png | Bin 36075 -> 32412 bytes .../setup/kubernetes/img/dm_gcp_iam_role.png | Bin 39465 -> 34276 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/_docs/setup/kubernetes/img/dm_gcp_iam.png b/_docs/setup/kubernetes/img/dm_gcp_iam.png index e770ed68d71af8e269c32a1292b6f6fe6959915d..48826f38c5905c14a670b54a2e9741e7fff665f4 100644 GIT binary patch literal 32412 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%0DI44J!MlFlt2Dye-_WASwM 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 BWPktw literal 36075 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 diff --git a/_docs/setup/kubernetes/img/dm_gcp_iam_role.png b/_docs/setup/kubernetes/img/dm_gcp_iam_role.png index 121df4ca87ac9843c41e9ac5428f0857b3a8db83..33517381eb9a7b4aad094a6b8797bed19b458faa 100644 GIT binary patch literal 34276 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 Wb>Pm-R=}609aK5I@1fEO@Bamf^vKWv literal 39465 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 Los@Rr*2Dh~boO=% From 5130d0c714f11983c620c14ade924a7eebe41674 Mon Sep 17 00:00:00 2001 From: Yossi Mesika <mesika@il.ibm.com> Date: Thu, 10 May 2018 05:58:47 +0300 Subject: [PATCH 183/191] Fixes #1241 (#1258) --- _docs/setup/kubernetes/sidecar-injection.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_docs/setup/kubernetes/sidecar-injection.md b/_docs/setup/kubernetes/sidecar-injection.md index cd367c05e116..c3cb65f71c90 100644 --- a/_docs/setup/kubernetes/sidecar-injection.md +++ b/_docs/setup/kubernetes/sidecar-injection.md @@ -134,6 +134,7 @@ Alternatively, you can also use Helm to generate the yaml file and install it ma ```command $ helm template --namespace=istio-system --set sidecar-injector.enabled=true install/kubernetes/helm/istio > istio.yaml +$ kubectl create ns istio-system $ kubectl apply -f istio.yaml ``` From c740f5d1966539e98c162742f41692fbe3e1a918 Mon Sep 17 00:00:00 2001 From: Guang Ya Liu <gyliu513@gmail.com> Date: Thu, 10 May 2018 11:04:40 +0800 Subject: [PATCH 184/191] Added namespace when create helm template. (#1234) --- _docs/setup/kubernetes/multicluster-install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/setup/kubernetes/multicluster-install.md b/_docs/setup/kubernetes/multicluster-install.md index ecb0f9635568..9071e61c27bd 100644 --- a/_docs/setup/kubernetes/multicluster-install.md +++ b/_docs/setup/kubernetes/multicluster-install.md @@ -144,7 +144,7 @@ $ export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-br 1. Use the helm template command on a remote to specify the Istio control plane service endpoints: ```command - $ helm template install/kubernetes/helm/istio-remote --name istio-remote --set global.pilotEndpoint=${PILOT_POD_IP} --set global.policyEndpoint=${POLICY_POD_IP} --set global.statsdEndpoint=${STATSD_POD_IP} > $HOME/istio-remote.yaml + $ helm template install/kubernetes/helm/istio-remote --namespace istio-system --name istio-remote --set global.pilotEndpoint=${PILOT_POD_IP} --set global.policyEndpoint=${POLICY_POD_IP} --set global.statsdEndpoint=${STATSD_POD_IP} > $HOME/istio-remote.yaml ``` 1. Create a namespace for remote Istio. From 4c06e0a0d12ab1c4d51c70345aafdd1a902aad13 Mon Sep 17 00:00:00 2001 From: Liam White <liamwhite@uk.ibm.com> Date: Fri, 11 May 2018 00:00:04 +0100 Subject: [PATCH 185/191] Add istioctl proxy-config to the troubleshooting section (#1267) --- _help/troubleshooting.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/_help/troubleshooting.md b/_help/troubleshooting.md index 97b7a5becd27..42d186646f88 100644 --- a/_help/troubleshooting.md +++ b/_help/troubleshooting.md @@ -327,6 +327,28 @@ More on viewing Mixer configuration can be found [here]({{home}}/help/faq/mixer. ## How can I debug issues with the service mesh? +### With [istioctl](https://preliminary.istio.io/docs/reference/commands/istioctl.html#istioctl%20proxy-config) + +Istioctl allows you to inspect the current xDS of a given Envoy from its admin interface (locally) or from Pilot using the `proxy-config` or `pc` command. + +For example, to retrieve the configured clusters in an Envoy via the admin interface run the following command: + +```command +istioctl proxy-config endpoint <pod-name> clusters +``` + +To retrieve endpoints for a given pod in the application namespace from Pilot run the following command: + +```command +istioctl proxy-config pilot -n application <pod-name> eds +``` + +The `proxy-config` command also allows you to retrieve the state of the entire mesh from Pilot using the following command: + +```command +istioctl proxy-config pilot mesh ads +``` + ### With [GDB](https://www.gnu.org/software/gdb/) To debug Istio with `gdb`, you will need to run the debug images of Envoy / Mixer / Pilot. A recent `gdb` and the golang extensions (for Mixer/Pilot or other golang components) is required. From efe8fb206808b7ea6ce270abceb03b0e5c831be5 Mon Sep 17 00:00:00 2001 From: Liam White <liamwhite@uk.ibm.com> Date: Fri, 11 May 2018 14:19:00 +0100 Subject: [PATCH 186/191] Fix istioctl proxy-config link to not point at prelim docs (#1269) Because that would be a dumb thing to do --- _help/troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_help/troubleshooting.md b/_help/troubleshooting.md index 42d186646f88..8e7ff3542039 100644 --- a/_help/troubleshooting.md +++ b/_help/troubleshooting.md @@ -327,7 +327,7 @@ More on viewing Mixer configuration can be found [here]({{home}}/help/faq/mixer. ## How can I debug issues with the service mesh? -### With [istioctl](https://preliminary.istio.io/docs/reference/commands/istioctl.html#istioctl%20proxy-config) +### With [istioctl](https://istio.io/docs/reference/commands/istioctl.html#istioctl%20proxy-config) Istioctl allows you to inspect the current xDS of a given Envoy from its admin interface (locally) or from Pilot using the `proxy-config` or `pc` command. From a25d10a83be1f42fd330385c2de48ff9657f49b8 Mon Sep 17 00:00:00 2001 From: Martin Taillefer <geeknoid@users.noreply.github.com> Date: Sun, 13 May 2018 07:44:40 -0700 Subject: [PATCH 187/191] Update how we insert images to make a transition from Jekyll to Hugo easier. (#1275) --- .spelling | 2 +- _about/contribute/writing-a-new-topic.md | 26 +++---- _blog/2017/0.1-announcement.md | 16 ++--- _blog/2017/0.1-auth.md | 16 ++--- _blog/2017/0.1-using-network-policy.md | 8 +-- _blog/2017/adapter-model.md | 8 +-- _blog/2017/mixer-spof-myth.md | 13 ++-- _blog/2018/aws-nlb.md | 32 ++++----- _blog/2018/egress-https.md | 40 ++++------- _blog/2018/egress-tcp.md | 32 ++++----- _blog/2018/v1alpha3-routing.md | 17 ++--- .../policy-and-control/mixer-config.md | 8 +-- _docs/concepts/policy-and-control/mixer.md | 27 ++++--- _docs/concepts/security/authn-policy.md | 8 +-- _docs/concepts/security/mutual-tls.md | 9 ++- _docs/concepts/security/rbac.md | 9 ++- .../traffic-management/load-balancing.md | 8 +-- _docs/concepts/traffic-management/overview.md | 8 +-- _docs/concepts/traffic-management/pilot.md | 7 +- .../traffic-management/request-routing.md | 18 +++-- _docs/concepts/what-is-istio/overview.md | 9 ++- _docs/guides/bookinfo.md | 16 ++--- _docs/guides/integrating-vms.md | 8 +-- _docs/setup/kubernetes/quick-start-gke-dm.md | 72 +++++++------------ _docs/tasks/telemetry/distributed-tracing.md | 32 ++++----- _docs/tasks/telemetry/querying-metrics.md | 8 +-- _docs/tasks/telemetry/servicegraph.md | 8 +-- _docs/tasks/telemetry/tcp-metrics.md | 9 ++- .../tasks/telemetry/using-istio-dashboard.md | 16 ++--- _includes/figure.html | 26 ------- _includes/image.html | 38 ++++++++++ 31 files changed, 233 insertions(+), 321 deletions(-) delete mode 100644 _includes/figure.html create mode 100644 _includes/image.html diff --git a/.spelling b/.spelling index cff75e38f60d..3ebda772d1cf 100644 --- a/.spelling +++ b/.spelling @@ -272,7 +272,6 @@ failovers faq faq.md fcm.googleapis.com -figure.html filename filenames fluentd @@ -307,6 +306,7 @@ https https_from_the_app.svg hyperkube i.e. +image.html img ingressgateway initializer diff --git a/_about/contribute/writing-a-new-topic.md b/_about/contribute/writing-a-new-topic.md index 83d781347dc2..96ac1b190c28 100644 --- a/_about/contribute/writing-a-new-topic.md +++ b/_about/contribute/writing-a-new-topic.md @@ -87,22 +87,20 @@ chunk of front matter you should start with: --- title: <title> description: <overview> - weight: <order> --- ``` Copy the above at the start of your new markdown file and update -the `<title>`, `<overview>` and `<order>` fields for your particular file. The available front +the `<title>`, `<description>` and `<weight>` fields for your particular file. The available front matter fields are: |Field | Description |---------------|------------ |`title` | The short title of the page -|`overview` | A one-line description of what the topic is about -|`order` | An integer used to determine the sort order of this page relative to other pages in the same directory. +|`description` | A one-line description of what the topic is about +|`weight` | An integer used to determine the sort order of this page relative to other pages in the same directory. |`layout` | Indicates which of the Jekyll layouts this page uses -|`index` | Indicates whether the page should appear in the doc's top nav tabs |`draft` | When true, prevents the page from showing up in any navigation area |`publish_date` | For blog posts, indicates the date of publication of the post |`subtitle` | For blog posts, supplies an optional subtitle to be displayed below the main title @@ -139,17 +137,21 @@ Within markdown, use the following sequence to add the image: ```html {% raw %} -{% include figure.html width='75%' ratio='69.52%' - img='./img/myfile.svg' - alt='Alternate text to display when the image is not available' - title='A tooltip displayed when hovering over the image' - caption='A caption displayed under the image' +{% include image.html width="75%" ratio="69.52%" + link="./img/myfile.svg" + alt="Alternate text to display when the image is not available" + title="A tooltip displayed when hovering over the image" + caption="A caption displayed under the image" %} {% endraw %} ``` -You need to fill in all the values. The width represents the percentage of space used by the image -relative to the surrounding text. The ratio is (image height / image width) * 100. +The `width`, `ratio`, `link` and `caption` values are required. If the `title` value isn't +supplied, it'll default to the same as `caption`. If the `alt` value is not supplied, it'll +default to `title` or if that's not defined, to `caption`. + +`width` represents the percentage of space used by the image +relative to the surrounding text. `ratio` (image height / image width) * 100. ## Linking to other pages diff --git a/_blog/2017/0.1-announcement.md b/_blog/2017/0.1-announcement.md index 9bb0c4647e3e..0108bbfec2b7 100644 --- a/_blog/2017/0.1-announcement.md +++ b/_blog/2017/0.1-announcement.md @@ -35,18 +35,14 @@ Google, IBM and Lyft joined forces to create Istio from a desire to provide a re **Fleet-wide Visibility**: Failures happen, and operators need tools to stay on top of the health of clusters and their graphs of microservices. Istio produces detailed monitoring data about application and network behaviors that is rendered using [Prometheus](https://prometheus.io/) & [Grafana](https://github.com/grafana/grafana), and can be easily extended to send metrics and logs to any collection, aggregation and querying system. Istio enables analysis of performance hotspots and diagnosis of distributed failure modes with [Zipkin](https://github.com/openzipkin/zipkin) tracing. -{% include figure.html width='100%' ratio='55.42%' - img='./img/istio_grafana_dashboard-new.png' - alt='Grafana Dashboard with Response Size' - title='Grafana Dashboard with Response Size' - caption='Grafana Dashboard with Response Size' +{% include image.html width="100%" ratio="55.42%" + link="./img/istio_grafana_dashboard-new.png" + caption="Grafana Dashboard with Response Size" %} -{% include figure.html width='100%' ratio='29.91%' - img='./img/istio_zipkin_dashboard.png' - alt='Zipkin Dashboard' - title='Zipkin Dashboard' - caption='Zipkin Dashboard' +{% include image.html width="100%" ratio="29.91%" + link="./img/istio_zipkin_dashboard.png" + caption="Zipkin Dashboard" %} **Resiliency and efficiency**: When developing microservices, operators need to assume that the network will be unreliable. Operators can use retries, load balancing, flow-control (HTTP/2), and circuit-breaking to compensate for some of the common failure modes due to an unreliable network. Istio provides a uniform approach to configuring these features, making it easier to operate a highly resilient service mesh. diff --git a/_blog/2017/0.1-auth.md b/_blog/2017/0.1-auth.md index 10d6699d4cc5..ecf91456e172 100644 --- a/_blog/2017/0.1-auth.md +++ b/_blog/2017/0.1-auth.md @@ -44,11 +44,9 @@ Istio Auth is based on industry standards like mutual TLS and X.509. Furthermore The diagram below provides an overview of the Istio Auth service authentication architecture on Kubernetes. -{% include figure.html width='100%' ratio='56.25%' - img='./img/istio_auth_overview.svg' - alt='Istio Auth Overview' - title='Istio Auth Overview' - caption='Istio Auth Overview' +{% include image.html width="100%" ratio="56.25%" + link="./img/istio_auth_overview.svg" + caption="Istio Auth Overview" %} The above diagram illustrates three key security features: @@ -81,11 +79,9 @@ Istio Auth provides a per-cluster CA (Certificate Authority) and automated key & The following diagram explains the end to end Istio Auth authentication workflow on Kubernetes: -{% include figure.html width='100%' ratio='56.25%' - img='./img/istio_auth_workflow.svg' - alt='Istio Auth Workflow' - title='Istio Auth Workflow' - caption='Istio Auth Workflow' +{% include image.html width="100%" ratio="56.25%" + link="./img/istio_auth_workflow.svg" + caption="Istio Auth Workflow" %} Istio Auth is part of the broader security story for containers. Red Hat, a partner on the development of Kubernetes, has identified [10 Layers](https://www.redhat.com/en/resources/container-security-openshift-cloud-devops-whitepaper) of container security. Istio and Istio Auth addresses two of these layers: "Network Isolation" and "API and Service Endpoint Management". As cluster federation evolves on Kubernetes and other platforms, our intent is for Istio to secure communications across services spanning multiple federated clusters. diff --git a/_blog/2017/0.1-using-network-policy.md b/_blog/2017/0.1-using-network-policy.md index 691f9271bd5b..3e48bbeaee5e 100644 --- a/_blog/2017/0.1-using-network-policy.md +++ b/_blog/2017/0.1-using-network-policy.md @@ -106,11 +106,9 @@ spec: Here is the service graph for the Bookinfo application. {% assign url = home | append: "/docs/guides/img/bookinfo/withistio.svg" %} -{% include figure.html width='80%' ratio='59.08%' - img=url - alt='Bookinfo Service Graph' - title='Bookinfo Service Graph' - caption='Bookinfo Service Graph' +{% include image.html width="80%" ratio="59.08%" + link=url + caption="Bookinfo Service Graph" %} This graph shows every connection that a correctly functioning application should be allowed to make. All other connections, say from the Istio Ingress directly to the Rating service, are not part of the application. Let’s lock out those extraneous connections so they cannot be used by an attacker. Imagine, for example, that the Ingress pod is compromised by an exploit that allows an attacker to run arbitrary code. If we only allow connections to the Product Page pods using Network Policy, the attacker has gained no more access to my application backends _even though they have compromised a member of the service mesh_. diff --git a/_blog/2017/adapter-model.md b/_blog/2017/adapter-model.md index c5cd94afecaa..dda97ec7271d 100644 --- a/_blog/2017/adapter-model.md +++ b/_blog/2017/adapter-model.md @@ -31,11 +31,9 @@ Adapters are Go packages that are directly linked into the Mixer binary. It’s Mixer is essentially an attribute processing and routing machine. The proxy sends it [attributes]({{home}}/docs/concepts/policy-and-control/attributes.html) as part of doing precondition checks and telemetry reports, which it turns into a series of calls into adapters. The operator supplies configuration which describes how to map incoming attributes to inputs for the adapters. {% assign url = home | append: "/docs/concepts/policy-and-control/img/mixer-config/machine.svg" %} -{% include figure.html width='60%' ratio='42.60%' - img=url - alt='Attribute Machine' - title='Attribute Machine' - caption='Attribute Machine' +{% include image.html width="60%" ratio="42.60%" + link=url + caption="Attribute Machine" %} Configuration is a complex task. In fact, evidence shows that the overwhelming majority of service outages are caused by configuration errors. To help combat this, Mixer’s configuration model enforces a number of constraints designed to avoid errors. For example, the configuration model uses strong typing to ensure that only meaningful attributes or attribute expressions are used in any given context. diff --git a/_blog/2017/mixer-spof-myth.md b/_blog/2017/mixer-spof-myth.md index 88851bf343dc..e46c51c9042e 100644 --- a/_blog/2017/mixer-spof-myth.md +++ b/_blog/2017/mixer-spof-myth.md @@ -34,10 +34,9 @@ In 2014, we started an initiative to create a replacement architecture that woul The older system was built around a centralized fleet of fairly heavy proxies into which all incoming traffic would flow, before being forwarded to the services where the real work was done. The newer architecture jettisons the shared proxy design and instead consists of a very lean and efficient distributed sidecar proxy sitting next to service instances, along with a shared fleet of sharded control plane intermediaries: -{% include figure.html width='75%' ratio='74.79%' - img='./img/mixer-spof-myth-1.svg' - alt='Google System Topology' - title='Google System Topology' +{% include image.html width="75%" ratio="74.79%" + link="./img/mixer-spof-myth-1.svg" + title="Google System Topology" caption="Google's API & Service Management System" %} @@ -47,10 +46,8 @@ Look familiar? Of course: it’s just like Istio! Istio was conceived as a secon As shown in the diagram below, Mixer sits between the mesh and the infrastructure backends that support it: -{% include figure.html width='75%' ratio='65.89%' - img='./img/mixer-spof-myth-2.svg' - alt='Istio Topology' - title='Istio Topology' +{% include image.html width="75%" ratio="65.89%" + link="./img/mixer-spof-myth-2.svg" caption="Istio Topology" %} diff --git a/_blog/2018/aws-nlb.md b/_blog/2018/aws-nlb.md index dd48fee409ec..9d47f446aab6 100644 --- a/_blog/2018/aws-nlb.md +++ b/_blog/2018/aws-nlb.md @@ -26,18 +26,14 @@ The following instructions require a Kubernetes **1.9.0 or newer** cluster. You need to apply policy on the master role in order to be able to provision network load balancer. 1. In AWS `iam` console click on policies and click on create a new one: -{% include figure.html width='80%' ratio='60%' - img='./img/createpolicystart.png' - alt='Create a new policy' - title='Create a new policy' - caption='Create a new policy' +{% include image.html width="80%" ratio="60%" + link="./img/createpolicystart.png" + caption="Create a new policy" %} 1. Select `json`: -{% include figure.html width='80%' ratio='60%' - img='./img/createpolicyjson.png' - alt='Select json' - title='Select json' - caption='Select json' +{% include image.html width="80%" ratio="60%" + link="./img/createpolicyjson.png" + caption="Select json" %} 1. Copy/paste text bellow: ```json @@ -79,18 +75,14 @@ You need to apply policy on the master role in order to be able to provision net } ``` 1. Click review policy, fill all fields and click create policy: -{% include figure.html width='80%' ratio='60%' - img='./img/create_policy.png' - alt='Validate policy' - title='Validate policy' - caption='Validate policy' +{% include image.html width="80%" ratio="60%" + link="./img/create_policy.png" + caption="Validate policy" %} 1. Click on roles, select you master role nodes, and click attach policy: -{% include figure.html width='100%' ratio='35%' - img='./img/roles_summary.png' - alt='Attach policy' - title='Attach policy' - caption='Attach policy' +{% include image.html width="100%" ratio="35%" + link="./img/roles_summary.png" + caption="Attach policy" %} 1. Your policy is now attach to your master node. diff --git a/_blog/2018/egress-https.md b/_blog/2018/egress-https.md index f7b98b11c2c1..fd5ac04b73ba 100644 --- a/_blog/2018/egress-https.md +++ b/_blog/2018/egress-https.md @@ -29,11 +29,9 @@ The Bookinfo configuration files reside in the `samples/bookinfo/kube` directory Here is a copy of the end-to-end architecture of the application from the original [Bookinfo Guide]({{home}}/docs/guides/bookinfo.html). {% assign url = home | append: "/docs/guides/img/bookinfo/withistio.svg" %} -{% include figure.html width='80%' ratio='59.08%' - img=url - alt='The Original Bookinfo Application' - title='The Original Bookinfo Application' - caption='The Original Bookinfo Application' +{% include image.html width="80%" ratio="59.08%" + link=url + caption="The Original Bookinfo Application" %} ### Bookinfo with details version 2 @@ -46,11 +44,9 @@ $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-deta The updated architecture of the application now looks as follows: -{% include figure.html width='80%' ratio='65.16%' - img='./img/bookinfo-details-v2.svg' - alt='The Bookinfo Application with details V2' - title='The Bookinfo Application with details V2' - caption='The Bookinfo Application with details V2' +{% include image.html width="80%" ratio="65.16%" + link="./img/bookinfo-details-v2.svg" + caption="The Bookinfo Application with details V2" %} Note that the Google Books web service is outside the Istio service mesh, the boundary of which is marked by a dashed line. @@ -77,11 +73,9 @@ Let's access the web page of the application, after [determining the ingress IP Oops... Instead of the book details we have the _Error fetching product details_ message displayed: -{% include figure.html width='80%' ratio='36.01%' - img='./img/errorFetchingBookDetails.png' - alt='The Error Fetching Product Details Message' - title='The Error Fetching Product Details Message' - caption='The Error Fetching Product Details Message' +{% include image.html width="80%" ratio="36.01%" + link="./img/errorFetchingBookDetails.png" + caption="The Error Fetching Product Details Message" %} The good news is that our application did not crash. With a good microservice design, we do not have **failure propagation**. In our case, the failing _details_ microservice does not cause the _productpage_ microservice to fail. Most of the functionality of the application is still provided, despite the failure in the _details_ microservice. We have **graceful service degradation**: as you can see, the reviews and the ratings are displayed correctly, and the application is still useful. @@ -110,11 +104,9 @@ EOF Now accessing the web page of the application displays the book details without error: -{% include figure.html width='80%' ratio='34.82%' - img='./img/externalBookDetails.png' - alt='Book Details Displayed Correctly' - title='Book Details Displayed Correctly' - caption='Book Details Displayed Correctly' +{% include image.html width="80%" ratio="34.82%" + link="./img/externalBookDetails.png" + caption="Book Details Displayed Correctly" %} Note that our egress rule allows traffic to any domain matching _*.googleapis.com_, on port 443, using the HTTPS protocol. Let's assume for the sake of the example that the applications in our Istio service mesh must access multiple subdomains of _googleapis.com_, for example _www.googleapis.com_ and also _fcm.googleapis.com_. Our rule allows traffic to both _www.googleapis.com_ and _fcm.googleapis.com_, since they both match _*.googleapis.com_. This **wildcard** feature allows us to enable traffic to multiple domains using a single egress rule. @@ -148,11 +140,9 @@ To allow Istio to perform filtering of egress requests based on domains, the mic The diagram below shows how the HTTPS traffic to external services is performed. On the top, a microservice outside an Istio service mesh sends regular HTTPS requests, encrypted end-to-end. On the bottom, the same microservice inside an Istio service mesh must send unencrypted HTTP requests inside a pod, which are intercepted by the sidecar Envoy proxy. The sidecar proxy performs TLS origination, so the traffic between the pod and the external service is encrypted. -{% include figure.html width='80%' ratio='65.16%' - img='./img/https_from_the_app.svg' - alt='HTTPS traffic to external services, from outside vs. from inside an Istio service mesh' - title='HTTPS traffic to external services, from outside vs. from inside an Istio service mesh' - caption='HTTPS traffic to external services, from outside vs. from inside an Istio service mesh' +{% include image.html width="80%" ratio="65.16%" + link="./img/https_from_the_app.svg" + caption="HTTPS traffic to external services, from outside vs. from inside an Istio service mesh" %} Here is how we code this behavior in the [the Bookinfo details microservice code](https://github.com/istio/istio/blob/master/samples/bookinfo/src/details/details.rb), using the Ruby [net/http module](https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html): diff --git a/_blog/2018/egress-tcp.md b/_blog/2018/egress-tcp.md index b9524585acde..49943a4f5e76 100644 --- a/_blog/2018/egress-tcp.md +++ b/_blog/2018/egress-tcp.md @@ -118,11 +118,9 @@ The example commands in this blog post work with Istio 0.3+, with or without [Mu As a reminder, here is the end-to-end architecture of the application from the [Bookinfo Guide]({{home}}/docs/guides/bookinfo.html). {% assign url = home | append: "/docs/guides/img/bookinfo/withistio.svg" %} -{% include figure.html width='80%' ratio='59.08%' - img=url - alt='The original Bookinfo application' - title='The original Bookinfo application' - caption='The original Bookinfo application' +{% include image.html width="80%" ratio="59.08%" + link=url + caption="The original Bookinfo application" %} ### Use the database for ratings data in Bookinfo application @@ -159,11 +157,9 @@ service. In addition, I route all the traffic destined to the _ratings_ service The updated architecture appears below. Note that the blue arrows inside the mesh mark the traffic configured according to the route rules we added. According to the route rules, the traffic is sent to _reviews v3_ and _ratings v2-mysql_. -{% include figure.html width='80%' ratio='59.31%' - img='./img/bookinfo-ratings-v2-mysql-external.svg' - alt='The Bookinfo application with ratings v2-mysql and an external MySQL database' - title='The Bookinfo application with ratings v2-mysql and an external MySQL database' - caption='The Bookinfo application with ratings v2-mysql and an external MySQL database' +{% include image.html width="80%" ratio="59.31%" + link="./img/bookinfo-ratings-v2-mysql-external.svg" + caption="The Bookinfo application with ratings v2-mysql and an external MySQL database" %} Note that the MySQL database is outside the Istio service mesh, or more precisely outside the Kubernetes cluster. The boundary of the service mesh is marked by a dashed line. @@ -174,11 +170,9 @@ Let's access the webpage of the application, after [determining the ingress IP a We have a problem... Instead of the rating stars, the message _"Ratings service is currently unavailable"_ is currently displayed below each review: -{% include figure.html width='80%' ratio='36.19%' - img='./img/errorFetchingBookRating.png' - alt='The Ratings service error messages' - title='The Ratings service error messages' - caption='The Ratings service error messages' +{% include image.html width="80%" ratio="36.19%" + link="./img/errorFetchingBookRating.png" + caption="The Ratings service error messages" %} As in [Consuming External Web Services]({{home}}/blog/2018/egress-https.html), we experience **graceful service degradation**, which is good. The application did not crash due to the error in the _ratings_ microservice. The webpage of the application correctly displayed the book information, the details, and the reviews, just without the rating stars. @@ -213,11 +207,9 @@ Note that for a TCP egress rule, we specify `tcp` as the protocol of a port of t It worked! Accessing the web page of the application displays the ratings without error: -{% include figure.html width='80%' ratio='36.69%' - img='./img/externalMySQLRatings.png' - alt='Book Ratings Displayed Correctly' - title='Book Ratings Displayed Correctly' - caption='Book Ratings Displayed Correctly' +{% include image.html width="80%" ratio="36.69%" + link="./img/externalMySQLRatings.png" + caption="Book Ratings Displayed Correctly" %} Note that we see a one-star rating for both displayed reviews, as expected. I changed the ratings to be one star to provide us with a visual clue that our external database is indeed being used. diff --git a/_blog/2018/v1alpha3-routing.md b/_blog/2018/v1alpha3-routing.md index 4699fc1e8906..b5c38b69c84c 100644 --- a/_blog/2018/v1alpha3-routing.md +++ b/_blog/2018/v1alpha3-routing.md @@ -54,11 +54,10 @@ services (e.g., Google Maps API). These may be called directly or, in certain de exiting the mesh may be forced through dedicated egress gateways. The following diagram depicts this mental model. -{% include figure.html width='80%' ratio='65.16%' - img='./img/gateways.svg' - alt='Role of gateways in the mesh' - title='Gateways in an Istio service mesh' - caption='Gateways in an Istio service mesh' +{% include image.html width="80%" ratio="65.16%" + link="./img/gateways.svg" + alt="Role of gateways in the mesh" + caption="Gateways in an Istio service mesh" %} With the above setup in mind, `v1alpha3` introduces the following new @@ -77,11 +76,9 @@ dedicated middleboxes. The figure below depicts the flow of control across configuration resources. -{% include figure.html width='80%' ratio='65.16%' - img='./img/virtualservices-destrules.svg' - alt='Relationship between different v1alpha3 elements' - title='Relationship between different v1alpha3 elements' - caption='Relationship between different v1alpha3 elements' +{% include image.html width="80%" ratio="65.16%" + link="./img/virtualservices-destrules.svg" + caption="Relationship between different v1alpha3 elements" %} ### Gateway diff --git a/_docs/concepts/policy-and-control/mixer-config.md b/_docs/concepts/policy-and-control/mixer-config.md index 2414a1ef209c..b4fb99cf65de 100644 --- a/_docs/concepts/policy-and-control/mixer-config.md +++ b/_docs/concepts/policy-and-control/mixer-config.md @@ -43,11 +43,9 @@ The set of attributes determines which backend Mixer calls for a given request a each is given. In order to hide the details of individual backends, Mixer uses modules known as [*adapters*](./mixer.html#adapters). -{% include figure.html width='60%' ratio='42.60%' - img='./img/mixer-config/machine.svg' - alt='Attribute Machine' - title='Attribute Machine' - caption='Attribute Machine' +{% include image.html width="60%" ratio="42.60%" + link="./img/mixer-config/machine.svg" + caption="Attribute Machine" %} Mixer's configuration has the following central responsibilities: diff --git a/_docs/concepts/policy-and-control/mixer.md b/_docs/concepts/policy-and-control/mixer.md index 9921d9fdf7ef..ca4abf3f3641 100644 --- a/_docs/concepts/policy-and-control/mixer.md +++ b/_docs/concepts/policy-and-control/mixer.md @@ -29,11 +29,10 @@ Mixer is designed to change the boundaries between layers in order to reduce systemic complexity, eliminating policy logic from service code and giving control to operators instead. -{% include figure.html width='60%' ratio='59%' - img='./img/mixer/traffic.svg' - alt='Showing the flow of traffic through Mixer.' - title='Mixer Traffic Flow' - caption='Mixer Traffic Flow' +{% include image.html width="60%" ratio="59%" + link="./img/mixer/traffic.svg" + alt="Showing the flow of traffic through Mixer." + caption="Mixer Traffic Flow" %} Mixer provides three core features: @@ -72,11 +71,10 @@ single consistent API, independent of the backends in use. The exact set of adapters used at runtime is determined through configuration and can easily be extended to target new or custom infrastructure backends. -{% include figure.html width='35%' ratio='138%' - img='./img/mixer/adapters.svg' - alt='Showing Mixer with adapters.' - title='Mixer and its Adapters' - caption='Mixer and its Adapters' +{% include image.html width="35%" ratio="138%" + link="./img/mixer/adapters.svg" + alt="Showing Mixer with adapters." + caption="Mixer and its Adapters" %} ## Configuration state @@ -136,11 +134,10 @@ phases: parameters. The Adapter Dispatching phase invokes the adapters associated with each aspect and passes them those parameters. -{% include figure.html width='50%' ratio='144%' - img='./img/mixer/phases.svg' - alt='Phases of Mixer request processing.' - title='Request Phases' - caption='Request Phases' +{% include image.html width="50%" ratio="144%" + link="./img/mixer/phases.svg" + alt="Phases of Mixer request processing." + caption="Request Phases" %} ## What's next diff --git a/_docs/concepts/security/authn-policy.md b/_docs/concepts/security/authn-policy.md index 9ad14c2e51b0..02aac8736b80 100644 --- a/_docs/concepts/security/authn-policy.md +++ b/_docs/concepts/security/authn-policy.md @@ -19,11 +19,9 @@ Identities from both authentication parts, if applicable, are output to the next Authentication policies are saved in Istio config store (in 0.7, the storage implementation uses Kubernetes CRD), and distributed by control plane. Depending on the size of the mesh, config propagation may take a few seconds to a few minutes. During the transition, you can expect traffic lost or inconsistent authentication results. -{% include figure.html width='80%' ratio='100%' - img='./img/authn.svg' - alt='Istio authentication policy architecture' - title='Istio authentication policy architecture' - caption='Istio authentication policy architecture' +{% include image.html width="80%" ratio="100%" + link="./img/authn.svg" + caption="Istio authentication policy architecture" %} Policy is scoped to namespaces, with (optional) target selector rules to narrow down the set of services (within the same namespace as the policy) on which the policy should be applied. This aligns with the ACL model based on Kubernetes RBAC. More specifically, only the admin of the namespace can set policies for services in that namespace. diff --git a/_docs/concepts/security/mutual-tls.md b/_docs/concepts/security/mutual-tls.md index 1ece86e9eca4..b59fab9dc41d 100644 --- a/_docs/concepts/security/mutual-tls.md +++ b/_docs/concepts/security/mutual-tls.md @@ -24,11 +24,10 @@ security. This diagram describes how Istio is used to secure the service-to-serv as the service account 'frontend-team' and service 'backend' running as the service account 'backend-team'. Istio supports services running on both Kubernetes containers and VM/bare-metal machines. -{% include figure.html width='80%' ratio='56.25%' - img='./img/mutual-tls/auth.svg' - alt='Components making up the Istio auth model.' - title='Istio Security Architecture' - caption='Istio Security Architecture' +{% include image.html width="80%" ratio="56.25%" + link="./img/mutual-tls/auth.svg" + alt="Components making up the Istio auth model." + caption="Istio Security Architecture" %} As illustrated in the diagram, Istio leverages secret volume mount to deliver keys/certs from Citadel to Kubernetes containers. For services running on diff --git a/_docs/concepts/security/rbac.md b/_docs/concepts/security/rbac.md index 8d322cca1b45..ead114865c56 100644 --- a/_docs/concepts/security/rbac.md +++ b/_docs/concepts/security/rbac.md @@ -22,11 +22,10 @@ It features: The diagram below shows the Istio RBAC architecture. Operators specify Istio RBAC policies. The policies are saved in the Istio config store. -{% include figure.html width='80%' ratio='56.25%' - img='./img/IstioRBAC.svg' - alt='Istio RBAC' - title='Istio RBAC Architecture' - caption='Istio RBAC Architecture' +{% include image.html width="80%" ratio="56.25%" + link="./img/IstioRBAC.svg" + alt="Istio RBAC" + caption="Istio RBAC Architecture" %} The Istio RBAC engine does two things: diff --git a/_docs/concepts/traffic-management/load-balancing.md b/_docs/concepts/traffic-management/load-balancing.md index 37db243b84d1..ead3ffdb3759 100644 --- a/_docs/concepts/traffic-management/load-balancing.md +++ b/_docs/concepts/traffic-management/load-balancing.md @@ -23,11 +23,9 @@ registry and provides a platform-agnostic service discovery interface. Envoy instances in the mesh perform service discovery and dynamically update their load balancing pools accordingly. -{% include figure.html width='80%' ratio='74.79%' - img='./img/pilot/LoadBalancing.svg' - alt='Discovery and Load Balancing' - title='Discovery and Load Balancing' - caption='Discovery and Load Balancing' +{% include image.html width="80%" ratio="74.79%" + link="./img/pilot/LoadBalancing.svg" + caption="Discovery and Load Balancing" %} As illustrated in the figure above, services in the mesh access each other diff --git a/_docs/concepts/traffic-management/overview.md b/_docs/concepts/traffic-management/overview.md index 64f856bdce5d..8497c2867fc2 100644 --- a/_docs/concepts/traffic-management/overview.md +++ b/_docs/concepts/traffic-management/overview.md @@ -43,11 +43,9 @@ of traffic for a particular service to go to a canary version irrespective of the size of the canary deployment, or send traffic to a particular version depending on the content of the request. -{% include figure.html width='85%' ratio='69.52%' - img='./img/pilot/TrafficManagementOverview.svg' - alt='Traffic Management with Istio' - title='Traffic Management with Istio' - caption='Traffic Management with Istio' +{% include image.html width="85%" ratio="69.52%" + link="./img/pilot/TrafficManagementOverview.svg" + caption="Traffic Management with Istio" %} Decoupling traffic flow from infrastructure scaling like this allows Istio diff --git a/_docs/concepts/traffic-management/pilot.md b/_docs/concepts/traffic-management/pilot.md index 40f301717e08..13c65c745f71 100644 --- a/_docs/concepts/traffic-management/pilot.md +++ b/_docs/concepts/traffic-management/pilot.md @@ -12,11 +12,10 @@ redirect_from: /docs/concepts/traffic-management/manager.html Pilot is responsible for the lifecycle of Envoy instances deployed across the Istio service mesh. -{% include figure.html width='60%' ratio='72.17%' - img='./img/pilot/PilotAdapters.svg' +{% include image.html width="60%" ratio="72.17%" + link="./img/pilot/PilotAdapters.svg" alt="Pilot's overall architecture." - title='Pilot Architecture' - caption='Pilot Architecture' + caption="Pilot Architecture" %} As illustrated in the figure above, Pilot maintains a canonical diff --git a/_docs/concepts/traffic-management/request-routing.md b/_docs/concepts/traffic-management/request-routing.md index 2de211c43623..01f12851dbcf 100644 --- a/_docs/concepts/traffic-management/request-routing.md +++ b/_docs/concepts/traffic-management/request-routing.md @@ -30,11 +30,10 @@ additional control over traffic between services. ## Communication between services -{% include figure.html width='60%' ratio='100.42%' - img='./img/pilot/ServiceModel_Versions.svg' - alt='Showing how service versions are handled.' - title='Service Versions' - caption='Service Versions' +{% include image.html width="60%" ratio="100.42%" + link="./img/pilot/ServiceModel_Versions.svg" + alt="Showing how service versions are handled." + caption="Service Versions" %} As illustrated in the figure above, clients of a service have no knowledge @@ -71,10 +70,9 @@ via the sidecar Envoy, operators can add failure recovery features such as timeouts, retries, circuit breakers, etc., and obtain detailed metrics on the connections to these services. -{% include figure.html width='60%' ratio='28.88%' - img='./img/pilot/ServiceModel_RequestFlow.svg' - alt='Ingress and Egress through Envoy.' - title='Request Flow' - caption='Request Flow' +{% include image.html width="60%" ratio="28.88%" + link="./img/pilot/ServiceModel_RequestFlow.svg" + alt="Ingress and Egress through Envoy." + caption="Request Flow" %} diff --git a/_docs/concepts/what-is-istio/overview.md b/_docs/concepts/what-is-istio/overview.md index 869f8f01bf9c..a3963965cc3a 100644 --- a/_docs/concepts/what-is-istio/overview.md +++ b/_docs/concepts/what-is-istio/overview.md @@ -59,11 +59,10 @@ configuring proxies to route traffic, as well as enforcing policies at runtime. The following diagram shows the different components that make up each plane: -{% include figure.html width='80%' ratio='56.25%' - img='./img/overview/arch.svg' - alt='The overall architecture of an Istio-based application.' - title='Istio Architecture' - caption='Istio Architecture' +{% include image.html width="80%" ratio="56.25%" + link="./img/overview/arch.svg" + alt="The overall architecture of an Istio-based application." + caption="Istio Architecture" %} ### Envoy diff --git a/_docs/guides/bookinfo.md b/_docs/guides/bookinfo.md index 3de2a3ae44e3..4761c96236b5 100644 --- a/_docs/guides/bookinfo.md +++ b/_docs/guides/bookinfo.md @@ -32,11 +32,9 @@ There are 3 versions of the reviews microservice: The end-to-end architecture of the application is shown below. -{% include figure.html width='80%' ratio='68.52%' - img='./img/bookinfo/noistio.svg' - alt='Bookinfo Application without Istio' - title='Bookinfo Application without Istio' - caption='Bookinfo Application without Istio' +{% include image.html width="80%" ratio="68.52%" + link="./img/bookinfo/noistio.svg" + caption="Bookinfo Application without Istio" %} This application is polyglot, i.e., the microservices are written in different languages. @@ -57,11 +55,9 @@ Istio-enabled environment, with Envoy sidecars injected along side each service. The needed commands and configuration vary depending on the runtime environment although in all cases the resulting deployment will look like this: -{% include figure.html width='80%' ratio='59.08%' - img='./img/bookinfo/withistio.svg' - alt='Bookinfo Application' - title='Bookinfo Application' - caption='Bookinfo Application' +{% include image.html width="80%" ratio="59.08%" + link="./img/bookinfo/withistio.svg" + caption="Bookinfo Application" %} All of the microservices will be packaged with an Envoy sidecar that intercepts incoming diff --git a/_docs/guides/integrating-vms.md b/_docs/guides/integrating-vms.md index 0e2729d3653c..aef23e1fe08e 100644 --- a/_docs/guides/integrating-vms.md +++ b/_docs/guides/integrating-vms.md @@ -16,11 +16,9 @@ VMs cannot initiate any direct communication to Kubernetes Pods even when using ## Overview -{% include figure.html width='80%' ratio='56.78%' - img='./img/mesh-expansion.svg' - alt='Bookinfo Application with Istio Mesh Expansion' - title='Bookinfo Application with Istio Mesh Expansion' - caption='Bookinfo Application with Istio Mesh Expansion' +{% include image.html width="80%" ratio="56.78%" + link="./img/mesh-expansion.svg" + caption="Bookinfo Application with Istio Mesh Expansion" %} <!-- source of the drawing https://docs.google.com/drawings/d/1gQp1OTusiccd-JUOHktQ9RFZaqREoQbwl2Vb-P3XlRQ/edit --> diff --git a/_docs/setup/kubernetes/quick-start-gke-dm.md b/_docs/setup/kubernetes/quick-start-gke-dm.md index 450be1dc625c..3942c0d79bd0 100644 --- a/_docs/setup/kubernetes/quick-start-gke-dm.md +++ b/_docs/setup/kubernetes/quick-start-gke-dm.md @@ -27,20 +27,16 @@ application. It uses Deployment Manager to automate the steps detailed in the [ To set this, navigate to the **IAM** section of the [Cloud Console](https://console.cloud.google.com/iam-admin/iam/project) as shown below and find your default GCE/GKE service account in the following form: `projectNumber-compute@developer.gserviceaccount.com`: by default it should just have the **Editor** role. Then in the **Roles** drop-down list for that account, find the **Kubernetes Engine** group and select the role **Kubernetes Engine Admin**. The **Roles** listing for your account will change to **Multiple**. - {% include figure.html width="100%" ratio="30%" - img='./img/dm_gcp_iam.png' - alt='GCP-IAM Service' - title='GCP-IAM Service' - caption='GKE-IAM Service' + {% include image.html width="100%" ratio="30%" + link="./img/dm_gcp_iam.png" + caption="GKE-IAM Service" %} Then add the ```Kubernetes Engine Admin``` Role - {% include figure.html width="100%" ratio="37%" - img='./img/dm_gcp_iam_role.png' - alt='GCP-IAM Role' - title='GCP-IAM Role' - caption='GKE-IAM Role' + {% include image.html width="100%" ratio="37%" + link="./img/dm_gcp_iam_role.png" + caption="GKE-IAM Role" %} ## Setup @@ -62,11 +58,9 @@ Then add the ```Kubernetes Engine Admin``` Role 1. Click **Deploy**: - {% include figure.html width="100%" ratio="67.17%" - img='./img/dm_launcher.png' - alt='GKE-Istio Launcher' - title='GKE-Istio Launcher' - caption='GKE-Istio Launcher' + {% include image.html width="100%" ratio="67.17%" + link="./img/dm_launcher.png" + caption="GKE-Istio Launcher" %} Wait until Istio is fully deployed. Note that this can take up to five minutes. @@ -130,11 +124,9 @@ Note down the IP and Port assigned to Bookinfo product page. (in the example abo You can also view the installation using the ***Kubernetes Engine -> Workloads** section on the [Cloud Console](https://console.cloud.google.com/kubernetes/workload): -{% include figure.html width="100%" ratio="65.37%" - img='./img/dm_kubernetes_workloads.png' - alt='GKE-Workloads' - title='GKE-Workloads' - caption='GKE-Workloads' +{% include image.html width="100%" ratio="65.37%" + link="./img/dm_kubernetes_workloads.png" + caption="GKE-Workloads" %} ### Access the Bookinfo sample @@ -148,11 +140,9 @@ You can also view the installation using the ***Kubernetes Engine -> Workloads** 1. Verify you can access the Bookinfo ```http://${GATEWAY_URL}/productpage```: - {% include figure.html width="100%" ratio="45.04%" - img='./img/dm_bookinfo.png' - alt='Bookinfo' - title='Bookinfo' - caption='Bookinfo' + {% include image.html width="100%" ratio="45.04%" + link="./img/dm_bookinfo.png" + caption="Bookinfo" %} 1. Now send some traffic to it: @@ -179,11 +169,9 @@ http://localhost:3000/dashboard/db/istio-dashboard ``` You should see some statistics for the requests you sent earlier. -{% include figure.html width="100%" ratio="48.49%" - img='./img/dm_grafana.png' - alt='Grafana' - title='Grafana' - caption='Grafana' +{% include image.html width="100%" ratio="48.49%" + link="./img/dm_grafana.png" + caption="Grafana" %} For more details about using Grafana, see [About the Grafana Add-on]({{home}}/docs/tasks/telemetry/using-istio-dashboard.html#about-the-grafana-add-on). @@ -202,11 +190,9 @@ View the console at: http://localhost:9090/graph ``` -{% include figure.html width="100%" ratio="43.88%" - img='./img/dm_prometheus.png' - alt='Prometheus' - title='Prometheus' - caption='Prometheus' +{% include image.html width="100%" ratio="43.88%" + link="./img/dm_prometheus.png" + caption="Prometheus" %} For more details, see [About the Prometheus Add-on]({{home}}/docs/tasks/telemetry/querying-metrics.html#about-the-prometheus-add-on). @@ -225,11 +211,9 @@ You should see the Bookinfo service topology at http://localhost:8088/dotviz ``` -{% include figure.html width="100%" ratio="53.33%" - img='./img/dm_servicegraph.png' - alt='ServiceGraph' - title='ServiceGraph' - caption='ServiceGraph' +{% include image.html width="100%" ratio="53.33%" + link="./img/dm_servicegraph.png" + caption="ServiceGraph" %} For more details, see [About the ServiceGraph Add-on]({{home}}/docs/tasks/telemetry/servicegraph.html#about-the-servicegraph-add-on). @@ -248,11 +232,9 @@ You should see the trace statistics sent earlier: http://localhost:9411 ``` -{% include figure.html width="100%" ratio="57.00%" - img='./img/dm_zipkin.png' - alt='Zipkin' - title='Zipkin' - caption='Zipkin' +{% include image.html width="100%" ratio="57.00%" + link="./img/dm_zipkin.png" + caption="Zipkin" %} For more details on tracing see [Understanding what happened]({{home}}/docs/tasks/telemetry/distributed-tracing.html#understanding-what-happened). diff --git a/_docs/tasks/telemetry/distributed-tracing.md b/_docs/tasks/telemetry/distributed-tracing.md index 7ed0835814fb..d1a6d9ec6c6f 100644 --- a/_docs/tasks/telemetry/distributed-tracing.md +++ b/_docs/tasks/telemetry/distributed-tracing.md @@ -67,36 +67,28 @@ With the Bookinfo application up and running, generate trace information by acce If you now look at the dashboard, you should see something similar to the following: -{% include figure.html width='100%' ratio='44.28%' - img='./img/zipkin_dashboard.png' - alt='Zipkin Dashboard' - title='Zipkin Dashboard' - caption='Zipkin Dashboard' +{% include image.html width="100%" ratio="44.28%" + link="./img/zipkin_dashboard.png" + caption="Zipkin Dashboard" %} -{% include figure.html width='100%' ratio='42.35%' - img='./img/jaeger_dashboard.png' - alt='Jaeger Dashboard' - title='Jaeger Dashboard' - caption='Jaeger Dashboard' +{% include image.html width="100%" ratio="42.35%" + link="./img/jaeger_dashboard.png" + caption="Jaeger Dashboard" %} If you click on the top (most recent) trace, you should see the details corresponding to your latest refresh of the `/productpage`. The page should look something like this: -{% include figure.html width='100%' ratio='19.70%' - img='./img/zipkin_span.png' - alt='Zipkin Trace View' - title='Zipkin Trace View' - caption='Zipkin Trace View' +{% include image.html width="100%" ratio="19.70%" + link="./img/zipkin_span.png" + caption="Zipkin Trace View" %} -{% include figure.html width='100%' ratio='26.99%' - img='./img/jaeger_trace.png' - alt='Jaeger Trace View' - title='Jaeger Trace View' - caption='Jaeger Trace View' +{% include image.html width="100%" ratio="26.99%" + link="./img/jaeger_trace.png" + caption="Jaeger Trace View" %} As you can see, the trace is comprised of spans, diff --git a/_docs/tasks/telemetry/querying-metrics.md b/_docs/tasks/telemetry/querying-metrics.md index 7b91d0b96fe1..f66c1909f493 100644 --- a/_docs/tasks/telemetry/querying-metrics.md +++ b/_docs/tasks/telemetry/querying-metrics.md @@ -60,11 +60,9 @@ application. The results will be similar to: -{% include figure.html width='100%' ratio='39.36%' - img='./img/prometheus_query_result.png' - alt='Prometheus Query Result' - title='Prometheus Query Result' - caption='Prometheus Query Result' +{% include image.html width="100%" ratio="39.36%" + link="./img/prometheus_query_result.png" + caption="Prometheus Query Result" %} Other queries to try: diff --git a/_docs/tasks/telemetry/servicegraph.md b/_docs/tasks/telemetry/servicegraph.md index 0d913b8e6a8a..fb80b067fefd 100644 --- a/_docs/tasks/telemetry/servicegraph.md +++ b/_docs/tasks/telemetry/servicegraph.md @@ -69,11 +69,9 @@ the example application throughout this task. The results will look similar to: - {% include figure.html width='75%' ratio='107.7%' - img='./img/servicegraph-example.png' - alt='Example Servicegraph' - title='Example Servicegraph' - caption='Example Servicegraph' + {% include image.html width="75%" ratio="107.7%" + link="./img/servicegraph-example.png" + caption="Example Servicegraph" %} 1. Experiment with Query Parameters diff --git a/_docs/tasks/telemetry/tcp-metrics.md b/_docs/tasks/telemetry/tcp-metrics.md index 4e6bd82419f9..3c2a5cdc2c04 100644 --- a/_docs/tasks/telemetry/tcp-metrics.md +++ b/_docs/tasks/telemetry/tcp-metrics.md @@ -210,11 +210,10 @@ Several TCP-specific attributes enable TCP policy and control within Istio. These attributes are generated by server-side Envoy proxies. They are forwarded to Mixer at connection establishment, and forwarded periodically when connection is alive (periodical report), and forwarded at connection close (final report). The default interval for periodical report is 10 seconds, and it should be at least 1 second. Additionally, context attributes provide the ability to distinguish between `http` and `tcp` protocols within policies. -{% include figure.html width='100%' ratio='192.50%' - img='./img/istio-tcp-attribute-flow.svg' - alt='Attribute Generation Flow for TCP Services in an Istio Mesh.' - title='TCP Attribute Flow' - caption='TCP Attribute Flow' +{% include image.html width="100%" ratio="192.50%" + link="./img/istio-tcp-attribute-flow.svg" + alt="Attribute Generation Flow for TCP Services in an Istio Mesh." + caption="TCP Attribute Flow" %} ## Cleanup diff --git a/_docs/tasks/telemetry/using-istio-dashboard.md b/_docs/tasks/telemetry/using-istio-dashboard.md index 2a94b75ccecf..7dbbaecb70e5 100644 --- a/_docs/tasks/telemetry/using-istio-dashboard.md +++ b/_docs/tasks/telemetry/using-istio-dashboard.md @@ -52,11 +52,9 @@ the example application throughout this task. The Istio Dashboard will look similar to: - {% include figure.html width='100%' ratio='56.57%' - img='./img/grafana-istio-dashboard.png' - alt='Istio Dashboard' - title='Istio Dashboard' - caption='Istio Dashboard' + {% include image.html width="100%" ratio="56.57%" + link="./img/grafana-istio-dashboard.png" + caption="Istio Dashboard" %} 1. Send traffic to the mesh. @@ -74,11 +72,9 @@ the example application throughout this task. Look at the Istio Dashboard again. It should reflect the traffic that was generated. It will look similar to: - {% include figure.html width='100%' ratio='56.57%' - img='./img/dashboard-with-traffic.png' - alt='Istio Dashboard With Traffic' - title='Istio Dashboard With Traffic' - caption='Istio Dashboard With Traffic' + {% include image.html width="100%" ratio="56.57%" + link="./img/dashboard-with-traffic.png" + caption="Istio Dashboard With Traffic" %} > `$GATEWAY_URL` is the value set in the [Bookinfo]({{home}}/docs/guides/bookinfo.html) guide. diff --git a/_includes/figure.html b/_includes/figure.html deleted file mode 100644 index b3ed3896d565..000000000000 --- a/_includes/figure.html +++ /dev/null @@ -1,26 +0,0 @@ -{% comment %} -Purpose: - Inserts a figure into a page. The user of this template specifies the - relative width of the figure in percentage, and an aspect ratio value in - lieu of the Y coordinate. Through CSS trickery, these two values let us - calculate the actual width and height of the image at render time in such - a way that it avoids the typical 'shifting text' problem as images are - loaded asynchronously. - -Usage: - {% include figure.html width='<NN>%' ratio='<NN>%' - img='<path to image file>' - alt='<text to display when the image is not available>' - title='<text to display when hovering over the image>' - caption='<text to display below the image>' - %} -{% endcomment %} - -<figure style="width: {{include.width}}"> - <div class="wrapper-with-intrinsic-ratio" style="padding-bottom: {{include.ratio}}"> - <a class="not-for-endnotes" href="{{include.img}}"> - <img class="element-to-stretch" src="{{include.img}}" alt="{{include.alt}}" title="{{include.title}}" /> - </a> - </div> - <figcaption>{{include.caption}}</figcaption> -</figure> diff --git a/_includes/image.html b/_includes/image.html new file mode 100644 index 000000000000..ddc72e3ce707 --- /dev/null +++ b/_includes/image.html @@ -0,0 +1,38 @@ +{% comment %} +Purpose: + Inserts a figure into a page. The user of this template specifies the + relative width of the figure in percentage, and an aspect ratio value in + lieu of the Y coordinate. Through CSS trickery, these two values let us + calculate the actual width and height of the image at render time in such + a way that it avoids the typical 'shifting text' problem as images are + loaded asynchronously. + +Usage: + {% include image.html width="<NN>%" ratio="<NN>%" + link="<path to image file>" + alt="<text to display when the image is not available>" + title="<text to display when hovering over the image>" + caption="<text to display below the image>" + %} +{% endcomment %} + +{% assign caption = include.caption %} + +{% assign title = include.title %} +{% if title == nil %}" + {% assign title = caption %} +{% endif %} + +{% assign alt = include.alt %} +{% if alt == nil %} + {% assign alt = title %} +{% endif %} + +<figure style="width: {{include.width}}"> + <div class="wrapper-with-intrinsic-ratio" style="padding-bottom: {{include.ratio}}"> + <a class="not-for-endnotes" href="{{include.link}}"> + <img class="element-to-stretch" src="{{include.link}}" alt="{{alt}}" title="{{title}}" /> + </a> + </div> + <figcaption>{{caption}}</figcaption> +</figure> From 399d4ad6bc7bc77179058dd6970f5025d58886e3 Mon Sep 17 00:00:00 2001 From: Martin Taillefer <geeknoid@users.noreply.github.com> Date: Sun, 13 May 2018 09:59:17 -0700 Subject: [PATCH 188/191] Change publish_date front-matter to publishdate to aid in the Jekyll to Hugo migration. (#1276) --- _about/contribute/writing-a-new-topic.md | 2 +- _blog/2017/0.1-announcement.md | 2 +- _blog/2017/0.1-auth.md | 2 +- _blog/2017/0.1-canary.md | 2 +- _blog/2017/0.1-using-network-policy.md | 2 +- _blog/2017/0.2-announcement.md | 2 +- _blog/2017/adapter-model.md | 2 +- _blog/2017/mixer-spof-myth.md | 2 +- _blog/2018/aws-nlb.md | 2 +- _blog/2018/egress-https.md | 2 +- _blog/2018/egress-tcp.md | 2 +- _blog/2018/soft-multitenancy.md | 2 +- _blog/2018/traffic-mirroring.md | 2 +- _blog/2018/v1alpha3-routing.md | 2 +- _includes/primary.html | 4 ++-- feed.xml | 2 +- 16 files changed, 17 insertions(+), 17 deletions(-) diff --git a/_about/contribute/writing-a-new-topic.md b/_about/contribute/writing-a-new-topic.md index 96ac1b190c28..4e4b7cc0f744 100644 --- a/_about/contribute/writing-a-new-topic.md +++ b/_about/contribute/writing-a-new-topic.md @@ -102,7 +102,7 @@ matter fields are: |`weight` | An integer used to determine the sort order of this page relative to other pages in the same directory. |`layout` | Indicates which of the Jekyll layouts this page uses |`draft` | When true, prevents the page from showing up in any navigation area -|`publish_date` | For blog posts, indicates the date of publication of the post +|`publishdate` | For blog posts, indicates the date of publication of the post |`subtitle` | For blog posts, supplies an optional subtitle to be displayed below the main title |`attribution` | For blog posts, supplies an optional author's name |`toc` | Set this to false to prevent the page from having a table of contents generated for it diff --git a/_blog/2017/0.1-announcement.md b/_blog/2017/0.1-announcement.md index 0108bbfec2b7..871a64e6afa2 100644 --- a/_blog/2017/0.1-announcement.md +++ b/_blog/2017/0.1-announcement.md @@ -1,7 +1,7 @@ --- title: Introducing Istio description: Istio 0.1 announcement -publish_date: May 24, 2017 +publishdate: 2018-05-24 subtitle: A robust service mesh for microservices attribution: The Istio Team diff --git a/_blog/2017/0.1-auth.md b/_blog/2017/0.1-auth.md index ecf91456e172..0e2158381f94 100644 --- a/_blog/2017/0.1-auth.md +++ b/_blog/2017/0.1-auth.md @@ -1,7 +1,7 @@ --- title: Using Istio to Improve End-to-End Security description: Istio Auth 0.1 announcement -publish_date: May 25, 2017 +publishdate: 2017-05-25 subtitle: Secure by default service to service communications attribution: The Istio Team diff --git a/_blog/2017/0.1-canary.md b/_blog/2017/0.1-canary.md index 7b59504bae0e..361f1d53f77e 100644 --- a/_blog/2017/0.1-canary.md +++ b/_blog/2017/0.1-canary.md @@ -1,7 +1,7 @@ --- title: Canary Deployments using Istio description: Using Istio to create autoscaled canary deployments -publish_date: June 14, 2017 +publishdate: 2017-06-14 subtitle: attribution: Frank Budinsky diff --git a/_blog/2017/0.1-using-network-policy.md b/_blog/2017/0.1-using-network-policy.md index 3e48bbeaee5e..2689c21a8e86 100644 --- a/_blog/2017/0.1-using-network-policy.md +++ b/_blog/2017/0.1-using-network-policy.md @@ -1,7 +1,7 @@ --- title: Using Network Policy with Istio description: How Kubernetes Network Policy relates to Istio policy -publish_date: August 10, 2017 +publishdate: 2017-08-10 subtitle: attribution: Spike Curtis diff --git a/_blog/2017/0.2-announcement.md b/_blog/2017/0.2-announcement.md index 6491ff14ad51..5e67dcde9584 100644 --- a/_blog/2017/0.2-announcement.md +++ b/_blog/2017/0.2-announcement.md @@ -1,7 +1,7 @@ --- title: Announcing Istio 0.2 description: Istio 0.2 announcement -publish_date: October 10, 2017 +publishdate: 2017-10-10 subtitle: Improved mesh and support for multiple environments attribution: The Istio Team diff --git a/_blog/2017/adapter-model.md b/_blog/2017/adapter-model.md index dda97ec7271d..db202cc25a01 100644 --- a/_blog/2017/adapter-model.md +++ b/_blog/2017/adapter-model.md @@ -1,7 +1,7 @@ --- title: Mixer Adapter Model description: Provides an overview of the Mixer plug-in architecture -publish_date: November 3, 2017 +publishdate: 2017-11-03 subtitle: Extending Istio to integrate with a world of infrastructure backends attribution: Martin Taillefer diff --git a/_blog/2017/mixer-spof-myth.md b/_blog/2017/mixer-spof-myth.md index e46c51c9042e..361769186c6f 100644 --- a/_blog/2017/mixer-spof-myth.md +++ b/_blog/2017/mixer-spof-myth.md @@ -1,7 +1,7 @@ --- title: Mixer and the SPOF Myth description: Improving availability and reducing latency -publish_date: December 7, 2017 +publishdate: 2017-12-07 subtitle: Improving availability and reducing latency attribution: Martin Taillefer diff --git a/_blog/2018/aws-nlb.md b/_blog/2018/aws-nlb.md index 9d47f446aab6..7c92a2201fd5 100644 --- a/_blog/2018/aws-nlb.md +++ b/_blog/2018/aws-nlb.md @@ -1,7 +1,7 @@ --- title: Configuring Istio Ingress with AWS NLB description: Describes how to configure Istio ingress with a network load balancer on AWS -publish_date: April 20, 2018 +publishdate: 2018-04-20 subtitle: Ingress AWS Network Load Balancer attribution: Julien SENON diff --git a/_blog/2018/egress-https.md b/_blog/2018/egress-https.md index fd5ac04b73ba..732ae0a90290 100644 --- a/_blog/2018/egress-https.md +++ b/_blog/2018/egress-https.md @@ -1,7 +1,7 @@ --- title: Consuming External Web Services description: Describes a simple scenario based on Istio Bookinfo sample -publish_date: January 31, 2018 +publishdate: 2018-01-31 subtitle: Egress Rules for HTTPS traffic attribution: Vadim Eisenberg diff --git a/_blog/2018/egress-tcp.md b/_blog/2018/egress-tcp.md index 49943a4f5e76..471931585764 100644 --- a/_blog/2018/egress-tcp.md +++ b/_blog/2018/egress-tcp.md @@ -1,7 +1,7 @@ --- title: Consuming External TCP Services description: Describes a simple scenario based on Istio Bookinfo sample -publish_date: February 6, 2018 +publishdate: 2018-02-06 subtitle: Egress rules for TCP traffic attribution: Vadim Eisenberg diff --git a/_blog/2018/soft-multitenancy.md b/_blog/2018/soft-multitenancy.md index 754ace010292..b049a0df98a5 100644 --- a/_blog/2018/soft-multitenancy.md +++ b/_blog/2018/soft-multitenancy.md @@ -1,7 +1,7 @@ --- title: Istio Soft Multi-tenancy Support description: Using Kubernetes namespace and RBAC to create an Istio soft multi-tenancy environment -publish_date: April 19, 2018 +publishdate: 2018-04-19 subtitle: Using multiple Istio control planes and RBAC to create multi-tenancy attribution: John Joyce and Rich Curran diff --git a/_blog/2018/traffic-mirroring.md b/_blog/2018/traffic-mirroring.md index e5866f42c149..ffd2fdbee82e 100644 --- a/_blog/2018/traffic-mirroring.md +++ b/_blog/2018/traffic-mirroring.md @@ -1,7 +1,7 @@ --- title: Traffic Mirroring with Istio for Testing in Production description: An introduction to safer, lower-risk deployments and release to production -publish_date: February 8, 2018 +publishdate: 2018-02-08 subtitle: Routing rules for HTTP traffic attribution: Christian Posta diff --git a/_blog/2018/v1alpha3-routing.md b/_blog/2018/v1alpha3-routing.md index b5c38b69c84c..ffd9155cfa3f 100644 --- a/_blog/2018/v1alpha3-routing.md +++ b/_blog/2018/v1alpha3-routing.md @@ -1,7 +1,7 @@ --- title: Introducing the Istio v1alpha3 routing API description: Introduction, motivation and design principles for the Istio v1alpha3 routing API. -publish_date: April 25, 2018 +publishdate: 2018-04-25 subtitle: attribution: Frank Budinsky (IBM) and Shriram Rajagopalan (VMware) diff --git a/_includes/primary.html b/_includes/primary.html index 18ebbb050fcc..fc92a9e8d959 100644 --- a/_includes/primary.html +++ b/_includes/primary.html @@ -47,12 +47,12 @@ <h1 id="title">{{page.title}}</h1> <p class="subtitle">{{page.subtitle}}</p> {% endif %} - {% if page.attribution != nil or page.publish_date != nil %} + {% if page.attribution != nil or page.publishdate != nil %} <p class="byline"> {% if page.attribution != nil %} By <span class="attribution">{{page.attribution}}</span> / {% endif %} - <span class="publish_date">{{page.publish_date}}</span> + <span class="publish_date">{{page.publishdate | date: "%B %e, %Y"}}</span> </p> {% endif %} diff --git a/feed.xml b/feed.xml index c65663dd6599..576b31ebad23 100644 --- a/feed.xml +++ b/feed.xml @@ -29,7 +29,7 @@ layout: null <item> <title>{{ post.title | xml_escape }} {{ post.overview | xml_escape }} - {{ post.publish_date | date_to_xmlschema }} + {{ post.publishdate | date_to_xmlschema }} {{root}}{{ post.url }} {{ post.attribution }} {{root}}{{ post.url }} From 448e9dba0af42f425ad36d1b24f4b7ac1ab0e1de Mon Sep 17 00:00:00 2001 From: mtail Date: Mon, 14 May 2018 07:43:27 -0700 Subject: [PATCH 189/191] Remove stray quotes. --- _includes/image.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/image.html b/_includes/image.html index ddc72e3ce707..49603473d405 100644 --- a/_includes/image.html +++ b/_includes/image.html @@ -19,7 +19,7 @@ {% assign caption = include.caption %} {% assign title = include.title %} -{% if title == nil %}" +{% if title == nil %} {% assign title = caption %} {% endif %} From a98563cb2a409c04316b860c7cc40f34fa65fd24 Mon Sep 17 00:00:00 2001 From: Oliver Liu Date: Mon, 14 May 2018 10:15:01 -0700 Subject: [PATCH 190/191] Shorten long titles and descriptions. (#1278) --- _docs/tasks/security/authn-policy.md | 4 ++-- _docs/tasks/security/basic-access-control.md | 4 ++-- _docs/tasks/security/health-check.md | 6 +++--- _docs/tasks/security/https-overlay.md | 4 ++-- _docs/tasks/security/mutual-tls.md | 4 ++-- _docs/tasks/security/per-service-mtls.md | 2 +- _docs/tasks/security/plugin-ca-cert.md | 4 ++-- _docs/tasks/security/role-based-access-control.md | 4 ++-- _docs/tasks/security/secure-access-control.md | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/_docs/tasks/security/authn-policy.md b/_docs/tasks/security/authn-policy.md index 01d442ef7ccc..128e460566ff 100644 --- a/_docs/tasks/security/authn-policy.md +++ b/_docs/tasks/security/authn-policy.md @@ -1,6 +1,6 @@ --- -title: Basic Istio Authentication Policy -description: Shows you how to use Istio authentication policy to setup mutual TLS and simple end-user authentication. +title: Basic Authentication Policy +description: Shows you how to use Istio authentication policy to setup mutual TLS and basic end-user authentication. weight: 10 diff --git a/_docs/tasks/security/basic-access-control.md b/_docs/tasks/security/basic-access-control.md index c633c81a61e0..b95a34bb9f31 100644 --- a/_docs/tasks/security/basic-access-control.md +++ b/_docs/tasks/security/basic-access-control.md @@ -1,6 +1,6 @@ --- -title: Setting up Basic Access Control -description: This task shows how to control access to a service using the Kubernetes labels. +title: Basic Access Control +description: Shows how to control access to a service using the Kubernetes labels. weight: 20 diff --git a/_docs/tasks/security/health-check.md b/_docs/tasks/security/health-check.md index 0d71b86bcc31..5a4da2763836 100644 --- a/_docs/tasks/security/health-check.md +++ b/_docs/tasks/security/health-check.md @@ -1,13 +1,13 @@ --- -title: Enabling Citadel health checking -description: This task shows how to enable Citadel health checking. +title: Citadel health checking +description: Shows how to enable Citadel health checking with Kubernetes. weight: 70 --- {% include home.html %} -This task shows how to enable Citadel health checking. Note this is an Alpha feature since Istio 0.6. +This task shows how to enable Kubernetes health checking for Citadel. Note this is an Alpha feature. Since Istio 0.6, Citadel has a health checking feature that can be optionally enabled. By default, the normal Istio deployment process does not enable this feature. diff --git a/_docs/tasks/security/https-overlay.md b/_docs/tasks/security/https-overlay.md index e03446f06979..007a0e455051 100644 --- a/_docs/tasks/security/https-overlay.md +++ b/_docs/tasks/security/https-overlay.md @@ -1,6 +1,6 @@ --- -title: Mutual TLS over HTTPS services -description: This task shows how to enable mTLS on HTTPS services. +title: Mutual TLS over HTTPS +description: Shows how to enable mTLS on HTTPS services. weight: 80 diff --git a/_docs/tasks/security/mutual-tls.md b/_docs/tasks/security/mutual-tls.md index 69ba30c2d036..25003e75cac1 100644 --- a/_docs/tasks/security/mutual-tls.md +++ b/_docs/tasks/security/mutual-tls.md @@ -1,6 +1,6 @@ --- -title: Testing Istio mutual TLS authentication -description: This task shows you how to verify and test Istio's automatic mutual TLS authentication. +title: Testing mutual TLS +description: Shows you how to verify and test Istio's automatic mutual TLS authentication. weight: 10 diff --git a/_docs/tasks/security/per-service-mtls.md b/_docs/tasks/security/per-service-mtls.md index 50ce7a288c39..91424a2fffbf 100644 --- a/_docs/tasks/security/per-service-mtls.md +++ b/_docs/tasks/security/per-service-mtls.md @@ -1,6 +1,6 @@ --- title: Per-service mutual TLS authentication control -description: This task shows how to change mutual TLS authentication for a single service. +description: Shows how to change mutual TLS authentication for a single service. weight: 50 diff --git a/_docs/tasks/security/plugin-ca-cert.md b/_docs/tasks/security/plugin-ca-cert.md index a1670d00fdf5..11d09e354af4 100644 --- a/_docs/tasks/security/plugin-ca-cert.md +++ b/_docs/tasks/security/plugin-ca-cert.md @@ -1,6 +1,6 @@ --- -title: Plugging in root certificate, signing certificate and key -description: This task shows how operators can configure Citadel with existing root certificate, signing certificate and key. +title: Plugging in external CA key and certificate +description: Shows how operators can configure Citadel with existing root certificate, signing certificate and key. weight: 60 diff --git a/_docs/tasks/security/role-based-access-control.md b/_docs/tasks/security/role-based-access-control.md index 26e64ff4f897..f39df187f4ef 100644 --- a/_docs/tasks/security/role-based-access-control.md +++ b/_docs/tasks/security/role-based-access-control.md @@ -1,6 +1,6 @@ --- -title: Setting up Istio Role-Based Access Control -description: This task shows how to set up role-based access control for services in Istio mesh. +title: Role-Based Access Control +description: Shows how to set up role-based access control for services in Istio mesh. weight: 40 diff --git a/_docs/tasks/security/secure-access-control.md b/_docs/tasks/security/secure-access-control.md index df6363c282c5..1e718146200a 100644 --- a/_docs/tasks/security/secure-access-control.md +++ b/_docs/tasks/security/secure-access-control.md @@ -1,6 +1,6 @@ --- -title: Setting up Secure Access Control -description: This task shows how to securely control access to a service using service accounts. +title: Secure Access Control +description: Shows how to securely control access to a service using service accounts. weight: 30 From 9db0e2f0ef14cad9a5ed1f0eb87bd0623c9cc02b Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Mon, 14 May 2018 10:29:45 -0700 Subject: [PATCH 191/191] Fix aspect ratio of a couple images. (#1277) The incorrect aspect ratio value was leading to spurious top/bottom padding on the images. Also, delete unecessary .png version of some .svg files. --- _blog/2018/img/gateways.png | Bin 36725 -> 0 bytes _blog/2018/img/gateways.svg | 203 ++++++++++++++++++- _blog/2018/img/virtualservices-destrules.png | Bin 23875 -> 0 bytes _blog/2018/v1alpha3-routing.md | 4 +- 4 files changed, 204 insertions(+), 3 deletions(-) delete mode 100644 _blog/2018/img/gateways.png delete mode 100644 _blog/2018/img/virtualservices-destrules.png diff --git a/_blog/2018/img/gateways.png b/_blog/2018/img/gateways.png deleted file mode 100644 index 5a66379b264ca0ca3adddc44a9417ebed04ca0f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36725 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 zÂ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 diff --git a/_blog/2018/img/gateways.svg b/_blog/2018/img/gateways.svg index 4c0bb6132358..9f57b6a49579 100644 --- a/_blog/2018/img/gateways.svg +++ b/_blog/2018/img/gateways.svg @@ -1 +1,202 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_blog/2018/img/virtualservices-destrules.png b/_blog/2018/img/virtualservices-destrules.png deleted file mode 100644 index 985444a18eb06fa9dd61e28e2c764ae47eb2c3d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23875 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 c3>$i-a5ucwO{*11j()%dZUK9J@!GwA1K
FieldTypeDescription
servicesstring[] +

A list of services.

+ +
namespacesstring[] +

A list of namespaces.

+