Цель

Заметки ИТ которые я не хочу потерять

menu_navigation

Deploy Redis cluster to Kubernetes with Gitlab CI

Создаем новый проект, и в нем создаем следующую структуру:

/redis-cluster
|--- manifests
                |--- service.yaml
                |--- statefulset.yaml
|--- .gitlab-ci.yml
|--- Dockerfile
|--- redis.conf

Реализация деплоя redis кластера в kubernetes с помощью gitlab ci, с манифестами. Основные переменные: название кластера $YOUR_APP – используется в yaml файлах, и $ KUBE_NAMESPASE – ваше имя пространства. 192.168.0.63 – это nexus докер репозиторий, для входа в него используются переменные $NEXUS_USER и $NEXUS_PASS которые добавлены в variables в настройках проекта gitlab. Namespace укажите свой. Количество реплик – 6, минимально рекомендуемое для работы кластера, 3 мастера и 3 слейва. В скрипте также конкретно указан кластер k8s, если у вас k8s интегрирован в gitlab закомментируйте эти строки.

Содержимое файлов

.gitlab-ci.yml
image: alpine:latest

variables:
  YOUR_APP: redis-cluster
  KUBERNETES_VERSION: 1.12.3
  KUBE_NAMESPASE: your_namespace
  KUBE_URL: https://192.168.0.74:6443
  KUBE_USER: kube
  KUBE_PASSWORD: your_password
 
stages:
  - build
  - production

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  script:
  - registry_login
  - docker pull 192.168.0.63/$YOUR_APP:latest || true
  - docker build --cache-from 192.168.0.63/$YOUR_APP:latest -t 192.168.0.63/$YOUR_APP:latest .
  - docker push 192.168.0.63/$YOUR_APP:latest
  only:
    - branches
    - tags

production:
  stage: production
  script:
    - install_dependencies
# подключаем конкретный кластер k8s
    - kubectl config set-cluster default-cluster --insecure-skip-tls-verify=true --server=${KUBE_URL}
   - kubectl config set-credentials default-admin --username=${KUBE_USER} --password=${KUBE_PASSWORD}
    - kubectl config set-context default-system --user=default-admin --namespace=${KUBE_NAMESPACE} --cluster=default-cluster
    - kubectl config use-context default-system
    - kubectl cluster-info
    - install_secrets
    - cd manifests/
    - sed -i "s/__YOUR_APP__/${YOUR_APP}/" statefulset.yaml service.yaml
- sed -i "s/__KUBE_NAMESPACE__/${KUBE_NAMESPACE}/" statefulset.yaml service.yaml
    - |
      if kubectl apply -f statefulset.yaml | grep -q unchanged; then
        kubectl patch -f statefulset.yaml -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"ci-last-updated\":\"$(date +'%s')\"}}}}}"
        echo "=> Patching statefulset to force image update."
      else
        echo "=> statefulset apply has changed the object, no need to force image update."
      fi
    - kubectl apply -f service.yaml
    - kubectl rollout status -f statefulset.yaml
    - create_redis_cluster
  environment:
    name: $YOUR_APP
    url: http://$YOUR_APP.$KUBE_INGRESS_BASE_DOMAIN

.auto_devops: &auto_devops |
  function create_redis_cluster() {
    kubectl -n your_namespace exec "$YOUR_APP"-0 -- bash -c "echo yes | redis-cli --cluster create $(kubectl -n your_namespace get pods -l app=$YOUR_APP -o jsonpath='{range.items[*]}{.status.podIP}:6379 ') --cluster-replicas 1"
  }

  function install_dependencies() {
    apk add -U curl
    curl -L -o /usr/bin/kubectl "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl"
    chmod +x /usr/bin/kubectl
    kubectl version --client
  }

  function registry_login() {
    if [[ -n "$NEXUS_USER" ]]; then
      echo "Logging to Nexus Container Registry"
      docker login -u "$NEXUS_USER" -p "$NEXUS_PASS" 192.168.0.63
      echo ""
    fi
  }
 
  function install_secrets() {
    kubectl create secret -n your_namespace \
      docker-registry regsecret \
      --docker-server="192.168.0.63" \
      --docker-username="$NEXUS_USER" \
      --docker-password="$NEXUS_PASS" \
      --docker-email="gitlab@nafanasev.local" \
      -o yaml --dry-run | kubectl replace -n your_namespace --force -f -
  }
 
before_script:
  - *auto_devops

Dockerfile
FROM redis:latest
RUN apt-get -y update \
  && apt-get -y upgrade \
  && apt-get -y --no-install-recommends install ruby apt-utils
RUN apt-get install -y rubygems
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
EXPOSE 6379

redis.conf
cluster-enabled yes
cluster-require-full-coverage no
cluster-node-timeout 1000
cluster-slave-validity-factor 2
cluster-migration-barrier 1
cluster-config-file nodes.conf
protected-mode no
maxmemory 100mb
maxmemory-policy allkeys-lru


service.yaml
apiVersion: v1
kind: Service
metadata:
  name: __YOUR_APP__
  namespace: __KUBE_NAMESPACE__
  labels:
    app: __YOUR_APP__
spec:
  ports:
    - name: client
      port: 6379
      protocol: TCP
      targetPort: 6379
    - name: cluster
      port: 16379
      protocol: TCP
      targetPort: 16379
  selector:
    app: __YOUR_APP__
  type: ClusterIP

statefulset.yaml
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: __YOUR_APP__
  namespace: __KUBE_NAMESPACE__ 
spec:
  serviceName: __YOUR_APP__
  replicas: 6
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: __YOUR_APP__
    spec:
      imagePullSecrets:
        - name: regsecret  
      containers:
      - name: __YOUR_APP__
        image: 192.168.0.63/__YOUR_APP__:latest
        ports:
        - containerPort: 6379
          name: client
        - containerPort: 16379
          name: cluster
        resources:
          requests:
            memory: "128Mi"
            cpu: "0.1"
          limits:
            memory: "1024Mi"
            cpu: "0.5"
        readinessProbe:
          exec:
            command:
            - sh
            - -c
            - "redis-cli -h $(hostname) ping"
          initialDelaySeconds: 15
          timeoutSeconds: 5
        livenessProbe:
          exec:
            command:
            - sh
            - -c
            - "redis-cli -h $(hostname) ping"
          initialDelaySeconds: 20
          periodSeconds: 3

Проверка кластера:

Вход на ноду кластера, с возможностью перенаправления на другую – флаг “–c”, задаем несколько пар ключей и значений, и проверяем вывод.

redis-cli -h YOUR_APP -c -p 6379
CLUSTER KEYSLOT {hash-tag1}key1
CLUSTER KEYSLOT {hash-tag1}key2
MSET {hash-tag1}key1 Hello {hash-tag1}key2 World
MGET {hash-tag1}key1 {hash-tag1}key2

Комментариев нет:

Отправить комментарий