+-------------------------------------------------------+
| Kubernetes Cluster |
| |
| +--------------------+ +--------------------+ |
| | | | | |
| | Control Plane | | Worker Nodes | |
| | | | | |
| | +--------------+ | | +--------------+ | |
| | | API Server | | | | Kubelet | | |
| | +--------------+ | | +--------------+ | |
| | | | | |
| | +--------------+ | | +--------------+ | |
| | | Scheduler | | | | Kube-proxy | | |
| | +--------------+ | | +--------------+ | |
| | | | | |
| | +--------------+ | | +--------------+ | |
| | | Controller | | | | Container | | |
| | | Manager | | | | Runtime | | |
| | +--------------+ | | +--------------+ | |
| | | | | |
| | +--------------+ | | | |
| | | etcd | | | | |
| | +--------------+ | | | |
| +--------------------+ +--------------------+ |
+-------------------------------------------------------+
API Server (kube-apiserver):
Scheduler (kube-scheduler):
Controller Manager (kube-controller-manager):
etcd:
Kubelet:
Kube-proxy:
Container Runtime:
# Cài đặt Minikube trên Linux
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
chmod +x minikube
sudo mv minikube /usr/local/bin/
# Khởi động cluster
minikube start
# Kiểm tra trạng thái
minikube status
# Linux
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
# Kiểm tra phiên bản
kubectl version --client
# 1. Cài đặt container runtime (ví dụ: Docker)
# 2. Cài đặt kubeadm, kubelet và kubectl
apt-get update
apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
add-apt-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
apt-get update
apt-get install -y kubelet kubeadm kubectl
# 3. Khởi tạo control plane
kubeadm init --pod-network-cidr=10.244.0.0/16
# 4. Cấu hình kubectl cho user
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 5. Cài đặt network plugin (ví dụ: Calico)
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
# 6. Join worker nodes
# Sử dụng lệnh từ output của kubeadm init
kubeadm join <control-plane-ip>:<port> --token <token> --discovery-token-ca-cert-hash <hash>
# Kiểm tra trạng thái các nodes
kubectl get nodes
# Kiểm tra các pods trong namespace kube-system
kubectl get pods -n kube-system
# Kiểm tra phiên bản server và client
kubectl version
Contexts và Clusters:
# Liệt kê contexts
kubectl config get-contexts
# Chuyển đổi context
kubectl config use-context my-cluster
# Xem cấu hình hiện tại
kubectl config view
Các file cấu hình quan trọng:
/etc/kubernetes/
: Chứa cấu hình của cluster~/.kube/config
: Cấu hình của kubectl/etc/systemd/system/kubelet.service.d/
: Cấu hình kubeletRoles và RBAC (Điều khiển truy cập dựa trên vai trò):
# Tạo Role
kubectl create role pod-reader --verb=get,list,watch --resource=pods
# Tạo RoleBinding
kubectl create rolebinding read-pods --role=pod-reader --user=jane
# Kiểm tra quyền
kubectl auth can-i list pods --as jane
Namespace:
# Tạo namespace
kubectl create namespace my-namespace
# Liệt kê namespaces
kubectl get namespaces
# Thực hiện lệnh trong namespace cụ thể
kubectl get pods -n my-namespace
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
- name: log-sidecar
image: busybox
command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
volumeMounts:
- name: logs-volume
mountPath: /var/log/nginx
volumes:
- name: logs-volume
emptyDir: {}
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIP
# daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: prometheus-node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
containers:
- name: node-exporter
image: prom/node-exporter
ports:
- containerPort: 9100
# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: "mongodb"
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo:4.4
ports:
- containerPort: 27017
volumeMounts:
- name: data
mountPath: /data/db
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
# cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: backup-database
spec:
schedule: "0 1 * * *" # Mỗi ngày lúc 1 giờ sáng
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: mybackup:1.0
command: ["/bin/sh", "-c", "backup.sh"]
restartPolicy: OnFailure
# Tạo từ file YAML
kubectl apply -f deployment.yaml
# Cập nhật image
kubectl set image deployment/nginx-deployment nginx=nginx:1.20
# Rollback
kubectl rollout undo deployment/nginx-deployment
# Scale
kubectl scale deployment/nginx-deployment --replicas=5
# Xóa
kubectl delete deployment nginx-deployment
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- port: 80
targetPort: 8080
type: ClusterIP
Truy cập từ bên ngoài qua <NodeIP>:<NodePort>
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # Port 30000-32767
type: NodePort
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: database.example.com
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: backend
ports:
- protocol: TCP
port: 5432
# Kiểm tra service
kubectl get svc my-service
# Debug DNS
kubectl run -i --tty --rm debug --image=busybox -- sh
# Trong container debug
nslookup my-service
# Kiểm tra endpoints
kubectl get endpoints my-service
# Xem network policies
kubectl get networkpolicies
apiVersion: v1
kind: Pod
metadata:
name: cache-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: cache-volume
mountPath: /cache
volumes:
- name: cache-volume
emptyDir: {}
apiVersion: v1
kind: Pod
metadata:
name: log-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: log-volume
mountPath: /var/log/nginx
volumes:
- name: log-volume
hostPath:
path: /var/log/pods
type: DirectoryOrCreate
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-storage
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: standard
hostPath:
path: /data/pv0001
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-storage-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: standard
apiVersion: v1
kind: Pod
metadata:
name: db-pod
spec:
containers:
- name: db
image: postgres:13
volumeMounts:
- name: db-data
mountPath: /var/lib/postgresql/data
volumes:
- name: db-data
persistentVolumeClaim:
claimName: db-storage-claim
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
fsType: ext4
reclaimPolicy: Delete
allowVolumeExpansion: true
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: db-snapshot
spec:
volumeSnapshotClassName: csi-hostpath-snapclass
source:
persistentVolumeClaimName: db-storage-claim
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: "postgres"
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:13
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "standard"
resources:
requests:
storage: 10Gi
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.host: "mysql"
database.port: "3306"
ui.theme: "dark"
config.json: |
{
"log_level": "info",
"debug": false,
"features": {
"billing": true,
"notifications": false
}
}
Biến môi trường:
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: nginx
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: database.port
envFrom - tất cả keys làm biến môi trường:
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: nginx
envFrom:
- configMapRef:
name: app-config
Volume mount:
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
# Giá trị phải ở dạng base64
username: YWRtaW4= # admin
password: c2VjcmV0 # secret
# Tạo từ file
kubectl create secret generic ssl-cert --from-file=cert.pem --from-file=key.pem
# Tạo từ literal
kubectl create secret generic api-keys --from-literal=api_key=123456 --from-literal=secret_key=abcdef
Biến môi trường:
apiVersion: v1
kind: Pod
metadata:
name: db-client
spec:
containers:
- name: app
image: myapp
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
Volume mount:
apiVersion: v1
kind: Pod
metadata:
name: db-client
spec:
containers:
- name: app
image: myapp
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-credentials
apiVersion: v1
kind: Secret
metadata:
name: docker-registry-cred
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64-encoded-docker-config>
apiVersion: v1
kind: Pod
metadata:
name: private-app
spec:
containers:
- name: app
image: myprivate/repo:tag
imagePullSecrets:
- name: docker-registry-cred
# Linux
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# macOS
brew install helm
# Windows
choco install kubernetes-helm
mychart/
Chart.yaml # Thông tin về chart
values.yaml # Giá trị mặc định cho templates
templates/ # Thư mục chứa templates
deployment.yaml
service.yaml
ingress.yaml
_helpers.tpl # Partial templates
charts/ # Charts phụ thuộc
templates/NOTES.txt # Notes hiển thị sau khi cài đặt
apiVersion: v2
name: myapp
version: 1.0.0
description: My Application Helm Chart
type: application
appVersion: "1.0.0"
dependencies:
- name: mysql
version: 8.8.5
repository: https://charts.bitnami.com/bitnami
# Default values
replicaCount: 2
image:
repository: nginx
tag: 1.19.0
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: false
hosts:
- host: chart-example.local
paths: ["/"]
apiVersion: apps/v1
kind: Deployment
metadata:
name: { { include "myapp.fullname" . } }
labels: { { - include "myapp.labels" . | nindent 4 } }
spec:
replicas: { { .Values.replicaCount } }
selector:
matchLabels: { { - include "myapp.selectorLabels" . | nindent 6 } }
template:
metadata:
labels: { { - include "myapp.selectorLabels" . | nindent 8 } }
spec:
containers:
- name: { { .Chart.Name } }
image: ":"
imagePullPolicy: { { .Values.image.pullPolicy } }
ports:
- name: http
containerPort: 80
protocol: TCP
# Tìm kiếm charts
helm search hub wordpress
# Thêm repository
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# Cài đặt chart
helm install my-release bitnami/wordpress
# Xem các releases đã cài đặt
helm list
# Kiểm tra trạng thái
helm status my-release
# Nâng cấp release
helm upgrade my-release bitnami/wordpress --values=custom-values.yaml
# Rollback
helm rollback my-release 1
# Gỡ cài đặt
helm uninstall my-release
# Tạo chart mới
helm create mychart
# Kiểm tra cấu trúc chart
helm lint mychart
# Đóng gói chart
helm package mychart
# Cài đặt chart local
helm install my-app ./mychart
# Cài đặt với custom values
helm install my-app ./mychart -f my-values.yaml
# Quote
app:
# Default
replicas:
# Indent
data:
# toYaml
labels:
# if/else
# ingress configuration
pre-install
, post-install
pre-delete
, post-delete
pre-upgrade
, post-upgrade
pre-rollback
, post-rollback
test
apiVersion: batch/v1
kind: Job
metadata:
name: -db-init
annotations:
"helm.sh/hook": post-install
"helm.sh/hook-weight": "0"
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
spec:
containers:
- name: db-init
image: postgres
command: ["psql", "--command", "CREATE DATABASE app"]
restartPolicy: Never
Xây dựng hệ thống microservices hoàn chỉnh và triển khai trên Kubernetes cluster, với các thành phần:
⬅️ Trở lại: DEVOPS/Docker2.md | 🏠 Home | ➡️ Tiếp theo: Tổng kết