Monitoreo de enlaces de microservicio y liberación automática
Monitoreo de enlace completo de microservicio
¿Qué es la supervisión de enlace completo?
Con la popularidad de la arquitectura de microservicios, los servicios se dividen según diferentes dimensiones y, a menudo, una solicitud implica varios servicios. Estos servicios se pueden desarrollar en diferentes lenguajes de programación, desarrollados por diferentes equipos, y se pueden implementar muchas copias. Por lo tanto, se necesitan algunas herramientas que pueden ayudar a comprender el comportamiento del sistema y analizar los problemas de rendimiento para que, cuando ocurra una falla, el problema se pueda localizar y resolver rápidamente. El componente de supervisión de enlace completo se creó en el contexto de este problema.
La supervisión del rendimiento del enlace completo muestra varios indicadores desde la dimensión general hasta la dimensión local, y muestra de forma centralizada la información de rendimiento de todas las cadenas de llamadas en todas las aplicaciones, lo que puede facilitar la medición del rendimiento general y local, y facilitar la identificación de la fuente de falla, que puede reducirse considerablemente en la producción. Tiempo de resolución de problemas.
¿Qué problema resuelve la supervisión de enlaces completos?
- Solicitar seguimiento de enlaces: analice las relaciones de las llamadas de servicio, extraiga información de topología en tiempo de ejecución y visualice la pantalla
- Medición del estado de la llamada: análisis de rendimiento de cada enlace de llamada, como rendimiento, tiempo de respuesta y número de errores.
- Referencia de planificación de contenedores: expansión / reducción de capacidad, degradación del servicio, control de flujo
- Comentarios sobre el estado de la operación: alarma y localiza rápidamente información de error a través de la cadena de llamadas y el registro comercial
Base de selección para el sistema de monitoreo de enlace completo
Hay muchos sistemas de monitoreo de enlace completo y debe elegir entre estos aspectos:
- El consumo de rendimiento de las sondas
debe ser lo suficientemente pequeño para los servicios de componentes de APM, el análisis de datos debe ser rápido y el rendimiento debe ser pequeño. - La intrusión del código
también se utiliza como un componente comercial, y debería haber la menor cantidad posible de otros sistemas comerciales, lo cual es transparente para el usuario y reduce la carga para los desarrolladores. - Hay
tantas dimensiones de análisis de dimensión de seguimiento como sea posible. - Escalabilidad
Un excelente sistema de seguimiento de llamadas debe admitir la implementación distribuida y tener una buena escalabilidad
. Cuantos más componentes se puedan admitir, mejor. - Sistemas convencionales: zipkin, skywalking, pinpoint
introducción precisa
Pinpoint es una herramienta APM (gestión del rendimiento de aplicaciones) adecuada para grandes sistemas distribuidos escritos en Java / PHP.
característica:
- Server Map (ServerMap) comprende la topología del sistema al visualizar los módulos del sistema distribuido y sus interconexiones. Al hacer clic en un nodo, se mostrarán los detalles del módulo, como su estado actual y el número de solicitudes.
- Gráfico de subprocesos activos en tiempo real (gráfico de subprocesos activos en tiempo real): Monitoreo en tiempo real de subprocesos activos dentro de la aplicación.
- Gráfico de dispersión de solicitudes / respuestas: visualización a largo plazo del número de solicitudes y patrones de respuesta para localizar problemas potenciales. Puede optar por solicitar información más detallada arrastrando el gráfico.
- CallStack (CallStack): genere vistas a nivel de código para cada llamada en un entorno distribuido y localice cuellos de botella y puntos de falla en una sola vista.
- Inspector: vea otra información detallada sobre la aplicación, como el uso de CPU, memoria / recolección de basura, TPS y parámetros de JVM.
implementación precisa
Implementación de Docker:
Primero descargue la imagen precisa y luego impórtela mediante la carga de la ventana acoplable
Enlace: https://pan.baidu.com/s/1-h8g7dxB9v6YiXMYVNv36Q Contraseña: u6qb
Si la descarga de github es lenta, puede clonar directamente el código fuente abierto en su propio gitee y luego descargarlo, que es más rápido
$ tar xf pinpoint-image.tar.gz && cd pinpoint-image
$ for i in $(ls ./); do docker load < $i; done # 导镜像
$ git clone https://github.com/naver/pinpoint-docker.git
$ cd pinpoint-docker && git checkout -b origin/1.8.5 #切换分支再操作
$ docker images
pinpointdocker/pinpoint-quickstart latest 09fd7f38d8e4 8 months ago 480MB
pinpointdocker/pinpoint-agent 1.8.5 ac7366387f2c 8 months ago 27.3MB
pinpointdocker/pinpoint-collector 1.8.5 034a20159cd7 8 months ago 534MB
pinpointdocker/pinpoint-web 1.8.5 3c58ee67076f 8 months ago 598MB
zookeeper 3.4 a27dff262890 8 months ago 256MB
pinpointdocker/pinpoint-mysql 1.8.5 99053614856e 8 months ago 455MB
pinpointdocker/pinpoint-hbase 1.8.5 1d3499afa5e9 8 months ago 992MB
flink 1.3.1 c08ccd5bb7a6 3 years ago 480MB
$ docker-compose pull && docker-compose up -d
Espere unos 10 minutos para visitar
Implementación de PinPoint Agent
- Directorio de código de retorno (simple-microservice-dev4)
- Agregue el agente de pingpoint y modifique el archivo de configuración (introducido por pinpoint)
eureka-service/pinpoint/pinpoint.config
gateway-service/pinpoint/pinpoint.config
order-service/order-service-biz/pinpoint/pinpoint.config
portal-service/pinpoint/pinpoint.config
product-service/product-service-biz/pinpoint/pinpoint.config
stock-service/stock-service-biz/pinpoint/pinpoint.config
# 将上述的配置文件修改如下:(我的pinpoint是192.168.56.14部署的)
profiler.collector.ip=192.168.56.14
- Modificación del archivo docker del proyecto
# eurake-server
$ vim eureka-service/Dockerfile
FROM java:8-jdk-alpine
LABEL maintainer [email protected]
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories &&\
apk add -U tzdata && \
rm -rf /var/cache/apk/* && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/eureka-service.jar ./
COPY pinpoint /pinpoint
EXPOSE 8888
CMD java -jar -javaagent:/pinpoint/pinpoint-bootstrap-1.8.3.jar -Dpinpoint.agentId=${HOSTNAME} -Dpinpoint.applicationName=ms-eureka -Deureka.instance.hostname=${MY_POD_NAME}.eureka.ms /eureka-service.jar
# gateway-service
$ vim gateway-service/Dockerfile
FROM java:8-jdk-alpine
LABEL maintainer [email protected]
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories &&\
apk add -U tzdata && \
rm -rf /var/cache/apk/* && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/gateway-service.jar ./
COPY pinpoint /pinpoint
EXPOSE 9999
CMD java -jar -javaagent:/pinpoint/pinpoint-bootstrap-1.8.3.jar -Dpinpoint.agentId=$(echo $HOSTNAME | awk -F- '{print "gateway-"$NF}') -Dpinpoint.applicationName=ms-gateway /gateway-service.jar
# order-service-biz/Dockerfile
$ order-service/order-service-biz/Dockerfile
FROM java:8-jdk-alpine
LABEL maintainer [email protected]
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories &&\
apk add -U tzdata && \
rm -rf /var/cache/apk/* && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/order-service-biz.jar ./
COPY pinpoint /pinpoint
EXPOSE 8020
CMD java -jar -javaagent:/pinpoint/pinpoint-bootstrap-1.8.3.jar -Dpinpoint.agentId=$(echo $HOSTNAME | awk -F- '{print "order-"$NF}') -Dpinpoint.applicationName=ms-order /order-service-biz.jar
# portal-service/Dockerfile
$ vim portal-service/Dockerfile
FROM java:8-jdk-alpine
LABEL maintainer [email protected]
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories &&\
apk add -U tzdata && \
rm -rf /var/cache/apk/* && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/portal-service.jar ./
COPY pinpoint /pinpoint
EXPOSE 8080
CMD java -jar -javaagent:/pinpoint/pinpoint-bootstrap-1.8.3.jar -Dpinpoint.agentId=$(echo $HOSTNAME | awk -F- '{print "portal-"$NF}') -Dpinpoint.applicationName=ms-portal /portal-service.jar
# product-service/product-service-biz/Dockerfile
FROM java:8-jdk-alpine
LABEL maintainer [email protected]
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories &&\
apk add -U tzdata && \
rm -rf /var/cache/apk/* && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/product-service-biz.jar ./
COPY pinpoint /pinpoint
EXPOSE 8010
CMD java -jar -javaagent:/pinpoint/pinpoint-bootstrap-1.8.3.jar -Dpinpoint.agentId=$(echo $HOSTNAME | awk -F- '{print "product-"$NF}') -Dpinpoint.applicationName=ms-product /product-service-biz.jar
# stock-service/stock-service-biz/Dockerfile
FROM java:8-jdk-alpine
LABEL maintainer [email protected]
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories &&\
apk add -U tzdata && \
rm -rf /var/cache/apk/* && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/stock-service-biz.jar ./
COPY pinpoint /pinpoint
EXPOSE 8030
CMD java -jar -javaagent:/pinpoint/pinpoint-bootstrap-1.8.3.jar -Dpinpoint.agentId=$(echo $HOSTNAME | awk -F- '{print "stock-"$NF}') -Dpinpoint.applicationName=ms-stock /stock-service-biz.jar
- Modificación de la base de datos del proyecto
主要在src/main/resources/application-fat.yml 配置文件中
1. msyql: order-service-biz,product-service-biz, stock-service-biz (**一定要配置上default ns 下的mysql svc**)
url: jdbc:mysql://java-demo-db-mysql.default:3306/tb_order?characterEncoding=utf-8
username: root
password: RRGynGS53N
2. eurake
defaultZone: http://eureka-0.eureka.ms:8888/eureka,http://eureka-1.eureka.ms:8888/eureka,http://eureka-2.eureka.ms:8888/eureka
- Lanzamiento de compilación con guión
$ cd microservic-code/simple-microservice-dev4/k8s
$ cd k8s && ls
docker_build.sh eureka.yaml gateway.yaml order.yaml portal.yaml product.yaml stock.yaml
$ vim docker_build.sh #自动构建脚本
#!/bin/bash
docker_registry=hub.cropy.cn
kubectl create secret docker-registry registry-pull-secret --docker-server=$docker_registry --docker-username=admin --docker-password=Harbor12345 [email protected] -n ms
service_list="eureka-service gateway-service order-service product-service stock-service portal-service"
service_list=${1:-${service_list}}
work_dir=$(dirname $PWD)
current_dir=$PWD
cd $work_dir
mvn clean package -Dmaven.test.skip=true
for service in $service_list; do
cd $work_dir/$service
if ls |grep biz &>/dev/null; then
cd ${service}-biz
fi
service=${service%-*}
image_name=$docker_registry/microservice/${service}:$(date +%F-%H-%M-%S)
docker build -t ${image_name} .
docker push ${image_name}
sed -i -r "s#(image: )(.*)#\1$image_name#" ${current_dir}/${service}.yaml
kubectl apply -f ${current_dir}/${service}.yaml
done
$ rm -fr *.yaml #删掉旧的yaml
$ cp ../../simple-microservice-dev3/k8s/*.yaml ./ #将之前改好的yaml放进来
$ ./docker_build.sh # 自动构建并上传镜像,同时启动服务
$ kubectl get pod -n ms # 查看构建之后的pod是否正常
Estado de la vista del navegador
El consumo de recursos es relativamente grande, por lo que solo muestre estos
Identifique los indicadores de la interfaz gráfica que necesitan atención
- Número de solicitudes / número de llamadas
- Memoria de pila (información de JVM)
- Información de llamada (seguimiento de pila)
- Tiempo de respuesta
- Tasa de error
- Topología de enlace de llamada de microservicio
Liberación automática
Diseño del proceso de lanzamiento
Preparación básica del entorno
K8s (controlador de entrada, CoreDNS, suministro automático fotovoltaico)
Para detalles:
Timón v3
1. Instale el complemento push
https://github.com/chartmuseum/helm-push
helm plugin install https://github.com/chartmuseum/helm-push
Si no puede descargarlo en línea, también puede descomprimir directamente el paquete en el software del curso:
# tar zxvf helm-push_0.7.1_linux_amd64.tar.gz
# mkdir -p /root/.local/share/helm/plugins/helm-push
# chmod +x /root/.local/share/helm/plugins/helm-push/bin/*
# mv bin plugin.yaml /root/.local/share/helm/plugins/helm-push
2. Configure Docker para que sea de confianza en el host de Jenkins. Si es HTTPS, copie el certificado
Todos los nodos del clúster k8s deben configurarse
$ cat /etc/docker/daemon.json
{
"graph": "/data/docker",
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"insecure-registries": ["hub.cropy.cn"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
$ ls /etc/docker/certs.d/hub.cropy.cn/hub.pem #这就是harbor证书,放到docker目录下
3. Agregar repositorio
$ helm repo add --username admin --password Harbor12345 myrepo https://hub.cropy.cn/chartrepo/library --ca-file /etc/docker/certs.d/hub.cropy.cn/hub.pem #需要制定自签证书否则会报错,建议k8s持续集成过程中habor关闭https,不然jenkins-slave部署过程中会报x509证书问题
$ helm repo add azure http://mirror.azure.cn/kubernetes/charts
4. Empuje e instale Chart (ejemplo)
$ helm pull azure/mysql --untar
$ helm package mysql
Successfully packaged chart and saved it to: /root/mysql-1.6.6.tgz
$ helm push mysql-1.6.6.tgz --username=admin --password=Harbor12345 https://hub.cropy.cn/chartrepo/library --ca-file /etc/docker/certs.d/hub.cropy.cn/hub.pem #需要制定自签证书,否则会报错
Gitlab
192.168.56.17 Este nodo está implementado, siempre que esté instalado Docker
mkdir gitlab
cd gitlab
docker run -d \
--name gitlab \
-p 8443:443 \
-p 9999:80 \
-p 9998:22 \
-v $PWD/config:/etc/gitlab \
-v $PWD/logs:/var/log/gitlab \
-v $PWD/data:/var/opt/gitlab \
-v /etc/localtime:/etc/localtime \
--restart=always \
lizhenliang/gitlab-ce-zh:latest
Dirección de visita: http: // IP: 9999
La contraseña de administrador se establecerá por primera vez y luego iniciará sesión. El nombre de usuario de administrador predeterminado es root y la contraseña se acaba de establecer.
Crea un proyecto y envía un código de prueba
Use el código de la rama dev3 de la lección anterior (que ha sido cambiado)
# 当时这个代码是放在k8s master节点上的
git config --global user.name "root"
git config --global user.email "[email protected]"
cd microservic-code/simple-microservice-dev3
find ./ -name target | xargs rm -fr #删除之前的构建记录
git init
git remote add origin http://192.168.56.17:9999/root/microservice.git
git add .
git commit -m 'all'
git push origin master
Harbour y habilite la función de almacenamiento de cartas
Se recomienda desactivar la función https; de lo contrario, el certificado autofirmado afectará el problema del tirón del timón
$ tar zxvf harbor-offline-installer-v2.0.0.tgz
$ cd harbor
$ cp harbor.yml.tmpl harbor.yml
$ vi harbor.yml #需要证书的话可以自行cfssl,或者openssl生成
hostname: hub.cropy.cn
http:
port: 80
#https:
# port: 443
# certificate: /etc/harbor/ssl/hub.pem
# private_key: /etc/harbor/ssl/hub-key.pem
harbor_admin_password: Harbor12345
$ ./prepare
$ ./install.sh --with-chartmuseum
$ docker-compose ps
MySQL (base de datos de microservicios)
El método de creación es el siguiente, también necesita importar la base de datos correspondiente
$ helm install java-demo-db --set persistence.storageClass="managed-nfs-storage" azure/mysql
$ kubectl get secret --namespace default java-demo-db-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo
RRGynGS53N
mysql -h java-demo-db-mysql -pRRGynGS53N # 获取访问方式
Eureka (Centro de registro)
$ cd microservic-code/simple-microservice-dev3/k8s
$ kubectl apply -f eureka.yaml
$ kubectl get pod -n ms # 查看eurake 创建
Departamento de Medio de Kenkins Jenkins
$ unzip jenkins.zip && cd jenkins && ls ./ #压缩包地址
deployment.yml ingress.yml rbac.yml service-account.yml service.yml
$ kubectl apply -f .
$ kubectl get pod
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
java-demo-db-mysql ClusterIP 10.0.0.142 <none> 3306/TCP 6d20h
jenkins NodePort 10.0.0.146 <none> 80:30006/TCP,50000:32669/TCP 16m
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 27d
Visite http://192.168.56.11:30006/ para configurar
Actualización de la contraseña y la dirección del complemento (muy importante)
- Busque el servidor NFS (192.168.56.13) configurado con aprovisionamiento automático pv e ingrese al directorio compartido
$ cd /ifs/kubernetes/default-jenkins-home-pvc-fdc745cc-6fa9-4940-ae6d-82be4242d2c5/
$ cat secrets/initialAdminPassword #这是默认密码,填写到http://192.168.56.11:30006 登陆界面即可
edf37aff6dbc46728a3aa37a7f3d3a5a
- Sin complemento
- Configurar nueva cuenta
- Modificar la fuente del complemento
# 默认从国外网络下载插件,会比较慢,建议修改国内源:
$ cd /ifs/kubernetes/default-jenkins-home-pvc-fdc745cc-6fa9-4940-ae6d-82be4242d2c5/updates/
sed -i 's/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && \
sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
- Reconstruir vaina
$ kubectl delete pod jenkins-754b6fb4b9-dxssj
- Instalación de complemento
Administrar Jenkins-> Configuración del sistema -> Administrar complementos -> Buscar parámetro de Git / Git / Pipeline / kubernetes / Proveedor de archivos de configuración respectivamente, seleccionar y hacer clic en instalar.
- Parámetro de Git: construcción con parámetros de Git
- Parámetro de elección extendida: construcción parametrizada de múltiples cuadros de selección
- Git: extraer el código
- Pipeline: Pipeline
- kubernetes: conéctese a Kubernetes para crear dinámicamente un agente esclavo
- Proveedor de archivos de configuración: almacena el archivo de configuración kubeconfig utilizado por kubectl para conectarse al clúster k8s
Oleoducto Jenkins y construcción parametrizada
Jenkins Pipeline es un conjunto de complementos que admiten la integración y las canalizaciones de entrega continua en Jenkins;
-
La tubería modela tuberías de transmisión simples a complejas a través de una sintaxis específica;
- Declarativo: sigue la misma sintaxis que Groovy. canalización {}
- Scripting: admite la mayoría de las funciones de Groovy y también es una herramienta muy expresiva y flexible. nodo {}
- La definición de Jenkins Pipeline se escribe en un archivo de texto llamado Jenkinsfile.
En el entorno real, a menudo hay muchos proyectos, especialmente la arquitectura de microservicio. Si se crea un elemento para cada servicio, inevitablemente aumentará la carga de trabajo de operación y mantenimiento. Por lo tanto, puede utilizar la construcción parametrizada de Jenkins y la interacción manual para confirmar el entorno de lanzamiento. Configuración, estado esperado, etc.
Imagen de jenkins-slave de compilación personalizada
Jenkins crea agentes dinámicamente en Kubernetes
Colocación de Jenkins Kubernetes
Complemento de Kubernetes: Jenkins ejecuta agentes dinámicos en un clúster de Kubernetes
Introducción al complemento: https://github.com/jenkinsci/kubernetes-plugin
- Configuración de la nube
Crear una imagen de esclavo jenkins
Consulte jenkins.zip para obtener más detalles.
$ unzip jenkins-slave.zip && cd jenkins-slave && ls ./
Dockerfile helm jenkins-slave kubectl settings.xml slave.jar
$ vim Dockerfile
FROM centos:7
LABEL maintainer [email protected]
RUN yum install -y java-1.8.0-openjdk maven curl git libtool-ltdl-devel && \
yum clean all && \
rm -rf /var/cache/yum/* && \
mkdir -p /usr/share/jenkins
COPY slave.jar /usr/share/jenkins/slave.jar
COPY jenkins-slave /usr/bin/jenkins-slave
COPY settings.xml /etc/maven/settings.xml
RUN chmod +x /usr/bin/jenkins-slave
COPY helm kubectl /usr/bin/
ENTRYPOINT ["jenkins-slave"]
$ docker build -t hub.cropy.cn/library/jenkins-slave-jdk:1.8 .
$ docker push hub.cropy.cn/library/jenkins-slave-jdk:1.8
ejemplo de compilación de jenkins-slave
- Configure pipeline-demo: implica tres parámetros de selección: NS (espacio de nombre), SVC (nombre de microservicio publicado), RS (número de copia publicada)
- Configurar canalización
// Uses Declarative syntax to run commands inside a container.
pipeline {
agent {
kubernetes {
label "jenkins-slave"
yaml '''
apiVersion: v1
kind: Pod
metadata:
name: jenkins-slave
spec:
containers:
- name: jnlp
image: hub.cropy.cn/library/jenkins-slave-jdk:1.8
'''
}
}
stages {
stage('第一步: 拉取代码') {
steps {
echo "Code Clone ${SVC}"
}
}
stage('第二步: 代码编译') {
steps {
echo "code build ${SVC}"
}
}
stage('第三步: 构建镜像') {
steps {
echo "build image ${SVC}"
}
}
stage('第四部: 发布到k8s平台') {
steps {
echo "deploy ${NS},replica: ${RS}"
}
}
}
}
- Ejecutar prueba
Construya el sistema JenkinsCI basado en kubernetes
Referencia de sintaxis de canalización
! [image-20200919150817707] (/ Users / wanghui / Library / Application Support / typora-user-images / image-20200919150817707.png)
Genere automáticamente una gramática maravillosa basada en el contenido seleccionado
Crear certificación
- certificación gitlab
- certificación portuaria
- autenticación de kubernetes kubeconfig
# 1. 使用ansible部署的k8s集群,可以在master找到原先的ansible-install-k8s目录,需要拷贝ca
$ mkdir ~/kubeconfig_file && cd kubeconfig_file
$ vim admin-csr.json
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "system:masters",
"OU": "System"
}
]
}
$ cp ~/ansible-install-k8s/ssl/k8s/ca* ./
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
# 2. 创建kubeconfig文件
# 设置集群参数
kubectl config set-cluster kubernetes \
--server=https://192.168.56.11:6443 \
--certificate-authority=ca.pem \
--embed-certs=true \
--kubeconfig=config
# 设置上下文参数
kubectl config set-context default \
--cluster=kubernetes \
--user=cluster-admin \
--kubeconfig=config
# 设置默认上下文
kubectl config use-context default --kubeconfig=config
# 设置客户端认证参数
kubectl config set-credentials cluster-admin \
--certificate-authority=ca.pem \
--embed-certs=true \
--client-key=admin-key.pem \
--client-certificate=admin.pem \
--kubeconfig=config
Crea una configuración personalizada
Copie la configuración de configuración de k8s en el contenido de la configuración
Cambio de configuracion
#!/usr/bin/env groovy
// 所需插件: Git Parameter/Git/Pipeline/Config File Provider/kubernetes/Extended Choice Parameter
// 公共
def registry = "hub.cropy.cn"
// 项目
def project = "microservice"
def git_url = "http://192.168.56.17:9999/root/microservice.git"
def gateway_domain_name = "gateway.ctnrs.com"
def portal_domain_name = "portal.ctnrs.com"
// 认证
def image_pull_secret = "registry-pull-secret"
def harbor_registry_auth = "05a90138-03df-4ec7-bfc6-f335566c263a"
def git_auth = "1e6ac63f-3646-4385-b4a3-da8114013945"
// ConfigFileProvider ID
def k8s_auth = "16904ea6-9724-4364-bffb-394f7af1d881"
pipeline {
agent {
kubernetes {
label "jenkins-slave"
yaml """
apiVersion: v1
kind: Pod
metadata:
name: jenkins-slave
spec:
containers:
- name: jnlp
image: "${registry}/library/jenkins-slave-jdk:1.8"
imagePullPolicy: Always
volumeMounts:
- name: docker-cmd
mountPath: /usr/bin/docker
- name: docker-sock
mountPath: /var/run/docker.sock
- name: maven-cache
mountPath: /root/.m2
volumes:
- name: docker-cmd
hostPath:
path: /usr/bin/docker
- name: docker-sock
hostPath:
path: /var/run/docker.sock
- name: maven-cache
hostPath:
path: /tmp/m2
"""
}
}
parameters {
gitParameter branch: '', branchFilter: '.*', defaultValue: '', description: '选择发布的分支', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH'
extendedChoice defaultValue: 'none', description: '选择发布的微服务', \
multiSelectDelimiter: ',', name: 'Service', type: 'PT_CHECKBOX', \
value: 'gateway-service:9999,portal-service:8080,product-service:8010,order-service:8020,stock-service:8030'
choice (choices: ['ms', 'demo'], description: '部署模板', name: 'Template')
choice (choices: ['1', '3', '5', '7'], description: '副本数', name: 'ReplicaCount')
choice (choices: ['ms'], description: '命名空间', name: 'Namespace')
}
stages {
stage('拉取代码'){
steps {
checkout([$class: 'GitSCM',
branches: [[name: "${params.Branch}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]
])
}
}
stage('代码编译') {
// 编译指定服务
steps {
sh """
mvn clean package -Dmaven.test.skip=true
"""
}
}
stage('构建镜像') {
steps {
withCredentials([usernamePassword(credentialsId: "${harbor_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
sh """
docker login -u ${username} -p '${password}' ${registry}
for service in \$(echo ${Service} |sed 's/,/ /g'); do
service_name=\${service%:*}
image_name=${registry}/${project}/\${service_name}:${BUILD_NUMBER}
cd \${service_name}
if ls |grep biz &>/dev/null; then
cd \${service_name}-biz
fi
docker build -t \${image_name} .
docker push \${image_name}
cd ${WORKSPACE}
done
"""
configFileProvider([configFile(fileId: "${k8s_auth}", targetLocation: "admin.kubeconfig")]){
sh """
# 添加镜像拉取认证
kubectl create secret docker-registry ${image_pull_secret} --docker-username=${username} --docker-password=${password} --docker-server=${registry} -n ${Namespace} --kubeconfig admin.kubeconfig |true
# 添加私有chart仓库
helm repo add --username ${username} --password ${password} myrepo http://${registry}/chartrepo/${project}
"""
}
}
}
}
stage('Helm部署到K8S') {
steps {
sh """
echo "deploy"
"""
}
}
}
}
Pipeline integra helm para lanzar proyectos de microservicios
Subir gráfico al puerto
helm push ms-0.1.0.tgz --username=admin --password=Harbor12345 http://hub.cropy.cn/chartrepo/microservice
Configurar la liberación automática del timón
La tubería es la siguiente:
#!/usr/bin/env groovy
// 所需插件: Git Parameter/Git/Pipeline/Config File Provider/kubernetes/Extended Choice Parameter
// 公共
def registry = "hub.cropy.cn"
// 项目
def project = "microservice"
def git_url = "http://192.168.56.17:9999/root/microservice.git"
def gateway_domain_name = "gateway.ctnrs.com"
def portal_domain_name = "portal.ctnrs.com"
// 认证
def image_pull_secret = "registry-pull-secret"
def harbor_registry_auth = "05a90138-03df-4ec7-bfc6-f335566c263a"
def git_auth = "1e6ac63f-3646-4385-b4a3-da8114013945"
// ConfigFileProvider ID
def k8s_auth = "16904ea6-9724-4364-bffb-394f7af1d881"
pipeline {
agent {
kubernetes {
label "jenkins-slave"
yaml """
apiVersion: v1
kind: Pod
metadata:
name: jenkins-slave
spec:
containers:
- name: jnlp
image: "${registry}/library/jenkins-slave-jdk:1.8"
imagePullPolicy: Always
volumeMounts:
- name: docker-cmd
mountPath: /usr/bin/docker
- name: docker-sock
mountPath: /var/run/docker.sock
- name: maven-cache
mountPath: /root/.m2
volumes:
- name: docker-cmd
hostPath:
path: /usr/bin/docker
- name: docker-sock
hostPath:
path: /var/run/docker.sock
- name: maven-cache
hostPath:
path: /tmp/m2
"""
}
}
parameters {
gitParameter branch: '', branchFilter: '.*', defaultValue: '', description: '选择发布的分支', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH'
extendedChoice defaultValue: 'none', description: '选择发布的微服务', \
multiSelectDelimiter: ',', name: 'Service', type: 'PT_CHECKBOX', \
value: 'gateway-service:9999,portal-service:8080,product-service:8010,order-service:8020,stock-service:8030'
choice (choices: ['ms', 'demo'], description: '部署模板', name: 'Template')
choice (choices: ['1', '3', '5', '7'], description: '副本数', name: 'ReplicaCount')
choice (choices: ['ms'], description: '命名空间', name: 'Namespace')
}
stages {
stage('拉取代码'){
steps {
checkout([$class: 'GitSCM',
branches: [[name: "${params.Branch}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]
])
}
}
stage('代码编译') {
// 编译指定服务
steps {
sh """
mvn clean package -Dmaven.test.skip=true
"""
}
}
stage('构建镜像') {
steps {
withCredentials([usernamePassword(credentialsId: "${harbor_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
sh """
docker login -u ${username} -p '${password}' ${registry}
for service in \$(echo ${Service} |sed 's/,/ /g'); do
service_name=\${service%:*}
image_name=${registry}/${project}/\${service_name}:${BUILD_NUMBER}
cd \${service_name}
if ls |grep biz &>/dev/null; then
cd \${service_name}-biz
fi
docker build -t \${image_name} .
docker push \${image_name}
cd ${WORKSPACE}
done
"""
configFileProvider([configFile(fileId: "${k8s_auth}", targetLocation: "admin.kubeconfig")]){
sh """
# 添加镜像拉取认证
kubectl create secret docker-registry ${image_pull_secret} --docker-username=${username} --docker-password=${password} --docker-server=${registry} -n ${Namespace} --kubeconfig admin.kubeconfig |true
# 添加私有chart仓库
helm repo add --username ${username} --password ${password} myrepo http://${registry}/chartrepo/${project}
"""
}
}
}
}
stage('Helm部署到K8S') {
steps {
sh """
common_args="-n ${Namespace} --kubeconfig admin.kubeconfig"
for service in \$(echo ${Service} |sed 's/,/ /g'); do
service_name=\${service%:*}
service_port=\${service#*:}
image=${registry}/${project}/\${service_name}
tag=${BUILD_NUMBER}
helm_args="\${service_name} --set image.repository=\${image} --set image.tag=\${tag} --set replicaCount=${replicaCount} --set imagePullSecrets[0].name=${image_pull_secret} --set service.targetPort=\${service_port} myrepo/${Template}"
# 判断是否为新部署
if helm history \${service_name} \${common_args} &>/dev/null;then
action=upgrade
else
action=install
fi
# 针对服务启用ingress
if [ \${service_name} == "gateway-service" ]; then
helm \${action} \${helm_args} \
--set ingress.enabled=true \
--set ingress.host=${gateway_domain_name} \
\${common_args}
elif [ \${service_name} == "portal-service" ]; then
helm \${action} \${helm_args} \
--set ingress.enabled=true \
--set ingress.host=${portal_domain_name} \
\${common_args}
else
helm \${action} \${helm_args} \${common_args}
fi
done
# 查看Pod状态
sleep 10
kubectl get pods \${common_args}
"""
}
}
}
}
Publicar de la siguiente manera
La verificación es la siguiente (vista de clúster de k8s):
kubectl get pod -n ms
NAME READY STATUS RESTARTS AGE
eureka-0 1/1 Running 3 2d23h
eureka-1 1/1 Running 3 2d23h
eureka-2 1/1 Running 3 2d23h
ms-gateway-service-659c8596b6-t4hk7 0/1 Running 0 48s
ms-order-service-7cfc4d4b74-bxbsn 0/1 Running 0 46s
ms-portal-service-655c968c4-9pstl 0/1 Running 0 47s
ms-product-service-68674c7f44-8mghj 0/1 Running 0 47s
ms-stock-service-85676485ff-7s5rz 0/1 Running 0 45s
Configurar jenkinsfile de jenkins en gitlab
Principio: lea el archivo de canalización en gitlab a través de jenkins para lograr el control de versiones para lograr la automatización