Thank you for reading this post, don't forget to subscribe!
1.POD
2.REPLICASET
3.DEPLOYMENT
4.readinessProbe и livenessProbe
5.LIMITS
6.SERVICE
7.INGRESS
8.CONFIGMAP
9.Deployment apache
10.log-nfs-server
11. Dynamic NFS provision
12.Nginx apache nfs-dinamic provision
13.Helm
14.Helm практика
15.Autoscaling
16.ci/cd gitlab
Дошли руки до разбора и практического запуска. Имеется установленный миникуб на нём рассмотрим практический запуск от простейщей сущности пода до более сложных
и так для начала запустим pod в котором будет 1 контейнер nginx
Но для начала настроим автозаполнение, чтобы пользоваться табом, для этого выполним:
yum install bash-completion
[root@minikub ~]# kubectl completion -h | grep bash
Output shell completion code for the specified shell (bash or zsh). The shell code must be evaluated to provide interactive completion of kubectl commands. This can be done by sourcing it from the .bash _profile.
# Installing bash completion on macOS using homebrew
brew install bash-completion
brew install bash-completion@2
kubectl completion bash > $(brew --prefix)/etc/bash_completion.d/kubectl
# Installing bash completion on Linux
## If bash-completion is not installed on Linux, please install the 'bash-completion' package
## Load the kubectl completion code for bash into the current shell
source <(kubectl completion bash)
## Write bash completion code to a file and source if from .bash_profile
kubectl completion bash > ~/.kube/completion.bash.inc
source '$HOME/.kube/completion.bash.inc'
" >> $HOME/.bash_profile
source $HOME/.bash_profile
[root@minikub ~]# kubectl completion bash > ~/.kube/completion.bash.inc
[root@minikub ~]# source '/root/.kube/completion.bash.inc'
[root@minikub ~]# cat pod.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 |
--- apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - image: nginx:1.12 name: nginx ports: - containerPort: 80 |
[/codesyntax]
[root@minikub ~]# kubectl create -f pod.yaml
1 2 3 |
[root@minikub ~]# <strong>kubectl get pod</strong> NAME READY STATUS RESTARTS AGE my-pod 1/1 Running 0 69s |
======================================
теперь запустим несколько контейнеров через replicaset
[root@minikub ~]# cat replicaset.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
--- apiVersion: apps/v1 kind: ReplicaSet metadata: name: my-replicaset spec: replicas: 3 selector: matchLabels: app: my-app ## тут начинается описание контейнера template: metadata: labels: app: my-app # по вот этому лейблу репликасет цепляет под spec: containers: - image: nginx:1.12 name: nginx ports: - containerPort: 80 |
[/codesyntax]
[root@minikub ~]# kubectl create -f replicaset.yaml
replicaset.apps/my-replicaset created
проверяем, как мы видим replicaset успешно запущена, смотрим поды, есть наш старый под с именем my-pod и 3 пода запущенные репликасетом, с именем my-replicaset-(id)
1 2 3 4 5 6 7 8 9 10 |
[root@minikub ~]# kubectl get rs NAME DESIRED CURRENT READY AGE my-replicaset 3 3 3 14s [root@minikub ~]# kubectl get pod NAME READY STATUS RESTARTS AGE my-pod 1/1 Running 0 24m my-replicaset-26lht 1/1 Running 0 22s my-replicaset-4pvr2 1/1 Running 0 22s my-replicaset-9vwqc 1/1 Running 0 22s |
=========================
теперь запустим деплоймент который дальше всегда и будем использовать
[root@minikub ~]# cat deployment.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
--- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 4 selector: matchLabels: app: my-app # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: my-app # по вот этому лейблу репликасет цепляет под spec: containers: - image: nginx:1.12 name: nginx ports: - containerPort: 80 |
[/codesyntax]
[root@minikub ~]# kubectl create -f deployment.yaml
deployment.apps/my-deployment created
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[root@minikub ~]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE my-deployment 4/4 4 4 27s видим что автоматически создался и репликасет с именем my-deployment [root@minikub ~]# kubectl get replicaset NAME DESIRED CURRENT READY AGE my-deployment-6cb88665b 4 4 4 50s my-replicaset 3 3 3 27m а также поды с именем my-deployment [root@minikub ~]# kubectl get pod NAME READY STATUS RESTARTS AGE my-deployment-6cb88665b-4q79q 1/1 Running 0 59s my-deployment-6cb88665b-74qv4 1/1 Running 0 59s my-deployment-6cb88665b-w2xlm 1/1 Running 0 59s my-deployment-6cb88665b-wslkl 1/1 Running 0 59s my-pod 1/1 Running 0 52m my-replicaset-26lht 1/1 Running 0 27m my-replicaset-4pvr2 1/1 Running 0 27m my-replicaset-9vwqc 1/1 Running 0 27m |
===================================================
Теперь добавим проверки на доступность, а именно readinessProbe и livenessProbe
[root@minikub ~]# cat deployment.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
--- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 4 selector: matchLabels: app: my-app # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: my-app # по вот этому лейблу репликасет цепляет под spec: containers: - image: nginx:1.12 name: nginx ports: - containerPort: 80 # тут начинаются проверки по доступности readinessProbe: # проверка готово ли приложение failureThreshold: 3 #указывает количество провалов при проверке httpGet: # по сути дёргает курлом на 80 порт path: / port: 80 periodSeconds: 10 #как часто должна проходить проверка (в секундах) successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда livenessProbe: #проверка на жизнь приложения, живо ли оно failureThreshold: 3 httpGet: path: / port: 80 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд |
[/codesyntax]
чтобы применить изменения, необходимо выполнить команду:
[root@minikub ~]# kubectl apply -f deployment.yaml
deployment.apps/my-deployment configured
==================================================
Теперь добавим лимиты
Limits - количество ресурсов которые pod может использовать(верхняя граница)
Requies - количество ресурсов которые резервируются для pod на ноде (не делятся с другими подами на ноде)
[root@minikub ~]# cat deployment.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
--- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 5 selector: matchLabels: app: my-app # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: my-app # по вот этому лейблу репликасет цепляет под spec: containers: - image: nginx:1.12 name: nginx ports: - containerPort: 80 # тут начинаются проверки по доступности readinessProbe: # проверка готово ли приложение failureThreshold: 3 #указывает количество провалов при проверке httpGet: # по сути дёргает курлом на 80 порт path: / port: 80 periodSeconds: 10 #как часто должна проходить проверка (в секундах) successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда livenessProbe: #проверка на жизнь приложения, живо ли оно failureThreshold: 3 httpGet: path: / port: 80 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд # тут начинается описание лимитов для пода resources: requests: #количество ресурсов которые резервируются для pod на ноде cpu: 50m memory: 100Mi limits: #количество ресурсов которые pod может использовать(верхняя граница) cpu: 100m memory: 100Mi |
[/codesyntax]
проверяем,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[root@minikub ~]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE my-deployment 5/5 5 5 126m время деплоймента 126 минут, посмотрим время подов, оно изменится потому что поды будут пересозданы из-за изменения лимитов: [root@minikub ~]# kubectl get pod NAME READY STATUS RESTARTS AGE my-deployment-7c88b95897-bcbsw 1/1 Running 0 49s my-deployment-7c88b95897-bxb9b 1/1 Running 0 49s my-deployment-7c88b95897-s72f5 1/1 Running 0 51s my-deployment-7c88b95897-wjlrk 1/1 Running 0 60s my-deployment-7c88b95897-x5bb8 1/1 Running 0 60s my-pod 1/1 Running 0 177m my-replicaset-26lht 1/1 Running 0 153m my-replicaset-4pvr2 1/1 Running 0 153m my-replicaset-9vwqc 1/1 Running 0 153m |
посмотрим по логам что там внутри одного из контейнеров:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[root@minikub ~]# kubectl get pod NAME READY STATUS RESTARTS AGE my-deployment-7c88b95897-bcbsw 1/1 Running 0 6m2s my-deployment-7c88b95897-bxb9b 1/1 Running 0 6m2s my-deployment-7c88b95897-s72f5 1/1 Running 0 6m4s my-deployment-7c88b95897-wjlrk 1/1 Running 0 6m13s my-deployment-7c88b95897-x5bb8 1/1 Running 0 6m13s my-pod 1/1 Running 0 3h2m my-replicaset-26lht 1/1 Running 0 158m my-replicaset-4pvr2 1/1 Running 0 158m my-replicaset-9vwqc 1/1 Running 0 158m как ниже видим, проверки успешно проходят [root@minikub ~]# kubectl logs my-deployment-7c88b95897-bcbsw 172.17.0.1 - - [03/May/2020:09:06:25 +0000] "GET / HTTP/1.1" 200 612 "-" "kube-probe/1.18" "-" 172.17.0.1 - - [03/May/2020:09:06:35 +0000] "GET / HTTP/1.1" 200 612 "-" "kube-probe/1.18" "-" 172.17.0.1 - - [03/May/2020:09:06:42 +0000] "GET / HTTP/1.1" 200 612 "-" "kube-probe/1.18" "-" 172.17.0.1 - - [03/May/2020:09:06:45 +0000] "GET / HTTP/1.1" 200 612 "-" "kube-probe/1.18" "-" |
посмотрим подробное описание пода:
[root@minikub ~]# kubectl describe pod my-deployment-7c88b95897-bcbsw
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
Name: my-deployment-7c88b95897-bcbsw Namespace: default Priority: 0 PriorityClassName: <none> Node: minikub/192.168.1.120 Start Time: Sun, 03 May 2020 15:06:22 +0600 Labels: app=my-app pod-template-hash=7c88b95897 Annotations: <none> Status: Running IP: 172.17.0.16 Controlled By: ReplicaSet/my-deployment-7c88b95897 Containers: nginx: Container ID: docker://1f30faff8bc2f64513eb081837f33eb2103ba7d55013a6bfbf3a5b54f427e5cd Image: nginx:1.12 Image ID: docker-pullable://nginx@sha256:72daaf46f11cc753c4eab981cbf869919bd1fee3d2170a2adeac12400f494728 Port: 80/TCP Host Port: 0/TCP State: Running Started: Sun, 03 May 2020 15:06:23 +0600 Ready: True Restart Count: 0 Limits: cpu: 100m memory: 100Mi Requests: cpu: 50m memory: 100Mi Liveness: http-get http://:80/ delay=10s timeout=1s period=10s #success=1 #failure=3 Readiness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-vqkds (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-vqkds: Type: Secret (a volume populated by a Secret) SecretName: default-token-vqkds Optional: false QoS Class: Burstable Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned default/my-deployment-7c88b95897-bcbsw to minikub Normal Pulled 10m kubelet, minikub Container image "nginx:1.12" already present on machine Normal Created 10m kubelet, minikub Created container nginx Normal Started 10m kubelet, minikub Started container nginx |
[/codesyntax]
===================================================
Теперь опишем service
Сервис по меткам(лейблам) даёт указания, что надо отправлять трафик на pod-ы
[root@minikub ~]# cat service.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
--- apiVersion: v1 kind: Service metadata: name: my-service # имя сервиса spec: ports: - port: 80 # принимать на 80 targetPort: 80 # отправлять на 80 selector: app: my-app #отправлять на все поды с данным лейблом type: ClusterIP |
[/codesyntax]
[root@minikub ~]# kubectl apply -f service.yaml
service/my-service created
проверяем что сервис стартанул:
1 2 3 4 5 6 7 8 9 10 |
[root@minikub ~]# kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 33d my-service ClusterIP 10.96.34.113 <none> 80/TCP 79s смотрим endpoints, т.е. куда my-service будет отправлять запросы [root@minikub ~]# kubectl get endpoints NAME ENDPOINTS AGE kubernetes 192.168.1.120:8443 33d my-service 172.17.0.10:80,172.17.0.11:80,172.17.0.12:80 + 5 more… 3m44s |
ну а чтобы отправить трафик на my-service используется INGRESS
===================================================
INGRESS
Данная сущность необходима чтобы зарулить запросы из интернета в наш кластер. т.е. ингрес берёт информацию из сервиса и минуя его отправляет трафик сразу на поды.
[root@minikub ~]# cat ingress.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
--- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: my-ingress spec: rules: - host: test.ru #тут указывается наш домен http: paths: #список путей которые хотим обслуживать(он дефолтный и все запросы будут отпаврляться на бэкенд, т.е. на сервис my-service) - backend: serviceName: my-service #тут указывается наш сервис на который servicePort: 80 #порт на котором сервис слушает # path: / все запросы на корень '/' будут уходить на наш сервис |
[/codesyntax]
[root@minikub ~]# kubectl apply -f ingress.yml
ingress.extensions/my-ingress created
проверяем:
1 2 3 |
[root@minikub ~]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE my-ingress <none> test.ru 192.168.1.120 80 57s |
видим что ингресс создан и обращения на домен test.ru, на 80 порт, будут уходить на наш сервис my-service, это можем увидеть если посмотрим describe
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[root@minikub ~]# kubectl describe ingress my-ingress Name: my-ingress Namespace: default Address: 192.168.1.120 Default backend: default-http-backend:80 (<none>) Rules: Host Path Backends ---- ---- -------- test.ru my-service:80 (<none>) Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{},"name":"my-ingress","namespace":"default"},"spec":{"rules":[{"host":"test.ru","http":{"paths":[{"backend":{"serviceName":"my-service","servicePort":80}}]}}]}} Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 3m5s nginx-ingress-controller Ingress default/my-ingress Normal UPDATE 2m16s nginx-ingress-controller Ingress default/my-ingress [root@minikub ~]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE my-ingress <none> test.ru 192.168.1.120 80 3m36s |
[/codesyntax]
==================================================
Configmap
Добавим к нашему nginx конфиг файл, который будет проксировать все запросы на наш деплоймент с apache.
[root@minikub my-project]# cat nginx-configmap.conf
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
apiVersion: v1 kind: ConfigMap metadata: name: nginx-conf data: my-app.conf: | server { listen 80; server_name _; location / { proxy_pass http://my-service-apache:80; # А вот сюда пишем название сервиса отвечающего за апач } } |
[/codesyntax]
создаём конфигмап
[root@minikub my-project]# kubectl create -f nginx-configmap.conf
configmap/nginx-conf created
проверяем:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[root@minikub my-project]# kubectl get configmap NAME DATA AGE nginx-conf 1 27s [root@minikub my-project]# kubectl describe configmap nginx-conf Name: nginx-conf Namespace: default Labels: <none> Annotations: <none> Data ==== my-app.conf: ---- server { listen 80; server_name _; location / { proxy_pass http://my-service-apache:80; # А вот сюда пишем название сервиса отвечающего за апач } } Events: <none> |
[/codesyntax]
и поправим деплоймент у nginx чтобы он мог подтащить новый конфигмап
[root@minikub my-project]# cat deployment.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
--- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 1 selector: matchLabels: app: my-app # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: my-app # по вот этому лейблу репликасет цепляет под spec: containers: - image: nginx:1.12 name: nginx ports: - containerPort: 80 # тут начинаются проверки по доступности readinessProbe: # проверка готово ли приложение failureThreshold: 3 #указывает количество провалов при проверке httpGet: # по сути дёргает курлом на 80 порт path: / port: 80 periodSeconds: 10 #как часто должна проходить проверка (в секундах) successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда livenessProbe: #проверка на жизнь приложения, живо ли оно failureThreshold: 3 httpGet: path: / port: 80 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд # тут начинается описание лимитов для пода resources: requests: #количество ресурсов которые резервируются для pod на ноде cpu: 50m memory: 100Mi limits: #количество ресурсов которые pod может использовать(верхняя граница) cpu: 100m memory: 100Mi # тут подключаем ранее созданный конфиг nginx volumeMounts: #должен располагаться под containers - name: nginx-conf #имя нашего конфигмапа, созданного ранее. mountPath: /etc/nginx/conf.d/ # путь по которому мы будем монтировать наш конфиг volumes: #(описывает тома) должен располагаться под spec - name: nginx-conf configMap: name: nginx-conf |
[/codesyntax]
применим новые изменения:
[root@minikub my-project]# kubectl apply -f deployment.yaml
=====================================================
Теперь запустим deployment с apache
[root@minikub my-project]# cat deployment-apache.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
--- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment-apache spec: replicas: 1 selector: matchLabels: app: apache # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: apache # по вот этому лейблу репликасет цепляет под spec: containers: - image: httpd:2.4.43 name: apache ports: - containerPort: 80 # тут начинаются проверки по доступности readinessProbe: # проверка готово ли приложение failureThreshold: 3 #указывает количество провалов при проверке httpGet: # по сути дёргает курлом на 80 порт path: / port: 80 periodSeconds: 10 #как часто должна проходить проверка (в секундах) successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда livenessProbe: #проверка на жизнь приложения, живо ли оно failureThreshold: 3 httpGet: path: / port: 80 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд # тут начинается описание лимитов для пода resources: requests: #количество ресурсов которые резервируются для pod на ноде cpu: 60m memory: 200Mi limits: #количество ресурсов которые pod может использовать(верхняя граница) cpu: 120m memory: 300Mi |
[/codesyntax]
[root@minikub my-project]# kubectl apply -f deployment-apache.yaml
deployment.apps/my-deployment-apache created
а также запустим сервис который будет проксировать всё с nginx на apache
[root@minikub my-project]# cat service-apache.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
--- apiVersion: v1 kind: Service metadata: name: my-service-apache # имя сервиса spec: ports: - port: 80 # принимать на 80 targetPort: 80 # отправлять на 80 selector: app: apache #отправлять на все поды с данным лейблом type: ClusterIP |
[/codesyntax]
my-service-apache - вот на это имя и нужно проксировать запросы с нашего nginx
[root@minikub my-project]# kubectl apply -f service-apache.yaml
service/my-service-apache created
проверяем что всё запущено:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
[root@minikub my-project]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE my-deployment 1/1 1 1 5m25s my-deployment-apache 1/1 1 1 4m6s [root@minikub my-project]# kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 35d my-service ClusterIP 10.100.200.137 <none> 80/TCP 5m4s my-service-apache ClusterIP 10.110.166.198 <none> 80/TCP 3m16s [root@minikub my-project]# kubectl get pod NAME READY STATUS RESTARTS AGE my-deployment-58d476c5c8-mrstm 1/1 Running 5 5m40s my-deployment-apache-859486bd8c-vxnbk 1/1 Running 0 4m21s [root@minikub my-project]# kubectl get configmap NAME DATA AGE nginx-conf 1 12m [root@minikub my-project]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE my-ingress <none> test.ru 192.168.1.120 80 26h |
проверим что запросы действительно долетают до апача.
Смотрим на каком ip висит наш pod с nginx
1 2 3 4 |
[root@minikub my-project]# <strong>kubectl get pod -o wide</strong> NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-deployment-58d476c5c8-mrstm 1/1 Running 5 9m12s <strong>172.17.0.6</strong> minikub <none> <none> my-deployment-apache-859486bd8c-vxnbk 1/1 Running 0 7m53s 172.17.0.7 minikub <none> <none> |
отправим пару запросов по домену test.ru указанному в ingress
[root@minikub my-project]# curl -I test.ru/TEEEEST
HTTP/1.1 404 Not Found
Server: openresty/1.15.8.2
Date: Mon, 04 May 2020 12:39:20 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Vary: Accept-Encoding
теперь смотрим лог пода apache
[root@minikub my-project]# kubectl log my-deployment-apache-859486bd8c-vxnbk | grep TEEEEST
log is DEPRECATED and will be removed in a future version. Use logs instead.
172.17.0.6 - - [04/May/2020:12:39:18 +0000] "HEAD /TEEEEST HTTP/1.0" 404 -
как видим всё ок, запрошенного урла нету, апач ответил 404, и запрос прилетел с ip 172.17.0.6
==================================================
Теперь прокинем директории для логов и файлов сайта на nfs сервер.
у нас установлен отдельный nfs сервер 192.168.1.82 который примонтирован к нашему миникубу в директории:
/nfs-client
1 2 |
[root@minikub ~]# df -h | grep nfs 192.168.1.82:/nfs 20G 45M 19G 1% /nfs-client |
создаём PersistentVolume на 2 гига в директории:
/nfs-client/test
[root@minikub ~]# cat pv.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
kind: PersistentVolume apiVersion: v1 metadata: name: research-vol labels: type: local spec: capacity: storage: 2Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain hostPath: path: "/nfs-client/test" |
[/codesyntax]
также создаём PersistentVolumeClaim - это запрос на PersistentVolume (на 1 гигабайт) с типом
ReadWriteMany – том может быть смонтирован к множеству подов в режиме чтения и записи.
[root@minikub ~]# cat pvc.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
--- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: research-pvc spec: accessModes: - ReadWriteMany storageClassName: "" volumeName: research-vol resources: requests: storage: 1Gi |
[/codesyntax]
применим
1 2 3 |
kubectl apply -f pv.yaml |
1 |
kubectl apply -f pvc.yaml |
проверим:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 |
[root@minikub ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE research-vol 2Gi RWX Retain Bound default/research-pvc 2d22h [root@minikub ~]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE research-pvc Bound research-vol 2Gi RWX 2d22h |
[/codesyntax]
теперь подключим этот pv к нашему деплойменту:
[root@minikub ~]# cat my-project/deployment.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
--- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 2 selector: matchLabels: app: my-app # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: my-app # по вот этому лейблу репликасет цепляет под spec: containers: - image: nginx:1.12 name: nginx ports: - containerPort: 80 # тут начинаются проверки по доступности readinessProbe: # проверка готово ли приложение failureThreshold: 3 #указывает количество провалов при проверке httpGet: # по сути дёргает курлом на 80 порт path: / port: 80 periodSeconds: 10 #как часто должна проходить проверка (в секундах) successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда livenessProbe: #проверка на жизнь приложения, живо ли оно failureThreshold: 3 httpGet: path: / port: 80 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд # тут начинается описание лимитов для пода resources: requests: #количество ресурсов которые резервируются для pod на ноде cpu: 50m memory: 100Mi limits: #количество ресурсов которые pod может использовать(верхняя граница) cpu: 100m memory: 100Mi # тут подключаем ранее созданный конфиг nginx volumeMounts: #должен располагаться под containers - name: nginx-conf #имя нашего конфигмапа, созданного ранее. mountPath: /etc/nginx/conf.d/ # путь по которому мы будем монтировать наш конфиг #тут подключаем наш persistant volume - name: research-vol # это имя взято из лейбла pv mountPath: /var/log/nginx/ # тут указываем какую директорию мы прокидываем в pv volumes: #(описывает тома) должен располагаться под spec - name: nginx-conf configMap: name: nginx-conf #тут указываем pvc - наш запрос на pv - name: research-vol # это имя взято из лейбла pv persistentVolumeClaim: claimName: research-pvc # это имя взято из лейбла pvс |
[/codesyntax]
применим изменения:
[root@minikub ~]# kubectl apply -f my-project/deployment.yaml
подождём когда поды обновятся и проверим:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
[root@minikub ~]# kubectl get pod NAME READY STATUS RESTARTS AGE my-deployment-575b6c74bf-qn2hf 1/1 Running 3 2d22h my-deployment-575b6c74bf-sh6zt 1/1 Running 3 2d22h my-deployment-apache-859486bd8c-d5pq5 1/1 Running 3 5d my-deployment-apache-859486bd8c-ql4zd 1/1 Running 3 5d my-deployment-apache-859486bd8c-tdt96 1/1 Running 3 5d my-deployment-apache-859486bd8c-vxnbk 1/1 Running 3 5d1h [root@minikub ~]# kubectl describe pod my-deployment-575b6c74bf-qn2hf Name: my-deployment-575b6c74bf-qn2hf Namespace: default Priority: 0 PriorityClassName: <none> Node: minikub/192.168.1.120 Start Time: Wed, 06 May 2020 20:47:56 +0600 Labels: app=my-app pod-template-hash=575b6c74bf Annotations: <none> Status: Running IP: 172.17.0.10 Controlled By: ReplicaSet/my-deployment-575b6c74bf Containers: nginx: Container ID: docker://b76f1205841a7fb962aab584419fea9cf0365f1aa320ac440706884ec53a2541 Image: nginx:1.12 Image ID: docker-pullable://nginx@sha256:72daaf46f11cc753c4eab981cbf869919bd1fee3d2170a2adeac12400f494728 Port: 80/TCP Host Port: 0/TCP State: Running Started: Sat, 09 May 2020 17:18:20 +0600 Last State: Terminated Reason: Error Exit Code: 1 Started: Sat, 09 May 2020 17:17:59 +0600 Finished: Sat, 09 May 2020 17:17:59 +0600 Ready: True Restart Count: 3 Limits: cpu: 100m memory: 100Mi Requests: cpu: 50m memory: 100Mi Liveness: http-get http://:80/ delay=10s timeout=1s period=10s #success=1 #failure=3 Readiness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3 Environment: <none> Mounts: /etc/nginx/conf.d/ from nginx-conf (rw) <strong>/var/log/nginx/ from research-vol (rw)</strong> /var/run/secrets/kubernetes.io/serviceaccount from default-token-vqkds (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: nginx-conf: Type: ConfigMap (a volume populated by a ConfigMap) Name: nginx-conf Optional: false research-vol: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: research-pvc ReadOnly: false default-token-vqkds: Type: Secret (a volume populated by a Secret) SecretName: default-token-vqkds Optional: false QoS Class: Burstable Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: <none> |
[/codesyntax]
запись
/var/log/nginx/ from research-vol (rw)
говорит нам, что наш том успешно прокинулся внутрь пода.
====
теперь добавим pv для файлов сайта.
создадим pv и pvc
[root@minikub ~]# cat persistent-volume-for-site-files.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
kind: PersistentVolume apiVersion: v1 metadata: name: pv-files-of-site-test.ru labels: type: local spec: capacity: storage: 2Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain hostPath: path: "/nfs-client/files-of-site-test.ru" --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: pvc-files-of-site-test.ru spec: accessModes: - ReadWriteMany storageClassName: "" volumeName: pv-files-of-site-test.ru resources: requests: storage: 1Gi |
[/codesyntax]
тут:
pv-files-of-site-test.ru - наш вольюм
pvc-files-of-site-test.ru - запрос на вольюм
/nfs-client/files-of-site-test.ru - директория на nfs сервере
создаём директорию
[root@minikub ~]# mkdir /nfs-client/files-of-site-test.ru
и создаём наши новые pv и pvc
[root@minikub ~]# kubectl apply -f persistent-volume-for-site-files.yaml
persistentvolume/pv-files-of-site-test.ru created
persistentvolumeclaim/pvc-files-of-site-test.ru created
проверяем:
1 2 3 4 5 6 7 8 9 |
[root@minikub ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-files-of-site-test.ru 2Gi RWX Retain Bound default/pvc-files-of-site-test.ru 106s research-vol 2Gi RWX Retain Bound default/research-pvc 2d22h [root@minikub ~]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-files-of-site-test.ru Bound pv-files-of-site-test.ru 2Gi RWX 110s research-pvc Bound research-vol 2Gi RWX 2d22h |
теперь поправим наши конфиг файлы для nginx и для apache
[root@minikub ~]# cat my-project/nginx-configmap.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
apiVersion: v1 kind: ConfigMap metadata: name: nginx-conf data: my-app.conf: | server { listen 80; server_name _; root /var/site; location / { proxy_pass http://my-service-apache:80; # А вот сюда пишем название сервиса отвечающего за апач } } --- apiVersion: v1 kind: ConfigMap metadata: name: apache-conf data: my-app-apache.conf: | Listen 80 <VirtualHost *:80> DocumentRoot "/var/site/" ServerName _ </VirtualHost> |
[root@minikub ~]# kubectl apply -f my-project/nginx-configmap.conf
configmap/nginx-conf created
configmap/apache-conf created
проверяем:
1 2 3 4 |
[root@minikub ~]# kubectl get configmap NAME DATA AGE apache-conf 1 2m59s nginx-conf 1 2m59s |
[root@minikub ~]# cat my-project/deployment.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
--- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 2 selector: matchLabels: app: my-app # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: my-app # по вот этому лейблу репликасет цепляет под spec: containers: - image: nginx:1.12 name: nginx ports: - containerPort: 80 # тут начинаются проверки по доступности readinessProbe: # проверка готово ли приложение failureThreshold: 3 #указывает количество провалов при проверке httpGet: # по сути дёргает курлом на 80 порт path: / port: 80 periodSeconds: 10 #как часто должна проходить проверка (в секундах) successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда livenessProbe: #проверка на жизнь приложения, живо ли оно failureThreshold: 3 httpGet: path: / port: 80 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд # тут начинается описание лимитов для пода resources: requests: #количество ресурсов которые резервируются для pod на ноде cpu: 50m memory: 100Mi limits: #количество ресурсов которые pod может использовать(верхняя граница) cpu: 100m memory: 100Mi # тут подключаем ранее созданный конфиг nginx volumeMounts: #должен располагаться под containers - name: nginx-conf #имя нашего конфигмапа, созданного ранее. mountPath: /etc/nginx/conf.d/ # путь по которому мы будем монтировать наш конфиг #тут подключаем наш persistant volume - name: research-vol # это имя взято из лейбла pv mountPath: /var/log/nginx/ # тут указываем какую директорию мы прокидываем в pv - name: pv-files-of-site-test-ru mountPath: /var/site/ volumes: #(описывает тома) должен располагаться под spec - name: nginx-conf configMap: name: nginx-conf #тут указываем pvc - наш запрос на pv - name: research-vol # это имя взято из лейбла pv persistentVolumeClaim: claimName: research-pvc # это имя взято из лейбла pvс - name: pv-files-of-site-test-ru persistentVolumeClaim: claimName: pvc-files-of-site-test-ru |
[/codesyntax]
[root@minikub ~]# cat my-project/deployment-apache.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
--- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment-apache spec: replicas: 4 selector: matchLabels: app: apache # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: apache # по вот этому лейблу репликасет цепляет под spec: containers: - image: httpd:2.4.43 name: apache ports: - containerPort: 80 # тут начинаются проверки по доступности readinessProbe: # проверка готово ли приложение failureThreshold: 3 #указывает количество провалов при проверке httpGet: # по сути дёргает курлом на 80 порт path: / port: 80 periodSeconds: 10 #как часто должна проходить проверка (в секундах) successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда livenessProbe: #проверка на жизнь приложения, живо ли оно failureThreshold: 3 httpGet: path: / port: 80 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд # тут начинается описание лимитов для пода resources: requests: #количество ресурсов которые резервируются для pod на ноде cpu: 60m memory: 200Mi limits: #количество ресурсов которые pod может использовать(верхняя граница) cpu: 120m memory: 300Mi resources: requests: #количество ресурсов которые резервируются для pod на ноде cpu: 50m memory: 100Mi limits: #количество ресурсов которые pod может использовать(верхняя граница) cpu: 100m memory: 100Mi # тут подключаем ранее созданный конфиг nginx volumeMounts: #должен располагаться под containers - name: apache-conf #имя нашего конфигмапа, созданного ранее. mountPath: /usr/local/apache2/conf/extra/ # путь по которому мы будем монтировать наш конфиг #тут подключаем наш persistant volume - name: research-vol # это имя взято из лейбла pv mountPath: /usr/local/apache2/logs/ # тут указываем какую директорию мы прокидываем в pv - name: pv-files-of-site-test-ru mountPath: /var/site/ volumes: #(описывает тома) должен располагаться под spec - name: apache-conf configMap: name: apache-conf #тут указываем pvc - наш запрос на pv - name: research-vol # это имя взято из лейбла pv persistentVolumeClaim: claimName: research-pvc # это имя взято из лейбла pvс - name: pv-files-of-site-test-ru persistentVolumeClaim: claimName: pvc-files-of-site-test-ru |
[/codesyntax]
[root@minikub ~]# kubectl apply -f my-project/deployment-apache.yaml
[root@minikub ~]# kubectl apply -f my-project/deployment.yaml
всё, после того как поды обновятся можно загружать файлы сайта в директорию:
/nfs-client/files-of-site-test.ru/
========================================================
Dynamic NFS provision
добавим динамическую работу с pv
у нас уже установлен nfs сервер:
192.168.1.82 и у него общая директория /nfs
на клиентах директория /nfs
cat rbac.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
kind: ServiceAccount apiVersion: v1 metadata: name: nfs-client-provisioner --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-client-provisioner-runner rules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "update", "patch"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: run-nfs-client-provisioner subjects: - kind: ServiceAccount name: nfs-client-provisioner namespace: default roleRef: kind: ClusterRole name: nfs-client-provisioner-runner apiGroup: rbac.authorization.k8s.io --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner subjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default roleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io |
[/codesyntax]
cat class.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: managed-nfs-storage annotations: storageclass.kubernetes.io/is-default-class: "true" provisioner: example.com/nfs reclaimPolicy: Retain parameters: archiveOnDelete: "false" |
[/codesyntax]
cat deployment.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner spec: replicas: 1 selector: matchLabels: app: nfs-client-provisioner strategy: type: Recreate template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: quay.io/external_storage/nfs-client-provisioner:latest volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: example.com/nfs - name: NFS_SERVER value: 192.168.1.82 - name: NFS_PATH value: /nfs volumes: - name: nfs-client-root nfs: server: 192.168.1.82 path: /nfs |
[/codesyntax]
запрос будет выглядеть следующим образом:
cat pvc.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 |
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc1 spec: storageClassName: managed-nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 500Mi |
[/codesyntax]
теперь применяем:
kubectl apply -f rbac.yaml
kubectl apply -f class.yaml
kubectl apply -f deployment.yaml
kubectl apply -f pvc.yaml
============================================================
apache nginx + файлы сайта на nfs сервере c auto provision.
[root@minikub ~]# cat nfs-auto-provisioner/rbac.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
kind: ServiceAccount apiVersion: v1 metadata: name: nfs-client-provisioner --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-client-provisioner-runner rules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "update", "patch"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: run-nfs-client-provisioner subjects: - kind: ServiceAccount name: nfs-client-provisioner namespace: default roleRef: kind: ClusterRole name: nfs-client-provisioner-runner apiGroup: rbac.authorization.k8s.io --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: leader-locking-nfs-client-provisioner subjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default roleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io |
[/codesyntax]
[root@minikub ~]# cat nfs-auto-provisioner/class.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 |
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: managed-nfs-storage annotations: storageclass.kubernetes.io/is-default-class: "true" provisioner: test.ru/nfs reclaimPolicy: Retain parameters: archiveOnDelete: "false" |
[root@minikub ~]# cat nfs-auto-provisioner/deployment.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner spec: replicas: 1 selector: matchLabels: app: nfs-client-provisioner strategy: type: Recreate template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: quay.io/external_storage/nfs-client-provisioner:latest volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: test.ru/nfs - name: NFS_SERVER value: 192.168.1.82 - name: NFS_PATH value: /nfs volumes: - name: nfs-client-root nfs: server: 192.168.1.82 path: /nfs |
[root@minikub ~]# kubectl apply -f rbac.yaml
[root@minikub ~]# kubectl apply -f class.yaml
[root@minikub ~]# kubectl apply -f deployment.yaml
cat pvc.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: volume-for-site-testru spec: storageClassName: managed-nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 3Gi --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: volume-for-logs-site-testru spec: storageClassName: managed-nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 4Gi |
[/codesyntax]
cat httpd/service-apache.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
--- apiVersion: v1 kind: Service metadata: name: service-apache-for-site-testru # имя сервиса spec: ports: - port: 8080 # принимать на 80 targetPort: 80 # отправлять на 80 selector: app: apache-site-testru #отправлять на все поды с данным лейблом type: ClusterIP |
[/codesyntax]
cat httpd/deployment-apache.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
apiVersion: v1 kind: ConfigMap metadata: name: apache-conf-for-site-testru data: testru.conf: | <VirtualHost *:80> ServerName _ DocumentRoot /var/site/ ErrorLog /var/log/httpd/testru-httpd-error.log CustomLog /var/log/httpd/testru-httpd-access.log combined <IfModule php7_module> AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps <IfModule dir_module> DirectoryIndex index.html index.php </IfModule> <Directory /var/site> Options -Indexes Options +ExecCGI Require all granted Options FollowSymLinks AllowOverride All </Directory> </IfModule> </VirtualHost> --- apiVersion: apps/v1 kind: Deployment metadata: name: deployment-apache-site-testru spec: replicas: 1 selector: matchLabels: app: apache-site-testru # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: apache-site-testru # по вот этому лейблу репликасет цепляет под spec: containers: - image: polinux/httpd-php:php72 name: apache ports: - containerPort: 80 # тут начинаются проверки по доступности readinessProbe: # проверка готово ли приложение failureThreshold: 3 #указывает количество провалов при проверке httpGet: # по сути дёргает курлом на 80 порт path: / port: 80 periodSeconds: 10 #как часто должна проходить проверка (в секундах) successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда livenessProbe: #проверка на жизнь приложения, живо ли оно failureThreshold: 3 httpGet: path: / port: 80 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд # тут начинается описание лимитов для пода resources: requests: #количество ресурсов которые резервируются для pod на ноде cpu: 1000m memory: 400Mi limits: #количество ресурсов которые pod может использовать(верхняя граница) cpu: 2000m memory: 1024Mi # тут подключаем ранее созданный конфиг apache volumeMounts: #должен располагаться под containers - name: apache-conf-for-site-testru #имя нашего конфигмапа, созданного ранее. mountPath: /etc/httpd/conf.d/ # путь по которому мы будем монтировать наш конфиг #тут подключаем наш persistant volume - name: volume-for-logs-site-testru # это имя взято из лейбла pv mountPath: /var/log/httpd/ # тут указываем какую директорию мы прокидываем в pv - name: volume-for-site-testru mountPath: /var/site/ volumes: #(описывает тома) должен располагаться под spec - name: apache-conf-for-site-testru configMap: name: apache-conf-for-site-testru #тут указываем pvc - наш запрос на pv - name: volume-for-site-testru # это имя взято из лейбла pv persistentVolumeClaim: claimName: volume-for-site-testru # это имя взято из лейбла pvс - name: volume-for-logs-site-testru persistentVolumeClaim: claimName: volume-for-logs-site-testru |
cat nginx/service-nginx.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
--- apiVersion: v1 kind: Service metadata: name: service-nginx-for-site-testru # имя сервиса spec: ports: - port: 80 # принимать на 80 targetPort: 80 # отправлять на 80 selector: app: nginx-site-testru #отправлять на все поды с данным лейблом type: ClusterIP |
[/codesyntax]
cat nginx/deployment-nginx.yaml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
apiVersion: v1 kind: ConfigMap metadata: name: nginx-conf-for-site-testru data: testru.conf: | server { listen 80; server_name _; access_log /var/log/nginx/testru-nginx-access.log; error_log /var/log/nginx/testru-nginx-error.log error; location ~* \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|wav|bmp|rtf|swf|js|html|htm|)$ { root /var/site; } location / { proxy_pass http://service-apache-for-site-testru:8080; # А вот сюда пишем название сервиса отвечающего за апач proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass_header Set-Cookie; } } --- apiVersion: apps/v1 kind: Deployment metadata: name: deployment-nginx-site-testru spec: replicas: 1 selector: matchLabels: app: nginx-site-testru # по вот этому лейблу репликасет цепляет под # тут описывается каким мокаром следует обновлять поды strategy: rollingUpdate: maxSurge: 1 # указывает на какое количество реплик можно увеличить maxUnavailable: 1 # указывает на какое количество реплик можно уменьшить #т.е. в одно время при обновлении, будет увеличено на один (новый под) и уменьшено на один (старый под) type: RollingUpdate ## тут начинается описание контейнера template: metadata: labels: app: nginx-site-testru # по вот этому лейблу репликасет цепляет под spec: containers: - image: nginx:1.12 name: nginx ports: - containerPort: 80 # тут начинаются проверки по доступности readinessProbe: # проверка готово ли приложение failureThreshold: 3 #указывает количество провалов при проверке httpGet: # по сути дёргает курлом на 80 порт path: / port: 80 periodSeconds: 10 #как часто должна проходить проверка (в секундах) successThreshold: 1 #сбрасывает счётчик неудач, т.е. при 3х проверках если 1 раз успешно прошло, то счётчик сбрасывается и всё ок timeoutSeconds: 1 #таймаут на выполнение пробы 1 секунда livenessProbe: #проверка на жизнь приложения, живо ли оно failureThreshold: 3 httpGet: path: / port: 80 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initialDelaySeconds: 10 #означает что первую проверку надо сделать только после 10 секунд # тут начинается описание лимитов для пода resources: requests: #количество ресурсов которые резервируются для pod на ноде cpu: 50m memory: 100Mi limits: #количество ресурсов которые pod может использовать(верхняя граница) cpu: 100m memory: 100Mi # тут подключаем ранее созданный конфиг nginx volumeMounts: #должен располагаться под containers - name: nginx-conf-for-site-testru #имя нашего конфигмапа, созданного ранее. mountPath: /etc/nginx/conf.d/ # путь по которому мы будем монтировать наш конфиг #тут подключаем наш persistant volume - name: volume-for-logs-site-testru # это имя взято из лейбла pv mountPath: /var/log/nginx/ # тут указываем какую директорию мы прокидываем в pv - name: volume-for-site-testru mountPath: /var/site/ volumes: #(описывает тома) должен располагаться под spec - name: nginx-conf-for-site-testru configMap: name: nginx-conf-for-site-testru #тут указываем pvc - наш запрос на pv - name: volume-for-site-testru # это имя взято из лейбла pv persistentVolumeClaim: claimName: volume-for-site-testru # это имя взято из лейбла pvс - name: volume-for-logs-site-testru persistentVolumeClaim: claimName: volume-for-logs-site-testru |
[/codesyntax]
kubectl apply -f pvc.yaml
kubectl apply -f httpd/service-apache.yaml
kubectl apply -f httpd/deployment-apache.yaml
kubectl apply -f nginx/service-nginx.yaml
kubectl apply -f nginx/deployment-nginx.yaml