上周内容回顾:
- 基于kubeadm部署k8s集群 *****
- Pod的基础管理 ***** 是K8S集群中最小的部署单元。
---> 网络基础容器(pause:v3.1),提供网络
---> 初始化容器(initContainer),做初始化的准备工作
---> 业务容器(containers),实际的业务容器
apiVersion: v1
kind: Pod
metadata:
name: oldboyedu-linux82
labels:
school: oldboyedu
class: linux82
nameSpace: oldboyedu-linux
spec:
imagePullSecret: oldboyedu-harbor
volume:
- name: data01
emptyDir: {}
- name: data02
hostPath:
path: /oldboyedu-linux82/data
- name: data03
nfs:
server: 10.0.0.151
path: /oldboyedu/data/k8s
- name: data03
configMap:
name: nginx.conf
imagePullPolicy: Always
hostNetwork: true
nodeName: k8s151.oldboyedu.com
initContainer:
containers:
- name: linux
image: harbor250.oldboyedu.com/oldboyedu-games/huangjinkuanggong:v0.1
# stdin: true
volumeMount:
- name: data01
mountPath: /oldboyedu-linux82
- name: data03
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
restartPolicy: Always
livenessProbe:
exec:
httpGet:
tcpSocket:
...
readinessProbe:
exec:
httpGet:
tcpSocket:
...
command: ---> docker ---> ENTRYPOINT
args: ---> docker ---> CMD
resources:
limit:
request:
env:
- name: SCHOOL
value: oldboyedu
- name: pod_name
valueFrom:
configMapKeyRef:
fieldRef:
secretKeyRef:
resourceFieldRef
- nameSpace *****
---> 用来隔离k8S集群的资源,通过"kubectl api-resources"的NAMESPACED(true表示支持名称空间哟。)
- configMap *****
---> 用于持久化配置文件。
- secret *****
---> 存储铭感数据,因为其使用了base64编码格式,数据并不是加密的哟!
- rc控制器基础使用 **
---> 控制Pod的副本数量。
- rs控制器基础使用 **
---> 控制Pod的副本数量。相比于rc资源,rs资源实现更加轻量级,功能更丰富。
- deploy控制器基础使用 *****
---> 生产环境中用于部署服务,微服务,无状态服务。
- svc服务发现基础使用 *****
---> 负载均衡和服务发现。
Q1: 请问deploy和rc资源对比,在升级过程中有什么区别?
相同点:
(1)都支持副本的控制;
(2)都支持升级
不同点:
(1)rc资源不支持声明式升级方式,deploy资源支持声明式升级
(2)rc升级过程中,需要手动修改svc的标签选择器字段"selector",deploy资源不需要;
Q2: 请问deploy资源在升级过程中,能否访问到旧的Pod业务呢?为什么?请说明原因?
deploy ---> rs, ---> old
---> rs, ---> new
svc ---> endPoint ---> selector ---> [old,new]
Q3: svc的类型有哪些?其应用场景在哪?
ClusterIP:
集群的IP,仅对K8S集群内部资源提供访问。ingress ---> ing
NodePort:
绑定K8S集群的所有worker节点的端口,优点就是可以让K8S外部用户进行访问,缺点就是费端口!
ExternalName,LoadBalancer:
云环境中使用的一种负载均衡器。
Q4: 请问访问一个Pod服务,有哪些方法,请举例说明?
1.pods.spec.hostNetwork
2.pods.spec.containers.ports.hostPort
3.service.spec.type.NodePort
...
Q5: 如何实现svc的后端服务的流量控制呢?
isito实现流量控制。
Endpoints资源案例:
1.创建MySQL服务
docker run -p 3306:3306 -de MYSQL_ROOT_PASSWORD=123 --name mysql57 k8s151.oldboyedu.com:5000/oldboyedu-db/mysql:5.7
2.添加授权用户
CREATE USER linux82 IDENTIFIED BY 'oldboyedu';
CREATE DATABASE wordpress CHARACTER SET = utf8mb4;
GRANT ALL ON wordpress.* TO linux82;
SHOW GRANTS FOR linux82;
3.测试连接
mysql -u linux82 -poldboyedu wordpress
SHOW TABLES FROM wordpress;
4.创建ep资源映射K8S集群外部的MySQL服务
[root@k8s151.oldboyedu.com v4]# cat 01-ep-mysql.yaml
apiVersion: v1
kind: Endpoints
metadata:
name: mysql-ep-v4
# 指定ep资源的后端服务
subsets:
# IP地址
- addresses:
- ip: 10.0.0.151
# 端口号
ports:
- port: 3306
[root@k8s151.oldboyedu.com v4]#
5.创建和ep资源名称相同的svc,注意,当删除svc时,对应的ep名称也被删除!
[root@k8s151.oldboyedu.com v4]# cat 02-svc-mysql.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-ep-v4
spec:
ports:
- port: 3306
targetPort: 3306
[root@k8s151.oldboyedu.com v4]#
6.WordPress指定数据库的主机地址为svc的名称
[root@k8s151.oldboyedu.com v4]# cat 03-deploy-wordpress.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: oldboyedu-linux82-wordpress-v2
spec:
replicas: 3
selector:
matchLabels:
apps: wordpress
template:
metadata:
name: oldboyedu-linux82-wordpress
labels:
apps: wordpress
spec:
volumes:
- name: wp
nfs:
server: k8s151.oldboyedu.com
path: /oldboyedu/data/kubernetes/wordpress/
containers:
- name: wordpress
image: k8s151.oldboyedu.com:5000/oldboyedu-wordpress/wordpress
env:
- name: WORDPRESS_DB_HOST
# value: 10.254.100.100
# value: mysq57-v3
value: mysql-ep-v4
- name: WORDPRESS_DB_USER
value: linux82
- name: WORDPRESS_DB_PASSWORD
value: oldboyedu
volumeMounts:
- name: wp
mountPath: /var/www/html
[root@k8s151.oldboyedu.com v4]#
7.暴露wordpress服务
[root@k8s151.oldboyedu.com v4]# cat 04-svc-wordpress.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-v3
spec:
type: NodePort
ports:
- port: 9999
targetPort: 80
nodePort: 30080
selector:
apps: wordpress
[root@k8s151.oldboyedu.com v4]#
8.访问WebUI进行测试,并验证数据库的数据
# docker exec mysql57 mysql -u linux82 -poldboyedu -e "SHOW TABLES FROM wordpress\G"
验证Kube-proxy底层默认采用了iptables实现负载均衡
1.查看日志
kubectl get pods -A -o wide| grep kube-system
kubectl -n kube-system logs -f kube-proxy-4tfrj
...
W0913 00:44:22.201735 1 proxier.go:513] Failed to load kernel module ip_vs with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules
W0913 00:44:22.202823 1 proxier.go:513] Failed to load kernel module ip_vs_rr with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules
W0913 00:44:22.203683 1 proxier.go:513] Failed to load kernel module ip_vs_wrr with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules
W0913 00:44:22.204579 1 proxier.go:513] Failed to load kernel module ip_vs_sh with modprobe. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules
W0913 00:44:22.210022 1 server_others.go:249] Flag proxy-mode="" unknown, assuming iptables proxy
I0913 00:44:22.217923 1 server_others.go:143] Using iptables Proxier.
2.验证iptables实现负载均衡
iptables-save | grep 10.254.230.102
iptables-save | grep KUBE-SVC-UCRS5B77IKZZYESP
iptables-save | grep KUBE-SEP-3E7IGDJUY2SRNIHO
iptables-save | grep KUBE-SEP-EO465CXBF2CDSL4W
iptables-save | grep KUBE-SEP-BFMP3WUEAK3XBKUH
使用ipvs替代iptables规则,生产环境中推荐使用ipvs代理模式:
1.所有worker节点安装ipvs的工具包
yum -y install conntrack-tools ipvsadm.x86_64
2.所有worker节点编写加载ipvs的配置文件
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
3.加载ipvs相关模块并查看
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
4.修改kube-proxy的工作模式为ipvs
kubectl -n kube-system edit cm kube-proxy
...
mode: "ipvs"
5.删除所有的Pod(生产环境中,建议一个一个的手动删除,删除后需要确保kube-proxy服务是正常启动滚动,再去删除下一个)
kubectl -n kube-system get pods | grep kube-proxy | awk '{print $1}' | xargs kubectl -n kube-system delete pods
6.验证IPVS是否成功
ipvsadm -ln | grep 10.254.230.102 -A 10 # 注意,此处的IP是svc的VIP地址哟!
修改svc的端口映射范围:
1.修改配置文件
vim /etc/kubernetes/manifests/kube-apiserver.yaml
...
spec:
containers:
- command:
- kube-apiserver
- --service-node-port-range=80-60000 # 进行添加这一行即可
...
2.测试svc
建议使用nginx镜像测试,可以明显看出效果哟。
使用deploy资源部署redis实战:
[root@k8s151.oldboyedu.com redis]# cat 01-deploy-redis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-leader
labels:
app: redis
role: leader
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
role: leader
tier: backend
spec:
containers:
- name: leader
image: "docker.io/redis:6.0.5"
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-leader
labels:
app: redis
role: leader
tier: backend
spec:
type: NodePort
ports:
- port: 6379
targetPort: 6379
nodePort: 6379
selector:
app: redis
role: leader
tier: backend
[root@k8s151.oldboyedu.com redis]#
测试:
kubectl exec -it redis-leader-7df78664-ccqx8 -- bash
# redis-cli
> KEYS * # 查看所有的KEY
> set school oldboyedu # 设置字符串
> GET school # 查看KEY的值
etcd API V3管理实战:
(1)设置别名,便于后续操作。
alias etcdctl='ETCDCTL_API=3 etcdctl --endpoints=https://[127.0.0.1]:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key'
(2)查看集群的成员
etcdctl member list
(3)查看前缀为"/registry/pods/"的所有KEY,对应的是po资源的存储。
etcdctl get --keys-only --prefix /registry/pods/
(4)查看前缀为"/registry/configmaps/"的所有KEY,对应的cm资源的存储。
etcdctl get --keys-only --prefix /registry/configmaps/
(5)查看default名称空间下的某个key的信息,(查询的数据可能是乱码,无需关心,生产环境中直接使用kubectl查看即可)
etcdctl get /registry/pods/default/oldboyedu-linux82-wordpress-v2-5b74b87dd7-4t5r9
(6)删除指定的KEY,此处我删除的是一个名为"redis-leader"的deploy控制器,意味着从etcd数据库删除了数据。[生产环境慎用!]
etcdctl del /registry/deployments/default/redis-leader
coreDNS概述:
coreDNS的作用就是将svc的名称解析为ClusterIP。
早期使用的skyDNS组件,需要单独部署,在k8s 1.9版本中,我们就可以直接使用kubeadm方式安装CoreDNS组件。
从k8s 1.12开始,CoreDNS就成为kubernetes默认的DNS服务器,但是kubeadm支持coreDNS的时间会更早。
推荐阅读:
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/coredns
coreDNS的IP地址:
vim /var/lib/kubelet/config.yaml
...
clusterDNS:
- 10.254.0.10 # 会将该DNS的IP地址写入到容器的"/etc/resolv.conf"文件中哟~
clusterDomain: cluster.local
coreDNS的A记录:
k8s的A记录格式:
<service name>.<namespace name>.svc.cluster.local
参考案例:
kube-dns.kube-system.svc.cluster.local
oldboyedu-mysql.default.svc.cluster.local
温馨提示:
(1)如果部署时直接写svc的名称,不写名称空间,则默认的名称空间为其引用资源的名称空间;
(2)kubeadm部署时,无需手动配置CoreDNS组件(默认在kube-system已创建),二进制部署时,需要手动安装该组件;
测试案例:
1)基于POD测试
# kubectl run test01 --image=alpine -it --rm -- sh
# ping mysql-ep-v4.default.svc.cluster.local
# ping kube-dns.kube-system.svc.cluster.local
2)使用dig测试
yum -y install bind-utils
dig @10.254.0.10 mysql-ep-v4.default.svc.cluster.local +short
dig @10.254.0.10 kube-dns.kube-system.svc.cluster.local +short
今日内容回顾:
- Endpoints ---> ep *****
一般用于将K8S外部的服务映射为K8S集群内部的服务,要求创建和其同名的svc。
当删除svc时,会自动删除其对应的ep资源。
- 部署PHP项目案例,WordPress为例。
架构拆分
deploy,nfs,svc,coreDNS,...
- kube-proxy的调度模式切换为ipvs,默认使用iptables.
- 修改nodePort的端口范围
- etcd的基础使用(了解即可)
- coreDNS组件
将svc的名称解析为ClusterIP。
Q1: master组件全部挂掉,svc的类型为NodePort,请问已经部署的服务能否正常访问?为什么?请说明原因。
Q2: 当kube-proxy组件挂掉,svc的类型为NodePort,请问已经部署的服务能够正常访问?为什么?请说明原因。
今日作业:
(1)完成课堂的所有练习;
(2)将phpadmin项目部署到K8S集群;
扩展作业:
(1)调研isito服务的基础使用;