Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[k8s] SkyServe on Kubernetes #3377

Merged
merged 89 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
34598a2
playing around
romilbhardwaj Feb 1, 2024
95b1eb0
wip with hacks
romilbhardwaj Feb 2, 2024
f93e6dd
wip refactor get_endpoints
romilbhardwaj Feb 5, 2024
c8276bb
working get_endpoints
romilbhardwaj Feb 6, 2024
c713293
wip
romilbhardwaj Feb 6, 2024
aa286e8
fixed circular import
romilbhardwaj Feb 6, 2024
9f768a2
Working for ingress and loadbalancer svc
romilbhardwaj Feb 6, 2024
1848b3a
lint
romilbhardwaj Feb 7, 2024
ba0ff60
add purging from #3094
romilbhardwaj Feb 15, 2024
13f7241
Use local catalog on the controller too
romilbhardwaj Feb 15, 2024
996742a
use externalip if available
romilbhardwaj Feb 19, 2024
7c8b5cd
Merge branch 'master' of https://github.com/skypilot-org/skypilot int…
romilbhardwaj Feb 20, 2024
b222186
Merge branch 'master' of https://github.com/skypilot-org/skypilot int…
romilbhardwaj Feb 23, 2024
d852c61
add dshm_size_limit
romilbhardwaj Feb 23, 2024
b9014df
optimize dependency installation
romilbhardwaj Feb 23, 2024
282bcef
Add todo
romilbhardwaj Feb 24, 2024
d10fb24
Merge branch 'master' of https://github.com/skypilot-org/skypilot int…
romilbhardwaj Feb 28, 2024
3cb948f
optimize ingress
romilbhardwaj Mar 2, 2024
4a7e10a
fix
romilbhardwaj Mar 2, 2024
9e0d910
fix
romilbhardwaj Mar 2, 2024
9e51793
Merge branch 'k8s_ingress_optimization' of https://github.com/skypilo…
romilbhardwaj Mar 3, 2024
68bb6e8
remove autostop timing
romilbhardwaj Mar 4, 2024
b72a814
Fix URLs for raw IP:ports
romilbhardwaj Mar 5, 2024
a22b6d3
fixes
romilbhardwaj Mar 7, 2024
4637f91
wip
romilbhardwaj Mar 7, 2024
d27ae5f
SA wip
romilbhardwaj Mar 7, 2024
cdc2e3f
Allow use of service accounts through remote_identity field
romilbhardwaj Mar 8, 2024
643fb77
Make purge work for no clusters in kubeconfig
romilbhardwaj Mar 8, 2024
7649fcb
Handle ingress namespace not present
romilbhardwaj Mar 8, 2024
8c76eb6
setup optimizations and critical SA key fix
romilbhardwaj Mar 8, 2024
2e20600
fix docs
romilbhardwaj Mar 16, 2024
de6a99c
fix docs
romilbhardwaj Mar 16, 2024
03e44eb
Add support for skypilot.co/external-ip annotation for ingress
romilbhardwaj Mar 24, 2024
7436a7e
Remove dshm_size_limit
romilbhardwaj Mar 25, 2024
3cc5352
Undo kind changes
romilbhardwaj Mar 25, 2024
d836f17
Update service account docs
romilbhardwaj Mar 25, 2024
1b559d2
minor docs
romilbhardwaj Mar 25, 2024
cda27b2
update comment
romilbhardwaj Mar 26, 2024
23d730b
is_same_cloud to cloud_in_list
romilbhardwaj Mar 27, 2024
cba92e3
refactor query_ports to use head_ip
romilbhardwaj Mar 27, 2024
789cefe
autodown + http prefixing in callers
romilbhardwaj Mar 27, 2024
55b63de
fix ssh key issues when user hash is reused
romilbhardwaj Mar 27, 2024
73ad2e6
linting
romilbhardwaj Mar 27, 2024
31418d2
lint
romilbhardwaj Mar 27, 2024
0684f2b
lint, HOST_CONTROLLERS
romilbhardwaj Mar 27, 2024
e7f232e
add serve smoke tests for k8s
romilbhardwaj Mar 28, 2024
2a1b916
disallow file_mounts and workdir if no storage cloud is enabled
romilbhardwaj Mar 28, 2024
f242037
minor
romilbhardwaj Mar 28, 2024
9b12cf1
lint
romilbhardwaj Mar 28, 2024
87330bd
Merge branch 'master' of https://github.com/skypilot-org/skypilot int…
romilbhardwaj Mar 28, 2024
3ca5d47
update fastchat to use --host 127.0.0.1
romilbhardwaj Mar 29, 2024
02ef50a
extend timeout
romilbhardwaj Mar 29, 2024
259917f
docs comments
romilbhardwaj Apr 9, 2024
8066a2a
Merge branch 'master' of https://github.com/skypilot-org/skypilot int…
romilbhardwaj Apr 9, 2024
665a12e
rename to port
romilbhardwaj Apr 10, 2024
fcc63fe
add to core.py
romilbhardwaj Apr 10, 2024
df21a0b
docstrs
romilbhardwaj Apr 10, 2024
5d8c9c7
add docs on exec based auth
romilbhardwaj Apr 10, 2024
937feb6
expand elif
romilbhardwaj Apr 10, 2024
33dfb01
add lb comment
romilbhardwaj Apr 10, 2024
87c77df
refactor
romilbhardwaj Apr 11, 2024
99547db
refactor
romilbhardwaj Apr 11, 2024
3d24b41
fix docs build
romilbhardwaj Apr 11, 2024
750d4d4
add PODIP mode support
romilbhardwaj Apr 8, 2024
87d4d25
make ssh services optional
romilbhardwaj Apr 12, 2024
a31a3bc
nits
romilbhardwaj Apr 29, 2024
e3bb4d7
Revert "make ssh services optional"
romilbhardwaj Apr 29, 2024
12096fd
Revert "add PODIP mode support"
romilbhardwaj Apr 29, 2024
c33572e
nits
romilbhardwaj Apr 29, 2024
803df4a
use 0.0.0.0 when on k8s; use common impl for other clouds
romilbhardwaj Apr 29, 2024
a0ba0d1
return dict instead of raising errors in core.endpoints()
romilbhardwaj Apr 29, 2024
fb88218
lint
romilbhardwaj Apr 29, 2024
1d968a6
Merge branch 'master' of https://github.com/skypilot-org/skypilot int…
romilbhardwaj Apr 29, 2024
e22908a
merge fixes
romilbhardwaj Apr 29, 2024
34a719c
merge fixes
romilbhardwaj Apr 29, 2024
017dcb5
Merge branch 'master' of https://github.com/skypilot-org/skypilot int…
romilbhardwaj May 7, 2024
cd08d0f
merge fixes
romilbhardwaj May 7, 2024
05f1996
lint
romilbhardwaj May 7, 2024
97b1d56
fix smoke tests
romilbhardwaj May 7, 2024
9a8ccd1
fix smoke tests
romilbhardwaj May 7, 2024
3b7d33f
comment
romilbhardwaj May 7, 2024
e029ebc
add enum for remote identity
romilbhardwaj May 7, 2024
7b201f2
lint
romilbhardwaj May 7, 2024
8a54faf
add skip_status_check
romilbhardwaj May 8, 2024
5fb4232
remove zone requirement
romilbhardwaj May 8, 2024
2e8afe9
fix timings for test
romilbhardwaj May 8, 2024
736e087
silence curl download
romilbhardwaj May 8, 2024
e3768b4
move jq from yaml to test_minimal
romilbhardwaj May 8, 2024
26cc380
move jq from yaml to test_minimal
romilbhardwaj May 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/source/cloud-setup/cloud-permissions/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ Table of Contents
aws
gcp
vsphere
kubernetes
234 changes: 234 additions & 0 deletions docs/source/cloud-setup/cloud-permissions/kubernetes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
.. _cloud-permissions-kubernetes:

