Nginx
March 26, 2023

Deployment with nginx

В данной статье рассмотрим примеры создания deployment с контейнером nginx.

Deployment с двумя подами и ресурсами.

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cameda-nginx
  namespace: default
  labels:
    app: nginx
    environment: prod
  annotations:
    author: cameda
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy: 
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports: 
        - name: http
          containerPort: 80
        resources: 
          requests: 
            cpu: 300m
            memory: 300Mi 
          limits: 
            memory: 400Mi
      restartPolicy: Always
      hostname: nginx
      subdomain: web
      dnsPolicy: ClusterFirst
      terminationGracePeriodSeconds: 90
EOF

Deployment с двумя подами, ресурсами, pv emptyDir, probe.

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cameda-nginx
  namespace: default
  labels:
    app: nginx
    environment: prod
  annotations:
    author: cameda
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy: 
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports: 
        - containerPort: 80
        - containerPort: 443  
        resources: 
          requests: 
            cpu: 300m
            memory: 300Mi 
          limits: 
            memory: 400Mi
        livenessProbe:
          failureThreshold: 10
          successThreshold: 1
          httpGet:
            path: /
            port: 80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 5
        readinessProbe:
          failureThreshold: 3
          successThreshold: 1
          exec:
            command:
            - curl
            - http://127.0.0.1:80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 7
        volumeMounts:
        - name: cam-emptydir
          mountPath: /mnt/emptydir
      restartPolicy: Always
      hostname: nginx
      subdomain: web
      dnsPolicy: ClusterFirst
      terminationGracePeriodSeconds: 90
      securityContext:
        runAsUser: 0
        runAsGroup: 0
        fsGroup: 2000
      volumes:
      - name: cam-emptydir
        emptyDir: {}
EOF

Deployment с двумя подами, ресурсами, pv emptyDir, probe, tolerations, podAffinity, secret, configmap, priorityclass.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata: 
  name: cam-secret
type: Opaque
data: 
  username: Y2FtZWRh 
  password: Z29vZFBhJCR3b3Jk
EOF
cat <<EOF | kubectl apply -f -
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: cam-pc
  namespace: default
  labels:
    pc: main
  annotations:
    author: cameda
value: 20
globalDefault: false
description: "Cameda first pc"
EOF

Файл /etc/nginx/site-available/default

server {
  listen 80 default_server;
  server_name cameda.ru;
  root /var/www/html/cameda1.ml;
  access_log off;

  location / {
    index.html;
  }
###########################################################################
  location ~ /\.ht {
    deny all;
  }
}

Создадим ConfigMap из этого файла.

kubectl create cm nginx-config --from-file /etc/nginx/site-available/default
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cameda-nginx
  namespace: default
  labels:
    app: nginx
    environment: prod
  annotations:
    author: cameda
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy: 
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx 
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports: 
        - containerPort: 80
        - containerPort: 443  
        resources: 
          requests: 
            cpu: 300m
            memory: 300Mi 
          limits: 
            memory: 400Mi
        livenessProbe:
          failureThreshold: 10
          successThreshold: 1
          httpGet:
            path: /
            port: 80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 5
        readinessProbe:
          failureThreshold: 3
          successThreshold: 1
          exec:
            command:
            - curl
            - http://127.0.0.1:80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 7
        volumeMounts:
        - name: cam-emptydir
          mountPath: /mnt/emptydir
        - name: nginx-secret
          mountPath: /etc/secret
          readOnly: true
        - name: nginx-configmap
          mountPath: /etc/nginx/sites-available
          readOnly: true
      restartPolicy: Always
      priorityClassName: cam-pc
      dnsPolicy: ClusterFirst
      hostname: nginx
      subdomain: web
      serviceAccountName: default
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 90
      securityContext:
        runAsUser: 0
        runAsGroup: 0
        fsGroup: 2000
      tolerations:
      - key: "cam"
        operator: "Exists"
        effect: "NoSchedule"
      - key: "cam"
        operator: "Exists"
        effect: "NoExecute"
      volumes:
      - name: cam-emptydir
        emptyDir: {}
      - name: nginx-secret
        secret:
          secretName: cam-secret
      - name: nginx-configmap
        configMap:
          name: nginx-config

Все поды попадают на одну ноду.

kubectl get po -owide
NAME                            READY   STATUS    RESTARTS     AGE    IP            NODE                        NOMINATED NODE   READINESS GATES
cameda-nginx                    1/1     Running   0            2d5h   10.11.0.222   cl14iev9l04rfqleuqa5-iguw   <none>           <none>
cameda-nginx-699869ddbd-4jcdc   1/1     Running   0            11m    10.11.0.1     cl14iev9l04rfqleuqa5-iguw   <none>           <none>
cameda-nginx-699869ddbd-5hntm   1/1     Running   0            11m    10.11.0.158   cl14iev9l04rfqleuqa5-iguw   <none>           <none>

