essh@kubernetes-master:~/node-cluster$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.7.240.1 none> 443/TCP 6h58m
terraform-nodejs LoadBalancer 10.7.246.234 35.197.220.103 80:32085/TCP 5m27s
esschtolts@gke-node-ks-node-ks-pool-07115c5b-bw15 ~ $ curl 10.7.246.234
terraform-nodejs-6bd565dc6c-mm7lh
esschtolts@gke-node-ks-node-ks-pool-07115c5b-bw15 ~ $ curl 10.7.246.234
terraform-nodejs-6bd565dc6c-mm7lh
esschtolts@gke-node-ks-node-ks-pool-07115c5b-bw15 ~ $ curl 10.7.246.234
terraform-nodejs-6bd565dc6c-hr5vg
esschtolts@gke-node-ks-node-ks-pool-07115c5b-bw15 ~ $ curl 10.7.246.234
terraform-nodejs-6bd565dc6c-hr5vg
esschtolts@gke-node-ks-node-ks-pool-07115c5b-bw15 ~ $ curl 10.7.246.234
terraform-nodejs-6bd565dc6c-8768b
esschtolts@gke-node-ks-node-ks-pool-07115c5b-bw15 ~ $ curl 10.7.246.234
terraform-nodejs-6bd565dc6c-mm7lh
essh@kubernetes-master:~/node-cluster$ curl 35.197.220.103
terraform-nodejs-6bd565dc6c-mm7lh
essh@kubernetes-master:~/node-cluster$ curl 35.197.220.103
terraform-nodejs-6bd565dc6c-mm7lh
essh@kubernetes-master:~/node-cluster$ curl 35.197.220.103
terraform-nodejs-6bd565dc6c-8768b
essh@kubernetes-master:~/node-cluster$ curl 35.197.220.103
terraform-nodejs-6bd565dc6c-hr5vg
essh@kubernetes-master:~/node-cluster$ curl 35.197.220.103
terraform-nodejs-6bd565dc6c-8768b
essh@kubernetes-master:~/node-cluster$ curl 35.197.220.103
terraform-nodejs-6bd565dc6c-mm7lh
Теперь перейдем к внедрению сервера NodeJS:
essh@kubernetes-master:~/node-cluster$ sudo ./terraform destroy
essh@kubernetes-master:~/node-cluster$ sudo ./terraform apply
essh@kubernetes-master:~/node-cluster$ sudo docker run -it –rm node:12 which node
/usr/local/bin/node
sudo docker run -it –rm -p 8222:80 node:12 /bin/bash -c 'cd /usr/src/ && git clone https://github.com/fhinkel/nodejs-hello-world.git &&
/usr/local/bin/node /usr/src/nodejs-hello-world/index.js'
firefox http://localhost:8222
Заменим блок у нашего контейнера на:
container {
image = "node:12"
name = "node-js"
command = ["/bin/bash"]
args = [
"-c",
"cd /usr/src/ && git clone https://github.com/fhinkel/nodejs-hello-world.git && /usr/local/bin/node /usr/src/nodejs-hello-world/index.js"
]
}
Если закомментировать модуль Kubernetes, а в кэше он остаётся, остаётся убрать из кэша лишнее:
essh@kubernetes-master:~/node-cluster$ ./terraform apply
Error: Provider configuration not present
essh@kubernetes-master:~/node-cluster$ ./terraform state list
data.google_client_config.default
module.Kubernetes.google_container_cluster.node-ks
module.Kubernetes.google_container_node_pool.node-ks-pool
module.nodejs.kubernetes_deployment.nodejs
module.nodejs.kubernetes_service.nodejs
essh@kubernetes-master:~/node-cluster$ ./terraform state rm module.nodejs.kubernetes_deployment.nodejs
Removed module.nodejs.kubernetes_deployment.nodejs
Successfully removed 1 resource instance(s).
essh@kubernetes-master:~/node-cluster$ ./terraform state rm module.nodejs.kubernetes_service.nodejs
Removed module.nodejs.kubernetes_service.nodejs
Successfully removed 1 resource instance(s).
essh@kubernetes-master:~/node-cluster$ ./terraform apply
module.Kubernetes.google_container_cluster.node-ks: Refreshing state… [id=node-ks]
module.Kubernetes.google_container_node_pool.node-ks-pool: Refreshing state… [id=europe-west2-a/node-ks/node-ks-pool]
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Надежность и автоматизация кластера на Terraform
В общих черта автоматизация рассмотрена в https://codelabs.developers.google.com/codelabs/cloud-builder-gke-continuous-deploy/index. html #0. Мы остановимся подробнее. Теперь, если мы запустим удаление ./terraform destroy и попытаемся воссоздать инфраструктуру целиком сначала, то у нас появятся ошибки. Ошибки получаются из-за того, что порядок создания сервисов не задан и terraform, по умолчанию, отравляет запросы к API в 10 параллельных потоков, хотя это можно изменить, указав при применении или удаление ключ -parallelism=1. В результате Terraform пытается создать Kubernetes сервисы (Deployment и service) на серверах (node-pull), которых пока ещё нет, та же ситуация и при создании сервиса, которому требуется , проксирующего ещё не созданный Deployment. Указывая Terraform запрашивать API в один поток ./terraform apply -parallelism=1 мы снижаем возможные ограничения со стороны провайдера на частоту обращений к API, но не решаем проблему отсутствия порядка создания сущностей. Мы не будем комментировать зависимые блоки и постепенно раскомментировать и запускать ./terraform apply, также не будем запускать по частям нашу систему, указывая конкретные блоки ./terraform apply -target=module.nodejs.kubernetes_deployment.nodejs. Мы укажем в коде сами зависимости на инициализации переменной, первая из которой уже определена как внешняя var.endpoint, а вторую мы создадим локально:
locals {
app = kubernetes_deployment.nodejs.metadata.0.labels.app
}
Теперь мы можем добавить зависимости в код depends_on = [var.endpoint] и depends_on = [kubernetes_deployment .nodejs].
Таже может появляться ошибка недоступности сервиса: Error: Get https://35.197.228.3/API/v1…: dial tcp 35.197.228.3:443: connect: connection refused, то скорее превышено время подключения, которое составляет по умолчанию 6 минут (3600 секунд), но тут можно просто попробовать еще раз.
Теперь перейдём к решению проблемы надёжности работы контейнера, основной процесс которого мы запускаем в командной оболочке. Первое, что мы сделаем, отделим создание приложения от запуска контейнера. Для этого нужно весь процесс создания сервиса перенести в процесс создания образа, которых можно протестировать, и по которому можно создать контейнер сервиса. Итак, создадим образ:
essh@kubernetes-master:~/node-cluster$ cat app/server.js
const http = require('http');
const server = http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end(`Nodejs_cluster is working! My host is ${process.env.HOSTNAME}`);
});
server.listen(80);
essh@kubernetes-master:~/node-cluster$ cat Dockerfile
Читать дальше