Setup

In order for your pods to be scheduled on spot VM’s, the Ocean admission controller needs to be installed in your cluster. The following procedure creates an admission controller in your cluster.

Create a file admission-controller.yaml with the following content

---
apiVersion: v1
kind: Service
metadata:
  name: spot-admission-controller
  namespace: kube-system
  labels:
    app.kubernetes.io/name: spot-admission-controller
spec:
  ports:
    - name: webhook
      port: 443
      targetPort: 8080
  selector:
    app.kubernetes.io/name: spot-admission-controller
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spot-admission-controller
  namespace: kube-system
  labels:
    app.kubernetes.io/name: spot-admission-controller
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: spot-admission-controller
  template:
    metadata:
      name: spot-admission-controller
      labels:
        app.kubernetes.io/name: spot-admission-controller
    spec:
      containers:
        - name: webhook
          image: gcr.io/spotinst-artifacts/spot-ocean-admission-controller:0.1.2
          imagePullPolicy: Always
          command: []
          args:
            - --certFile=/etc/certs/cert.pem
            - --keyFile=/etc/certs/key.pem
          resources:
            limits:
              memory: 50Mi
              cpu: 300m
            requests:
              memory: 00Mi
              cpu: 300m
          volumeMounts:
            - name: webhook-certs
              mountPath: /etc/certs
              readOnly: true
            - name: logs
              mountPath: /tmp
          securityContext:
            readOnlyRootFilesystem: true
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: kubernetes.io/os
                    operator: NotIn
                    values:
                      - windows
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                    - key: app.kubernetes.io/name
                      operator: In
                      values:
                        - spot-admission-controller
                topologyKey: kubernetes.io/hostname
      volumes:
        - name: webhook-certs
          secret:
            secretName: spot-admission-controller
        - name: logs
          emptyDir: {}
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: "spot-admission-controller.kube-system.svc"
webhooks:
  - name: "spot-admission-controller.kube-system.svc"
    objectSelector:
      matchExpressions:
        - key: app.kubernetes.io/name
          operator: NotIn
          values:
            - spot-admission-controller
    namespaceSelector:
      matchLabels:
        spot.io/inject-aks-spot-toleration: "true"
    rules:
      - apiGroups:   [""]
        apiVersions: ["v1"]
        operations:  ["CREATE"]
        resources:   ["pods"]
        scope:       "Namespaced"
    clientConfig:
      service:
        namespace: "kube-system"
        name: "spot-admission-controller"
        path: "/add-taints"
      caBundle: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURURENDQWpTZ0F3SUJBZ0lVSXRKVU9zU2kwanYwSjg5MW1sSXNOMWRjME00d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1BqRUxNQWtHQTFVRUJoTUNTVXd4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RURBT0JnTlZCQW9UQjBWNApZVzF3YkdVeEN6QUpCZ05WQkFzVEFrTkJNQjRYRFRJek1UQXdPVEEzTWpBd01Gb1hEVEk0TVRBd056QTNNakF3Ck1Gb3dQakVMTUFrR0ExVUVCaE1DU1V3eEVEQU9CZ05WQkFnVEIwVjRZVzF3YkdVeEVEQU9CZ05WQkFvVEIwVjQKWVcxd2JHVXhDekFKQmdOVkJBc1RBa05CTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQwpBUUVBcjZUVWYwd2tNaDI3SmNBWVV2eWJIajhZbjFxYU9vTVA1bkNrKzBQRW1oaEpVQkpsQ1ZjZ0FFS2p0K3ZpCk9xRUZRZHVxVHNuQUEySVdlaytvUVM5RkVoYXMxaVBTV0FFT0pyUy9uaGJmd0hZTXVCanY2cHJEbU9BaVBnVkgKcTJmMDlEWUpKSDdabWtjdnUxeWE3R204bCtaZ2Z5WTNlcE9HY0haUzdEbEI3Y2hmOUZrcGEybGNPbnZGaHU5bApJcjJmS2tMN25CVEY5L3Z2OXdWaGlZbDRCaWxZNDFLUEhoT1lxT2pEK3JBZ1NRUHZtdUFIdGRaSlFjZmk0VkZkCkxaMnIzb0xUSXFTdGxHNzB2M0tEeDVKYnl5RVFUa1Yzd3VvVzN6ekRhR2VMMVI5emFDNWtXMVl0amtmKzhhNGIKTVZITFVPelVyVXUzYVVJc3YrWUJRQkNHN3dJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBUVl3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUVyZHJFa0x5WlY5TENQVW1VeG15MGFFR1pNb3dEUVlKCktvWklodmNOQVFFTEJRQURnZ0VCQUVrcVVUR1loUlFmTU5aNm40dXBsZlV0SDRYNGs4SXNKTEh1MVZIR25XUGsKNnJWUlRENUJuQW5uK1JqZTZHc1M3c0JhTEtWNEtEdTUvT3d1R1BwQ2o1SnAvWHBpTG9WNXNKN0xTY2hHRHpvMQo0bnRNSVVKR0twZzNKajBYMVZtc0d4dXkyRTRBNjRBNEdyd2JIeTVpalJBbzA2R1BIaGdKK1FMd0IvNy9sYXBWCis2QnpXcEk2NkRNNjM2VFRzRy9XSC82Ynd5OURiSmZqU0hMY0VBeW1EdkZJTVFHZm1Xb0ZqRTgreU04S3ZSSEcKMFlQQmFkNWhnLzUxbDhDQml5YWlwaG9NOFErYW4yeFFKRUF2MVZpZ3VIeklldGFVMytEb1VaeGJqMlZQVjJIOQpVbVNSMElrejFGNGlYMm4xNkF5YU5uaVMzK3F0R1BqQ0VaWkNjMjFET2dVPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="
    admissionReviewVersions: ["v1"]
    sideEffects: None
    timeoutSeconds: 5
    failurePolicy: Ignore
