文章目录
1. kubernetes常用资源
1.1 deployment资源
有rc在滚动升级之后,会造成服务访问中断。这是因为基于rc滚动升级时其对应的Pod标签会发生变化,想要快速恢复业务,则需要人工手动修改"svc"资源管理的pod标签。于是k8s引入了deployment资源。Deployment是最常见的控制器,用于更高级部署和管理Pod。
deployment相对于rc的优势:
1.服务升级,访问不会中断
2.服务升级不依赖配置文件
[root@k8s-master ~]# mkdir -p /root/k8s_yaml/deployment
[root@k8s-master deployment]# cat 01-deploy.yaml
apiVersion: extensions/v1beta1 # 注意观察这个API的版本编号哟~在后期的版本中其是有变化的!
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
template:
metadata:
labels:
app: dk-nginx
spec:
containers:
- name: nginx
image: 10.0.0.11:5000/nginx:1.13
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 10M
requests:
cpu: 100m
memory: 10M
[root@k8s-master deployment]# kubectl apply -f 01-deploy.yaml
# 创建dePloyment然后会生成rs然后再由rs生成对应的pod,rs是rc的升级加强版
[root@k8s-master deployment]# kubectl get all
# 进行手动升级,直接修改容器版本号即可,直接生效
[root@k8s-master deployment]# kubectl edit deployment nginx
1.2 deployment升级和回滚
[root@k8s-master deployment]# cat 02-deploy.yaml
apiVersion: extensions/v1beta1 # 注意观察这个API的版本编号,在后期的版本中其是有变化的!
kind: Deployment
metadata:
name: nginx
spec:
replicas: 5 # 指定启动Pod的副本数。
strategy: # 指定滚动升级策略
rollingUpdate:
maxSurge: 2 # 在原有的Pod基础上,多启动Pod的数量,假设原来待升级的Pod数量为5,如果我们该值设置为2,表示同时允许启动5 + 2个容器数量。 注意哈,我们也可以指定百分比
maxUnavailable: 1 # 指定最大不可用的Pod数量,如果我们设置该值为1,很明显,副本数为5,表示最少要有4个Pod是可用的。
type: RollingUpdate # 滚动升级
minReadySeconds: 30 # 指定Pod升级的间隔时间,以秒为单位。
template:
metadata:
labels:
app: dk-nginx
spec:
containers:
- name: nginx
image: 10.0.0.101:5000/docker.io/nginx:1.13
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 10M
requests:
cpu: 100m
memory: 10M
(2)应用资源清单
[root@k8s-master deployment]# kubectl apply -f 02-deploy.yaml
deployment "nginx" created
(3)升级Pod
[root@k8s-master deployment]# kubectl set image deployment nginx nginx=10.0.0.11:5000/nginx:1.15
# 命令行创建deployment
kubectl run nginx --image=10.0.0.11:5000/nginx:1.13 --replicas --record
# 命令行升级版本,nginx=指代的是pod中的容器
kubectl set image deployment nginx nginx=10.0.0.11:5000/nginx:1.15
# 查看deployment所有历史版本
kubectl rollout history deployment nginx
# 查看详细的版本
kubectl get rs -o wide
# deployment回滚生一个版本
kubectl rollout undo deployment nginx
# deployment回滚到指定版本
kubectl rollout undo deployment nginx --to-revision=2
1.3 tomcat连接mysql
(1) 启动MySQL实例
[root@k8s-master ~]# vim mysql-rc.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: mysql
spec:
replicas: 1
selector:
app: dk-mysql
template:
metadata:
labels:
app: dk-mysql
spec:
containers:
- name: mysql
image: 10.0.0.101:5000/mysql:5.7
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: '123456'
[root@k8s-master ~]# kubectl apply -f mysql-rc.yml
提示:deployment的yaml文件如下这样写,tomcat的也是这样写的
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql
spec:
replicas: 1
template:
metadata:
labels:
app: dk-mysql
spec:
containers:
- name: mysql
image: 10.0.0.101:5000/mysql:5.7
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: '123456'
(2) 启动MySQL实例的SVC
[root@k8s-master ~]# vim mysql-svc.yml
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
targetPort: 3306
selector:
app: dk-mysql
[root@k8s-master ~]# kubectl apply -f mysql-svc.yml
service "mysql" configured
(3) 启动tomcat实例
[root@k8s-master ~]# cat tomcat-rc.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: dk-web
spec:
replicas: 1
selector:
app: dk-tomcat-app
template:
metadata:
labels:
app: dk-tomcat-app
spec:
containers:
- name: myweb
image: 10.0.0.101:5000/tomcat-app:v1
ports:
- containerPort: 8080
env:
- name: MYSQL_SERVICE_HOST
# 指定MySQL的svc资源的VIP地址即可.kubectl get svc 进行查看mysql的clusterip
# kubectl describe svc mysql查看
value: '10.254.87.39'
- name: MYSQL_SERVICE_PORT
value: '3306'
[root@k8s-master ~]# kubectl apply -f tomcat-rc.yml
replicationcontroller "dk-web" configured
(4) 启动tomcat的实例的svc
[root@k8s-master ~]# cat tomcat-svc.yml
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30008
selector:
app: dk-tomcat-app
[root@k8s-master ~]# kubectl apply -f tomcat-svc.yml
service "myweb" created
[root@k8s-master ~]# kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 15d
mysql 10.254.87.39 <none> 3306/TCP 24m
myweb 10.254.43.201 <nodes> 8080:30008/TCP 8m
温馨提示:
在浏览器访问svc暴露的30008端口就能访问到tomcat,但请注意要访问"http://10.0.0.12:30008/demo/index.jsp"才能进入到下面的界面哟。
2. kubernetes的附加组件
2.1 kubernetes集群配置dns服务
k8s集群中的dns服务的作用就是将svc的名称解析成对应的VIP地址
在kubernetes早期版本中,比如k8s1.5版本中使用的是SkyDNS组件来进行解析,本案例也将采用该版本进行解析哟。但在较新的k8s版本中,CoreDNS已经替代了SkyDNS组件,由于CoreDNS组件得天独厚的优势对于SkyDNS而言简直是降维打击,感兴趣的小伙伴可以自行查阅相关资料进行对比。
在kubernetes 1.9版本中,使用kubeadm方式安装的集群可以通过命令直接安装CoreDNS。即"kubeadm init --feature-getas=CoreDNS=true"。
从kubernetes1.12开始,CoreDNS就成为kubernetes的默认DNS服务器,但是kubeadm默认安装CoreDNS的时间更早。
# 1.下载dns_docker镜像包
# 2.导入dns_docker镜像包(node2节点10.0.0.13)
# 3.修改skydns-rc.yaml,在master节点创建dns服务
spec:
nodeName: 10.0.0.13
containers:
# 4.创建dns服务,两处需要修改
vi skydns-rc.yaml
...
spec:
nodeName: 10.0.0.13
containers:
args:
- --kube-master-url=http://10.0.0.11:8080
# skydns-rc.yaml和skydns-svc.yaml在官网下载
kubectl create -f skydns-rc.yaml
kubectl create -f skydns-svc.yaml
# 5. 检查
kubectl get all --namespace=kube-system
# 6. 修改所有node节点kubelet的配置文件
vim /etc/kubernetes/kubelet
# 10.254.230.254这个ip是在skydns-svc.yaml的clusterIP中写死的
KUBELET_ARGS="--cluster_dns=10.254.230.254 --cluster_domain=cluster.local"
systemctl restart kubelet
# 进行查看
[root@k8s-master ~]# kubectl exec -it dk-web-1912278232-gcxn1 /bin/bash
web-1912278232-gcxn1:/usr/local/tomcat# grep nameserver /etc/resolv.conf
nameserver 10.254.230.254
总结: 在上面的tomcat和mysql例子中,需要在tomcat中指定mysql的vip地址,但是如果mysql的svc重启,这样vip的地址会变。k8s的dns组件服务直接把svc的名称解析成对应的VIP地址,重启svc服务也不会收到影响。
skydns-rc.yaml
[root@k8s-master skydns]# cat skydns-rc.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
spec:
replicas: 1
strategy:
rollingUpdate:
maxSurge: 10%
maxUnavailable: 0
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
spec:
nodeName: 10.0.0.13
containers:
- name: kubedns
image: myhub.fdccloud.com/library/kubedns-amd64:1.9
resources:
limits:
memory: 170Mi
requests:
cpu: 100m
memory: 70Mi
livenessProbe:
httpGet:
path: /healthz-kubedns
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /readiness
port: 8081
scheme: HTTP
initialDelaySeconds: 3
timeoutSeconds: 5
args:
- --domain=cluster.local.
- --dns-port=10053
- --config-map=kube-dns
- --kube-master-url=http://10.0.0.11:8080
env:
- name: PROMETHEUS_PORT
value: "10055"
ports:
- containerPort: 10053
name: dns-local
protocol: UDP
- containerPort: 10053
name: dns-tcp-local
protocol: TCP
- containerPort: 10055
name: metrics
protocol: TCP
- name: dnsmasq
image: myhub.fdccloud.com/library/kube-dnsmasq-amd64:1.4
livenessProbe:
httpGet:
path: /healthz-dnsmasq
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
args:
- --cache-size=1000
- --no-resolv
- --server=127.0.0.1#10053
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
resources:
requests:
cpu: 150m
memory: 10Mi
- name: dnsmasq-metrics
image: myhub.fdccloud.com/library/dnsmasq-metrics-amd64:1.0
livenessProbe:
httpGet:
path: /metrics
port: 10054
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
args:
- --v=2
- --logtostderr
ports:
- containerPort: 10054
name: metrics
protocol: TCP
resources:
requests:
memory: 10Mi
- name: healthz
image: myhub.fdccloud.com/library/exechealthz-amd64:1.2
resources:
limits:
memory: 50Mi
requests:
cpu: 10m
memory: 50Mi
args:
- --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null
- --url=/healthz-dnsmasq
- --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1:10053 >/dev/null
- --url=/healthz-kubedns
- --port=8080
- --quiet
ports:
- containerPort: 8080
protocol: TCP
dnsPolicy: Default # Don't use cluster DNS.
skydns-svc.yaml
[root@k8s-master skydns]# cat skydns-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "KubeDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.254.230.254
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
2.2 namespace命名空间
一个业务,一个单独的namespace
在K8S集群中,一切皆资源。而namespace的作用主要是做资源隔离的。若不为资源指定名称空间,则默认使用的是"default"资源。
一旦有了namespace我们就可以对资源进行分门别类,值得注意的是,在同一个名称空间的同一种资源类型是不能重名的,但不同的名称空间是可以出现同名的资源类型哟。
kubectl get all # 默认查看default命名空间
kubectl get all -n tomcat # 查看tomcat命名空间下的所有资源
kubectl get namespaces # 列出所有的命名空间
kubectl create namespace <namespace_name> # 创建一个命名空间
kubectl get pods -n <namespace_name> #查看命名空间中的资源
kubectl get services -n <namespace_name> # 查看命名空间中的资源
2.3 kubernetes健康检查
常用探针的种类:
livenessProbe:
健康状态检查,周期性检查服务是否存活,检查结果失败,将重启容器。
readinessProbe:
可用性检查,周期性检查服务是否可用,不可用将从service的endpoints中移除。
探针的检测方法:
exec:
执行一段命令,根据返回值判断执行结果。
返回值为0, 非0两种结果,可以理解为"echo $?"。
httpGet:
通过发起HTTTP协议的GET请求检测某个http请求的返回状态码,从而判断服务是否正常。
常见的状态码分为很多类,比如: "2xx,3xx"正常, "4xx,5xx"错误。
200: 返回状态码成功。
301: 永久跳转,会将跳转信息缓存到浏览器本地。
302: 临时跳转,并不会将本次跳转缓存到本地。
401: 验证失败。
403: 权限被拒绝。
404: 文件找不到。
413: 文件上传过大。
500: 服务器内部错误。
502: 无效的请求。
504: 后端应用网关相应超时。
...
tcpSocket:
测试某个TCP端口是否能够连接,类似于telnet这样的工具。
温馨提示: 对于健康检查("livenessProbe")和可用性检查("readinessProbe)是可以同时使用的
2.4.1 健康检查livenessprobo
(1)exec使用
[root@k8s-master ~]# cat nginx_pod_exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: dk-exec # 指定Pod名称
spec:
containers: # 配置容器相关参数
- name: nginx # 指定容器的名称
image: 10.0.0.11:5000/nginx:1.13 # 指定镜像版本
ports:
- containerPort: 80 # 指定暴露容器的端口
args: # 指定容器启动时初始化命令。
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe: # 定义健康检查探针
exec: # 指定探针的检测方法为exec。
command: # 指定exec要执行的命令
- cat
- /tmp/healthy
initialDelaySeconds: 5 # 一定要大于服务的正常启动的时间
periodSeconds: 10 # 指定每次周期的健康检查的间隔时间。
timeoutSeconds: 5 # 指定执行exec定义命令的超时的秒数。
successThreshold: 1 # 检查1次成功就认为服务是健康的。
failureThreshold: 3 # 检查连续3次失败就认为服务是不健康的。
温馨提示: 当我们手动启动Pod后,可以执行"kubectl describe pod dk-exec"指令来查看Pod的运行情况。很明显每次Pod被kill掉并重新被创建其对应的重启次数会进行加1
(2)httpGet使用
[root@k8s-master ~]# cat nginx_pod_httpGet.yaml
apiVersion: v1
kind: Pod
metadata:
name: httpget
spec:
containers:
- name: nginx
image: 10.0.0.11:5000/nginx:1.13
ports:
- containerPort: 80
livenessProbe:
httpGet: # 指定探针的检测方法为httpGet。
path: /index.html # 指定访问的文件路径信息即可,无需指定IP地址,因为默认就是访问本机,可以理解为127.0.0.1。
port: 80 # 指定对容器的哪个端口发送GET请求。
initialDelaySeconds: 3
periodSeconds: 3
温馨提示:
正常情况下,我们启动Pod是并不会触发重启操作的,因此我们需要故意去搞一下破坏,可以进入到容器去删除首页文件,当检测到index.html访问不到时,就会杀死容器重新启动。
如下图所示,我们可以执行"kubectl describe pod httpget"命令进行分析,并观察重启次数会加1
[root@k8s-master ~]# kubectl exec -it httpget bash
httpget:/# ls -l /usr/share/nginx/html/index.html
-rw-r--r-- 1 root root 612 Apr 9 2018 /usr/share/nginx/html/index.html
httpget:/# rm -f /usr/share/nginx/html/index.html
httpget:/# ls -l /usr/share/nginx/html/index.html
ls: cannot access '/usr/share/nginx/html/index.html': No such file or directory
httpget:/# exit
(3)tcpSocket使用
[root@k8s-master ~]# cat nginx_pod_tcpSocket.yaml
apiVersion: v1
kind: Pod
metadata:
name: autumn-tcpsocket
spec:
containers:
- name: nginx
image: 10.0.0.11:5000/nginx:1.13
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- tail -f /etc/hosts
livenessProbe:
tcpSocket:
port: 80 # 检测80端口是否可以连通,若连不通则会抛出检查容器出现问题,而后重启容器。
initialDelaySeconds: 10
periodSeconds: 3
温馨提示:
上述案例暴露了80端口,可惜呀,启动容器时并没有启动nginx,而是去使用tail指令去查看一个文件内容达到阻塞容器的目的,因此在容器启动10后就开始第一次检查,而后每个3秒检查1次,达到指定次数后会触发重启操作,这个失败的次数我们是可以自定义,通过"failureThreshold"参数定义即可。
2.4.2 可用性检查readinessprobe
(1)httpGet使用
[root@k8s-master ~]# cat 04-nginx-rc-httpGet.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: dk-readiness
spec:
replicas: 2
selector:
app: readiness
template:
metadata:
labels:
app: readiness
spec:
containers:
- name: readiness
image: 10.0.0.11:5000/nginx:1.13
ports:
- containerPort: 80
readinessProbe: # 检查服务的可用性
httpGet:
path: /dk.html # 指定检查的路径,若该文件不存在,则容器始终不会启动成功,除非我们手动将其创建哟~
port: 80
initialDelaySeconds: 3
periodSeconds: 3
[root@k8s-master ~]# kubectl expose rc dk-readiness --port=80 --target-port=80 --type=NodePort
service "dk-readiness" exposed
温馨提示:
(1)暴露svc后,记得使用"kubectl describe svc dk-readiness"指令观察"Endpoints"字段信息。
(2)我们可以进入到任意一个Pod中,手动创建"/usr/share/nginx/html/dk.html"文件,pod自动加入svc的endpoint中
2.4 dashboard服务
安装步骤:
(1)上传并导入镜像,打标签
(2)创建dashboard的deployment和service
(3)访问http://10.0.0.11:8080/ui
# (1) deployment资源
[root@k8s-master ~]# cat dashboard.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
# Keep the name in sync with image version and
# gce/coreos/kube-manifests/addons/dashboard counterparts
name: kubernetes-dashboard-latest
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
version: latest
kubernetes.io/cluster-service: "true"
spec:
nodeName: 10.0.0.13 # 需要修改,可以起到优化作用
containers:
- name: kubernetes-dashboard
image: 10.0.0.11:5000/kubernetes-dashboard-amd64:v1.4.1 # 指定镜像的名称
resources:
# keep request = limit to keep this container in guaranteed class
limits:
cpu: 100m
memory: 50Mi
requests:
cpu: 100m
memory: 50Mi
ports:
- containerPort: 9090
args:
- --apiserver-host=http://10.0.0.11:8080 # 指定apiserver的地址
livenessProbe:
httpGet:
path: /
port: 9090
initialDelaySeconds: 30
timeoutSeconds: 30
# (2)编写svc服务
[root@k8s-master ~]# cat dashboard-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kubernetes-dashboard
namespace: kube-system
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/cluster-service: "true"
spec:
selector:
k8s-app: kubernetes-dashboard
ports:
- port: 80
targetPort: 9090
(3) 应用配置文件创建service和deployment资源。
[root@k8s-master ~]# kubectl apply -f .
温馨提示:
我们上面创建的service资源并没有指定类型,则会使用默认的ClusterIP类型。因此我们无法直接通过node节点ip加端口号访问Dashboard的WebUI, 这里直接使用apiserver的IP加端口号/ui来进行访问 http://10.0.0.11:8080/ui
2.5 DaemonSet资源
DaemonSet功能概述:
(1)在每一个Node上运行一个pod;
(2)新加入的Node也同样会自动运行一个Pod;
应用场景:
(1)网络插件(例如kube-proxy,colico);
(2)zabbix agent;
(3)node-export;
(4)日志收集端,例如filebeat;
...
温馨提示:
(1)DaemonSet不支持副本设置哟,其特点是在所有不含污点的工作节点上只运行一个Pod,如果配置了污点容忍也可以在被打污点的工作节点上运行哟;
(2)DaemonSet也支持滚动更新
写一个daemon,没有副本的概念,有几个k8s节点就创建几个pod,大多数用于监控
[root@k8s-master deamonset]# cat 02-deploy.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: nginx
spec:
template:
metadata:
labels:
app: dk2-nginx
spec:
containers:
- name: nginx
image: 10.0.0.11:5000/nginx:1.13
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 10M
requests:
cpu: 100m
memory: 10M
2.6 其他资源
pet sets: 宠物应用,有状态的应用,pod名字固定 01 02 03
statsfulset: 数据库的应用 redis elasticsearch mysql
其他: 畜生应用,无状态的应用 pod名字随机
job: 一次性任务 complate
cronjobs: 定时任务
pod: 一直运行
service: 四层负载均衡
ingress: 七层负载均衡
pvc和pv: 存储
secret: 密码,密钥
config maps: 配置文件
2.7 通过apiserver反向代理访问service
# 第一种: NodePort类型(端口映射和apiserver反向代理都可以访问)
type: NodePort
ports:
- port: 80
targetport: 80
nodePort: 30008
# 第二种: ClusterIP(service没有做端口映射也可以被外界访问,可以使用apiserver反向代理)
type: ClusterIP
port:
- port: 80
targetPort: 80
http://10.0.0.11:8080/api/v1/proxy/namespaces/命名空间/services/service的名字/
http://10.0.0.11:8080/api/v1/proxy/namespaces/default/services/wordpress/
常用命令
创建dePloyment然后会生成rs然后再由rs生成对应的pod
rs是rc的升级加强版
kubectl get all
kubectl edit deployment nginx
kubectl rollout history deploy nginx
kubectl delete deployment nginx
kubectl get rs -o wide
查看内核转发
sysctl -a | grep ipv4 | grep ip_forward
sysctl -a 2>/dev/null | grep ipv4 | grep ip_forward
kubectl scale -n tomcat rc myweb --replicas=2
删除节点
kubectl delete node 10.0.0.12
在重新加入节点
systemctl restart kubelet.service
查看所有命名空间下的svc
kubectl get svc --all-namespaces