11 KiB
11 KiB
Kubernetes Deployment - Detailed Reference
Detailed configurations và examples cho Kubernetes deployment trong GoodGo.
Table of Contents
- Complete Deployment Example
- Helm Chart Templates
- Kustomize Configuration
- CI/CD Integration
- Production Configurations
Complete Deployment Example
Namespace
# k8s/base/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: goodgo
labels:
name: goodgo
environment: production
Complete Service Deployment
# k8s/base/iam-service/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: iam-service
namespace: goodgo
labels:
app.kubernetes.io/name: iam-service
app.kubernetes.io/part-of: goodgo
app.kubernetes.io/version: "1.0.0"
spec:
replicas: 3
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: iam-service
template:
metadata:
labels:
app.kubernetes.io/name: iam-service
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: iam-service
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: iam-service
image: goodgo/iam-service:1.0.0
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
ports:
- name: http
containerPort: 8080
protocol: TCP
envFrom:
- configMapRef:
name: iam-config
env:
- name: ConnectionStrings__DefaultConnection
valueFrom:
secretKeyRef:
name: iam-secrets
key: database-url
- name: Jwt__SecretKey
valueFrom:
secretKeyRef:
name: iam-secrets
key: jwt-secret
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
httpGet:
path: /health/startup
port: http
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 30
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: iam-service
topologyKey: kubernetes.io/hostname
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: iam-service
Service Account
# k8s/base/iam-service/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: iam-service
namespace: goodgo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: iam-service-role
namespace: goodgo
rules:
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: iam-service-rolebinding
namespace: goodgo
subjects:
- kind: ServiceAccount
name: iam-service
roleRef:
kind: Role
name: iam-service-role
apiGroup: rbac.authorization.k8s.io
PodDisruptionBudget
# k8s/base/iam-service/pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: iam-service-pdb
namespace: goodgo
spec:
minAvailable: 2
selector:
matchLabels:
app.kubernetes.io/name: iam-service
Helm Chart Templates
Chart.yaml
# charts/goodgo-service/Chart.yaml
apiVersion: v2
name: goodgo-service
description: A Helm chart for GoodGo microservices
type: application
version: 1.0.0
appVersion: "1.0.0"
maintainers:
- name: GoodGo Team
email: team@goodgo.vn
Deployment Template
# charts/goodgo-service/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "goodgo-service.fullname" . }}
labels:
{{- include "goodgo-service.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "goodgo-service.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "goodgo-service.selectorLabels" . | nindent 8 }}
spec:
serviceAccountName: {{ include "goodgo-service.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
{{- if .Values.env }}
env:
{{- toYaml .Values.env | nindent 12 }}
{{- end }}
{{- if .Values.envFromSecret }}
envFrom:
- secretRef:
name: {{ include "goodgo-service.fullname" . }}-secrets
{{- end }}
livenessProbe:
httpGet:
path: {{ .Values.probes.liveness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.liveness.periodSeconds }}
readinessProbe:
httpGet:
path: {{ .Values.probes.readiness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.readiness.periodSeconds }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
Helpers Template
# charts/goodgo-service/templates/_helpers.tpl
{{/*
Expand the name of the chart.
*/}}
{{- define "goodgo-service.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "goodgo-service.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "goodgo-service.labels" -}}
helm.sh/chart: {{ include "goodgo-service.chart" . }}
{{ include "goodgo-service.selectorLabels" . }}
app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "goodgo-service.selectorLabels" -}}
app.kubernetes.io/name: {{ include "goodgo-service.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
Production Values
# charts/goodgo-service/values/production.yaml
replicaCount: 3
image:
repository: gcr.io/goodgo/iam-service
tag: "1.0.0"
pullPolicy: IfNotPresent
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 20
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
hosts:
- host: api.goodgo.vn
paths:
- path: /api/v1/iam
pathType: Prefix
tls:
- secretName: goodgo-tls
hosts:
- api.goodgo.vn
probes:
liveness:
path: /health/live
initialDelaySeconds: 10
periodSeconds: 10
readiness:
path: /health/ready
initialDelaySeconds: 5
periodSeconds: 5
CI/CD Integration
GitHub Actions Deploy
# .github/workflows/deploy.yml
name: Deploy to Kubernetes
on:
push:
branches: [main]
tags: ['v*']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GCR
uses: docker/login-action@v3
with:
registry: gcr.io
username: _json_key
password: ${{ secrets.GCP_SA_KEY }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: ./services/iam-service-net
push: true
tags: gcr.io/goodgo/iam-service:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Set up kubectl
uses: azure/setup-kubectl@v3
- name: Set up Helm
uses: azure/setup-helm@v3
- name: Deploy to Kubernetes
run: |
helm upgrade --install iam-service ./charts/goodgo-service \
--namespace goodgo \
--create-namespace \
--values ./charts/goodgo-service/values/production.yaml \
--set image.tag=${{ github.sha }} \
--wait