Compare commits
11 Commits
dependabot
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87fc8b7027 | ||
|
|
4e4cbcf65f | ||
|
|
fe5cf87558 | ||
|
|
64e6342b95 | ||
|
|
41e03d0f49 | ||
|
|
70ba5ff245 | ||
|
|
6c0ffc0567 | ||
| df7b5af263 | |||
| a01503f2aa | |||
| f067bf1186 | |||
| 4838d89b4a |
61
.github/workflows/build.yaml
vendored
Normal file
61
.github/workflows/build.yaml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
name: Virtual Kubelet Docker Build and Deploy
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 输出触发信息
|
||||
run: |
|
||||
echo "🎉 该作业由 ${{ github.event_name }} 事件自动触发。"
|
||||
echo "🐧 此作业当前在 GitHub 托管的 ${{ runner.os }} 服务器上运行!"
|
||||
echo "🔎 您的发布版本是 ${{ github.ref_name }},仓库是 ${{ github.repository }}。"
|
||||
|
||||
- name: 检出仓库代码
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 输出工作区信息
|
||||
run: |
|
||||
echo "💡 ${{ github.repository }} 仓库已克隆到运行器。"
|
||||
echo "🖥️ 工作流现在已准备好在运行器上测试您的代码。"
|
||||
ls -la ${{ github.workspace }}
|
||||
echo "🍏 此作业的状态是 ${{ job.status }}。"
|
||||
|
||||
- name: 设置 Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: 从标签名中提取版本号
|
||||
id: extract_version
|
||||
run: |
|
||||
# 从Release标签名中提取版本号,例如从 v0.1.0 中提取 v0.1.0
|
||||
VERSION=$(echo "${{ github.ref_name }}" | sed 's|refs/tags/||')
|
||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||
echo "提取的版本号:$VERSION"
|
||||
|
||||
- name: 登录 Docker 注册表
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: registry.cn-beijing.aliyuncs.com
|
||||
username: ${{ secrets.ALI_DOCKER_REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.ALI_DOCKER_REGISTRY_PASSWORD }}
|
||||
|
||||
- name: 构建并推送 Virtual Kubelet 镜像
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile # 确保Dockerfile路径正确
|
||||
push: true
|
||||
tags: |
|
||||
registry.cn-beijing.aliyuncs.com/d8dcloud/virtual-kubelet:eci-alpine
|
||||
build-args: |
|
||||
GOLANG_CI_LINT_VERSION=v1.68.0
|
||||
BUILD_TAGS=""
|
||||
labels: |
|
||||
org.opencontainers.image.title=Virtual Kubelet
|
||||
org.opencontainers.image.description=Kubernetes Virtual Kubelet implementation
|
||||
org.opencontainers.image.version=${{ env.VERSION }}
|
||||
org.opencontainers.image.source=${{ github.repositoryUrl }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
56
CLAUDE.md
Normal file
56
CLAUDE.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
This is the Alibaba Cloud ECI (Elastic Container Instance) provider for Virtual Kubelet. It allows Kubernetes pods to be scheduled onto Alibaba Cloud's serverless container instances instead of traditional cluster nodes.
|
||||
|
||||
## Key Commands
|
||||
|
||||
- `make build` - Build the virtual-kubelet binary
|
||||
- `make test` - Run all tests
|
||||
- `make vet` - Run go vet for code analysis
|
||||
- `make lint` - Run golangci-lint for linting
|
||||
- `make mod` - Tidy Go modules
|
||||
- `make clean` - Remove built binaries
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Main Provider**: `eci.go` - Implements the Virtual Kubelet provider interface
|
||||
- **ECI Client**: `eci/` directory - Contains Alibaba Cloud ECI API client and data structures
|
||||
- **CLI**: `cmd/virtual-kubelet/` - Command-line interface using Cobra
|
||||
- **Configuration**: `config.go` - Provider configuration handling
|
||||
|
||||
## Key Files
|
||||
|
||||
- `eci.go` - Main provider implementation (ECIProvider struct)
|
||||
- `eci/client.go` - ECI API client
|
||||
- `config.go` - Configuration parsing and validation
|
||||
- `cmd/virtual-kubelet/main.go` - Main entry point
|
||||
|
||||
## Development
|
||||
|
||||
- Go 1.13+ required
|
||||
- Uses Go modules for dependency management
|
||||
- Follows Virtual Kubelet provider interface conventions
|
||||
- Integration with Alibaba Cloud ECI API
|
||||
|
||||
## Testing
|
||||
|
||||
- Run `make test` to execute tests
|
||||
- Test files follow `*_test.go` naming convention
|
||||
- Uses standard Go testing framework
|
||||
|
||||
## Building
|
||||
|
||||
The build produces `bin/virtual-kubelet` binary with version information embedded via ldflags.
|
||||
|
||||
## CI/CD
|
||||
|
||||
- CircleCI configuration in `.circleci/config.yml`
|
||||
- Runs validation (vet, lint), tests, and module checks
|
||||
- Uses golangci-lint for linting
|
||||
|
||||
## Develop Notes
|
||||
- Always response in Chinese
|
||||
34
Dockerfile
Normal file
34
Dockerfile
Normal file
@@ -0,0 +1,34 @@
|
||||
ARG GOLANG_CI_LINT_VERSION
|
||||
|
||||
FROM golang:1.23 as builder
|
||||
ENV PATH /go/bin:/usr/local/go/bin:$PATH
|
||||
ENV GOPATH /go
|
||||
COPY . /go/src/github.com/virtual-kubelet/alibabacloud-eci
|
||||
WORKDIR /go/src/github.com/virtual-kubelet/alibabacloud-eci
|
||||
RUN make build
|
||||
RUN cp bin/virtual-kubelet /usr/bin/virtual-kubelet
|
||||
|
||||
FROM golangci/golangci-lint:${GOLANG_CI_LINT_VERSION} as lint
|
||||
WORKDIR /app
|
||||
COPY go.mod ./
|
||||
COPY go.sum ./
|
||||
RUN \
|
||||
--mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go mod download
|
||||
COPY . .
|
||||
ARG OUT_FORMAT
|
||||
RUN \
|
||||
--mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
--mount=type=cache,target=/root/.cache/golangci-lint \
|
||||
golangci-lint run -v --out-format="${OUT_FORMAT:-colored-line-number}"
|
||||
|
||||
FROM alpine:latest
|
||||
COPY --from=builder /usr/bin/virtual-kubelet /usr/bin/virtual-kubelet
|
||||
COPY --from=builder /etc/ssl/certs/ /etc/ssl/certs
|
||||
|
||||
RUN mkdir -p /root/.kube
|
||||
|
||||
ENTRYPOINT [ "/usr/bin/virtual-kubelet" ]
|
||||
CMD [ "--help" ]
|
||||
230
docs/eci.md
Normal file
230
docs/eci.md
Normal file
@@ -0,0 +1,230 @@
|
||||
```markdown
|
||||
# 创建抢占式实例
|
||||
|
||||
**更新时间:2024-11-19 14:56:45**
|
||||
|
||||
ECI支持抢占式实例,对于短时间运行的Job任务,以及部分扩展性和容错率高的无状态应用,使用抢占式实例可以有效地节约实例使用成本。本文介绍在Kubernetes集群中,如何创建抢占式实例类型的ECI Pod。
|
||||
|
||||
## 背景信息
|
||||
|
||||
抢占式实例是一种低成本竞价型实例,您可以对阿里云当前闲置的资源出价,获得资源后运行容器,直到出价低于市场价格或者库存不足等原因导致资源回收。
|
||||
|
||||
抢占式实例适用于短时间运行的Job任务,以及部分扩展性和容错率高的无状态应用,例如可弹性伸缩的Web站点服务、图像渲染、大数据分析和大规模并行计算等。应用程序的分布度、可扩展性和容错能力越高,越适合使用抢占式实例节省成本和提升吞吐量。更多信息,请参见[什么是抢占式实例](https://help.aliyun.com/zh/eci/user-guide/overview-22)。
|
||||
|
||||
## 基本概念
|
||||
|
||||
创建抢占式实例前,您需要了解以下信息:
|
||||
|
||||
### 计费方式
|
||||
|
||||
抢占式实例的市场价格随供需变化而浮动,您需要在创建抢占式实例时指定出价模式,当指定实例规格的实时市场价格低于出价且库存充足时,就能成功创建抢占式实例。创建成功后,在保护期(默认1小时)内按照成交时的市场价格计费。超过保护期后,按照实时的市场价格计费。
|
||||
|
||||
> **说明**
|
||||
> 抢占式实例相对于按量付费实例价格有一定的折扣,实际价格随供求波动,并按实际使用时长进行收费。更多信息,请参见[抢占式实例计费](https://help.aliyun.com/zh/eci/user-guide/billing-overview-4)。
|
||||
|
||||
### 回收机制
|
||||
|
||||
超过保护期后,系统每隔5分钟将自动检测一次实例规格的市场价格和库存。如果某一时刻的市场价格高于出价或实例规格库存不足,抢占式实例会被释放。
|
||||
|
||||
> **说明**
|
||||
> 资源回收前约3分钟,系统会产生准备释放的事件。
|
||||
>
|
||||
> 资源回收后,实例不再收费,但会保留实例信息,且状态会变更为已过期(Expired)。
|
||||
|
||||
## 注意事项
|
||||
|
||||
基于抢占式实例的特点,使用抢占式实例时,请注意以下信息:
|
||||
|
||||
- 选择一个合适的实例规格和一个合理的出价。
|
||||
- 您可以通过ECS的OpenAPI接口查询抢占式实例近30天的信息,以便选择实例规格和出价。相关接口如下:
|
||||
- `DescribeSpotPriceHistory`:查询实例历史价格。
|
||||
- `DescribeSpotAdvice`:查询实例平均释放率、平均折扣率等信息。
|
||||
|
||||
> **重要**
|
||||
> 您的出价应该足够高,同时充分考虑了市场价格的波动,并且符合您对自身业务评估后的预期。这样才能成功创建抢占式实例,且实例不会因为价格因素被释放,在满足业务需求的同时实现成本节约。
|
||||
>
|
||||
> 使用不受抢占式实例释放影响的存储介质来保存您的重要数据,例如:云盘(关闭随实例释放)、NAS等。
|
||||
|
||||
## 创建方式
|
||||
|
||||
支持指定ECS规格,或者指定vCPU和内存来创建抢占式ECI实例:
|
||||
|
||||
### 指定ECS规格
|
||||
|
||||
计费以指定规格的按量市场价格和实时折扣为准。
|
||||
|
||||
### 指定vCPU和内存
|
||||
|
||||
该方式与指定ECS规格方式的效果相同。系统会自动匹配满足规格和价格要求的ECS规格,并以此规格的市场价格作为计费的原始市场价格,即折扣是基于该ECS规格的市场价,而非对应ECI的vCPU和内存的按量价格。
|
||||
|
||||
该方式仅支持2 vCPU及以上规格,支持指定的vCPU和内存规格如下表所示。如果指定的规格不支持,系统会自动向上规整。
|
||||
|
||||
| vCPU | 内存(GiB) |
|
||||
|------|-------------|
|
||||
| 2 | 2、4、8、16 |
|
||||
| 4 | 4、8、16、32 |
|
||||
| 8 | 8、16、32、64 |
|
||||
| 12 | 12、24、48、96 |
|
||||
| 16 | 16、32、64、128 |
|
||||
| 24 | 24、48、96、192 |
|
||||
| 32 | 32、64、128、256 |
|
||||
| 52 | 96、192、384 |
|
||||
| 64 | 128、256、512 |
|
||||
|
||||
## 配置说明
|
||||
|
||||
您可以在Pod metadata中添加Annotation来创建抢占式实例。相关Annotation如下:
|
||||
|
||||
| Annotation | 示例值 | 是否必选 | 说明 |
|
||||
|------------|--------|----------|------|
|
||||
| `k8s.aliyun.com/eci-spot-strategy` | `SpotAsPriceGo` | 是 | 抢占式实例的出价策略。可根据需要配置为:<br>- `SpotWithPriceLimit`:自定义设置抢占实例价格上限。此时必须通过`k8s.aliyun.com/eci-spot-price-limit`来指定每小时价格上限。<br>- `SpotAsPriceGo`:系统自动出价,跟随当前市场实际价格。<br><br>**重要**:使用`SpotAsPriceGo`策略时,如果对应可用区规格资源紧张,最高价格可能会达到按量价格。 |
|
||||
| `k8s.aliyun.com/eci-spot-price-limit` | `"0.5"` | 否 | 抢占式实例的每小时价格上限,最多支持精确到小数点后三位。<br>仅当`k8s.aliyun.com/eci-spot-strategy`设置为`SpotWithPriceLimit`时有效。 |
|
||||
| `k8s.aliyun.com/eci-spot-duration` | `"0"` | 否 | 抢占式实例的保护期。默认为1,可设置为0,表示无保护期。 |
|
||||
| `k8s.aliyun.com/eci-spot-fallback` | `"true"` | 否 | 抢占式实例没有库存时,是否自动转为按量付费,以保证实例创建成功。默认为false。 |
|
||||
|
||||
> **重要**
|
||||
> - Annotation请添加在Pod的metadata下,例如:创建Job时,Annotation需添加在`spec>template>metadata`下。
|
||||
> - 仅支持在创建ECI Pod时添加ECI相关Annotation来生效ECI功能,更新ECI Pod时添加或者修改ECI相关Annotation均不会生效。
|
||||
|
||||
### 示例一:指定ECS规格,采用SpotWithPriceLimit策略
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: spot-example-1
|
||||
annotations:
|
||||
k8s.aliyun.com/eci-spot-strategy: "SpotWithPriceLimit"
|
||||
k8s.aliyun.com/eci-spot-price-limit: "0.5"
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
||||
```
|
||||
|
||||
### 示例二:指定vCPU和内存,采用SpotAsPriceGo策略
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: spot-example-2
|
||||
annotations:
|
||||
k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo"
|
||||
k8s.aliyun.com/eci-use-specs: "2-4Gi"
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
||||
```
|
||||
|
||||
### 示例三:设置无保护期
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: spot-example-3
|
||||
annotations:
|
||||
k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo"
|
||||
k8s.aliyun.com/eci-spot-duration: "0"
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
||||
```
|
||||
|
||||
### 示例四:设置没有库存时自动转为按量付费
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: spot-example-4
|
||||
annotations:
|
||||
k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo"
|
||||
k8s.aliyun.com/eci-spot-fallback: "true"
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
||||
```
|
||||
|
||||
## 释放说明
|
||||
|
||||
抢占式实例创建成功后,在保护期内可以正常运行。超出保护期后,如果市场价格高于出价或者资源库存不足,抢占式实例会被释放。您可以通过以下信息了解抢占式实例的释放情况。
|
||||
|
||||
### 预释放事件
|
||||
|
||||
抢占式实例在释放前约3分钟,会产生`SpotToBeReleased`事件。
|
||||
|
||||
> **重要**
|
||||
> ECI会通过Kubernetes Events事件通知的方式告知您抢占式实例将被释放。在此期间,您可以做一定的处理来确保业务不受实例释放所影响。更多信息,请参见[优雅下线](#优雅下线)。
|
||||
|
||||
通过`kubectl describe`命令查看Pod详细信息,在返回信息的Events中可以看到预释放事件。示例如下:
|
||||
|
||||
```bash
|
||||
Events:
|
||||
Type Reason Age From Message
|
||||
---- ------ ---- ---- -------
|
||||
Warning SpotToBeReleased 3m32s kubelet, eci Spot ECI will be released in 3 minutes
|
||||
```
|
||||
|
||||
通过`kubectl get events`命令查看事件信息,在返回信息中可以看到预释放事件。示例如下:
|
||||
|
||||
```bash
|
||||
LAST SEEN TYPE REASON OBJECT MESSAGE
|
||||
3m39s Warning SpotToBeReleased pod/pi-frmr8 Spot ECI will be released in 3 minutes
|
||||
```
|
||||
|
||||
### 释放后Pod状态
|
||||
|
||||
抢占式实例释放后,实例信息仍会保留,状态变更为`Failed`,Failed原因为`BidFailed`。
|
||||
|
||||
通过`kubectl get pod`命令查看Pod信息,在返回信息中可以看到Pod状态已变更。示例如下:
|
||||
|
||||
```bash
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pi-frmr8 1/1 BidFailed 0 3h5m
|
||||
```
|
||||
|
||||
通过`kubectl describe`命令查看Pod详细信息,在返回信息中可以看到Pod状态信息。示例如下:
|
||||
|
||||
```bash
|
||||
Status: Failed
|
||||
Reason: BidFailed
|
||||
Message: The pod is spot instance, and have been released at 2020-04-08T12:36Z
|
||||
```
|
||||
|
||||
## 优雅下线
|
||||
|
||||
抢占式实例在释放前约3分钟,会产生`SpotToBeReleased`事件,同时会将Pod Conditions中的`ContainerInstanceExpired`字段置为`true`。为尽量避免抢占式实例回收导致的业务中断,您可以基于这些通知机制,进行抢占实例的优雅退出和Pod轮转等处理。
|
||||
|
||||
目前虚拟节点已支持配置ECI抢占式实例优雅下线的功能。您可以为抢占式实例类型的ECI Pod添加`k8s.aliyun.com/eci-spot-release-strategy: api-evict`的Annotation,实现当虚拟节点收到`SpotToBeReleased`事件时,会调用Eviction API来驱逐该抢占式实例。
|
||||
|
||||
> **重要**
|
||||
> ACK Virtual Node需要升级到v2.11.0及以上版本,才支持通过Pod Conditions进行抢占实例中断通知以及配置Eviction API来驱逐抢占式实例。更多信息,请参见[ACK Virtual Node](https://help.aliyun.com/zh/ack/ack-virtual-node)。
|
||||
|
||||
API发起的驱逐将遵从您的PodDisruptionBudget(PDB)和`terminationGracePeriodSeconds`配置。使用API创建Eviction对象,类似于对Pod执行策略控制的DELETE操作。相关流程如下:
|
||||
|
||||
1. **调用API请求**
|
||||
- 虚拟节点接收到`SpotToBeReleased` Event,调用Eviction API。
|
||||
|
||||
2. **PDB检查**
|
||||
- API服务器验证与目标Pod关联的PodDisruptionBudget。
|
||||
|
||||
3. **驱逐执行**
|
||||
- 如果API服务器允许驱逐,Pod将按照如下方式删除:
|
||||
- API服务器中的Pod资源会更新删除时间戳,之后API服务器会认为此Pod资源将被终止。此Pod资源还会标记上配置的宽限期。
|
||||
- 本地运行状态的Pod所处节点上的kubelet注意到Pod资源被标记为终止,并开始优雅停止本地Pod。
|
||||
- 当kubelet停止Pod时,控制面从Endpoint和EndpointSlice对象中移除该Pod。因此,控制器不再将此Pod视为有用对象。
|
||||
- Pod的宽限期到期后,kubelet强制终止本地Pod。
|
||||
- kubelet告知API服务器要删除Pod资源。
|
||||
- API服务器删除Pod资源。
|
||||
|
||||
4. **负载Reconcile**
|
||||
- 如果目标Pod是由控制器(如ReplicaSet、StatefulSet,以及设置了容错的Job、sparkApplication、Workflow)管理的,控制器通常会创建一个新的Pod来替代被驱逐的Pod。
|
||||
|
||||
> **说明**
|
||||
> 如果PodDisruptionBudget配置错误,或者调用Eviction API时工作负载存在大量尚未Ready的Pod,则会导致Eviction阻塞。在抢占式实例到期前,如果仍未完成Eviction动作,抢占式实例会被直接释放。
|
||||
```
|
||||
27
eci.go
27
eci.go
@@ -185,6 +185,33 @@ func (p *ECIProvider) CreatePod(ctx context.Context, pod *v1.Pod) error {
|
||||
request := eci.CreateCreateContainerGroupRequest()
|
||||
request.RestartPolicy = string(pod.Spec.RestartPolicy)
|
||||
|
||||
// 解析ECS规格注解
|
||||
if pod.Annotations != nil {
|
||||
if specs, exists := pod.Annotations["k8s.aliyun.com/eci-use-specs"]; exists {
|
||||
request.InstanceType = specs
|
||||
}
|
||||
|
||||
// 解析EIP注解
|
||||
if withEip, exists := pod.Annotations["k8s.aliyun.com/eci-with-eip"]; exists {
|
||||
if autoCreate, err := strconv.ParseBool(withEip); err == nil {
|
||||
request.AutoCreateEip = requests.Boolean(strconv.FormatBool(autoCreate))
|
||||
}
|
||||
}
|
||||
|
||||
if eipInstanceId, exists := pod.Annotations["k8s.aliyun.com/eci-eip-instanceid"]; exists {
|
||||
request.EipInstanceId = eipInstanceId
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有配置EIP注解,默认启用自动创建EIP
|
||||
if request.AutoCreateEip == "" && request.EipInstanceId == "" {
|
||||
request.AutoCreateEip = requests.Boolean(strconv.FormatBool(true))
|
||||
}
|
||||
|
||||
// 添加抢占式实例策略配置
|
||||
request.SpotStrategy = "SpotAsPriceGo" // 设置抢占式实例策略为按价格竞价
|
||||
//request.SpotDuration = 0 // 设置抢占式实例持续时间为0(非定时抢占)
|
||||
|
||||
// get containers
|
||||
containers, err := p.getContainers(pod, false)
|
||||
initContainers, err := p.getContainers(pod, true)
|
||||
|
||||
@@ -89,7 +89,12 @@ type CreateContainerGroupRequest struct {
|
||||
VSwitchId string `position:"Query" name:"VSwitchId"`
|
||||
Volumes []Volume `position:"Query" name:"Volume" type:"Repeated"`
|
||||
ContainerGroupName string `position:"Query" name:"ContainerGroupName"`
|
||||
AutoCreateEip requests.Boolean `position:"Query" name:"AutoCreateEip"`
|
||||
EipInstanceId string `position:"Query" name:"EipInstanceId"`
|
||||
ZoneId string `position:"Query" name:"ZoneId"`
|
||||
SpotStrategy string `position:"Query" name:"SpotStrategy"`
|
||||
InstanceType string `position:"Query" name:"InstanceType"`
|
||||
// SpotDuration requests.Integer `position:"Query" name:"SpotDuration"`
|
||||
}
|
||||
|
||||
type CreateContainer struct {
|
||||
|
||||
6
go.mod
6
go.mod
@@ -21,9 +21,9 @@ require (
|
||||
github.com/virtual-kubelet/virtual-kubelet v0.10.0
|
||||
go.opencensus.io v0.21.0
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/api v0.15.10
|
||||
k8s.io/apimachinery v0.15.10
|
||||
k8s.io/apiserver v0.15.10 // indirect
|
||||
k8s.io/api v0.0.0
|
||||
k8s.io/apimachinery v0.0.0
|
||||
k8s.io/apiserver v0.0.0-20190805142138-368b2058237c // indirect
|
||||
k8s.io/client-go v11.0.0+incompatible
|
||||
k8s.io/klog v0.3.3
|
||||
k8s.io/kubernetes v1.14.3 // indirect
|
||||
|
||||
13
go.sum
13
go.sum
@@ -209,9 +209,8 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
|
||||
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA=
|
||||
@@ -274,9 +273,8 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -284,12 +282,13 @@ k8s.io/api v0.0.0-20190805141119-fdd30b57c827 h1:Yf7m8lslHFWm22YDRTAHrGPh729A6Lm
|
||||
k8s.io/api v0.0.0-20190805141119-fdd30b57c827/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A=
|
||||
k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719 h1:uV4S5IB5g4Nvi+TBVNf3e9L4wrirlwYJ6w88jUQxTUw=
|
||||
k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719/go.mod h1:I4A+glKBHiTgiEjQiCCQfCAIcIMFGt291SmsvcrFzJA=
|
||||
k8s.io/apiserver v0.15.10 h1:jI3P8UzY4UcLUd14pFrqtJz5P9OtdQB37AcdVdI+9fA=
|
||||
k8s.io/apiserver v0.15.10/go.mod h1:6KNMxtnZD0q3kmaRiBF8xyuBeF/D6HlAHgtOR0CsNBc=
|
||||
k8s.io/apiserver v0.0.0-20190805142138-368b2058237c h1:OxQmmVHy+tsC9ciM88NSUWyX3PWastYCO192eVJ7HNg=
|
||||
k8s.io/apiserver v0.0.0-20190805142138-368b2058237c/go.mod h1:k9Vk6Fiw9pZljxzTtvH2MAfADQK6+hPgf7/eRaZb//o=
|
||||
k8s.io/client-go v0.0.0-20190805141520-2fe0317bcee0 h1:BtLpkscF7UZVmtKshdjDIcWLnfGOY01MRIdtYTUme+o=
|
||||
k8s.io/client-go v0.0.0-20190805141520-2fe0317bcee0/go.mod h1:ayzmabJptoFlxo7SQxN2Oz3a12t9kmpMKADzQmr5Zbc=
|
||||
k8s.io/component-base v0.15.10/go.mod h1:cYv0GMIaJQEHd1Pgdva5eBRxu1ZXwi1dyYAM0vRhyW0=
|
||||
k8s.io/component-base v0.0.0-20190805141645-3a5e5ac800ae/go.mod h1:VLedAFwENz2swOjm0zmUXpAP2mV55c49xgaOzPBI/QQ=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68=
|
||||
k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c=
|
||||
k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
|
||||
Reference in New Issue
Block a user