With podAntiAffinity

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cameda-nginx
  namespace: default
  labels:
    app: nginx
    environment: prod
  annotations:
    author: cameda
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy: 
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx 
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports: 
        - containerPort: 80
        - containerPort: 443  
        resources: 
          requests: 
            cpu: 300m
            memory: 300Mi 
          limits: 
            memory: 400Mi
        livenessProbe:
          failureThreshold: 10
          successThreshold: 1
          httpGet:
            path: /
            port: 80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 5
        readinessProbe:
          failureThreshold: 3
          successThreshold: 1
          exec:
            command:
            - curl
            - http://127.0.0.1:80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 7
        volumeMounts:
        - name: cam-emptydir
          mountPath: /mnt/emptydir
        - name: nginx-secret
          mountPath: /etc/secret
          readOnly: true
        - name: nginx-configmap
          mountPath: /etc/nginx/sites-available
          readOnly: true
      restartPolicy: Always
      priorityClassName: cam-pc
      dnsPolicy: ClusterFirst
      hostname: nginx
      subdomain: web
      serviceAccountName: default
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 90
      securityContext:
        runAsUser: 0
        runAsGroup: 0
        fsGroup: 2000
      tolerations:
      - key: "cam"
        operator: "Exists"
        effect: "NoSchedule"
      - key: "cam"
        operator: "Exists"
        effect: "NoExecute"
      volumes:
      - name: cam-emptydir
        emptyDir: {}
      - name: nginx-secret
        secret:
          secretName: cam-secret
      - name: nginx-configmap
        configMap:
          name: nginx-config

Все поды попадают на разные ноды.

kubectl get po -owide
NAME                           READY   STATUS    RESTARTS     AGE    IP            NODE                        NOMINATED NODE   READINESS GATES
cameda-nginx                   1/1     Running   0            2d5h   10.11.0.222   cl14iev9l04rfqleuqa5-iguw   <none>           <none>
cameda-nginx-64b5c49d6-jxl78   1/1     Running   0            21s    10.11.3.186   cl1k0lmd1e01fb8jfc48-oliw   <none>           <none>
cameda-nginx-64b5c49d6-zsvj2   1/1     Running   0            21s    10.11.2.56    cl1k0lmd1e01fb8jfc48-iqoq   <none>           <none>

Deployment с двумя подами, ресурсами, pv emptyDir, hostPath, probe, tolerations, podAffinity.

При использовании PV с типом hostPath надо убедиться в том, что на ноде есть директория которая монтируется в под.

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cameda-nginx
  namespace: default
  labels:
    app: nginx
    environment: prod
  annotations:
    author: cameda
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy: 
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx 
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports: 
        - containerPort: 80
        - containerPort: 443  
        resources: 
          requests: 
            cpu: 300m
            memory: 300Mi 
          limits: 
            memory: 400Mi
        livenessProbe:
          failureThreshold: 10
          successThreshold: 1
          httpGet:
            path: /
            port: 80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 5
        readinessProbe:
          failureThreshold: 3
          successThreshold: 1
          exec:
            command:
            - curl
            - http://127.0.0.1:80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 7
        volumeMounts:
        - name: cam-emptydir
          mountPath: /mnt/emptydir
        - name: cam-hostpath
          mountPath: /mnt/hostpath
      restartPolicy: Always
      dnsPolicy: ClusterFirst
      hostname: nginx
      subdomain: web
      serviceAccountName: default
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 90
      securityContext:
        runAsUser: 0
        runAsGroup: 0
        fsGroup: 2000
      tolerations:
      - key: "cam"
        operator: "Exists"
        effect: "NoSchedule"
      - key: "cam"
        operator: "Exists"
        effect: "NoExecute"
      volumes:
      - name: cam-emptydir
        emptyDir: {}
      - name: cam-hostpath
        hostPath: 
          path: /mnt/cam
          type: Directory
EOF

Deployment с двумя подами, ресурсами, pv emptyDir, hostPath, probe, tolerations, podAntiAffinity.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cameda-nginx
  namespace: default
  labels:
    app: nginx
    environment: prod
  annotations:
    author: cameda
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  strategy: 
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx 
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports: 
        - containerPort: 80
        - containerPort: 443  
        resources: 
          requests: 
            cpu: 300m
            memory: 300Mi 
          limits: 
            memory: 400Mi
        livenessProbe:
          failureThreshold: 10
          successThreshold: 1
          httpGet:
            path: /
            port: 80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 5
        readinessProbe:
          failureThreshold: 3
          successThreshold: 1
          exec:
            command:
            - curl
            - http://127.0.0.1:80
          periodSeconds: 10
          timeoutSeconds: 1
          initialDelaySeconds: 7
        volumeMounts:
        - name: cam-emptydir
          mountPath: /mnt/emptydir
        - name: cam-hostpath
          mountPath: /mnt/hostpath
      restartPolicy: Always
      dnsPolicy: ClusterFirst
      hostname: nginx
      subdomain: web
      serviceAccountName: default
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 90
      securityContext:
        runAsUser: 0
        runAsGroup: 0
        fsGroup: 2000
      tolerations:
      - key: "cam"
        operator: "Exists"
        effect: "NoSchedule"
      - key: "cam"
        operator: "Exists"
        effect: "NoExecute"
      volumes:
      - name: cam-emptydir
        emptyDir: {}
      - name: cam-hostpath
        hostPath: 
          path: /mnt/cam
          type: Directory

PS. Если при копировании и вставки манифеста "как есть" возникает ошибка, то копируем манифест в файл и убираем первую и последнюю строчки. Где указан EOF.