Standalone Operator Install

This guide installs Istio using the standalone Istio operator. The only dependencies required are a supported Kubernetes cluster, the kubectl command at the version to match the cluster, and the istioctl command at the desired release version.

The operator is beta in 1.6 and suitable for production use.


  1. Perform any necessary platform-specific setup.

  2. Check the Requirements for Pods and Services.

  3. Install the istioctl command.

  4. Deploy the Istio operator:

    $ istioctl operator init

    This command runs the operator by creating the following resources in the istio-operator namespace:

    • The operator custom resource definition
    • The operator controller deployment
    • A service to access operator metrics
    • Necessary Istio operator RBAC rules

    You can configure which namespace the operator controller is installed in, the namespace(s) the operator watches, the installed Istio image sources and versions, and more. For example, you can pass one or more namespaces to watch using the --watchedNamespaces flag:

    $ istioctl operator init --watchedNamespaces=istio-namespace1,istio-namespace2

    See the istioctl operator init command reference for details.


To install the Istio demo configuration profile using the operator, run the following command:

$ kubectl create ns istio-system
$ kubectl apply -f - <<EOF
kind: IstioOperator
  namespace: istio-system
  name: example-istiocontrolplane
  profile: demo

The controller will detect the IstioOperator resource and then install the Istio components corresponding to the specified (demo) configuration.

You can confirm the Istio control plane services have been deployed with the following commands:

$ kubectl get svc -n istio-system
NAME                        TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                      AGE
grafana                     ClusterIP     <none>        3000/TCP                                                                     13s
istio-egressgateway         ClusterIP   <none>        80/TCP,443/TCP,15443/TCP                                                     17s
istio-ingressgateway        LoadBalancer   <pending>     15020:31077/TCP,80:30689/TCP,443:32419/TCP,31400:31411/TCP,15443:30176/TCP   17s
istiod                      ClusterIP    <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP,53/UDP,853/TCP                         30s
jaeger-agent                ClusterIP      None             <none>        5775/UDP,6831/UDP,6832/UDP                                                   13s
jaeger-collector            ClusterIP   <none>        14267/TCP,14268/TCP,14250/TCP                                                13s
jaeger-collector-headless   ClusterIP      None             <none>        14250/TCP                                                                    13s
jaeger-query                ClusterIP    <none>        16686/TCP                                                                    13s
kiali                       ClusterIP    <none>        20001/TCP                                                                    13s
prometheus                  ClusterIP   <none>        9090/TCP                                                                     13s
tracing                     ClusterIP   <none>        80/TCP                                                                       13s
zipkin                      ClusterIP     <none>        9411/TCP                                                                     13s
$ kubectl get pods -n istio-system
NAME                                   READY   STATUS    RESTARTS   AGE
grafana-54b54568fc-fk6p5               1/1     Running   0          82s
istio-egressgateway-5444c68db8-9h6dz   1/1     Running   0          87s
istio-ingressgateway-5c68cb968-x7qv9   1/1     Running   0          87s
istio-tracing-9dd6c4f7c-hd9qq          1/1     Running   0          82s
istiod-598984548d-wjq9j                1/1     Running   0          99s
kiali-d45468dc4-4nqdv                  1/1     Running   0          82s
prometheus-6cf46c47fb-tvvkv            2/2     Running   0          82s


Now, with the controller running, you can change the Istio configuration by editing or replacing the IstioOperator resource. The controller will detect the change and respond by updating the Istio installation correspondingly.

For example, you can switch the installation to the default profile with the following command:

$ kubectl apply -f - <<EOF
kind: IstioOperator
  namespace: istio-system
  name: example-istiocontrolplane
  profile: default

You can also enable or disable components and modify resource settings. For example, to enable the Grafana component and increase pilot memory requests:

$ kubectl apply -f - <<EOF
kind: IstioOperator
  namespace: istio-system
  name: example-istiocontrolplane
  profile: default
            memory: 3072Mi
      enabled: true

You can observe the changes that the controller makes in the cluster in response to IstioOperator CR updates by checking the operator controller logs:

$ kubectl logs -f -n istio-operator $(kubectl get pods -n istio-operator -lname=istio-operator -o jsonpath='{.items[0]}')

Refer to the IstioOperator API for the complete set of configuration settings.


Delete the Istio deployment:

$ kubectl delete -n istio-system example-istiocontrolplane

Wait until Istio is uninstalled - this may take some time. Delete the Istio operator:

$ istioctl operator remove


$ kubectl delete ns istio-operator --grace-period=0 --force

Note that deleting the operator before Istio is fully removed may result in leftover Istio resources. To clean up anything not removed by the operator:

$ istioctl manifest generate | kubectl delete -f -
$ kubectl delete ns istio-system --grace-period=0 --force
Was this information useful?
Do you have any suggestions for improvement?

Thanks for your feedback!