Una pequeña nota sobre el tema de ejecutar vue.js en el clúster de kubernetes

imagen
Esta es una breve nota sobre cómo empacar la aplicación vue.js en Dockerfile y luego ejecutarla en un contenedor en kubernetes'e.


Que hace


Escribí un pequeño programa que genera un número gratuito de NodePort . En realidad, ella no hace nada particularmente útil, pero no tiene que acelerar con la búsqueda de un puerto, y por diversión, vea cómo se puede hacer esto.


Empezado


Todo el proyecto consta de dos partes: interfaz y servidor. El front-end le pregunta a nodePort del servidor, y el lado del servidor encuentra algunos gratis a través de la API de Kubernetes.
En realidad, para que esto funcione en la ventana acoplable, debe extraer algunas variables de la aplicación, como la dirección kubernetes api, puerto, token, etc.
Se ve así:


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) 

Digamos que todo está probado y nuestra aplicación funciona.


Crear una imagen acoplable


Aquellos que trabajaron con vue.js saben que hay muchos tipos de archivos, para los cuales todos son necesarios, no lo sé, pero necesitan ser vistos. Pero gracias al hecho de que existe algo como vue-cli, todo puede ser simplemente empaquetado. Ahora empacamos todo:


 npm run build 

Después de eso, tendremos la carpeta "dist" y el archivo "index.html" en "k8s-nodeport-gen / client". Y para el trabajo solo los necesitamos. Es decir, en teoría, para que la interfaz funcione, necesita algún tipo de servidor http. Pero en este caso, también hay un backend, que también debería funcionar. Por lo tanto, en mi caso, como servidor http, node.js express funcionará.
Los archivos se ubicarán más tarde en la carpeta k8s-nodeport-gen / public. Para hacer esto, agregue la opción a server / index.js


 app.use(express.static(__dirname + '/public')) 

Ahora que tiene los archivos analizados, puede crear un Dockerfile. Nosotros, desde la interfaz, solo necesitamos crear archivos para la carpeta "dist". Para hacer esto, usaremos algo tan novedoso como la construcción en varias etapas .


 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"] 

Es decir, en el primer contenedor, ejecute "npm run build", y en el segundo contenedor, copie los archivos de "dist" a "public". Al final, obtenemos una imagen de 95mb.
Ahora tenemos una imagen de docker que he subido a hub.docker.com .


Lanzamiento


Ahora queremos ejecutar esta imagen en kubernetes'e, además, necesitamos un token que pueda ver qué puertos ya están en uso a través de la api de kubernetes.


Para hacer esto, debe crear una cuenta de servidor , un rol (puede usar uno existente) y un rolebinding (no sé cómo traducir correctamente).
Ya tengo un rol de "vista" en el clúster


 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] 

Ahora crea una cuenta y rolebinding
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" 

rolebindng_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: "" 

Ahora tenemos una cuenta y él tiene un token. Su nombre está escrito en la cuenta:


 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 

Ahora solo necesita escribir despliegue, servicio, ingreso para la página. Comencemos:
deploy_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 

Hay dos cosas a las que debe prestar atención: "serviceAccountName: portng-service-get" y el token para kubernetes, o mejor dicho, la forma en que lo agregué.


Ahora escribamos un servicio:
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 

Y entrada, para ello debes tener instalado un controlador de entrada
ingress_portng.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 

Todo, solo queda subir archivos al servidor y ejecutarlos.
Todo esto se puede lanzar como un contenedor acoplable e incluso sin él, pero la parte con cuentas en kubernetes'e aún tendrá que pasar.


Recursos:


Imagen de Docker en hub.docker.com
Repositorio de Git en github.com


Como puede ver, no hay nada especial en este artículo, pero para algunos creo que será interesante.

Source: https://habr.com/ru/post/es419033/


All Articles