Notas Mentales de Un SysAdmin

blog sobre tecnologías para sysadmin y devops

Month: diciembre 2020

Buenas prácticas: ¿Email o chat?

Estás a punto de enviar un mensaje para actualizar a su compañera de trabajo sobre su último proyecto. ¿Escribes un correo electrónico o le escribes a Hangouts?

Tradicionalmente, los mejores casos para usar el correo electrónico son cuando:

  • El contenido es demasiado largo para enviar mensajes.
  • El mensaje es información pesada.
  • El mensaje requiere formalidad.
  • Es la primera vez que contactas a alguien

Los mejores casos para usar el chat son cuando:

  • Debe ser rápido y oportuno
  • El mensaje es conciso.
  • Es un diálogo con múltiples personas
  • La discusión debe ser más informal.

Árbol de decisión

Por qué

Oportunidad

El correo electrónico es asíncrono, lo que significa que un correo electrónico que envía a su compañero de trabajo no es en tiempo real como
lo es la mensajería. Esta es una diferencia clave para el razonamiento detrás del uso de uno versus el otro. La mensajería es instantánea, por lo
que sería más rápido que el correo electrónico cuando se trata de enviar información a alguien.
Según un estudio sobre el uso de mensajes por parte de IBM, la razón principal por la cual las personas eligen usar mensajes en cualquier otro
medio en un momento dado es porque permite una «respuesta rápida» y «respuestas rápidas y cortas».

Longitud

Originalmente, el chat estaba destinado a ser breve, mientras que el correo electrónico podía manejar mensajes más voluminosos y con mucho
contenido. Esto es una ventaja cuando se trata de mensajes porque significa que puedes ser más informal y rápido con lo que tienes que decir.
Pedir a los compañeros de trabajo que almuercen contigo se comunica mejor a través de mensajes, mientras que dar a alguien detalles largos
sobre un informe sería mejor por correo electrónico.

Diálogo

Tanto el correo electrónico como la mensajería se usan para el diálogo, pero el correo electrónico de ida y vuelta es muy diferente a la
mensajería. El chat es mejor si la conversación continuará durante más de unas pocas oraciones. El chat también refleja el cara a cara
más que el correo electrónico, lo que también es una razón para usar uno sobre el otro cuando se trata de largas conversaciones en línea.
Según un estudio de The Radicati Group, «el uso comercial de mensajería instantánea está creciendo a un ritmo mucho más rápido que el uso
de mensajería instantánea por parte de los consumidores». El estudio analiza todo tipo de mensajes, incluidos mensajes instantáneos,
mensajería instantánea pública, mensajería instantánea empresarial y mensajería móvil. El crecimiento de la mensajería muestra que el correo
electrónico no es la única forma de enviar un mensaje en el trabajo.


Problema resuelto!

Chuleta de YAML para Kubernetes en GCP

Nunca viene mal una chuleta cuando se trabaja con Kubernetes. En este caso, es una chuleta especial para el entono de GKE en la plataforma de GCP. En este caso, son el tipo de cargas de trabajo, servicios, etc. que más suelo usar en mi día a día. Espero que os sean de utilidad.

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: name-deployment
  namespace: dev
  labels:
    app: app-name
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-name
  template:
    metadata:
      labels:
        app: app-name
    spec:
      containers:
      - name: container-name
        image: container-image:tag
        ports:
          - containerPort: 1234
        envFrom:
          - configMapRef:
              name: configmap-name
          - secretRef:
              name: secret-name
        volumeMounts:
          - name: name-vol
            mountPath: /unix/source/route/map
      volumes:
        - name: name-vol
          persistentVolumeClaim:
            claimName: name-pvc

StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: name-statefulset
  namespace: dev
  labels:
    app: app-name
spec:
  serviceName: app-service-name"
  replicas: 1
  selector:
    matchLabels:
      app: app-name
  template:
    metadata:
      labels:
        app: app-name
    spec:
      containers:
        - name: container-name
          image: container-image:tag
          ports:
            - containerPort: 1234
              name: port-name
          resources:
            limits:
              memory: "2000Mi"
            requests:
              memory: "300Mi"
          envFrom:
          - configMapRef:
              name: configmap-name
          - secretRef:
              name: secret-name
        volumeMounts:
          - name: name-vol
            mountPath: /unix/source/route/map
      volumes:
        - name: name-vol
          persistentVolumeClaim:
            claimName: name-pvc

Cronjob

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: name-cronjob
  namespace: dev
spec:
  schedule: "01 0 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: container-name
              image: container-image:tag
              args:
                - /bin/sh
                - -c
                - sh /scripts/script.sh
          restartPolicy: Never

PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: name-pvc
  namespace: dev
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 25Gi

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: genportal-integration-config
  namespace: dev
data:
  #Comments
  VAR_NAME: "value"

Secrets

apiVersion: v1
kind: Secret
metadata:
  name: name-secret
  namespace: dev
type: Opaque
data:
  VAR_NAME: "password_in_base_64"

Service

apiVersion: v1
kind: Service
metadata:
  name: name-service
  labels:
    app: app-name
  namespace: dev
spec:
  ports:
    - port: 1234
      protocol: TCP
      targetPort: 1234
  selector:
    app: app-name
  sessionAffinity: None
  type: LoadBalancer / ClusterIP / NodePort
