Kubernetes 架构简介和概览
Docker 简介
什么是容器?
容器是一个软件的标准单元,其中打包了代码及其所有的依赖。
什么是 Docker?
Docke Engine
作为守护进程运行的服务
有 Restful API
命令行界面(cli)
注: 本文中采用 Ubuntu 16.04进行所有的安装及测试
apt -get update
# 安装
apt -get install docker . io -y
# 查看状态
systemctl status docker
# 拉取镜像
docker pull nginx
# 查看镜像
docker images
# 运行容器
docker run -d -p 192.168.x.x : 80 : 80 --name nginx -container nginx
# 查看容器
docker ps # 或 docker container ls
# 进入容器
docker exec -it nginx -container /bin /bash
Kubernetes 集群架构概览
什么是 Kubernetes?
单节点 Kubernetes 部署(Minikube)
apt -get update
apt -get install curl -y
apt install virtualbox virtualbox -ext -pack
mkdir /minikube && cd /minikube
curl -Lo minikube https : //storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
chmod +x minikube
mv -v minikube /usr /local /bin /
curl -LO https : //storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x kubectl
mv -v kubectl /usr /local /bin
# 启动服务
minikube start # 虚拟机中可以使用minikube start --vm-driver=none
# 检查minikube 所安装的服务
kubectl get pods --all -namespaces
掌握 YAML文件
什么是 YAML?
两个 Kubernetes 对象字段:
apiVersion : v1
kind : Deployment
metadata :
name : nginx -dev
spec :
containers :
- name : nginx
image : nginx : 1.7.9
ports :
- containerPort : 80
常用 Kubernetes对象:
Nodes
Pods
Deployments
Services
ConfigMaps
构建第一个 Pod
# vi nginx.yaml
apiVersion : v1 # for versions before 1.9.0 use apps/v1beta2
kind : Pod
metadata :
name : nginx -deployment
spec :
containers :
- name : nginx
image : nginx : 1.7.9
ports :
- containerPort : 80
# 创建
kubectl create -f nginx . yaml
# 查看
kubectl get pods
配置 Kubernetes 集群
规划Kubernetes 集群
为什么要设计 Kubernetes集群?
通过构建集群来启动团队自治
以花费较少的方式进行伸缩
设计 Kubernetes 集群
Labels:组织服务
RBAC:Role-Based Access Control
命名空间管理员:管理命名空间中的所有内容
命名空间部署负责人:允许使用”get”, “list”, “watch”, “create”, “update”, “patch”和”delete”
集群读用户:允许使用”get”, “list”和”watch”
命名空间
资源配额
自动伸缩
Helm:包管理器
环境设置概览
安装 Kubernetes 的步骤:
在所有节点上安装 Docker
添加仓库密钥
下载 Kubernetes 二进制文件
添加仓库源
更新系统
安装工具:kubeadm kubelet kubectl
kubeadm init
添加工作节点的密钥
对用户应用权限
配置 CNI(容器网络接口),有 flannel 、Contiv 和 Weave
需开启的端口(如开启了防火墙):
Kubernetes 集群安装
准备两台主机/虚拟机:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 国内可替换镜像源
sudo sed -i "s/archive.ubuntu.com/mirrors.aliyun.com/g" /etc /apt /sources . list
sudo sed -i "s/security.ubuntu.com/mirrors.aliyun.com/g" /etc /apt /sources . list
# 安装
apt -get update && apt -get upgrade -y
apt -get install docker . io -y
curl -s https : //packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
vi /etc /apt /sources . list . d /kubernetes . list
deb https : //apt.kubernetes.io/ kubernetes-xenial main
apt -get update
apt install -y kubelet kubeadm kubectl
swapoff -a
# master
kubeadm init --pod -network -cidr =10.244.0.0 /16 # 10.244.0.0/16为 flannel 配置的默认值
# 也可指定 IP:kubeadm init --apiserver-advertise-address=192.168.x.x --pod-network-cidr=10.244.0.0/16
# 出现错误可进行重置kubeadm reset
根据提示分别在主节点上使用普通用户执行如下命令:
mkdir -p $ HOME /. kube
sudo cp -i /etc /kubernetes /admin . conf $ HOME /. kube /config
sudo chown $ ( id -u ) : $ ( id -g ) $ HOME /. kube /config
# 查看启动状况
kubectl get pods --all -namespaces
# 启动 flannel
kubectl apply -f https : //raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
在 worker 节点的 root 用户下执行前面所提示的命令(请根据实际状况修改):
kubeadm join 192.168.50.143 : 6443 --token u12uxc . hae8535xmsue7w55 \
--discovery -token -ca -cert -hash sha256 : ac7d6fe0371dd84d406f7378d5e0c6314611e6e48209bc6c480bf886b83466b4
若出现如下错误:
[ WARNING IsDockerSystemdCheck ] : detected "cgroupfs" as the Docker cgroup driver . The recommended driver is "systemd" . Please follow the guide at https : //kubernetes.io/docs/setup/cri/
可按照文档执行:
cat > /etc /docker /daemon . json < < EOF
{
"exec-opts" : [ "native.cgroupdriver=systemd" ] ,
"log-driver" : "json-file" ,
"log-opts" : {
"max-size" : "100m"
} ,
"storage-driver" : "overlay2"
}
EOF
mkdir -p /etc /systemd /system /docker . service . d
# Restart docker.
systemctl daemon -reload
systemctl restart docker
注意: 如果使用的镜像默认创建的主机名都相同,请在/etc/hostname 中进行修改
其它命令
# 创建打印 token
kubeadm token create --print -join -command
Kubernetes 服务验证
kubectl get pods --all -namespaces
kubectl get nodes
free -h
cat /proc /swaps
# 节点出现问题可查看日志
kubelet logs worker -node1
sudo journalctl -u kubelet
sudo service kubelet status # 查看服务状态
ps -aux | grep kube -proxy
kubectl cluster -info
kubectl cluster -info dump # 详情
集群通信详情
集群通信概览
所有内容来自 API 服务
默认加密是 TSL(传输层加密)
kubeadm 为 worker 节点创建证书
就为节点提供公用证书
通信路径
API 服务对 kubelet
获取 pod 的日志
连接运行中的 pod
端口转发功能
验证连接 –kubelet-certificate-authority
SSH通道
API服务对其它(node, pod, services)
Kubernetes 管理
部署、平滑升级和回滚
测试文件(nginx-dep.yaml)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion : apps /v1 < em > # for versions before 1.9.0 use apps/v1beta2</em>
kind : Deployment
metadata :
name : nginx -dep
spec :
selector :
matchLabels :
app : nginx
replicas : 2
template :
metadata :
labels :
app : nginx
spec :
containers :
- name : nginx
image : nginx : 1.7.9
ports :
- containerPort : 80
使用kubectl create -f nginx-dep.yaml
命令创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
kubectl get deployments # 查看
kubectl describe deployment nginx -dep
kubectl get deployment nginx -dep -o yaml # 导出 yaml
kubectl set image deployment /nginx -dep nginx =nginx : 1.8 # 升级 Nginx
kubectl rollout status deployment /nginx -dep # 查看状态
kubectl describe deployment nginx -dep # 再次查看确定Nginx版本
# 第二种升级方式:编辑nginx-dep.yml 中的 image 版本(如1.9.1)然后执行
kubectl apply -f nginx -dep . yaml
kubectl get deployments # 查看
kubectl describe deployment nginx -dep # 确认版本,其中也包含 revision的版本号(此处为3),如出现错误,可进行回滚
# 回滚
kubectl rollout history deployment /nginx -dep --revision =3 # 查看
kubectl rollout undo deployment /nginx -dep --to -revision =2 # 回滚
kubectl rollout status deployment /nginx -dep # 查看回滚状态
kubectl describe deployment nginx -dep # 再次确认
服务网络
kubectl expose deployment nginx -dep --type ="NodePort" --port 80
kubectl get services # 查看服务
kubectl describe services nginx -dep # 查看具体服务
# 此时使用 worker 节点的 IP,加NodePort 即可在浏览器中进行访问,如 http://192.168.0.12:30523
Ingress
kubectl apply -f https : //raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
kubectl get pods --all -namespaces # 查看状态
创建 pod
web-01.yaml
apiVersion : v1
kind : Pod
metadata :
name : web -01
labels :
app : Nginx
spec :
containers :
- name : nginx
image : nginx : 1.7.9
ports :
- containerPort : 80
使用kubectl create -f web-01.yaml
命令创建
kubectl get pods # 查看
kubectl expose pod web -01 --type ="ClusterIP" --port 80 # 暴露端口
kubectl get services # 查看服务
ingress.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion : v1
kind : Service
metadata :
name : ingress -nginx
namespace : ingress -nginx
labels :
app . kubernetes . io /name : ingress -nginx
app . kubernetes . io /part -of : ingress -nginx
spec :
type : NodePort
ports :
- name : http -new
port : 80
targetPort : 80
protocol : TCP
nodePort : 30090
selector :
app . kubernetes . io /name : ingress -nginx
app . kubernetes . io /part -of : ingress -nginx
使用kubectl create -f ingress.yaml
命令创建
kubectl get services --all -namespaces # 查看
ingress-rules.yaml
apiVersion : extensions /v1beta1
kind : Ingress
metadata :
name : ingress -test
annotations :
kubernetes . io /ingress . class : nginx
ingress . kubernetes . io /rewrite -target : /
spec :
rules :
- host : test . kuber . net
http :
paths :
- path : /
backend :
serviceName : web -01
servicePort : 80
使用kubectl create -f ingress-rules.yaml
命令创建
在本地查看机器的 hosts 文件中绑定:
your . worker . node . ip test . kuber . net
此时在浏览器中使用 http://test.kuber.net:30090/即可进行访问
部署负载均衡
loadbalancer.yaml
kind : Service
apiVersion : v1
metadata :
name : loadbalancer -service
spec :
selector :
app : app -lb
ports :
- protocol : TCP
port : 80
targetPort : 9376
clusterIP : < internalIP >
loadBalancerIP : < externalIP >
type : LoadBalancer
配置和使用集群 DNS
kubectl get pods -n kube -system # 查看默认有 coredns
busybox.yaml
vagrant @ master -node : ~ $ clear
apiVersion : v1
kind : Pod
metadata :
name : busybox
namespace : default
spec :
containers :
- image : busybox : 1.28
command :
- sleep
- "3600"
imagePullPolicy : IfNotPresent
name : busybox
restartPolicy : Always
使用kubectl create -f busybox.yaml
命令创建
kubectl get pods # 查看创建进度
kubectl exec -it busybox -- nslookup kubernetes
# 出现问题排查思路
kubectl exec -it busybox -- cat /etc /resolv . conf
kubectl get pods -n kube -system
kubectl get services -n kube -system
kubectl get endpoints kube -dns -n kube -system
补充:若执行以上命令出现unable to upgrade connection pod does not exist报错
kubectl get nodes < worker -node > -o yaml # 修改名称查看statuses中的addresses
# 如为无法连接到的IP,则需进行修改
# 进入对应的工作节点
# vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# 在EnvironmentFile=-/etc/default/kubelet行之后添加
Environment ="KUBELET_EXTRA_ARGS=--node-ip=<your.ip.addr>"
# 重启
systemctl daemon -reload
systemctl restart kubelet
# 若依然有问题则打执行 kubeadm reset 重新加入主节点
持久化存储
进入执行化存储所需的步骤:
创建 NFS 存储服务
在 Kubernetes 中配置持久化磁盘卷
声明持久化磁盘卷存储
创建 Pod
apt -get install nfs -kernel -server -y
mkdir /var /nfs /general -p
cd /var /nfs /
chown nobody : nogroup general /
id nobody # 查看用户 id,稍后使用
# vi /etc/exports 可在其中添加多个 worker node
/var /nfs /general 192.168.x.x ( rw , sync , no_subtree_check ) 192.168.x.x ( rw , sync , no_subtree_check )
exportfs -r # 不执行这条可能后续可能会失败并报mount.nfs: access denied by server while mounting...
在Master 节点添加pv.yaml
apiVersion : v1
kind : PersistentVolume
metadata :
name : kube -pv
spec :
capacity :
storage : 1Gi
volumeMode : Filesystem
accessModes :
- ReadWriteMany
persistentVolumeReclaimPolicy : Recycle
nfs :
path : /var /nfs /general
server : 192.168.0.11
readOnly : false
使用kubectl create -f pv.yaml
命令创建
pvc.yaml
apiVersion : v1
kind : PersistentVolumeClaim
metadata :
name : kube -pvc
spec :
accessModes :
- ReadWriteMany
resources :
requests :
storage : 1Gi
使用kubectl create -f pvc.yaml
命令创建
kubectl get pvc # 查看
kubectl get pv # 此时状态会变成Bound
nfs-pod.yaml(65534 为 id nobody 所获取的值)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion : v1
kind : Pod
metadata :
name : nfs -pod
labels :
name : nfs -pod
spec :
containers :
- name : nfs -container
image : busybox : 1.28
command :
- sleep
- "3600"
volumeMounts :
- name : nfsvol
mountPath : /tmp
restartPolicy : Always
securityContext :
fsGroup : 65534
runAsUser : 65534
volumes :
- name : nfsvol
persistentVolumeClaim :
claimName : kube -pvc
使用kubectl create -f nfs-pod.yaml
命令创建
kubectl get pods # 查看创建状态
kubectl exec -it nfs -pod -- sh
/ $ cd /tmp
/tmp $ touch hello . txt
# 回到/var/nfs/general目录进行查看
自修复和自动伸缩
Kubernetes 自修复
kubectl get pods -o wide # 此前建立 nginx-dep 有两个 pod 来运行中
kubectl delete pod nginx -dep -9f46bb5 -bck7x # 删除其中的一个
kubectl get pods -o wide # 再次查看会发现 Kubernetes 正在重新创建一个
# 进入一个 worker 节点停止服务
service kubelet stop
# 几分钟后节点会显示为NotReady(kubectl get nodes)
kubectl get pods -o wide # 此时如有多个节点会自动在其它节点上创建Pod
Kubernetes 中的存活探针
存活探针类型
liveness.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion : v1
kind : Pod
metadata :
labels :
test : liveness
name : liveness -exec
spec :
containers :
- name : liveness
image : k8s . gcr . io /busybox
args :
- /bin /sh
- -c
- touch /tmp /healthy ; sleep 30 ; rm -rf /tmp /healthy ; sleep 600
livenessProbe :
exec :
command :
- cat
- /tmp /healthy
initialDelaySeconds : 5
periodSeconds : 5
使用kubectl create -f liveness.yaml
命令创建
# 通过以下命令会看到存活探针失败并重启的提示
kubectl describe pod liveness -exec
自动伸缩
什么是自动伸缩?
是根据不同时间所需资源来分配资源的过程
按需资源
成本节约
Kubernetes 中的自动伸缩由指标驱动
横向 Pod 自动伸缩
横向 Pod 自动伸缩(HPA)
步骤:
克隆一个 metric 服务
创建一个 Pod
配置 HPA
git clone https : //github.com/kubernetes-incubator/metrics-server
kubectl create -f metrics -server /deploy /1.8 +/ # 同时对该目录下的所有 yaml 文件进行创建
kubectl get pods --all -namespaces # 查看启动状态
kubectl get --raw /apis /metrics . k8s . io /v1beta1
kubectl top nodes
# 横向扩展示例
kubectl run php -apache --image =k8s . gcr . io /hpa -example --requests =cpu =200m --expose --port =80
kubectl autoscale deployment php -apache --cpu -percent =50 --min =1 --max =4
kubectl get hpa -w # 查看
metrics-server-deployment.yaml文件修改(Error from server (ServiceUnavailable): the server is currently unable to handle the request (get nodes.metrics.k8s.io))
containers :
- name : metrics -server
#image: k8s.gcr.io/metrics-server-amd64:v0.3.5
image : mirrorgooglecontainers /metrics -server -amd64 : v0 . 3.5 # 国内被墙的问题
# 以下均作出了修改
imagePullPolicy : IfNotPresent
command :
- /metrics -server
- --kubelet -insecure -tls
- --kubelet -preferred -address -types =InternalIP
监控类型
监控
监控让我们知道基础架构的性能和稳定性
两种主要类型的监控
基础架构监控
应用性能监控
两种展现数据的方式
聚合:视觉形式展现数据
警报:通知相关方
实现方案:
Prometheus:收集信息及存储数据
Grafana:展示数据
配置Prometheus和Grafana
配置 Prometheus 和 Grafana 的要求
Helm 安装
Charts
安装步骤
安装 Helm
下载 charts
Values.yml文件自定义设置
在Grafana 中配置 Prometheus数据源并验证其连接
curl -L https : //git.io/get_helm.sh | bash
helm init --wait
kubectl --namespace =kube -system create clusterrolebinding add -on -cluster -admin --clusterrole =cluster -admin --serviceaccount =kube -system : default
helm ls # 验证,无报错信息即为正常
git clone https : //github.com/kubernetes/charts
# vi prometheus-values.yml(仅测试使用)
alertmanager :
persistentVolume :
enabled : false
server :
persistentVolume :
enabled : false
helm install -f prometheus -values . yml charts /stable /prometheus --name prometheus --namespace prometheus
集群监控
应用监控
报警