JSON到YAML的格式转换:
https://json2yaml.com/convert-yaml-to-json
在生产环境一般使用多MASTER架构,中间要有一个LOADBALANCE,连接到VIP
用HAPROXY做负载均衡
KEEPALIVE:配置VIP,检查节点的状态。
在每一个MASTER节点中部署KEEPAVLIVE,HAPROXY
在MASTER中安装KEEPALIVE:
yum install keepalived
systemctl start keepalived.service
systemctl status keepalived.service
systemctl enable keepalived.service
在master上安装haproxy:
yum install haproxy
systemctl start haproxy
systemctl status haproxy
systemctl enable haproxy
安装kubeadm,kukbectl,kubelet
yum install -y kubelet-1.16.3 kubeadm-1.16.3 kubectl-1.16.3
systemctl enable kubelet
在master1上执行:
kubeadm init --config kubeadmin-config.yaml
查看集群的状态:
kubectl get cs
kubectl get pods -n kube-system
容器调度K8S:
master:APISERVER,SCHEDULER,CONTROLLER-MANAGER
node:KUBELET,PROXY
一般NODE节点的配置要比MASTER高
集群同步状态:
ETCD
ZOOKEEPER
服务发现: ETCD
vi /etc/kubernetes/aipserver
vi /etc/etcd/etcd.conf
node:
vi /etc/kubernetes/kubelet
vi /etc/kubernetes/config
创建一个POD:
vi k8s_pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: web
spec:
containers:
name: nginx
image: nginx
ports:
containerPort: 80
创建:
kubectl create -f k8s_pod.yaml 或者 kubectl apply -f k8s_pod.yaml
apply 表示资源不存在就创建,如果存在就更新。
create 表示没有就创建,有就报错。
查询:
kubectl get pods
kubectl get pods -o wide ----查看更详细的信息
kubectl describe pods
curl http://10.244.3.50 ----访问POD
kubectl delete -f 02-create-pod.yaml ---删除POD
kubectl delete pods nginx ---删除POD
kubectl delete pods pod1
docker load -i pod-infrastructure-latest.tar.gz ---导入镜像
vi /etc/kubernetes/kubelet
systemctl restart kubelet.service
systemctl status kubelet.service
kubectl run nginx-app2 --image=nginx:latest --image-pull-policy=IfNotPresent --replicas=1
kubectl delete pods nginx-app2
kubectl get deployment.apps
kubectl get pods -n kube-system
kubectl get pods --namespace kube-system
kubectl get pods --namespace erp-test ---查看命名空间的内容
kubectl get pods --namespace kube-system
kubectl get service
kubectl get svc
kubectl get nodes
kubectl get namespace
kubectl cluster-info ---检查集群健康状态
kubectl get cs ---检查集群健康状态
kubectl version
kubectl api-resources
kubectl delete ns dev ----删除命名空间
kubectl create namespace test ---创建namespace
kubectl get namespace
kubectl get ns
kubectl get endpoints -n dev ----获取POD的内部访问路径
kubectl describe endpoints service-hello
endpoints 是实现实际服务的端点集合
service ------->endpoints------->POD
NodePort:将service的端口映射到NODE的一个端口
vi 01-create-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test2
kubectl apply -f 01-create-ns.yaml ---应用YAML文件,创建一个NAMESPACE名称为:TEST2
kubectl delete namespace test2 -----删除命名空间
kubectl delete -f 01-create-ns.yaml ---根据资源清单文件来删除NAMESPACE
kubectl delete service nginx-app2-svc
docker pull nginx:latest
cat 02-create-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: nginx-container
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginxport
containerPort: 80
kubectl apply -f 02-create-pod.yaml
cfssl gencert -initca ca-csr.json | cfssl.json -bare ca ----签发证书
kubectl expose deployment web --port=80 --target-port=80 --dry-run -o yaml > service1.yaml ---生成YAML文件
targetPort:容器端口
port:访问service使用端口
service类型:ClusterIP,NodePort,LoadBalancer
ClusterIP:集群内部使用
NodePort:对外访问应用使用
LoadBalancer:对外访问应用使用,此模式需要有外部云环境支持
INGRESS: 把端口号对外暴露,通过IP+端口号进行访问。使用service里面的NodePort来实现。
意味着每个端口只能使用一次,一个端口对应一个应用。
实际访问中都是域名,根据不同域名跳转到不同的端口服务中。
ingress和POD的关系:
POD和ingress通过service关联的。
ingress作为统一入口,由service关联一组POD
入口
ingress ----->service------>pod
----->service------>pod
使用ingress对外暴露应用:
kubectl create deployment web --image=nginx
kubectl get pods
kubectl get deployment
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
kubectl get svc
使用ingress:
1、部署ingress controller
2、创建ingress规则
apiVersion: network.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.ingredemo.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
3、在Windows系统hosts文件中添加域名访问规则
kubectl get ingress
控制器(controler)有几种类型:DaemonSet(守护进程),JOB(一次性任务),CronJob(定时任务),有状态的(StatefulSet),无状态的(deployment)
ReplicaSet(副本集控制器)
DaemonSet能够保证在每个节点都运行一个POD
在每个节点安装数据采集工具:
vi ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-test
labels:
app: filebeat
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
labels:
app: filebeat
spec:
containers:
- name: logs
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: varlog
mountpath: /tmp/log
volumns:
- name: varlog
hostPath:
path: /var/log
kubectl delete statefulset --all ----删除有状态的控制器
kubectl delete svc nginx ---删除Nginx服务
kubectl delete svc web ---删除web服务
kubectl apply -f ds.yaml
kubectl exec -it ds-test-cbk6v -n dev /bin/bash ----进入容器
创建一个一次性任务JOB:
vi testjob.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl","Mbignum=bpi","-wle","print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
kubectl create -f testjob.yaml
kubectl get pods -o wide ---宽泛的显示
kubectl get pods -o json ---以JSON的格式显示
kubectl get pods -o yaml ---以YAML的格式显示
kubectl get jobs
kubectl logs 容器名 ---查看这个容器的日志
kubectl delete -f testjob.yaml
创建一个定时任务:
vi cronjob_test.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date;echo Hello from the kubenetes cluster
restartPolicy: OnFailure
kubectl apply -f conjob_test.yaml
kubectl get cronjobs
Secret:他主要用于存储敏感信息,比如:密码,存储加密数据在ETCD中,让POD容器以挂载VOLUMN的方式访问。
base64编码:
echo -n 'admin' | base64
创建一个secret:
vi secret_test.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: ywaaw4
password: 343eertwyr
kubectl apply -f secret_test.yaml
kubectl get secret
kubectl describe secret -n dev
kubectl exec -it mysecret bash
kubectl delete secret --all
kubectl delete pod --all
configmap主要用来存储配置信息的,用来存储不加密的数据到ETCD,让POD以变量或者VOLUME挂载到容器。
vi configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap
namespace: dev
data:
info:
username: admin
password: 123456
kubectl describe cm configmap -n dev
vi redis.properties
kubectl create configmap redis-config --from-file=redis.properties
kubectl get cm
kubectl describe cm redis-config
vi cm.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox
image: busybox
command: [ "/bin/sh","-c","cat /etc/config/redis.properties" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: redis-config
restartPolicy: Never
kubectl create -f cm.yaml
kubectl logs mypod
YAML的说明:
apiVersion: API版本
kind: 资源类型
metadata: 资源元数据
spec: 资源规格
replicas: 副本数量
selector: 标签选择器
template: POD模板
metadata:POD元数据
spec: POD规则
containers: 容器配置
如何快速编写YAML:
1、使用kubectl create 生成YAML文件
kubectl create deployment web --image=nginx -o yaml --dry-run >my1.yaml
2、使用kubectl get 命令导出yaml文件
kubectl get deploy nginx -o=yaml --export >my2.yaml
https://helm.sh/
Helm Kubernetes 包管理器:
Helm 是包管理器,类似于一个Linux的YUM.
helm三个重要概念:
1、helm是一个命令行客户端工具
2、chart 把YAML打包,是YAML集合
3、release 基于chart部署实例,应用级别的版本管理
V3版本架构:
helm chart---->kube-config---->kube-aipserver----->deplyment,service,ingress
安装HELM:
将文件解压后移动到/usr/bin/下面即可
mv helm /usr/bin
配置HELM仓库
1、添加仓库
helm repo add stable http://mirror.azure.cn/kubernetes/charts
2、helm repo list
3、helm repo update ---更新仓库地址
4、helm repo remove aliyun ---删除仓库
使用HELM快速部署应用:
1、使用命令搜索应用
helm search repo 名称
helm search repo weave
2、根据搜索内容选择安装
helm install 安装之后的名称 搜索的应用名称
helm install ui stable/weave-scope
查看安装之后的状态:
helm list
helm status 安装之后的名称
helm status ui
修改service的YAML文件,将类型改为NodePort:
kubectl edit svc ui-weave-scope
如何创建自己的CHART:
helm create mychart
Chart.yaml: 当前CHART属性配置信息
values.yaml: yaml文件可以使用全局变量
templates: 编写YAML文件放到这个目录中
kubectl create deployment web1 --image=nginx --dry-run -o yaml >deployment.yaml
kubectl expose deployment web1 --port=80 --target-port=80 --type=NodePort --dry-run -o yaml >service.yaml
安装mychart:
helm install web1 mychart/
应用升级:
helm upgrade web1 mychart/
POD重启机制:
restartPolicy:Never
Never: 当容器终止退出,从不重启容器。
Always: 当容器终止退出后,总是重启容器,默认策略。
OnFailure: 当容器异常退出时,才重启容器。
kubectl get pods aaa -n dev -w ----动态显示
容器探测:
livenessProbe: 存活检查探测,决定是否重启容器
readinessProbe: 就绪检查探测,决定是否将请求转发给容器
livenessProbe:
exec:
command:
- cat
- /tmp/healty
livenessProbe:
tcpSocket:
port: 8080
POD实现机制:
1、共享网络
2、共享存储
镜像拉取策略:
imagePullPolicy:
Always: 每次创建POD都会重新拉取一次镜像
Never: POD永远不会主动拉取这个镜像
IfNotPresent: 默认值,镜像在宿主机上不存在时才拉取
POD重启,数据就不存在了,需要对数据进行持久化存储。
EmptyDir就是HOST上的一个空目录,当POD销毁时,EmptyDir中的数据也会被销毁,只能临时存储。EmptyDir中的数据不会被持久化。
申明一个名字是logs-volume 的volume,类型为emptyDir
volumes:
- name: logs-volume
emptyDir: {}
kubectl logs -f pod名称 -n dev -c busybox ----查看指定容器的标准输出
HostPath: 挂载到宿主机上的一个目录,可以永久存储
volumes:
- name: logs-volume
hostPath:
path: /root/logs
type: DirectoryOrCreate #目录存在就使用,不存在就创建
PV:持久化存储,对存储资源进行抽象,对外提供可以调用的地方。
PVC:用于调用,不需要关心内部实现细节。
kubectl scale deploy pc-deployment --replicas=5 -n dev ----变更副本数为5
测试K8S集群功能:
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort ---对外暴露端口
kubectl get pods,svc
访问:http://nodeiP:端口
RBAC 鉴权机制:基于角色的访问控制
1、创建命名空间
kubectl create ns roledemo
2、在新创建的命名空间中创建POD
kubectl run nginx --image=nginx -n roledemo
3、创建角色:
kubectl apply -f rbac-role.yaml
kubectl get role -n roledemo
4、创建角色绑定
kubectl apply -f rbac-rolebinding.yaml
kubectl get role,rolebinding -n roledemo
5、
定向调度:直接将POD调度到指定名称的节点上,这种是强制调度。
nodeName: node1 -----调度到node1上
nodeSelector:
nodeenv: pro
亲和性就是偏好的意思
nodeAffinity :节点亲和性调度,以NODE为目标,解决POD可以调度到哪些NODE的问题
硬亲和性:约束条件必须满足
软亲和性:尝试满足,不保证
podAffinity: POD亲和性,解决POD可以和哪些已存在的POD部署在一起的问题
podAntiAffinity:POD反亲和性,以POD为目标,解决POD不能和哪些POD部署在一起的问题
kubectl get pods --show labels
POD调度:污点,容忍
污点就是拒绝,容忍就是忽略,NODE通过污点拒绝POD调度上去,POD通过容忍忽略拒绝
污点:
NoSchedule: 新的不要来,在这里的就不要动了
PreferNoSchedule:尽量不要来,除非没有办法
NoExcute:新的不要来,在这里的赶紧走
kubectl taint nodes node1 key=value:effect ----设置污点
kubectl taint nodes node1 tag=heima:NoSchedule
kubectl taint nodes node1 key:effect- ----去除污点
kubectl taint nodes node1 tag:PreferNoSchedule-
kubectl taint nodes node1 key- -----去除所有污点
容忍:
tolerations:
- key: "tag"
operator: "Equal"
value: "heima"
effect: "NoEcecute"
无状态控制器:
1、认为POD都是一样的
2、没有顺序要求
3、不用考虑在哪个NODE上运行
4、随意进行伸缩和扩展
有状态控制器:kind: StatefulSet
1、唯一的网络标识符,持久存储
2、有序,比如MYSQL主从
3、让每个POD独立的,保持POD启动顺序和唯一性
部署有状态应用:
无头service:
clusterIP:none
下面这个为无头service:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-statefulset
namespace: default
spec:
serviceName: nginx
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
deployment和statefulset区别:有身份的(唯一标识的)
根据主机名 + 按照一定规则生成域名
每个POD有唯一主机名
K8S部署项目流程(细节过程)
制作镜像----》推送镜像仓库----》控制器部署镜像-----》对外暴露应用----》运维
DockerFile 阿里云 Deployment service,ingress 监控,升级
K8S集群部署JAVA项目:
第一步 准备JAVA项目,把JAVA进行打包(jar包 或者 war包),这一步要开发人员完成
通过maven打包:mvn clean package
第二步 制作镜像
docker build -t java-demo:latest
docker images
docker run -d -p 8111:8111 java-demo:latest -t -----本地启动镜像
第三步 上传镜像到镜像服务器中(阿里云)
第四步 部署镜像,暴露应用
kubectl create deployment javademo1 --image=镜像的名字 --dry-run -o yaml >javademo1.yaml
kubectl apply -f javademo1.yaml
kubectl get pods -o wide
kubectl scale deployment javademo1 --replicas=3 ----扩容,产生3个副本
kubectl expose deployment javademo1 --port=8111 --target-port=8111 --type=NodePort
kubectl get svc
升级策略:
spec:
strategy:
type: Recreate
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSure: 25%
kubectl set image deploy pc-deployment nginx=nginx:1.17.3 -n dev ----升级
版本回退:
kubectl rollout status deploy pc-deployment -n dev ----查看状态
kubectl rollout history deploy pc-deployment -n dev ----查看历史状态
kubectl rollout undo deploy pc-deployment --to-revision=1 -n dev ----回退到第一个版本
HPA控制器,通过监控负载,可以动态调整POD的个数
kubectl top node ------查看资源的使用情况
service kubelet status ----查看状态
kubectl get pods --all-namespaces
K8S监控平台:
prometheus + grafana