Предисловие переводчика: Minikube — удобный инструмент, который мы применяем в компании для локальных экспериментов с Kubernetes (в частности, для выполнения лабораторных работ по этой системе при обучении сотрудников). Эта статья показалась мне полезной во время моего знакомства с Kubernetes. Она написана год назад автором, использующим Mac OS X, а я проделывал все операции в Ubuntu 16.04 совсем недавно и с актуальными версиями основного софта: Minikube 0.20, Docker 17.06.0-ce, kubectl 1.7.0. Поэтому все выводы команд были переделаны под новые версии и незначительно отличаются от приведённых в оригинальной статье.
Kubernetes — система оркестровки контейнеров с открытым исходным кодом, готовая для production и предназначенная для автоматизации размещения, масштабирования и управления контейнерами.
Это упрощенная версия руководства Hello Minikube, в которой Minikube используется для запуска локального кластера Kubernetes вместо Google Container Engine, благодаря чему отпадает необходимость в наличии облачной платформы.
Руководство написано под Mac OS X, но представленные ниже команды подойдут и для любой другой ОС. (Как уже отмечалось выше, всё было воспроизведено и адаптировано под Linux — прим. перев.)
Предварительные условия
- Проверьте, что ваша система поддерживает виртуализацию VT-x/AMD-v с помощью команды:
- Для Linux:
$ cat /proc/cpuinfo | grep 'vmx|svm' flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts
- Для Mac OS X:
$ sysctl -a | grep machdep.cpu.features | grep VMX machdep.cpu.features: FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 CLFSH DS ACPI MMX FXSR SSE SSE2 SS HTT TM PBE SSE3 PCLMULQDQ DTES64 MON DSCPL VMX SMX EST TM2 SSSE3 CX16 TPR PDCM SSE4.1 SSE4.2 POPCNT AES PCID
Если команда вернула непустой результат — можно продолжать.
- Для Linux:
- Установите последний VirtualBox или VMware Fusion. В этом руководстве используется VirtualBox. Если вы устанавливали Docker Toolbox, то, возможно, у вас уже есть установленный VirtualBox.
- Проверить в Linux (Ubuntu/Debian):
$ dpkg -l | grep virtualbox ii unity-scope-virtualbox 0.1+13.10.20130723-0ubuntu1 all VirtualBox scope for Unity ii virtualbox-5.1 5.1.22-115126~Ubuntu~xenial amd64 Oracle VM VirtualBox
- В Mac OS X:
$ ls /Applications | grep VirtualBox VirtualBox.app
- Проверить в Linux (Ubuntu/Debian):
- Установите последний Minikube для вашей ОС и архитектуры:
- В Linux:
$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.20.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
- В Mac OS X:
$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.20.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
Прим. перев.:
sudo mv minikube /usr/local/bin/
можно убрать или поменять, если вы хотите использовать другой путь. - В Linux:
- Установите kubectl для вашей ОС и архитектуры:
- Для Linux:
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/
Прим. перев.: Для Ubuntu 16.04 и старше еще доступен snap-пакет:
$ sudo snap install kubectl --classic
- Для Mac OS X:
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/
- Для Linux:
Протестируйте свою инсталляцию Minikube
$ minikube start
Starting local Kubernetes v1.6.4 cluster...
Starting VM...
Moving files into cluster...
Setting up certs...
Starting cluster components...
Connecting to cluster...
Setting up kubeconfig...
Kubectl is now configured to use the cluster.
Мы можем увидеть список запущенных в кластере подов:
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system kube-addon-manager-minikube 1/1 Running 6 1d
kube-system kube-dns-1301475494-p5x6k 3/3 Running 18 1d
kube-system kubernetes-dashboard-llc98 1/1 Running 6 1d
… и нод:
$ kubectl get nodes
NAME STATUS AGE VERSION
minikube Ready 1d v1.6.4
Установка пода hello-minikube
Проект Minikube на GitHub предлагает демо-версию для быстрого старта, использующую собранный Docker-образ hello-minikube
. Так как мы уже запустили кластер, то первый шаг (minikube start
) можно пропустить.
Теперь давайте запустим встроенный под hello-minikube
. Для этого пода будет создан предварительно настроенный deployment:
$ kubectl run hello-minikube --image=gcr.io/google_containers/echoserver:1.4 --port=8080
deployment "hello-minikube" created
С помощью следующих команд мы можем посмотреть на актуальные списки подов и deployments, чтобы убедиться в случившихся изменениях:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-minikube-938614450-nng53 1/1 Running 0 2m
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-minikube 1 1 1 1 2m
Для доступа к сервису hello-minikube
нужно открыть ему внешний IP командой:
$ kubectl expose deployment hello-minikube --type=NodePort
service "hello-minikube" exposed
Примечание: необходимо использовать тип NodePort
, т.к. Minikube не поддерживает сервис LoadBalancer
. Так можно убедиться, что сервис стал открыт:
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-minikube 10.0.0.70 <nodes> 8080:30531/TCP 2m
kubernetes 10.0.0.1 <none> 443/TCP 1d
Теперь мы можем либо с помощью curl
из командной строки, либо браузером открыть ссылку на сервис. Чтобы узнать его внешний IP и порт, предварительно воспользуемся командой:
$ minikube service hello-minikube --url
http://192.168.99.100:30531
$ curl $(minikube service hello-minikube --url)
CLIENT VALUES:
client_address=172.17.0.1
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://192.168.99.100:8080/
SERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001
HEADERS RECEIVED:
accept=*/*
host=192.168.99.100:30531
user-agent=curl/7.47.0
BODY:
-no body in request-
Примечание: IP-адрес, который управляется VirtualBox'ом, может изменяться. Узнайте его с помощью команды minikube ip
или в выводе ifconfig
:
…
vboxnet0 Link encap:Ethernet HWaddr 0a:00:27:00:00:00
inet addr:192.168.99.1 Bcast:192.168.99.255 Mask:255.255.255.0
…
После того, как мы закончили с hello-minikube
, можем удалить его deployment и сервис, освободив ресурсы и проверив, что все действительно удалено:
$ kubectl delete service,deployment hello-minikube
service "hello-minikube" deleted
deployment "hello-minikube" deleted
$ kubectl get pods
No resources found.
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.0.0.1 <none> 443/TCP 1d
Сборка и установка сервиса с Docker
Этот пример несколько сложнее и описывает создание небольшого Node.js-сервера, сборки его в образ Docker с использованием Dockerfile и запуск в Kubernetes.
Создадим простой Node.js-проект hello-node
:
$ mkdir hello-node && cd hello-node && touch Dockerfile server.js
$ tree
.
├── Dockerfile
└── server.js
0 directories, 2 files
Создадим простой HTTP-сервер, который возвращает «Hello World!»:
$ vi server.js
var http = require('http');
var handleRequest = function(request, response) {
response.writeHead(200);
response.end('Hello World!');
};
var helloServer = http.createServer(handleRequest);
helloServer.listen(8080);
Поправим Dockerfile
, объявив, что образ использует node 4.4 и контейнер запускает сервис с помощью файла server.js
:
$ vi Dockerfile
FROM node:4.4
EXPOSE 8080
COPY server.js .
CMD node server.js
Перед запуском каких-либо команд Docker нужно задать окружение. Аналогично запуску eval $(docker-machine env)
, мы создаем переменные окружения Docker для Minikube с помощью команды minikube docker-env
:
$ eval $(minikube docker-env)
Теперь соберем образ. Это займет некоторое время, т.к. для разрешения зависимостей будут подгружены образы из Docker Hub, такие как node 4.4. По завершении вы получите новый Docker-образ, готовый к деплою (завершающая точка .
в конце команды говорит Docker собрать образ из текущей директории — прим. перев.):
$ docker build -t hello-node:v1 .
Sending build context to Docker daemon 3.072kB
Step 1 : FROM node:4.4
---> 93b396996a16
Step 2 : EXPOSE 8080
---> Using cache
---> 989ed85905c2
Step 3 : COPY server.js .
---> a5dc90f3df9d
Removing intermediate container 8fbc055e7016
Step 4 : CMD node server.js
---> Running in c58bc5e3daff
---> 8521ce4accb3
Removing intermediate container c58bc5e3daff
Successfully built 8521ce4accb3
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-node v1 8521ce4accb3 30 seconds ago 647MB
<none> <none> dc5a4cc0b371 3 days ago 647MB
gcr.io/google_containers/kubernetes-dashboard-amd64 v1.6.1 71dfe833ce74 2 months ago 134MB
gcr.io/google_containers/k8s-dns-sidecar-amd64 1.14.2 7c4034e4ffa4 2 months ago 44.5MB
gcr.io/google_containers/k8s-dns-kube-dns-amd64 1.14.2 ca8759c215c9 2 months ago 52.4MB
gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64 1.14.2 e5c335701995 2 months ago 44.8MB
gcr.io/google-containers/kube-addon-manager v6.4-beta.1 85809f318123 4 months ago 127MB
node 4.4 93b396996a16 11 months ago 647MB
gcr.io/google_containers/echoserver 1.4 a90209bb39e3 13 months ago 140MB
gcr.io/google_containers/pause-amd64 3.0 99e59f495ffa 14 months ago 747kB
Теперь мы можем разместить под hello-node
в локальный кластер Kubernetes с помощью kubectl
:
$ kubectl run hello-node --image=hello-node:v1 --port=8080
deployment "hello-node" created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-node-1644695913-h7qwh 1/1 Running 0 6s
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-node 1 1 1 1 18s
Как и прежде, необходимо присвоить сервису внешний IP и порт, чтобы получить к нему доступ с помощью curl
:
$ kubectl expose deployment hello-node --type=NodePort
service "hello-node" exposed
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node 10.0.0.219 <nodes> 8080:30987/TCP 8s
kubernetes 10.0.0.1 <none> 443/TCP 4d
$ curl $(minikube service hello-node --url)
Hello World!
Победа! Мы успешно написали, собрали и разместили простой сервис Node.js, используя Docker-образ в локальном кластере Kubernetes.
Этот игрушечный проект предназначен для начинающих, желающих попробовать Kubernetes локально перед тем, как вы начнете публиковать поды в платных облачных платформах. Он позволяет вам сделать первые шаги без лишних затрат на эти эксперименты.
Уборка
Не забудьте удалить сервис и deployment для hello-node
и выключить службу minikube
, когда закончите:
$ kubectl delete service,deployment hello-node
service "hello-node" deleted
deployment "hello-node" deleted
$ minikube stop
Stopping local Kubernetes cluster...
Machine stopped.
P.S. От переводчика
Более полную документацию по локальному запуску Kubernetes с Minikube можно найти на сайте проекта. Вам также могут быть интересны следующие статьи из нашего блога:
- «Наш опыт с Kubernetes в небольших проектах» (видео доклада, включающего в себя знакомство с техническим устройством Kubernetes);
- «Зачем нужен Kubernetes и почему он больше, чем PaaS?»;
- «Собираем Docker-образы для CI/CD быстро и удобно вместе с dapp» (видео доклада с HighLoad++ 2016).
Автор: Флант