3.k8s的附件组件
孙富阳, 江湖人称没人称。多年互联网运维工作经验,曾负责过孙布斯大规模集群架构自动化运维管理工作。擅长Web集群架构与自动化运维,曾负责国内某大型博客网站运维工作。
1.dns服务
1.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的时间更早。
推荐阅读:
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/coredns
2.DNS服务组件安装
下载镜像组件
[root@k8s-node-1 ~]# wget www.buyao007.icu/sfy-docker-skydns.tar.gz
[root@k8s-node-2 ~]# docker load -i sfy-docker-skydns.tar.gz
[root@k8s-master dns]# wget www.buyao007.icu/skydns-yaml.tar.gz
[root@k8s-master dns]# tar xf skydns-yaml.tar.gz
修改官方的yaml文件
[root@k8s-master dns]# vim 01-skydns.yaml
···
spec:
nodeName: k8s102.com # 让容器指定调度到某一个节点。
containers:
···
args:
···
# 指定ApiServer的地址,请一定要指定IP地址,不要指定主机名,因为容器的"/etc/hosts"并未解析!
- --kube-master-url=http://10.0.0.110:8080
skydns的工作原理:
Pod如果需要解析域名时会找DNS组件进行解析,如果DNS有记录则会直接返回给Pod相应的映射关系。如果DNS本地解析并没有记录,则DNS组件会向ApiServer发起查询请求,请求对应SVC暴露的IP地址与对应Pod的关联关系
[root@k8s-master dns]# vim 02-skydns-svc.yaml
...
spec:
...
clusterIP: 10.254.254.254
温馨提示:
修改SVC的IP地址本质上修改是后期暴露的DNS地址
运行DNS的相关Pod,观察是否调度到指定的节点
[root@k8s-master dns]# kubectl apply -f .
[root@k8s-master dns]# kubectl get pod -o wide -n kube-system
[root@k8s-master dns]# kubectl get svc -o wide -n kube-system
可以看到创建了指定的svc,pod也被调度到了指定节点

修改kubelet,指定自定义的DNS地址
vim /etc/kubernetes/kubelet
...
# 指定集群的DNS地址及域名信息,所谓的DNS地址指的就是DNS的Pod其SVC暴露的CLUSTER-IP地址哟~
KUBELET_ARGS="--cluster_dns=10.254.254.254 --cluster_domain=cluster.local"
[root@k8s-node-1 ~]# systemctl restart kubelet.service
3.验证DNS服务是否正常
注意在解析svc域名的时候,相同命名空间的可以直接写svc的名字,不同命名空间要写<svc-name>.<svc-namespace-name>.svc.cluster.local
同时因为namespace隔离性,svc和后端代理的节点应该在一个namespace空间
[root@k8s-master deployment]# cat deploy-wordpress2.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: k8s-master:5000/mysql:5.7
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: somewordpress
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: wordpress
---
apiVersion: v1
kind: Service #简称svc
metadata:
name: musql-svc
namespace: kube-system
spec:
clusterIP: 10.254.86.101
type: ClusterIP
ports:
- port: 3306
targetPort: 3306 #pod port
selector:
app: mysql
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: wordpress
spec:
replicas: 1
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: k8s-master:5000/wordpress:latest
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: musql-svc.kube-system.svc.cluster.local ###这里写的svc的域名
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: wordpress
---
apiVersion: v1
kind: Service #简称svc
metadata:
name: wordpress-svc
spec:
type: NodePort
ports:
- port: 80
nodePort: 31001
targetPort: 80 #pod port
selector:
app: wordpress
2.namespace命名空间
1.namespace的作用
在K8S集群中,一切皆资源。而namespace的作用主要是做资源隔离的。
若不为资源指定名称空间,则默认使用的是"default"资源。
一旦有了namespace我们就可以对资源进行分门别类,值得注意的是,在同一个名称空间的同一种资源类型是不能重名的,但不同的名称空间是可以出现同名的资源类型哟
删除一个namespace时,这意味着该名称空间下的所有资源都将被删除,生产环境中请谨慎使用
2.创建namespace资源
###基于命令行创建
[root@k8s-master ~]# kubectl create namespace sfy
###基于yaml编写资源清单
[root@k8s-master namespace]# vim sfy-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: sfy1
[root@k8s-master namespace]# kubectl apply -f sfy-namespace.yaml

3.健康检查和可用性检查探针(Probe)
1.探针的种类和作用
livenessProbe:健康状态检查,周期性检查服务是否存活,检查结果失败,将重启容器
readinessProbe:可用性检查,周期性检查服务是否可用,不可用将从service的endpoints中移除
2.探针的检测方法
exec:执行一段命令 返回值为0, 非0
httpGet:检测某个 http 请求的返回状态码 2xx,3xx正常, 4xx,5xx错误
tcpSocket:测试某个端口是否能够连接
3.liveness探针的exec使用
[root@k8s-master k8s_yaml]# mkdir check
[root@k8s-master k8s_yaml]# cd check/
[root@k8s-master check]# cat nginx_pod_exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: exec
spec:
containers:
- name: nginx
image: k8s-master:5000/sunfuyang/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次失败就认为服务是不健康的
[root@k8s-master check]# kubectl create -f nginx_pod_exec.yaml
我们可以通过describe查看pod检查失败重启了一次

