Ресурсы/объекты в Kubernetes (Deployment, Service, ReplicaSet, Pod и т .д.) можно создавать двумя методами/способами
Императивный – определяем что должно произойти/какие команды нужно выполнить и в какой последовательности, каким образом нужно получить желаемое состояние ресурсов
Декларативный – определяем состояние ресурсов, которое мы хотим получить, без указания каким именно образом должно быть достигнуто такое состояние.
Такое определение выражается в создании yaml|json манифестов с последующим их применением
Императивное создание ресурсов(Imperative)
Создадим Deployment с именем hello-world
1 |
# kubectl run hello-world --image=gcr.io/google-samples/hello-app:1.0 |
1 2 |
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. deployment.apps/hello-world created |
При этом создается следующая цепочка ресурсов
1 |
Deployment->ReplicaSet->Pod |
Имя ReplicaSet имеет формат
1 |
<Deployment-name>-<random-string> |
Имя Pod-а имеет формат
1 |
<ReplicaSet-name>-<another-random-string> |
т.е.
1 |
<Deployment-name>-<random-string>-<another-random-string> |
Просмотр всех существующих ресурсов в дефолтном namespace
1 |
# kubectl get all |
1 2 3 4 5 6 7 8 9 10 11 |
NAME READY STATUS RESTARTS AGE pod/hello-world-58d58c846c-66pwl 1/1 Running 0 26s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d16h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/hello-world 1/1 1 1 26s NAME DESIRED CURRENT READY AGE replicaset.apps/hello-world-58d58c846c 1 1 1 26s |
Детальное описание пода, реплики-сет и деплоймента
1 |
# kubectl describe pod hello-world-58d58c846c-66pwl |
1 |
# kubectl describe rs hello-world-58d58c846c |
1 |
# kubectl describe deployment hello-world |
Просмотр сущесутвующих Pod-ов в default namespace
1 |
# kubectl get pods |
1 2 |
NAME READY STATUS RESTARTS AGE hello-world-58d58c846c-66pwl 1/1 Running 0 7m1s |
Просмотр сущесутвующих ReplicaSet в default namespace
1 |
# kubectl get rs |
1 2 |
NAME DESIRED CURRENT READY AGE hello-world-58d58c846c 1 1 1 7m5s |
Просмотр сущесутвующих Deployment в default namespace
1 |
# kubectl get deployment |
1 2 |
NAME READY UP-TO-DATE AVAILABLE AGE hello-world 1/1 1 1 7m9s |
Просмотр ноды, на которой запущен под
1 |
# kubectl get pod -o wide |
1 2 |
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hello-world-58d58c846c-66pwl 1/1 Running 0 9m20s 192.168.1.2 kub-node1 <none> <none> |
Просмотр логов контейнера, запущенного в поде hello-world-58d58c846c-66pwl
1 |
# kubectl logs -f hello-world-58d58c846c-66pwl |
1 |
2019/03/27 09:33:37 Server listening on port 8080 |
Альтернативным вариантом просмотра логов контейнера, является их просмотр через docker команду, выполненную на ноде, на которой запущен Pod
Подключимся к ноде, на которой запущен под и посмотрим логии контейнера
1 |
# ssh kub-node1 |
1 |
root@kub-node1 ~ # docker ps |
1 2 3 |
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f4bc927c3bce gcr.io/google-samples/hello-app "./hello-app" 9 minutes ago Up 9 minutes k8s_hello-world_hello-world-58d58c846c-66pwl_default_64c1ca5b-5073-11e9-bd78-5a86f7c1ad23_0 96fd36655665 k8s.gcr.io/pause:3.1 "/pause" 9 minutes ago Up 9 minutes k8s_POD_hello-world-58d58c846c-66pwl_default_64c1ca5b-5073-11e9-bd78-5a86f7c1ad23_0 |
1 |
root@kub-node1 ~ # docker logs -f f4bc927c3bce |
1 |
2019/03/27 09:33:37 Server listening on port 8080 |
Выполнение команд внутри контейнера, запущенного внутри пода
1 |
# kubectl exec -it hello-world-58d58c846c-66pwl -- /bin/sh |
1 |
/ # hostname |
1 |
hello-world-58d58c846c-66pwl |
1 |
/ # ip addr |
1 2 3 4 5 6 7 8 9 10 |
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1440 qdisc noqueue state UP link/ether 36:b6:b7:1a:f5:9b brd ff:ff:ff:ff:ff:ff inet 192.168.1.2/32 scope global eth0 valid_lft forever preferred_lft forever |
1 |
/ # exit |
Создание Service для существующего deployment(порт сервиса 80 и порт приложения, запущенного в контейнере – 8080)
Будет создан Service с типом ClusterIP(доступ к такому сервису возможен только изнутри кластера)
1 |
# kubectl expose deployment hello-world --port 80 --target-port 8080 |
1 |
service/hello-world exposed |
Проверка наличия созданного ресурса Service с именем hello-world, а также кластерного IP-адреса и порта, на котором доступна Service
1 |
# kubectl get service hello-world |
1 2 |
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world ClusterIP 10.108.178.162 <none> 80/TCP 20m |
Просмотр детального описания Service(также здесь указаны конечные точки(endpoints) – поды, на которые по факту перенаправляются запросы, поступающие на Service)
1 |
# kubectl describe service hello-world |
1 2 3 4 5 6 7 8 9 10 11 12 |
Name: hello-world Namespace: default Labels: run=hello-world Annotations: <none> Selector: run=hello-world Type: ClusterIP IP: 10.108.178.162 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 192.168.1.2:80 Session Affinity: None Events: <none> |
Доступ к Service внутри кластера – т.е. с любой ноды и с любого пода можно получить доступ к Service по следующем кластерному адресу и порту 10.108.178.162:80
Service действует как виртуальный балансировщик нагрузки, перенаправляя поступивший на Service запрос одному из активных/запущенных Pod-ов(endpoint-ов) и принимая ответ от этого Poda для дальнейшей передачи его клиенту
Проверяем доступ к Service со всех нод
1 |
root@kub-node1 ~ # curl 10.108.178.162:80 |
1 2 3 |
Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-66pwl |
1 |
root@kub-node2 ~ # curl 10.108.178.162:80 |
1 2 3 |
Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-66pwl |
1 |
root@kub-master ~ # curl 10.108.178.162:80 |
1 2 3 |
Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-66pwl |
Для траблшутинга/дебага также можно напрямую обращаться/посылать запрос на активные/текущие pod-ы (в описании Service, доступного по команде kubectl describe service hello-world, они указывается в параметре Endpoints)
Просмотр текущих endpoint-ов, доступных для Service
1 |
# kubectl get endpoints hello-world |
1 2 |
NAME ENDPOINTS AGE hello-world 192.168.1.2:8080 29m |
Проверка доступности указанного пода со всех нод кластера
1 |
root@kub-master ~ # curl 192.168.1.2:8080 |
1 2 3 |
Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-66pwl |
1 |
root@kub-node1 ~ # curl 192.168.1.2:8080 |
1 2 3 |
Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-66pwl |
1 |
root@kub-node2 ~ # curl 192.168.1.2:8080 |
1 2 3 |
Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-66pwl |
Получение информации об объекте/ресурсе
1 |
# kubectl explain service | less |
Получение доступных параметров/опций для описания ресурса
1 |
# kubectl explain service.spec | less |
1 |
# kubectl explain service.spec | less |
1 |
# kubectl explain service.spec.ports | less |
Получение описания ресурсов(например, service) в json,yaml-форматах
1 |
# kubectl get service hello-world -o json |
1 |
# kubectl get service hello-world -o yaml |
Экспортирование описания ресурсов service и deployment в yaml-файл.
1 |
# kubectl get service hello-world -o yaml --export > service-hello-world.yaml |
1 |
# kubectl get deployment hello-world -o yaml --export > deployment-hello-world.yaml |
1 |
# ls -l *.yaml |
1 2 |
-rw-r--r-- 1 root root 1046 Mar 27 12:14 deployment-hello-world.yaml -rw-r--r-- 1 root root 345 Mar 27 12:13 service-hello-world.yaml |
Полученные YAML-файлы можно использовать для создания тех же ресурсов, из описания которых они были cозданы(service, deployment)
Удаление ресурсов, созданных императивным способом
1 |
# kubectl delete service hello-world |
1 |
service "hello-world" deleted |
1 |
# kubectl delete deployment hello-world |
1 |
deployment.extensions "hello-world" deleted |
Проверим отсутствие ресурсов
1 |
# kubectl get all | grep hello |
Создание объектов/ресурсов типа Deployment и Service с помощью декларативного способа(Declarative)
1 |
# kubectl apply -f deployment-hello-world.yaml |
1 |
deployment.extensions/hello-world created |
1 |
# kubectl apply -f service-hello-world.yaml |
1 |
service/hello-world created |
Проверяем наличие созданных ресурсов(включая ReplicaSet иPod)
1 |
# kubectl get all |
1 2 3 4 5 6 7 8 9 10 11 12 |
NAME READY STATUS RESTARTS AGE pod/hello-world-58d58c846c-wg2cr 1/1 Running 0 29s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/hello-world ClusterIP 10.101.79.190 <none> 80/TCP 24s service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d19h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/hello-world 1/1 1 1 29s NAME DESIRED CURRENT READY AGE replicaset.apps/hello-world-58d58c846c 1 1 1 29s |
Проверим доступность Service
1 |
# curl 10.101.79.190:80 |
1 2 3 |
Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-wg2cr |
Масштабируем наш деплоймент с одной до двух реплик
1 |
# nano deployment-hello-world.yaml |
1 2 3 |
… replicas: 2 … |
Обновляем нашу конфигурацию с помощью команды kubectl apply
1 |
# kubectl apply -f deployment-hello-world.yaml |
1 |
deployment.extensions/hello-world configured |
Проверяем наличие двух реплик deployment
1 |
# kubectl get deployment hello-world |
1 2 |
NAME READY UP-TO-DATE AVAILABLE AGE hello-world 2/2 2 2 8m53s |
Выполним сurl-запросы к Service hello-world для проверки балансировки запросов на разные Pod-ы
Просмотр кластерного IP-адреса и порта Service
1 |
# kubectl get service hello-world |
1 2 |
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world ClusterIP 10.101.79.190 <none> 80/TCP 10m |
Просмотр доступных Pod-ов для Service hello-world
1 |
# kubectl get endpoints hello-world |
1 2 |
NAME ENDPOINTS AGE hello-world 192.168.1.3:8080,192.168.2.2:8080 13m |
1 |
# kubectl get pod -l "run=hello-world" |
1 2 3 |
NAME READY STATUS RESTARTS AGE hello-world-58d58c846c-9qptx 1/1 Running 0 8m13s hello-world-58d58c846c-wg2cr 1/1 Running 0 15m |
Проверка балансировки запросов между подами
1 |
# for i in `seq 1 7`; do curl 10.101.79.190:80; done |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-9qptx Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-9qptx Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-wg2cr Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-wg2cr Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-wg2cr Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-9qptx Hello, world! Version: 1.0.0 Hostname: hello-world-58d58c846c-wg2cr |
Изменение ресурсов «на лету»
Можно редактировать ресурсы «на лету» внося изменения конфигурации с помощью команды kubectl edit.
Изменения сразу сохраняются в etcd – кластерное хранилище
При этом, естественно, эти изменения не влияют на/не изменяют yaml-файлы, с которых создавались ресурсы декларативным методом
Например, увеличим кол-ва реплик деплоймента с 2-х до 3-х
1 |
# kubectl edit deployment hello-world |
1 2 3 |
… replicas: 3 … |
Проверяем кол-во деплойментов и соответсвенно подов
1 |
# kubectl get deployment |
1 2 |
NAME READY UP-TO-DATE AVAILABLE AGE hello-world 3/3 3 3 17m |
1 |
# kubectl get pod -l "run=hello-world" |
1 2 3 4 |
NAME READY STATUS RESTARTS AGE hello-world-58d58c846c-9qptx 1/1 Running 0 10m hello-world-58d58c846c-nb8vn 1/1 Running 0 73s hello-world-58d58c846c-wg2cr 1/1 Running 0 18m |
Удаление созданный декларативным методом ресурсов.
1 |
# kubectl delete service hello-world |
1 |
# kubectl delete deployment hello-world |
1 |
# kubectl get all |
Полезные команды kubectl
https://kubernetes.io/docs/reference/kubectl/cheatsheet
https://github.com/dennyzhang/cheatsheet-kubernetes-A4
Несколько полезных команд kubectl
1 |
# kubectl get node |
1 |
# kubectl get node -o wide |
1 |
# kubectl get pods |
1 |
# kubectl get pods --namespace kube-system |
1 |
# kubectl get pods --namespace kube-system -o wide |
1 |
# kubectl get pod --all-namespaces |
1 |
# kubectl get all --all-namespaces -o wide |
1 |
# kubectl get all --all-namespaces |
1 |
# kubectl api-resources | head -n 10 |
1 |
# kubectl api-resources | grep pod |
1 |
# kubectl explain pod |
1 |
# kubectl explain pod.spec |
1 |
# kubectl explain pod.spec.containers |
1 |
# kubectl describe node nodename |
Источник:
https://kubernetes.io/docs/reference/kubectl/overview