Kubernetes
==========

When running outside your Kubernetes cluster, SkyPilot uses your local ``~/.kube/config`` file
for authentication and creating resources on your Kubernetes cluster.

When running inside your Kubernetes cluster (e.g., as a Spot controller or Serve controller),
SkyPilot can operate using either of the following three authentication methods:

1. **Using your local kubeconfig file**: In this case, SkyPilot will
copy your local ``~/.kube/config`` file to the controller pod and use it for
authentication. This is the default method when running inside the cluster,
and no additional configuration is required.

.. note::

If your cluster uses exec based authentication in your ``~/.kube/config`` file
(e.g., GKE uses exec auth by default), SkyPilot may not be able to authenticate using this method. In this case,
consider using the service account methods below.
Michaelvll marked this conversation as resolved.
Show resolved Hide resolved

2. **Creating a service account**: SkyPilot can automatically create the service
account and roles for itself to manage resources in the Kubernetes cluster.
To use this method, set ``remote_identity: SERVICE_ACCOUNT`` to your
Kubernetes configuration in the :ref:`~/.sky/config.yaml <config-yaml>` file:

.. code-block:: yaml

kubernetes:
remote_identity: SERVICE_ACCOUNT

For details on the permissions that are granted to the service account,
refer to the `Permissions required for SkyPilot`_ section below.