status:
  loadBalancer: {}

Tipos de servicio en función de su comportamiento:

  • ClusterIP: expone el servicio en una IP interna del clúster. Elegir este valor hace que el Servicio solo sea accesible desde dentro del clúster. Este es el ServiceType predeterminado.
  • NodePort: expone el servicio en la IP de cada nodo en un puerto estático (el NodePort). Se crea automáticamente un servicio ClusterIP, al que se enruta el servicio NodePort. Podrá ponerse en contacto con el servicio NodePort, desde fuera del clúster, solicitando <NodeIP>: <NodePort>.
  • LoadBalancer: expone el servicio de forma externa mediante el equilibrador de carga de un proveedor de nube. Los servicios NodePort y ClusterIP, a los que se enruta el equilibrador de carga externo, se crean automáticamente.

Problema resuelto!

Chuleta de PSQL

Aunque te hayas pegado a menudo con una base de datos postgresql, normalmente, se tocan de uvas a peras. Es difícil acordarse de todo, y por ello, hoy os dejo mi chuleta personal cuando no me acuerdo de algo.

Ficheros de configuración

/var/lib/postgresql/11/main'		# use data in another directory
/etc/postgresql/11/main/postgresql.conf' #default conf file
/etc/postgresql/11/main/pg_hba.conf'	# host-based authentication file

Conectarse desde cliente psql

Para hacer login en la BD postgres, utilizaremos la siguiente sintaxis:

psql -h [HOST] -U [user] [BD]

Ejemplo:

psql -h localhost -U user_name db_name

Visualizar ROLES

\du

Resultado:

                                Lista de roles
  Nombre de rol  |                   Atributos                    | Miembro de
-----------------+------------------------------------------------+------------
 postgres        | Superusuario, Crear rol, Crear BD, Replicación | {}
 xxxxxxxxx       | Superusuario                                   | {}
 yyyyyyyyyyy     |                                                | {}

Crear un GRUPO

CREATE ROLE nombre [ [ WITH ] opción [ ... ] ]

Donde opción puede ser:

  SUPERUSER | NOSUPERUSER
| CREATEDB | NOCREATEDB
| CREATEROLE | NOCREATEROLE
| CREATEUSER | NOCREATEUSER
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| REPLICATION | NOREPLICATION
| CONNECTION LIMIT límite_conexiones
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'contraseña'
| VALID UNTIL 'fecha_hora'
| IN ROLE nombre_de_rol [, ...]
| IN GROUP nombre_de_rol [, ...]
| ROLE nombre_de_rol [, ...]
| ADMIN nombre_de_rol [, ...]
| USER nombre_de_rol [, ...]
| SYSID uid

Ejemplo:

CREATE GROUP dev WITH LOGIN NOCREATEDB NOSUPERUSER NOCREATEROLE;

Dar permisos de conexión sobre una BD

GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
    ON DATABASE database_name [, ...]
    TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

Para más info de GRANT sobre postgres, visitar:
Postgres GRANT

Ejemplo:

GRANT CONNECT ON DATABASE tellmegen TO dev;

Mostrar todos los SCHEMA disponibles

select schema_name from information_schema.schemata;

Resultado:

    schema_name
--------------------
 isisaudit
 isiscommand
 isissecurity
 isissessionlogger
 pg_toast
 pg_temp_1
 pg_toast_temp_1
 pg_catalog
 information_schema
 public

Dar permisos de SELECT, INSERT… sobre SCHEMA

GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [,...] | ALL [ PRIVILEGES ] }
    ON { [ TABLE ] table_name [, ...]
         | ALL TABLES IN SCHEMA schema_name [, ...] }
    TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

Ejemplo:1

GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO dev;

Crear usuario y agregarlo a grupo

Utilizaremos la misma sintaxis que para crear un grupo. Ejemplo:

CREATE ROLE user_name WITH LOGIN NOCREATEDB NOSUPERUSER NOCREATEROLE CONNECTION LIMIT 1 PASSWORD 'password' IN GROUP dev;

Es interesante establecer CONNECTION LIMIT 1, para evitar suplantación de identidad del usuario

Cambiar de grupo al usuario

Eliminar usuario del grupo:

REVOKE user_name FROM group_name;

Modificar el fichero de conexión pg_hba.conf

Para permitir el acceso del usuario, hay que modificar el fichero pg_hba.conf. Esta configuración no funciona para usuarios, así que para permitir el acceso, habrá que añadir a cada usuario de manera individual.

/var/lib/pgsql/9.3/data/pg_hba.conf

o o para postgres11:

/etc/postgresql/11/main/pg_hba.conf

La sintaxis del fichero debe de llevar alguna de las siguientes formas:

# local      DATABASE  USER  METHOD  [OPTIONS]
# host       DATABASE  USER  ADDRESS  METHOD  [OPTIONS]
# hostssl    DATABASE  USER  ADDRESS  METHOD  [OPTIONS]
# hostnossl  DATABASE  USER  ADDRESS  METHOD  [OPTIONS]

Ejemplo para login local:

local database_name user_name peer

Ejemplo para login remoto / pgadmin:

host database_name user_name ip/32 trust

Reiniciar siempre el servicio de postgres para aplicar cambios:

service postgresql-9.3.service restart

Problema resuelto!

Scroll hacia arriba