/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
Комментариев нет:
Отправить комментарий