官方文档:https://kubernetes.io/zh-cn/docs/home/
部署k8s集群
集群部署方式
kubeadmin
minikube
Docker内置的Kubernetes
二进制安装包
购买云厂商的容器服务(阿里云 - ACK、亚马逊云 - EKS、腾讯云 - TKE)
部署步骤
略
Kubectl
# linux安装kubectl
sudo curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.28.3/2023-11-14/bin/linux/amd64/kubectl
sudo chmod +x ./kubectl
sudo mkdir -p $HOME/bin && sudo cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
sudo echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
# window安装docker时已经安装kubectl,此处略
# 验证
kubectl version
# 帮助命令
kubectl -h
# kubectl rollout SUBCOMMAND [options]
KubeConfig
# 文件路径 $HOME/.kube/config
# 查看kube-config示例:
cat $HOME/.kube/config
apiVersion: v1
clusters:
- cluster:
server: https://192.168.100.210:6443
certificate-authority-data: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
name: kubernetes-dev
contexts:
- context:
cluster: kubernetes-dev
user: "dev-admin"
name: dev
current-context: dev
kind: Config
preferences: {}
users:
- name: "dev-admin"
user:
token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# kubectl查看kube-config(如果已经安装kubectl,推荐使用)
kubectl config view
# 查看所有上下文
kubectl config get-contexts
# 查看当前上下文
kubectl config current-context
# 切换上下文
kubectl config use-context dev
# 帮助命令
kubectl config -h
Namespace
# 命令模式创建
kubectl create ns test-ns
# yaml模式创建
apiVersion: v1
kind: Namespace
metadata:
name: test-ns
# 查看namespace
kubectl get ns
# 删除namespace
kubectl delete ns test-ns
注:删除namespace时,该namespace下所有资源都会删除,如:secret、configmap、deployment、pod、service、ingress等
Secret
创建Secret
# 命令模式创建
kubectl create secret generic test-secret --from-literal=username=zs --from-literal=password=123456
kubectl create secret generic test-secret --from-file=username=./username.txt --from-file=password=./password.txt
# yaml模式创建
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: zs
password: "666666"
TZ: Asia/Shanghai
stringData:
config.yaml: |
apiUrl: "https://my.api.com/api/v1"
username: <user>
password: <password>
type: Opaque
# 查看secret
kubectl get secret -n default
kubectl get secret test-secret -o jsonpath='{.data}'
使用Secret
# deploy或pod使用secret
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: Always
ports:
- name: http
containerPort: 80
protocol: TCP
# 环境变量方式
env:
- name: TZ
valueFrom:
secretKeyRef:
name: test-secret
key: TZ
# 挂载数据卷的方式
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: test-secret
optional: true
Docker-Secret
# 创建secret
kubectl create secret docker-registry image-repository --docker-server=registry.cn-shanghai.aliyuncs.com --docker-username=xxx --docker-password=xxx
# deployment或pod中使用secret
spec:
imagePullSecrets:
- name: image-repository
TLS-Secret
# 命令模式创建
kubectl create secret tls tls-secret --cert=file.crt --key=file.key
# yaml模式创建
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
# 值为 base64 编码,这样会掩盖它们,但不会提供任何有用的机密性级别
tls.crt: |
LS0tLS1CRUdJT*******************************NQTBHQ1NxR1NJYjNERklDQVRFLS0tLS0K
# 在这个例子中,密钥数据不是真正的 PEM 编码的私钥
tls.key: |
RXhhbXBsZSBkYX************************IGNydCBmaWVsZA
# ingress使用secret
spec:
tls:
- hosts:
- xxx.xxx.com
secretName: tls-secret
不可更改的Secret
apiVersion: v1
kind: Secret
metadata:
name: test-secret
# data...
immutable: true
ConfigMap
创建ConfigMap
# 创建configmap
apiVersion: v1
kind: ConfigMap
metadata:
name: test-cm
data:
# 类属性键;每一个键都映射到一个简单的值
username: "zs"
password: "666666"
# 类文件键
config.properties: |
username=zs
password="666666"
# 查看configmap
kubectl get cm -n default
使用ConfigMap
# deploy或pod使用configmap
spec:
containers:
- name: alpine
image: alpine
command: ["sleep", "3600"]
env:
# 定义环境变量
- name: my_username # 请注意这里和 ConfigMap 中的键名是不一样的
valueFrom:
configMapKeyRef:
name: test-cm # 这个值来自 ConfigMap
key: username # 需要取值的键
- name: my_password
valueFrom:
configMapKeyRef:
name: test-cm
key: password
volumeMounts:
- name: config
mountPath: "/etc/alpine/config"
readOnly: true
# 你可以在 Pod 级别设置卷,然后将其挂载到 Pod 内的容器中
volumes:
- name: config
configMap:
name: test-cm # 提供你想要挂载的 ConfigMap 的名字
# 来自 ConfigMap 的一组键,将被创建为文件
items:
- key: "config.properties"
path: "config.properties"
Deployment
# 命令方式创建
kubectl create deployment nginx --image=nginx -n default
# yaml方式创建
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default #非必填,默认default
labels:
app: nginx
service: nginx
spec:
replicas: 1 #非必填,默认1
selector:
matchLabels:
service: nginx
template:
metadata:
labels:
app: nginx
service: nginx
logging: "true" # 一定要具有该标签才会被采集日志
annotations: # 特定注解(示例:集成dapr)
dapr.io/enabled: "true"
dapr.io/app-id: nginx
dapr.io/app-port: "80"
dapr.io/config: "dapr-config"
dapr.io/http-max-request-size: "512"
dapr.io/sidecar-cpu-request: "10m"
dapr.io/sidecar-memory-request: "32Mi"
spec:
imagePullSecrets:
- name: image-repository
containers:
- name: nginx
image: nginx # 对应的latest镜像版本,如果是某个版本 image:tag,如 nginx:1.19.8
# 镜像拉取策略
imagePullPolicy:
- name: Always
# Always(默认策略): 如果kubelet有一个容器镜像,并且对应的摘要已在本地缓存,kubelet 就会使用其缓存的镜像; 否则,kubelet 就会使用解析后的摘要拉取镜像,并使用该镜像来启动容器。
# IfNotPresent: 只有当镜像在本地不存在时才会拉取。
# Never: Kubelet不会尝试获取镜像。如果镜像已经以某种方式存在本地, kubelet 会尝试启动容器;否则,会启动失败。
ports:
- name: http
containerPort: 80
protocol: TCP
envFrom:
- configMapRef:
name: test-cm
- secretRef:
name: test-secret
env:
# {{- toYaml .Values.envVariables | nindent 12 }} #从helm的values.yaml中加载环境变量
- name: TZ
valueFrom:
secretKeyRef:
name: test-secret
key: TZ
# 使用就绪探针进行健康检查
readinessProbe:
httpGet:
path: /Healthz
port: 80
initialDelaySeconds: 10 # 10秒钟后开始进行健康检查
periodSeconds: 30 # 周期:每30秒进行一次健康检查
resources:
# {{- toYaml .Values.resources | nindent 12 }} #从helm的values.yaml中加载resources
# limits:
# cpu: 100m
# memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
# 查看deployment
kubectl get deploy -n default
# 重启应用
kubectl rollout restart deploy nginx -n default
# 查看历史版本
kubectl rollout history deploy nginx -n default
kubectl rollout history deploy nginx -n default --revision=1
# 版本回滚
kubectl rollout undo deploy nginx -n default
kubectl rollout undo deploy nginx -n default --to-revision=2
# 伸缩pod
kubectl scale deploy nginx -n default -n default --replicas=3
# 删除deployment
kubectl delete deploy nginx -n default
Service
# 命令方式创建
kubectl expose deployment nginx --port=80 --type=NodePort -n default
# ClusterIP:此默认 Service 类型从你的集群中为此预留的 IP 地址池中分配一个 IP 地址。在创建 Service 的请求中,你可以通过设置 spec.clusterIP 字段来指定自己的集群 IP 地址。
# NodePort: Kubernetes 控制平面将在 --service-node-port-range 标志所指定的范围内分配端口(默认值:30000-32767)。 每个节点将该端口(每个节点上的相同端口号)上的流量代理到你的 Service。 你的 Service 在其 .spec.ports[*].nodePort 字段中报告已分配的端口。
# LoadBalance:为 Service 提供负载均衡器。 负载均衡器的实际创建过程是异步进行的,关于所制备的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段公开出来。
# yaml方式创建
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
labels:
app: nginx
service: nginx
# annotations:
# service.beta.kubernetes.io/xxx: xxx
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
selector:
service: nginx
# 查看service
kubectl get svc -n default
# 删除service
kubectl delete svc nginx -n default
Ingress
# 创建ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # 强制重定向到 HTTPS
nginx.ingress.kubernetes.io/proxy-body-size: "500M" # 限制请求数据的大小
# 其他注解示例(aws)
# kubernetes.io/ingress.class: alb
# alb.ingress.kubernetes.io/xxx: xxx
spec:
tls:
- hosts:
- xxx.xxx.com
secretName: tls-secret
rules:
- host: xxx.xxx.com
http:
paths:
- path: /
pathType: ImplementationSpecific
# ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者作与 Prefix 或 Exact 类型相同的处理。
# Exact:精确匹配 URL 路径,且区分大小写。
# Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写, 并且对路径中各个元素逐个执行匹配操作。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配。
backend:
service:
name: nginx # 对应的后台服务名称
port:
number: 80 # # 对应的后台服务端口
# 查看ingress
kubectl get ing -n default
# 删除service
kubectl delete ing nginx -n default