3. **Using a custom service account**: If you have a custom service account
with the `necessary permissions <k8s-permissions_>`__, you can configure
SkyPilot to use it by adding this to your :ref:`~/.sky/config.yaml <config-yaml>` file:

.. code-block:: yaml

kubernetes:
remote_identity: your-service-account-name

.. note::

Service account based authentication applies only when the remote SkyPilot
cluster (including spot and serve controller) is launched inside the
Kubernetes cluster. When running outside the cluster (e.g., on AWS),
SkyPilot will use the local ``~/.kube/config`` file for authentication.

Below are the permissions required by SkyPilot and an example service account YAML that you can use to create a service account with the necessary permissions.

.. _k8s-permissions:

Permissions required for SkyPilot
---------------------------------

SkyPilot requires permissions equivalent to the following roles to be able to manage the resources in the Kubernetes cluster:

.. code-block:: yaml

# Namespaced role for the service account
# Required for creating pods, services and other necessary resources in the namespace.
# Note these permissions only apply in the namespace where SkyPilot is deployed.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sky-sa-role
namespace: default
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
# ClusterRole for accessing cluster-wide resources. Details for each resource below:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sky-sa-cluster-role
namespace: default
labels:
parent: skypilot
rules:
- apiGroups: [""]
resources: ["nodes"] # Required for getting node resources.
verbs: ["get", "list", "watch"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings"] # Required for launching more SkyPilot clusters from within the pod.
verbs: ["get", "list", "watch"]
- apiGroups: ["node.k8s.io"]
resources: ["runtimeclasses"] # Required for autodetecting the runtime class of the nodes.
verbs: ["get", "list", "watch"]
---
# Optional: If using ingresses, role for accessing ingress service IP
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: ingress-nginx
name: sky-sa-role-ingress-nginx
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["list", "get"]

These roles must apply to both the user account configured in the kubeconfig file and the service account used by SkyPilot (if configured).

.. _k8s-sa-example:

Example using Custom Service Account
------------------------------------

To create a service account that has the necessary permissions for SkyPilot, you can use the following YAML:

.. code-block:: yaml

# create-sky-sa.yaml
kind: ServiceAccount
apiVersion: v1
metadata:
name: sky-sa
namespace: default
labels:
parent: skypilot
---
# Role for the service account
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sky-sa-role
namespace: default
labels:
parent: skypilot
rules:
- apiGroups: ["*"] # Required for creating pods, services, secrets and other necessary resources in the namespace.
resources: ["*"]
verbs: ["*"]
---
# RoleBinding for the service account
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sky-sa-rb
namespace: default
labels:
parent: skypilot
subjects:
- kind: ServiceAccount
name: sky-sa
roleRef:
kind: Role
name: sky-sa-role
apiGroup: rbac.authorization.k8s.io
---
# Role for accessing ingress resources
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: ingress-nginx
name: sky-sa-role-ingress-nginx
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["list", "get", "watch"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["list", "get", "watch"]
---
# RoleBinding for accessing ingress resources
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: sky-sa-rolebinding-ingress-nginx
namespace: ingress-nginx
subjects:
- kind: ServiceAccount
name: sky-sa
namespace: default
roleRef:
kind: Role
name: sky-sa-role-ingress-nginx
apiGroup: rbac.authorization.k8s.io
---
# ClusterRole for the service account
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sky-sa-cluster-role
namespace: default
labels:
parent: skypilot
rules:
- apiGroups: [""]
resources: ["nodes"] # Required for getting node resources.
verbs: ["get", "list", "watch"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings"] # Required for launching more SkyPilot clusters from within the pod.
verbs: ["get", "list", "watch"]
- apiGroups: ["node.k8s.io"]
resources: ["runtimeclasses"] # Required for autodetecting the runtime class of the nodes.
verbs: ["get", "list", "watch"]
- apiGroups: ["networking.k8s.io"] # Required for exposing services.
resources: ["ingressclasses"]
verbs: ["get", "list", "watch"]
---
# ClusterRoleBinding for the service account
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sky-sa-cluster-role-binding
namespace: default
labels:
parent: skypilot
subjects:
- kind: ServiceAccount
name: sky-sa
namespace: default
roleRef:
kind: ClusterRole
name: sky-sa-cluster-role
apiGroup: rbac.authorization.k8s.io

Create the service account using the following command:

.. code-block:: bash

$ kubectl apply -f create-sky-sa.yaml

After creating the service account, configure SkyPilot to use it through ``~/.sky/config.yaml``:

.. code-block:: yaml

kubernetes:
remote_identity: sky-sa # Or your service account name
32 changes: 28 additions & 4 deletions docs/source/reference/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -205,21 +205,21 @@ Available fields and semantics:


# Reserved capacity (optional).
#
#
# Whether to prioritize reserved instance types/locations (considered as 0
# cost) in the optimizer.
#
#
# If you have "automatically consumed" reservations in your GCP project:
# Setting this to true guarantees the optimizer will pick any matching
# reservation and GCP will auto consume your reservation, and setting to
# false means optimizer uses regular, non-zero pricing in optimization (if
# by chance any matching reservation is selected, GCP still auto consumes
# the reservation).
#
#
# If you have "specifically targeted" reservations (set by the
# `specific_reservations` field below): This field will automatically be set
# to true.
#
#
# Default: false.
prioritize_reservations: false
#
Expand Down Expand Up @@ -298,6 +298,30 @@ Available fields and semantics:
# Default: loadbalancer
ports: loadbalancer

# Identity to use for all Kubernetes pods (optional).
#
# LOCAL_CREDENTIALS: The user's local ~/.kube/config will be uploaded to the
# Kubernetes pods created by SkyPilot. They are used for authenticating with
# the Kubernetes API server and launching new pods (e.g., for
# spot/serve controllers).
#
# SERVICE_ACCOUNT: Local ~/.kube/config is not uploaded to Kubernetes pods.
# SkyPilot will auto-create and reuse a service account with necessary roles
# in the user's namespace.
#
# <string>: The name of a service account to use for all Kubernetes pods.
# This service account must exist in the user's namespace and have all
# necessary permissions. Refer to https://skypilot.readthedocs.io/en/latest/cloud-setup/cloud-permissions/kubernetes.html
# for details on the roles required by the service account.
#
# Using SERVICE_ACCOUNT or a custom service account only affects Kubernetes
# instances. Local ~/.kube/config will still be uploaded to non-Kubernetes
# instances (e.g., a serve controller on GCP or AWS may need to provision
# Kubernetes resources).
#
# Default: 'LOCAL_CREDENTIALS'.
remote_identity: my-k8s-service-account

# Attach custom metadata to Kubernetes objects created by SkyPilot
#
# Uses the same schema as Kubernetes metadata object: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#objectmeta-v1-meta
Expand Down
18 changes: 17 additions & 1 deletion docs/source/reference/kubernetes/kubernetes-setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ To use this mode:
# ingress-nginx-controller LoadBalancer 10.24.4.254 35.202.58.117 80:31253/TCP,443:32699/TCP

.. note::
If the ``EXTERNAL-IP`` field is ``<none>``, you must manually assign an External IP.
If the ``EXTERNAL-IP`` field is ``<none>``, you may manually assign it an External IP.
This can be done by patching the service with an IP that can be accessed from outside the cluster.
If the service type is ``NodePort``, you can set the ``EXTERNAL-IP`` to any node's IP address:

Expand All @@ -395,6 +395,22 @@ To use this mode:
If the ``EXTERNAL-IP`` field is left as ``<none>``, SkyPilot will use ``localhost`` as the external IP for the Ingress,
and the endpoint may not be accessible from outside the cluster.

.. note::
If you cannot update the ``EXTERNAL-IP`` field of the service, you can also
specify the Ingress IP or hostname through the ``skypilot.co/external-ip``
annotation on the ``ingress-nginx-controller`` service. In this case,
having a valid ``EXTERNAL-IP`` field is not required.

For example, if your ``ingress-nginx-controller`` service is ``NodePort``:

.. code-block:: bash

# Add skypilot.co/external-ip annotation to the nginx ingress service.
# Replace <IP> in the following command with the IP you select.
# Can be any node's IP if using NodePort service type.
$ kubectl annotate service ingress-nginx-controller skypilot.co/external-ip=<IP> -n ingress-nginx


3. Update the :ref:`SkyPilot config <config-yaml>` at :code:`~/.sky/config` to use the ingress mode.

.. code-block:: yaml
Expand Down
3 changes: 2 additions & 1 deletion docs/source/serving/sky-serve.rst
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,12 @@ Let's bring up a real LLM chat service with FastChat + Vicuna. We'll use the `Vi
conda activate chatbot

echo 'Starting controller...'
python -u -m fastchat.serve.controller > ~/controller.log 2>&1 &
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we also mention serving on kubernetes a bit in the serving doc and refer to the cloud-permissions for the setup?
We may also want to explicitly list out why people should use skyserve on kubernetes than just using deployments, such as:

  1. easier customization for load balancer and autoscaling policy
  2. simple interface and easy to setup
  3. spillover to clouds.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea - filed #3518, will submit a separate PR for docs.

python -u -m fastchat.serve.controller --host 127.0.0.1 > ~/controller.log 2>&1 &
sleep 10
echo 'Starting model worker...'
python -u -m fastchat.serve.model_worker \
--model-path lmsys/vicuna-${MODEL_SIZE}b-v1.3 2>&1 \
--host 127.0.0.1 \
| tee model_worker.log &

echo 'Waiting for model worker to start...'
Expand Down
3 changes: 2 additions & 1 deletion examples/serve/gorilla/gorilla.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ run: |
conda activate chatbot

echo 'Starting controller...'
python -u -m fastchat.serve.controller > ~/controller.log 2>&1 &
python -u -m fastchat.serve.controller --host 127.0.0.1 > ~/controller.log 2>&1 &
sleep 10
echo 'Starting model worker...'
python -u -m fastchat.serve.model_worker \
--model-path gorilla-llm/gorilla-falcon-7b-hf-v0 2>&1 \
--host 127.0.0.1 \
| tee model_worker.log &

echo 'Waiting for model worker to start...'
Expand Down
3 changes: 2 additions & 1 deletion examples/serve/vicuna-v1.5.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ run: |
conda activate chatbot

echo 'Starting controller...'
python -u -m fastchat.serve.controller > ~/controller.log 2>&1 &
python -u -m fastchat.serve.controller --host 127.0.0.1 > ~/controller.log 2>&1 &
sleep 10
echo 'Starting model worker...'
python -u -m fastchat.serve.model_worker \
--model-path lmsys/vicuna-${MODEL_SIZE}b-v1.5 2>&1 \
--host 127.0.0.1 \
| tee model_worker.log &

echo 'Waiting for model worker to start...'
Expand Down
3 changes: 2 additions & 1 deletion llm/llama-2/chatbot-hf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ run: |
conda activate chatbot

echo 'Starting controller...'
python -u -m fastchat.serve.controller > ~/controller.log 2>&1 &
python -u -m fastchat.serve.controller --host 127.0.0.1 > ~/controller.log 2>&1 &
sleep 10
echo 'Starting model worker...'
python -u -m fastchat.serve.model_worker \
--model-path meta-llama/Llama-2-${MODEL_SIZE}b-chat-hf \
--num-gpus $SKYPILOT_NUM_GPUS_PER_NODE 2>&1 \
--host 127.0.0.1 \
| tee model_worker.log &

echo 'Waiting for model worker to start...'
Expand Down
3 changes: 2 additions & 1 deletion llm/vicuna-llama-2/serve.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ run: |
conda activate chatbot

echo 'Starting controller...'
python -u -m fastchat.serve.controller > ~/controller.log 2>&1 &
python -u -m fastchat.serve.controller --host 127.0.0.1 > ~/controller.log 2>&1 &
sleep 10
echo 'Starting model worker...'
python -u -m fastchat.serve.model_worker \
--model-path /skypilot-vicuna 2>&1 \
--host 127.0.0.1 \
| tee model_worker.log &

echo 'Waiting for model worker to start...'
Expand Down
Loading
Loading