4.liveness探针的httpGet使用
[root@k8s-master check]# cat nginx_pod_httpGet.yaml
apiVersion: v1
kind: Pod
metadata:
name: httpget
spec:
containers:
- name: nginx
image: k8s-master:5000/sunfuyang/nginx:1.13
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 3
periodSeconds: 3
[root@k8s-master check]# kubectl create -f nginx_pod_httpGet.yaml
[root@k8s-master check]# kubectl exec -it httpget bash
root@httpget:/# rm -f /usr/share/nginx/html/index.html
root@httpget:/# exit
可以看到当进入容器删掉检查的文件时,容器重启了一次

5.liveness探针的tcpSocket使用
[root@k8s-master check]# cat nginx_pod_tcpSocket.yaml
apiVersion: v1
kind: Pod
metadata:
name: tcpsocket
spec:
containers:
- name: nginx
image: k8s-master:5000/sunfuyang/nginx:1.13
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- tail -f /etc/hosts
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 10
periodSeconds: 3
[root@k8s-master check]# kubectl create -f nginx_pod_tcpSocket.yaml
很明显,暴露了80端口,可是启动容器时并没有启动nginx,而是去使用tail指令去查看一个文件内容达到阻塞容器的目的,因此在容器启动10后就开始第一次检查,而后每个3秒检查1次,达到指定次数后会触发重启操作

6.readiness探针的httpGet使用
[root@k8s-master check]# cat nginx-rc-httpGet.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: readiness
spec:
replicas: 2
selector:
app: readiness
template:
metadata:
labels:
app: readiness
spec:
containers:
- name: readiness
image: k8s-master:5000/sunfuyang/nginx:1.13
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /sfy.html
port: 80
initialDelaySeconds: 3
periodSeconds: 3
[root@k8s-master check]# kubectl apply -f nginx-rc-httpGet.yaml
[root@k8s-master check]# kubectl expose rc readiness --port=80 --target-port=80 --type=NodePort
可以看到pod不健康,svc后端节点为空

此时进入容器创建对应的健康检查的文件
[root@k8s-master check]# kubectl exec -it readiness-9qwnx bash
root@readiness-9qwnx:/# touch /usr/share/nginx/html/sfy.html
root@readiness-9qwnx:/# exit
此时发现创建文件的节点被加入了svc的后端节点

4.dashboard服务
1.dashboard概述
dashboard可以将K8S集群的操作封装成WebUI进行操作。不仅如此,我们还可以对其进行角色访问控制
2.安装dashboard服务
##上传镜像
wget www.buyao007.icu/kubernetes-dashboard-amd64.tar
docker load -i kubernetes-dashboard-amd64.tar
###修改dashboard的yaml文件
[root@k8s-master k8s_yaml]# mkdir dashboard
[root@k8s-master k8s_yaml]# cd dashboard/
wget www.buyao007.icu/dashboard-yaml.tar.gz
[root@k8s-master dashboard]# cat 01-deploy-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: k8s-node-2
containers:
- name: kubernetes-dashboard
image: k8s-master:5000/sunfuyang/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.101:8080
livenessProbe:
httpGet:
path: /
port: 9090
initialDelaySeconds: 30
timeoutSeconds: 30
[root@k8s-master dashboard]# cat 02-deyloy-dashboard-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kubernetes-dashboard
namespace: kube-system
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/cluster-service: "true"
school: "BeiJing_ShangHai_ShenZhen"
spec:
type: NodePort
selector:
k8s-app: kubernetes-dashboard
ports:
- port: 80
targetPort: 9090
nodePort: 30886
3.访问dashboard的WebUI

除了通过nodeport访问以外还可以通过apiserver反向代理访问
浏览器输入10.0.0.11:8080/ui会自动跳转

5.通过apiserver反向代理访问service
1.分析通过apiserver反向代理访问service
我们以dashboard服务为例,分析通过apiserver反向代理访问service如下:
(1)带有锚点的URL(其中以"#"之后的所有内容均为锚点)
http://k8s.com:8080/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard/#/workload?namespace=default
(2)找出真实的URL,如下所示:
http://k8s.com:8080/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard
(3)分析通过apiserver反向代理访问service的语法格式
http://apiserver:8080/api/v1/proxy/namespaces/<Pod资源所在的名称空间>/services/<暴露Pod资源的service名称>
温馨提示:
尽管我们没有对service配置NodePort,但我们可以通过apiserver反向代理访问service,但这样的话URL会很长,因此建议大家还是使用NodePort类型对外提供访问,这样对用户来说比较友好
2.测试
访问地址:
http://10.0.0.11:8080/api/v1/proxy/namespaces/default/services/wordpress/
发现和使用nodeport访问效果一样

未经允许不得转载:孙某某的运维之路 » 3.k8s的附件组件
评论已关闭