kubernetes-2
Kubernetes 中的域名是如何解析的
从Kubernetes 1.11版本开始,Kubernetes集群的DNS服务由CoreDNS提供。CoreDNS是CNCF基金会的一个项目,是用Go语言实现的高性能、插件式、易扩展的DNS服务端。CoreDNS解决了KubeDNS的一些问题,例如dnsmasq的安全漏洞、externalName不能使用stubDomains设置.
作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,这就需要一个集群范围内的DNS服务来完成从服务名到ClusterIP的解析。
CoreDNS支持自定义DNS记录及配置upstream DNS Server,可以统一管理Kubernetes基于服务的内部DNS和数据中心的物理DNS。
CoreDNS没有使用多个容器的架构,只用一个容器便实现了KubeDNS内3个容器的全部功能。
在 Kubernetes 中,比如服务 a 访问服务 b,对于同一个 Namespace下,可以直接在 pod 中,通过 curl b 来访问。对于跨 Namespace 的情况,服务名后边对应 Namespace即可。比如 curl b.default。
kubernetes中的域名解析流程
在 Kubernetes 中,服务发现有几种方式:
①:基于环境变量的方式
②:基于内部域名的方式
基本上,使用环境变量的方式很少,主要还是使用内部域名这种服务发现的方式。
其中,基于内部域名的方式,涉及到 Kubernetes 内部域名的解析,而 kubedns,是 Kubernetes 官方的 DNS 解析组件。从 1.11 版本开始,kubeadm 已经使用第三方的 CoreDNS 替换官方的 kubedns 作为 Kubernetes 集群的内部域名解析组件。
1.kubernetes内部署Coredns和官方Dashboard
1.1 Coredns
下载官方kubernetes二进制包 传送门
分别下载:
Source Code
: [kubernetes.tar.gz](https://dl.k8s.io/v1.24.0/kubernetes.tar.gz)
Client Binaries
: [kubernetes-client-linux-amd64.tar.gz](https://dl.k8s.io/v1.24.0/kubernetes-client-linux-amd64.tar.gz)
Server Binaries
: [kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.24.0/kubernetes-server-linux-amd64.tar.gz)
Node Binaries
: [kubernetes-node-linux-amd64.tar.gz](https://dl.k8s.io/v1.24.0/kubernetes-node-linux-amd64.tar.gz)
# tar xf <kuebrnetes-xx.tar.gz>
解压会在同一个目录下kubernetes
# cd /kubernetes/cluster/addons/dns
# cp kube-dns.yaml.base kube-dns.yaml
#cat coredns.yaml
# __MACHINE_GENERATED_WARNING__
apiVersion: v1
kind: ServiceAccount
metadata:
name: coredns
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
kubernetes.io/bootstrapping: rbac-defaults
addonmanager.kubernetes.io/mode: Reconcile
name: system:coredns
rules:
- apiGroups:
- ""
resources:
- endpoints
- services
- pods
- namespaces
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- 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
addonmanager.kubernetes.io/mode: EnsureExists
name: system:coredns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:coredns
subjects:
- kind: ServiceAccount
name: coredns
namespace: kube-system
---
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: EnsureExists
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes lychuad in-addr.arpa ip6.arpa { #需要把__DNS__DOMAIN__ 改为 kubeasz hosts CLUSTER_DNS_DOMAIN设置的域名
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/name: "CoreDNS"
spec:
# replicas: not specified here:
# 1. In order to make Addon Manager do not reconcile this replicas parameter.
# 2. Default is 1.
# 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
priorityClassName: system-cluster-critical
serviceAccountName: coredns
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: k8s-app
operator: In
values: ["kube-dns"]
topologyKey: kubernetes.io/hostname
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
nodeSelector:
kubernetes.io/os: linux
containers:
- name: coredns
image: ccr.ccs.tencentyun.com/tcb-100008233720-nhwk/coredns:v1.8.6
imagePullPolicy: IfNotPresent
resources:
limits:
memory: __DNS__MEMORY__LIMIT__
requests:
cpu: 100m
memory: 70Mi
args: [ "-conf", "/etc/coredns/Corefile" ]
volumeMounts:
- name: config-volume
mountPath: /etc/coredns
readOnly: true
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
- containerPort: 9153
name: metrics
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /ready
port: 8181
scheme: HTTP
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- all
readOnlyRootFilesystem: true
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"
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/name: "CoreDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 169.254.20.10
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
- name: metrics
port: 9153
protocol: TCP
root@master1:~# kubectl apply -f coredns.yaml
查看下pod
状态
root@master1:~# kubectl get po -n kube-system
1.2 验证pod
是否能解析到域名
先随便run
几个pod
做测试
root@master1:~# kubectl run net-test1 --image=ubuntu sleep 360000
pod/net-test1 created
root@master1:~# kubectl run net-test2 --image=ubuntu sleep 360000
pod/net-test2 created
root@master1:~# kubectl run net-test3 --image=ubuntu sleep 360000
pod/net-test3 created
进入pod
ping 百度看下pod
是否能解析到百度ip
,测试下pod
直接是否能通信
# kubectl exec -it net-test1 bash
2.部署Dashboard
部署kubernetes的web管理界⾯dashboard
# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml
# mv recommended.yaml dashboard-v2.5.1.yaml
# kubectl apply -f dashboard-v2.5.1.yaml
# # kubectl get svc -n kubernetes-dashboard
修改kubernetes-dashboard
svc
ClusterIP
改为NodePort
查看修是否修改成功
# kubectl get svc -n kubernetes-dashboard
dashboard
svc
映射443到39237
访问dashboard
WEB
页面https://masterip:39237
2.1 创建账号admin-user
# cat admin-user.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
# kubectl apply -f admin-user.yaml
2.2 查看token
# kubectl get secrets -n kubernetes-dashboard |grep admin
# kubectl describe secrets -n kubernetes-dashboard admin-user-token-sjwm9
回到dashboard
web
页面选择token
登录
2.3 设置token登录会话保持时间
在dashboard.yaml
添加
- --token-ttl=43200
重新生效配置
kubectl apply -f dashboard.yaml
3.熟练掌握kubtctl命令使用
3.1Kubectl 自动补全
source <(kubectl completion bash) # setup autocomplete in bash, bash-completion package should be installed first.
source <(kubectl completion zsh) # setup autocomplete in zsh
3.2 Kubectl 上下文和配置
设置 kubectl
命令交互的 kubernetes 集群并修改配置信息。参阅 使用 kubeconfig 文件进行跨集群验证 获取关于配置文件的详细信
kubectl config view # 显示合并后的 kubeconfig 配置
# 同时使用多个 kubeconfig 文件并查看合并后的配置
KUBECONFIG=~/.kube/config:~/.kube/kubconfig2 kubectl config view
# 获取 e2e 用户的密码
kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'
kubectl config current-context # 显示当前的上下文
kubectl config use-context my-cluster-name # 设置默认上下文为 my-cluster-name
# 向 kubeconf 中增加支持基本认证的新集群
kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword
# 使用指定的用户名和 namespace 设置上下文
kubectl config set-context gce --user=cluster-admin --namespace=foo \
&& kubectl config use-context gce
3.3 显示和查找资源
# Get commands with basic output
$ kubectl get services # 列出所有 namespace 中的所有 service
$ kubectl get pods --all-namespaces # 列出所有 namespace 中的所有 pod
$ kubectl get pods -o wide # 列出所有 pod 并显示详细信息
$ kubectl get deployment my-dep # 列出指定 deployment
$ kubectl get pods --include-uninitialized # 列出该 namespace 中的所有 pod 包括未初始化的
# 使用详细输出来描述命令
$ kubectl describe nodes my-node
$ kubectl describe pods my-pod
$ kubectl get services --sort-by=.metadata.name # List Services Sorted by Name
# 根据重启次数排序列出 pod
$ kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'
# 获取所有具有 app=cassandra 的 pod 中的 version 标签
$ kubectl get pods --selector=app=cassandra rc -o \
jsonpath='{.items[*].metadata.labels.version}'
# 获取所有节点的 ExternalIP
$ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'
# 列出属于某个 PC 的 Pod 的名字
# “jq”命令用于转换复杂的 jsonpath,参考 https://stedolan.github.io/jq/
$ sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
$ echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})
# 查看哪些节点已就绪
$ JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
&& kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"
# 列出当前 Pod 中使用的 Secret
$ kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq
3.4 更新资源
$ kubectl rolling-update frontend-v1 -f frontend-v2.json # 滚动更新 pod frontend-v1
$ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 # 更新资源名称并更新镜像
$ kubectl rolling-update frontend --image=image:v2 # 更新 frontend pod 中的镜像
$ kubectl rolling-update frontend-v1 frontend-v2 --rollback # 退出已存在的进行中的滚动更新
$ cat pod.json | kubectl replace -f - # 基于 stdin 输入的 JSON 替换 pod
# 强制替换,删除后重新创建资源。会导致服务中断。
$ kubectl replace --force -f ./pod.json
# 为 nginx RC 创建服务,启用本地 80 端口连接到容器上的 8000 端口
$ kubectl expose rc nginx --port=80 --target-port=8000
# 更新单容器 pod 的镜像版本(tag)到 v4
$ kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -
$ kubectl label pods my-pod new-label=awesome # 添加标签
$ kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq # 添加注解
$ kubectl autoscale deployment foo --min=2 --max=10 # 自动扩展 deployment “foo”
3.5 修补资源
使用策略合并补丁并修补资源。
$ kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' # 部分更新节点
# 更新容器镜像; spec.containers[*].name 是必须的,因为这是合并的关键字
$ kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'
# 使用具有位置数组的 json 补丁更新容器镜像
$ kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'
# 使用具有位置数组的 json 补丁禁用 deployment 的 livenessProbe
$ kubectl patch deployment valid-deployment --type json -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'
3.6 编辑资源
在编辑器中编辑任何 API 资源。
$ kubectl edit svc/docker-registry # 编辑名为 docker-registry 的 service
$ KUBE_EDITOR="nano" kubectl edit svc/docker-registry # 使用其它编辑器
3.7 Scale 资源
$ kubectl scale --replicas=3 rs/foo # Scale a replicaset named 'foo' to 3
$ kubectl scale --replicas=3 -f foo.yaml # Scale a resource specified in "foo.yaml" to 3
$ kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # If the deployment named mysql's current size is 2, scale mysql to 3
$ kubectl scale --replicas=5 rc/foo rc/bar rc/baz # Scale multiple replication controllers
3.8 删除资源
$ kubectl delete -f ./pod.json # 删除 pod.json 文件中定义的类型和名称的 pod
$ kubectl delete pod,service baz foo # 删除名为“baz”的 pod 和名为“foo”的 service
$ kubectl delete pods,services -l name=myLabel # 删除具有 name=myLabel 标签的 pod 和 serivce
$ kubectl delete pods,services -l name=myLabel --include-uninitialized # 删除具有 name=myLabel 标签的 pod 和 service,包括尚未初始化的
$ kubectl -n my-ns delete po,svc --all # 删除 my-ns namespace 下的所有 pod 和 serivce,包括尚未初始化的
3.9 与运行中的 Pod 交互
$ kubectl logs my-pod # dump 输出 pod 的日志(stdout)
$ kubectl logs my-pod -c my-container # dump 输出 pod 中容器的日志(stdout,pod 中有多个容器的情况下使用)
$ kubectl logs -f my-pod # 流式输出 pod 的日志(stdout)
$ kubectl logs -f my-pod -c my-container # 流式输出 pod 中容器的日志(stdout,pod 中有多个容器的情况下使用)
$ kubectl run -i --tty busybox --image=busybox -- sh # 交互式 shell 的方式运行 pod
$ kubectl attach my-pod -i # 连接到运行中的容器
$ kubectl port-forward my-pod 5000:6000 # 转发 pod 中的 6000 端口到本地的 5000 端口
$ kubectl exec my-pod -- ls / # 在已存在的容器中执行命令(只有一个容器的情况下)
$ kubectl exec my-pod -c my-container -- ls / # 在已存在的容器中执行命令(pod 中有多个容器的情况下)
$ kubectl top pod POD_NAME --containers # 显示指定 pod 和容器的指标度量
3.10 与节点和集群交互
$ kubectl cordon my-node # 标记 my-node 不可调度
$ kubectl drain my-node # 清空 my-node 以待维护
$ kubectl uncordon my-node # 标记 my-node 可调度
$ kubectl top node my-node # 显示 my-node 的指标度量
$ kubectl cluster-info # 显示 master 和服务的地址
$ kubectl cluster-info dump # 将当前集群状态输出到 stdout
$ kubectl cluster-info dump --output-directory=/path/to/cluster-state # 将当前集群状态输出到 /path/to/cluster-state
# 如果该键和影响的污点(taint)已存在,则使用指定的值替换
$ kubectl taint nodes foo dedicated=special-user:NoSchedule
3.11 资源类型
下表列出的是 kubernetes 中所有支持的类型和缩写的别名。
资源类型 | 缩写别名 |
---|---|
clusters |
|
componentstatuses |
cs |
configmaps |
cm |
daemonsets |
ds |
deployments |
deploy |
endpoints |
ep |
event |
ev |
horizontalpodautoscalers |
hpa |
ingresses |
ing |
jobs |
|
limitranges |
limits |
namespaces |
ns |
networkpolicies |
|
nodes |
no |
statefulsets |
|
persistentvolumeclaims |
pvc |
persistentvolumes |
pv |
pods |
po |
podsecuritypolicies |
psp |
podtemplates |
|
replicasets |
rs |
replicationcontrollers |
rc |
resourcequotas |
quota |
cronjob |
|
secrets |
|
serviceaccount |
sa |
services |
svc |
storageclasses |
|
thirdpartyresources |
3.12 格式化输出
要以特定的格式向终端窗口输出详细信息,可以在 kubectl
命令中添加 -o
或者 -output
标志。
输出格式 | 描述 |
---|---|
-o=custom-columns=<spec> |
使用逗号分隔的自定义列列表打印表格 |
-o=custom-columns-file=<filename> |
使用 文件中的自定义列模板打印表格 |
-o=json |
输出 JSON 格式的 API 对象 |
-o=jsonpath=<template> |
打印 jsonpath 表达式中定义的字段 |
-o=jsonpath-file=<filename> |
打印由 文件中的 jsonpath 表达式定义的字段 |
-o=name |
仅打印资源名称 |
-o=wide |
以纯文本格式输出任何附加信息,对于 Pod ,包含节点名称 |
-o=yaml |
输出 YAML 格式的 API 对象 |
3.13 Kubectl 详细输出和调试
使用 -v
或 --v
标志跟着一个整数来指定日志级别。
详细等级 | 描述 |
---|---|
--v=0 |
总是对操作人员可见。 |
--v=1 |
合理的默认日志级别,如果您不需要详细输出。 |
--v=2 |
可能与系统的重大变化相关的,有关稳定状态的信息和重要的日志信息。这是对大多数系统推荐的日志级别。 |
--v=3 |
有关更改的扩展信息。 |
--v=4 |
调试级别详细输出。 |
--v=6 |
显示请求的资源。 |
--v=7 |
显示HTTP请求的header。 |
--v=8 |
显示HTTP请求的内容。 |
4.掌握对etcdctl的命令客户端使用
etcd
实现数据备份与恢复
etcd V3 API
版本数据备份恢复
WAL是write ahead log
(预写日志)的缩写,顾名思义,也就是在执行真正的写操作之前先写一个日志,预写日志。
wal:存放预写日志,最大的作用是记录了整个数据变化的全部的历程,在etcd中,所有数据的修改在提交前,都要先写入到WAL中。
V3版本备份数据:
# etcdctl snapshot save snapshot.db
Snapshot saved at snapshot.db
V3版本数据恢复:
# etcdctl restore snapshot.db --data-dir=/opt/etcd #将数据恢复到新的目录下
#自动备份数据
# mkdir /data/etcd-backup-dir/ -p
# cat script.sh
#!/bin/bash
source /etc/profile
DATE=`date +%Y-%m%d_%H-%M-%S`
ETCDCTL_API=3 /usr/local/bin/etcdctl snapshot save /data/etcd-backup-dir/etcd-snapshot-${DATE}.db
ETCD数据恢复流程:
当etcd集群宕机数量超过集群总节点数一半以上的时候(如总数为三台宕机两台),就会导致整个集群宕机,后期需要重新恢复数据,则恢复流程如下:
- 回复服务器系统
- 重新部署ETCD集群
- 停止
kube-apiserver/controller-manager/scheduler/kubelet/kube-proxy
- 停止
ETCD
集群 - 各ETCD节点恢复同一份备份数据
- 启动各节点并验证ETCD集群
- 启动
kube-apiserver/controller-manager/scheduler/kubelet/kube-proxy
- 验证
k8s master
状态及pod
数据
root@master1:~# etcdctl version
etcdctl version: 3.4.13
API version: 3.4
root@master1:/data/kubernetes/server/bin# etcdctl
NAME:
etcdctl - A simple command line client for etcd3.
USAGE:
etcdctl [flags]
VERSION:
3.5.1
API VERSION:
3.5
COMMANDS:
alarm disarm Disarms all alarms
alarm list Lists all alarms
auth disable Disables authentication
auth enable Enables authentication
auth status Returns authentication status
check datascale Check the memory usage of holding data for different workloads on a given server endpoint.
check perf Check the performance of the etcd cluster
compaction Compacts the event history in etcd
defrag Defragments the storage of the etcd members with given endpoints
del Removes the specified key or range of keys [key, range_end)
elect Observes and participates in leader election
endpoint hashkv Prints the KV history hash for each endpoint in --endpoints
endpoint health Checks the healthiness of endpoints specified in `--endpoints` flag
endpoint status Prints out the status of endpoints specified in `--endpoints` flag
get Gets the key or a range of keys
help Help about any command
lease grant Creates leases
lease keep-alive Keeps leases alive (renew)
lease list List all active leases
lease revoke Revokes leases
lease timetolive Get lease information
lock Acquires a named lock
make-mirror Makes a mirror at the destination etcd cluster
member add Adds a member into the cluster
member list Lists all members in the cluster
member promote Promotes a non-voting member in the cluster
member remove Removes a member from the cluster
member update Updates a member in the cluster
move-leader Transfers leadership to another etcd cluster member.
put Puts the given key into the store
role add Adds a new role
role delete Deletes a role
role get Gets detailed information of a role
role grant-permission Grants a key to a role
role list Lists all roles
role revoke-permission Revokes a key from a role
snapshot restore Restores an etcd member snapshot to an etcd directory
snapshot save Stores an etcd node backend snapshot to a given file
snapshot status [deprecated] Gets backend snapshot status of a given file
txn Txn processes all the requests in one transaction
user add Adds a new user
user delete Deletes a user
user get Gets detailed information of a user
user grant-role Grants a role to a user
user list Lists all users
user passwd Changes password of user
user revoke-role Revokes a role from a user
version Prints the version of etcdctl
watch Watches events stream on keys or prefixes
OPTIONS:
--cacert="" verify certificates of TLS-enabled secure servers using this CA bundle
--cert="" identify secure client using this TLS certificate file
--command-timeout=5s timeout for short running command (excluding dial timeout)
--debug[=false] enable client-side debug logging
--dial-timeout=2s dial timeout for client connections
-d, --discovery-srv="" domain name to query for SRV records describing cluster endpoints
--discovery-srv-name="" service name to query when using DNS discovery
--endpoints=[127.0.0.1:2379] gRPC endpoints
-h, --help[=false] help for etcdctl
--hex[=false] print byte strings as hex encoded strings
--insecure-discovery[=true] accept insecure SRV records describing cluster endpoints
--insecure-skip-tls-verify[=false] skip server certificate verification (CAUTION: this option should be enabled only for testing purposes)
--insecure-transport[=true] disable transport security for client connections
--keepalive-time=2s keepalive time for client connections
--keepalive-timeout=6s keepalive timeout for client connections
--key="" identify secure client using this TLS key file
--password="" password for authentication (if this option is used, --user option shouldn't include password)
--user="" username[:password] for authentication (prompt if password is not supplied)
-w, --write-out="simple" set the output format (fields, json, protobuf, simple, table)
4.1 查看当前节点ETCD
状态
root@master1:~# etcdctl endpoint health
127.0.0.1:2379 is healthy: successfully committed proposal: took = 3.384086ms
4.2 查看ETCD
集群所有成员状态
root@master1:~# export NODE_IPS="11.0.1.44 11.0.1.45 11.0.1.43"
root@master1:~# for ip in ${NODE_IPS}; do ETCDCTL_API=3 /usr/local/bin/etcdctl --endpoints=https://${ip}:2379 --cacert=/etc/kubernetes/pki/etcd/ca.pem --cert=/etc/kubernetes/pki/etcd/etcd.pem --key=/etc/kubernetes/pki/etcd/etcd-key.pem endpoint health; done
https://11.0.1.44:2379 is healthy: successfully committed proposal: took = 10.05831ms
https://11.0.1.45:2379 is healthy: successfully committed proposal: took = 15.28305ms
https://11.0.1.43:2379 is healthy: successfully committed proposal: took = 13.803392ms
4.3 以表格方式查看节点详细信息状态
root@master1:~# export NODE_IPS="11.0.1.44 11.0.1.45 11.0.1.43"
root@master1:~# for ip in ${NODE_IPS}; do ETCDCTL_API=3 /usr/local/bin/etcdctl --write-out=table endpoint status --endpoints=https://${ip}:2379 --cacert=/etc/kubernetes/pki/etcd/etcd-ca.pem --cert=/etc/kubernetes/pki/etcd/etcd.pem --key=/etc/kubernetes/pki/etcd/etcd-key.pem endpoint health; done
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| https://11.0.1.43:2379 | 310b83fe6f4488f7 | 3.4.13 | 23 MB | false | false | 1019 | 28203629 | 28203629 | |
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| https://11.0.1.44:2379 | fe79f852b36478e5 | 3.4.13 | 23 MB | true | false | 1019 | 28203629 | 28203629 | |
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| https://11.0.1.45:2379 | 39230c0ad620d6b7 | 3.4.13 | 23 MB | false | false | 1019 | 28203629 | 28203629 | |
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
4.4 查看ETCD
数据信息
etcdctl get / --prefix --keys-only
kube-system
信息, pods
deployment
都可以查看过滤
etcdctl get / --prefix --keys-only | grep namespace
4.4 以通过etcdctl
拿到pod
value
信息
etcdctl get / --prefix --keys-only | grep nfs-client-provisioner-856794d5b4-tsl2n
etcdctl get /registry/pods/default/nfs-client-provisioner-856794d5b4-tsl2
3.5 ETCD
增删改查
添加数据
ETCDCTL_API=3 /usr/local/bin/etcdctl put /name "test"
etcdctl /usr/local/bin/etcdctl put /name "test"
查询数据
etcdctl /usr/local/bin/etcdctl get /name "test"
改数据
该数据相当于直接覆盖数据
etcdctl /usr/local/bin/etcdctl put /name "test"
验证改动数据是否成功
etcdctl /usr/local/bin/etcdctl put /name "test"
/name
test
删除数据
etcdctl del /registry/pods/default/net-test1
通过etcdctl
删除pod
以下命令谨慎操作
创建一个测试pod
root@master1:~# kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
net-test1 1/1 Running 0 3m15s
root@master1:~# etcdctl get / --prefix --keys-only | grep net-test1
root@master1:~# etcdctl del /registry/pods/default/net-test1
root@master1:~# kubectl get pods -n default
No resources found in default namespace
现在无法看到net-test
服务
4.6 etcd数据watch机制
基于不断看数据,发生变化就主动触发通知客户端,ETCD V3 的Watch某个固定的key,也支持Watch一个范围。
在ETCD 某一个节点watch一个key,没有变化key也可以执行watch,后期可以在创建:
master01
# ETCDCTL_API=3 /usr/local/bin/etcdctl watch /tmp
PUT
/tmp
data v2
PUT
/tmp
data v3
master03
# etcdctl put /tmp "data v2"
OK
# etcdctl put /tmp "data v3"
OK
4.7 数据备份演示
# etcdctl snapshot save /data/etcd-backup/etcd_backup-2022-05-14-01
{"level":"info","ts":1652523984.344787,"caller":"snapshot/v3_snapshot.go:119","msg":"created temporary db file","path":"/data/etcd-backup/etcd_backup-2022-05-14-01.part"}
{"level":"info","ts":"2022-05-14T18:26:24.345+0800","caller":"clientv3/maintenance.go:200","msg":"opened snapshot stream; downloading"}
{"level":"info","ts":1652523984.3453805,"caller":"snapshot/v3_snapshot.go:127","msg":"fetching snapshot","endpoint":"127.0.0.1:2379"}
{"level":"info","ts":"2022-05-14T18:26:24.546+0800","caller":"clientv3/maintenance.go:208","msg":"completed snapshot read; closing"}
{"level":"info","ts":1652523984.5758638,"caller":"snapshot/v3_snapshot.go:142","msg":"fetched snapshot","endpoint":"127.0.0.1:2379","size":"23 MB","took":0.231010645}
{"level":"info","ts":1652523984.5759547,"caller":"snapshot/v3_snapshot.go:152","msg":"saved","path":"/data/etcd-backup/etcd_backup-2022-05-14-01"}
Snapshot saved at /data/etcd-backup/etcd_backup-2022-05-14-01
/data/etcd-backup/etcd_backup-2022-05-14-01
自定义指定备份路径,必须真实存在绝对路径
etcd_backup-2022-05-14-01
备份数据命名最好是日期+备份时间。
4.8 单机数据恢复
# etcdctl snapshot restore /data/etcd-backup/etcd_backup-2022-05-14-01 --data-dir=/tmp/etcd
"level":"info","ts":1652524645.9453328,"caller":"snapshot/v3_snapshot.go:296","msg":"restoring snapshot","path":"/data/etcd-backup/etcd_backup-2022-05-14-01","wal-dir":"/tmp/etcd/member/wal","data-dir":"/tmp/etcd","snap-dir":"/tmp/etcd/member/snap"}
{"level":"info","ts":1652524646.1597452,"caller":"mvcc/kvstore.go:380","msg":"restored last compact revision","meta-bucket-name":"meta","meta-bucket-name-key":"finishedCompactRev","restored-compact-revision":24716203}
{"level":"info","ts":1652524646.173012,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"cdf818194e3a8c32","local-member-id":"0","added-peer-id":"8e9e05c52164694d","added-peer-peer-urls":["http://localhost:2380"]}
{"level":"info","ts":1652524646.1795242,"caller":"snapshot/v3_snapshot.go:309","msg":"restored snapshot","path":"/data/etcd-backup/etcd_backup-2022-05-14-01","wal-dir":"/tmp/etcd/member/wal","data-dir":"/tmp/etcd","snap-dir":"/tmp/etcd/member/snap"}
# ls /tmp/
/data/etcd-backup/etcd_backup-2022-05-14-01
备份文件路径
--data-dir=
恢复到指定路径,指定路径是自动创建的,不需要手动创建。
修改etcd.service
数据路径
WorkingDirectory=
--data-dir
修改完后重启etcd
# systemctl restart etcd.service
4.9kubeasz
集群备份恢复
4.9.1 备份
ansible
yml 文件参考
./ezctl backup k8s-01
备份ETCD数据在clusters/k8s-01/backup/
路径下
4.9.2 恢复
root@master1:/etc/kubeasz# ./ezctl restore k8s-01
恢复完成 !
5 .kubernetes集群版本升级
5.1 升级准备
- 备份kubernetes原先的二进制文件和配置文件。
- 下载最新版本的kubernetes二进制包,如1.8.5版本,下载二进制包,我们使用的是kubernetes-server-linux-amd64.tar.gz,分发到集群的每个节点上。
5.1.1 升级方式
在软件领域,主流的应用升级方式有两种,分别是原地升级和替换升级。目前这两种升级方式在业内互联网大厂均有采用,具体方案选择与集群上业务有很大关系。
替换升级:
- Kubernetes 替换升级是先准备一个高版本集群,对低版本集群通过逐个节点排干、删除最后加入新集群的方式将低版本集群内节点逐步轮换升级到新版本。
- 替换升级的优点是原子性更强,逐步升级各个节点,升级过程不存在中间态,对业务安全更有保障;缺点是集群升级工作量较大,排干操作对 Pod 重启敏感度高的应用、有状态应用、单副本应用等都不友好。
5.1.2 原地升级:
- Kubernetes 原地升级是对节点上服务如 kube-controller-manager、 kubelet 等组件按照一定顺序批量更新,从节点角色维度批量管理组件版本。
- 原地升级的优点是自动化操作便捷,并且通过适当的修改能够很好的保证容器的生命周期连续性;缺点是集群升级中组件升级顺序很重要,升级中存在中间态,并且一个组件重启失败可能影响后续其他组件升级,原子性差。
容器集群上运行的部分业务对重启容忍度较低,尽可能避免容器重启是升级工作的第一要务。当解决好升级版本带来的容器重启后,结合业务容器化程度和业务类型不同,因地制宜的选择升级方式即可。二进制部署集群建议选择原地升级的方式,具有时间短,操作简捷,单副本业务不会被升级影响的好处。
5.1.3 跨版本升级
由于Kubernetes 本身是基于 API 的微服务架构,Kuberntes 内部架构也是通过 API 的调用和对资源对象的 List-Watch 来协同资源状态,因此社区开发者在设计 API 时遵循向上或向下兼容的原则。这个兼容性规则也是遵循社区的偏差策略,即 API groups 弃用、启用时,对于 Alpha 版本会立即生效,对于 Beta 版本将会继续支持3个版本,超过对应版本将导致 API resource version 不兼容。例如 kubernetes 在 v1.16 对 Deploymetn 等资源的 extensions/v1beta1 版本执行了弃用,在 v1.18 版本从代码级别执行了删除,当跨3个版本以上升级时会导致相关资源无法被识别,相应的增删改查操作都无法执行。
如果按照官方建议的升级策略,从 v1.10 升级到 v1.17 需要经过至少 7 次升级,这对于业务场景复杂的生产环境来说运维复杂度高,业务风险大。
升级前提v1.23.1
--> v1.23.5
源码包下载 github-kubernetes
根据系统架构下载
Source Code
Client Binaries
Server Binaries
Node Binaries
解压下载都有的tar.gz包
root@master1:/data/kubernetes/server/bin# pwd
/data/kubernetes/server/bin
root@master1:/data/kubernetes/server/bin# ./kube-apiserver --version
Kubernetes v1.23.5
包括master所有的升级文件
拷贝文件至/etc/kubeasz/bin
root@master1:/data/kubernetes/server/bin# cp kube-apiserver kube-controller-manager kube-scheduler kube-proxy kubelet kubectl /etc/kubeasz/bin
5.2 开始升级
如果是高可用,先下线所要升级的节点
5.2.1 升级master01
systemctl restart kube-lb.service
停止k8s组件
# systemctl stop kube-apiserver.service kube-controller-manager.service kube-scheduler.service kube-proxy.service kubelet.service
升级前集群各节点版本
替换文件
# \cp kube-apiserver kube-controller-manager kube-scheduler kube-proxy kubelet kubectl /usr/local/bin/
重启服务
# systemctl start kube-apiserver.service kube-controller-manager.service kube-scheduler.service kube-proxy.service kubelet.service
所有master节点同样操作
5.2.2 node节点升级
停止 kubelet
kube-proxy
服务
systemctl stop kubelet.service kube-proxy.service
拷贝文件到需要升级node
节点上
scp kube-proxy kubelet root@11.0.1.46:/usr/local/bin/
所有node
节点同样操作
node
节点升级完成
6. Deployment 简述
Deployment
为 Pod
和ReplicaSet
提供了一个声明式定义 (declarative) 方法,用来替代以前的 ReplicationController
更方便的管理应用。
作为最常用的 Kubernetes
对象,Deployment
常会用来创建 ReplicaSet
和 Pod
,我们往往不会直接在集群中使用 ReplicaSet
部署一个新的微服务,一方面是因为 ReplicaSet
的功能其实不够强大,一些常见的更新、扩容和缩容运维操作都不支持,Deployment 的引入就是为了支持这些复杂的操作。
6.1 Deployment 一个典型的用例
一个典型的用例如下:
- 使用
eployment
来创建ReplicaSet
。ReplicaSet
在后台创建pod
。检查启动状态,看它是成功还是失败。 - 然后,通过更新
Deployment
的PodTemplateSpec
字段来声明 Pod 的新状态。这会创建一个新的
ReplicaSet
,Deployment
会按照控制的速率将pod
从旧的ReplicaSet
移动到新的ReplicaSet
中。 - 如果当前状态不稳定,回滚到之前的
Deployment revision
。每次回滚都会更新Deployment
的revision
。 - 扩容
Deployment
以满足更高的负载。 - 暂停
Deployment
来应用PodTemplateSpec
的多个修复,然后恢复上线。 - 根据
Deployment
的状态判断上线是否hang
住了。 - 清除旧的不必要的
ReplicaSet
。
6.2 创建 Deployment
Deployment
yaml
文件包含四个部分:
apiVersion
: 表示版本kind
: 表示资源metadata
: 表示元信息spec
: 资源规范字段
6.3 Deployment yaml 详解
apiVersion: apps/v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Deployment # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
name: demo # 资源的名字,在同一个namespace中必须唯一
namespace: default # 部署在哪个namespace中
labels: # 设定资源的标签
app: demo
version: stable
spec: # 资源规范字段
replicas: 1 # 声明副本数目
revisionHistoryLimit: 3 # 保留历史版本
selector: # 选择器
matchLabels: # 匹配标签
app: demo
version: stable
strategy: # 策略
rollingUpdate: # 滚动更新
maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 30% # 示在更新过程中能够进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
type: RollingUpdate # 滚动更新策略
template: # 模版
metadata: # 资源的元数据/属性
annotations: # 自定义注解列表
sidecar.istio.io/inject: "false" # 自定义注解名字
labels: # 设定资源的标签
app: demo
version: stable
spec: # 资源规范字段
containers:
- name: demo # 容器的名字
image: demo:v1 # 容器使用的镜像地址
imagePullPolicy: IfNotPresent # 每次Pod启动拉取镜像策略,三个选择 Always、Never、IfNotPresent
# Always,每次都检查;Never,每次都不检查(不管本地是否有);IfNotPresent,如果本地有就不检查,如果没有就拉取
resources: # 资源管理
limits: # 最大使用
cpu: 300m # CPU,1核心 = 1000m
memory: 500Mi # 内存,1G = 1024Mi
requests: # 容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
cpu: 100m
memory: 100Mi
livenessProbe: # pod 内部健康检查的设置
httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常
path: /healthCheck # URI地址
port: 8080 # 端口
scheme: HTTP # 协议
# host: 127.0.0.1 # 主机地址
initialDelaySeconds: 30 # 表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5 # 检测的超时时间
periodSeconds: 30 # 检查间隔时间
successThreshold: 1 # 成功门槛
failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
readinessProbe: # Pod 准备服务健康检查设置
httpGet:
path: /healthCheck
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 5
#也可以用这种方法
#exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常
# command:
# - cat
# - /tmp/health
#也可以用这种方法
#tcpSocket: # 通过tcpSocket检查健康
# port: number
ports:
- name: http # 名称
containerPort: 8080 # 容器开发对外的端口
protocol: TCP # 协议
imagePullSecrets: # 镜像仓库拉取密钥
- name: harbor-certification
affinity: # 亲和性调试
nodeAffinity: # 节点亲和力
requiredDuringSchedulingIgnoredDuringExecution: # pod 必须部署到满足条件的节点上
nodeSelectorTerms: # 节点满足任何一个条件就可以
- matchExpressions: # 有多个选项,则只有同时满足这些逻辑选项的节点才能运行 pod
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
本文来自博客园,作者:LYChuad,转载请注明原文链接:https://www.cnblogs.com/lychuad/articles/16271505.html