Skaffold — это инструмент командной строки, разработанный Google, который призван содействовать непрерывной разработке приложений Kubernetes. Это автоматизирует задачу создания и развертывания в кластере Kubernetes, тогда как вы, как разработчик, можете сосредоточиться на написании кода. Это кажется достаточно интересным, чтобы поближе взглянуть на это!
Вступление
В ноябре 2019 года был объявлен общедоступный выпуск, обещающий сэкономить время разработчиков за счет автоматизации рабочего процесса разработки . Что Скаффолд сделает для нас?
- Он обнаруживает изменения источника во время разработки
- Он автоматически создает и создает ваши артефакты (ваш образ Docker) на основе Dockerfile или Jib
- Помечает артефакты
- Он выдвигает и развертывает артефакты в вашем кластере Kubernetes
Чтобы познакомиться со Skaffold, мы запустим локальный кластер Kubernetes с помощью minikube и развернем с помощью kubectl, инструмента интерфейса командной строки для Kubernetes.
Рекомендуется взглянуть на официальную документацию Skaffold и примеры для получения более подробной информации. Источники, которые мы используем в этом посте, доступны на GitHub .
Вам также может понравиться: Полная коллекция Kubernetes [Учебники и инструменты]
Предпосылки
Прежде чем начать, нам нужно установить minikube, kubectl и Skaffold, если вы этого еще не сделали. Мы будем использовать Ubuntu 18.04.
Установить Миникуб
Установка minikube (версия 1.6.2) довольно проста при работе с Linux. Если вы работаете с Windows, пожалуйста, взгляните на один из наших предыдущих постов , тогда это был довольно сложный путь, но, возможно, за это время ситуация улучшилась.
Сначала проверьте, включена ли в нашей системе поддержка виртуализации:
Оболочка
xxxxxxxxxx
1
$ egrep -q 'vmx|svm' /proc/cpuinfo && echo yes || echo no
2
yes
Вывод команды — да , что означает, что нам не нужно выполнять никаких дополнительных шагов.
Скачайте и установите миникуб:
Оболочка
xxxxxxxxxx
1
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_1.6.2.deb && sudo dpkg -i minikube_1.6.2.deb
Запустить миникуб:
Оболочка
xxxxxxxxxx
1
$ minikube start
2
minikube v1.6.2 on Ubuntu 18.04
3
Automatically selected the 'virtualbox' driver (alternates: [none])
4
Downloading VM boot image ...
5
> minikube-v1.6.0.iso.sha256: 65 B / 65 B [--------------] 100.00% ? p/s 0s
6
> minikube-v1.6.0.iso: 150.93 MiB / 150.93 MiB [-] 100.00% 8.44 MiB p/s 18s
7
Creating virtualbox VM (CPUs=2, Memory=2000MB, Disk=20000MB) ...
8
Preparing Kubernetes v1.17.0 on Docker '19.03.5' ...
9
Downloading kubelet v1.17.0
10
Downloading kubeadm v1.17.0
11
Pulling images ...
12
Launching Kubernetes ...
13
Waiting for cluster to come online ...
14
Done! kubectl is now configured to use "minikube"
Установить Kubectl
Инструкции по установке kubectl можно найти здесь . Для Linux мы должны выполнить следующие шаги, и kubectl version
мы проверим успешную установку:
Оболочка
xxxxxxxxxx
1
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
2
$ chmod +x ./kubectl
3
$ sudo mv ./kubectl /usr/local/bin/kubectl
4
$ kubectl version
5
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:20:10Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
6
Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.0", GitCommit:"70132b0f130acc0bed193d9ba59dd186f0e634cf", GitTreeState:"clean", BuildDate:"2019-12-07T21:12:17Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}
Установить Скаффолд
Инструкции по установке для Skaffold можно найти здесь . Инструкции очень похожи на инструкции для kubectl.
Оболочка
xxxxxxxxxx
1
$ curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
2
$ chmod +x skaffold
3
$ sudo mv skaffold /usr/local/bin
4
$ skaffold version
5
v1.1.0
Создать демо-приложение
Мы создадим простое демонстрационное приложение Spring Boot. Мы используем Spring MVC и создаем одну конечную точку REST, которая будет возвращать приветственное сообщение.
Наш pom содержит следующие зависимости и плагины:
XML
xxxxxxxxxx
1
<dependencies>
2
<dependency>
3
<groupId>org.springframework.boot</groupId>
4
<artifactId>spring-boot-starter-actuator</artifactId>
5
</dependency>
6
<dependency>
7
<groupId>org.springframework.boot</groupId>
8
<artifactId>spring-boot-starter-web</artifactId>
9
</dependency>
10
<dependency>
11
<groupId>org.springframework.boot</groupId>
12
<artifactId>spring-boot-starter-test</artifactId>
13
<scope>test</scope>
14
</dependency>
15
</dependencies>
16
17
<build>
18
<plugins>
19
<plugin>
20
<groupId>org.springframework.boot</groupId>
21
<artifactId>spring-boot-maven-plugin</artifactId>
22
</plugin>
23
</plugins>
24
</build>
HelloController
Содержит один метод, который возвращает приветственное сообщение и адрес хоста , на котором она выполняется.
Джава
xxxxxxxxxx
1
2
public class HelloController {
3
4
"/hello") (
5
public String hello() {
6
StringBuilder message = new StringBuilder("Hello Skaffold!");
7
try {
8
InetAddress ip = InetAddress.getLocalHost();
9
message.append(" From host: " + ip);
10
} catch (UnknownHostException e) {
11
e.printStackTrace();
12
}
13
return message.toString();
14
}
15
16
}
Используйте Скаффолд
Теперь, когда мы закончили все необходимые приготовления, пришло время начать использовать Скаффолд. В настоящее время мы сознательно оставили некоторые важные настройки, которые понадобятся Skaffold, но это позволит нам проверить, какие сообщения об ошибках возвращаются и как их решать.
Создать скаффолд.yaml
Skaffold понадобится skaffold.yaml
файл, содержащий рабочий процесс разработки, который вы хотите использовать. Файл может быть сгенерирован, когда init
команда выполняется из каталога вашего проекта.
Оболочка
xxxxxxxxxx
1
$ skaffold init
2
FATA[0000] one or more valid Kubernetes manifests is required to run skaffold
Skaffold init не создает файлы манифеста Kubernetes для нас , нам нужно будет создавать их вручную.
Мы создадим файл развертывания k8s с помощью kubectl. Мы копируем вывод команды в файл deployment.yaml
в k8s
каталоге. Параметр CLI --dry-run
гарантирует, что развертывание еще не выполнено, параметр -oyaml
выведет конфигурацию, которая позволит нам просто скопировать содержимое.
Оболочка
xxxxxxxxxx
1
$ kubectl create deployment myskaffoldplanet --image=docker.io/mydeveloperplanet/myskaffoldplanet --dry-run -oyaml
2
apiVersion: apps/v1
3
kind: Deployment
4
metadata:
5
creationTimestamp: null
6
labels:
7
app: myskaffoldplanet
8
name: myskaffoldplanet
9
spec:
10
replicas: 1
11
selector:
12
matchLabels:
13
app: myskaffoldplanet
14
strategy: {}
15
template:
16
metadata:
17
creationTimestamp: null
18
labels:
19
app: myskaffoldplanet
20
spec:
21
containers:
22
- image: docker.io/mydeveloperplanet/myskaffoldplanet
23
name: myskaffoldplanet
24
resources: {}
25
status: {}
При skaffold init
повторном запуске возвращается новая ошибка:
Оболочка
xxxxxxxxxx
1
$ skaffold init
2
FATA[0000] one or more valid builder configuration (Dockerfile or Jib configuration) must be present to build images with skaffold; please provide at least one build config and try again or run `skaffold init --skip-build`
Мы могли ожидать этого, потому что мы не предоставили конфигурацию Dockerfile или Jib. Мы будем использовать Jib после нашего положительного опыта с ним в нашем предыдущем посте . Добавьте плагин Jib Maven к нашему pom
. Мы не предоставляем учетные данные на этот раз, потому что мы не собираемся помещать образ Docker в реестр Docker.
XML
xxxxxxxxxx
1
<plugin>
2
<groupId>com.google.cloud.tools</groupId>
3
<artifactId>jib-maven-plugin</artifactId>
4
<version>1.8.0</version>
5
<configuration>
6
<!-- openjdk:11.0.5-jre -->
7
<from>
8
<image>openjdk@sha256:b3e19d27caa8249aad6f90c6e987943d03e915bbf3a66bc1b7f994a4fed668f6</image>
9
</from>
10
<to>
11
<image>docker.io/${docker.image.prefix}/${project.artifactId}</image>
12
<tags>
13
<tag>${project.version}</tag>
14
</tags>
15
</to>
16
<container>
17
<mainClass>com.mydeveloperplanet.myskaffoldplanet.MySkaffoldPlanetApplication</mainClass>
18
<user>nobody</user>
19
</container>
20
</configuration>
21
</plugin>
Чтобы использовать Jib, нам нужно добавить флаг --XXenableJibInit
, см. Также эту проблему .
Оболочка
xxxxxxxxxx
1
$ skaffold init --XXenableJibInit
2
apiVersion: skaffold/v2alpha1
3
kind: Config
4
metadata:
5
name: myskaffoldplanet
6
build:
7
artifacts:
8
- image: docker.io/mydeveloperplanet/myskaffoldplanet
9
jib: {}
10
deploy:
11
kubectl:
12
manifests:
13
- k8s/deployment.yaml
14
15
Do you want to write this configuration to skaffold.yaml? [y/n]: y
16
Configuration skaffold.yaml was written
17
You can now run [skaffold build] to build the artifacts
18
or [skaffold run] to build and deploy
19
or [skaffold dev] to enter development mode, with auto-redeploy
Скаффолд Непрерывное развитие
Мы настроили всю необходимую конфигурацию, чтобы поэкспериментировать с skaffold dev
командой. Это отсканирует наш проект на наличие изменений и автоматически соберет и развернет их в нашем кластере Kubernetes. Запустите следующую команду:
Оболочка
xxxxxxxxxx
1
$ skaffold dev
Наше приложение создается и разворачивается в нашем кластере Kubernetes. Мы также можем проверить это с помощью приборной панели minikube:
Оболочка
xxxxxxxxxx
1
$ minikube dashboard
Мы пока не можем вызвать наш URL, потому что мы еще не создали сервис. Мы отобразим порт 8080 через NodePort
. Сгенерируйте сервис yaml и добавьте содержимое (без меток) в файл service.yaml
в k8s
каталоге:
Оболочка
xxxxxxxxxx
1
$ kubectl expose deployment myskaffoldplanet --type=NodePort --port=8080 --dry-run -oyaml
2
apiVersion: v1
3
kind: Service
4
metadata:
5
creationTimestamp: null
6
labels:
7
app: myskaffoldplanet
8
app.kubernetes.io/managed-by: skaffold-v1.1.0
9
skaffold.dev/builder: local
10
skaffold.dev/cleanup: "true"
11
skaffold.dev/deployer: kubectl
12
skaffold.dev/docker-api-version: "1.40"
13
skaffold.dev/run-id: c8fc23d2-85f5-453a-bc22-19f4a9ec88a6
14
skaffold.dev/tag-policy: git-commit
15
skaffold.dev/tail: "true"
16
name: myskaffoldplanet
17
spec:
18
ports:
19
- port: 8080
20
protocol: TCP
21
targetPort: 8080
22
selector:
23
app: myskaffoldplanet
24
type: NodePort
25
status:
26
loadBalancer: {}
Также добавьте service.yaml
файл как манифест в skaffold.yaml
файл:
YAML
xxxxxxxxxx
1
deploy
2
kubectl
3
manifests
4
k8s/deployment.yaml
5
k8s/service.yaml
Скаффолд немедленно замечает это изменение и создает сервис. Это можно проверить в выводе консоли Skaffold:
Оболочка
xxxxxxxxxx
1
Starting deploy...
2
- deployment.apps/myskaffoldplanet configured
3
- service/myskaffoldplanet created
4
Watching for changes...
Проверьте создание сервиса с помощью kubectl:
Оболочка
xxxxxxxxxx
1
$ kubectl get services
2
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3
kubernetes ClusterIP 10.96.0.1 443/TCP 24h
4
myskaffoldplanet NodePort 10.96.65.87 8080:30272/TCP 42s
NodePort
, Который был назначен, порт 30272 (см столбец PORT (S)). Теперь мы можем вызвать нашу конечную точку отдыха:
Оболочка
xxxxxxxxxx
1
$ curl $(minikube ip):30272/hello
2
Hello Skaffold! From host: myskaffoldplanet-76f44959c9-tcvw5/172.17.0.6
Измените текст приветствия в HelloController
:
Джава
xxxxxxxxxx
1
StringBuilder message = new StringBuilder("Hello there, Skaffold!");
Опять же, изменение автоматически обнаруживается Skaffold, и в фоновом режиме наше приложение создается и разворачивается. Еще раз введите URL:
Оболочка
xxxxxxxxxx
1
$ curl $(minikube ip):30272/hello
2
Hello there, Skaffold! From host: myskaffoldplanet-54b59fb785-hczn8/172.17.0.7
Мы также можем использовать команду skaffold run
для развертывания по запросу:
Оболочка
xxxxxxxxxx
1
$ skaffold run
2
...
3
Starting deploy...
4
- deployment.apps/myskaffoldplanet created
5
- service/myskaffoldplanet created
6
You can also run [skaffold run --tail] to get the logs
Опять же, проверьте, работает ли NodePort
служба, и вызовите URL.
Поиск проблемы
Однажды мы столкнулись со следующей ошибкой при запуске skaffold dev
и skaffold run
:
Оболочка
xxxxxxxxxx
1
rpc error: code = Unknown desc = Error response from daemon: pull access denied for mydeveloperplanet/myskaffoldplanet, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
Мы решили это, добавив следующие строки в skaffold.yaml
файл. Позже, казалось, больше не было необходимости.
YAML
xxxxxxxxxx
1
build
2
local
3
pushfalse
4
artifacts
5
image docker.io/mydeveloperplanet/myskaffoldplanet
6
jib
Заключение
В этой статье мы рассмотрели Skaffold для автоматической сборки и развертывания нашего приложения в кластере Kubernetes во время разработки. Мы лишь поцарапали поверхность того, на что способен Скаффолд, но этот инструмент нас очень впечатлил. Определенно что-то, чтобы использовать и следить.