Это короткая заметка о том, как упаковать приложение vue.js в Dockerfile, а затем запустить его в контейнере в Kubernetes.
Что он делает Я написал короткометражку программа , который генерирует свободный номер НодПорт .
Собственно, ничего особенно полезного он не делает, но вам не придется беспокоиться о поиске порта, а просто ради интереса посмотреть, как это можно сделать.
Начал Весь проект состоит из двух частей — фронтенда и сервера.
Фронтенд запрашивает у сервера NodePort, а серверная часть использует API Kubernetes, чтобы найти свободный.
На самом деле, чтобы это работало в Docker, вам нужно удалить из приложения некоторые переменные, такие как адрес API Kubernetes, порт, токен и т. д. Это выглядит так:
Допустим, все проверено и наше приложение работает. Создание образа докера Те, кто работал с vue.js, знают, что там куча разных файлов, не знаю, зачем они все нужны, но видимо они нужны.k8s-nodeport-gen/server/index.js: var k8sInfo = { url: process.env.K8SURL, port: process.env.K8SPORT, timeout: process.env.K8STIMEOUT || '30', respath: process.env.RESSPATH || '/api/v1/services', token: process.env.K8STOKEN, nodePortStart: process.env.K8SPORTSTART || '30000', nodePortEnd: process.env.K8SPORTEND || '32000' } app.listen(process.env.PORT || 8081)
Но благодаря тому, что есть такая штука как vue-cli, упаковать все можно довольно просто.
Теперь все упакуем: npm run build
После этого у нас появится папка «dist» и файл «index.html» в «k8s-nodeport-gen/client».
А для работы нам нужны только они.
То есть по идее для работы фронтенда нужен какой-то http-сервер.
Но в этом случае есть еще и бэкенд, который тоже должен работать.
Поэтому в моем случае node.js express будет работать как http-сервер.
Позже файлы будут расположены в папке k8s-nodeport-gen/public. Для этого добавьте опцию в server/index.js. app.use(express.static(__dirname + '/public'))
Теперь, когда вы разобрались с файлами, вы можете создать Dockerfile. Нам нужно только создать файлы для папки «dist» во внешнем интерфейсе.
Для этого воспользуемся такой новомодной вещью, как многоэтапная сборка .
FROM node:10-alpine AS base
COPY client /portgen/client
COPY server /portgen/server
WORKDIR /portgen
RUN cd client && npm i && npm run build
FROM node:10-alpine
WORKDIR /portgen
COPY server/index.js /portgen/index.js
COPY server/package.json /portgen/package.json
COPY --from=base /portgen/client/dist .
/public
RUN npm i
CMD ["/usr/local/bin/node", "/portgen/index.js"]
То есть в первом контейнере запускаем «npm run build», а во втором контейнере копируем файлы из «dist» в «public».
В итоге получаем образ размером 95МБ.
Теперь у нас есть образ докера, который я уже загрузил в Hub.docker.com .
Запуск Теперь мы хотим запустить этот образ в Kubernetes, а также нам нужен токен, который сможет видеть через API Kubernetes, какие порты уже используются.
Для этого вам необходимо создать сервисный аккаунт , роль (можно использовать существующую) и привязка ролей (не знаю как правильно перевести).
В моем кластере уже есть роль «представление» кластера.
ceku@ceku1> kubectl describe clusterrole view
Name: view
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate=true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
bindings [] [] [get list watch]
configmaps [] [] [get list watch]
endpoints [] [] [get list watch]
events [] [] [get list watch]
limitranges [] [] [get list watch]
namespaces [] [] [get list watch]
namespaces/status [] [] [get list watch]
persistentvolumeclaims [] [] [get list watch]
pods [] [] [get list watch]
pods/log [] [] [get list watch]
pods/status [] [] [get list watch]
replicationcontrollers [] [] [get list watch]
replicationcontrollers/scale [] [] [get list watch]
replicationcontrollers/status [] [] [get list watch]
resourcequotas [] [] [get list watch]
resourcequotas/status [] [] [get list watch]
serviceaccounts [] [] [get list watch]
services [] [] [get list watch]
daemonsets.apps [] [] [get list watch]
deployments.apps [] [] [get list watch]
deployments.apps/scale [] [] [get list watch]
replicasets.apps [] [] [get list watch]
replicasets.apps/scale [] [] [get list watch]
statefulsets.apps [] [] [get list watch]
horizontalpodautoscalers.autoscaling [] [] [get list watch]
cronjobs.batch [] [] [get list watch]
jobs.batch [] [] [get list watch]
daemonsets.extensions [] [] [get list watch]
deployments.extensions [] [] [get list watch]
deployments.extensions/scale [] [] [get list watch]
ingresses.extensions [] [] [get list watch]
networkpolicies.extensions [] [] [get list watch]
replicasets.extensions [] [] [get list watch]
replicasets.extensions/scale [] [] [get list watch]
replicationcontrollers.extensions/scale [] [] [get list watch]
networkpolicies.networking.k8s.io [] [] [get list watch]
poddisruptionbudgets.policy [] [] [get list watch]
Теперь давайте создадим учетную запись и привязку ролей.
account_portng.yml: apiVersion: v1
kind: ServiceAccount
metadata:
name: portng-service-get
namespace: internal
labels:
k8s-app: portng-service-get
kubernetes.io/cluster-service: "true"
рольbindng_portng.yml: kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: internal
name: view
labels:
k8s-app: portng-service-get
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
subjects:
- kind: ServiceAccount
name: portng-service-get
namespace: kube-system
apiGroup: ""
roleRef:
kind: ClusterRole
name: view
apiGroup: ""
Теперь у нас есть аккаунт и у него есть токен.
Его название записано в аккаунте: ceku@ceku1 /a/r/aditointernprod.aditosoftware.local> kubectl get serviceaccount portng-service-get -n internal -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2018-08-02T07:31:54Z
labels:
k8s-app: portng-service-get
kubernetes.io/cluster-service: "true"
name: portng-service-get
namespace: internal
resourceVersion: "7270593"
selfLink: /api/v1/namespaces/internal/serviceaccounts/portng-service-get
uid: 2153dfa0-9626-11e8-aaa3-ac1f6b664c1c
secrets:
- name: portng-service-get-token-vr5bj
Теперь вам просто нужно написать Deploy, Service, Ingress для страницы.
Давайте начнем:
развертывание_portng.yml apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/v1beta1
kind: Deployment
metadata:
namespace: internal
name: portng.server.local
spec:
replicas: 1
template:
metadata:
labels:
app: portng.server.local
spec:
serviceAccountName: portng-service-get
containers:
- name: portgen
image: de1m/k8s-nodeport-gen
env:
- name: K8SURL
value: ceku.server.local
- name: K8SPORT
value: '6443'
- name: K8STIMEOUT
value: '30'
- name: RESSPATH
value: '/api/v1/services'
- name: K8SPORTSTART
value: '30000'
- name: K8SPORTEND
value: '32000'
- name: PORT
value: '8080'
args:
- /bin/sh
- -c
- export K8STOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) && node /portgen/index.js
Здесь нужно обратить внимание на две вещи, это «serviceAccountName:portng-service-get» и токен для kubernetes, точнее то, как я его добавил.
Теперь напишем сервис:
svc_portng.yml apiVersion: v1
kind: Service
metadata:
name: portng-server-local
namespace: internal
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: portng.server.local
И вход, он у вас должен быть установлен входной контроллер
входной_портнг.
yaml: apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: portng.aditosoftware.local
namespace: internal
annotations:
kubernetes.io/ingress.class: "internal"
spec:
rules:
- host: portng.server.local
http:
paths:
- path: /
backend:
serviceName: portng-server-local
servicePort: 8080
Всё, осталось только загрузить файлы на сервер и запустить его.
Все это можно запускать как Docker-контейнер или даже без него, но часть с учетными записями в kubernetes все равно придется дорабатывать.
Ресурсы:
Докер-образ на сайтеhub.docker.com. Git-репозиторий на github.com Как видите, ничего особенного в этой статье нет, но кому-то, думаю, будет интересно.Теги: #docker #DevOps #vuejs2 #kubernets
-
Если Вам Еще Не Хватило. Microsoft И Yahoo.
19 Oct, 24 -
Amazon Купил «Книжную» Соцсеть
19 Oct, 24 -
Что Такое Службы .Net Ria?
19 Oct, 24