K8s 高可用集群(十六)
coredns的部署
基于二进制kubernetes集群中的CoreDNS部署
wget -O coredns.yaml.sed https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/coredns.yaml.sed
vim coredns.yaml
apiVersion:v1
kind:ServiceAccount
metadata:
name:coredns
namespace:kube-system
---
apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRole
metadata:
labels:
kubernetes.io/bootstrapping:rbac-defaults
name:system:coredns
rules:
-apiGroups:
-""
resources:
-endpoints
-services
-pods-namespaces
verbs:
-list
-watch
-apiGroups:-discovery.k8s.io
resources:
-endpointslices
verbs:
-list
-watch
---
apiVersion:rbac.authorization.k8s.io/v1
kind:ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate:"true"
labels:
kubernetes.io/bootstrapping:rbac-defaults
name:system:coredns
roleRef:
apiGroup:rbac.authorization.k8s.io
kind:ClusterRole
name:system:corednssubjects:
-kind:ServiceAccount
name:coredns
namespace:kube-system
---
apiVersion:v1
kind:ConfigMap
metadata:
name:coredns
namespace:kube-system
data:
Corefile:|
.:53{
errors
health{
lameduck5s
}
readyready
#此处CLUSTER_DOMAIN修改cluster.local,REVERSE_CIDRS修改为in-addr.arpa
ip6.arpa
kubernetes cluster.local in-addr.arpa ip6.arpa { #【修改1】替换CLUSTER_DOMAIN REVERSE_CIDRS
fallthroughin-addr.arpaip6.arpa
}
prometheus:9153
forward . /etc/resolv.conf { #【修改2】替换UPSTREAMNAMESERVER
#此处UPSTREAMNAMESERVER修改为
/etc/resolv.conf
max_concurrent1000
}
cache30
loop
reload
loadbalance
}STUBDOMAINS
---
apiVersion:apps/v1
kind:Deployment
metadata:
name:coredns
namespace:kube-systemlabels:
k8s-app:kube-dns
kubernetes.io/name:"CoreDNS"
spec:
#replicas:notspecifiedhere:
#1.Defaultis1.
#2.WillbetunedinrealtimeifDNShorizontalauto-scalingisturnedon.
replicas:2#添加此行为多副本,默认为1
strategy:
type:RollingUpdate
rollingUpdate:
maxUnavailable:1
selector:
matchLabels:
k8s-app:kube-dns
template:
metadata:
labels:
k8s-app:kube-dnsspec:
priorityClassName:system-cluster-critical
serviceAccountName:coredns
tolerations:
-key:"CriticalAddonsOnly"
operator:"Exists"
nodeSelector:
kubernetes.io/os:linux
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
-labelSelector:
matchExpressions:
-key:k8s-app
operator:In
values:["kube-dns"]
topologyKey:kubernetes.io/hostnamecontainers:
-name:coredns
image:coredns/coredns:1.9.4
imagePullPolicy:IfNotPresent
resources:
limits:
memory:170Mi#此处的资源限制修改为合适的值,比如:4096Mi
requests:
cpu:100m#此处的资源限制修改为合适的值
memory:70Mi#此处的资源限制修改为合适的值
args:["-conf","/etc/coredns/Corefile"]
volumeMounts:
-name:config-volume
mountPath:/etc/coredns
readOnly:true
ports:
-containerPort:53
name:dnsprotocol:UDP
-containerPort:53
name:dns-tcp
protocol:TCP-containerPort:9153
name:metrics
protocol:TCP
securityContext:
allowPrivilegeEscalation:false
capabilities:
add:
-NET_BIND_SERVICE
drop:
-all
readOnlyRootFilesystem:true
livenessProbe:
httpGet:
path:/health
port:8080
scheme:HTTP
initialDelaySeconds:60
timeoutSeconds:5successThreshold:1
failureThreshold:5
readinessProbe:
httpGet:
path:/ready
port:8181
scheme:HTTP
dnsPolicy:Default
volumes:
-name:config-volume
configMap:
name:coredns
items:
-key:Corefile
path:Corefile---
apiVersion:v1
kind:Service
metadata:
name:kube-dns
namespace:kube-system
annotations:
prometheus.io/port:"9153"
prometheus.io/scrape:"true"
labels:
k8s-app:kube-dns
kubernetes.io/cluster-service:"true"
kubernetes.io/name:"CoreDNS"
spec:
selector:
k8s-app:kube-dns
clusterIP:10.96.0.2 #【修改3】替换CLUSTER_DNS_IP
#修改此处为kube-dnsSVC的地址,比如:10.96.0.10,可通过查看
Pod的/etc/resolv.conf获取ports:
-name:dns
port:53
protocol:UDP
-name:dns-tcp
port:53
protocol:TCP-name:metrics
port:9153
protocol:TCP
#应用创建coredns的Pod
kubectl apply -f coredns.yaml
coredns解析内部服务的原理解析
1.Pod 域名请求发至 kube-dns ServiceIP,路由到 CoreDNS Pod。
2.CoreDNS 依靠 RBAC 权限持续监听 Service、EndpointSlice 资源。
3.kubernetes插件拦截.cluster.local域名:
匹配内部服务域名,直接返回 ClusterIP / 后端 PodIP;
fallthrough:反向解析查不到数据,则流转下一插件。
4.非集群域名(外网域名),流转至forward转发上游 DNS。
5.cache 缓存解析结果,loadbalance 随机打乱多记录实现简易轮询
pod配置
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
.:53:监听全部域名,53 端口提供 DNS 服务
errors:打印 DNS 查询错误日志
health:提供健康检测接口;lameduck 5s,关闭前等待 5s 处理存量请求
ready:提供就绪探测接口
kubernetes:处理集群内部域名;cluster.local 集群域名后缀;支持正反解析;fallthrough 反向解析未命中交给后续插件
prometheus :9153:9153 端口输出监控指标
forward:外部域名转发上游 DNS,读取宿主机 resolv.conf;限制最大并发查询 1000
cache 30:解析结果缓存 30 秒
loop:检测阻断 DNS 循环转发
reload:Corefile 变更自动加载
loadbalance:多条 A 记录随机返回,实现简易轮询
案例
配置CoreDNS的域名解析转发至指定的DNS Server
#创建集群外的DNS
安装部署dns
#!/bin/bash
# install_dns.sh 安装bind9主DNS服务器 Ubuntu24.04
set -e
DOMAIN="wang.org"
NS_MASTER="master"
NS_IP="10.0.0.200"
# 1.安装软件
apt update
apt install -y bind9 bind9utils bind9-doc
# 2.修改全局配置 /etc/bind/named.conf.local
cat > /etc/bind/named.conf.local <<EOF
zone "$DOMAIN" {
type master;
file "/etc/bind/$DOMAIN.zone";
};
EOF
# 3.生成区域解析文件
cat > /etc/bind/${DOMAIN}.zone <<EOF
\$TTL 1D
@ IN SOA $NS_MASTER admin (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS $NS_MASTER
$NS_MASTER A $NS_IP
www A 10.0.0.200
harbor A 10.0.0.100
test A 6.6.6.6
a A 1.1.1.1
b A 2.2.2.2
EOF
# 4.权限
chown bind:bind /etc/bind/${DOMAIN}.zone
# 5.语法校验
named-checkconf
named-checkzone $DOMAIN /etc/bind/${DOMAIN}.zone
# 6.重启服务
systemctl restart bind9
systemctl enable bind9
echo "DNS bind9 部署完成!"
echo "测试命令:nslookup www.$DOMAIN 127.0.0.1"
bashinstall_dns.sh
cat > /etc/bind/wang.org.zone <<'EOF'
$TTL 1D
@ IN SOA master admin (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS master
master A 10.0.0.200
www A 10.0.0.200
harbor A 10.0.0.100
test A 6.6.6.6
a A 1.1.1.1
b A 2.2.2.2
EOF
chown bind:bind /etc/bind/wang.org.zone
生效
rndc reload
.:53{
errors
health{
lameduck5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure #【新增】允许解析pod主机域名
fallthrough in-addr.arpa ip6.arpa
ttl 30 #【新增】内部域名解析TTL设置30秒
}
prometheus :9153
forward wang.org 10.0.0.200{ #【新增】wang.org域名转发至自建DNS10.0.0.200
prefer_udp
}
forward . /etc/resolv.conf{
max_concurrent 1000
}
cache 30{ #【修改】扩展cache配置
disable success cluster.local #关闭集群域名正向缓存
disable denial cluster.local #关闭集群域名否定缓存
}
loop
reload
loadbalance
}
重新创建coredns的Pod生效
kubectl rollout restart deployment -n kube-system coredns
kubectl run client-test-$RANDOM --image registry.cn-beijing.aliyuncs.com/wangxiaochun/admin-box:v0.1 --restart=Never --rm -it --command -- /bin/bash
root@client-test-908/# host a.wang.org
a.wang.org has address 1.1.1.1
root@client-test-908/# host b.wang.org
b.wang.org has address 2.2.2.2
#复现异常
Host b.wang.org not found: 3(NXDOMAIN)
Host a.wang.org not found: 3(NXDOMAIN)
部署ingress nginx控制器
基于YAML部署
基于kubectl apply部署
[root@master1~]#VERSION=1.15.1
wget https://raw.githubusercontent.com/kubernetes/ingress-
nginx/controller-v${VERSION}/deploy/static/provider/cloud/deploy.yaml
#修改三处image地址指向国内镜像地址
[root@master1~]#vim deploy.yaml
#1 controller
#image:registry.k8s.io/ingress-nginx/controller:v11.14.3@sha256:ac444cd9515af325ba577b596fe4f27a34be1aa330538e8b317ad9d6c8fb94ee
image:registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.14.3
#2 certgen第一处
#image:registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.7@sha256:7a38cf0f8480775baaee71ab519c7465fd1dfeac66c421f28f087786e631456e
image:registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.6.7
#3 certgen第二处
#image:registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.7@sha256:7a38cf0f8480775baaee71ab519c7465fd1dfeac66c421f28f087786e631456e
image:registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.6.7
应用资源配置文件
[root@master1~]#kubectl apply -f deploy.yaml
查看ingress-nginx-controller的Pod运行在哪个节点上
[root@master1~]#kubectl get pod -A -o wide | grep ingress-nginx-controller
确认效果
[root@master1~]#kubectl get ns
生成IngressClass
[root@master1~]#kubectl get ingressclass
查看secret
[root@master1~]#kubectl get secrets -n ingress-nginx
[root@master1~]#kubectl get secrets -n ingress-nginx ingress-nginx-admission -
o yaml
kubectl get ep -n ingress-nginx
NAME ENDPOINTS AGE
ingress-nginx-controller 10.244.1.126:443,10.244.1.126:80 13m
ingress-nginx-controller-admission 10.244.1.126:8443 13m
curl 10.0.0.101:32699
#返回:400 Bad Request,明文HTTP请求访问HTTPS端口,流量到达ingress-nginx
直接获取状态码
curl -I -o /dev/null -s -w %{http_code}"\n" 10.0.0.101:32453
返回状态码:404
#流量抵达ingress-nginx,无匹配Ingress规则
查看访问日志
kubectl logs -f -n ingress-nginx ingress-nginx-controller-548b8cb9b8-tsxpl
#作用:实时查看ingress-nginx控制器运行日志,排查访问异常
案例
子URL访问
命令式实现单域名支持子URL
#添加/*,支持子URL,如果有URL则转发至Pod对应相同的URL
kubectl create ingress demo-ingress \
--rule="hao123.com/*=my-svc:80" \
--class=nginx \
-o yaml --dry-run=client
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: demo-ingress
spec:
ingressClassName: nginx
rules:
- host: hao123.com
http:
paths:
- path: /(.*)
pathType: Prefix
backend:
service:
name: my-svc
port:
number: 80
status:
loadBalancer: {}
创建
kubectl create ingress demo-ingress \
--rule="hao123.com/*=pod-test1:80" \
--class=nginx
kubectl get ingress -n default
查看
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: "2021-05-28T01:36:20Z"
generation: 1
name: demo-ingress
namespace: default
resourceVersion: "1502354"
uid: 0938aeda-0ea6-4235-a032-3a6adb0e2174
spec:
ingressClassName: nginx
rules:
- host: hao123.com
http:
paths:
- backend:
service:
name: pod-test1
port:
number: 80
path: /(.*)
pathType: Prefix
status:
loadBalancer: {}
kubectl get ingress demo-ingress -o yaml
客户端访问测试
curl -H "host:hao123.com" 10.0.0.99
curl -H "host:hao123.com" 10.0.0.99/hostname
蓝绿发布
基于 Service Selector 的蓝绿发布
当前在线版本:蓝(Blue)
新版本:绿(Green)
部署新版本 Pod(绿),和老版本(蓝)同时运行
测试验证绿色版本业务正常
修改 Service,流量全部切到绿色
业务稳定后,按需删除蓝色旧版本
核心:靠 Service 标签选择器切换流量,无需 Ingress 改动
环境说明
现有业务:pod-test1(蓝色老版本) 新建绿色版本:pod-test2(新版本)
Service 名称:svc-test Ingress:
demo-ingress 绑定 svc-test
蓝部署 yaml blue.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-test-blue
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: pod-test
version: blue
template:
metadata:
labels:
app: pod-test
version: blue
spec:
containers:
- name: pod-test
image: xxx:v1 # 老镜像v1
ports:
- containerPort: 80
部署
kubectl apply -f blue.yaml
Service(初始指向蓝版本)svc.yaml
apiVersion: v1 kind: Service metadata: name: svc-test namespace: default spec: selector: app: pod-test version: blue # 当前流量走向:蓝 ports: - port: 80 targetPort: 80 type: ClusterIP
kubectl apply -f svc.yaml
Ingress(之前配置好的,不用改动)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
namespace: default
spec:
ingressClassName: nginx
rules:
- host: hao123.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-test
port:
number: 80
kubectl apply -f ingress-demo.yaml
客户端 → Ingress → svc-test → label version=blue Pod(老版本)
部署绿色新版本 green.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-test-green
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: pod-test
version: green
template:
metadata:
labels:
app: pod-test
version: green
spec:
containers:
- name: pod-test
image: xxx:v2 # 新版本镜像v2
ports:
- containerPort: 80
kubectl apply -f green.yaml
此时:蓝 Pod、绿 Pod同时运行,但是流量依旧全部走蓝。
单独测试绿色版本
流量切换:修改 Service 标签,切到绿色
编辑 svc.yaml,selector 改为 version: green
spec:
selector:
app: pod-test
version: green
更新生效
kubectl apply -f svc.yaml
验证业务
curl -H "Host:hao123.com" 10.0.0.101:32453
两种情况
情况 A:新版本一切正常 → 清理旧版本
kubectl delete -f blue.yaml
情况 B:新版本出问题 → 快速回滚
kubectl apply -f svc.yaml
快速查看状态
# 查看两个deployment
kubectl get deploy
# 查看service标签选择器
kubectl describe svc svc-test
# 查看哪些Pod被service选中
kubectl get endpoints svc-test
Ingress 切换后端实现蓝绿发布
逻辑:两套独立 Deployment + 两个独立 Service svc-blue(老版本 / 蓝)、svc-green(新版本 / 绿)Service、Deployment 不动,只修改 Ingress 后端指向谁实现流量切换
Ingress 始终绑定同一个域名,切换不用改客户端
客户端 → hao123.com(Ingress) →【切换目标】svc-blue /svc-green → Pod
蓝环境(老版本)blue.yaml
apiVersion: apps/v1
kind: Deployment
name: pod-test-blue
spec:
replicas: 2
selector:
matchLabels:
app: pod-test
ver: blue
template:
metadata:
labels:
app: pod-test
ver: blue
spec:
containers:
- name: web
image: v1镜像
ports:
- containerPort:80
kubectl apply -f blue.yaml
蓝对应的 Service svc-blue.yaml
apiVersion: v1
kind: Service
name: svc-blue
spec:
selector:
app: pod-test
ver: blue
ports:
- port:80
targetPort:80
kubectl apply -f svc-blue.yaml
绿环境(新版本)green.yaml
apiVersion: apps/v1
kind: Deployment
name: pod-test-green
spec:
replicas: 2
selector:
matchLabels:
app: pod-test
ver: green
template:
metadata:
labels:
app: pod-test
ver: green
spec:
containers:
- name: web
image: v2新版本镜像
ports:
- containerPort:80
kubectl apply -f green.yaml
绿对应的 Service svc-green.yaml
apiVersion: v1
kind: Service
name: svc-green
spec:
selector:
app: pod-test
ver: green
ports:
- port:80
targetPort:80
kubectl apply -f svc-green.yaml
初始 Ingress:流量指向蓝(正式对外使用)ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
name: demo-ingress
spec:
ingressClassName: nginx
rules:
- host: hao123.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-blue # 当前指向蓝
port:
number: 80
验证
curl -H "Host:hao123.com" 10.0.0.101:32453
测试新版本
kubectl create ingress test-green --rule="test.hao123.com/*=svc-green:80" --class=nginx
流量全量切换到绿色(修改 Ingress service 名称)
修改 ingress.yaml 中 service.name: svc-blue → svc-green
backend:
service:
name: svc-green
port:
number: 80
更新生效
kubectl apply -f ingress.yaml
验证流量已经切新版本
curl -H "Host:hao123.com" 10.0.0.101:32453
故障回滚操作
把 Ingress 改回 svc-blue,再次 apply,立刻切回老版本
业务稳定后清理
kubectl delete -f blue.yaml
kubectl delete -f svc-blue.yaml
两种蓝绿方案对比
修改 Service selector 切换流量
优点:Ingress 固定不变
缺点:只能一个 Service
修改 Ingress 后端切换 Service
优点:两套 Service 完全隔离;多域名、多路径场景更灵活
缺点:需要维护两个 Service
更多推荐
所有评论(0)