---
apiVersion: v1
data:
  cert.pem: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVDRENDQXZDZ0F3SUJBZ0lVRFZKZGZZdUh4K0k2RVgrUmZxQzB1M251Q24wd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1BqRUxNQWtHQTFVRUJoTUNTVXd4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RURBT0JnTlZCQW9UQjBWNApZVzF3YkdVeEN6QUpCZ05WQkFzVEFrTkJNQjRYRFRJek1UQXdPVEEzTWpBd01Gb1hEVFF6TVRBd05EQTNNakF3Ck1Gb3dQakVMTUFrR0ExVUVCaE1DU1V3eEVEQU9CZ05WQkFnVEIwVjRZVzF3YkdVeEVEQU9CZ05WQkFvVEIwVjQKWVcxd2JHVXhDekFKQmdOVkJBc1RBa05CTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQwpBUUVBd3NpVXQ1MmY3WVZ3QTE3NVYvVi85bVF6VEFNMEpNZGtIVksrSWNNOFdjM0pabUZJZktFbURSa1hSS082CllQS1pPVGM5dVdTVWZxaWlJcVJJUmYyL1V3S1FzblpSMTlYTExraU14NlFIejh4Um9ManhqdnpYOXVZRjB1bjcKSnJvRjRnOWZYSWR1YUtwUXN1NXJqWXNrY01aY1FtekswUzFzSDZvbTJTcEFHSkZZMWhHT252ZUp0K2xzQzZKeQpoMk1qY1NkNy9ianh6YXE4aGUrYmNEeWNCMGFOUjJHcVNmMHd2Vzk1aVR3MlBvcitMZXdvczVoQnE5SkJza3owClJ4aUxsWXU1L1pncUxjUFlHVkdsMmNOWVJVUndBdWlab2NlQ1JiQWxXT2FFMnAvUTZBeVFQREJJM09JTkk2NTEKbHRITU9CRzhBTVVMd2dOR3o3T1Q4ZVZnNFFJREFRQUJvNEg5TUlINk1BNEdBMVVkRHdFQi93UUVBd0lGb0RBZApCZ05WSFNVRUZqQVVCZ2dyQmdFRkJRY0RBUVlJS3dZQkJRVUhBd0l3REFZRFZSMFRBUUgvQkFJd0FEQWRCZ05WCkhRNEVGZ1FValJXdmVSdnB2UnlERDc5a3pXSVlHM1M4b3Nrd2dac0dBMVVkRVFTQmt6Q0JrSUlaYzNCdmRDMWgKWkcxcGMzTnBiMjR0WTI5dWRISnZiR3hsY29JM2MzQnZkQzFoWkcxcGMzTnBiMjR0WTI5dWRISnZiR3hsY2k1cgpkV0psTFhONWMzUmxiUzV6ZG1NdVkyeDFjM1JsY2k1c2IyTmhiSUlwYzNCdmRDMWhaRzFwYzNOcGIyNHRZMjl1CmRISnZiR3hsY2k1cmRXSmxMWE41YzNSbGJTNXpkbU9DQ1d4dlkyRnNhRzl6ZEljRWZ3QUFBVEFOQmdrcWhraUcKOXcwQkFRc0ZBQU9DQVFFQUNIbXBQYUpZeE5yV1E5M3BKaEpySllldXcwdk9qU3NLU2V1UG9VTkcyK1NPU25rTwpUdzZYS3ZybG1qKzB5bHk5aHd0UTJHV1JNT2ZzOUJZTVFQTUlKcTJrTWdUaVIzODVWYkMybkk0dWEzSDlZU0YrClBUYTRadzgrRllQVmZ0OFpIMHJvSWpWYk1aZ2daWDJPSFhGcDVYSEcrVUg0MmI2YitmR2haKzV3TzFNZm1ENjkKZ0ZVQ0xrM2JndEFrMmliMHV1NjJzMkdCaEZTbUhzWTQ0aFpaWElGV3dEL053bG1TZ1Zabm9mQXpUZGRjQmNiWQpabm5DWFRFMEFVQlhYUTYzMDhsMVptWnVXcmtwK0JYNXk4UHFsR3pCWnFRK1kzZ2I1R21Id0xLYzlUd3JoTHRrCjhMQVpRcFp2WWFWVHVLT3BrYW1ucDBKYkRrQVNJU0c4MW90Rnp3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
  key.pem: "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBd3NpVXQ1MmY3WVZ3QTE3NVYvVi85bVF6VEFNMEpNZGtIVksrSWNNOFdjM0pabUZJCmZLRW1EUmtYUktPNllQS1pPVGM5dVdTVWZxaWlJcVJJUmYyL1V3S1FzblpSMTlYTExraU14NlFIejh4Um9MangKanZ6WDl1WUYwdW43SnJvRjRnOWZYSWR1YUtwUXN1NXJqWXNrY01aY1FtekswUzFzSDZvbTJTcEFHSkZZMWhHTwpudmVKdCtsc0M2SnloMk1qY1NkNy9ianh6YXE4aGUrYmNEeWNCMGFOUjJHcVNmMHd2Vzk1aVR3MlBvcitMZXdvCnM1aEJxOUpCc2t6MFJ4aUxsWXU1L1pncUxjUFlHVkdsMmNOWVJVUndBdWlab2NlQ1JiQWxXT2FFMnAvUTZBeVEKUERCSTNPSU5JNjUxbHRITU9CRzhBTVVMd2dOR3o3T1Q4ZVZnNFFJREFRQUJBb0lCQVFDNVNONFdyKzBDbncwSApWOSt1S1F6WlQwVndpQmVnNkw2MkdoQmN3My8wR1FuOHhvdVNhaVJ0RHpJUURBTHQxN2VqTW9ZWGhiS3ZyUy9WCjdob0Y0ak9OL2dHd2tWYVhEbnJoQXdoUG5Cd0dNZUJ3RjUxSW5BRy9qZDE2WFRLWUN4b3ZpTm40aGFla0RtY0gKWGo2Vy9RWGo5UHlyL3hzSzBiOXBlNHpLeFNNRmVnd09rRlJGbVdRcGpoOXNPTXNFbGZoVHU1TTBVT2pCeXRvegpCTE13ODdXbFJURDBVMnptZ0hTK0pVeDRYa2lET0VkRGVSa3BXeUNGWFJSZWZNZHFrNFQ5RGxhdWlZQWVHcFpGCmhtWExsVzhyNXBnZFArQUlDQ0tmNTJjWEFFOHFOMml2cXpYcEIvYW1NQ3NUdWE0TGxsSWVTQVdBUGVlQ2FrM3MKVk5HcVVCRUJBb0dCQU5VTjV1V1RxYVArQlNxdWIzcGJqcVI2cHEyL2JDWFRaQUg3WnhHeXB2V0VCaE0ydXhrYQo1T2Y2dmlWV3M1RmJwT1hPa3E0S1d2NW5pZTZEeit5U0dqRmxGV3pHNWpQOVF2TFp2WUl5eGx5ZHJUR2ZEeXZJCkVYSkRKTUVSNHVaSHZVb2t6WVI5dTBHZWhCZzc2aTJkY0w3Unc2ZmFFQ25rejNWVnRLYnVUWHVSQW9HQkFPb0wKM1NzU0svRXYvTjJINDRxaVlRNU53dTJMQzM3cTAwaS9lRkFIclhjaS8xYmxNdU01RFRFVGY4cFJETDZ2WUViRQpvejJheFdlQUFBY2wvZFpoQUNUOTlhNDVrSmdYaEZqMGl2MGhPbHp6a0t4ZnB3LzRIM0tjRTRNaHIxVjhMWTlQCjNpd2poRzdSNVY2b3VzckdrNllxU2VoUFI5eDZyVjBVcjh4NVdNaFJBb0dCQUppWTZIUXVteWFXWG1UL28yRGsKQ3ZyTHptNUwyTTRPNW1aMUJwR3FmK01CdU1neVB6ZndCMXdRUC9qR2JMOEVBTXVJZFk2cVpCb3JWcU83VFVXSQpMN0tKVUJzbEt1UzUxU1hUeHVSbU1hVk1XaXhjWEtWakd2dllFNDhsbkhxTGo0eDNaNndwMGVGaUJBTEhoeWM4CnlQQWpsaHUzR0RTcGFkNEVrT3V2YTFmQkFvR0JBT0lIYXlUNWU2NkdKYkxjVllmQm9mSHFiMkp4Y2p5MEZEQ2gKbVZQUTFsbkVWc3hZdFhoejFLV2NxMEY4WE02YkdHTy82OWJHN2ZZeXk5UWJnTFhWSUFxWnFQY0ZhUHM1V3Z0OQp6K3orZGhybXJzV0o2eEdsRXRuZ21ZZCt0SkhlUnpHc2RHZzBOT1hCbDc1L1BVWXYyTkFVN3lPSHpXTEVwMERKCmhhMzNVeUxCQW9HQVZLMGdJaVgyYnRUbXlLVW8ra0ZqQWg2a0U4aGI5Yzlmby84eCtPcVJEOVNPcTN2ZGpaVHQKSzV6clZaL1FRR0hOZE1ubkl2ZjlNQjRmYzNwQVROcStwemFCMjYwSnZXYVR1Nk9xMDRLNEZmdEp0RVVNblg0QwpuUGZjMGlkMU9ZSWpjaVlPdXhvQWV2V3kyM09mOGkzNi9UcjVBY1lhZmJtVTZxczIrYXE2QlA4PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo="
kind: Secret
metadata:
  name: spot-admission-controller
  namespace: kube-system
type: Opaque

Install the admission controller for the first time with Kubectl, run the following : kubectl apply -f admission-controller.yaml

➜  kubectl apply -f admission-controller.yaml
service/spot-admission-controller configured
deployment.apps/spot-admission-controller created
mutatingwebhookconfiguration.admissionregistration.k8s.io/spot-admission-controller.kube-system.svc configured
secret/spot-admission-controller configured

List the running pods to make sure that the admission controller is up by runing the following : kubectl get pods -n kube-system | grep "admission

➜  kubectl get pods -n kube-system | grep "admission" 
spot-admission-controller-67587bb89c-rnnwh             1/1     Running   0       112m
spot-admission-controller-67587bb89c-xjrck             1/1     Running   0       112m

There are several ways avaialble for installing the admission controller, for more options please use our Cluster import wizard