Таким образом, вы следовали основным шагам, чтобы получить сервис, развернутый в Кубейнес, давайте скажем, что сервис Nginx , потому что почему нет …
$ kubectl create deployment ngx --image=nginx:latest
Давайте масштабируемся до 2, потому что действительно запущено всего 1 POD, слишком базовый
$ kubectl scale deployment --replicas 2 ngx
У вас есть 2 Nginx Стручки работают на вашем кластере K8S «, я использую встроенную установку K8S, которая поставляется с Docker Edge
$ kubectl get pods NAME READY STATUS RESTARTS AGE ngx-5cb59c856c-cmn8p 1/1 Running 0 52m ngx-5cb59c856c-s65nh 1/1 Running 0 52m
Теперь, когда у нас есть 2 стручка, нам нужно как-то получить доступ к службе, чтобы мы могли сделать некоторые основные проверки себя, например, чтобы проверить, что вещи работают, как и ожидалось, прежде чем сделать эту услугу, публично доступную через LoadBalancer или Ingress — поэтому мы обнаруживаем его как внутреннее обслуживание на данный момент
$ kubectl expose deployment ngx --port 8080 --target-port 80
с использованием
$ kubectl proxy &
Затем вы можете получить доступ к вашим услугам (надежно, это на самом деле зашифрованный туннель) через
http://localhost:8001/api/v1/namespaces/default/services/ngx:8080/proxy/
детали того, как это работает здесь , но в двух словах вы можете получить доступ к любому внутреннему обслуживанию через
http://localhost:8001/api/v1/namespace/{namespace}/services/{service-name}:{port}/
Так что именно здесь вы замечаете, что одна из контейнеров ведет себя странно, а иногда, похоже, не может подключаться к бэкэнде или просто работает с периодическими и т. Д. (Что-то не так, в основном) и так вы решите, вы хотели бы запустить нгреп
или TCPDUMP
или stroace
Чтобы выяснить, что происходит, но вы также не хотите изменять изображение контейнера … Так что мы можем сделать?
Пока у вас есть доступ к узлу, запущенному экземпляру контейнера, вам повезет — в этом примере мы просто будем использовать локальную установку Docker4Mac, но он работает с любым узлом, работающим докереми.
Узнайте, какой узел запускает хлопотный контейнер с
$ kubectl describe pod ngx-5cb59c856c-cmn8p Name: ngx-5cb59c856c-cmn8p Namespace: default Node: docker-for-desktop/192.168.65.3
и войдите в этот узел; Я изначально пытался редактировать стручок с
$ kubectl edit pod ngx-5cb59c856c-cmn8p
добавить Отладка Контейнер, но сохранение этого конфигурации не удается, так как вы не можете добавлять/удалять контейнеры из стручка:(
Как мы находимся в узле, который запускает контейнер, однако, мы можем создать пользовательский контейнер для отладки (локально) и запустить, что внутри той же пространства имен PID и сети как существующие NGX-5CB59C856C-CMN8P.
Dockerfile может быть что-то вроде этого (бесстыдно скопировано/используется из https://medium.com/@rothgar/how-toCo-debug-a-running-docker-container-from-se-separate-container-983f11740dc6 )
FROM alpine RUN apk update && apk add strace CMD ["strace", "-p", "1"]
бегать
$ docker build -t strace .
И как только контейнер будет построен (на самом деле, вы построете постоянную отладочную контейнер и сделаете, чтобы вы могли начать в любое время от GCR или ECR или где-либо). Вы запускаете его с помощью --привили
(Да, мы не заботимся о безопасности в этом примере, см. Postin Garrison сообщение о том, как сделать это более ограничительным, так что вы можете сделать все вещи и не приходится Бой разрешения).
Прикрепить к PID
и нетто
пространство имен, вам нужно Контейнер ID
или имя, это легко найти с
$ docker ps | grep nginx 6b6e65ebc7c8 nginx "nginx -g 'daemon of…" About an hour ago Up About an hour k8s\_nginx\_ngx-5cb59c856c-cmn8p\_default\_402e0d53-a933-11e8-93cb-025000000001\_0 e245d91ba045 nginx "nginx -g 'daemon of…" About an hour ago Up About an hour k8s\_nginx\_ngx-5cb59c856c-s65nh\_default\_36a3a1e7-a933-11e8-93cb-025000000001\_0
Итак, мы будем использовать первый, который является 6b6e65ebc7c8.
(Вы должны, очевидно, использовать тот, который вызывает проблемы) …
docker run -ti --pid=container:6b6e65ebc7c8 --net=container:6b6e65ebc7c8 --privileged strace /bin/ash
После выполнения вам нужен PID, который на самом деле выполняет работу, PID 1 на самом деле является процессом родителей Nginx, но это не обрабатывает никаких запросов, это просто управление дочерними процессами
/ # ps -ef PID USER TIME COMMAND 1 root 0:00 nginx: master process nginx -g daemon off; 6 101 0:00 nginx: worker process 44 root 0:00 /bin/ash 50 root 0:00 ps -ef / #
Хорошо, так давайте сделаем stroace
на PID 6, как это на самом деле делает работу …
/ # strace -fp 6 strace: Process 6 attached gettimeofday({tv\_sec=1535294355, tv\_usec=751153}, NULL) = 0 epoll\_wait(8, [{EPOLLIN, {u32=2097902081, u64=139627189727745}}], 512, 61010) = 1 gettimeofday({tv\_sec=1535294359, tv\_usec=908313}, NULL) = 0 recvfrom(3, "GET / HTTP/1.1\r\nHost: localhost:"..., 1024, 0, NULL, NULL) = 213 stat("/usr/share/nginx/html/index.html", {st\_mode=S\_IFREG|0644, st\_size=612, ...}) = 0 open("/usr/share/nginx/html/index.html", O\_RDONLY|O\_NONBLOCK) = 11 fstat(11, {st\_mode=S\_IFREG|0644, st\_size=612, ...}) = 0 writev(3, [{iov\_base="HTTP/1.1 200 OK\r\nServer: nginx/1"..., iov\_len=238}], 1) = 238 sendfile(3, 11, [0] =\> [612], 612) = 612 write(5, "10.1.0.1 - - [26/Aug/2018:14:39:"..., 111) = 111 close(11) = 0 epoll\_wait(8, [{EPOLLIN, {u32=2097902081, u64=139627189727745}}], 512, 65000) = 1 gettimeofday({tv\_sec=1535294361, tv\_usec=971440}, NULL) = 0 recvfrom(3, "GET / HTTP/1.1\r\nHost: localhost:"..., 1024, 0, NULL, NULL) = 213 stat("/usr/share/nginx/html/index.html", {st\_mode=S\_IFREG|0644, st\_size=612, ...}) = 0 open("/usr/share/nginx/html/index.html", O\_RDONLY|O\_NONBLOCK) = 11 fstat(11, {st\_mode=S\_IFREG|0644, st\_size=612, ...}) = 0 writev(3, [{iov\_base="HTTP/1.1 200 OK\r\nServer: nginx/1"..., iov\_len=238}], 1) = 238 sendfile(3, 11, [0] =\> [612], 612) = 612 write(5, "10.1.0.1 - - [26/Aug/2018:14:39:"..., 111) = 111 close(11) = 0 epoll\_wait(8, ^Cstrace: Process 6 detached \
И там есть, 2 запроса на этот конкретный экземпляр Nginx без к
- Перераспределите POD с дополнительным отладочным контейнером (вы можете утверждать, что это будет лучше, но вы не сможете повторно изготавливать проблему сразу и может потребоваться запустить его в течение длительного времени, которые стоит ресурсы)
- Изменяйте DockerFile любым способом (установить инструменты отладки)
- Измените привилегии на беговой контейнере, он может продолжать работать в более безопасной среде против отладочного контейнера, который имеет дополнительные возможности
Приятная вещь об этом шаблоне состоит в том, что вы можете создать себе отладочную контейнер, который вы можете повторно использовать для отладки приложений, работающих на любом узле, который работает Docker (ECS, On-Prom K8S, EKS, AKS, GKE).
Счастливая отладки!
Кредиты и ресурсы:
- https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-services/#manually-constructing-apiserver-proxy-urls
- https://medium.com/@rothgar/how-to-debug-a-running-docker-container-from-a-separate-container-983f11740dc6
- https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0
Оригинал: «https://dev.to/ineedale/access-and-debug-your-kubernetes-service-docker-container-39oh»