
Ceci est une courte note sur la façon de compresser l'application vue.js dans Dockerfile, puis de l'exécuter dans un conteneur dans kubernetes'e.
Qu'est-ce que
J'ai écrit un petit programme qui génère un numéro NodePort gratuit. En fait, elle ne fait rien de particulièrement utile, mais vous n'avez pas à vous lancer dans la recherche d'un port, et donc pour le plaisir, voyez comment cela peut être fait.
Commencé
L'ensemble du projet se compose de deux parties - frontend et serveur. Le front-end demande à nodePort du serveur, et le côté serveur en trouve gratuitement via l'API kubernetes.
En fait, pour que cela fonctionne dans le docker, vous devez extraire certaines variables de l'application, telles que l'adresse kubernetes api, le port, le jeton, etc.
Cela ressemble à ceci:
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)
Disons que tout est testé et que notre application fonctionne.
Créer une image docker
Ceux qui ont travaillé avec vue.js savent qu'il y a beaucoup de fichiers de toutes sortes, pour lesquels ils sont tous nécessaires, je ne sais pas, mais ils doivent être vus. Mais grâce au fait qu'il existe une chose telle que vue-cli, tout peut être tout simplement emballé. Maintenant, nous emballons tout:
npm run build
Après cela, nous aurons le dossier "dist" et le fichier "index.html" dans "k8s-nodeport-gen / client". Et pour le travail, nous n'avons besoin que d'eux. Autrement dit, pour que le frontend fonctionne, vous avez besoin d'une sorte de serveur http. Mais dans ce cas, il y a aussi un backend, qui devrait également fonctionner. Par conséquent, dans mon cas, en tant que serveur http, node.js express fonctionnera.
Les fichiers se trouveront plus tard dans le dossier k8s-nodeport-gen / public. Pour ce faire, ajoutez l'option à server / index.js
app.use(express.static(__dirname + '/public'))
Maintenant que les fichiers sont analysés, vous pouvez créer un Dockerfile. Nous avons seulement besoin de créer des fichiers pour le dossier "dist". Pour ce faire, nous utiliserons une chose aussi nouvelle que la construction à plusieurs étages .
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
Autrement dit, dans le premier conteneur, exécutez "npm run build" et dans le deuxième conteneur, copiez les fichiers de "dist" vers "public". À la fin, nous obtenons une image de 95 Mo.
Nous avons maintenant une image docker que j'ai téléchargée sur hub.docker.com .
Lancement
Maintenant, nous voulons exécuter cette image dans kubernetes'e, en plus, nous avons besoin d'un jeton qui peut voir quels ports sont déjà utilisés via kubernetes api.
Pour ce faire, vous devez créer un compte serveur , un rôle (vous pouvez en utiliser un déjà existant) et la liaison de rôles (je ne sais pas comment traduire correctement).
J'ai déjà un rôle de cluster "voir" dans le cluster
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]
Créez maintenant un compte et une liaison de rôle
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: ""
Maintenant, nous avons un compte et il a un jeton. Son nom est inscrit dans le compte:
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
Il vous suffit maintenant d'écrire deploy, service, ingress pour la page. Commençons:
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
Il y a deux choses à faire attention: "serviceAccountName: portng-service-get" et le jeton pour kubernetes, ou plutôt, la façon dont je l'ai ajouté.
Écrivons maintenant un service:
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
Et l'entrée, pour cela, vous devez avoir un contrôleur d'entrée installé
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
Tout, il ne reste plus qu'à télécharger des fichiers sur le serveur et à exécuter.
Tout cela peut être lancé à la fois en tant que conteneur docker et même sans lui, mais la partie avec les comptes dans kubernetes'e devra encore passer.
Ressources:
Image Docker sur hub.docker.com
Dépôt Git sur github.com
Comme vous pouvez le voir, il n'y a rien de spécial dans cet article, mais pour certains, je pense que ce sera intéressant.